Changeset 50704 in webkit
- Timestamp:
- Nov 9, 2009 6:19:04 PM (14 years ago)
- Location:
- trunk
- Files:
-
- 3 added
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/ChangeLog
r50703 r50704 1 2009-11-09 Oliver Hunt <oliver@apple.com> 2 3 Reviewed by Gavin Barraclough. 4 5 Can cache prototype lookups on uncacheable dictionaries. 6 https://bugs.webkit.org/show_bug.cgi?id=31198 7 8 Replace fromDictionaryTransition with flattenDictionaryObject and 9 flattenDictionaryStructure. This change is necessary as we need to 10 guarantee that our attempt to convert away from a dictionary structure 11 will definitely succeed, and in some cases this requires mutating the 12 object storage itself. 13 14 * interpreter/Interpreter.cpp: 15 (JSC::Interpreter::tryCacheGetByID): 16 * jit/JITStubs.cpp: 17 (JSC::JITThunks::tryCacheGetByID): 18 (JSC::DEFINE_STUB_FUNCTION): 19 * runtime/BatchedTransitionOptimizer.h: 20 (JSC::BatchedTransitionOptimizer::~BatchedTransitionOptimizer): 21 * runtime/JSObject.h: 22 (JSC::JSObject::flattenDictionaryObject): 23 * runtime/Operations.h: 24 (JSC::normalizePrototypeChain): 25 * runtime/Structure.cpp: 26 (JSC::Structure::flattenDictionaryStructure): 27 (JSC::comparePropertyMapEntryIndices): 28 * runtime/Structure.h: 29 1 30 2009-11-09 Laszlo Gombos <laszlo.1.gombos@nokia.com> 2 31 -
trunk/JavaScriptCore/interpreter/Interpreter.cpp
r50675 r50704 1043 1043 // should not be treated as a dictionary. 1044 1044 if (baseObject->structure()->isDictionary()) 1045 baseObject-> setStructure(Structure::fromDictionaryTransition(baseObject->structure()));1045 baseObject->flattenDictionaryObject(); 1046 1046 1047 1047 ASSERT(!baseObject->structure()->isUncacheableDictionary()); -
trunk/JavaScriptCore/jit/JITStubs.cpp
r50443 r50704 772 772 // should not be treated as a dictionary. 773 773 if (slotBaseObject->structure()->isDictionary()) 774 slotBaseObject-> setStructure(Structure::fromDictionaryTransition(slotBaseObject->structure()));774 slotBaseObject->flattenDictionaryObject(); 775 775 776 776 stubInfo->initGetByIdProto(structure, slotBaseObject->structure()); … … 1182 1182 // should not be treated as a dictionary. 1183 1183 if (slotBaseObject->structure()->isDictionary()) 1184 slotBaseObject-> setStructure(Structure::fromDictionaryTransition(slotBaseObject->structure()));1184 slotBaseObject->flattenDictionaryObject(); 1185 1185 1186 1186 // The result fetched should always be the callee! … … 1335 1335 // should not be treated as a dictionary. 1336 1336 if (slotBaseObject->structure()->isDictionary()) 1337 slotBaseObject-> setStructure(Structure::fromDictionaryTransition(slotBaseObject->structure()));1337 slotBaseObject->flattenDictionaryObject(); 1338 1338 1339 1339 int listIndex; -
trunk/JavaScriptCore/runtime/BatchedTransitionOptimizer.h
r48582 r50704 44 44 ~BatchedTransitionOptimizer() 45 45 { 46 m_object-> setStructure(Structure::fromDictionaryTransition(m_object->structure()));46 m_object->flattenDictionaryObject(); 47 47 } 48 48 -
trunk/JavaScriptCore/runtime/JSObject.h
r50254 r50704 211 211 } 212 212 213 void flattenDictionaryObject() 214 { 215 m_structure->flattenDictionaryStructure(this); 216 } 217 213 218 protected: 214 219 static const unsigned StructureFlags = 0; -
trunk/JavaScriptCore/runtime/Operations.h
r49734 r50704 244 244 // should not be treated as a dictionary. 245 245 if (cell->structure()->isDictionary()) 246 asObject(cell)-> setStructure(Structure::fromDictionaryTransition(cell->structure()));246 asObject(cell)->flattenDictionaryObject(); 247 247 248 248 ++count; … … 266 266 // should not be treated as a dictionary. 267 267 if (base->structure()->isDictionary()) 268 asObject(base)-> setStructure(Structure::fromDictionaryTransition(base->structure()));268 asObject(base)->flattenDictionaryObject(); 269 269 270 270 ++count; -
trunk/JavaScriptCore/runtime/Structure.cpp
r50320 r50704 78 78 #endif 79 79 80 static int comparePropertyMapEntryIndices(const void* a, const void* b); 81 80 82 void Structure::dumpStatistics() 81 83 { … … 535 537 } 536 538 537 PassRefPtr<Structure> Structure::fromDictionaryTransition(Structure* structure) 538 { 539 ASSERT(structure->isDictionary()); 540 541 // Since dictionary Structures are not shared, and no opcodes specialize 542 // for them, we don't need to allocate a new Structure when transitioning 543 // to non-dictionary status. 544 545 // FIMXE: We can make this more efficient by canonicalizing the Structure (draining the 546 // deleted offsets vector) before transitioning from dictionary. 547 if (!structure->m_propertyTable || !structure->m_propertyTable->deletedOffsets || structure->m_propertyTable->deletedOffsets->isEmpty()) 548 structure->m_dictionaryKind = NoneDictionaryKind; 549 550 return structure; 539 PassRefPtr<Structure> Structure::flattenDictionaryStructure(JSObject* object) 540 { 541 ASSERT(isDictionary()); 542 if (isUncacheableDictionary()) { 543 ASSERT(m_propertyTable); 544 Vector<PropertyMapEntry*> sortedPropertyEntries(m_propertyTable->keyCount); 545 PropertyMapEntry** p = sortedPropertyEntries.data(); 546 unsigned entryCount = m_propertyTable->keyCount + m_propertyTable->deletedSentinelCount; 547 for (unsigned i = 1; i <= entryCount; i++) { 548 if (m_propertyTable->entries()[i].key) 549 *p++ = &m_propertyTable->entries()[i]; 550 } 551 size_t propertyCount = p - sortedPropertyEntries.data(); 552 qsort(sortedPropertyEntries.data(), propertyCount, sizeof(PropertyMapEntry*), comparePropertyMapEntryIndices); 553 sortedPropertyEntries.resize(propertyCount); 554 555 // We now have the properties currently defined on this object 556 // in the order that they are expected to be in, but we need to 557 // reorder the storage, so we have to copy the current values out 558 Vector<JSValue> values(propertyCount); 559 unsigned anonymousSlotCount = m_propertyTable->anonymousSlotCount; 560 for (unsigned i = 0; i < propertyCount; i++) { 561 PropertyMapEntry* entry = sortedPropertyEntries[i]; 562 values[i] = object->getDirectOffset(entry->offset); 563 // Update property table to have the new property offsets 564 entry->offset = anonymousSlotCount + i; 565 entry->index = i; 566 } 567 568 // Copy the original property values into their final locations 569 for (unsigned i = 0; i < propertyCount; i++) 570 object->putDirectOffset(anonymousSlotCount + i, values[i]); 571 572 if (m_propertyTable->deletedOffsets) { 573 delete m_propertyTable->deletedOffsets; 574 m_propertyTable->deletedOffsets = 0; 575 } 576 } 577 578 m_dictionaryKind = NoneDictionaryKind; 579 return this; 551 580 } 552 581 … … 1005 1034 } 1006 1035 1007 staticint comparePropertyMapEntryIndices(const void* a, const void* b)1036 int comparePropertyMapEntryIndices(const void* a, const void* b) 1008 1037 { 1009 1038 unsigned ia = static_cast<PropertyMapEntry* const*>(a)[0]->index; -
trunk/JavaScriptCore/runtime/Structure.h
r50254 r50704 75 75 static PassRefPtr<Structure> toCacheableDictionaryTransition(Structure*); 76 76 static PassRefPtr<Structure> toUncacheableDictionaryTransition(Structure*); 77 static PassRefPtr<Structure> fromDictionaryTransition(Structure*); 77 78 PassRefPtr<Structure> flattenDictionaryStructure(JSObject*); 78 79 79 80 ~Structure(); -
trunk/LayoutTests/ChangeLog
r50698 r50704 1 2009-11-09 Oliver Hunt <oliver@apple.com> 2 3 Reviewed by Gavin Barraclough. 4 5 Can cache prototype lookups on uncacheable dictionaries. 6 https://bugs.webkit.org/show_bug.cgi?id=31198 7 8 Add tests for lookup on uncacheable prototype. 9 10 * fast/js/dictionary-prototype-caching-expected.txt: Added. 11 * fast/js/dictionary-prototype-caching.html: Added. 12 * fast/js/script-tests/dictionary-prototype-caching.js: Added. 13 (protoTest): 14 1 15 2009-11-09 Anders Carlsson <andersca@apple.com> 2 16
Note: See TracChangeset
for help on using the changeset viewer.