Changeset 36401 in webkit for trunk/JavaScriptCore/VM/CTI.cpp
- Timestamp:
- Sep 14, 2008, 1:18:49 AM (17 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/VM/CTI.cpp
r36327 r36401 585 585 emitPutArg(X86::edx, 8); // leave the base in edx 586 586 emitCall(i, Machine::cti_op_put_by_id); 587 i += 6;587 i += 8; 588 588 break; 589 589 } … … 1305 1305 case op_put_by_id_generic: 1306 1306 case op_put_by_id_replace: 1307 case op_put_by_id_transition: 1307 1308 ASSERT_NOT_REACHED(); 1308 1309 } … … 1835 1836 } 1836 1837 1838 extern "C" { 1839 1840 static JSValue* SFX_CALL transitionObject(StructureID* newStructureID, size_t cachedOffset, JSObject* baseObject, JSValue* value) 1841 { 1842 StructureID* oldStructureID = newStructureID->previousID(); 1843 1844 baseObject->transitionTo(newStructureID); 1845 1846 if (oldStructureID->propertyMap().storageSize() == JSObject::inlineStorageCapacity) 1847 baseObject->allocatePropertyStorage(oldStructureID->propertyMap().storageSize(), oldStructureID->propertyMap().size()); 1848 1849 baseObject->putDirectOffset(cachedOffset, value); 1850 return baseObject; 1851 } 1852 1853 } 1854 1855 static inline bool transitionWillNeedStorageRealloc(StructureID* oldStructureID, StructureID* newStructureID) 1856 { 1857 if (oldStructureID->propertyMap().storageSize() == JSObject::inlineStorageCapacity) 1858 return true; 1859 1860 if (oldStructureID->propertyMap().storageSize() < JSObject::inlineStorageCapacity) 1861 return false; 1862 1863 if (oldStructureID->propertyMap().size() != newStructureID->propertyMap().size()) 1864 return true; 1865 1866 return false; 1867 } 1868 1869 void* CTI::privateCompilePutByIdTransition(StructureID* oldStructureID, StructureID* newStructureID, size_t cachedOffset, StructureIDChain* sIDC) 1870 { 1871 Vector<X86Assembler::JmpSrc, 16> failureCases; 1872 // check eax is an object of the right StructureID. 1873 m_jit.testl_i32r(JSImmediate::TagMask, X86::eax); 1874 failureCases.append(m_jit.emitUnlinkedJne()); 1875 m_jit.cmpl_i32m(reinterpret_cast<uint32_t>(oldStructureID), OBJECT_OFFSET(JSCell, m_structureID), X86::eax); 1876 failureCases.append(m_jit.emitUnlinkedJne()); 1877 Vector<X86Assembler::JmpSrc> successCases; 1878 1879 // ecx = baseObject 1880 m_jit.movl_mr(OBJECT_OFFSET(JSCell, m_structureID), X86::eax, X86::ecx); 1881 // proto(ecx) = baseObject->structureID()->prototype() 1882 m_jit.cmpl_i32m(ObjectType, OBJECT_OFFSET(StructureID, m_type), X86::ecx); 1883 failureCases.append(m_jit.emitUnlinkedJne()); 1884 m_jit.movl_mr(OBJECT_OFFSET(StructureID, m_prototype), X86::ecx, X86::ecx); 1885 1886 // ecx = baseObject->m_structureID 1887 for (RefPtr<StructureID>* it = sIDC->head(); *it; ++it) { 1888 // null check the prototype 1889 m_jit.cmpl_i32r(reinterpret_cast<intptr_t> (jsNull()), X86::ecx); 1890 successCases.append(m_jit.emitUnlinkedJe()); 1891 1892 // Check the structure id 1893 m_jit.cmpl_i32m(reinterpret_cast<uint32_t>(it->get()), OBJECT_OFFSET(JSCell, m_structureID), X86::ecx); 1894 failureCases.append(m_jit.emitUnlinkedJne()); 1895 1896 m_jit.movl_mr(OBJECT_OFFSET(JSCell, m_structureID), X86::ecx, X86::ecx); 1897 m_jit.cmpl_i32m(ObjectType, OBJECT_OFFSET(StructureID, m_type), X86::ecx); 1898 failureCases.append(m_jit.emitUnlinkedJne()); 1899 m_jit.movl_mr(OBJECT_OFFSET(StructureID, m_prototype), X86::ecx, X86::ecx); 1900 } 1901 1902 failureCases.append(m_jit.emitUnlinkedJne()); 1903 for (unsigned i = 0; i < successCases.size(); ++i) 1904 m_jit.link(successCases[i], m_jit.label()); 1905 1906 X86Assembler::JmpSrc callTarget; 1907 // Fast case, don't need to do any heavy lifting, so don't bother making a call. 1908 if (!transitionWillNeedStorageRealloc(oldStructureID, newStructureID)) { 1909 // Assumes m_refCount can be decremented easily, refcount decrement is safe as 1910 // codeblock should ensure oldStructureID->m_refCount > 0 1911 m_jit.subl_i8m(1, reinterpret_cast<void*>(oldStructureID)); 1912 m_jit.addl_i8m(1, reinterpret_cast<void*>(newStructureID)); 1913 m_jit.movl_i32m(reinterpret_cast<uint32_t>(newStructureID), OBJECT_OFFSET(JSCell, m_structureID), X86::eax); 1914 1915 // write the value 1916 m_jit.movl_mr(OBJECT_OFFSET(JSObject, m_propertyStorage), X86::eax, X86::eax); 1917 m_jit.movl_rm(X86::edx, cachedOffset * sizeof(JSValue*), X86::eax); 1918 } else { 1919 // Slow case transition -- we're going to need to quite a bit of work, 1920 // so just make a call 1921 m_jit.pushl_r(X86::edx); 1922 m_jit.pushl_r(X86::eax); 1923 m_jit.movl_i32r(cachedOffset, X86::eax); 1924 m_jit.pushl_r(X86::eax); 1925 m_jit.movl_i32r(reinterpret_cast<uint32_t>(newStructureID), X86::eax); 1926 m_jit.pushl_r(X86::eax); 1927 callTarget = m_jit.emitCall(); 1928 m_jit.addl_i32r(4 * sizeof(void*), X86::esp); 1929 } 1930 m_jit.ret(); 1931 void* code = m_jit.copy(); 1932 ASSERT(code); 1933 1934 for (unsigned i = 0; i < failureCases.size(); ++i) 1935 X86Assembler::link(code, failureCases[i], reinterpret_cast<void*>(Machine::cti_op_put_by_id_fail)); 1936 1937 if (transitionWillNeedStorageRealloc(oldStructureID, newStructureID)) 1938 X86Assembler::link(code, callTarget, reinterpret_cast<void*>(transitionObject)); 1939 1940 m_codeBlock->structureIDAccessStubs.append(code); 1941 1942 return code; 1943 } 1944 1837 1945 void* CTI::privateArrayLengthTrampoline() 1838 1946 {
Note:
See TracChangeset
for help on using the changeset viewer.