Changeset 36316 in webkit for trunk/JavaScriptCore


Ignore:
Timestamp:
Sep 10, 2008, 1:42:43 AM (17 years ago)
Author:
[email protected]
Message:

2008-09-10 Maciej Stachowiak <[email protected]>

Reviewed by Oliver.


  • enable polymorphic inline caching of properties of primitives


1.012x speedup on SunSpider.

We create special structure IDs for JSString and
JSNumberCell. Unlike normal structure IDs, these cannot hold the
true prototype. Due to JS autoboxing semantics, the prototype used
when looking up string or number properties depends on the lexical
global object of the call site, not the creation site. Thus we
enable StructureIDs to handle this quirk for primitives.


Everything else should be straightforward.


  • VM/CTI.cpp: (JSC::CTI::privateCompileGetByIdProto): (JSC::CTI::privateCompileGetByIdChain):
  • VM/CTI.h: (JSC::CTI::compileGetByIdProto): (JSC::CTI::compileGetByIdChain):
  • VM/JSPropertyNameIterator.h: (JSC::JSPropertyNameIterator::JSPropertyNameIterator):
  • VM/Machine.cpp: (JSC::Machine::Machine): (JSC::cachePrototypeChain): (JSC::Machine::tryCachePutByID): (JSC::Machine::tryCacheGetByID): (JSC::Machine::privateExecute): (JSC::Machine::tryCTICachePutByID): (JSC::Machine::tryCTICacheGetByID):
  • kjs/GetterSetter.h: (JSC::GetterSetter::GetterSetter):
  • kjs/JSCell.h:
  • kjs/JSGlobalData.cpp: (JSC::JSGlobalData::JSGlobalData):
  • kjs/JSGlobalData.h:
  • kjs/JSGlobalObject.h: (JSC::StructureID::prototypeForLookup):
  • kjs/JSNumberCell.h: (JSC::JSNumberCell::JSNumberCell): (JSC::jsNumberCell):
  • kjs/JSObject.h: (JSC::JSObject::prototype):
  • kjs/JSString.cpp: (JSC::jsString): (JSC::jsSubstring): (JSC::jsOwnedString):
  • kjs/JSString.h: (JSC::JSString::JSString): (JSC::JSString::): (JSC::jsSingleCharacterString): (JSC::jsSingleCharacterSubstring): (JSC::jsNontrivialString):
  • kjs/SmallStrings.cpp: (JSC::SmallStrings::createEmptyString): (JSC::SmallStrings::createSingleCharacterString):
  • kjs/StructureID.cpp: (JSC::StructureID::StructureID): (JSC::StructureID::addPropertyTransition): (JSC::StructureID::getterSetterTransition): (JSC::StructureIDChain::StructureIDChain):
  • kjs/StructureID.h: (JSC::StructureID::create): (JSC::StructureID::storedPrototype):
