Changeset 50254 in webkit for trunk/JavaScriptCore/runtime


Ignore:
Timestamp:
Oct 28, 2009, 6:25:02 PM (16 years ago)
Author:
[email protected]
Message:

Improve for..in enumeration performance
https://bugs.webkit.org/show_bug.cgi?id=30887

Reviewed by Geoff Garen.

Improve indexing of an object with a for..in iterator by
identifying cases where get_by_val is being used with a iterator
as the subscript and replace it with a new get_by_pname
bytecode. get_by_pname then optimizes lookups that directly access
the base object.

Location:
trunk/JavaScriptCore/runtime
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/runtime/JSObject.h

    r49721 r50254  
    203203        bool isUsingInlineStorage() const { return m_structure->isUsingInlineStorage(); }
    204204
    205         static const size_t inlineStorageCapacity = sizeof(EncodedJSValue) == 2 * sizeof(void*) ? 4 : 3;
    206         static const size_t nonInlineBaseStorageCapacity = 16;
     205        static const unsigned inlineStorageCapacity = sizeof(EncodedJSValue) == 2 * sizeof(void*) ? 4 : 3;
     206        static const unsigned nonInlineBaseStorageCapacity = 16;
    207207
    208208        static PassRefPtr<Structure> createStructure(JSValue prototype)
  • trunk/JavaScriptCore/runtime/JSPropertyNameIterator.cpp

    r49734 r50254  
    4444    PropertyNameArray propertyNames(exec);
    4545    o->getPropertyNames(exec, propertyNames);
    46     JSPropertyNameIterator* jsPropertyNameIterator = new (exec) JSPropertyNameIterator(exec, propertyNames.data());
     46    size_t numCacheableSlots = 0;
     47    if (!o->structure()->hasNonEnumerableProperties() && !o->structure()->hasAnonymousSlots() &&
     48        !o->structure()->isUncacheableDictionary() && !o->structure()->typeInfo().overridesGetPropertyNames())
     49        numCacheableSlots = o->structure()->propertyStorageSize();
     50
     51    JSPropertyNameIterator* jsPropertyNameIterator = new (exec) JSPropertyNameIterator(exec, propertyNames.data(), numCacheableSlots);
    4752
    4853    if (o->structure()->isDictionary())
  • trunk/JavaScriptCore/runtime/JSPropertyNameIterator.h

    r49955 r50254  
    5555        virtual void markChildren(MarkStack&);
    5656
     57        bool getOffset(size_t i, int& offset)
     58        {
     59            if (i >= m_numCacheableSlots)
     60                return false;
     61            offset = i;
     62            return true;
     63        }
     64
    5765        JSValue get(ExecState*, JSObject*, size_t i);
    5866        size_t size() { return m_jsStringsSize; }
     
    6573
    6674    private:
    67         JSPropertyNameIterator(ExecState*, PropertyNameArrayData* propertyNameArrayData);
     75        JSPropertyNameIterator(ExecState*, PropertyNameArrayData* propertyNameArrayData, size_t numCacheableSlot);
    6876
    6977        Structure* m_cachedStructure;
    7078        RefPtr<StructureChain> m_cachedPrototypeChain;
    71         size_t m_jsStringsSize;
     79        uint32_t m_numCacheableSlots;
     80        uint32_t m_jsStringsSize;
    7281        OwnArrayPtr<JSValue> m_jsStrings;
    7382    };
    7483
    75 inline JSPropertyNameIterator::JSPropertyNameIterator(ExecState* exec, PropertyNameArrayData* propertyNameArrayData)
     84inline JSPropertyNameIterator::JSPropertyNameIterator(ExecState* exec, PropertyNameArrayData* propertyNameArrayData, size_t numCacheableSlots)
    7685    : JSCell(exec->globalData().propertyNameIteratorStructure.get())
    7786    , m_cachedStructure(0)
     87    , m_numCacheableSlots(numCacheableSlots)
    7888    , m_jsStringsSize(propertyNameArrayData->propertyNameVector().size())
    7989    , m_jsStrings(new JSValue[m_jsStringsSize])
  • trunk/JavaScriptCore/runtime/Structure.cpp

    r49734 r50254  
    376376    transition->m_propertyStorageCapacity = structure->m_propertyStorageCapacity;
    377377    transition->m_hasGetterSetterProperties = structure->m_hasGetterSetterProperties;
     378    transition->m_hasNonEnumerableProperties = structure->m_hasNonEnumerableProperties;
    378379
    379380    if (structure->m_propertyTable) {
     
    418419    transition->m_propertyStorageCapacity = structure->m_propertyStorageCapacity;
    419420    transition->m_hasGetterSetterProperties = structure->m_hasGetterSetterProperties;
     421    transition->m_hasNonEnumerableProperties = structure->m_hasNonEnumerableProperties;
    420422
    421423    // Don't set m_offset, as one can not transition to this.
     
    434436    transition->m_propertyStorageCapacity = structure->m_propertyStorageCapacity;
    435437    transition->m_hasGetterSetterProperties = structure->m_hasGetterSetterProperties;
     438    transition->m_hasNonEnumerableProperties = structure->m_hasNonEnumerableProperties;
    436439
    437440    // Don't set m_offset, as one can not transition to this.
     
    465468    transition->m_propertyStorageCapacity = structure->m_propertyStorageCapacity;
    466469    transition->m_hasGetterSetterProperties = structure->m_hasGetterSetterProperties;
     470    transition->m_hasNonEnumerableProperties = structure->m_hasNonEnumerableProperties;
    467471
    468472    if (structure->m_propertyTable) {
     
    493497    transition->m_propertyStorageCapacity = structure->m_propertyStorageCapacity;
    494498    transition->m_hasGetterSetterProperties = transition->m_hasGetterSetterProperties;
     499    transition->m_hasNonEnumerableProperties = structure->m_hasNonEnumerableProperties;
    495500
    496501    // Don't set m_offset, as one can not transition to this.
     
    511516    transition->m_propertyStorageCapacity = structure->m_propertyStorageCapacity;
    512517    transition->m_hasGetterSetterProperties = structure->m_hasGetterSetterProperties;
     518    transition->m_hasNonEnumerableProperties = structure->m_hasNonEnumerableProperties;
    513519   
    514520    structure->materializePropertyMapIfNecessary();
     
    551557
    552558    m_isPinnedPropertyTable = true;
     559    if (attributes & DontEnum)
     560        m_hasNonEnumerableProperties = true;
     561
    553562    size_t offset = put(propertyName, attributes, specificValue);
    554563    if (propertyStorageSize() > propertyStorageCapacity())
  • trunk/JavaScriptCore/runtime/Structure.h

    r49734 r50254  
    9696
    9797        void growPropertyStorageCapacity();
    98         size_t propertyStorageCapacity() const { return m_propertyStorageCapacity; }
    99         size_t propertyStorageSize() const { return m_propertyTable ? m_propertyTable->keyCount + m_propertyTable->anonymousSlotCount + (m_propertyTable->deletedOffsets ? m_propertyTable->deletedOffsets->size() : 0) : m_offset + 1; }
     98        unsigned propertyStorageCapacity() const { return m_propertyStorageCapacity; }
     99        unsigned propertyStorageSize() const { return m_propertyTable ? m_propertyTable->keyCount + m_propertyTable->anonymousSlotCount + (m_propertyTable->deletedOffsets ? m_propertyTable->deletedOffsets->size() : 0) : m_offset + 1; }
    100100        bool isUsingInlineStorage() const;
    101101
     
    120120        void setHasGetterSetterProperties(bool hasGetterSetterProperties) { m_hasGetterSetterProperties = hasGetterSetterProperties; }
    121121
     122        bool hasNonEnumerableProperties() const { return m_hasNonEnumerableProperties; }
     123
     124        bool hasAnonymousSlots() const { return m_propertyTable && m_propertyTable->anonymousSlotCount; }
     125       
    122126        bool isEmpty() const { return m_propertyTable ? !m_propertyTable->keyCount : m_offset == noOffset; }
    123127
     
    191195        PropertyMapHashTable* m_propertyTable;
    192196
    193         size_t m_propertyStorageCapacity;
     197        uint32_t m_propertyStorageCapacity;
    194198        signed char m_offset;
    195199
     
    197201        bool m_isPinnedPropertyTable : 1;
    198202        bool m_hasGetterSetterProperties : 1;
     203        bool m_hasNonEnumerableProperties : 1;
    199204#if COMPILER(WINSCW)
    200205        // Workaround for Symbian WINSCW compiler that cannot resolve unsigned type of the declared
Note: See TracChangeset for help on using the changeset viewer.