Changeset 92569 in webkit
- Timestamp:
- Aug 6, 2011 8:44:45 PM (13 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r92555 r92569 1 2011-08-06 Gavin Barraclough <barraclough@apple.com> 2 3 https://bugs.webkit.org/show_bug.cgi?id=65821 4 Don't form identifiers the first time a string is used as a property name. 5 6 Reviewed by Oliver Hunt. 7 8 This is a 1% win on SunSpider. 9 10 * dfg/DFGOperations.cpp: 11 - Use fastGetOwnProperty. 12 * jit/JITStubs.cpp: 13 (JSC::DEFINE_STUB_FUNCTION): 14 - Use fastGetOwnProperty. 15 * runtime/JSCell.h: 16 * runtime/JSObject.h: 17 (JSC::JSCell::fastGetOwnProperty): 18 - Fast call to get a property without creating an identifier the first time. 19 * runtime/PropertyMapHashTable.h: 20 (JSC::PropertyTable::find): 21 (JSC::PropertyTable::findWithString): 22 - Add interface to look up by either strinsg or identifiers. 23 * runtime/Structure.h: 24 (JSC::Structure::get): 25 - Add a get() call that takes a UString, not an Identifier. 26 * wtf/text/StringImpl.h: 27 (WTF::StringImpl::hasHash): 28 - Add a call to check if the has has been set (to detect the first use as a property name). 29 1 30 2011-08-06 Aron Rosenberg <arosenberg@logitech.com> 2 31 -
trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp
r91883 r92569 211 211 return getByVal(exec, base, propertyAsUInt32); 212 212 } else if (property.isString()) { 213 Identifier propertyName(exec, asString(property)->value(exec)); 214 PropertySlot slot(base); 215 if (base->fastGetOwnPropertySlot(exec, propertyName, slot)) 216 return JSValue::encode(slot.getValue(exec, propertyName)); 213 if (JSValue result = base->fastGetOwnProperty(exec, asString(property)->value(exec))) 214 return JSValue::encode(result); 217 215 } 218 216 } -
trunk/Source/JavaScriptCore/jit/JITStubs.cpp
r91903 r92569 2250 2250 2251 2251 if (LIKELY(baseValue.isCell() && subscript.isString())) { 2252 Identifier propertyName(callFrame, asString(subscript)->value(callFrame)); 2253 PropertySlot slot(baseValue.asCell()); 2254 // JSString::value may have thrown, but we shouldn't find a property with a null identifier, 2255 // so we should miss this case and wind up in the CHECK_FOR_EXCEPTION_AT_END, below. 2256 if (baseValue.asCell()->fastGetOwnPropertySlot(callFrame, propertyName, slot)) { 2257 JSValue result = slot.getValue(callFrame, propertyName); 2252 if (JSValue result = baseValue.asCell()->fastGetOwnProperty(callFrame, asString(subscript)->value(callFrame))) { 2258 2253 CHECK_FOR_EXCEPTION(); 2259 2254 return JSValue::encode(result); -
trunk/Source/JavaScriptCore/runtime/JSCell.h
r92233 r92569 138 138 // property names, we want a similar interface with appropriate optimizations.) 139 139 bool fastGetOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&); 140 JSValue fastGetOwnProperty(ExecState*, const UString&); 140 141 141 142 static ptrdiff_t structureOffset() -
trunk/Source/JavaScriptCore/runtime/JSObject.h
r91199 r92569 537 537 } 538 538 539 // Fast call to get a property where we may not yet have converted the string to an 540 // identifier. The first time we perform a property access with a given string, try 541 // performing the property map lookup without forming an identifier. We detect this 542 // case by checking whether the hash has yet been set for this string. 543 ALWAYS_INLINE JSValue JSCell::fastGetOwnProperty(ExecState* exec, const UString& name) 544 { 545 if (!m_structure->typeInfo().overridesGetOwnPropertySlot() && !m_structure->hasGetterSetterProperties()) { 546 size_t offset = name.impl()->hasHash() 547 ? m_structure->get(exec->globalData(), Identifier(exec, name)) 548 : m_structure->get(exec->globalData(), name); 549 if (offset != WTF::notFound) 550 return asObject(this)->locationForOffset(offset)->get(); 551 } 552 return JSValue(); 553 } 554 539 555 // It may seem crazy to inline a function this large but it makes a big difference 540 556 // since this is function very hot in variable lookup -
trunk/Source/JavaScriptCore/runtime/PropertyMapHashTable.h
r86499 r92569 155 155 156 156 // Find a value in the table. 157 find_iterator find(const KeyType& key); 157 find_iterator find(const KeyType&); 158 find_iterator findWithString(const KeyType&); 158 159 // Add a value to the table 159 160 std::pair<find_iterator, bool> add(const ValueType& entry); … … 325 326 { 326 327 ASSERT(key); 328 ASSERT(key->isIdentifier()); 327 329 unsigned hash = key->existingHash(); 328 330 unsigned step = 0; … … 344 346 345 347 if (!step) 346 step =WTF::doubleHash(key->existingHash()) | 1; 348 step = WTF::doubleHash(key->existingHash()) | 1; 349 hash += step; 350 351 #if DUMP_PROPERTYMAP_STATS 352 ++numRehashes; 353 #endif 354 } 355 } 356 357 inline PropertyTable::find_iterator PropertyTable::findWithString(const KeyType& key) 358 { 359 ASSERT(key); 360 ASSERT(!key->isIdentifier() && !key->hasHash()); 361 unsigned hash = key->hash(); 362 unsigned step = 0; 363 364 #if DUMP_PROPERTYMAP_STATS 365 ++numProbes; 366 #endif 367 368 while (true) { 369 unsigned entryIndex = m_index[hash & m_indexMask]; 370 if (entryIndex == EmptyEntryIndex) 371 return std::make_pair((ValueType*)0, hash & m_indexMask); 372 if (equal(key, table()[entryIndex - 1].key)) 373 return std::make_pair(&table()[entryIndex - 1], hash & m_indexMask); 374 375 #if DUMP_PROPERTYMAP_STATS 376 ++numCollisions; 377 #endif 378 379 if (!step) 380 step = WTF::doubleHash(key->existingHash()) | 1; 347 381 hash += step; 348 382 -
trunk/Source/JavaScriptCore/runtime/Structure.h
r92233 r92569 113 113 114 114 size_t get(JSGlobalData&, const Identifier& propertyName); 115 size_t get(JSGlobalData&, const UString& name); 115 116 size_t get(JSGlobalData&, StringImpl* propertyName, unsigned& attributes, JSCell*& specificValue); 116 117 size_t get(JSGlobalData& globalData, const Identifier& propertyName, unsigned& attributes, JSCell*& specificValue) … … 266 267 } 267 268 269 inline size_t Structure::get(JSGlobalData& globalData, const UString& name) 270 { 271 ASSERT(structure()->classInfo() == &s_info); 272 materializePropertyMapIfNecessary(globalData); 273 if (!m_propertyTable) 274 return notFound; 275 276 PropertyMapEntry* entry = m_propertyTable->findWithString(name.impl()).first; 277 ASSERT(!entry || entry->offset >= m_anonymousSlotCount); 278 return entry ? entry->offset : notFound; 279 } 280 268 281 inline bool JSCell::isObject() const 269 282 { -
trunk/Source/JavaScriptCore/wtf/text/StringImpl.h
r91913 r92569 239 239 unsigned hash() const { if (!m_hash) m_hash = StringHasher::computeHash(m_data, m_length); return m_hash; } 240 240 unsigned existingHash() const { ASSERT(m_hash); return m_hash; } 241 bool hasHash() const { return m_hash; } 241 242 242 243 ALWAYS_INLINE void deref() { m_refCountAndFlags -= s_refCountIncrement; if (!(m_refCountAndFlags & (s_refCountMask | s_refCountFlagStatic))) delete this; }
Note: See TracChangeset
for help on using the changeset viewer.