Changeset 41232 in webkit for trunk/JavaScriptCore/runtime
- Timestamp:
- Feb 25, 2009, 3:44:07 PM (16 years ago)
- Location:
- trunk/JavaScriptCore/runtime
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/runtime/JSGlobalObject.h
r41126 r41232 330 330 } 331 331 332 inline JSValuePtr Structure::prototypeForLookup(ExecState* exec) 332 inline JSValuePtr Structure::prototypeForLookup(ExecState* exec) const 333 333 { 334 334 if (typeInfo().type() == ObjectType) … … 340 340 ASSERT(typeInfo().type() == NumberType); 341 341 return exec->lexicalGlobalObject()->numberPrototype(); 342 } 343 344 inline StructureChain* Structure::prototypeChain(ExecState* exec) const 345 { 346 // We cache our prototype chain so our clients can share it. 347 if (!isValid(exec, m_cachedPrototypeChain.get())) { 348 JSValuePtr prototype = prototypeForLookup(exec); 349 m_cachedPrototypeChain = StructureChain::create(prototype.isNull() ? 0 : asObject(prototype)->structure()); 350 } 351 return m_cachedPrototypeChain.get(); 352 } 353 354 inline bool Structure::isValid(ExecState* exec, StructureChain* cachedPrototypeChain) const 355 { 356 if (!cachedPrototypeChain) 357 return false; 358 359 JSValuePtr prototype = prototypeForLookup(exec); 360 RefPtr<Structure>* cachedStructure = cachedPrototypeChain->head(); 361 while(*cachedStructure && !prototype.isNull()) { 362 if (asObject(prototype)->structure() != *cachedStructure) 363 return false; 364 ++cachedStructure; 365 prototype = asObject(prototype)->prototype(); 366 } 367 return prototype.isNull() && !*cachedStructure; 342 368 } 343 369 -
trunk/JavaScriptCore/runtime/JSPropertyNameIterator.h
r40046 r41232 100 100 return noValue(); 101 101 102 if (m_data->cachedStructure() == m_object->structure() && structureChainsAreEqual(m_data->cachedPrototypeChain(), m_object->structure()->cachedPrototypeChain()))102 if (m_data->cachedStructure() == m_object->structure() && m_data->cachedPrototypeChain() == m_object->structure()->prototypeChain(exec)) 103 103 return jsOwnedString(exec, (*m_position++).ustring()); 104 104 -
trunk/JavaScriptCore/runtime/Operations.h
r41168 r41232 227 227 } 228 228 229 inline StructureChain* cachePrototypeChain(CallFrame* callFrame, Structure* structure)230 {231 JSValuePtr prototype = structure->prototypeForLookup(callFrame);232 if (!prototype.isCell())233 return 0;234 RefPtr<StructureChain> chain = StructureChain::create(asObject(prototype)->structure());235 structure->setCachedPrototypeChain(chain.release());236 return structure->cachedPrototypeChain();237 }238 239 229 inline size_t countPrototypeChainEntriesAndCheckForProxies(CallFrame* callFrame, JSValuePtr baseValue, const PropertySlot& slot) 240 230 { … … 255 245 // Since we're accessing a prototype in a loop, it's a good bet that it 256 246 // should not be treated as a dictionary. 257 if (cell->structure()->isDictionary()) { 258 RefPtr<Structure> transition = Structure::fromDictionaryTransition(cell->structure()); 259 asObject(cell)->setStructure(transition.release()); 260 cell->structure()->setCachedPrototypeChain(0); 261 } 247 if (cell->structure()->isDictionary()) 248 asObject(cell)->setStructure(Structure::fromDictionaryTransition(cell->structure())); 262 249 263 250 ++count; -
trunk/JavaScriptCore/runtime/PropertyNameArray.h
r38528 r41232 66 66 : m_data(PropertyNameArrayData::create()) 67 67 , m_globalData(globalData) 68 , m_ cacheable(true)68 , m_shouldCache(true) 69 69 { 70 70 } … … 73 73 : m_data(PropertyNameArrayData::create()) 74 74 , m_globalData(&exec->globalData()) 75 , m_ cacheable(true)75 , m_shouldCache(true) 76 76 { 77 77 } … … 96 96 PassRefPtr<PropertyNameArrayData> releaseData() { return m_data.release(); } 97 97 98 void set Cacheable(bool cacheable) { m_cacheable = cacheable; }99 bool cacheable() const { return m_cacheable; }98 void setShouldCache(bool shouldCache) { m_shouldCache = shouldCache; } 99 bool shouldCache() const { return m_shouldCache; } 100 100 101 101 private: … … 105 105 IdentifierSet m_set; 106 106 JSGlobalData* m_globalData; 107 bool m_ cacheable;107 bool m_shouldCache; 108 108 }; 109 109 -
trunk/JavaScriptCore/runtime/Structure.cpp
r40608 r41232 124 124 : m_typeInfo(typeInfo) 125 125 , m_prototype(prototype) 126 , m_cachedPrototypeChain(0)127 , m_previous(0)128 , m_nameInPrevious(0)129 126 , m_propertyTable(0) 130 127 , m_propertyStorageCapacity(JSObject::inlineStorageCapacity) … … 290 287 void Structure::getEnumerablePropertyNames(ExecState* exec, PropertyNameArray& propertyNames, JSObject* baseObject) 291 288 { 292 bool shouldCache = propertyNames.cacheable() && !(propertyNames.size() || m_isDictionary); 289 bool shouldCache = propertyNames.shouldCache() && !(propertyNames.size() || m_isDictionary); 290 291 if (shouldCache && m_cachedPropertyNameArrayData) { 292 if (m_cachedPropertyNameArrayData->cachedPrototypeChain() == prototypeChain(exec)) { 293 propertyNames.setData(m_cachedPropertyNameArrayData); 294 return; 295 } 296 clearEnumerationCache(); 297 } 298 299 getEnumerableNamesFromPropertyTable(propertyNames); 300 getEnumerableNamesFromClassInfoTable(exec, baseObject->classInfo(), propertyNames); 301 302 if (m_prototype.isObject()) { 303 propertyNames.setShouldCache(false); // No need for our prototypes to waste memory on caching, since they're not being enumerated directly. 304 asObject(m_prototype)->getPropertyNames(exec, propertyNames); 305 } 293 306 294 307 if (shouldCache) { 295 if (m_cachedPropertyNameArrayData) {296 if (structureChainsAreEqual(m_cachedPropertyNameArrayData->cachedPrototypeChain(), cachedPrototypeChain())) {297 propertyNames.setData(m_cachedPropertyNameArrayData);298 return;299 }300 }301 propertyNames.setCacheable(false);302 }303 304 getEnumerablePropertyNamesInternal(propertyNames);305 306 // Add properties from the static hashtables of properties307 for (const ClassInfo* info = baseObject->classInfo(); info; info = info->parentClass) {308 const HashTable* table = info->propHashTable(exec);309 if (!table)310 continue;311 table->initializeIfNeeded(exec);312 ASSERT(table->table);313 #if ENABLE(PERFECT_HASH_SIZE)314 int hashSizeMask = table->hashSizeMask;315 #else316 int hashSizeMask = table->compactSize - 1;317 #endif318 const HashEntry* entry = table->table;319 for (int i = 0; i <= hashSizeMask; ++i, ++entry) {320 if (entry->key() && !(entry->attributes() & DontEnum))321 propertyNames.add(entry->key());322 }323 }324 325 if (m_prototype.isObject())326 asObject(m_prototype)->getPropertyNames(exec, propertyNames);327 328 if (shouldCache) {329 if (m_cachedPropertyNameArrayData)330 m_cachedPropertyNameArrayData->setCachedStructure(0);331 332 308 m_cachedPropertyNameArrayData = propertyNames.data(); 333 334 StructureChain* chain = cachedPrototypeChain(); 335 if (!chain) 336 chain = createCachedPrototypeChain(); 337 m_cachedPropertyNameArrayData->setCachedPrototypeChain(chain); 309 m_cachedPropertyNameArrayData->setCachedPrototypeChain(prototypeChain(exec)); 338 310 m_cachedPropertyNameArrayData->setCachedStructure(this); 339 311 } … … 535 507 clearEnumerationCache(); 536 508 return offset; 537 }538 539 StructureChain* Structure::createCachedPrototypeChain()540 {541 ASSERT(typeInfo().type() == ObjectType);542 ASSERT(!m_cachedPrototypeChain);543 544 JSValuePtr prototype = storedPrototype();545 if (!prototype.isCell())546 return 0;547 548 RefPtr<StructureChain> chain = StructureChain::create(asObject(prototype)->structure());549 setCachedPrototypeChain(chain.release());550 return cachedPrototypeChain();551 509 } 552 510 … … 925 883 } 926 884 927 void Structure::getEnumerable PropertyNamesInternal(PropertyNameArray& propertyNames)885 void Structure::getEnumerableNamesFromPropertyTable(PropertyNameArray& propertyNames) 928 886 { 929 887 materializePropertyMapIfNecessary(); … … 979 937 for (size_t i = 0; i < sortedEnumerables.size(); ++i) 980 938 propertyNames.add(sortedEnumerables[i]->key); 939 } 940 } 941 942 void Structure::getEnumerableNamesFromClassInfoTable(ExecState* exec, const ClassInfo* classInfo, PropertyNameArray& propertyNames) 943 { 944 // Add properties from the static hashtables of properties 945 for (; classInfo; classInfo = classInfo->parentClass) { 946 const HashTable* table = classInfo->propHashTable(exec); 947 if (!table) 948 continue; 949 table->initializeIfNeeded(exec); 950 ASSERT(table->table); 951 #if ENABLE(PERFECT_HASH_SIZE) 952 int hashSizeMask = table->hashSizeMask; 953 #else 954 int hashSizeMask = table->compactSize - 1; 955 #endif 956 const HashEntry* entry = table->table; 957 for (int i = 0; i <= hashSizeMask; ++i, ++entry) { 958 if (entry->key() && !(entry->attributes() & DontEnum)) 959 propertyNames.add(entry->key()); 960 } 981 961 } 982 962 } -
trunk/JavaScriptCore/runtime/Structure.h
r40046 r41232 88 88 89 89 JSValuePtr storedPrototype() const { return m_prototype; } 90 JSValuePtr prototypeForLookup(ExecState*); 90 JSValuePtr prototypeForLookup(ExecState*) const; 91 StructureChain* prototypeChain(ExecState*) const; 91 92 92 93 Structure* previousID() const { return m_previous.get(); } 93 94 StructureChain* createCachedPrototypeChain();95 void setCachedPrototypeChain(PassRefPtr<StructureChain> cachedPrototypeChain) { m_cachedPrototypeChain = cachedPrototypeChain; }96 StructureChain* cachedPrototypeChain() const { return m_cachedPrototypeChain.get(); }97 94 98 95 void growPropertyStorageCapacity(); … … 114 111 size_t put(const Identifier& propertyName, unsigned attributes); 115 112 size_t remove(const Identifier& propertyName); 116 void getEnumerablePropertyNamesInternal(PropertyNameArray&); 113 void getEnumerableNamesFromPropertyTable(PropertyNameArray&); 114 void getEnumerableNamesFromClassInfoTable(ExecState*, const ClassInfo*, PropertyNameArray&); 117 115 118 116 void expandPropertyMapHashTable(); … … 145 143 return m_offset == noOffset ? 0 : m_offset + 1; 146 144 } 145 146 bool isValid(ExecState*, StructureChain* cachedPrototypeChain) const; 147 147 148 148 static const unsigned emptyEntryIndex = 0; … … 155 155 156 156 JSValuePtr m_prototype; 157 RefPtr<StructureChain> m_cachedPrototypeChain;157 mutable RefPtr<StructureChain> m_cachedPrototypeChain; 158 158 159 159 RefPtr<Structure> m_previous; -
trunk/JavaScriptCore/runtime/StructureChain.cpp
r40046 r41232 33 33 namespace JSC { 34 34 35 StructureChain::StructureChain(Structure* structure)35 StructureChain::StructureChain(Structure* head) 36 36 { 37 size_t size = 1; 38 39 Structure* tmp = structure; 40 while (!tmp->storedPrototype().isNull()) { 37 size_t size = 0; 38 for (Structure* current = head; current; current = current->storedPrototype().isNull() ? 0 : asObject(current->storedPrototype())->structure()) 41 39 ++size; 42 tmp = asCell(tmp->storedPrototype())->structure();43 }44 40 45 41 m_vector.set(new RefPtr<Structure>[size + 1]); 46 42 47 size_t i; 48 for (i = 0; i < size - 1; ++i) { 49 m_vector[i] = structure; 50 structure = asObject(structure->storedPrototype())->structure(); 51 } 52 m_vector[i] = structure; 53 m_vector[i + 1] = 0; 54 } 55 56 bool structureChainsAreEqual(StructureChain* chainA, StructureChain* chainB) 57 { 58 if (!chainA || !chainB) 59 return false; 60 61 RefPtr<Structure>* a = chainA->head(); 62 RefPtr<Structure>* b = chainB->head(); 63 while (1) { 64 if (*a != *b) 65 return false; 66 if (!*a) 67 return true; 68 a++; 69 b++; 70 } 43 size_t i = 0; 44 for (Structure* current = head; current; current = current->storedPrototype().isNull() ? 0 : asObject(current->storedPrototype())->structure()) 45 m_vector[i++] = current; 46 m_vector[i] = 0; 71 47 } 72 48 -
trunk/JavaScriptCore/runtime/StructureChain.h
r38440 r41232 38 38 class StructureChain : public RefCounted<StructureChain> { 39 39 public: 40 static PassRefPtr<StructureChain> create(Structure* structure) { return adoptRef(new StructureChain(structure)); } 41 40 static PassRefPtr<StructureChain> create(Structure* head) { return adoptRef(new StructureChain(head)); } 42 41 RefPtr<Structure>* head() { return m_vector.get(); } 43 42 44 43 private: 45 StructureChain(Structure* structure);44 StructureChain(Structure* head); 46 45 47 46 OwnArrayPtr<RefPtr<Structure> > m_vector; 48 47 }; 49 48 50 bool structureChainsAreEqual(StructureChain*, StructureChain*);51 52 49 } // namespace JSC 53 50
Note:
See TracChangeset
for help on using the changeset viewer.