Changeset 36325 in webkit for trunk/JavaScriptCore
- Timestamp:
- Sep 10, 2008, 7:42:18 PM (17 years ago)
- Location:
- trunk/JavaScriptCore
- Files:
-
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/ChangeLog
r36324 r36325 1 2008-09-10 Sam Weinig <[email protected]> 2 3 Reviewed by Geoff Garen. 4 5 Add inline property storage for JSObject. 6 7 1.2% progression on Sunspider. .5% progression on the v8 test suite. 8 9 * JavaScriptCore.exp: 10 * VM/CTI.cpp: 11 (JSC::CTI::privateCompileGetByIdProto): 12 (JSC::CTI::privateCompileGetByIdChain): 13 * kjs/JSObject.cpp: 14 (JSC::JSObject::mark): There is no reason to check storageSize now that 15 we start from 0. 16 (JSC::JSObject::allocatePropertyStorage): Allocates/reallocates heap storage. 17 * kjs/JSObject.h: 18 (JSC::JSObject::offsetForLocation): m_propertyStorage is not an OwnArrayPtr 19 now so there is no reason to .get() 20 (JSC::JSObject::usingInlineStorage): 21 (JSC::JSObject::JSObject): Start with m_propertyStorage pointing to the 22 inline storage. 23 (JSC::JSObject::~JSObject): Free the heap storage if not using the inline 24 storage. 25 (JSC::JSObject::putDirect): Switch to the heap storage only when we know 26 we know that we are about to add a property that will overflow the inline 27 storage. 28 * kjs/PropertyMap.cpp: 29 (JSC::PropertyMap::createTable): Don't allocate the propertyStorage, that is 30 now handled by JSObject. 31 (JSC::PropertyMap::rehash): PropertyStorage is not a OwnArrayPtr anymore. 32 * kjs/PropertyMap.h: 33 (JSC::PropertyMap::storageSize): Rename from markingCount. 34 * kjs/StructureID.cpp: 35 (JSC::StructureID::addPropertyTransition): Don't resize the property storage 36 if we are using inline storage. 37 * kjs/StructureID.h: 38 1 39 2008-09-10 Oliver Hunt <[email protected]> 2 40 -
trunk/JavaScriptCore/JavaScriptCore.exp
r36314 r36325 104 104 __ZN3JSC11ProfileNode4sortEPFbRKN3WTF6RefPtrIS0_EES5_E 105 105 __ZN3JSC11ProgramNode6createEPNS_12JSGlobalDataEPNS_14SourceElementsEPN3WTF6VectorISt4pairINS_10IdentifierEjELm16EEEPNS6_INS5_6RefPtrINS_12FuncDeclNodeEEELm16EEEPNS_14SourceProviderEbbi 106 __ZN3JSC11PropertyMap3putERKNS_10IdentifierEPNS_7JSValueEjbPNS_8JSObjectERNS_15PutPropertySlotER N3WTF11OwnArrayPtrIS5_EE106 __ZN3JSC11PropertyMap3putERKNS_10IdentifierEPNS_7JSValueEjbPNS_8JSObjectERNS_15PutPropertySlotERPS5_ 107 107 __ZN3JSC11PropertyMap9getOffsetERKNS_10IdentifierE 108 108 __ZN3JSC11PropertyMap9getOffsetERKNS_10IdentifierERj 109 109 __ZN3JSC11PropertyMapD1Ev 110 __ZN3JSC11StructureID21addPropertyTransitionEPS0_RKNS_10IdentifierEPNS_7JSValueEj bPNS_8JSObjectERNS_15PutPropertySlotERN3WTF11OwnArrayPtrIS6_EE110 __ZN3JSC11StructureID21addPropertyTransitionEPS0_RKNS_10IdentifierEPNS_7JSValueEjPNS_8JSObjectERNS_15PutPropertySlotERPS6_ 111 111 __ZN3JSC11StructureID24fromDictionaryTransitionEPS0_ 112 112 __ZN3JSC11StructureID25changePrototypeTransitionEPS0_PNS_7JSValueE … … 232 232 __ZN3JSC8JSObject18getPrimitiveNumberEPNS_9ExecStateERdRPNS_7JSValueE 233 233 __ZN3JSC8JSObject22fillGetterPropertySlotERNS_12PropertySlotEPPNS_7JSValueE 234 __ZN3JSC8JSObject23allocatePropertyStorageEmm 234 235 __ZN3JSC8JSObject3putEPNS_9ExecStateERKNS_10IdentifierEPNS_7JSValueERNS_15PutPropertySlotE 235 236 __ZN3JSC8JSObject3putEPNS_9ExecStateEjPNS_7JSValueE -
trunk/JavaScriptCore/VM/CTI.cpp
r36324 r36325 1738 1738 // referencing the prototype object - let's speculatively load it's table nice and early!) 1739 1739 JSObject* protoObject = static_cast<JSObject*>(structureID->prototypeForLookup(exec)); 1740 OwnArrayPtr<JSValue*>* protoPropertyStorage = &protoObject->m_propertyStorage;1740 PropertyStorage* protoPropertyStorage = &protoObject->m_propertyStorage; 1741 1741 m_jit.movl_mr(static_cast<void*>(protoPropertyStorage), X86::edx); 1742 1742 … … 1783 1783 StructureID* currStructureID = structureID; 1784 1784 RefPtr<StructureID>* chainEntries = chain->head(); 1785 JS Cell* protoObject = 0;1785 JSObject* protoObject = 0; 1786 1786 for (unsigned i = 0; i<count; ++i) { 1787 protoObject = static_cast<JS Cell*>(currStructureID->prototypeForLookup(exec));1787 protoObject = static_cast<JSObject*>(currStructureID->prototypeForLookup(exec)); 1788 1788 currStructureID = chainEntries[i].get(); 1789 1789 … … 1794 1794 } 1795 1795 ASSERT(protoObject); 1796 1797 OwnArrayPtr<JSValue*>* protoPropertyStorage = &static_cast<JSObject*>(protoObject)->m_propertyStorage;1796 1797 PropertyStorage* protoPropertyStorage = &protoObject->m_propertyStorage; 1798 1798 m_jit.movl_mr(static_cast<void*>(protoPropertyStorage), X86::edx); 1799 1799 m_jit.movl_mr(cachedOffset * sizeof(JSValue*), X86::edx, X86::eax); -
trunk/JavaScriptCore/kjs/JSObject.cpp
r36310 r36325 71 71 m_structureID->mark(); 72 72 73 unsigned storageSize = m_structureID->propertyMap().markingCount(); 74 if (storageSize) { 75 for (unsigned i = 0; i < storageSize; ++i) { 76 JSValue* v = m_propertyStorage[i]; 77 if (!v->marked()) 78 v->mark(); 79 } 73 unsigned storageSize = m_structureID->propertyMap().storageSize(); 74 for (unsigned i = 0; i < storageSize; ++i) { 75 JSValue* v = m_propertyStorage[i]; 76 if (!v->marked()) 77 v->mark(); 80 78 } 81 79 … … 529 527 } 530 528 529 void JSObject::allocatePropertyStorage(size_t oldSize, size_t newSize) 530 { 531 JSValue** oldPropertStorage = m_propertyStorage; 532 m_propertyStorage = new JSValue*[newSize]; 533 534 for (unsigned i = 0; i < oldSize; ++i) 535 m_propertyStorage[i] = oldPropertStorage[i]; 536 537 if (oldPropertStorage != m_inlineStorage) 538 delete oldPropertStorage; 539 } 540 531 541 JSObject* constructEmptyObject(ExecState* exec) 532 542 { -
trunk/JavaScriptCore/kjs/JSObject.h
r36316 r36325 143 143 size_t offsetForLocation(JSValue** location) 144 144 { 145 return location - m_propertyStorage .get();145 return location - m_propertyStorage; 146 146 } 147 147 … … 176 176 virtual bool isNotAnObjectErrorStub() const { return false; } 177 177 178 void allocatePropertyStorage(size_t oldSize, size_t newSize); 179 bool usingInlineStorage() const { return m_propertyStorage == m_inlineStorage; } 180 178 181 protected: 179 182 bool getOwnPropertySlotForWrite(ExecState*, const Identifier&, PropertySlot&, bool& slotIsWriteable); … … 185 188 StructureID* createInheritorID(); 186 189 187 PropertyStorage m_propertyStorage; 190 static const size_t inlineStorageCapacity = 2; 191 188 192 RefPtr<StructureID> m_inheritorID; 193 194 PropertyStorage m_propertyStorage; 195 JSValue* m_inlineStorage[inlineStorageCapacity]; 189 196 }; 190 197 … … 193 200 inline JSObject::JSObject(JSObject* prototype) 194 201 : JSCell(prototype->inheritorID()) 202 , m_propertyStorage(m_inlineStorage) 195 203 { 196 204 ASSERT(m_structureID); … … 202 210 inline JSObject::JSObject(PassRefPtr<StructureID> structureID) 203 211 : JSCell(structureID.releaseRef()) // ~JSObject balances this ref() 212 , m_propertyStorage(m_inlineStorage) 204 213 { 205 214 ASSERT(m_structureID); … … 209 218 { 210 219 ASSERT(m_structureID); 220 if (m_propertyStorage != m_inlineStorage) 221 delete [] m_propertyStorage; 211 222 m_structureID->deref(); 212 223 } … … 365 376 366 377 if (m_structureID->isDictionary()) { 378 unsigned currentAttributes; 379 size_t offset = m_structureID->propertyMap().getOffset(propertyName, currentAttributes); 380 if (offset != WTF::notFound) { 381 if (checkReadOnly && currentAttributes & ReadOnly) 382 return; 383 m_propertyStorage[offset] = value; 384 slot.setExistingProperty(this, offset); 385 return; 386 } 387 388 if (m_structureID->propertyMap().storageSize() == inlineStorageCapacity) 389 allocatePropertyStorage(m_structureID->propertyMap().storageSize(), m_structureID->propertyMap().size()); 367 390 m_structureID->propertyMap().put(propertyName, value, attributes, checkReadOnly, this, slot, m_propertyStorage); 368 391 return; … … 379 402 } 380 403 381 RefPtr<StructureID> structureID = StructureID::addPropertyTransition(m_structureID, propertyName, value, attributes, checkReadOnly, this, slot, m_propertyStorage); 404 if (m_structureID->propertyMap().storageSize() == inlineStorageCapacity) 405 allocatePropertyStorage(m_structureID->propertyMap().storageSize(), m_structureID->propertyMap().size()); 406 407 RefPtr<StructureID> structureID = StructureID::addPropertyTransition(m_structureID, propertyName, value, attributes, this, slot, m_propertyStorage); 382 408 setStructureID(structureID.release()); 383 409 } -
trunk/JavaScriptCore/kjs/PropertyMap.cpp
r36314 r36325 429 429 m_table->sizeMask = newTableSize - 1; 430 430 431 propertyStorage.set(new JSValue*[m_table->size]);432 433 431 checkConsistency(propertyStorage); 434 432 } … … 441 439 442 440 Table* oldTable = m_table; 443 JSValue** oldPropertStorage = propertyStorage .release();441 JSValue** oldPropertStorage = propertyStorage; 444 442 445 443 m_table = static_cast<Table*>(fastZeroedMalloc(Table::allocationSize(newTableSize))); … … 447 445 m_table->sizeMask = newTableSize - 1; 448 446 449 propertyStorage .set(new JSValue*[m_table->size]);447 propertyStorage = new JSValue*[m_table->size]; 450 448 451 449 unsigned lastIndexUsed = 0; … … 461 459 fastFree(oldTable); 462 460 delete [] oldPropertStorage; 463 464 checkConsistency(propertyStorage);465 }466 467 void PropertyMap::resizePropertyStorage(PropertyStorage& propertyStorage, unsigned oldSize)468 {469 ASSERT(m_table);470 471 if (propertyStorage) {472 JSValue** oldPropertStorage = propertyStorage.release();473 propertyStorage.set(new JSValue*[m_table->size]);474 475 // FIXME: this can probalby use memcpy476 for (unsigned i = 0; i < oldSize; ++i)477 propertyStorage[i] = oldPropertStorage[i];478 479 delete [] oldPropertStorage;480 } else481 propertyStorage.set(new JSValue*[m_table->size]);482 461 483 462 checkConsistency(propertyStorage); -
trunk/JavaScriptCore/kjs/PropertyMap.h
r36314 r36325 33 33 class PropertyNameArray; 34 34 35 typedef OwnArrayPtr<JSValue*>PropertyStorage;35 typedef JSValue** PropertyStorage; 36 36 37 37 struct PropertyMapEntry { … … 101 101 102 102 unsigned size() const { return m_table ? m_table->size : 0; } 103 unsigned markingCount() const { return m_table ? m_table->keyCount + m_table->deletedSentinelCount : 0; } 104 105 void resizePropertyStorage(PropertyStorage&, unsigned oldSize); 103 unsigned storageSize() const { return m_table ? m_table->keyCount + m_table->deletedSentinelCount : 0; } 106 104 107 105 private: -
trunk/JavaScriptCore/kjs/StructureID.cpp
r36316 r36325 48 48 } 49 49 50 PassRefPtr<StructureID> StructureID::addPropertyTransition(StructureID* structureID, const Identifier& propertyName, JSValue* value, unsigned attributes, bool checkReadOnly,JSObject* slotBase, PutPropertySlot& slot, PropertyStorage& propertyStorage)50 PassRefPtr<StructureID> StructureID::addPropertyTransition(StructureID* structureID, const Identifier& propertyName, JSValue* value, unsigned attributes, JSObject* slotBase, PutPropertySlot& slot, PropertyStorage& propertyStorage) 51 51 { 52 52 ASSERT(!structureID->m_isDictionary); … … 54 54 55 55 if (StructureID* existingTransition = structureID->m_transitionTable.get(make_pair(propertyName.ustring().rep(), attributes))) { 56 if ( structureID->m_propertyMap.size() != existingTransition->m_propertyMap.size())57 existingTransition->m_propertyMap.resizePropertyStorage(propertyStorage, structureID->m_propertyMap.size());56 if (!slotBase->usingInlineStorage() && structureID->m_propertyMap.size() != existingTransition->m_propertyMap.size()) 57 slotBase->allocatePropertyStorage(structureID->m_propertyMap.size(), existingTransition->m_propertyMap.size()); 58 58 59 59 size_t offset = existingTransition->propertyMap().getOffset(propertyName); 60 60 ASSERT(offset != WTF::notFound); 61 61 propertyStorage[offset] = value; 62 slot.set ExistingProperty(slotBase, offset);62 slot.setNewProperty(slotBase, offset); 63 63 64 64 return existingTransition; … … 67 67 if (structureID->m_transitionCount > s_maxTransitionLength) { 68 68 RefPtr<StructureID> transition = toDictionaryTransition(structureID); 69 transition->m_propertyMap.put(propertyName, value, attributes, checkReadOnly, slotBase, slot, propertyStorage);69 transition->m_propertyMap.put(propertyName, value, attributes, false, slotBase, slot, propertyStorage); 70 70 return transition.release(); 71 71 } … … 79 79 transition->m_propertyMap = structureID->m_propertyMap; 80 80 81 transition->m_propertyMap.put(propertyName, value, attributes, checkReadOnly, slotBase, slot, propertyStorage);81 transition->m_propertyMap.put(propertyName, value, attributes, false, slotBase, slot, propertyStorage); 82 82 83 83 structureID->m_transitionTable.add(make_pair(propertyName.ustring().rep(), attributes), transition.get()); -
trunk/JavaScriptCore/kjs/StructureID.h
r36316 r36325 79 79 80 80 static PassRefPtr<StructureID> changePrototypeTransition(StructureID*, JSValue* prototype); 81 static PassRefPtr<StructureID> addPropertyTransition(StructureID*, const Identifier& propertyName, JSValue*, unsigned attributes, bool checkReadOnly,JSObject* slotBase, PutPropertySlot&, PropertyStorage&);81 static PassRefPtr<StructureID> addPropertyTransition(StructureID*, const Identifier& propertyName, JSValue*, unsigned attributes, JSObject* slotBase, PutPropertySlot&, PropertyStorage&); 82 82 static PassRefPtr<StructureID> getterSetterTransition(StructureID*); 83 83 static PassRefPtr<StructureID> toDictionaryTransition(StructureID*);
Note:
See TracChangeset
for help on using the changeset viewer.