Changeset 36316 in webkit for trunk/JavaScriptCore/VM/Machine.cpp


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):
File:
1 edited

Legend:

Unmodified
Added
Removed
  • 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);
Note: See TracChangeset for help on using the changeset viewer.