Changeset 36016 in webkit for trunk/JavaScriptCore/kjs/PropertyMap.cpp
- Timestamp:
- Sep 1, 2008, 2:22:54 PM (17 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/kjs/PropertyMap.cpp
r35027 r36016 22 22 #include "PropertyMap.h" 23 23 24 #include "JSObject.h"25 24 #include "protect.h" 26 25 #include "PropertyNameArray.h" … … 44 43 #define USE_SINGLE_ENTRY 1 45 44 46 // 2/28/2006 ggaren: command-line JS iBench says that USE_SINGLE_ENTRY is a47 // 3.2% performance boost.48 49 45 namespace KJS { 50 46 … … 81 77 #endif 82 78 83 struct PropertyMapEntry {84 UString::Rep* key;85 JSValue* value;86 unsigned attributes;87 unsigned index;88 89 PropertyMapEntry(UString::Rep* k, JSValue* v, int a)90 : key(k)91 , value(v)92 , attributes(a)93 , index(0)94 {95 }96 };97 98 // lastIndexUsed is an ever-increasing index used to identify the order items99 // were inserted into the property map. It's required that getEnumerablePropertyNames100 // return the properties in the order they were added for compatibility with other101 // browsers' JavaScript implementations.102 struct PropertyMapHashTable {103 unsigned sizeMask;104 unsigned size;105 unsigned keyCount;106 unsigned deletedSentinelCount;107 unsigned lastIndexUsed;108 unsigned entryIndicies[1];109 110 PropertyMapEntry* entries()111 {112 // The entries vector comes after the indices vector.113 // The 0th item in the entries vector is not really used; it has to114 // have a 0 in its key to allow the hash table lookup to handle deleted115 // sentinels without any special-case code, but the other fields are unused.116 return reinterpret_cast<PropertyMapEntry*>(&entryIndicies[size]);117 }118 119 static size_t allocationSize(unsigned size)120 {121 // We never let a hash table get more than half full,122 // So the number of indices we need is the size of the hash table.123 // But the number of entries is half that (plus one for the deleted sentinel).124 return sizeof(PropertyMapHashTable)125 + (size - 1) * sizeof(unsigned)126 + (1 + size / 2) * sizeof(PropertyMapEntry);127 }128 };129 130 79 static const unsigned emptyEntryIndex = 0; 131 80 static const unsigned deletedSentinelIndex = 1; … … 157 106 } 158 107 159 void PropertyMap::clear()160 {161 if (!m_usingTable) {162 #if USE_SINGLE_ENTRY163 if (m_singleEntryKey) {164 m_singleEntryKey->deref();165 m_singleEntryKey = 0;166 }167 #endif168 return;169 }170 171 unsigned entryCount = m_u.table->keyCount + m_u.table->deletedSentinelCount;172 for (unsigned i = 1; i <= entryCount; i++) {173 if (UString::Rep* key = m_u.table->entries()[i].key)174 key->deref();175 }176 for (unsigned i = 0; i < m_u.table->size; i++)177 m_u.table->entryIndicies[i] = emptyEntryIndex;178 m_u.table->keyCount = 0;179 m_u.table->deletedSentinelCount = 0;180 }181 182 108 JSValue* PropertyMap::get(const Identifier& propertyName, unsigned& attributes) const 183 109 { … … 388 314 } 389 315 390 void PropertyMap::put(const Identifier& propertyName, JSValue* value, unsigned attributes, bool checkReadOnly )316 void PropertyMap::put(const Identifier& propertyName, JSValue* value, unsigned attributes, bool checkReadOnly, JSObject* slotBase, PutPropertySlot& slot) 391 317 { 392 318 ASSERT(!propertyName.isNull()); … … 405 331 m_singleEntryAttributes = static_cast<short>(attributes); 406 332 checkConsistency(); 333 slot.setNewProperty(slotBase, KJS_INVALID_OFFSET); 407 334 return; 408 335 } … … 414 341 #endif 415 342 416 if (!m_usingTable || (m_u.table->keyCount + m_u.table->deletedSentinelCount) * 2 >= m_u.table->size)343 if (!m_usingTable) 417 344 expand(); 418 345 … … 439 366 m_u.table->entries()[entryIndex - 1].value = value; 440 367 // Attributes are intentionally not updated. 368 slot.setExistingProperty(slotBase, offsetForTableLocation(&m_u.table->entries()[entryIndex - 1].value)); 441 369 return; 442 370 } else if (entryIndex == deletedSentinelIndex) { … … 486 414 ++m_u.table->keyCount; 487 415 416 if ((m_u.table->keyCount + m_u.table->deletedSentinelCount) * 2 >= m_u.table->size) 417 expand(); 418 488 419 checkConsistency(); 420 slot.setNewProperty(slotBase, offsetForTableLocation(&m_u.table->entries()[entryIndex - 1].value)); 489 421 } 490 422 … … 696 628 return +1; 697 629 return 0; 698 }699 700 bool PropertyMap::containsGettersOrSetters() const701 {702 if (!m_usingTable) {703 #if USE_SINGLE_ENTRY704 return !!(m_singleEntryAttributes & IsGetterSetter);705 #else706 return false;707 #endif708 }709 710 unsigned entryCount = m_u.table->keyCount + m_u.table->deletedSentinelCount;711 for (unsigned i = 1; i <= entryCount; i++) {712 if (m_u.table->entries()[i].attributes & IsGetterSetter)713 return true;714 }715 716 return false;717 630 } 718 631
Note:
See TracChangeset
for help on using the changeset viewer.