Ignore:
Timestamp:
Sep 8, 2008, 11:55:39 PM (17 years ago)
Author:
[email protected]
Message:

JavaScriptCore:

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

Reviewed by Maciej Stachowiak and Oliver Hunt.

Split storage of properties out of the PropertyMap and into the JSObject
to allow sharing PropertyMap on the StructureID. In order to get this
function correctly, the StructureID's transition mappings were changed to
transition based on property name and attribute pairs, instead of just
property name.

  • Removes the single property optimization now that the PropertyMap is shared. This will be replaced by in-lining some values on the JSObject.

This is a wash on Sunspider and a 6.7% win on the v8 test suite.

  • JavaScriptCore.base.exp:
  • VM/CTI.cpp: (JSC::CTI::privateCompileGetByIdSelf): Get the storage directly off the JSObject. (JSC::CTI::privateCompileGetByIdProto): Ditto. (JSC::CTI::privateCompileGetByIdChain): Ditto. (JSC::CTI::privateCompilePutByIdReplace): Ditto.
  • kjs/JSObject.cpp: (JSC::JSObject::mark): Mark the PropertyStorage. (JSC::JSObject::put): Update to get the propertyMap of the StructureID. (JSC::JSObject::deleteProperty): Ditto. (JSC::JSObject::defineGetter): Return early if the property is already a getter/setter. (JSC::JSObject::defineSetter): Ditto. (JSC::JSObject::getPropertyAttributes): Update to get the propertyMap of the StructureID (JSC::JSObject::getPropertyNames): Ditto. (JSC::JSObject::removeDirect): Ditto.
  • kjs/JSObject.h: Remove PropertyMap and add PropertyStorage. (JSC::JSObject::propertyStorage): return the PropertyStorage. (JSC::JSObject::getDirect): Update to get the propertyMap of the StructureID. (JSC::JSObject::getDirectLocation): Ditto. (JSC::JSObject::offsetForLocation): Compute location directly. (JSC::JSObject::hasCustomProperties): Update to get the propertyMap of the StructureID. (JSC::JSObject::hasGetterSetterProperties): Ditto. (JSC::JSObject::getDirectOffset): Get by indexing into PropertyStorage. (JSC::JSObject::putDirectOffset): Put by indexing into PropertyStorage. (JSC::JSObject::getOwnPropertySlotForWrite): Update to get the propertyMap of the StructureID. (JSC::JSObject::getOwnPropertySlot): Ditto. (JSC::JSObject::putDirect): Move putting into the StructureID unless the property already exists.
  • kjs/PropertyMap.cpp: Use the propertyStorage as the storage for the JSValues. (JSC::PropertyMap::checkConsistency): (JSC::PropertyMap::operator=): (JSC::PropertyMap::~PropertyMap): (JSC::PropertyMap::get): (JSC::PropertyMap::getLocation): (JSC::PropertyMap::put): (JSC::PropertyMap::getOffset): (JSC::PropertyMap::insert): (JSC::PropertyMap::expand): (JSC::PropertyMap::rehash): (JSC::PropertyMap::createTable): (JSC::PropertyMap::resizePropertyStorage): Resize the storage to match the size of the map (JSC::PropertyMap::remove): (JSC::PropertyMap::getEnumerablePropertyNames):
  • kjs/PropertyMap.h: (JSC::PropertyMapEntry::PropertyMapEntry): (JSC::PropertyMap::isEmpty): (JSC::PropertyMap::size): (JSC::PropertyMap::makingCount): (JSC::PropertyMap::PropertyMap):
  • kjs/StructureID.cpp: (JSC::StructureID::addPropertyTransition): Transitions now are based off the property name and attributes. (JSC::StructureID::toDictionaryTransition): Copy the map. (JSC::StructureID::changePrototypeTransition): Copy the map. (JSC::StructureID::getterSetterTransition): Copy the map. (JSC::StructureID::~StructureID):
  • kjs/StructureID.h: (JSC::TransitionTableHash::hash): Custom hash for transition map. (JSC::TransitionTableHash::equal): Ditto. (JSC::TransitionTableHashTraits::emptyValue): Custom traits for transition map (JSC::TransitionTableHashTraits::constructDeletedValue): Ditto. (JSC::TransitionTableHashTraits::isDeletedValue): Ditto. (JSC::StructureID::propertyMap): Added.

JavaScriptGlue:

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

Reviewed by Maciej Stachowiak and Oliver Hunt.

Add forwarding headers.

  • ForwardingHeaders/wtf/HashFunctions.h: Added.
  • ForwardingHeaders/wtf/HashTraits.h: Added.

WebCore:

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

Reviewed by Maciej Stachowiak and Oliver Hunt.

