Changeset 37381 in webkit


Ignore:
Timestamp:
Oct 7, 2008 11:17:37 AM (15 years ago)
Author:
cwzwarich@webkit.org
Message:

2008-10-07 Cameron Zwarich <zwarich@apple.com>

Rubber-stamped by Mark Rowe.

Roll out r37370.

Location:
trunk/JavaScriptCore
Files:
10 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/ChangeLog

    r37370 r37381  
     12008-10-07  Cameron Zwarich  <zwarich@apple.com>
     2
     3        Rubber-stamped by Mark Rowe.
     4
     5        Roll out r37370.
     6
    172008-10-06  Sam Weinig  <sam@webkit.org>
    28
  • trunk/JavaScriptCore/JavaScriptCore.exp

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

    r37370 r37381  
    27442744static JSValue* SFX_CALL transitionObject(StructureID* newStructureID, size_t cachedOffset, JSObject* baseObject, JSValue* value)
    27452745{
     2746    StructureID* oldStructureID = newStructureID->previousID();
     2747
    27462748    baseObject->transitionTo(newStructureID);
     2749
     2750    if (oldStructureID->propertyMap().storageSize() == JSObject::inlineStorageCapacity)
     2751        baseObject->allocatePropertyStorage(oldStructureID->propertyMap().storageSize(), oldStructureID->propertyMap().size());
     2752
    27472753    baseObject->putDirectOffset(cachedOffset, value);
    27482754    return baseObject;
     
    27532759static inline bool transitionWillNeedStorageRealloc(StructureID* oldStructureID, StructureID* newStructureID)
    27542760{
    2755     return oldStructureID->propertyStorageCapacity() != newStructureID->propertyStorageCapacity();
     2761    if (oldStructureID->propertyMap().storageSize() == JSObject::inlineStorageCapacity)
     2762        return true;
     2763
     2764    if (oldStructureID->propertyMap().storageSize() < JSObject::inlineStorageCapacity)
     2765        return false;
     2766
     2767    if (oldStructureID->propertyMap().size() != newStructureID->propertyMap().size())
     2768        return true;
     2769
     2770    return false;
    27562771}
    27572772
  • trunk/JavaScriptCore/VM/Machine.cpp

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

    r37370 r37381  
    135135   
    136136    unsigned attributes;
    137     if ((m_structureID->propertyMap().get(propertyName, attributes) != WTF::notFound) && attributes & ReadOnly)
     137    if ((m_structureID->propertyMap().getOffset(propertyName, attributes) != WTF::notFound) && attributes & ReadOnly)
    138138        return;
    139139
     
    201201{
    202202    unsigned attributes;
    203     if (m_structureID->propertyMap().get(propertyName, attributes) != WTF::notFound) {
     203    if (m_structureID->propertyMap().getOffset(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().get(propertyName, attributes) != WTF::notFound)
     415    if (m_structureID->propertyMap().getOffset(propertyName, attributes) != WTF::notFound)
    416416        return true;
    417417   
     
    469469void JSObject::removeDirect(const Identifier& propertyName)
    470470{
    471     size_t offset;
    472471    if (m_structureID->isDictionary()) {
    473         offset = m_structureID->propertyMap().remove(propertyName);
    474         if (offset != WTF::notFound) {
    475             m_propertyStorage[offset] = jsUndefined();
    476             m_structureID->clearEnumerationCache();
    477         }
     472        m_structureID->propertyMap().remove(propertyName, m_propertyStorage);
     473        m_structureID->clearEnumerationCache();
    478474        return;
    479475    }
    480476
    481477    RefPtr<StructureID> structureID = StructureID::toDictionaryTransition(m_structureID);
    482     offset = structureID->propertyMap().remove(propertyName);
    483     if (offset != WTF::notFound)
    484         m_propertyStorage[offset] = jsUndefined();
     478    structureID->propertyMap().remove(propertyName, m_propertyStorage);
    485479    setStructureID(structureID.release());
    486480}
     
    507501void JSObject::allocatePropertyStorage(size_t oldSize, size_t newSize)
    508502{
    509     ASSERT(newSize > oldSize);
    510 
    511503    JSValue** oldPropertStorage = m_propertyStorage;
    512504    m_propertyStorage = new JSValue*[newSize];
  • trunk/JavaScriptCore/kjs/JSObject.h

    r37370 r37381  
    123123        JSValue* getDirect(const Identifier& propertyName) const
    124124        {
    125             size_t offset = m_structureID->propertyMap().get(propertyName);
     125            size_t offset = m_structureID->propertyMap().getOffset(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().get(propertyName);
     131            size_t offset = m_structureID->propertyMap().getOffset(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().get(propertyName, attributes);
     137            size_t offset = m_structureID->propertyMap().getOffset(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;
    182181
    183182        static PassRefPtr<StructureID> createStructureID(JSValue* proto) { return StructureID::create(proto, TypeInfo(ObjectType)); }
     
    366365    ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this));
    367366
    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     }
     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     }
    391384
    392385    unsigned currentAttributes;
    393     size_t offset = m_structureID->propertyMap().get(propertyName, currentAttributes);
     386    size_t offset = m_structureID->propertyMap().getOffset(propertyName, currentAttributes);
    394387    if (offset != WTF::notFound) {
    395388        if (checkReadOnly && currentAttributes & ReadOnly)
     
    400393    }
    401394
    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());
     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());
    412401}
    413402
    414403inline void JSObject::transitionTo(StructureID* newStructureID)
    415404{
    416     if (m_structureID->propertyStorageCapacity() != newStructureID->propertyStorageCapacity())
    417         allocatePropertyStorage(m_structureID->propertyStorageCapacity(), newStructureID->propertyStorageCapacity());
     405    StructureID::transitionTo(m_structureID, newStructureID, this);
    418406    setStructureID(newStructureID);
    419407}
  • trunk/JavaScriptCore/kjs/PropertyMap.cpp

    r37370 r37381  
    7878#if !DO_PROPERTYMAP_CONSTENCY_CHECK
    7979
    80 inline void PropertyMap::checkConsistency()
     80inline void PropertyMap::checkConsistency(PropertyStorage&)
    8181{
    8282}
     
    9898    }
    9999
    100     m_deletedOffsets = other.m_deletedOffsets;
    101100    m_getterSetterFlag = other.m_getterSetterFlag;
    102101    return *this;
     
    116115}
    117116
    118 size_t PropertyMap::put(const Identifier& propertyName, unsigned attributes)
     117size_t PropertyMap::put(const Identifier& propertyName, JSValue* value, unsigned attributes, bool checkReadOnly, JSObject* slotBase, PutPropertySlot& slot, PropertyStorage& propertyStorage)
    119118{
    120119    ASSERT(!propertyName.isNull());
    121     ASSERT(get(propertyName) == WTF::notFound);
    122 
    123     checkConsistency();
     120    ASSERT(value);
     121
     122    checkConsistency(propertyStorage);
    124123
    125124    UString::Rep* rep = propertyName._ustring.rep();
    126125
    127126    if (!m_table)
    128         createTable();
     127        expand(propertyStorage);
    129128
    130129    // FIXME: Consider a fast case for tables with no deleted sentinels.
     
    144143            break;
    145144
    146         if (entryIndex == deletedSentinelIndex) {
     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) {
    147154            // If we find a deleted-element sentinel, remember it for use later.
    148155            if (!foundDeletedElement) {
     
    187194    m_table->entries()[entryIndex - 1].attributes = attributes;
    188195    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 + m_table->deletedSentinelCount;
    196     m_table->entries()[entryIndex - 1].offset = newOffset;
    197 
    198196    ++m_table->keyCount;
    199197
     198    propertyStorage[entryIndex - 2] = value;
     199
    200200    if ((m_table->keyCount + m_table->deletedSentinelCount) * 2 >= m_table->size)
    201         expand();
    202 
    203     checkConsistency();
    204     return newOffset;
    205 }
    206 
    207 size_t PropertyMap::remove(const Identifier& propertyName)
     201        expand(propertyStorage);
     202
     203    checkConsistency(propertyStorage);
     204    slot.setNewProperty(slotBase, entryIndex - 2);
     205    return entryIndex - 2;
     206}
     207
     208void PropertyMap::remove(const Identifier& propertyName, PropertyStorage& propertyStorage)
    208209{
    209210    ASSERT(!propertyName.isNull());
    210211
    211     checkConsistency();
     212    checkConsistency(propertyStorage);
    212213
    213214    UString::Rep* rep = propertyName._ustring.rep();
    214215
    215216    if (!m_table)
    216         return WTF::notFound;
    217 
     217        return;
    218218
    219219#if DUMP_PROPERTYMAP_STATS
     
    230230        entryIndex = m_table->entryIndices[i & m_table->sizeMask];
    231231        if (entryIndex == emptyEntryIndex)
    232             return WTF::notFound;
     232            return;
    233233
    234234        key = m_table->entries()[entryIndex - 1].key;
     
    253253    // the entry so we can iterate all the entries as needed.
    254254    m_table->entryIndices[i & m_table->sizeMask] = deletedSentinelIndex;
    255 
    256     size_t offset = m_table->entries()[entryIndex - 1].offset;
    257 
    258255    key->deref();
    259256    m_table->entries()[entryIndex - 1].key = 0;
    260257    m_table->entries()[entryIndex - 1].attributes = 0;
    261     m_table->entries()[entryIndex - 1].offset = 0;
    262     m_deletedOffsets.append(offset);
     258
     259    propertyStorage[entryIndex - 2] = jsUndefined();
    263260
    264261    ASSERT(m_table->keyCount >= 1);
     
    267264
    268265    if (m_table->deletedSentinelCount * 4 >= m_table->size)
    269         rehash();
    270 
    271     checkConsistency();
    272     return offset;
    273 }
    274 
    275 size_t PropertyMap::get(const Identifier& propertyName, unsigned& attributes)
     266        rehash(propertyStorage);
     267
     268    checkConsistency(propertyStorage);
     269}
     270
     271size_t PropertyMap::getOffset(const Identifier& propertyName, unsigned& attributes)
    276272{
    277273    ASSERT(!propertyName.isNull());
     
    294290    if (rep == m_table->entries()[entryIndex - 1].key) {
    295291        attributes = m_table->entries()[entryIndex - 1].attributes;
    296         return m_table->entries()[entryIndex - 1].offset;
     292        return entryIndex - 2;
    297293    }
    298294
     
    316312        if (rep == m_table->entries()[entryIndex - 1].key) {
    317313            attributes = m_table->entries()[entryIndex - 1].attributes;
    318             return m_table->entries()[entryIndex - 1].offset;
    319         }
    320     }
    321 }
    322 
    323 void PropertyMap::insert(const Entry& entry)
     314            return entryIndex - 2;
     315        }
     316    }
     317}
     318
     319void PropertyMap::insert(const Entry& entry, JSValue* value, PropertyStorage& propertyStorage)
    324320{
    325321    ASSERT(m_table);
     
    355351    m_table->entries()[entryIndex - 1] = entry;
    356352
     353    propertyStorage[entryIndex - 2] = value;
     354
    357355    ++m_table->keyCount;
    358356}
    359357
    360 void PropertyMap::expand()
     358void PropertyMap::expand(PropertyStorage& propertyStorage)
     359{
     360    if (!m_table)
     361        createTable(propertyStorage);
     362    else
     363        rehash(m_table->size * 2, propertyStorage);
     364}
     365
     366void PropertyMap::rehash(PropertyStorage& propertyStorage)
    361367{
    362368    ASSERT(m_table);
    363     rehash(m_table->size * 2);
    364 }
    365 
    366 void PropertyMap::createTable()
     369    ASSERT(m_table->size);
     370    rehash(m_table->size, propertyStorage);
     371}
     372
     373void PropertyMap::createTable(PropertyStorage& propertyStorage)
    367374{
    368375    const unsigned newTableSize = 16;
     
    370377    ASSERT(!m_table);
    371378
    372     checkConsistency();
     379    checkConsistency(propertyStorage);
    373380
    374381    m_table = static_cast<Table*>(fastZeroedMalloc(Table::allocationSize(newTableSize)));
     
    376383    m_table->sizeMask = newTableSize - 1;
    377384
    378     checkConsistency();
    379 }
    380 
    381 void PropertyMap::rehash()
     385    checkConsistency(propertyStorage);
     386}
     387
     388void PropertyMap::rehash(unsigned newTableSize, PropertyStorage& propertyStorage)
    382389{
    383390    ASSERT(m_table);
    384     ASSERT(m_table->size);
    385     rehash(m_table->size);
    386 }
    387 
    388 void PropertyMap::rehash(unsigned newTableSize)
    389 {
    390     ASSERT(m_table);
    391 
    392     checkConsistency();
     391
     392    checkConsistency(propertyStorage);
    393393
    394394    Table* oldTable = m_table;
     395    JSValue** oldPropertStorage = propertyStorage;
    395396
    396397    m_table = static_cast<Table*>(fastZeroedMalloc(Table::allocationSize(newTableSize)));
    397398    m_table->size = newTableSize;
    398399    m_table->sizeMask = newTableSize - 1;
     400
     401    propertyStorage = new JSValue*[m_table->size];
    399402
    400403    unsigned lastIndexUsed = 0;
     
    403406        if (oldTable->entries()[i].key) {
    404407            lastIndexUsed = max(oldTable->entries()[i].index, lastIndexUsed);
    405             insert(oldTable->entries()[i]);
     408            insert(oldTable->entries()[i], oldPropertStorage[i - 1], propertyStorage);
    406409        }
    407410    }
     
    409412
    410413    fastFree(oldTable);
    411 
    412     checkConsistency();
     414    delete [] oldPropertStorage;
     415
     416    checkConsistency(propertyStorage);
    413417}
    414418
     
    482486#if DO_PROPERTYMAP_CONSTENCY_CHECK
    483487
    484 void PropertyMap::checkConsistency()
     488void PropertyMap::checkConsistency(PropertyStorage& propertyStorage)
    485489{
    486490    if (!m_table)
     
    522526    for (unsigned c = 1; c <= m_table->keyCount + m_table->deletedSentinelCount; ++c) {
    523527        UString::Rep* rep = m_table->entries()[c].key;
    524         if (!rep)
     528        if (!rep) {
     529            ASSERT(propertyStorage[c - 1]->isUndefined());
    525530            continue;
     531        }
    526532        ++nonEmptyEntryCount;
    527533        unsigned i = rep->computedHash();
  • trunk/JavaScriptCore/kjs/PropertyMap.h

    r37370 r37381  
    4343    struct PropertyMapEntry {
    4444        UString::Rep* key;
    45         unsigned offset;
    4645        unsigned attributes;
    4746        unsigned index;
     
    4948        PropertyMapEntry(UString::Rep* k, int a)
    5049            : key(k)
    51             , offset(0)
    5250            , attributes(a)
    5351            , index(0)
     
    9795        bool isEmpty() { return !m_table; }
    9896
    99         size_t get(const Identifier& propertyName);
    100         size_t get(const Identifier& propertyName, unsigned& attributes);
    101         size_t put(const Identifier& propertyName, unsigned attributes);
    102         size_t remove(const Identifier& propertyName);
     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);
    103102
    104103        void getEnumerablePropertyNames(PropertyNameArray&) const;
     
    116115        typedef PropertyMapHashTable Table;
    117116
    118         void expand();
    119         void rehash();
    120         void rehash(unsigned newTableSize);
    121         void createTable();
     117        void expand(PropertyStorage&);
     118        void rehash(PropertyStorage&);
     119        void rehash(unsigned newTableSize, PropertyStorage&);
     120        void createTable(PropertyStorage&);
    122121
    123         void insert(const Entry&);
     122        void insert(const Entry&, JSValue*, PropertyStorage&);
    124123
    125         void checkConsistency();
     124        void checkConsistency(PropertyStorage&);
    126125
    127126        Table* m_table;
    128         Vector<unsigned> m_deletedOffsets;
    129127        bool m_getterSetterFlag : 1;
    130128    };
     
    136134    }
    137135
    138     inline size_t PropertyMap::get(const Identifier& propertyName)
     136    inline size_t PropertyMap::getOffset(const Identifier& propertyName)
    139137    {
    140138        ASSERT(!propertyName.isNull());
     
    156154
    157155        if (rep == m_table->entries()[entryIndex - 1].key)
    158             return m_table->entries()[entryIndex - 1].offset;
     156            return entryIndex - 2;
    159157
    160158#if DUMP_PROPERTYMAP_STATS
     
    176174
    177175            if (rep == m_table->entries()[entryIndex - 1].key)
    178                 return m_table->entries()[entryIndex - 1].offset;
     176                return entryIndex - 2;
    179177        }
    180178    }
  • trunk/JavaScriptCore/kjs/StructureID.cpp

    r37370 r37381  
    4545    , m_nameInPrevious(0)
    4646    , m_transitionCount(0)
    47     , m_propertyStorageCapacity(JSObject::inlineStorageCapacity)
    4847    , m_cachedTransistionOffset(WTF::notFound)
    4948{
     
    104103}
    105104
    106 void StructureID::growPropertyStorageCapacity()
    107 {
    108     if (m_propertyStorageCapacity == JSObject::inlineStorageCapacity)
    109         m_propertyStorageCapacity = JSObject::nonInlineBaseStorageCapacity;
    110     else
    111         m_propertyStorageCapacity *= 2;
    112 }
    113 
    114 PassRefPtr<StructureID> StructureID::addPropertyTransition(StructureID* structureID, const Identifier& propertyName, unsigned attributes, size_t& offset)
     105void 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
     111PassRefPtr<StructureID> StructureID::addPropertyTransition(StructureID* structureID, const Identifier& propertyName, JSValue* value, unsigned attributes, JSObject* slotBase, PutPropertySlot& slot, PropertyStorage& propertyStorage)
    115112{
    116113    ASSERT(!structureID->m_isDictionary);
     
    118115
    119116    if (StructureID* existingTransition = structureID->m_transitionTable.get(make_pair(propertyName.ustring().rep(), attributes))) {
    120         offset = existingTransition->cachedTransistionOffset();
     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();
    121121        ASSERT(offset != WTF::notFound);
     122        propertyStorage[offset] = value;
     123        slot.setNewProperty(slotBase, offset);
     124
    122125        return existingTransition;
    123126    }
     
    125128    if (structureID->m_transitionCount > s_maxTransitionLength) {
    126129        RefPtr<StructureID> transition = toDictionaryTransition(structureID);
    127         offset = transition->m_propertyMap.put(propertyName, attributes);
    128         if (transition->m_propertyMap.storageSize() > transition->propertyStorageCapacity())
    129             transition->growPropertyStorageCapacity();
     130        transition->m_propertyMap.put(propertyName, value, attributes, false, slotBase, slot, propertyStorage);
    130131        return transition.release();
    131132    }
     
    138139    transition->m_transitionCount = structureID->m_transitionCount + 1;
    139140    transition->m_propertyMap = structureID->m_propertyMap;
    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 
     141
     142    size_t offset = transition->m_propertyMap.put(propertyName, value, attributes, false, slotBase, slot, propertyStorage);
    146143    transition->setCachedTransistionOffset(offset);
    147144
     
    157154    transition->m_isDictionary = true;
    158155    transition->m_propertyMap = structureID->m_propertyMap;
    159     transition->m_propertyStorageCapacity = structureID->m_propertyStorageCapacity;
    160156    return transition.release();
    161157}
     
    177173    transition->m_transitionCount = structureID->m_transitionCount + 1;
    178174    transition->m_propertyMap = structureID->m_propertyMap;
    179     transition->m_propertyStorageCapacity = structureID->m_propertyStorageCapacity;
    180175    return transition.release();
    181176}
     
    186181    transition->m_transitionCount = structureID->m_transitionCount + 1;
    187182    transition->m_propertyMap = structureID->m_propertyMap;
    188     transition->m_propertyStorageCapacity = structureID->m_propertyStorageCapacity;
    189183    return transition.release();
    190184}
  • trunk/JavaScriptCore/kjs/StructureID.h

    r37370 r37381  
    8484
    8585        static PassRefPtr<StructureID> changePrototypeTransition(StructureID*, JSValue* prototype);
    86         static PassRefPtr<StructureID> addPropertyTransition(StructureID*, const Identifier& propertyName, unsigned attributes, size_t& offset);
     86        static PassRefPtr<StructureID> addPropertyTransition(StructureID*, const Identifier& propertyName, JSValue*, unsigned attributes, JSObject* slotBase, PutPropertySlot&, PropertyStorage&);
    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 
    124121        void getEnumerablePropertyNames(ExecState*, PropertyNameArray&, JSObject*);
    125122        void clearEnumerationCache();
     123
     124        static void transitionTo(StructureID* oldStructureID, StructureID* newStructureID, JSObject* slotBase);
    126125
    127126    private:
     
    150149
    151150        PropertyMap m_propertyMap;
    152         size_t m_propertyStorageCapacity;
    153151
    154152        size_t m_cachedTransistionOffset;
Note: See TracChangeset for help on using the changeset viewer.