Changeset 37388 in webkit for trunk/JavaScriptCore


Ignore:
Timestamp:
Oct 7, 2008, 1:49:36 PM (17 years ago)
Author:
[email protected]
Message:

2008-10-07 Sam Weinig <[email protected]>

Reviewed by Cameron Zwarich.

Roll r37370 back in with bug fixes.

  • PropertyMap::storageSize() should reflect the number of keys + deletedOffsets and has nothing to do with the internal deletedSentinel count anymore.
Location:
trunk/JavaScriptCore
Files:
10 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/ChangeLog

    r37386 r37388  
     12008-10-07  Sam Weinig  <[email protected]>
     2
     3        Reviewed by Cameron Zwarich.
     4
     5        Roll r37370 back in with bug fixes.
     6
     7        - PropertyMap::storageSize() should reflect the number of keys + deletedOffsets
     8          and has nothing to do with the internal deletedSentinel count anymore.
     9
    1102008-10-07  Gavin Barraclough  <[email protected]>
    211
  • trunk/JavaScriptCore/JavaScriptCore.exp

    r37381 r37388  
    109109__ZN3JSC11ProfileNode4sortEPFbRKN3WTF6RefPtrIS0_EES5_E
    110110__ZN3JSC11ProgramNode6createEPNS_12JSGlobalDataEPNS_14SourceElementsEPN3WTF6VectorISt4pairINS_10IdentifierEjELm16EEEPNS6_INS5_6RefPtrINS_12FuncDeclNodeEEELm16EEERKNS_10SourceCodeEji
    111 __ZN3JSC11PropertyMap3putERKNS_10IdentifierEPNS_7JSValueEjbPNS_8JSObjectERNS_15PutPropertySlotERPS5_
    112 __ZN3JSC11PropertyMap9getOffsetERKNS_10IdentifierERj
     111__ZN3JSC11PropertyMap3getERKNS_10IdentifierERj
     112__ZN3JSC11PropertyMap3putERKNS_10IdentifierEj
    113113__ZN3JSC11PropertyMapD1Ev
    114 __ZN3JSC11StructureID21addPropertyTransitionEPS0_RKNS_10IdentifierEPNS_7JSValueEjPNS_8JSObjectERNS_15PutPropertySlotERPS6_
     114__ZN3JSC11StructureID21addPropertyTransitionEPS0_RKNS_10IdentifierEjRm
    115115__ZN3JSC11StructureID21clearEnumerationCacheEv
    116116__ZN3JSC11StructureID24fromDictionaryTransitionEPS0_
    117117__ZN3JSC11StructureID25changePrototypeTransitionEPS0_PNS_7JSValueE
     118__ZN3JSC11StructureID27growPropertyStorageCapacityEv
    118119__ZN3JSC11StructureIDC1EPNS_7JSValueERKNS_8TypeInfoE
    119120__ZN3JSC11StructureIDD1Ev
  • trunk/JavaScriptCore/VM/CTI.cpp

    r37386 r37388  
    27782778static JSValue* SFX_CALL transitionObject(StructureID* newStructureID, size_t cachedOffset, JSObject* baseObject, JSValue* value)
    27792779{
    2780     StructureID* oldStructureID = newStructureID->previousID();
    2781 
    27822780    baseObject->transitionTo(newStructureID);
    2783 
    2784     if (oldStructureID->propertyMap().storageSize() == JSObject::inlineStorageCapacity)
    2785         baseObject->allocatePropertyStorage(oldStructureID->propertyMap().storageSize(), oldStructureID->propertyMap().size());
    2786 
    27872781    baseObject->putDirectOffset(cachedOffset, value);
    27882782    return baseObject;
     
    27932787static inline bool transitionWillNeedStorageRealloc(StructureID* oldStructureID, StructureID* newStructureID)
    27942788{
    2795     if (oldStructureID->propertyMap().storageSize() == JSObject::inlineStorageCapacity)
    2796         return true;
    2797 
    2798     if (oldStructureID->propertyMap().storageSize() < JSObject::inlineStorageCapacity)
    2799         return false;
    2800 
    2801     if (oldStructureID->propertyMap().size() != newStructureID->propertyMap().size())
    2802         return true;
    2803 
    2804     return false;
     2789    return oldStructureID->propertyStorageCapacity() != newStructureID->propertyStorageCapacity();
    28052790}
    28062791
  • trunk/JavaScriptCore/VM/Machine.cpp

    r37386 r37388  
    27222722
    27232723                baseObject->transitionTo(newStructureID);
    2724                 if (oldStructureID->propertyMap().storageSize() == JSObject::inlineStorageCapacity)
    2725                     baseObject->allocatePropertyStorage(oldStructureID->propertyMap().storageSize(), oldStructureID->propertyMap().size());
    27262724
    27272725                int value = vPC[3].u.operand;
  • trunk/JavaScriptCore/kjs/JSObject.cpp

    r37381 r37388  
    135135   
    136136    unsigned attributes;
    137     if ((m_structureID->propertyMap().getOffset(propertyName, attributes) != WTF::notFound) && attributes & ReadOnly)
     137    if ((m_structureID->propertyMap().get(propertyName, attributes) != WTF::notFound) && attributes & ReadOnly)
    138138        return;
    139139
     
    201201{
    202202    unsigned attributes;
    203     if (m_structureID->propertyMap().getOffset(propertyName, attributes) != WTF::notFound) {
     203    if (m_structureID->propertyMap().get(propertyName, attributes) != WTF::notFound) {
    204204        if ((attributes & DontDelete))
    205205            return false;
     
    413413bool JSObject::getPropertyAttributes(ExecState* exec, const Identifier& propertyName, unsigned& attributes) const
    414414{
    415     if (m_structureID->propertyMap().getOffset(propertyName, attributes) != WTF::notFound)
     415    if (m_structureID->propertyMap().get(propertyName, attributes) != WTF::notFound)
    416416        return true;
    417417   
     
    469469void JSObject::removeDirect(const Identifier& propertyName)
    470470{
     471    size_t offset;
    471472    if (m_structureID->isDictionary()) {
    472         m_structureID->propertyMap().remove(propertyName, m_propertyStorage);
    473         m_structureID->clearEnumerationCache();
     473        offset = m_structureID->propertyMap().remove(propertyName);
     474        if (offset != WTF::notFound) {
     475            m_propertyStorage[offset] = jsUndefined();
     476            m_structureID->clearEnumerationCache();
     477        }
    474478        return;
    475479    }
    476480
    477481    RefPtr<StructureID> structureID = StructureID::toDictionaryTransition(m_structureID);
    478     structureID->propertyMap().remove(propertyName, m_propertyStorage);
     482    offset = structureID->propertyMap().remove(propertyName);
     483    if (offset != WTF::notFound)
     484        m_propertyStorage[offset] = jsUndefined();
    479485    setStructureID(structureID.release());
    480486}
     
    501507void JSObject::allocatePropertyStorage(size_t oldSize, size_t newSize)
    502508{
     509    ASSERT(newSize > oldSize);
     510
    503511    JSValue** oldPropertStorage = m_propertyStorage;
    504512    m_propertyStorage = new JSValue*[newSize];
  • trunk/JavaScriptCore/kjs/JSObject.h

    r37381 r37388  
    123123        JSValue* getDirect(const Identifier& propertyName) const
    124124        {
    125             size_t offset = m_structureID->propertyMap().getOffset(propertyName);
     125            size_t offset = m_structureID->propertyMap().get(propertyName);
    126126            return offset != WTF::notFound ? m_propertyStorage[offset] : 0;
    127127        }
     
    129129        JSValue** getDirectLocation(const Identifier& propertyName)
    130130        {
    131             size_t offset = m_structureID->propertyMap().getOffset(propertyName);
     131            size_t offset = m_structureID->propertyMap().get(propertyName);
    132132            return offset != WTF::notFound ? locationForOffset(offset) : 0;
    133133        }
     
    135135        JSValue** getDirectLocation(const Identifier& propertyName, unsigned& attributes)
    136136        {
    137             size_t offset = m_structureID->propertyMap().getOffset(propertyName, attributes);
     137            size_t offset = m_structureID->propertyMap().get(propertyName, attributes);
    138138            return offset != WTF::notFound ? locationForOffset(offset) : 0;
    139139        }
     
    179179
    180180        static const size_t inlineStorageCapacity = 2;
     181        static const size_t nonInlineBaseStorageCapacity = 16;
    181182
    182183        static PassRefPtr<StructureID> createStructureID(JSValue* proto) { return StructureID::create(proto, TypeInfo(ObjectType)); }
     
    365366    ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this));
    366367
    367      if (m_structureID->isDictionary()) {
    368          unsigned currentAttributes;
    369          size_t offset = m_structureID->propertyMap().getOffset(propertyName, currentAttributes);
    370          if (offset != WTF::notFound) {
    371              if (checkReadOnly && currentAttributes & ReadOnly)
    372                  return;
    373              m_propertyStorage[offset] = value;
    374              slot.setExistingProperty(this, offset);
    375              return;
    376          }
    377 
    378          if (m_structureID->propertyMap().storageSize() == inlineStorageCapacity)
    379              allocatePropertyStorage(m_structureID->propertyMap().storageSize(), m_structureID->propertyMap().size());
    380          m_structureID->propertyMap().put(propertyName, value, attributes, checkReadOnly, this, slot, m_propertyStorage);
    381          m_structureID->clearEnumerationCache();
    382          return;
    383      }
     368    if (m_structureID->isDictionary()) {
     369        unsigned currentAttributes;
     370        size_t offset = m_structureID->propertyMap().get(propertyName, currentAttributes);
     371        if (offset != WTF::notFound) {
     372            if (checkReadOnly && currentAttributes & ReadOnly)
     373                return;
     374            m_propertyStorage[offset] = value;
     375            slot.setExistingProperty(this, offset);
     376            return;
     377        }
     378
     379        size_t currentCapacity = m_structureID->propertyStorageCapacity();
     380        offset = m_structureID->propertyMap().put(propertyName, attributes);
     381        if (m_structureID->propertyMap().storageSize() > m_structureID->propertyStorageCapacity()) {
     382            m_structureID->growPropertyStorageCapacity();
     383            allocatePropertyStorage(currentCapacity, m_structureID->propertyStorageCapacity());
     384        }
     385
     386        m_propertyStorage[offset] = value;
     387        slot.setNewProperty(this, offset);
     388        m_structureID->clearEnumerationCache();
     389        return;
     390    }
    384391
    385392    unsigned currentAttributes;
    386     size_t offset = m_structureID->propertyMap().getOffset(propertyName, currentAttributes);
     393    size_t offset = m_structureID->propertyMap().get(propertyName, currentAttributes);
    387394    if (offset != WTF::notFound) {
    388395        if (checkReadOnly && currentAttributes & ReadOnly)
     
    393400    }
    394401
    395      if (m_structureID->propertyMap().storageSize() == inlineStorageCapacity)
    396          allocatePropertyStorage(m_structureID->propertyMap().storageSize(), m_structureID->propertyMap().size());
    397 
    398      RefPtr<StructureID> structureID = StructureID::addPropertyTransition(m_structureID, propertyName, value, attributes, this, slot, m_propertyStorage);
    399      slot.setWasTransition(true);
    400      setStructureID(structureID.release());
     402    size_t currentCapacity = m_structureID->propertyStorageCapacity();
     403    RefPtr<StructureID> structureID = StructureID::addPropertyTransition(m_structureID, propertyName, attributes, offset);
     404    if (currentCapacity != structureID->propertyStorageCapacity())
     405        allocatePropertyStorage(currentCapacity, structureID->propertyStorageCapacity());
     406
     407    ASSERT(offset < structureID->propertyStorageCapacity());
     408    m_propertyStorage[offset] = value;
     409    slot.setNewProperty(this, offset);
     410    slot.setWasTransition(true);
     411    setStructureID(structureID.release());
    401412}
    402413
    403414inline void JSObject::transitionTo(StructureID* newStructureID)
    404415{
    405     StructureID::transitionTo(m_structureID, newStructureID, this);
     416    if (m_structureID->propertyStorageCapacity() != newStructureID->propertyStorageCapacity())
     417        allocatePropertyStorage(m_structureID->propertyStorageCapacity(), newStructureID->propertyStorageCapacity());
    406418    setStructureID(newStructureID);
    407419}
  • trunk/JavaScriptCore/kjs/PropertyMap.cpp

    r37381 r37388  
    7878#if !DO_PROPERTYMAP_CONSTENCY_CHECK
    7979
    80 inline void PropertyMap::checkConsistency(PropertyStorage&)
     80inline void PropertyMap::checkConsistency()
    8181{
    8282}
     
    9898    }
    9999
     100    m_deletedOffsets = other.m_deletedOffsets;
    100101    m_getterSetterFlag = other.m_getterSetterFlag;
    101102    return *this;
     
    115116}
    116117
    117 size_t PropertyMap::put(const Identifier& propertyName, JSValue* value, unsigned attributes, bool checkReadOnly, JSObject* slotBase, PutPropertySlot& slot, PropertyStorage& propertyStorage)
     118size_t PropertyMap::put(const Identifier& propertyName, unsigned attributes)
    118119{
    119120    ASSERT(!propertyName.isNull());
    120     ASSERT(value);
    121 
    122     checkConsistency(propertyStorage);
     121    ASSERT(get(propertyName) == WTF::notFound);
     122
     123    checkConsistency();
    123124
    124125    UString::Rep* rep = propertyName._ustring.rep();
    125126
    126127    if (!m_table)
    127         expand(propertyStorage);
     128        createTable();
    128129
    129130    // FIXME: Consider a fast case for tables with no deleted sentinels.
     
    143144            break;
    144145
    145         if (m_table->entries()[entryIndex - 1].key == rep) {
    146             if (checkReadOnly && (m_table->entries()[entryIndex - 1].attributes & ReadOnly))
    147                 return WTF::notFound;
    148             // Put a new value in an existing hash table entry.
    149             propertyStorage[entryIndex - 2] = value;
    150             // Attributes are intentionally not updated.
    151             slot.setExistingProperty(slotBase, entryIndex - 2);
    152             return entryIndex - 2;
    153         } else if (entryIndex == deletedSentinelIndex) {
     146        if (entryIndex == deletedSentinelIndex) {
    154147            // If we find a deleted-element sentinel, remember it for use later.
    155148            if (!foundDeletedElement) {
     
    194187    m_table->entries()[entryIndex - 1].attributes = attributes;
    195188    m_table->entries()[entryIndex - 1].index = ++m_table->lastIndexUsed;
     189
     190    unsigned newOffset;
     191    if (!m_deletedOffsets.isEmpty()) {
     192        newOffset = m_deletedOffsets.last();
     193        m_deletedOffsets.removeLast();
     194    } else
     195        newOffset = m_table->keyCount;
     196    m_table->entries()[entryIndex - 1].offset = newOffset;
     197
    196198    ++m_table->keyCount;
    197199
    198     propertyStorage[entryIndex - 2] = value;
    199 
    200200    if ((m_table->keyCount + m_table->deletedSentinelCount) * 2 >= m_table->size)
    201         expand(propertyStorage);
    202 
    203     checkConsistency(propertyStorage);
    204     slot.setNewProperty(slotBase, entryIndex - 2);
    205     return entryIndex - 2;
    206 }
    207 
    208 void PropertyMap::remove(const Identifier& propertyName, PropertyStorage& propertyStorage)
     201        expand();
     202
     203    checkConsistency();
     204    return newOffset;
     205}
     206
     207size_t PropertyMap::remove(const Identifier& propertyName)
    209208{
    210209    ASSERT(!propertyName.isNull());
    211210
    212     checkConsistency(propertyStorage);
     211    checkConsistency();
    213212
    214213    UString::Rep* rep = propertyName._ustring.rep();
    215214
    216215    if (!m_table)
    217         return;
     216        return WTF::notFound;
    218217
    219218#if DUMP_PROPERTYMAP_STATS
     
    230229        entryIndex = m_table->entryIndices[i & m_table->sizeMask];
    231230        if (entryIndex == emptyEntryIndex)
    232             return;
     231            return WTF::notFound;
    233232
    234233        key = m_table->entries()[entryIndex - 1].key;
     
    253252    // the entry so we can iterate all the entries as needed.
    254253    m_table->entryIndices[i & m_table->sizeMask] = deletedSentinelIndex;
     254
     255    size_t offset = m_table->entries()[entryIndex - 1].offset;
     256
    255257    key->deref();
    256258    m_table->entries()[entryIndex - 1].key = 0;
    257259    m_table->entries()[entryIndex - 1].attributes = 0;
    258 
    259     propertyStorage[entryIndex - 2] = jsUndefined();
     260    m_table->entries()[entryIndex - 1].offset = 0;
     261    m_deletedOffsets.append(offset);
    260262
    261263    ASSERT(m_table->keyCount >= 1);
     
    264266
    265267    if (m_table->deletedSentinelCount * 4 >= m_table->size)
    266         rehash(propertyStorage);
    267 
    268     checkConsistency(propertyStorage);
    269 }
    270 
    271 size_t PropertyMap::getOffset(const Identifier& propertyName, unsigned& attributes)
     268        rehash();
     269
     270    checkConsistency();
     271    return offset;
     272}
     273
     274size_t PropertyMap::get(const Identifier& propertyName, unsigned& attributes)
    272275{
    273276    ASSERT(!propertyName.isNull());
     
    290293    if (rep == m_table->entries()[entryIndex - 1].key) {
    291294        attributes = m_table->entries()[entryIndex - 1].attributes;
    292         return entryIndex - 2;
     295        return m_table->entries()[entryIndex - 1].offset;
    293296    }
    294297
     
    312315        if (rep == m_table->entries()[entryIndex - 1].key) {
    313316            attributes = m_table->entries()[entryIndex - 1].attributes;
    314             return entryIndex - 2;
    315         }
    316     }
    317 }
    318 
    319 void PropertyMap::insert(const Entry& entry, JSValue* value, PropertyStorage& propertyStorage)
     317            return m_table->entries()[entryIndex - 1].offset;
     318        }
     319    }
     320}
     321
     322void PropertyMap::insert(const Entry& entry)
    320323{
    321324    ASSERT(m_table);
     
    351354    m_table->entries()[entryIndex - 1] = entry;
    352355
    353     propertyStorage[entryIndex - 2] = value;
    354 
    355356    ++m_table->keyCount;
    356357}
    357358
    358 void PropertyMap::expand(PropertyStorage& propertyStorage)
    359 {
    360     if (!m_table)
    361         createTable(propertyStorage);
    362     else
    363         rehash(m_table->size * 2, propertyStorage);
    364 }
    365 
    366 void PropertyMap::rehash(PropertyStorage& propertyStorage)
     359void PropertyMap::expand()
    367360{
    368361    ASSERT(m_table);
    369     ASSERT(m_table->size);
    370     rehash(m_table->size, propertyStorage);
    371 }
    372 
    373 void PropertyMap::createTable(PropertyStorage& propertyStorage)
     362    rehash(m_table->size * 2);
     363}
     364
     365void PropertyMap::createTable()
    374366{
    375367    const unsigned newTableSize = 16;
     
    377369    ASSERT(!m_table);
    378370
    379     checkConsistency(propertyStorage);
     371    checkConsistency();
    380372
    381373    m_table = static_cast<Table*>(fastZeroedMalloc(Table::allocationSize(newTableSize)));
     
    383375    m_table->sizeMask = newTableSize - 1;
    384376
    385     checkConsistency(propertyStorage);
    386 }
    387 
    388 void PropertyMap::rehash(unsigned newTableSize, PropertyStorage& propertyStorage)
     377    checkConsistency();
     378}
     379
     380void PropertyMap::rehash()
    389381{
    390382    ASSERT(m_table);
    391 
    392     checkConsistency(propertyStorage);
     383    ASSERT(m_table->size);
     384    rehash(m_table->size);
     385}
     386
     387void PropertyMap::rehash(unsigned newTableSize)
     388{
     389    ASSERT(m_table);
     390
     391    checkConsistency();
    393392
    394393    Table* oldTable = m_table;
    395     JSValue** oldPropertStorage = propertyStorage;
    396394
    397395    m_table = static_cast<Table*>(fastZeroedMalloc(Table::allocationSize(newTableSize)));
    398396    m_table->size = newTableSize;
    399397    m_table->sizeMask = newTableSize - 1;
    400 
    401     propertyStorage = new JSValue*[m_table->size];
    402398
    403399    unsigned lastIndexUsed = 0;
     
    406402        if (oldTable->entries()[i].key) {
    407403            lastIndexUsed = max(oldTable->entries()[i].index, lastIndexUsed);
    408             insert(oldTable->entries()[i], oldPropertStorage[i - 1], propertyStorage);
     404            insert(oldTable->entries()[i]);
    409405        }
    410406    }
     
    412408
    413409    fastFree(oldTable);
    414     delete [] oldPropertStorage;
    415 
    416     checkConsistency(propertyStorage);
     410
     411    checkConsistency();
    417412}
    418413
     
    486481#if DO_PROPERTYMAP_CONSTENCY_CHECK
    487482
    488 void PropertyMap::checkConsistency(PropertyStorage& propertyStorage)
     483void PropertyMap::checkConsistency()
    489484{
    490485    if (!m_table)
     
    526521    for (unsigned c = 1; c <= m_table->keyCount + m_table->deletedSentinelCount; ++c) {
    527522        UString::Rep* rep = m_table->entries()[c].key;
    528         if (!rep) {
    529             ASSERT(propertyStorage[c - 1]->isUndefined());
     523        if (!rep)
    530524            continue;
    531         }
    532525        ++nonEmptyEntryCount;
    533526        unsigned i = rep->computedHash();
  • trunk/JavaScriptCore/kjs/PropertyMap.h

    r37381 r37388  
    4343    struct PropertyMapEntry {
    4444        UString::Rep* key;
     45        unsigned offset;
    4546        unsigned attributes;
    4647        unsigned index;
     
    4849        PropertyMapEntry(UString::Rep* k, int a)
    4950            : key(k)
     51            , offset(0)
    5052            , attributes(a)
    5153            , index(0)
     
    9395        PropertyMap& operator=(const PropertyMap&);
    9496
    95         bool isEmpty() { return !m_table; }
    9697
    97         size_t put(const Identifier& propertyName, JSValue*, unsigned attributes, bool checkReadOnly, JSObject* slotBase, PutPropertySlot&, PropertyStorage&);
    98         void remove(const Identifier& propertyName, PropertyStorage&);
    99 
    100         size_t getOffset(const Identifier& propertyName);
    101         size_t getOffset(const Identifier& propertyName, unsigned& attributes);
     98        size_t get(const Identifier& propertyName);
     99        size_t get(const Identifier& propertyName, unsigned& attributes);
     100        size_t put(const Identifier& propertyName, unsigned attributes);
     101        size_t remove(const Identifier& propertyName);
    102102
    103103        void getEnumerablePropertyNames(PropertyNameArray&) const;
     
    106106        void setHasGetterSetterProperties(bool f) { m_getterSetterFlag = f; }
    107107
    108         unsigned size() const { return m_table ? m_table->size : 0; }
    109         unsigned storageSize() const { return m_table ? m_table->keyCount + m_table->deletedSentinelCount : 0; }
     108        bool isEmpty() { return !m_table; }
     109        unsigned storageSize() const { return m_table ? m_table->keyCount + m_deletedOffsets.size() : 0; }
    110110
    111111        static const unsigned emptyEntryIndex = 0;
     
    115115        typedef PropertyMapHashTable Table;
    116116
    117         void expand(PropertyStorage&);
    118         void rehash(PropertyStorage&);
    119         void rehash(unsigned newTableSize, PropertyStorage&);
    120         void createTable(PropertyStorage&);
     117        void expand();
     118        void rehash();
     119        void rehash(unsigned newTableSize);
     120        void createTable();
    121121
    122         void insert(const Entry&, JSValue*, PropertyStorage&);
     122        void insert(const Entry&);
    123123
    124         void checkConsistency(PropertyStorage&);
     124        void checkConsistency();
    125125
    126126        Table* m_table;
     127        Vector<unsigned> m_deletedOffsets;
    127128        bool m_getterSetterFlag : 1;
    128129    };
     
    134135    }
    135136
    136     inline size_t PropertyMap::getOffset(const Identifier& propertyName)
     137    inline size_t PropertyMap::get(const Identifier& propertyName)
    137138    {
    138139        ASSERT(!propertyName.isNull());
     
    154155
    155156        if (rep == m_table->entries()[entryIndex - 1].key)
    156             return entryIndex - 2;
     157            return m_table->entries()[entryIndex - 1].offset;
    157158
    158159#if DUMP_PROPERTYMAP_STATS
     
    174175
    175176            if (rep == m_table->entries()[entryIndex - 1].key)
    176                 return entryIndex - 2;
     177                return m_table->entries()[entryIndex - 1].offset;
    177178        }
    178179    }
  • trunk/JavaScriptCore/kjs/StructureID.cpp

    r37381 r37388  
    4545    , m_nameInPrevious(0)
    4646    , m_transitionCount(0)
     47    , m_propertyStorageCapacity(JSObject::inlineStorageCapacity)
    4748    , m_cachedTransistionOffset(WTF::notFound)
    4849{
     
    103104}
    104105
    105 void StructureID::transitionTo(StructureID* oldStructureID, StructureID* newStructureID, JSObject* slotBase)
    106 {
    107     if (!slotBase->usingInlineStorage() && oldStructureID->m_propertyMap.size() != newStructureID->m_propertyMap.size())
    108         slotBase->allocatePropertyStorage(oldStructureID->m_propertyMap.size(), newStructureID->m_propertyMap.size());
    109 }
    110 
    111 PassRefPtr<StructureID> StructureID::addPropertyTransition(StructureID* structureID, const Identifier& propertyName, JSValue* value, unsigned attributes, JSObject* slotBase, PutPropertySlot& slot, PropertyStorage& propertyStorage)
     106void StructureID::growPropertyStorageCapacity()
     107{
     108    if (m_propertyStorageCapacity == JSObject::inlineStorageCapacity)
     109        m_propertyStorageCapacity = JSObject::nonInlineBaseStorageCapacity;
     110    else
     111        m_propertyStorageCapacity *= 2;
     112}
     113
     114PassRefPtr<StructureID> StructureID::addPropertyTransition(StructureID* structureID, const Identifier& propertyName, unsigned attributes, size_t& offset)
    112115{
    113116    ASSERT(!structureID->m_isDictionary);
     
    115118
    116119    if (StructureID* existingTransition = structureID->m_transitionTable.get(make_pair(propertyName.ustring().rep(), attributes))) {
    117         if (!slotBase->usingInlineStorage() && structureID->m_propertyMap.size() != existingTransition->m_propertyMap.size())
    118             slotBase->allocatePropertyStorage(structureID->m_propertyMap.size(), existingTransition->m_propertyMap.size());
    119 
    120         size_t offset = existingTransition->cachedTransistionOffset();
     120        offset = existingTransition->cachedTransistionOffset();
    121121        ASSERT(offset != WTF::notFound);
    122         propertyStorage[offset] = value;
    123         slot.setNewProperty(slotBase, offset);
    124 
    125122        return existingTransition;
    126123    }
     
    128125    if (structureID->m_transitionCount > s_maxTransitionLength) {
    129126        RefPtr<StructureID> transition = toDictionaryTransition(structureID);
    130         transition->m_propertyMap.put(propertyName, value, attributes, false, slotBase, slot, propertyStorage);
     127        offset = transition->m_propertyMap.put(propertyName, attributes);
     128        if (transition->m_propertyMap.storageSize() > transition->propertyStorageCapacity())
     129            transition->growPropertyStorageCapacity();
    131130        return transition.release();
    132131    }
     
    139138    transition->m_transitionCount = structureID->m_transitionCount + 1;
    140139    transition->m_propertyMap = structureID->m_propertyMap;
    141 
    142     size_t offset = transition->m_propertyMap.put(propertyName, value, attributes, false, slotBase, slot, propertyStorage);
     140    transition->m_propertyStorageCapacity = structureID->m_propertyStorageCapacity;
     141
     142    offset = transition->m_propertyMap.put(propertyName, attributes);
     143    if (transition->m_propertyMap.storageSize() > transition->propertyStorageCapacity())
     144        transition->growPropertyStorageCapacity();
     145
    143146    transition->setCachedTransistionOffset(offset);
    144147
     
    154157    transition->m_isDictionary = true;
    155158    transition->m_propertyMap = structureID->m_propertyMap;
     159    transition->m_propertyStorageCapacity = structureID->m_propertyStorageCapacity;
    156160    return transition.release();
    157161}
     
    173177    transition->m_transitionCount = structureID->m_transitionCount + 1;
    174178    transition->m_propertyMap = structureID->m_propertyMap;
     179    transition->m_propertyStorageCapacity = structureID->m_propertyStorageCapacity;
    175180    return transition.release();
    176181}
     
    181186    transition->m_transitionCount = structureID->m_transitionCount + 1;
    182187    transition->m_propertyMap = structureID->m_propertyMap;
     188    transition->m_propertyStorageCapacity = structureID->m_propertyStorageCapacity;
    183189    return transition.release();
    184190}
  • trunk/JavaScriptCore/kjs/StructureID.h

    r37381 r37388  
    8484
    8585        static PassRefPtr<StructureID> changePrototypeTransition(StructureID*, JSValue* prototype);
    86         static PassRefPtr<StructureID> addPropertyTransition(StructureID*, const Identifier& propertyName, JSValue*, unsigned attributes, JSObject* slotBase, PutPropertySlot&, PropertyStorage&);
     86        static PassRefPtr<StructureID> addPropertyTransition(StructureID*, const Identifier& propertyName, unsigned attributes, size_t& offset);
    8787        static PassRefPtr<StructureID> getterSetterTransition(StructureID*);
    8888        static PassRefPtr<StructureID> toDictionaryTransition(StructureID*);
     
    119119        size_t cachedTransistionOffset() const { return m_cachedTransistionOffset; }
    120120
     121        void growPropertyStorageCapacity();
     122        size_t propertyStorageCapacity() const { return m_propertyStorageCapacity; }
     123
    121124        void getEnumerablePropertyNames(ExecState*, PropertyNameArray&, JSObject*);
    122125        void clearEnumerationCache();
    123 
    124         static void transitionTo(StructureID* oldStructureID, StructureID* newStructureID, JSObject* slotBase);
    125126
    126127    private:
     
    149150
    150151        PropertyMap m_propertyMap;
     152        size_t m_propertyStorageCapacity;
    151153
    152154        size_t m_cachedTransistionOffset;
Note: See TracChangeset for help on using the changeset viewer.