2008-12-29 Sam Weinig <sam@webkit.org>
authorweinig@apple.com <weinig@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 30 Dec 2008 00:28:40 +0000 (00:28 +0000)
committerweinig@apple.com <weinig@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 30 Dec 2008 00:28:40 +0000 (00:28 +0000)
        Reviewed by Oliver Hunt.

        Patch for https://bugs.webkit.org/show_bug.cgi?id=23026
        Move the deleted offsets vector into the PropertyMap

        Saves 3 words per Structure.

        * runtime/PropertyMapHashTable.h:
        * runtime/Structure.cpp:
        (JSC::Structure::addPropertyTransition):
        (JSC::Structure::changePrototypeTransition):
        (JSC::Structure::getterSetterTransition):
        (JSC::Structure::toDictionaryTransition):
        (JSC::Structure::fromDictionaryTransition):
        (JSC::Structure::copyPropertyTable):
        (JSC::Structure::put):
        (JSC::Structure::remove):
        (JSC::Structure::rehashPropertyMapHashTable):
        * runtime/Structure.h:
        (JSC::Structure::propertyStorageSize):

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

JavaScriptCore/ChangeLog
JavaScriptCore/runtime/PropertyMapHashTable.h
JavaScriptCore/runtime/Structure.cpp
JavaScriptCore/runtime/Structure.h

index 0aa1259..aa24b53 100644 (file)
@@ -1,3 +1,26 @@
+2008-12-29  Sam Weinig  <sam@webkit.org>
+
+        Reviewed by Oliver Hunt.
+
+        Patch for https://bugs.webkit.org/show_bug.cgi?id=23026
+        Move the deleted offsets vector into the PropertyMap
+
+        Saves 3 words per Structure.
+
+        * runtime/PropertyMapHashTable.h:
+        * runtime/Structure.cpp:
+        (JSC::Structure::addPropertyTransition):
+        (JSC::Structure::changePrototypeTransition):
+        (JSC::Structure::getterSetterTransition):
+        (JSC::Structure::toDictionaryTransition):
+        (JSC::Structure::fromDictionaryTransition):
+        (JSC::Structure::copyPropertyTable):
+        (JSC::Structure::put):
+        (JSC::Structure::remove):
+        (JSC::Structure::rehashPropertyMapHashTable):
+        * runtime/Structure.h:
+        (JSC::Structure::propertyStorageSize):
+
 2008-12-29  Cameron Zwarich  <cwzwarich@uwaterloo.ca>
 
         Reviewed by Oliver Hunt.
index 62c5e6a..935df68 100644 (file)
@@ -22,6 +22,7 @@
 #define PropertyMapHashTable_h
 
 #include "UString.h"
