Changeset 36325 in webkit for trunk/JavaScriptCore


Ignore:
Timestamp:
Sep 10, 2008, 7:42:18 PM (17 years ago)
Author:
[email protected]
Message:

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

Reviewed by Geoff Garen.

Add inline property storage for JSObject.

1.2% progression on Sunspider. .5% progression on the v8 test suite.

  • JavaScriptCore.exp:
  • VM/CTI.cpp: (JSC::CTI::privateCompileGetByIdProto): (JSC::CTI::privateCompileGetByIdChain):
  • kjs/JSObject.cpp: (JSC::JSObject::mark): There is no reason to check storageSize now that we start from 0. (JSC::JSObject::allocatePropertyStorage): Allocates/reallocates heap storage.
  • kjs/JSObject.h: (JSC::JSObject::offsetForLocation): m_propertyStorage is not an OwnArrayPtr now so there is no reason to .get() (JSC::JSObject::usingInlineStorage): (JSC::JSObject::JSObject): Start with m_propertyStorage pointing to the inline storage. (JSC::JSObject::~JSObject): Free the heap storage if not using the inline storage. (JSC::JSObject::putDirect): Switch to the heap storage only when we know we know that we are about to add a property that will overflow the inline storage.
  • kjs/PropertyMap.cpp: (JSC::PropertyMap::createTable): Don't allocate the propertyStorage, that is now handled by JSObject. (JSC::PropertyMap::rehash): PropertyStorage is not a OwnArrayPtr anymore.
  • kjs/PropertyMap.h: (JSC::PropertyMap::storageSize): Rename from markingCount.
  • kjs/StructureID.cpp: (JSC::StructureID::addPropertyTransition): Don't resize the property storage if we are using inline storage.
  • kjs/StructureID.h:
