Reviewed by Darin.
authormjs <mjs@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 23 Apr 2007 04:10:47 +0000 (04:10 +0000)
committermjs <mjs@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 23 Apr 2007 04:10:47 +0000 (04:10 +0000)
        - shrink PropertyMap by 8 bytes and therefore shrink CELL_SIZE to 40 (for 32-bit;
        similar shrinkage for 64-bit)
        http://bugs.webkit.org/show_bug.cgi?id=13384

        Inspired by similar changes by Christopher E. Hyde <C.Hyde@parableuk.force9.co.uk>
        done in the kjs-tweaks branch of KDE's kjs. However, this version is somewhat
        cleaner style-wise and avoids some of the negative speed impact (at least on gcc/x86)
        of his version.

        This is nearly a wash performance-wise, maybe a slight slowdown, but worth doing
        to eventually reach cell size 32.

        * kjs/collector.cpp:
        (KJS::):
        * kjs/property_map.cpp:
        (KJS::PropertyMap::~PropertyMap):
        (KJS::PropertyMap::clear):
        (KJS::PropertyMap::get):
        (KJS::PropertyMap::getLocation):
        (KJS::PropertyMap::put):
        (KJS::PropertyMap::insert):
        (KJS::PropertyMap::expand):
        (KJS::PropertyMap::rehash):
        (KJS::PropertyMap::remove):
        (KJS::PropertyMap::mark):
        (KJS::PropertyMap::containsGettersOrSetters):
        (KJS::PropertyMap::getEnumerablePropertyNames):
        (KJS::PropertyMap::getSparseArrayPropertyNames):
        (KJS::PropertyMap::save):
        (KJS::PropertyMap::checkConsistency):
        * kjs/property_map.h:
        (KJS::PropertyMap::hasGetterSetterProperties):
        (KJS::PropertyMap::setHasGetterSetterProperties):
        (KJS::PropertyMap::):
        (KJS::PropertyMap::PropertyMap):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@21018 268f45cc-cd09-0410-ab3c-d52691b4dbfc

JavaScriptCore/ChangeLog
JavaScriptCore/kjs/collector.cpp
JavaScriptCore/kjs/property_map.cpp
JavaScriptCore/kjs/property_map.h

index 13964cb14d7faae18d48bda39a3c158318f8cb12..c597ce4e12a7efb27c34cbfedc503e707e3cf066 100644 (file)
@@ -1,3 +1,43 @@
+2007-04-22  Maciej Stachowiak  <mjs@apple.com>
+
+        Reviewed by Darin.
+        
+        - shrink PropertyMap by 8 bytes and therefore shrink CELL_SIZE to 40 (for 32-bit; 
+        similar shrinkage for 64-bit)
+        http://bugs.webkit.org/show_bug.cgi?id=13384
+
+        Inspired by similar changes by Christopher E. Hyde <C.Hyde@parableuk.force9.co.uk>
+        done in the kjs-tweaks branch of KDE's kjs. However, this version is somewhat 
+        cleaner style-wise and avoids some of the negative speed impact (at least on gcc/x86) 
+        of his version.
+        
+        This is nearly a wash performance-wise, maybe a slight slowdown, but worth doing
+        to eventually reach cell size 32.
+        
+        * kjs/collector.cpp:
+        (KJS::):
+        * kjs/property_map.cpp:
+        (KJS::PropertyMap::~PropertyMap):
+        (KJS::PropertyMap::clear):
+        (KJS::PropertyMap::get):
+        (KJS::PropertyMap::getLocation):
+        (KJS::PropertyMap::put):
+        (KJS::PropertyMap::insert):
+        (KJS::PropertyMap::expand):
+        (KJS::PropertyMap::rehash):
+        (KJS::PropertyMap::remove):
+        (KJS::PropertyMap::mark):
+        (KJS::PropertyMap::containsGettersOrSetters):
+        (KJS::PropertyMap::getEnumerablePropertyNames):
+        (KJS::PropertyMap::getSparseArrayPropertyNames):
+        (KJS::PropertyMap::save):
+        (KJS::PropertyMap::checkConsistency):
+        * kjs/property_map.h:
+        (KJS::PropertyMap::hasGetterSetterProperties):
+        (KJS::PropertyMap::setHasGetterSetterProperties):
+        (KJS::PropertyMap::):
+        (KJS::PropertyMap::PropertyMap):
+
 2007-04-22  Maciej Stachowiak  <mjs@apple.com>
 
         Reviewed by Darin.
