Ignore:
Timestamp:
Feb 24, 2010, 1:02:40 AM (15 years ago)
Author:
[email protected]
Message:

2010-02-24 Oliver Hunt <[email protected]>

Reviewed by Gavin Barraclough.

Speed up getter performance in the jit
https://bugs.webkit.org/show_bug.cgi?id=35332

Implement getter lookup caching in the interpreter.
The getter stubs are generated through basically the
same code paths as the normal get_by_id caching.
Instead of simply loading a property and returning,
we load the getter slot, and pass the getter, base value
and return address to a shared stub used for getter
dispatch.

  • jit/JIT.h: (JSC::JIT::compileGetByIdProto): (JSC::JIT::compileGetByIdSelfList): (JSC::JIT::compileGetByIdProtoList): (JSC::JIT::compileGetByIdChainList): (JSC::JIT::compileGetByIdChain):
  • jit/JITPropertyAccess.cpp: (JSC::JIT::privateCompileGetByIdProto): (JSC::JIT::privateCompileGetByIdSelfList): (JSC::JIT::privateCompileGetByIdProtoList): (JSC::JIT::privateCompileGetByIdChainList): (JSC::JIT::privateCompileGetByIdChain):
  • jit/JITPropertyAccess32_64.cpp: (JSC::JIT::privateCompileGetByIdProto): (JSC::JIT::privateCompileGetByIdSelfList): (JSC::JIT::privateCompileGetByIdProtoList): (JSC::JIT::privateCompileGetByIdChainList): (JSC::JIT::privateCompileGetByIdChain):
  • jit/JITStubs.cpp: (JSC::JITThunks::tryCacheGetByID): (JSC::DEFINE_STUB_FUNCTION):
  • jit/JITStubs.h: (JSC::):
  • runtime/GetterSetter.h:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/jit/JITStubs.cpp

    r55002 r55185  
    3939#include "Debugger.h"
    4040#include "ExceptionHelpers.h"
     41#include "GetterSetter.h"
    4142#include "GlobalEvalFunction.h"
    4243#include "JIT.h"
     
    857858
    858859    // Uncacheable: give up.
    859     if (!slot.isCacheableValue()) {
     860    if (!slot.isCacheable()) {
    860861        ctiPatchCallByReturnAddress(codeBlock, returnAddress, FunctionPtr(cti_op_get_by_id_generic));
    861862        return;
    862863    }
    863     ASSERT(!slot.isGetter());
    864864
    865865    JSCell* baseCell = asCell(baseValue);
     
    876876        // set this up, so derefStructures can do it's job.
    877877        stubInfo->initGetByIdSelf(structure);
    878 
    879         JIT::patchGetByIdSelf(codeBlock, stubInfo, structure, slot.cachedOffset(), returnAddress);
     878        if (slot.isGetter())
     879            ctiPatchCallByReturnAddress(codeBlock, returnAddress, FunctionPtr(cti_op_get_by_id_self_fail));
     880        else
     881            JIT::patchGetByIdSelf(codeBlock, stubInfo, structure, slot.cachedOffset(), returnAddress);
    880882        return;
    881883    }
     
    903905        ASSERT(!structure->isDictionary());
    904906        ASSERT(!slotBaseObject->structure()->isDictionary());
    905         JIT::compileGetByIdProto(callFrame->scopeChain()->globalData, callFrame, codeBlock, stubInfo, structure, slotBaseObject->structure(), offset, returnAddress);
     907        JIT::compileGetByIdProto(callFrame->scopeChain()->globalData, callFrame, codeBlock, stubInfo, structure, slotBaseObject->structure(), slot.isGetter(), offset, returnAddress);
    906908        return;
    907909    }
     
    916918    StructureChain* prototypeChain = structure->prototypeChain(callFrame);
    917919    stubInfo->initGetByIdChain(structure, prototypeChain);
    918     JIT::compileGetByIdChain(callFrame->scopeChain()->globalData, callFrame, codeBlock, stubInfo, structure, prototypeChain, count, offset, returnAddress);
     920    JIT::compileGetByIdChain(callFrame->scopeChain()->globalData, callFrame, codeBlock, stubInfo, structure, prototypeChain, count, slot.isGetter(), offset, returnAddress);
    919921}
    920922
     
    13761378
    13771379    if (baseValue.isCell()
    1378         && slot.isCacheableValue()
     1380        && slot.isCacheable()
    13791381        && !asCell(baseValue)->structure()->isUncacheableDictionary()
    13801382        && slot.slotBase() == baseValue) {
     
    13981400        }
    13991401
    1400         JIT::compileGetByIdSelfList(callFrame->scopeChain()->globalData, codeBlock, stubInfo, polymorphicStructureList, listIndex, asCell(baseValue)->structure(), slot.cachedOffset());
     1402        JIT::compileGetByIdSelfList(callFrame->scopeChain()->globalData, codeBlock, stubInfo, polymorphicStructureList, listIndex, asCell(baseValue)->structure(), slot.isGetter(), slot.cachedOffset());
    14011403
    14021404        if (listIndex == (POLYMORPHIC_LIST_CACHE_SIZE - 1))
     
    14361438}
    14371439
     1440DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_getter_stub)
     1441{
     1442    STUB_INIT_STACK_FRAME(stackFrame);
     1443    CallFrame* callFrame = stackFrame.callFrame;
     1444    GetterSetter* getterSetter = asGetterSetter(stackFrame.args[0].jsObject());
     1445    if (!getterSetter->getter())
     1446        return JSValue::encode(jsUndefined());
     1447    JSObject* getter = asObject(getterSetter->getter());
     1448    CallData callData;
     1449    CallType callType = getter->getCallData(callData);
     1450    JSValue result = call(callFrame, getter, callType, callData, stackFrame.args[1].jsObject(), ArgList());
     1451    if (callFrame->hadException())
     1452        returnToThrowTrampoline(&callFrame->globalData(), stackFrame.args[2].returnAddress(), STUB_RETURN_ADDRESS);
     1453
     1454    return JSValue::encode(result);
     1455}
     1456
    14381457DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_proto_list)
    14391458{
     
    14491468    CHECK_FOR_EXCEPTION();
    14501469
    1451     if (!baseValue.isCell() || !slot.isCacheableValue() || asCell(baseValue)->structure()->isDictionary()) {
     1470    if (!baseValue.isCell() || !slot.isCacheable() || asCell(baseValue)->structure()->isDictionary()) {
    14521471        ctiPatchCallByReturnAddress(callFrame->codeBlock(), STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_id_proto_fail));
    14531472        return JSValue::encode(result);
     
    14771496        PolymorphicAccessStructureList* prototypeStructureList = getPolymorphicAccessStructureListSlot(stubInfo, listIndex);
    14781497
    1479         JIT::compileGetByIdProtoList(callFrame->scopeChain()->globalData, callFrame, codeBlock, stubInfo, prototypeStructureList, listIndex, structure, slotBaseObject->structure(), offset);
     1498        JIT::compileGetByIdProtoList(callFrame->scopeChain()->globalData, callFrame, codeBlock, stubInfo, prototypeStructureList, listIndex, structure, slotBaseObject->structure(), slot.isGetter(), offset);
    14801499
    14811500        if (listIndex == (POLYMORPHIC_LIST_CACHE_SIZE - 1))
     
    14871506
    14881507        StructureChain* protoChain = structure->prototypeChain(callFrame);
    1489         JIT::compileGetByIdChainList(callFrame->scopeChain()->globalData, callFrame, codeBlock, stubInfo, prototypeStructureList, listIndex, structure, protoChain, count, offset);
     1508        JIT::compileGetByIdChainList(callFrame->scopeChain()->globalData, callFrame, codeBlock, stubInfo, prototypeStructureList, listIndex, structure, protoChain, count, slot.isGetter(), offset);
    14901509
    14911510        if (listIndex == (POLYMORPHIC_LIST_CACHE_SIZE - 1))
Note: See TracChangeset for help on using the changeset viewer.