Add forwarding headers.

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

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/kjs/JSObject.cpp

    r36263 r36285  
    7070    JSCell::mark();
    7171    m_structureID->mark();
    72     m_propertyMap.mark();
     72
     73    unsigned storageSize = m_structureID->propertyMap().makingCount();
     74    if (storageSize) {
     75        for (unsigned i = 1; i <= storageSize; ++i) {
     76            JSValue* v = m_propertyStorage[i];
     77            if (!v->marked())
     78                v->mark();
     79        }
     80    }
    7381
    7482    JSOBJECT_MARK_END();
     
    120128    // Check if there are any setters or getters in the prototype chain
    121129    JSValue* prototype;
    122     for (JSObject* obj = this; !obj->m_propertyMap.hasGetterSetterProperties(); obj = static_cast<JSObject*>(prototype)) {
     130    for (JSObject* obj = this; !obj->structureID()->propertyMap().hasGetterSetterProperties(); obj = static_cast<JSObject*>(prototype)) {
    123131        prototype = obj->prototype();
    124132        if (prototype->isNull()) {
     
    129137   
    130138    unsigned attributes;
    131     if (m_propertyMap.get(propertyName, attributes) && attributes & ReadOnly)
     139    if (m_structureID->propertyMap().get(propertyName, attributes, m_propertyStorage) && attributes & ReadOnly)
    132140        return;
    133141
    134142    for (JSObject* obj = this; ; obj = static_cast<JSObject*>(prototype)) {
    135         if (JSValue* gs = obj->m_propertyMap.get(propertyName)) {
     143        if (JSValue* gs = obj->structureID()->propertyMap().get(propertyName, obj->propertyStorage())) {
    136144            if (gs->isGetterSetter()) {
    137145                JSObject* setterFunc = static_cast<GetterSetter*>(gs)->setter();       
     
    195203{
    196204    unsigned attributes;
    197     JSValue* v = m_propertyMap.get(propertyName, attributes);
     205    JSValue* v = m_structureID->propertyMap().get(propertyName, attributes, m_propertyStorage);
    198206    if (v) {
    199207        if ((attributes & DontDelete))
     
    286294void JSObject::defineGetter(ExecState* exec, const Identifier& propertyName, JSObject* getterFunction)
    287295{
    288     GetterSetter* getterSetter;
     296    JSValue* object = getDirect(propertyName);
     297    if (object && object->isGetterSetter()) {
     298        ASSERT(m_structureID->propertyMap().hasGetterSetterProperties());
     299        GetterSetter* getterSetter = static_cast<GetterSetter*>(object);
     300        getterSetter->setGetter(getterFunction);
     301        return;
     302    }
     303
    289304    PutPropertySlot slot;
    290 
    291     JSValue* object = getDirect(propertyName);
    292     if (object && object->isGetterSetter())
    293         getterSetter = static_cast<GetterSetter*>(object);
    294     else {
    295         getterSetter = new (exec) GetterSetter;
    296         putDirect(propertyName, getterSetter, None, true, slot);
    297     }
     305    GetterSetter* getterSetter = new (exec) GetterSetter;
     306    putDirect(propertyName, getterSetter, None, true, slot);
    298307
    299308    // putDirect will change our StructureID if we add a new property. For
     
    307316    }
    308317
    309     m_propertyMap.setHasGetterSetterProperties(true);
     318    m_structureID->propertyMap().setHasGetterSetterProperties(true);
    310319    getterSetter->setGetter(getterFunction);
    311320}
     
    313322void JSObject::defineSetter(ExecState* exec, const Identifier& propertyName, JSObject* setterFunction)
    314323{
    315     GetterSetter* getterSetter;
     324    JSValue* object = getDirect(propertyName);
     325    if (object && object->isGetterSetter()) {
     326        ASSERT(m_structureID->propertyMap().hasGetterSetterProperties());
     327        GetterSetter* getterSetter = static_cast<GetterSetter*>(object);
     328        getterSetter->setSetter(setterFunction);
     329        return;
     330    }
     331
    316332    PutPropertySlot slot;
    317 
    318     JSValue* object = getDirect(propertyName);
    319     if (object && object->isGetterSetter())
    320         getterSetter = static_cast<GetterSetter*>(object);
    321     else {
    322         getterSetter = new (exec) GetterSetter;
    323         putDirect(propertyName, getterSetter, None, true, slot);
    324     }
     333    GetterSetter* getterSetter = new (exec) GetterSetter;
     334    putDirect(propertyName, getterSetter, None, true, slot);
    325335
    326336    // putDirect will change our StructureID if we add a new property. For
     
    334344    }
    335345
    336     m_propertyMap.setHasGetterSetterProperties(true);
     346    m_structureID->propertyMap().setHasGetterSetterProperties(true);
    337347    getterSetter->setSetter(setterFunction);
    338348}
     
    412422bool JSObject::getPropertyAttributes(ExecState* exec, const Identifier& propertyName, unsigned& attributes) const
    413423{
    414     if (m_propertyMap.get(propertyName, attributes))
     424    if (m_structureID->propertyMap().get(propertyName, attributes, m_propertyStorage))
    415425        return true;
    416426   
     
    427437void JSObject::getPropertyNames(ExecState* exec, PropertyNameArray& propertyNames)
    428438{
    429     m_propertyMap.getEnumerablePropertyNames(propertyNames);
     439    m_structureID->propertyMap().getEnumerablePropertyNames(propertyNames);
    430440
    431441    // Add properties from the static hashtables of properties
     
    486496void JSObject::removeDirect(const Identifier& propertyName)
    487497{
    488     m_propertyMap.remove(propertyName);
    489     if (!m_structureID->isDictionary()) {
    490         RefPtr<StructureID> structureID = StructureID::toDictionaryTransition(m_structureID);
    491         setStructureID(structureID.release());
    492     }
     498    if (m_structureID->isDictionary()) {
     499        m_structureID->propertyMap().remove(propertyName, m_propertyStorage);
     500        return;
     501    }
     502
     503    RefPtr<StructureID> structureID = StructureID::toDictionaryTransition(m_structureID);
     504    structureID->propertyMap().remove(propertyName, m_propertyStorage);
     505    setStructureID(structureID.release());
    493506}
    494507
Note: See TracChangeset for help on using the changeset viewer.