+#include <wtf/Vector.h>
 
 namespace JSC {
 
@@ -58,6 +59,7 @@ namespace JSC {
         unsigned keyCount;
         unsigned deletedSentinelCount;
         unsigned lastIndexUsed;
+        Vector<unsigned>* deletedOffsets;
         unsigned entryIndices[1];
 
         PropertyMapEntry* entries()
index 069c58b..be36056 100644 (file)
@@ -38,7 +38,7 @@
 #include <wtf/Threading.h>
 #endif
 
-#define DUMP_STRUCTURE_ID_STATISTICS 0
+#define DUMP_STRUCTURE_ID_STATISTICS 1
 
 #ifndef NDEBUG
 #define DO_PROPERTYMAP_CONSTENCY_CHECK 0
@@ -101,6 +101,8 @@ void Structure::dumpStatistics()
         if (structure->m_propertyTable) {
             ++numberWithPropertyMaps;
             totalPropertyMapsSize += PropertyMapHashTable::allocationSize(structure->m_propertyTable->size);
+            if (structure->m_propertyTable->deletedOffsets)
+                totalPropertyMapsSize += (structure->m_propertyTable->deletedOffsets->capacity() * sizeof(unsigned)); 
         }
     }
 
@@ -378,7 +380,6 @@ PassRefPtr<Structure> Structure::addPropertyTransition(Structure* structure, con
 {
     ASSERT(!structure->m_isDictionary);
     ASSERT(structure->typeInfo().type() == ObjectType);
-    ASSERT(structure->m_deletedOffsets.isEmpty());
     ASSERT(!Structure::addPropertyTransitionToExistingStructure(structure, propertyName, attributes, offset));
 
     if (structure->m_transitionCount > s_maxTransitionLength) {
@@ -450,7 +451,6 @@ PassRefPtr<Structure> Structure::changePrototypeTransition(Structure* structure,
     RefPtr<Structure> transition = create(prototype, structure->typeInfo());
 
     transition->m_transitionCount = structure->m_transitionCount + 1;
-    transition->m_deletedOffsets = structure->m_deletedOffsets;
     transition->m_propertyStorageCapacity = structure->m_propertyStorageCapacity;
     transition->m_hasGetterSetterProperties = structure->m_hasGetterSetterProperties;
 
@@ -467,7 +467,6 @@ PassRefPtr<Structure> Structure::getterSetterTransition(Structure* structure)
 {
     RefPtr<Structure> transition = create(structure->storedPrototype(), structure->typeInfo());
     transition->m_transitionCount = structure->m_transitionCount + 1;
-    transition->m_deletedOffsets = structure->m_deletedOffsets;
     transition->m_propertyStorageCapacity = structure->m_propertyStorageCapacity;
     transition->m_hasGetterSetterProperties = transition->m_hasGetterSetterProperties;
 
@@ -486,7 +485,6 @@ PassRefPtr<Structure> Structure::toDictionaryTransition(Structure* structure)
 
     RefPtr<Structure> transition = create(structure->m_prototype, structure->typeInfo());
     transition->m_isDictionary = true;
-    transition->m_deletedOffsets = structure->m_deletedOffsets;
     transition->m_propertyStorageCapacity = structure->m_propertyStorageCapacity;
     transition->m_hasGetterSetterProperties = structure->m_hasGetterSetterProperties;
 
@@ -507,7 +505,7 @@ PassRefPtr<Structure> Structure::fromDictionaryTransition(Structure* structure)
 
     // FIMXE: We can make this more efficient by canonicalizing the Structure (draining the
     // deleted offsets vector) before transitioning from dictionary. 
-    if (structure->m_deletedOffsets.isEmpty())
+    if (!structure->m_propertyTable || !structure->m_propertyTable->deletedOffsets || structure->m_propertyTable->deletedOffsets->isEmpty())
         structure->m_isDictionary = false;
 
     return structure;
@@ -603,6 +601,10 @@ PropertyMapHashTable* Structure::copyPropertyTable()
             key->ref();
     }
 
+    // Copy the deletedOffsets vector.
+    if (m_propertyTable->deletedOffsets)
+        newTable->deletedOffsets = new Vector<unsigned>(*m_propertyTable->deletedOffsets);
+
     return newTable;
 }
 
@@ -728,9 +730,9 @@ size_t Structure::put(const Identifier& propertyName, unsigned attributes)
     m_propertyTable->entries()[entryIndex - 1].index = ++m_propertyTable->lastIndexUsed;
 
     unsigned newOffset;
-    if (!m_deletedOffsets.isEmpty()) {
-        newOffset = m_deletedOffsets.last();
-        m_deletedOffsets.removeLast();
+    if (m_propertyTable->deletedOffsets && !m_propertyTable->deletedOffsets->isEmpty()) {
+        newOffset = m_propertyTable->deletedOffsets->last();
+        m_propertyTable->deletedOffsets->removeLast();
     } else
         newOffset = m_propertyTable->keyCount;
     m_propertyTable->entries()[entryIndex - 1].offset = newOffset;
@@ -798,7 +800,10 @@ size_t Structure::remove(const Identifier& propertyName)
     m_propertyTable->entries()[entryIndex - 1].key = 0;
     m_propertyTable->entries()[entryIndex - 1].attributes = 0;
     m_propertyTable->entries()[entryIndex - 1].offset = 0;
-    m_deletedOffsets.append(offset);
+
+    if (!m_propertyTable->deletedOffsets)
+        m_propertyTable->deletedOffsets = new Vector<unsigned>;
+    m_propertyTable->deletedOffsets->append(offset);
 
     ASSERT(m_propertyTable->keyCount >= 1);
     --m_propertyTable->keyCount;
@@ -903,6 +908,7 @@ void Structure::rehashPropertyMapHashTable(unsigned newTableSize)
         }
     }
     m_propertyTable->lastIndexUsed = lastIndexUsed;
+    m_propertyTable->deletedOffsets = oldTable->deletedOffsets;
 
     fastFree(oldTable);
 
index c204a7f..68dc3c2 100644 (file)
@@ -34,9 +34,6 @@
 #include "StructureTransitionTable.h"
 #include "TypeInfo.h"
 #include "UString.h"
-#include <wtf/HashFunctions.h>
-#include <wtf/HashTraits.h>
-#include <wtf/OwnArrayPtr.h>
 #include <wtf/PassRefPtr.h>
 #include <wtf/RefCounted.h>
 
@@ -100,7 +97,7 @@ namespace JSC {
 
         void growPropertyStorageCapacity();
         size_t propertyStorageCapacity() const { return m_propertyStorageCapacity; }
-        size_t propertyStorageSize() const { return m_propertyTable ? m_propertyTable->keyCount + m_deletedOffsets.size() : m_offset + 1; }
+        size_t propertyStorageSize() const { return m_propertyTable ? m_propertyTable->keyCount + (m_propertyTable->deletedOffsets ? m_propertyTable->deletedOffsets->size() : 0) : m_offset + 1; }
 
         size_t get(const Identifier& propertyName);
         size_t get(const Identifier& propertyName, unsigned& attributes);
@@ -163,7 +160,6 @@ namespace JSC {
         RefPtr<PropertyNameArrayData> m_cachedPropertyNameArrayData;
 
         PropertyMapHashTable* m_propertyTable;
-        Vector<unsigned> m_deletedOffsets;
 
         size_t m_propertyStorageCapacity;
         size_t m_offset;