Changeset 37388 in webkit for trunk/JavaScriptCore
- Timestamp:
- Oct 7, 2008, 1:49:36 PM (17 years ago)
- Location:
- trunk/JavaScriptCore
- Files:
-
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/ChangeLog
r37386 r37388 1 2008-10-07 Sam Weinig <[email protected]> 2 3 Reviewed by Cameron Zwarich. 4 5 Roll r37370 back in with bug fixes. 6 7 - PropertyMap::storageSize() should reflect the number of keys + deletedOffsets 8 and has nothing to do with the internal deletedSentinel count anymore. 9 1 10 2008-10-07 Gavin Barraclough <[email protected]> 2 11 -
trunk/JavaScriptCore/JavaScriptCore.exp
r37381 r37388 109 109 __ZN3JSC11ProfileNode4sortEPFbRKN3WTF6RefPtrIS0_EES5_E 110 110 __ZN3JSC11ProgramNode6createEPNS_12JSGlobalDataEPNS_14SourceElementsEPN3WTF6VectorISt4pairINS_10IdentifierEjELm16EEEPNS6_INS5_6RefPtrINS_12FuncDeclNodeEEELm16EEERKNS_10SourceCodeEji 111 __ZN3JSC11PropertyMap3 putERKNS_10IdentifierEPNS_7JSValueEjbPNS_8JSObjectERNS_15PutPropertySlotERPS5_112 __ZN3JSC11PropertyMap 9getOffsetERKNS_10IdentifierERj111 __ZN3JSC11PropertyMap3getERKNS_10IdentifierERj 112 __ZN3JSC11PropertyMap3putERKNS_10IdentifierEj 113 113 __ZN3JSC11PropertyMapD1Ev 114 __ZN3JSC11StructureID21addPropertyTransitionEPS0_RKNS_10IdentifierE PNS_7JSValueEjPNS_8JSObjectERNS_15PutPropertySlotERPS6_114 __ZN3JSC11StructureID21addPropertyTransitionEPS0_RKNS_10IdentifierEjRm 115 115 __ZN3JSC11StructureID21clearEnumerationCacheEv 116 116 __ZN3JSC11StructureID24fromDictionaryTransitionEPS0_ 117 117 __ZN3JSC11StructureID25changePrototypeTransitionEPS0_PNS_7JSValueE 118 __ZN3JSC11StructureID27growPropertyStorageCapacityEv 118 119 __ZN3JSC11StructureIDC1EPNS_7JSValueERKNS_8TypeInfoE 119 120 __ZN3JSC11StructureIDD1Ev -
trunk/JavaScriptCore/VM/CTI.cpp
r37386 r37388 2778 2778 static JSValue* SFX_CALL transitionObject(StructureID* newStructureID, size_t cachedOffset, JSObject* baseObject, JSValue* value) 2779 2779 { 2780 StructureID* oldStructureID = newStructureID->previousID();2781 2782 2780 baseObject->transitionTo(newStructureID); 2783 2784 if (oldStructureID->propertyMap().storageSize() == JSObject::inlineStorageCapacity)2785 baseObject->allocatePropertyStorage(oldStructureID->propertyMap().storageSize(), oldStructureID->propertyMap().size());2786 2787 2781 baseObject->putDirectOffset(cachedOffset, value); 2788 2782 return baseObject; … … 2793 2787 static inline bool transitionWillNeedStorageRealloc(StructureID* oldStructureID, StructureID* newStructureID) 2794 2788 { 2795 if (oldStructureID->propertyMap().storageSize() == JSObject::inlineStorageCapacity) 2796 return true; 2797 2798 if (oldStructureID->propertyMap().storageSize() < JSObject::inlineStorageCapacity) 2799 return false; 2800 2801 if (oldStructureID->propertyMap().size() != newStructureID->propertyMap().size()) 2802 return true; 2803 2804 return false; 2789 return oldStructureID->propertyStorageCapacity() != newStructureID->propertyStorageCapacity(); 2805 2790 } 2806 2791 -
trunk/JavaScriptCore/VM/Machine.cpp
r37386 r37388 2722 2722 2723 2723 baseObject->transitionTo(newStructureID); 2724 if (oldStructureID->propertyMap().storageSize() == JSObject::inlineStorageCapacity)2725 baseObject->allocatePropertyStorage(oldStructureID->propertyMap().storageSize(), oldStructureID->propertyMap().size());2726 2724 2727 2725 int value = vPC[3].u.operand; -
trunk/JavaScriptCore/kjs/JSObject.cpp
r37381 r37388 135 135 136 136 unsigned attributes; 137 if ((m_structureID->propertyMap().get Offset(propertyName, attributes) != WTF::notFound) && attributes & ReadOnly)137 if ((m_structureID->propertyMap().get(propertyName, attributes) != WTF::notFound) && attributes & ReadOnly) 138 138 return; 139 139 … … 201 201 { 202 202 unsigned attributes; 203 if (m_structureID->propertyMap().get Offset(propertyName, attributes) != WTF::notFound) {203 if (m_structureID->propertyMap().get(propertyName, attributes) != WTF::notFound) { 204 204 if ((attributes & DontDelete)) 205 205 return false; … … 413 413 bool JSObject::getPropertyAttributes(ExecState* exec, const Identifier& propertyName, unsigned& attributes) const 414 414 { 415 if (m_structureID->propertyMap().get Offset(propertyName, attributes) != WTF::notFound)415 if (m_structureID->propertyMap().get(propertyName, attributes) != WTF::notFound) 416 416 return true; 417 417 … … 469 469 void JSObject::removeDirect(const Identifier& propertyName) 470 470 { 471 size_t offset; 471 472 if (m_structureID->isDictionary()) { 472 m_structureID->propertyMap().remove(propertyName, m_propertyStorage); 473 m_structureID->clearEnumerationCache(); 473 offset = m_structureID->propertyMap().remove(propertyName); 474 if (offset != WTF::notFound) { 475 m_propertyStorage[offset] = jsUndefined(); 476 m_structureID->clearEnumerationCache(); 477 } 474 478 return; 475 479 } 476 480 477 481 RefPtr<StructureID> structureID = StructureID::toDictionaryTransition(m_structureID); 478 structureID->propertyMap().remove(propertyName, m_propertyStorage); 482 offset = structureID->propertyMap().remove(propertyName); 483 if (offset != WTF::notFound) 484 m_propertyStorage[offset] = jsUndefined(); 479 485 setStructureID(structureID.release()); 480 486 } … … 501 507 void JSObject::allocatePropertyStorage(size_t oldSize, size_t newSize) 502 508 { 509 ASSERT(newSize > oldSize); 510 503 511 JSValue** oldPropertStorage = m_propertyStorage; 504 512 m_propertyStorage = new JSValue*[newSize]; -
trunk/JavaScriptCore/kjs/JSObject.h
r37381 r37388 123 123 JSValue* getDirect(const Identifier& propertyName) const 124 124 { 125 size_t offset = m_structureID->propertyMap().get Offset(propertyName);125 size_t offset = m_structureID->propertyMap().get(propertyName); 126 126 return offset != WTF::notFound ? m_propertyStorage[offset] : 0; 127 127 } … … 129 129 JSValue** getDirectLocation(const Identifier& propertyName) 130 130 { 131 size_t offset = m_structureID->propertyMap().get Offset(propertyName);131 size_t offset = m_structureID->propertyMap().get(propertyName); 132 132 return offset != WTF::notFound ? locationForOffset(offset) : 0; 133 133 } … … 135 135 JSValue** getDirectLocation(const Identifier& propertyName, unsigned& attributes) 136 136 { 137 size_t offset = m_structureID->propertyMap().get Offset(propertyName, attributes);137 size_t offset = m_structureID->propertyMap().get(propertyName, attributes); 138 138 return offset != WTF::notFound ? locationForOffset(offset) : 0; 139 139 } … … 179 179 180 180 static const size_t inlineStorageCapacity = 2; 181 static const size_t nonInlineBaseStorageCapacity = 16; 181 182 182 183 static PassRefPtr<StructureID> createStructureID(JSValue* proto) { return StructureID::create(proto, TypeInfo(ObjectType)); } … … 365 366 ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this)); 366 367 367 if (m_structureID->isDictionary()) { 368 unsigned currentAttributes; 369 size_t offset = m_structureID->propertyMap().getOffset(propertyName, currentAttributes); 370 if (offset != WTF::notFound) { 371 if (checkReadOnly && currentAttributes & ReadOnly) 372 return; 373 m_propertyStorage[offset] = value; 374 slot.setExistingProperty(this, offset); 375 return; 376 } 377 378 if (m_structureID->propertyMap().storageSize() == inlineStorageCapacity) 379 allocatePropertyStorage(m_structureID->propertyMap().storageSize(), m_structureID->propertyMap().size()); 380 m_structureID->propertyMap().put(propertyName, value, attributes, checkReadOnly, this, slot, m_propertyStorage); 381 m_structureID->clearEnumerationCache(); 382 return; 383 } 368 if (m_structureID->isDictionary()) { 369 unsigned currentAttributes; 370 size_t offset = m_structureID->propertyMap().get(propertyName, currentAttributes); 371 if (offset != WTF::notFound) { 372 if (checkReadOnly && currentAttributes & ReadOnly) 373 return; 374 m_propertyStorage[offset] = value; 375 slot.setExistingProperty(this, offset); 376 return; 377 } 378 379 size_t currentCapacity = m_structureID->propertyStorageCapacity(); 380 offset = m_structureID->propertyMap().put(propertyName, attributes); 381 if (m_structureID->propertyMap().storageSize() > m_structureID->propertyStorageCapacity()) { 382 m_structureID->growPropertyStorageCapacity(); 383 allocatePropertyStorage(currentCapacity, m_structureID->propertyStorageCapacity()); 384 } 385 386 m_propertyStorage[offset] = value; 387 slot.setNewProperty(this, offset); 388 m_structureID->clearEnumerationCache(); 389 return; 390 } 384 391 385 392 unsigned currentAttributes; 386 size_t offset = m_structureID->propertyMap().get Offset(propertyName, currentAttributes);393 size_t offset = m_structureID->propertyMap().get(propertyName, currentAttributes); 387 394 if (offset != WTF::notFound) { 388 395 if (checkReadOnly && currentAttributes & ReadOnly) … … 393 400 } 394 401 395 if (m_structureID->propertyMap().storageSize() == inlineStorageCapacity) 396 allocatePropertyStorage(m_structureID->propertyMap().storageSize(), m_structureID->propertyMap().size()); 397 398 RefPtr<StructureID> structureID = StructureID::addPropertyTransition(m_structureID, propertyName, value, attributes, this, slot, m_propertyStorage); 399 slot.setWasTransition(true); 400 setStructureID(structureID.release()); 402 size_t currentCapacity = m_structureID->propertyStorageCapacity(); 403 RefPtr<StructureID> structureID = StructureID::addPropertyTransition(m_structureID, propertyName, attributes, offset); 404 if (currentCapacity != structureID->propertyStorageCapacity()) 405 allocatePropertyStorage(currentCapacity, structureID->propertyStorageCapacity()); 406 407 ASSERT(offset < structureID->propertyStorageCapacity()); 408 m_propertyStorage[offset] = value; 409 slot.setNewProperty(this, offset); 410 slot.setWasTransition(true); 411 setStructureID(structureID.release()); 401 412 } 402 413 403 414 inline void JSObject::transitionTo(StructureID* newStructureID) 404 415 { 405 StructureID::transitionTo(m_structureID, newStructureID, this); 416 if (m_structureID->propertyStorageCapacity() != newStructureID->propertyStorageCapacity()) 417 allocatePropertyStorage(m_structureID->propertyStorageCapacity(), newStructureID->propertyStorageCapacity()); 406 418 setStructureID(newStructureID); 407 419 } -
trunk/JavaScriptCore/kjs/PropertyMap.cpp
r37381 r37388 78 78 #if !DO_PROPERTYMAP_CONSTENCY_CHECK 79 79 80 inline void PropertyMap::checkConsistency( PropertyStorage&)80 inline void PropertyMap::checkConsistency() 81 81 { 82 82 } … … 98 98 } 99 99 100 m_deletedOffsets = other.m_deletedOffsets; 100 101 m_getterSetterFlag = other.m_getterSetterFlag; 101 102 return *this; … … 115 116 } 116 117 117 size_t PropertyMap::put(const Identifier& propertyName, JSValue* value, unsigned attributes, bool checkReadOnly, JSObject* slotBase, PutPropertySlot& slot, PropertyStorage& propertyStorage)118 size_t PropertyMap::put(const Identifier& propertyName, unsigned attributes) 118 119 { 119 120 ASSERT(!propertyName.isNull()); 120 ASSERT( value);121 122 checkConsistency( propertyStorage);121 ASSERT(get(propertyName) == WTF::notFound); 122 123 checkConsistency(); 123 124 124 125 UString::Rep* rep = propertyName._ustring.rep(); 125 126 126 127 if (!m_table) 127 expand(propertyStorage);128 createTable(); 128 129 129 130 // FIXME: Consider a fast case for tables with no deleted sentinels. … … 143 144 break; 144 145 145 if (m_table->entries()[entryIndex - 1].key == rep) { 146 if (checkReadOnly && (m_table->entries()[entryIndex - 1].attributes & ReadOnly)) 147 return WTF::notFound; 148 // Put a new value in an existing hash table entry. 149 propertyStorage[entryIndex - 2] = value; 150 // Attributes are intentionally not updated. 151 slot.setExistingProperty(slotBase, entryIndex - 2); 152 return entryIndex - 2; 153 } else if (entryIndex == deletedSentinelIndex) { 146 if (entryIndex == deletedSentinelIndex) { 154 147 // If we find a deleted-element sentinel, remember it for use later. 155 148 if (!foundDeletedElement) { … … 194 187 m_table->entries()[entryIndex - 1].attributes = attributes; 195 188 m_table->entries()[entryIndex - 1].index = ++m_table->lastIndexUsed; 189 190 unsigned newOffset; 191 if (!m_deletedOffsets.isEmpty()) { 192 newOffset = m_deletedOffsets.last(); 193 m_deletedOffsets.removeLast(); 194 } else 195 newOffset = m_table->keyCount; 196 m_table->entries()[entryIndex - 1].offset = newOffset; 197 196 198 ++m_table->keyCount; 197 199 198 propertyStorage[entryIndex - 2] = value;199 200 200 if ((m_table->keyCount + m_table->deletedSentinelCount) * 2 >= m_table->size) 201 expand(propertyStorage); 202 203 checkConsistency(propertyStorage); 204 slot.setNewProperty(slotBase, entryIndex - 2); 205 return entryIndex - 2; 206 } 207 208 void PropertyMap::remove(const Identifier& propertyName, PropertyStorage& propertyStorage) 201 expand(); 202 203 checkConsistency(); 204 return newOffset; 205 } 206 207 size_t PropertyMap::remove(const Identifier& propertyName) 209 208 { 210 209 ASSERT(!propertyName.isNull()); 211 210 212 checkConsistency( propertyStorage);211 checkConsistency(); 213 212 214 213 UString::Rep* rep = propertyName._ustring.rep(); 215 214 216 215 if (!m_table) 217 return ;216 return WTF::notFound; 218 217 219 218 #if DUMP_PROPERTYMAP_STATS … … 230 229 entryIndex = m_table->entryIndices[i & m_table->sizeMask]; 231 230 if (entryIndex == emptyEntryIndex) 232 return ;231 return WTF::notFound; 233 232 234 233 key = m_table->entries()[entryIndex - 1].key; … … 253 252 // the entry so we can iterate all the entries as needed. 254 253 m_table->entryIndices[i & m_table->sizeMask] = deletedSentinelIndex; 254 255 size_t offset = m_table->entries()[entryIndex - 1].offset; 256 255 257 key->deref(); 256 258 m_table->entries()[entryIndex - 1].key = 0; 257 259 m_table->entries()[entryIndex - 1].attributes = 0; 258 259 propertyStorage[entryIndex - 2] = jsUndefined();260 m_table->entries()[entryIndex - 1].offset = 0; 261 m_deletedOffsets.append(offset); 260 262 261 263 ASSERT(m_table->keyCount >= 1); … … 264 266 265 267 if (m_table->deletedSentinelCount * 4 >= m_table->size) 266 rehash(propertyStorage); 267 268 checkConsistency(propertyStorage); 269 } 270 271 size_t PropertyMap::getOffset(const Identifier& propertyName, unsigned& attributes) 268 rehash(); 269 270 checkConsistency(); 271 return offset; 272 } 273 274 size_t PropertyMap::get(const Identifier& propertyName, unsigned& attributes) 272 275 { 273 276 ASSERT(!propertyName.isNull()); … … 290 293 if (rep == m_table->entries()[entryIndex - 1].key) { 291 294 attributes = m_table->entries()[entryIndex - 1].attributes; 292 return entryIndex - 2;295 return m_table->entries()[entryIndex - 1].offset; 293 296 } 294 297 … … 312 315 if (rep == m_table->entries()[entryIndex - 1].key) { 313 316 attributes = m_table->entries()[entryIndex - 1].attributes; 314 return entryIndex - 2;315 } 316 } 317 } 318 319 void PropertyMap::insert(const Entry& entry , JSValue* value, PropertyStorage& propertyStorage)317 return m_table->entries()[entryIndex - 1].offset; 318 } 319 } 320 } 321 322 void PropertyMap::insert(const Entry& entry) 320 323 { 321 324 ASSERT(m_table); … … 351 354 m_table->entries()[entryIndex - 1] = entry; 352 355 353 propertyStorage[entryIndex - 2] = value;354 355 356 ++m_table->keyCount; 356 357 } 357 358 358 void PropertyMap::expand(PropertyStorage& propertyStorage) 359 { 360 if (!m_table) 361 createTable(propertyStorage); 362 else 363 rehash(m_table->size * 2, propertyStorage); 364 } 365 366 void PropertyMap::rehash(PropertyStorage& propertyStorage) 359 void PropertyMap::expand() 367 360 { 368 361 ASSERT(m_table); 369 ASSERT(m_table->size); 370 rehash(m_table->size, propertyStorage); 371 } 372 373 void PropertyMap::createTable(PropertyStorage& propertyStorage) 362 rehash(m_table->size * 2); 363 } 364 365 void PropertyMap::createTable() 374 366 { 375 367 const unsigned newTableSize = 16; … … 377 369 ASSERT(!m_table); 378 370 379 checkConsistency( propertyStorage);371 checkConsistency(); 380 372 381 373 m_table = static_cast<Table*>(fastZeroedMalloc(Table::allocationSize(newTableSize))); … … 383 375 m_table->sizeMask = newTableSize - 1; 384 376 385 checkConsistency( propertyStorage);386 } 387 388 void PropertyMap::rehash( unsigned newTableSize, PropertyStorage& propertyStorage)377 checkConsistency(); 378 } 379 380 void PropertyMap::rehash() 389 381 { 390 382 ASSERT(m_table); 391 392 checkConsistency(propertyStorage); 383 ASSERT(m_table->size); 384 rehash(m_table->size); 385 } 386 387 void PropertyMap::rehash(unsigned newTableSize) 388 { 389 ASSERT(m_table); 390 391 checkConsistency(); 393 392 394 393 Table* oldTable = m_table; 395 JSValue** oldPropertStorage = propertyStorage;396 394 397 395 m_table = static_cast<Table*>(fastZeroedMalloc(Table::allocationSize(newTableSize))); 398 396 m_table->size = newTableSize; 399 397 m_table->sizeMask = newTableSize - 1; 400 401 propertyStorage = new JSValue*[m_table->size];402 398 403 399 unsigned lastIndexUsed = 0; … … 406 402 if (oldTable->entries()[i].key) { 407 403 lastIndexUsed = max(oldTable->entries()[i].index, lastIndexUsed); 408 insert(oldTable->entries()[i] , oldPropertStorage[i - 1], propertyStorage);404 insert(oldTable->entries()[i]); 409 405 } 410 406 } … … 412 408 413 409 fastFree(oldTable); 414 delete [] oldPropertStorage; 415 416 checkConsistency(propertyStorage); 410 411 checkConsistency(); 417 412 } 418 413 … … 486 481 #if DO_PROPERTYMAP_CONSTENCY_CHECK 487 482 488 void PropertyMap::checkConsistency( PropertyStorage& propertyStorage)483 void PropertyMap::checkConsistency() 489 484 { 490 485 if (!m_table) … … 526 521 for (unsigned c = 1; c <= m_table->keyCount + m_table->deletedSentinelCount; ++c) { 527 522 UString::Rep* rep = m_table->entries()[c].key; 528 if (!rep) { 529 ASSERT(propertyStorage[c - 1]->isUndefined()); 523 if (!rep) 530 524 continue; 531 }532 525 ++nonEmptyEntryCount; 533 526 unsigned i = rep->computedHash(); -
trunk/JavaScriptCore/kjs/PropertyMap.h
r37381 r37388 43 43 struct PropertyMapEntry { 44 44 UString::Rep* key; 45 unsigned offset; 45 46 unsigned attributes; 46 47 unsigned index; … … 48 49 PropertyMapEntry(UString::Rep* k, int a) 49 50 : key(k) 51 , offset(0) 50 52 , attributes(a) 51 53 , index(0) … … 93 95 PropertyMap& operator=(const PropertyMap&); 94 96 95 bool isEmpty() { return !m_table; }96 97 97 size_t put(const Identifier& propertyName, JSValue*, unsigned attributes, bool checkReadOnly, JSObject* slotBase, PutPropertySlot&, PropertyStorage&); 98 void remove(const Identifier& propertyName, PropertyStorage&); 99 100 size_t getOffset(const Identifier& propertyName); 101 size_t getOffset(const Identifier& propertyName, unsigned& attributes); 98 size_t get(const Identifier& propertyName); 99 size_t get(const Identifier& propertyName, unsigned& attributes); 100 size_t put(const Identifier& propertyName, unsigned attributes); 101 size_t remove(const Identifier& propertyName); 102 102 103 103 void getEnumerablePropertyNames(PropertyNameArray&) const; … … 106 106 void setHasGetterSetterProperties(bool f) { m_getterSetterFlag = f; } 107 107 108 unsigned size() const { return m_table ? m_table->size : 0; }109 unsigned storageSize() const { return m_table ? m_table->keyCount + m_ table->deletedSentinelCount: 0; }108 bool isEmpty() { return !m_table; } 109 unsigned storageSize() const { return m_table ? m_table->keyCount + m_deletedOffsets.size() : 0; } 110 110 111 111 static const unsigned emptyEntryIndex = 0; … … 115 115 typedef PropertyMapHashTable Table; 116 116 117 void expand( PropertyStorage&);118 void rehash( PropertyStorage&);119 void rehash(unsigned newTableSize , PropertyStorage&);120 void createTable( PropertyStorage&);117 void expand(); 118 void rehash(); 119 void rehash(unsigned newTableSize); 120 void createTable(); 121 121 122 void insert(const Entry& , JSValue*, PropertyStorage&);122 void insert(const Entry&); 123 123 124 void checkConsistency( PropertyStorage&);124 void checkConsistency(); 125 125 126 126 Table* m_table; 127 Vector<unsigned> m_deletedOffsets; 127 128 bool m_getterSetterFlag : 1; 128 129 }; … … 134 135 } 135 136 136 inline size_t PropertyMap::get Offset(const Identifier& propertyName)137 inline size_t PropertyMap::get(const Identifier& propertyName) 137 138 { 138 139 ASSERT(!propertyName.isNull()); … … 154 155 155 156 if (rep == m_table->entries()[entryIndex - 1].key) 156 return entryIndex - 2;157 return m_table->entries()[entryIndex - 1].offset; 157 158 158 159 #if DUMP_PROPERTYMAP_STATS … … 174 175 175 176 if (rep == m_table->entries()[entryIndex - 1].key) 176 return entryIndex - 2;177 return m_table->entries()[entryIndex - 1].offset; 177 178 } 178 179 } -
trunk/JavaScriptCore/kjs/StructureID.cpp
r37381 r37388 45 45 , m_nameInPrevious(0) 46 46 , m_transitionCount(0) 47 , m_propertyStorageCapacity(JSObject::inlineStorageCapacity) 47 48 , m_cachedTransistionOffset(WTF::notFound) 48 49 { … … 103 104 } 104 105 105 void StructureID::transitionTo(StructureID* oldStructureID, StructureID* newStructureID, JSObject* slotBase) 106 { 107 if (!slotBase->usingInlineStorage() && oldStructureID->m_propertyMap.size() != newStructureID->m_propertyMap.size()) 108 slotBase->allocatePropertyStorage(oldStructureID->m_propertyMap.size(), newStructureID->m_propertyMap.size()); 109 } 110 111 PassRefPtr<StructureID> StructureID::addPropertyTransition(StructureID* structureID, const Identifier& propertyName, JSValue* value, unsigned attributes, JSObject* slotBase, PutPropertySlot& slot, PropertyStorage& propertyStorage) 106 void StructureID::growPropertyStorageCapacity() 107 { 108 if (m_propertyStorageCapacity == JSObject::inlineStorageCapacity) 109 m_propertyStorageCapacity = JSObject::nonInlineBaseStorageCapacity; 110 else 111 m_propertyStorageCapacity *= 2; 112 } 113 114 PassRefPtr<StructureID> StructureID::addPropertyTransition(StructureID* structureID, const Identifier& propertyName, unsigned attributes, size_t& offset) 112 115 { 113 116 ASSERT(!structureID->m_isDictionary); … … 115 118 116 119 if (StructureID* existingTransition = structureID->m_transitionTable.get(make_pair(propertyName.ustring().rep(), attributes))) { 117 if (!slotBase->usingInlineStorage() && structureID->m_propertyMap.size() != existingTransition->m_propertyMap.size()) 118 slotBase->allocatePropertyStorage(structureID->m_propertyMap.size(), existingTransition->m_propertyMap.size()); 119 120 size_t offset = existingTransition->cachedTransistionOffset(); 120 offset = existingTransition->cachedTransistionOffset(); 121 121 ASSERT(offset != WTF::notFound); 122 propertyStorage[offset] = value;123 slot.setNewProperty(slotBase, offset);124 125 122 return existingTransition; 126 123 } … … 128 125 if (structureID->m_transitionCount > s_maxTransitionLength) { 129 126 RefPtr<StructureID> transition = toDictionaryTransition(structureID); 130 transition->m_propertyMap.put(propertyName, value, attributes, false, slotBase, slot, propertyStorage); 127 offset = transition->m_propertyMap.put(propertyName, attributes); 128 if (transition->m_propertyMap.storageSize() > transition->propertyStorageCapacity()) 129 transition->growPropertyStorageCapacity(); 131 130 return transition.release(); 132 131 } … … 139 138 transition->m_transitionCount = structureID->m_transitionCount + 1; 140 139 transition->m_propertyMap = structureID->m_propertyMap; 141 142 size_t offset = transition->m_propertyMap.put(propertyName, value, attributes, false, slotBase, slot, propertyStorage); 140 transition->m_propertyStorageCapacity = structureID->m_propertyStorageCapacity; 141 142 offset = transition->m_propertyMap.put(propertyName, attributes); 143 if (transition->m_propertyMap.storageSize() > transition->propertyStorageCapacity()) 144 transition->growPropertyStorageCapacity(); 145 143 146 transition->setCachedTransistionOffset(offset); 144 147 … … 154 157 transition->m_isDictionary = true; 155 158 transition->m_propertyMap = structureID->m_propertyMap; 159 transition->m_propertyStorageCapacity = structureID->m_propertyStorageCapacity; 156 160 return transition.release(); 157 161 } … … 173 177 transition->m_transitionCount = structureID->m_transitionCount + 1; 174 178 transition->m_propertyMap = structureID->m_propertyMap; 179 transition->m_propertyStorageCapacity = structureID->m_propertyStorageCapacity; 175 180 return transition.release(); 176 181 } … … 181 186 transition->m_transitionCount = structureID->m_transitionCount + 1; 182 187 transition->m_propertyMap = structureID->m_propertyMap; 188 transition->m_propertyStorageCapacity = structureID->m_propertyStorageCapacity; 183 189 return transition.release(); 184 190 } -
trunk/JavaScriptCore/kjs/StructureID.h
r37381 r37388 84 84 85 85 static PassRefPtr<StructureID> changePrototypeTransition(StructureID*, JSValue* prototype); 86 static PassRefPtr<StructureID> addPropertyTransition(StructureID*, const Identifier& propertyName, JSValue*, unsigned attributes, JSObject* slotBase, PutPropertySlot&, PropertyStorage&);86 static PassRefPtr<StructureID> addPropertyTransition(StructureID*, const Identifier& propertyName, unsigned attributes, size_t& offset); 87 87 static PassRefPtr<StructureID> getterSetterTransition(StructureID*); 88 88 static PassRefPtr<StructureID> toDictionaryTransition(StructureID*); … … 119 119 size_t cachedTransistionOffset() const { return m_cachedTransistionOffset; } 120 120 121 void growPropertyStorageCapacity(); 122 size_t propertyStorageCapacity() const { return m_propertyStorageCapacity; } 123 121 124 void getEnumerablePropertyNames(ExecState*, PropertyNameArray&, JSObject*); 122 125 void clearEnumerationCache(); 123 124 static void transitionTo(StructureID* oldStructureID, StructureID* newStructureID, JSObject* slotBase);125 126 126 127 private: … … 149 150 150 151 PropertyMap m_propertyMap; 152 size_t m_propertyStorageCapacity; 151 153 152 154 size_t m_cachedTransistionOffset;
Note:
See TracChangeset
for help on using the changeset viewer.