index a4ef8d8ea493f4d505491ec690e704b2f6410bcd..bbaaf2e13224210b73bf2102cb7cedc2ce508961 100644 (file)
@@ -68,8 +68,8 @@ namespace KJS {
 // tunable parameters
 
 template<size_t bytesPerWord> struct CellSize;
-template<> struct CellSize<sizeof(uint32_t)> { static const size_t m_value = 48; }; // 32-bit
-template<> struct CellSize<sizeof(uint64_t)> { static const size_t m_value = 80; }; // 64-bit
+template<> struct CellSize<sizeof(uint32_t)> { static const size_t m_value = 40; }; // 32-bit
+template<> struct CellSize<sizeof(uint64_t)> { static const size_t m_value = 64; }; // 64-bit
 
 const size_t BLOCK_SIZE = (16 * 4096); // 64k
 const size_t SPARE_EMPTY_BLOCKS = 2;
index b6d35d0f20aafa6e4c5205e40a6b64272823600e..5350cb98b0a04616e7614eb708ac401c63c10860 100644 (file)
@@ -39,8 +39,6 @@ using std::max;
 // 2/28/2006 ggaren: super accurate JS iBench says that USE_SINGLE_ENTRY is a
 // 3.2% performance boost.
 
-// FIXME: _singleEntry.index is unused.
-
 #if !DO_CONSISTENCY_CHECK
 #define checkConsistency() ((void)0)
 #endif
@@ -110,17 +108,17 @@ static inline bool isValid(UString::Rep* key)
 
 PropertyMap::~PropertyMap()
 {
-    if (!_table) {
+    if (!m_usingTable) {
 #if USE_SINGLE_ENTRY
-        UString::Rep *key = _singleEntry.key;
+        UString::Rep* key = m_singleEntryKey;
         if (key)
             key->deref();
 #endif
         return;
     }
     
-    int minimumKeysToProcess = _table->keyCount + _table->sentinelCount;
-    Entry *entries = _table->entries;
+    int minimumKeysToProcess = m_u.table->keyCount + m_u.table->sentinelCount;
+    Entry *entries = m_u.table->entries;
     for (int i = 0; i < minimumKeysToProcess; i++) {
         UString::Rep *key = entries[i].key;
         if (key) {
@@ -129,24 +127,24 @@ PropertyMap::~PropertyMap()
         } else
             ++minimumKeysToProcess;
     }
-    fastFree(_table);
+    fastFree(m_u.table);
 }
 
 void PropertyMap::clear()
 {
-    if (!_table) {
+    if (!m_usingTable) {
 #if USE_SINGLE_ENTRY
-        UString::Rep *key = _singleEntry.key;
+        UString::Rep* key = m_singleEntryKey;
         if (key) {
             key->deref();
-            _singleEntry.key = 0;
+            m_singleEntryKey = 0;
         }
 #endif
         return;
     }
 
-    int size = _table->size;
-    Entry *entries = _table->entries;
+    int size = m_u.table->size;
+    Entry *entries = m_u.table->entries;
     for (int i = 0; i < size; i++) {
         UString::Rep *key = entries[i].key;
         if (isValid(key)) {
@@ -155,8 +153,8 @@ void PropertyMap::clear()
             entries[i].value = 0;
         }
     }
-    _table->keyCount = 0;
-    _table->sentinelCount = 0;
+    m_u.table->keyCount = 0;
+    m_u.table->sentinelCount = 0;
 }
 
 JSValue *PropertyMap::get(const Identifier &name, unsigned &attributes) const
@@ -165,20 +163,20 @@ JSValue *PropertyMap::get(const Identifier &name, unsigned &attributes) const
     
     UString::Rep *rep = name._ustring.rep();
     
-    if (!_table) {
+    if (!m_usingTable) {
 #if USE_SINGLE_ENTRY
-        UString::Rep *key = _singleEntry.key;
+        UString::Rep* key = m_singleEntryKey;
         if (rep == key) {
-            attributes = _singleEntry.attributes;
-            return _singleEntry.value;
+            attributes = m_singleEntryAttributes;
+            return m_u.singleEntryValue;
         }
 #endif
         return 0;
     }
     
     unsigned h = rep->hash();
-    int sizeMask = _table->sizeMask;
-    Entry *entries = _table->entries;
+    int sizeMask = m_u.table->sizeMask;
+    Entry *entries = m_u.table->entries;
     int i = h & sizeMask;
     int k = 0;
 #if DUMP_STATISTICS
@@ -206,18 +204,18 @@ JSValue *PropertyMap::get(const Identifier &name) const
     
     UString::Rep *rep = name._ustring.rep();
 
-    if (!_table) {
+    if (!m_usingTable) {
 #if USE_SINGLE_ENTRY
-        UString::Rep *key = _singleEntry.key;
+        UString::Rep *key = m_singleEntryKey;
         if (rep == key)
-            return _singleEntry.value;
+            return m_u.singleEntryValue;
 #endif
         return 0;
     }
     
     unsigned h = rep->hash();
-    int sizeMask = _table->sizeMask;
-    Entry *entries = _table->entries;
+    int sizeMask = m_u.table->sizeMask;
+    Entry *entries = m_u.table->entries;
     int i = h & sizeMask;
     int k = 0;
 #if DUMP_STATISTICS
@@ -243,18 +241,18 @@ JSValue **PropertyMap::getLocation(const Identifier &name)
     
     UString::Rep *rep = name._ustring.rep();
 
-    if (!_table) {
+    if (!m_usingTable) {
 #if USE_SINGLE_ENTRY
-        UString::Rep *key = _singleEntry.key;
+        UString::Rep *key = m_singleEntryKey;
         if (rep == key)
-            return &_singleEntry.value;
+            return &m_u.singleEntryValue;
 #endif
         return 0;
     }
     
     unsigned h = rep->hash();
-    int sizeMask = _table->sizeMask;
-    Entry *entries = _table->entries;
+    int sizeMask = m_u.table->sizeMask;
+    Entry *entries = m_u.table->entries;
     int i = h & sizeMask;
     int k = 0;
 #if DUMP_STATISTICS
@@ -310,30 +308,30 @@ void PropertyMap::put(const Identifier &name, JSValue *value, int attributes, bo
 #endif
     
 #if USE_SINGLE_ENTRY
-    if (!_table) {
-        UString::Rep *key = _singleEntry.key;
+    if (!m_usingTable) {
+        UString::Rep *key = m_singleEntryKey;
         if (key) {
-            if (rep == key && !(roCheck && (_singleEntry.attributes & ReadOnly))) {
-                _singleEntry.value = value;
+            if (rep == key && !(roCheck && (m_singleEntryAttributes & ReadOnly))) {
+                m_u.singleEntryValue = value;
                 return;
             }
         } else {
             rep->ref();
-            _singleEntry.key = rep;
-            _singleEntry.value = value;
-            _singleEntry.attributes = static_cast<short>(attributes);
+            m_singleEntryKey = rep;
+            m_u.singleEntryValue = value;
+            m_singleEntryAttributes = static_cast<short>(attributes);
             checkConsistency();
             return;
         }
     }
 #endif
 
-    if (!_table || _table->keyCount * 2 >= _table->size)
+    if (!m_usingTable || m_u.table->keyCount * 2 >= m_u.table->size)
         expand();
     
     unsigned h = rep->hash();
-    int sizeMask = _table->sizeMask;
-    Entry *entries = _table->entries;
+    int sizeMask = m_u.table->sizeMask;
+    Entry *entries = m_u.table->entries;
     int i = h & sizeMask;
     int k = 0;
     bool foundDeletedElement = false;
@@ -344,7 +342,7 @@ void PropertyMap::put(const Identifier &name, JSValue *value, int attributes, bo
 #endif
     while (UString::Rep *key = entries[i].key) {
         if (rep == key) {
-            if (roCheck && (_table->entries[i].attributes & ReadOnly)) 
+            if (roCheck && (m_u.table->entries[i].attributes & ReadOnly)) 
                 return;
             // Put a new value in an existing hash table entry.
             entries[i].value = value;
@@ -367,7 +365,7 @@ void PropertyMap::put(const Identifier &name, JSValue *value, int attributes, bo
     // Use either the deleted element or the 0 at the end of the chain.
     if (foundDeletedElement) {
         i = deletedElementIndex;
-        --_table->sentinelCount;
+        --m_u.table->sentinelCount;
     }
 
     // Create a new hash table entry.
@@ -375,19 +373,19 @@ void PropertyMap::put(const Identifier &name, JSValue *value, int attributes, bo
     entries[i].key = rep;
     entries[i].value = value;
     entries[i].attributes = static_cast<short>(attributes);
-    entries[i].index = ++_table->lastIndexUsed;
-    ++_table->keyCount;
+    entries[i].index = ++m_u.table->lastIndexUsed;
+    ++m_u.table->keyCount;
 
     checkConsistency();
 }
 
 void PropertyMap::insert(UString::Rep *key, JSValue *value, int attributes, int index)
 {
-    assert(_table);
+    assert(m_u.table);
 
     unsigned h = key->hash();
-    int sizeMask = _table->sizeMask;
-    Entry *entries = _table->entries;
+    int sizeMask = m_u.table->sizeMask;
+    Entry *entries = m_u.table->entries;
     int i = h & sizeMask;
     int k = 0;
 #if DUMP_STATISTICS
@@ -412,40 +410,45 @@ void PropertyMap::insert(UString::Rep *key, JSValue *value, int attributes, int
 
 void PropertyMap::expand()
 {
-    Table *oldTable = _table;
-    int oldTableSize = oldTable ? oldTable->size : 0;    
+    Table *oldTable = m_u.table;
+    int oldTableSize = m_usingTable ? oldTable->size : 0;    
     rehash(oldTableSize ? oldTableSize * 2 : 16);
 }
 
 void PropertyMap::rehash()
 {
-    assert(_table);
-    assert(_table->size);
-    rehash(_table->size);
+    assert(m_u.table);
+    assert(m_u.table->size);
+    rehash(m_u.table->size);
 }
 
 void PropertyMap::rehash(int newTableSize)
 {
     checkConsistency();
+
+#if USE_SINGLE_ENTRY
+    JSValue* oldSingleEntryValue = m_u.singleEntryValue;
+#endif
+
+    Table *oldTable = m_usingTable ? m_u.table : 0;
+    int oldTableSize = m_usingTable ? oldTable->size : 0;
+    int oldTableKeyCount = m_usingTable ? oldTable->keyCount : 0;
     
-    Table *oldTable = _table;
-    int oldTableSize = oldTable ? oldTable->size : 0;
-    int oldTableKeyCount = oldTable ? oldTable->keyCount : 0;
-    
-    _table = (Table *)fastCalloc(1, sizeof(Table) + (newTableSize - 1) * sizeof(Entry) );
-    _table->size = newTableSize;
-    _table->sizeMask = newTableSize - 1;
-    _table->keyCount = oldTableKeyCount;
+    m_u.table = (Table *)fastCalloc(1, sizeof(Table) + (newTableSize - 1) * sizeof(Entry) );
+    m_u.table->size = newTableSize;
+    m_u.table->sizeMask = newTableSize - 1;
+    m_u.table->keyCount = oldTableKeyCount;
+    m_usingTable = true;
 
 #if USE_SINGLE_ENTRY
-    UString::Rep *key = _singleEntry.key;
+    UString::Rep* key = m_singleEntryKey;
     if (key) {
-        insert(key, _singleEntry.value, _singleEntry.attributes, 0);
-        _singleEntry.key = 0;
+        insert(key, oldSingleEntryValue, m_singleEntryAttributes, 0);
+        m_singleEntryKey = 0;
         // update the count, because single entries don't count towards
         // the table key count
-        ++_table->keyCount;
-        assert(_table->keyCount == 1);
+        ++m_u.table->keyCount;
+        assert(m_u.table->keyCount == 1);
     }
 #endif
     
@@ -459,7 +462,7 @@ void PropertyMap::rehash(int newTableSize)
             insert(key, entry.value, entry.attributes, index);
         }
     }
-    _table->lastIndexUsed = lastIndexUsed;
+    m_u.table->lastIndexUsed = lastIndexUsed;
 
     fastFree(oldTable);
 
@@ -476,12 +479,12 @@ void PropertyMap::remove(const Identifier &name)
 
     UString::Rep *key;
 
-    if (!_table) {
+    if (!m_usingTable) {
 #if USE_SINGLE_ENTRY
-        key = _singleEntry.key;
+        key = m_singleEntryKey;
         if (rep == key) {
             key->deref();
-            _singleEntry.key = 0;
+            m_singleEntryKey = 0;
             checkConsistency();
         }
 #endif
@@ -490,8 +493,8 @@ void PropertyMap::remove(const Identifier &name)
 
     // Find the thing to remove.
     unsigned h = rep->hash();
-    int sizeMask = _table->sizeMask;
-    Entry *entries = _table->entries;
+    int sizeMask = m_u.table->sizeMask;
+    Entry *entries = m_u.table->entries;
     int i = h & sizeMask;
     int k = 0;
 #if DUMP_STATISTICS
@@ -519,11 +522,11 @@ void PropertyMap::remove(const Identifier &name)
     entries[i].key = key;
     entries[i].value = 0;
     entries[i].attributes = DontEnum;
-    assert(_table->keyCount >= 1);
-    --_table->keyCount;
-    ++_table->sentinelCount;
+    assert(m_u.table->keyCount >= 1);
+    --m_u.table->keyCount;
+    ++m_u.table->sentinelCount;
     
-    if (_table->sentinelCount * 4 >= _table->size)
+    if (m_u.table->sentinelCount * 4 >= m_u.table->size)
         rehash();
 
     checkConsistency();
@@ -531,10 +534,10 @@ void PropertyMap::remove(const Identifier &name)
 
 void PropertyMap::mark() const
 {
-    if (!_table) {
+    if (!m_usingTable) {
 #if USE_SINGLE_ENTRY
-        if (_singleEntry.key) {
-            JSValue *v = _singleEntry.value;
+        if (m_singleEntryKey) {
+            JSValue* v = m_u.singleEntryValue;
             if (!v->marked())
                 v->mark();
         }
@@ -542,8 +545,8 @@ void PropertyMap::mark() const
         return;
     }
 
-    int minimumKeysToProcess = _table->keyCount;
-    Entry *entries = _table->entries;
+    int minimumKeysToProcess = m_u.table->keyCount;
+    Entry *entries = m_u.table->entries;
     for (int i = 0; i < minimumKeysToProcess; i++) {
         JSValue *v = entries[i].value;
         if (v) {
@@ -568,16 +571,16 @@ static int comparePropertyMapEntryIndices(const void *a, const void *b)
 
 bool PropertyMap::containsGettersOrSetters() const
 {
-    if (!_table) {
+    if (!m_usingTable) {
 #if USE_SINGLE_ENTRY
-        return !!(_singleEntry.attributes & GetterSetter);
+        return !!(m_singleEntryAttributes & GetterSetter);
 #else
         return false;
 #endif
     }
 
-    for (int i = 0; i != _table->size; ++i) {
-        if (_table->entries[i].attributes & GetterSetter)
+    for (int i = 0; i != m_u.table->size; ++i) {
+        if (m_u.table->entries[i].attributes & GetterSetter)
             return true;
     }
     
@@ -586,22 +589,22 @@ bool PropertyMap::containsGettersOrSetters() const
 
 void PropertyMap::getEnumerablePropertyNames(PropertyNameArray& propertyNames) const
 {
-    if (!_table) {
+    if (!m_usingTable) {
 #if USE_SINGLE_ENTRY
-        UString::Rep *key = _singleEntry.key;
-        if (key && !(_singleEntry.attributes & DontEnum))
+        UString::Rep* key = m_singleEntryKey;
+        if (key && !(m_singleEntryAttributes & DontEnum))
             propertyNames.add(Identifier(key));
 #endif
         return;
     }
 
     // Allocate a buffer to use to sort the keys.
-    Vector<Entry*, smallMapThreshold> sortedEnumerables(_table->keyCount);
+    Vector<Entry*, smallMapThreshold> sortedEnumerables(m_u.table->keyCount);
 
     // Get pointers to the enumerable entries in the buffer.
     Entry** p = sortedEnumerables.data();
-    int size = _table->size;
-    Entry* entries = _table->entries;
+    int size = m_u.table->size;
+    Entry* entries = m_u.table->entries;
     for (int i = 0; i != size; ++i) {
         Entry* e = &entries[i];
         if (e->key && !(e->attributes & DontEnum))
@@ -618,9 +621,9 @@ void PropertyMap::getEnumerablePropertyNames(PropertyNameArray& propertyNames) c
 
 void PropertyMap::getSparseArrayPropertyNames(PropertyNameArray& propertyNames) const
 {
-    if (!_table) {
+    if (!m_usingTable) {
 #if USE_SINGLE_ENTRY
-        UString::Rep *key = _singleEntry.key;
+        UString::Rep *key = m_singleEntryKey;
         if (key) {
             UString k(key);
             bool fitsInUInt32;
@@ -632,8 +635,8 @@ void PropertyMap::getSparseArrayPropertyNames(PropertyNameArray& propertyNames)
         return;
     }
 
-    int size = _table->size;
-    Entry *entries = _table->entries;
+    int size = m_u.table->size;
+    Entry *entries = m_u.table->entries;
     for (int i = 0; i != size; ++i) {
         UString::Rep *key = entries[i].key;
         if (isValid(key)) {
@@ -650,14 +653,14 @@ void PropertyMap::save(SavedProperties &p) const
 {
     int count = 0;
 
-    if (!_table) {
+    if (!m_usingTable) {
 #if USE_SINGLE_ENTRY
-        if (_singleEntry.key && !(_singleEntry.attributes & (ReadOnly | Function)))
+        if (m_singleEntryKey && !(m_singleEntryAttributes & (ReadOnly | Function)))
             ++count;
 #endif
     } else {
-        int size = _table->size;
-        Entry *entries = _table->entries;
+        int size = m_u.table->size;
+        Entry *entries = m_u.table->entries;
         for (int i = 0; i != size; ++i)
             if (isValid(entries[i].key) && !(entries[i].attributes & (ReadOnly | Function)))
                 ++count;
@@ -673,12 +676,12 @@ void PropertyMap::save(SavedProperties &p) const
     
     SavedProperty *prop = p._properties.get();
     
-    if (!_table) {
+    if (!m_usingTable) {
 #if USE_SINGLE_ENTRY
-        if (_singleEntry.key && !(_singleEntry.attributes & (ReadOnly | Function))) {
-            prop->key = Identifier(_singleEntry.key);
-            prop->value = _singleEntry.value;
-            prop->attributes = _singleEntry.attributes;
+        if (m_singleEntryKey && !(m_singleEntryAttributes & (ReadOnly | Function))) {
+            prop->key = Identifier(m_singleEntryKey);
+            prop->value = m_u.singleEntryValue;
+            prop->attributes = m_singleEntryAttributes;
             ++prop;
         }
 #endif
@@ -691,8 +694,8 @@ void PropertyMap::save(SavedProperties &p) const
 
         // Get pointers to the entries in the buffer.
         Entry** p = sortedEntries.data();
-        int size = _table->size;
-        Entry* entries = _table->entries;
+        int size = m_u.table->size;
+        Entry* entries = m_u.table->entries;
         for (int i = 0; i != size; ++i) {
             Entry *e = &entries[i];
             if (isValid(e->key) && !(e->attributes & (ReadOnly | Function)))
@@ -723,13 +726,13 @@ void PropertyMap::restore(const SavedProperties &p)
 
 void PropertyMap::checkConsistency()
 {
-    if (!_table)
+    if (!m_usingTable)
         return;
 
     int count = 0;
     int sentinelCount = 0;
-    for (int j = 0; j != _table->size; ++j) {
-        UString::Rep *rep = _table->entries[j].key;
+    for (int j = 0; j != m_u.table->size; ++j) {
+        UString::Rep *rep = m_u.table->entries[j].key;
         if (!rep)
             continue;
         if (rep == deletedSentinel()) {
@@ -737,23 +740,23 @@ void PropertyMap::checkConsistency()
             continue;
         }
         unsigned h = rep->hash();
-        int i = h & _table->sizeMask;
+        int i = h & m_u.table->sizeMask;
         int k = 0;
-        while (UString::Rep *key = _table->entries[i].key) {
+        while (UString::Rep *key = m_u.table->entries[i].key) {
             if (rep == key)
                 break;
             if (k == 0)
-                k = 1 | (h % _table->sizeMask);
-            i = (i + k) & _table->sizeMask;
+                k = 1 | (h % m_u.table->sizeMask);
+            i = (i + k) & m_u.table->sizeMask;
         }
         assert(i == j);
         ++count;
     }
-    assert(count == _table->keyCount);
-    assert(sentinelCount == _table->sentinelCount);
-    assert(_table->size >= 16);
-    assert(_table->sizeMask);
-    assert(_table->size == _table->sizeMask + 1);
+    assert(count == m_u.table->keyCount);
+    assert(sentinelCount == m_u.table->sentinelCount);
+    assert(m_u.table->size >= 16);
+    assert(m_u.table->sizeMask);
+    assert(m_u.table->size == m_u.table->sizeMask + 1);
 }
 
 #endif // DO_CONSISTENCY_CHECK
index 00793cb2a99675d471fe46bbf26e5d4170c12f0c..6702c8fdde3b143740418455c2ac5c21c453c8e4 100644 (file)
@@ -1,4 +1,4 @@
-// -*- c-basic-offset: 2 -*-
+// -*- mode: c++; c-basic-offset: 4 -*-
 /*
  *  This file is part of the KDE libraries
  *  Copyright (C) 2004, 2005, 2006 Apple Computer, Inc.
@@ -58,8 +58,7 @@ namespace KJS {
         PropertyMapHashTableEntry() : key(0) { }
         UString::Rep *key;
         JSValue *value;
-        short attributes;
-        short globalGetterSetterFlag;
+        int attributes;
         int index;
     };
 
@@ -86,8 +85,8 @@ namespace KJS {
         void save(SavedProperties &) const;
         void restore(const SavedProperties &p);
 
-        bool hasGetterSetterProperties() const { return !!_singleEntry.globalGetterSetterFlag; }
-        void setHasGetterSetterProperties(bool f) { _singleEntry.globalGetterSetterFlag = f; }
+        bool hasGetterSetterProperties() const { return m_getterSetterFlag; }
+        void setHasGetterSetterProperties(bool f) { m_getterSetterFlag = f; }
 
         bool containsGettersOrSetters() const;
     private:
@@ -103,15 +102,24 @@ namespace KJS {
         typedef PropertyMapHashTableEntry Entry;
         typedef PropertyMapHashTable Table;
 
-        Table *_table;
-        
-        Entry _singleEntry;
+        UString::Rep* m_singleEntryKey;
+        union {
+          JSValue* singleEntryValue;
+          Table* table;
+        } m_u;
+
+        short m_singleEntryAttributes;
+        bool m_getterSetterFlag;
+        bool m_usingTable;
     };
 
-inline PropertyMap::PropertyMap() : _table(0)
-{
-    _singleEntry.globalGetterSetterFlag = 0;
-}
+    inline PropertyMap::PropertyMap() 
+        : m_singleEntryKey(0)
+        , m_getterSetterFlag(false)
+        , m_usingTable(false)
+
+    {
+    }
 
 } // namespace