Location:
trunk/JavaScriptCore
Files:
17 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/ChangeLog

    r36315 r36316  
     12008-09-10  Maciej Stachowiak  <[email protected]>
     2
     3        Reviewed by Oliver.
     4       
     5        - enable polymorphic inline caching of properties of primitives
     6       
     7        1.012x speedup on SunSpider.
     8
     9        We create special structure IDs for JSString and
     10        JSNumberCell. Unlike normal structure IDs, these cannot hold the
     11        true prototype. Due to JS autoboxing semantics, the prototype used
     12        when looking up string or number properties depends on the lexical
     13        global object of the call site, not the creation site. Thus we
     14        enable StructureIDs to handle this quirk for primitives.
     15       
     16        Everything else should be straightforward.
     17       
     18        * VM/CTI.cpp:
     19        (JSC::CTI::privateCompileGetByIdProto):
     20        (JSC::CTI::privateCompileGetByIdChain):
     21        * VM/CTI.h:
     22        (JSC::CTI::compileGetByIdProto):
     23        (JSC::CTI::compileGetByIdChain):
     24        * VM/JSPropertyNameIterator.h:
     25        (JSC::JSPropertyNameIterator::JSPropertyNameIterator):
     26        * VM/Machine.cpp:
     27        (JSC::Machine::Machine):
     28        (JSC::cachePrototypeChain):
     29        (JSC::Machine::tryCachePutByID):
     30        (JSC::Machine::tryCacheGetByID):
     31        (JSC::Machine::privateExecute):
     32        (JSC::Machine::tryCTICachePutByID):
     33        (JSC::Machine::tryCTICacheGetByID):
     34        * kjs/GetterSetter.h:
     35        (JSC::GetterSetter::GetterSetter):
     36        * kjs/JSCell.h:
     37        * kjs/JSGlobalData.cpp:
     38        (JSC::JSGlobalData::JSGlobalData):
     39        * kjs/JSGlobalData.h:
     40        * kjs/JSGlobalObject.h:
     41        (JSC::StructureID::prototypeForLookup):
     42        * kjs/JSNumberCell.h:
     43        (JSC::JSNumberCell::JSNumberCell):
     44        (JSC::jsNumberCell):
     45        * kjs/JSObject.h:
     46        (JSC::JSObject::prototype):
     47        * kjs/JSString.cpp:
     48        (JSC::jsString):
     49        (JSC::jsSubstring):
     50        (JSC::jsOwnedString):
     51        * kjs/JSString.h:
     52        (JSC::JSString::JSString):
     53        (JSC::JSString::):
     54        (JSC::jsSingleCharacterString):
     55        (JSC::jsSingleCharacterSubstring):
     56        (JSC::jsNontrivialString):
     57        * kjs/SmallStrings.cpp:
     58        (JSC::SmallStrings::createEmptyString):
     59        (JSC::SmallStrings::createSingleCharacterString):
     60        * kjs/StructureID.cpp:
     61        (JSC::StructureID::StructureID):
     62        (JSC::StructureID::addPropertyTransition):
     63        (JSC::StructureID::getterSetterTransition):
     64        (JSC::StructureIDChain::StructureIDChain):
     65        * kjs/StructureID.h:
     66        (JSC::StructureID::create):
     67        (JSC::StructureID::storedPrototype):
     68
    1692008-09-09  Joerg Bornemann  <[email protected]>
    270
  • trunk/JavaScriptCore/VM/CTI.cpp

    r36311 r36316  
    16731673}
    16741674
    1675 void* CTI::privateCompileGetByIdProto(StructureID* structureID, StructureID* prototypeStructureID, size_t cachedOffset)
     1675void* CTI::privateCompileGetByIdProto(ExecState* exec, StructureID* structureID, StructureID* prototypeStructureID, size_t cachedOffset)
    16761676{
    16771677    // The prototype object definitely exists (if this stub exists the CodeBlock is referencing a StructureID that is
    16781678    // referencing the prototype object - let's speculatively load it's table nice and early!)
    1679     JSObject* protoObject = static_cast<JSObject*>(structureID->prototype());
     1679    JSObject* protoObject = static_cast<JSObject*>(structureID->prototypeForLookup(exec));
    16801680    OwnArrayPtr<JSValue*>* protoPropertyStorage = &protoObject->m_propertyStorage;
    16811681    m_jit.movl_mr(static_cast<void*>(protoPropertyStorage), X86::edx);
     
    17091709}
    17101710
    1711 void* CTI::privateCompileGetByIdChain(StructureID* structureID, StructureIDChain* chain, size_t count, size_t cachedOffset)
     1711void* CTI::privateCompileGetByIdChain(ExecState* exec, StructureID* structureID, StructureIDChain* chain, size_t count, size_t cachedOffset)
    17121712{
    17131713    ASSERT(count);
     
    17251725    JSCell* protoObject = 0;
    17261726    for (unsigned i = 0; i<count; ++i) {
    1727         protoObject = static_cast<JSCell*>(currStructureID->prototype());
     1727        protoObject = static_cast<JSCell*>(currStructureID->prototypeForLookup(exec));
    17281728        currStructureID = chainEntries[i].get();
    17291729
  • trunk/JavaScriptCore/VM/CTI.h

    r36311 r36316  
    246246        {
    247247            CTI cti(machine, exec, codeBlock);
    248             return cti.privateCompileGetByIdProto(structureID, prototypeStructureID, cachedOffset);
     248            return cti.privateCompileGetByIdProto(exec, structureID, prototypeStructureID, cachedOffset);
    249249        }
    250250
     
    252252        {
    253253            CTI cti(machine, exec, codeBlock);
    254             return cti.privateCompileGetByIdChain(structureID, chain, count, cachedOffset);
     254            return cti.privateCompileGetByIdChain(exec, structureID, chain, count, cachedOffset);
    255255        }
    256256
     
    289289        void privateCompile();
    290290        void* privateCompileGetByIdSelf(StructureID*, size_t cachedOffset);
    291         void* privateCompileGetByIdProto(StructureID*, StructureID* prototypeStructureID, size_t cachedOffset);
    292         void* privateCompileGetByIdChain(StructureID*, StructureIDChain*, size_t count, size_t cachedOffset);
     291        void* privateCompileGetByIdProto(ExecState*, StructureID*, StructureID* prototypeStructureID, size_t cachedOffset);
     292        void* privateCompileGetByIdChain(ExecState*, StructureID*, StructureIDChain*, size_t count, size_t cachedOffset);
    293293        void* privateCompilePutByIdReplace(StructureID*, size_t cachedOffset);
    294294        void* privateArrayLengthTrampoline();
  • trunk/JavaScriptCore/VM/JSPropertyNameIterator.h

    r36263 r36316  
    6767
    6868inline JSPropertyNameIterator::JSPropertyNameIterator(JSObject* object, Identifier* propertyNames, size_t numProperties)
    69     : m_object(object)
     69    : JSCell(0)
     70    , m_object(object)
    7071    , m_propertyNames(propertyNames)
    7172    , m_position(propertyNames)
  • trunk/JavaScriptCore/VM/Machine.cpp

    r36267 r36316  
    545545    static_cast<JSCell*>(jsArray)->~JSCell();
    546546
    547     JSString* jsString = new (storage) JSString("");
     547    JSString* jsString = new (storage) JSString(JSString::VPtrStealingHack);
    548548    m_jsStringVptr = jsString->vptr();
    549549    static_cast<JSCell*>(jsString)->~JSCell();
     
    11061106}
    11071107
    1108 StructureIDChain* cachePrototypeChain(StructureID* structureID)
    1109 {
    1110     RefPtr<StructureIDChain> chain = StructureIDChain::create(static_cast<JSObject*>(structureID->prototype())->structureID());
     1108static StructureIDChain* cachePrototypeChain(ExecState* exec, StructureID* structureID)
     1109{
     1110    RefPtr<StructureIDChain> chain = StructureIDChain::create(static_cast<JSObject*>(structureID->prototypeForLookup(exec))->structureID());
    11111111    structureID->setCachedPrototypeChain(chain.release());
    11121112    return structureID->cachedPrototypeChain();
     
    11361136    JSCell* baseCell = static_cast<JSCell*>(baseValue);
    11371137    StructureID* structureID = baseCell->structureID();
    1138 
    1139     // FIXME: Remove this !structureID check once all objects have StructureIDs.
    1140     if (!structureID) {
    1141         vPC[0] = getOpcode(op_put_by_id_generic);
    1142         return;
    1143     }
    11441138
    11451139    if (structureID->isDictionary()) {
     
    12111205    StructureID* structureID = static_cast<JSCell*>(baseValue)->structureID();
    12121206
    1213     // FIXME: Remove this !structureID check once all JSCells have StructureIDs.
    1214     if (!structureID) {
    1215         vPC[0] = getOpcode(op_get_by_id_generic);
    1216         return;
    1217     }
    1218 
    12191207    if (structureID->isDictionary()) {
    12201208        vPC[0] = getOpcode(op_get_by_id_generic);
     
    12461234    }
    12471235
    1248     if (slot.slotBase() == structureID->prototype()) {
     1236    if (slot.slotBase() == structureID->prototypeForLookup(exec)) {
    12491237        ASSERT(slot.slotBase()->isObject());
    12501238
     
    12701258    JSObject* o = static_cast<JSObject*>(baseValue);
    12711259    while (slot.slotBase() != o) {
    1272         JSValue* v = o->structureID()->prototype();
     1260        JSValue* v = o->structureID()->prototypeForLookup(exec);
    12731261
    12741262        // If we didn't find base in baseValue's prototype chain, then baseValue
     
    12941282    StructureIDChain* chain = structureID->cachedPrototypeChain();
    12951283    if (!chain)
    1296         chain = cachePrototypeChain(structureID);
     1284        chain = cachePrototypeChain(exec, structureID);
    12971285
    12981286    vPC[0] = getOpcode(op_get_by_id_chain);
     
    22652253
    22662254            if (LIKELY(baseCell->structureID() == structureID)) {
    2267                 ASSERT(structureID->prototype()->isObject());
    2268                 JSObject* protoObject = static_cast<JSObject*>(structureID->prototype());
     2255                ASSERT(structureID->prototypeForLookup(exec)->isObject());
     2256                JSObject* protoObject = static_cast<JSObject*>(structureID->prototypeForLookup(exec));
    22692257                StructureID* protoStructureID = vPC[5].u.structureID;
    22702258
     
    23062294                while (1) {
    23072295                    ASSERT(baseCell->isObject());
    2308                     JSObject* baseObject = static_cast<JSObject*>(baseCell->structureID()->prototype());
     2296                    JSObject* baseObject = static_cast<JSObject*>(baseCell->structureID()->prototypeForLookup(exec));
    23092297                    if (UNLIKELY(baseObject->structureID() != (*it).get()))
    23102298                        break;
     
    23382326
    23392327        Identifier& ident = codeBlock->identifiers[property];
     2328
    23402329        JSValue* baseValue = r[base].jsValue(exec);
    23412330        PropertySlot slot(baseValue);
     
    35503539    StructureID* structureID = baseCell->structureID();
    35513540
    3552     // FIXME: Remove this !structureID check once all objects have StructureIDs.
    3553     if (!structureID) {
    3554         ctiRepatchCallByReturnAddress(returnAddress, (void*)cti_op_put_by_id_generic);
    3555         return;
    3556     }
    3557 
    35583541    if (structureID->isDictionary()) {
    35593542        ctiRepatchCallByReturnAddress(returnAddress, (void*)cti_op_put_by_id_generic);
     
    36253608    JSCell* baseCell = static_cast<JSCell*>(baseValue);
    36263609    StructureID* structureID = baseCell->structureID();
    3627 
    3628     // FIXME: Remove this !structureID check once all JSCells have StructureIDs.
    3629     if (!structureID) {
    3630         ctiRepatchCallByReturnAddress(returnAddress, (void*)cti_op_get_by_id_generic);
    3631         return;
    3632     }
    36333610
    36343611    if (structureID->isDictionary()) {
     
    36563633    }
    36573634
    3658     if (slot.slotBase() == structureID->prototype()) {
     3635    if (slot.slotBase() == structureID->prototypeForLookup(exec)) {
    36593636        ASSERT(slot.slotBase()->isObject());
    36603637
     
    36823659    JSObject* o = static_cast<JSObject*>(baseValue);
    36833660    while (slot.slotBase() != o) {
    3684         JSValue* v = o->structureID()->prototype();
     3661        JSValue* v = o->structureID()->prototypeForLookup(exec);
    36853662
    36863663        // If we didn't find slotBase in baseValue's prototype chain, then baseValue
     
    37073684    StructureIDChain* chain = structureID->cachedPrototypeChain();
    37083685    if (!chain)
    3709         chain = cachePrototypeChain(structureID);
     3686        chain = cachePrototypeChain(exec, structureID);
    37103687
    37113688    vPC[0] = getOpcode(op_get_by_id_chain);
  • trunk/JavaScriptCore/kjs/GetterSetter.h

    r36263 r36316  
    3535    public:
    3636        GetterSetter()
    37             : m_getter(0)
     37            : JSCell(0)
     38            , m_getter(0)
    3839            , m_setter(0)
    3940        {
  • trunk/JavaScriptCore/kjs/JSCell.h

    r36263 r36316  
    4141        friend class CTI;
    4242    private:
    43         JSCell();
    4443        JSCell(StructureID*);
    4544        virtual ~JSCell();
     
    109108    };
    110109
    111     inline JSCell::JSCell()
    112         : m_structureID(0)
    113     {
    114     }
    115 
    116110    inline JSCell::JSCell(StructureID* structureID)
    117111        : m_structureID(structureID)
  • trunk/JavaScriptCore/kjs/JSGlobalData.cpp

    r36263 r36316  
    7878#endif
    7979    , nullProtoStructureID(StructureID::create(jsNull()))
     80    , stringStructureID(StructureID::create(jsNull(), StringType))
     81    , numberStructureID(StructureID::create(jsNull(), NumberType))
    8082    , identifierTable(createIdentifierTable())
    8183    , propertyNames(new CommonIdentifiers(this))
  • trunk/JavaScriptCore/kjs/JSGlobalData.h

    r36263 r36316  
    7575       
    7676        RefPtr<StructureID> nullProtoStructureID;
     77        RefPtr<StructureID> stringStructureID;
     78        RefPtr<StructureID> numberStructureID;
    7779
    7880        IdentifierTable* identifierTable;
  • trunk/JavaScriptCore/kjs/JSGlobalObject.h

    r36263 r36316  
    2525#include "JSGlobalData.h"
    2626#include "JSVariableObject.h"
     27#include "NumberPrototype.h"
     28#include "StringPrototype.h"
    2729#include <wtf/HashSet.h>
    2830#include <wtf/OwnPtr.h>
     
    294296    }
    295297
     298    inline JSValue* StructureID::prototypeForLookup(ExecState* exec) {
     299        if (m_type == ObjectType)
     300            return m_prototype;
     301
     302        if (m_type == StringType)
     303            return exec->lexicalGlobalObject()->stringPrototype();
     304
     305        ASSERT(m_type == NumberType);
     306        return exec->lexicalGlobalObject()->numberPrototype();
     307    }
     308
    296309} // namespace JSC
    297310
  • trunk/JavaScriptCore/kjs/JSNumberCell.h

    r36263 r36316  
    7171
    7272    private:
    73         JSNumberCell(double value)
    74             : m_value(value)
     73        JSNumberCell(ExecState* exec, double value)
     74            : JSCell(exec->globalData().numberStructureID.get())
     75            , m_value(value)
    7576        {
    7677        }
     
    9091    inline JSValue* jsNumberCell(ExecState* exec, double d)
    9192    {
    92         return new (exec) JSNumberCell(d);
     93        return new (exec) JSNumberCell(exec, d);
    9394    }
    9495
  • trunk/JavaScriptCore/kjs/JSObject.h

    r36314 r36316  
    214214inline JSValue* JSObject::prototype() const
    215215{
    216     return m_structureID->prototype();
     216    return m_structureID->storedPrototype();
    217217}
    218218
  • trunk/JavaScriptCore/kjs/JSString.cpp

    r36263 r36316  
    126126            return exec->globalData().smallStrings.singleCharacterString(exec, c);
    127127    }
    128     return new (exec) JSString(s);
     128    return new (exec) JSString(exec, s);
    129129}
    130130   
     
    141141            return exec->globalData().smallStrings.singleCharacterString(exec, c);
    142142    }
    143     return new (exec) JSString(UString::Rep::create(s.rep(), offset, length));
     143    return new (exec) JSString(exec, UString::Rep::create(s.rep(), offset, length));
    144144}
    145145
     
    154154            return exec->globalData().smallStrings.singleCharacterString(exec, c);
    155155    }
    156     return new (exec) JSString(s, JSString::HasOtherOwner);
     156    return new (exec) JSString(exec, s, JSString::HasOtherOwner);
    157157}
    158158
  • trunk/JavaScriptCore/kjs/JSString.h

    r36263 r36316  
    5353    class JSString : public JSCell {
    5454        friend class CTI;
     55        friend class Machine;
    5556
    5657    public:
    57         JSString(const UString& value)
    58             : m_value(value)
     58        JSString(ExecState* exec, const UString& value)
     59            : JSCell(exec->globalData().stringStructureID.get())
     60            , m_value(value)
    5961        {
    6062            Heap::heap(this)->reportExtraMemoryCost(value.cost());
     
    6264
    6365        enum HasOtherOwnerType { HasOtherOwner };
    64         JSString(const UString& value, HasOtherOwnerType)
    65             : m_value(value)
     66        JSString(ExecState* exec, const UString& value, HasOtherOwnerType)
     67            : JSCell(exec->globalData().stringStructureID.get())
     68            , m_value(value)
    6669        {
    6770        }
    68         JSString(PassRefPtr<UString::Rep> value, HasOtherOwnerType)
    69             : m_value(value)
     71        JSString(ExecState* exec, PassRefPtr<UString::Rep> value, HasOtherOwnerType)
     72            : JSCell(exec->globalData().stringStructureID.get())
     73            , m_value(value)
    7074        {
    7175        }
     
    8084
    8185    private:
     86        enum VPtrStealingHackType { VPtrStealingHack };
     87        JSString(VPtrStealingHackType)
     88            : JSCell(0)
     89        {
     90        }
    8291        virtual bool isString() const;
    8392
     
    109118        if (c <= 0xFF)
    110119            return exec->globalData().smallStrings.singleCharacterString(exec, c);
    111         return new (exec) JSString(UString(&c, 1));
     120        return new (exec) JSString(exec, UString(&c, 1));
    112121    }
    113122
     
    118127        if (c <= 0xFF)
    119128            return exec->globalData().smallStrings.singleCharacterString(exec, c);
    120         return new (exec) JSString(UString::Rep::create(s.rep(), offset, 1));
     129        return new (exec) JSString(exec, UString::Rep::create(s.rep(), offset, 1));
    121130    }
    122131
     
    126135        ASSERT(s[0]);
    127136        ASSERT(s[1]);
    128         return new (exec) JSString(s);
     137        return new (exec) JSString(exec, s);
    129138    }
    130139
     
    132141    {
    133142        ASSERT(s.size() > 1);
    134         return new (exec) JSString(s);
     143        return new (exec) JSString(exec, s);
    135144    }
    136145
  • trunk/JavaScriptCore/kjs/SmallStrings.cpp

    r36263 r36316  
    9191{
    9292    ASSERT(!m_emptyString);
    93     m_emptyString = new (exec) JSString("", JSString::HasOtherOwner);
     93    m_emptyString = new (exec) JSString(exec, "", JSString::HasOtherOwner);
    9494}
    9595
     
    9999        m_storage.set(new SmallStringsStorage);
    100100    ASSERT(!m_singleCharacterStrings[character]);
    101     m_singleCharacterStrings[character] = new (exec) JSString(m_storage->rep(character), JSString::HasOtherOwner);
     101    m_singleCharacterStrings[character] = new (exec) JSString(exec, m_storage->rep(character), JSString::HasOtherOwner);
    102102}
    103103
  • trunk/JavaScriptCore/kjs/StructureID.cpp

    r36285 r36316  
    3535namespace JSC {
    3636
    37 StructureID::StructureID(JSValue* prototype)
     37    StructureID::StructureID(JSValue* prototype, JSType type)
    3838    : m_isDictionary(false)
     39    , m_type(type)
    3940    , m_prototype(prototype)
    4041    , m_cachedPrototypeChain(0)
     
    5051{
    5152    ASSERT(!structureID->m_isDictionary);
     53    ASSERT(structureID->m_type == ObjectType);
    5254
    5355    if (StructureID* existingTransition = structureID->m_transitionTable.get(make_pair(propertyName.ustring().rep(), attributes))) {
     
    114116PassRefPtr<StructureID> StructureID::getterSetterTransition(StructureID* structureID)
    115117{
    116     RefPtr<StructureID> transition = create(structureID->prototype());
     118    RefPtr<StructureID> transition = create(structureID->storedPrototype());
    117119    transition->m_transitionCount = structureID->m_transitionCount + 1;
    118120    transition->m_propertyMap = structureID->m_propertyMap;
     
    133135
    134136    StructureID* tmp = structureID;
    135     while (!tmp->prototype()->isNull()) {
     137    while (!tmp->storedPrototype()->isNull()) {
    136138        ++size;
    137         tmp = static_cast<JSCell*>(tmp->prototype())->structureID();
     139        tmp = static_cast<JSCell*>(tmp->storedPrototype())->structureID();
    138140    }
    139141   
     
    143145    for (i = 0; i < size - 1; ++i) {
    144146        m_vector[i] = structureID;
    145         structureID = static_cast<JSObject*>(structureID->prototype())->structureID();
     147        structureID = static_cast<JSObject*>(structureID->storedPrototype())->structureID();
    146148    }
    147149    m_vector[i] = structureID;
  • trunk/JavaScriptCore/kjs/StructureID.h

    r36285 r36316  
    2727#define StructureID_h
    2828
     29#include "JSType.h"
    2930#include "JSValue.h"
    3031#include "PropertyMap.h"
     
    7273    class StructureID : public RefCounted<StructureID> {
    7374    public:
    74         static PassRefPtr<StructureID> create(JSValue* prototype)
     75        static PassRefPtr<StructureID> create(JSValue* prototype, JSType type = ObjectType)
    7576        {
    76             return adoptRef(new StructureID(prototype));
     77            return adoptRef(new StructureID(prototype, type));
    7778        }
    7879
     
    9394        bool isDictionary() const { return m_isDictionary; }
    9495
    95         JSValue* prototype() const { return m_prototype; }
    96 
     96        JSValue* storedPrototype() const { return m_prototype; }
     97        JSValue* prototypeForLookup(ExecState*);
     98       
    9799        void setCachedPrototypeChain(PassRefPtr<StructureIDChain> cachedPrototypeChain) { m_cachedPrototypeChain = cachedPrototypeChain; }
    98100        StructureIDChain* cachedPrototypeChain() const { return m_cachedPrototypeChain.get(); }
     
    105107        typedef HashMap<TransitionTableKey, StructureID*, TransitionTableHash, TransitionTableHashTraits> TransitionTable;
    106108
    107         StructureID(JSValue* prototype);
     109        StructureID(JSValue* prototype, JSType);
    108110       
    109111        static const size_t s_maxTransitionLength = 64;
    110112
    111113        bool m_isDictionary;
     114        JSType m_type;
    112115
    113116        JSValue* m_prototype;
Note: See TracChangeset for help on using the changeset viewer.