Ignore:
Timestamp:
Feb 28, 2011, 7:53:09 PM (14 years ago)
Author:
[email protected]
Message:

Bug 55423 - Clean up property tables in Structure

Reviewed by Sam Weinig & Darin Adler.

Encapsulate, reduce duplication of table search code,
and reduce the size of the tables (remove the index,
just maintain the tables in the correct order).

Shows a 0.5% - 1% progression on sunspider.

../JavaScriptCore:

(JSC::isPowerOf2):
(JSC::nextPowerOf2):

bit ops used to calculate table size.

(JSC::PropertyMapEntry::PropertyMapEntry):
(JSC::PropertyTable::ordered_iterator::operator++):
(JSC::PropertyTable::ordered_iterator::operator==):
(JSC::PropertyTable::ordered_iterator::operator!=):
(JSC::PropertyTable::ordered_iterator::operator*):
(JSC::PropertyTable::ordered_iterator::operator->):
(JSC::PropertyTable::ordered_iterator::ordered_iterator):

implementation of the iterator types

(JSC::PropertyTable::PropertyTable):
(JSC::PropertyTable::~PropertyTable):

constructors take an initial capacity for the table,
a table to copy, or both.

(JSC::PropertyTable::begin):
(JSC::PropertyTable::end):

create in-order iterators.

(JSC::PropertyTable::find):

search the hash table

(JSC::PropertyTable::add):

add a value to the hash table

(JSC::PropertyTable::remove):

remove a value from the hash table

(JSC::PropertyTable::size):
(JSC::PropertyTable::isEmpty):

accessors.

(JSC::PropertyTable::propertyStorageSize):
(JSC::PropertyTable::clearDeletedOffsets):
(JSC::PropertyTable::hasDeletedOffset):
(JSC::PropertyTable::getDeletedOffset):
(JSC::PropertyTable::addDeletedOffset):

cache deleted (available) offsets in the property storage array.

(JSC::PropertyTable::copy):

take a copy of the PropertyTable, potentially expanding the capacity.

(JSC::PropertyTable::sizeInMemory):

used for DEBUG build statistics

(JSC::PropertyTable::reinsert):
(JSC::PropertyTable::rehash):
(JSC::PropertyTable::tableCapacity):
(JSC::PropertyTable::deletedEntryIndex):
(JSC::PropertyTable::skipDeletedEntries):
(JSC::PropertyTable::table):
(JSC::PropertyTable::usedCount):
(JSC::PropertyTable::dataSize):
(JSC::PropertyTable::sizeForCapacity):
(JSC::PropertyTable::canInsert):

these methods provide internal implementation.

  • runtime/Structure.cpp:

(JSC::Structure::dumpStatistics):
(JSC::Structure::~Structure):
(JSC::Structure::materializePropertyMap):
(JSC::Structure::despecifyDictionaryFunction):
(JSC::Structure::addPropertyTransition):
(JSC::Structure::flattenDictionaryStructure):
(JSC::Structure::copyPropertyTable):
(JSC::Structure::get):
(JSC::Structure::despecifyFunction):
(JSC::Structure::despecifyAllFunctions):
(JSC::Structure::put):
(JSC::Structure::remove):
(JSC::Structure::createPropertyMap):
(JSC::Structure::getPropertyNames):
(JSC::PropertyTable::checkConsistency):
(JSC::Structure::checkConsistency):

factored out code to PropertyMapHashTable.h

  • runtime/Structure.h:

(JSC::Structure::propertyStorageSize):
(JSC::Structure::isEmpty):
(JSC::Structure::get):

factored out code to PropertyMapHashTable.h