Location:
trunk/JavaScriptCore
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/ChangeLog

    r36324 r36325  
     12008-09-10  Sam Weinig  <[email protected]>
     2
     3        Reviewed by Geoff Garen.
     4
     5        Add inline property storage for JSObject.
     6
     7        1.2% progression on Sunspider. .5% progression on the v8 test suite.
     8
     9        * JavaScriptCore.exp:
     10        * VM/CTI.cpp:
     11        (JSC::CTI::privateCompileGetByIdProto):
     12        (JSC::CTI::privateCompileGetByIdChain):
     13        * kjs/JSObject.cpp:
     14        (JSC::JSObject::mark): There is no reason to check storageSize now that
     15        we start from 0.
     16        (JSC::JSObject::allocatePropertyStorage): Allocates/reallocates heap storage.
     17        * kjs/JSObject.h:
     18        (JSC::JSObject::offsetForLocation): m_propertyStorage is not an OwnArrayPtr
     19        now so there is no reason to .get()
     20        (JSC::JSObject::usingInlineStorage):
     21        (JSC::JSObject::JSObject): Start with m_propertyStorage pointing to the
     22        inline storage.
     23        (JSC::JSObject::~JSObject): Free the heap storage if not using the inline
     24        storage.
     25        (JSC::JSObject::putDirect): Switch to the heap storage only when we know
     26        we know that we are about to add a property that will overflow the inline
     27        storage.
     28        * kjs/PropertyMap.cpp:
     29        (JSC::PropertyMap::createTable): Don't allocate the propertyStorage, that is
     30        now handled by JSObject.
     31        (JSC::PropertyMap::rehash): PropertyStorage is not a OwnArrayPtr anymore.
     32        * kjs/PropertyMap.h:
     33        (JSC::PropertyMap::storageSize): Rename from markingCount.
     34        * kjs/StructureID.cpp:
     35        (JSC::StructureID::addPropertyTransition): Don't resize the property storage
     36        if we are using inline storage.
     37        * kjs/StructureID.h:
     38
    1392008-09-10  Oliver Hunt  <[email protected]>
    240
  • trunk/JavaScriptCore/JavaScriptCore.exp

    r36314 r36325  
    104104__ZN3JSC11ProfileNode4sortEPFbRKN3WTF6RefPtrIS0_EES5_E
    105105__ZN3JSC11ProgramNode6createEPNS_12JSGlobalDataEPNS_14SourceElementsEPN3WTF6VectorISt4pairINS_10IdentifierEjELm16EEEPNS6_INS5_6RefPtrINS_12FuncDeclNodeEEELm16EEEPNS_14SourceProviderEbbi
    106 __ZN3JSC11PropertyMap3putERKNS_10IdentifierEPNS_7JSValueEjbPNS_8JSObjectERNS_15PutPropertySlotERN3WTF11OwnArrayPtrIS5_EE
     106__ZN3JSC11PropertyMap3putERKNS_10IdentifierEPNS_7JSValueEjbPNS_8JSObjectERNS_15PutPropertySlotERPS5_
    107107__ZN3JSC11PropertyMap9getOffsetERKNS_10IdentifierE
    108108__ZN3JSC11PropertyMap9getOffsetERKNS_10IdentifierERj
    109109__ZN3JSC11PropertyMapD1Ev
    110 __ZN3JSC11StructureID21addPropertyTransitionEPS0_RKNS_10IdentifierEPNS_7JSValueEjbPNS_8JSObjectERNS_15PutPropertySlotERN3WTF11OwnArrayPtrIS6_EE
     110__ZN3JSC11StructureID21addPropertyTransitionEPS0_RKNS_10IdentifierEPNS_7JSValueEjPNS_8JSObjectERNS_15PutPropertySlotERPS6_
    111111__ZN3JSC11StructureID24fromDictionaryTransitionEPS0_
    112112__ZN3JSC11StructureID25changePrototypeTransitionEPS0_PNS_7JSValueE
     
    232232__ZN3JSC8JSObject18getPrimitiveNumberEPNS_9ExecStateERdRPNS_7JSValueE
    233233__ZN3JSC8JSObject22fillGetterPropertySlotERNS_12PropertySlotEPPNS_7JSValueE
     234__ZN3JSC8JSObject23allocatePropertyStorageEmm
    234235__ZN3JSC8JSObject3putEPNS_9ExecStateERKNS_10IdentifierEPNS_7JSValueERNS_15PutPropertySlotE
    235236__ZN3JSC8JSObject3putEPNS_9ExecStateEjPNS_7JSValueE
  • trunk/JavaScriptCore/VM/CTI.cpp

    r36324 r36325  
    17381738    // referencing the prototype object - let's speculatively load it's table nice and early!)
    17391739    JSObject* protoObject = static_cast<JSObject*>(structureID->prototypeForLookup(exec));
    1740     OwnArrayPtr<JSValue*>* protoPropertyStorage = &protoObject->m_propertyStorage;
     1740    PropertyStorage* protoPropertyStorage = &protoObject->m_propertyStorage;
    17411741    m_jit.movl_mr(static_cast<void*>(protoPropertyStorage), X86::edx);
    17421742
     
    17831783    StructureID* currStructureID = structureID;
    17841784    RefPtr<StructureID>* chainEntries = chain->head();
    1785     JSCell* protoObject = 0;
     1785    JSObject* protoObject = 0;
    17861786    for (unsigned i = 0; i<count; ++i) {
    1787         protoObject = static_cast<JSCell*>(currStructureID->prototypeForLookup(exec));
     1787        protoObject = static_cast<JSObject*>(currStructureID->prototypeForLookup(exec));
    17881788        currStructureID = chainEntries[i].get();
    17891789
     
    17941794    }
    17951795    ASSERT(protoObject);
    1796  
    1797     OwnArrayPtr<JSValue*>* protoPropertyStorage = &static_cast<JSObject*>(protoObject)->m_propertyStorage;
     1796
     1797    PropertyStorage* protoPropertyStorage = &protoObject->m_propertyStorage;
    17981798    m_jit.movl_mr(static_cast<void*>(protoPropertyStorage), X86::edx);
    17991799    m_jit.movl_mr(cachedOffset * sizeof(JSValue*), X86::edx, X86::eax);
  • trunk/JavaScriptCore/kjs/JSObject.cpp

    r36310 r36325  
    7171    m_structureID->mark();
    7272
    73     unsigned storageSize = m_structureID->propertyMap().markingCount();
    74     if (storageSize) {
    75         for (unsigned i = 0; i < storageSize; ++i) {
    76             JSValue* v = m_propertyStorage[i];
    77             if (!v->marked())
    78                 v->mark();
    79         }
     73    unsigned storageSize = m_structureID->propertyMap().storageSize();
     74    for (unsigned i = 0; i < storageSize; ++i) {
     75        JSValue* v = m_propertyStorage[i];
     76        if (!v->marked())
     77            v->mark();
    8078    }
    8179
     
    529527}
    530528
     529void JSObject::allocatePropertyStorage(size_t oldSize, size_t newSize)
     530{
     531    JSValue** oldPropertStorage = m_propertyStorage;
     532    m_propertyStorage = new JSValue*[newSize];
     533
     534    for (unsigned i = 0; i < oldSize; ++i)
     535        m_propertyStorage[i] = oldPropertStorage[i];
     536
     537    if (oldPropertStorage != m_inlineStorage)
     538        delete oldPropertStorage;
     539}
     540
    531541JSObject* constructEmptyObject(ExecState* exec)
    532542{
  • trunk/JavaScriptCore/kjs/JSObject.h

    r36316 r36325  
    143143        size_t offsetForLocation(JSValue** location)
    144144        {
    145             return location - m_propertyStorage.get();
     145            return location - m_propertyStorage;
    146146        }
    147147
     
    176176        virtual bool isNotAnObjectErrorStub() const { return false; }
    177177
     178        void allocatePropertyStorage(size_t oldSize, size_t newSize);
     179        bool usingInlineStorage() const { return m_propertyStorage == m_inlineStorage; }
     180
    178181    protected:
    179182        bool getOwnPropertySlotForWrite(ExecState*, const Identifier&, PropertySlot&, bool& slotIsWriteable);
     
    185188        StructureID* createInheritorID();
    186189
    187         PropertyStorage m_propertyStorage;
     190        static const size_t inlineStorageCapacity = 2;
     191
    188192        RefPtr<StructureID> m_inheritorID;
     193
     194        PropertyStorage m_propertyStorage;       
     195        JSValue* m_inlineStorage[inlineStorageCapacity];
    189196    };
    190197
     
    193200inline JSObject::JSObject(JSObject* prototype)
    194201    : JSCell(prototype->inheritorID())
     202    , m_propertyStorage(m_inlineStorage)
    195203{
    196204    ASSERT(m_structureID);
     
    202210inline JSObject::JSObject(PassRefPtr<StructureID> structureID)
    203211    : JSCell(structureID.releaseRef()) // ~JSObject balances this ref()
     212    , m_propertyStorage(m_inlineStorage)
    204213{
    205214    ASSERT(m_structureID);
     
    209218{
    210219    ASSERT(m_structureID);
     220    if (m_propertyStorage != m_inlineStorage)
     221        delete [] m_propertyStorage;
    211222    m_structureID->deref();
    212223}
     
    365376
    366377     if (m_structureID->isDictionary()) {
     378         unsigned currentAttributes;
     379         size_t offset = m_structureID->propertyMap().getOffset(propertyName, currentAttributes);
     380         if (offset != WTF::notFound) {
     381             if (checkReadOnly && currentAttributes & ReadOnly)
     382                 return;
     383             m_propertyStorage[offset] = value;
     384             slot.setExistingProperty(this, offset);
     385             return;
     386         }
     387
     388         if (m_structureID->propertyMap().storageSize() == inlineStorageCapacity)
     389             allocatePropertyStorage(m_structureID->propertyMap().storageSize(), m_structureID->propertyMap().size());
    367390         m_structureID->propertyMap().put(propertyName, value, attributes, checkReadOnly, this, slot, m_propertyStorage);
    368391         return;
     
    379402     }
    380403
    381      RefPtr<StructureID> structureID = StructureID::addPropertyTransition(m_structureID, propertyName, value, attributes, checkReadOnly, this, slot, m_propertyStorage);
     404     if (m_structureID->propertyMap().storageSize() == inlineStorageCapacity)
     405         allocatePropertyStorage(m_structureID->propertyMap().storageSize(), m_structureID->propertyMap().size());
     406
     407     RefPtr<StructureID> structureID = StructureID::addPropertyTransition(m_structureID, propertyName, value, attributes, this, slot, m_propertyStorage);
    382408     setStructureID(structureID.release());
    383409}
  • trunk/JavaScriptCore/kjs/PropertyMap.cpp

    r36314 r36325  
    429429    m_table->sizeMask = newTableSize - 1;
    430430
    431     propertyStorage.set(new JSValue*[m_table->size]);
    432 
    433431    checkConsistency(propertyStorage);
    434432}
     
    441439
    442440    Table* oldTable = m_table;
    443     JSValue** oldPropertStorage = propertyStorage.release();
     441    JSValue** oldPropertStorage = propertyStorage;
    444442
    445443    m_table = static_cast<Table*>(fastZeroedMalloc(Table::allocationSize(newTableSize)));
     
    447445    m_table->sizeMask = newTableSize - 1;
    448446
    449     propertyStorage.set(new JSValue*[m_table->size]);
     447    propertyStorage = new JSValue*[m_table->size];
    450448
    451449    unsigned lastIndexUsed = 0;
     
    461459    fastFree(oldTable);
    462460    delete [] oldPropertStorage;
    463 
    464     checkConsistency(propertyStorage);
    465 }
    466 
    467 void PropertyMap::resizePropertyStorage(PropertyStorage& propertyStorage, unsigned oldSize)
    468 {
    469     ASSERT(m_table);
    470 
    471     if (propertyStorage) {
    472         JSValue** oldPropertStorage = propertyStorage.release();
    473         propertyStorage.set(new JSValue*[m_table->size]);
    474 
    475         // FIXME: this can probalby use memcpy
    476         for (unsigned i = 0; i < oldSize; ++i)
    477             propertyStorage[i] = oldPropertStorage[i];
    478 
    479         delete [] oldPropertStorage;
    480     } else
    481         propertyStorage.set(new JSValue*[m_table->size]);
    482461
    483462    checkConsistency(propertyStorage);
  • trunk/JavaScriptCore/kjs/PropertyMap.h

    r36314 r36325  
    3333    class PropertyNameArray;
    3434
    35     typedef OwnArrayPtr<JSValue*> PropertyStorage;
     35    typedef JSValue** PropertyStorage;
    3636
    3737    struct PropertyMapEntry {
     
    101101
    102102        unsigned size() const { return m_table ? m_table->size : 0; }
    103         unsigned markingCount() const { return m_table ? m_table->keyCount + m_table->deletedSentinelCount : 0; }
    104 
    105         void resizePropertyStorage(PropertyStorage&, unsigned oldSize);
     103        unsigned storageSize() const { return m_table ? m_table->keyCount + m_table->deletedSentinelCount : 0; }
    106104
    107105    private:
  • trunk/JavaScriptCore/kjs/StructureID.cpp

    r36316 r36325  
    4848}
    4949
    50 PassRefPtr<StructureID> StructureID::addPropertyTransition(StructureID* structureID, const Identifier& propertyName, JSValue* value, unsigned attributes, bool checkReadOnly, JSObject* slotBase, PutPropertySlot& slot, PropertyStorage& propertyStorage)
     50PassRefPtr<StructureID> StructureID::addPropertyTransition(StructureID* structureID, const Identifier& propertyName, JSValue* value, unsigned attributes, JSObject* slotBase, PutPropertySlot& slot, PropertyStorage& propertyStorage)
    5151{
    5252    ASSERT(!structureID->m_isDictionary);
     
    5454
    5555    if (StructureID* existingTransition = structureID->m_transitionTable.get(make_pair(propertyName.ustring().rep(), attributes))) {
    56         if (structureID->m_propertyMap.size() != existingTransition->m_propertyMap.size())
    57             existingTransition->m_propertyMap.resizePropertyStorage(propertyStorage, structureID->m_propertyMap.size());
     56        if (!slotBase->usingInlineStorage() && structureID->m_propertyMap.size() != existingTransition->m_propertyMap.size())
     57            slotBase->allocatePropertyStorage(structureID->m_propertyMap.size(), existingTransition->m_propertyMap.size());
    5858
    5959        size_t offset = existingTransition->propertyMap().getOffset(propertyName);
    6060        ASSERT(offset != WTF::notFound);
    6161        propertyStorage[offset] = value;
    62         slot.setExistingProperty(slotBase, offset);
     62        slot.setNewProperty(slotBase, offset);
    6363
    6464        return existingTransition;
     
    6767    if (structureID->m_transitionCount > s_maxTransitionLength) {
    6868        RefPtr<StructureID> transition = toDictionaryTransition(structureID);
    69         transition->m_propertyMap.put(propertyName, value, attributes, checkReadOnly, slotBase, slot, propertyStorage);
     69        transition->m_propertyMap.put(propertyName, value, attributes, false, slotBase, slot, propertyStorage);
    7070        return transition.release();
    7171    }
     
    7979    transition->m_propertyMap = structureID->m_propertyMap;
    8080
    81     transition->m_propertyMap.put(propertyName, value, attributes, checkReadOnly, slotBase, slot, propertyStorage);
     81    transition->m_propertyMap.put(propertyName, value, attributes, false, slotBase, slot, propertyStorage);
    8282
    8383    structureID->m_transitionTable.add(make_pair(propertyName.ustring().rep(), attributes), transition.get());
  • trunk/JavaScriptCore/kjs/StructureID.h

    r36316 r36325  
    7979
    8080        static PassRefPtr<StructureID> changePrototypeTransition(StructureID*, JSValue* prototype);
    81         static PassRefPtr<StructureID> addPropertyTransition(StructureID*, const Identifier& propertyName, JSValue*, unsigned attributes, bool checkReadOnly, JSObject* slotBase, PutPropertySlot&, PropertyStorage&);
     81        static PassRefPtr<StructureID> addPropertyTransition(StructureID*, const Identifier& propertyName, JSValue*, unsigned attributes, JSObject* slotBase, PutPropertySlot&, PropertyStorage&);
    8282        static PassRefPtr<StructureID> getterSetterTransition(StructureID*);
    8383        static PassRefPtr<StructureID> toDictionaryTransition(StructureID*);
Note: See TracChangeset for help on using the changeset viewer.