../JavaScriptGlue:

  • ForwardingHeaders/wtf/HashTable.h: Added.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/runtime/Structure.h

    r79435 r79963  
    4141#include <wtf/RefCounted.h>
    4242
    43 #ifndef NDEBUG
    44 #define DUMP_PROPERTYMAP_STATS 0
    45 #else
    46 #define DUMP_PROPERTYMAP_STATS 0
    47 #endif
    4843
    4944namespace JSC {
     
    106101        void growPropertyStorageCapacity();
    107102        unsigned propertyStorageCapacity() const { return m_propertyStorageCapacity; }
    108         unsigned propertyStorageSize() const { return m_anonymousSlotCount + (m_propertyTable ? m_propertyTable->keyCount + (m_propertyTable->deletedOffsets ? m_propertyTable->deletedOffsets->size() : 0) : static_cast<unsigned>(m_offset + 1)); }
     103        unsigned propertyStorageSize() const { return m_anonymousSlotCount + (m_propertyTable ? m_propertyTable->propertyStorageSize() : static_cast<unsigned>(m_offset + 1)); }
    109104        bool isUsingInlineStorage() const;
    110105
    111106        size_t get(const Identifier& propertyName);
    112         size_t get(const StringImpl* rep, unsigned& attributes, JSCell*& specificValue);
     107        size_t get(StringImpl* propertyName, unsigned& attributes, JSCell*& specificValue);
    113108        size_t get(const Identifier& propertyName, unsigned& attributes, JSCell*& specificValue)
    114109        {
     
    125120        unsigned anonymousSlotCount() const { return m_anonymousSlotCount; }
    126121       
    127         bool isEmpty() const { return m_propertyTable ? !m_propertyTable->keyCount : m_offset == noOffset; }
     122        bool isEmpty() const { return m_propertyTable ? m_propertyTable->isEmpty() : m_offset == noOffset; }
    128123
    129124        void despecifyDictionaryFunction(const Identifier& propertyName);
     
    158153        size_t remove(const Identifier& propertyName);
    159154
    160         void expandPropertyMapHashTable();
    161         void rehashPropertyMapHashTable();
    162         void rehashPropertyMapHashTable(unsigned newTableSize);
    163         void createPropertyMapHashTable();
    164         void createPropertyMapHashTable(unsigned newTableSize);
    165         void insertIntoPropertyMapHashTable(const PropertyMapEntry&);
     155        void createPropertyMap(unsigned keyCount = 0);
    166156        void checkConsistency();
    167157
     
    169159        void despecifyAllFunctions();
    170160
    171         PropertyMapHashTable* copyPropertyTable();
     161        PropertyTable* copyPropertyTable();
    172162        void materializePropertyMap();
    173163        void materializePropertyMapIfNecessary()
    174164        {
    175             if (m_propertyTable || !m_previous)             
    176                 return;
    177             materializePropertyMap();
     165            if (!m_propertyTable && m_previous)
     166                materializePropertyMap();
    178167        }
    179168
     
    186175        bool isValid(ExecState*, StructureChain* cachedPrototypeChain) const;
    187176
    188         static const unsigned emptyEntryIndex = 0;
    189    
    190177        static const signed char s_maxTransitionLength = 64;
    191178
     
    209196        WeakGCPtr<JSPropertyNameIterator> m_enumerationCache;
    210197
    211         PropertyMapHashTable* m_propertyTable;
     198        OwnPtr<PropertyTable> m_propertyTable;
    212199
    213200        uint32_t m_propertyStorageCapacity;
     
    235222    inline size_t Structure::get(const Identifier& propertyName)
    236223    {
    237         ASSERT(!propertyName.isNull());
    238 
    239224        materializePropertyMapIfNecessary();
    240225        if (!m_propertyTable)
    241             return WTF::notFound;
    242 
    243         StringImpl* rep = propertyName.impl();
    244 
    245         unsigned i = rep->existingHash();
    246 
    247 #if DUMP_PROPERTYMAP_STATS
    248         ++numProbes;
    249 #endif
    250 
    251         unsigned entryIndex = m_propertyTable->entryIndices[i & m_propertyTable->sizeMask];
    252         if (entryIndex == emptyEntryIndex)
    253             return WTF::notFound;
    254 
    255         if (rep == m_propertyTable->entries()[entryIndex - 1].key)
    256             return m_propertyTable->entries()[entryIndex - 1].offset;
    257 
    258 #if DUMP_PROPERTYMAP_STATS
    259         ++numCollisions;
    260 #endif
    261 
    262         unsigned k = 1 | WTF::doubleHash(rep->existingHash());
    263 
    264         while (1) {
    265             i += k;
    266 
    267 #if DUMP_PROPERTYMAP_STATS
    268             ++numRehashes;
    269 #endif
    270 
    271             entryIndex = m_propertyTable->entryIndices[i & m_propertyTable->sizeMask];
    272             if (entryIndex == emptyEntryIndex)
    273                 return WTF::notFound;
    274 
    275             if (rep == m_propertyTable->entries()[entryIndex - 1].key)
    276                 return m_propertyTable->entries()[entryIndex - 1].offset;
    277         }
     226            return notFound;
     227
     228        PropertyMapEntry* entry = m_propertyTable->find(propertyName.impl()).first;
     229        ASSERT(!entry || entry->offset >= m_anonymousSlotCount);
     230        return entry ? entry->offset : notFound;
    278231    }
    279232
Note: See TracChangeset for help on using the changeset viewer.