Changeset 46879 in webkit for trunk/JavaScriptCore


Ignore:
Timestamp:
Aug 6, 2009, 8:05:42 PM (16 years ago)
Author:
[email protected]
Message:

2009-08-06 Gavin Barraclough <[email protected]>

Reviewed by Oliver Hunt.

Make get_by_id/put_by_id/method_check/call defer optimization using a data flag rather than a code modification.
( https://bugs.webkit.org/show_bug.cgi?id=27635 )

This improves performance of ENABLE(ASSEMBLER_WX_EXCLUSIVE) builds by 2-2.5%, reducing the overhead to about 2.5%.
(No performance impact with ASSEMBLER_WX_EXCLUSIVE disabled).

  • bytecode/CodeBlock.cpp: (JSC::printStructureStubInfo):
    • Make StructureStubInfo store the type as an integer, rather than an OpcodeID.
  • bytecode/CodeBlock.h: (JSC::): (JSC::CallLinkInfo::seenOnce): (JSC::CallLinkInfo::setSeen): (JSC::MethodCallLinkInfo::seenOnce): (JSC::MethodCallLinkInfo::setSeen):
    • Change a pointer in CallLinkInfo/MethodCallLinkInfo to use a PtrAndFlags, use a flag to track when an op has been executed once.
  • bytecode/StructureStubInfo.cpp: (JSC::StructureStubInfo::deref):
    • Make StructureStubInfo store the type as an integer, rather than an OpcodeID.
  • bytecode/StructureStubInfo.h: (JSC::StructureStubInfo::StructureStubInfo): (JSC::StructureStubInfo::initGetByIdSelf): (JSC::StructureStubInfo::initGetByIdProto): (JSC::StructureStubInfo::initGetByIdChain): (JSC::StructureStubInfo::initGetByIdSelfList): (JSC::StructureStubInfo::initGetByIdProtoList): (JSC::StructureStubInfo::initPutByIdTransition): (JSC::StructureStubInfo::initPutByIdReplace): (JSC::StructureStubInfo::seenOnce): (JSC::StructureStubInfo::setSeen):
    • Make StructureStubInfo store the type as an integer, rather than an OpcodeID, add a flag to track when an op has been executed once.
  • bytecompiler/BytecodeGenerator.cpp: (JSC::BytecodeGenerator::emitGetById): (JSC::BytecodeGenerator::emitPutById):
    • Make StructureStubInfo store the type as an integer, rather than an OpcodeID.
  • jit/JIT.cpp: (JSC::JIT::privateCompileCTIMachineTrampolines): (JSC::JIT::unlinkCall):
    • Remove the "don't lazy link" stage of calls.
  • jit/JIT.h: (JSC::JIT::compileCTIMachineTrampolines):
    • Remove the "don't lazy link" stage of calls.
  • jit/JITCall.cpp: (JSC::JIT::compileOpCallSlowCase):
    • Remove the "don't lazy link" stage of calls.
  • jit/JITStubs.cpp: (JSC::JITThunks::JITThunks): (JSC::JITThunks::tryCachePutByID): (JSC::JITThunks::tryCacheGetByID): (JSC::JITStubs::DEFINE_STUB_FUNCTION): (JSC::JITStubs::getPolymorphicAccessStructureListSlot):
    • Remove the "don't lazy link" stage of calls, and the "_second" stage of get_by_id/put_by_id/method_check.
  • jit/JITStubs.h: (JSC::JITThunks::ctiStringLengthTrampoline): (JSC::JITStubs::):
    • Remove the "don't lazy link" stage of calls, and the "_second" stage of get_by_id/put_by_id/method_check.
  • wtf/PtrAndFlags.h: (WTF::PtrAndFlags::PtrAndFlags): (WTF::PtrAndFlags::operator!): (WTF::PtrAndFlags::operator->):
    • Add ! and -> operators, add constuctor with pointer argument.
Location:
trunk/JavaScriptCore
Files:
14 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/ChangeLog

    r46877 r46879  
     12009-08-06  Gavin Barraclough  <[email protected]>
     2
     3        Reviewed by Oliver Hunt.
     4
     5        Make get_by_id/put_by_id/method_check/call defer optimization using a data flag rather than a code modification.
     6        ( https://bugs.webkit.org/show_bug.cgi?id=27635 )
     7
     8        This improves performance of ENABLE(ASSEMBLER_WX_EXCLUSIVE) builds by 2-2.5%, reducing the overhead to about 2.5%.
     9        (No performance impact with ASSEMBLER_WX_EXCLUSIVE disabled).
     10
     11        * bytecode/CodeBlock.cpp:
     12        (JSC::printStructureStubInfo):
     13            - Make StructureStubInfo store the type as an integer, rather than an OpcodeID.
     14
     15        * bytecode/CodeBlock.h:
     16        (JSC::):
     17        (JSC::CallLinkInfo::seenOnce):
     18        (JSC::CallLinkInfo::setSeen):
     19        (JSC::MethodCallLinkInfo::seenOnce):
     20        (JSC::MethodCallLinkInfo::setSeen):
     21            - Change a pointer in CallLinkInfo/MethodCallLinkInfo to use a PtrAndFlags, use a flag to track when an op has been executed once.
     22
     23        * bytecode/StructureStubInfo.cpp:
     24        (JSC::StructureStubInfo::deref):
     25            - Make StructureStubInfo store the type as an integer, rather than an OpcodeID.
     26
     27        * bytecode/StructureStubInfo.h:
     28        (JSC::StructureStubInfo::StructureStubInfo):
     29        (JSC::StructureStubInfo::initGetByIdSelf):
     30        (JSC::StructureStubInfo::initGetByIdProto):
     31        (JSC::StructureStubInfo::initGetByIdChain):
     32        (JSC::StructureStubInfo::initGetByIdSelfList):
     33        (JSC::StructureStubInfo::initGetByIdProtoList):
     34        (JSC::StructureStubInfo::initPutByIdTransition):
     35        (JSC::StructureStubInfo::initPutByIdReplace):
     36        (JSC::StructureStubInfo::seenOnce):
     37        (JSC::StructureStubInfo::setSeen):
     38            - Make StructureStubInfo store the type as an integer, rather than an OpcodeID, add a flag to track when an op has been executed once.
     39
     40        * bytecompiler/BytecodeGenerator.cpp:
     41        (JSC::BytecodeGenerator::emitGetById):
     42        (JSC::BytecodeGenerator::emitPutById):
     43            - Make StructureStubInfo store the type as an integer, rather than an OpcodeID.
     44
     45        * jit/JIT.cpp:
     46        (JSC::JIT::privateCompileCTIMachineTrampolines):
     47        (JSC::JIT::unlinkCall):
     48            - Remove the "don't lazy link" stage of calls.
     49
     50        * jit/JIT.h:
     51        (JSC::JIT::compileCTIMachineTrampolines):
     52            - Remove the "don't lazy link" stage of calls.
     53
     54        * jit/JITCall.cpp:
     55        (JSC::JIT::compileOpCallSlowCase):
     56            - Remove the "don't lazy link" stage of calls.
     57
     58        * jit/JITStubs.cpp:
     59        (JSC::JITThunks::JITThunks):
     60        (JSC::JITThunks::tryCachePutByID):
     61        (JSC::JITThunks::tryCacheGetByID):
     62        (JSC::JITStubs::DEFINE_STUB_FUNCTION):
     63        (JSC::JITStubs::getPolymorphicAccessStructureListSlot):
     64            - Remove the "don't lazy link" stage of calls, and the "_second" stage of get_by_id/put_by_id/method_check.
     65
     66        * jit/JITStubs.h:
     67        (JSC::JITThunks::ctiStringLengthTrampoline):
     68        (JSC::JITStubs::):
     69            - Remove the "don't lazy link" stage of calls, and the "_second" stage of get_by_id/put_by_id/method_check.
     70
     71        * wtf/PtrAndFlags.h:
     72        (WTF::PtrAndFlags::PtrAndFlags):
     73        (WTF::PtrAndFlags::operator!):
     74        (WTF::PtrAndFlags::operator->):
     75            - Add ! and -> operators, add constuctor with pointer argument.
     76
    1772009-08-06  Zoltan Horvath  <[email protected]>
    278
  • trunk/JavaScriptCore/bytecode/CodeBlock.cpp

    r46620 r46879  
    231231static void printStructureStubInfo(const StructureStubInfo& stubInfo, unsigned instructionOffset)
    232232{
    233     switch (stubInfo.opcodeID) {
    234     case op_get_by_id_self:
     233    switch (stubInfo.accessType) {
     234    case access_get_by_id_self:
    235235        printf("  [%4d] %s: %s\n", instructionOffset, "get_by_id_self", pointerToSourceString(stubInfo.u.getByIdSelf.baseObjectStructure).UTF8String().c_str());
    236236        return;
    237     case op_get_by_id_proto:
     237    case access_get_by_id_proto:
    238238        printf("  [%4d] %s: %s, %s\n", instructionOffset, "get_by_id_proto", pointerToSourceString(stubInfo.u.getByIdProto.baseObjectStructure).UTF8String().c_str(), pointerToSourceString(stubInfo.u.getByIdProto.prototypeStructure).UTF8String().c_str());
    239239        return;
    240     case op_get_by_id_chain:
     240    case access_get_by_id_chain:
    241241        printf("  [%4d] %s: %s, %s\n", instructionOffset, "get_by_id_chain", pointerToSourceString(stubInfo.u.getByIdChain.baseObjectStructure).UTF8String().c_str(), pointerToSourceString(stubInfo.u.getByIdChain.chain).UTF8String().c_str());
    242242        return;
    243     case op_get_by_id_self_list:
     243    case access_get_by_id_self_list:
    244244        printf("  [%4d] %s: %s (%d)\n", instructionOffset, "op_get_by_id_self_list", pointerToSourceString(stubInfo.u.getByIdSelfList.structureList).UTF8String().c_str(), stubInfo.u.getByIdSelfList.listSize);
    245245        return;
    246     case op_get_by_id_proto_list:
     246    case access_get_by_id_proto_list:
    247247        printf("  [%4d] %s: %s (%d)\n", instructionOffset, "op_get_by_id_proto_list", pointerToSourceString(stubInfo.u.getByIdProtoList.structureList).UTF8String().c_str(), stubInfo.u.getByIdProtoList.listSize);
    248248        return;
    249     case op_put_by_id_transition:
     249    case access_put_by_id_transition:
    250250        printf("  [%4d] %s: %s, %s, %s\n", instructionOffset, "put_by_id_transition", pointerToSourceString(stubInfo.u.putByIdTransition.previousStructure).UTF8String().c_str(), pointerToSourceString(stubInfo.u.putByIdTransition.structure).UTF8String().c_str(), pointerToSourceString(stubInfo.u.putByIdTransition.chain).UTF8String().c_str());
    251251        return;
    252     case op_put_by_id_replace:
     252    case access_put_by_id_replace:
    253253        printf("  [%4d] %s: %s\n", instructionOffset, "put_by_id_replace", pointerToSourceString(stubInfo.u.putByIdReplace.baseObjectStructure).UTF8String().c_str());
    254254        return;
    255     case op_get_by_id:
     255    case access_get_by_id:
    256256        printf("  [%4d] %s\n", instructionOffset, "get_by_id");
    257257        return;
    258     case op_put_by_id:
     258    case access_put_by_id:
    259259        printf("  [%4d] %s\n", instructionOffset, "put_by_id");
    260260        return;
    261     case op_get_by_id_generic:
     261    case access_get_by_id_generic:
    262262        printf("  [%4d] %s\n", instructionOffset, "op_get_by_id_generic");
    263263        return;
    264     case op_put_by_id_generic:
     264    case access_put_by_id_generic:
    265265        printf("  [%4d] %s\n", instructionOffset, "op_put_by_id_generic");
    266266        return;
    267     case op_get_array_length:
     267    case access_get_array_length:
    268268        printf("  [%4d] %s\n", instructionOffset, "op_get_array_length");
    269269        return;
    270     case op_get_string_length:
     270    case access_get_string_length:
    271271        printf("  [%4d] %s\n", instructionOffset, "op_get_string_length");
    272272        return;
     
    13201320            structure->deref();
    13211321            // Both members must be filled at the same time
    1322             ASSERT(m_methodCallLinkInfos[i].cachedPrototypeStructure);
     1322            ASSERT(!!m_methodCallLinkInfos[i].cachedPrototypeStructure);
    13231323            m_methodCallLinkInfos[i].cachedPrototypeStructure->deref();
    13241324        }
  • trunk/JavaScriptCore/bytecode/CodeBlock.h

    r46831 r46879  
    3737#include "JumpTable.h"
    3838#include "Nodes.h"
     39#include "PtrAndFlags.h"
    3940#include "RegExp.h"
    4041#include "UString.h"
     
    5455
    5556namespace JSC {
     57
     58    enum HasSeenShouldRepatch {
     59        hasSeenShouldRepatch
     60    };
    5661
    5762    class ExecState;
     
    106111        CodeLocationDataLabelPtr hotPathBegin;
    107112        CodeLocationNearCall hotPathOther;
    108         CodeBlock* ownerCodeBlock;
     113        PtrAndFlags<CodeBlock, HasSeenShouldRepatch> ownerCodeBlock;
    109114        CodeBlock* callee;
    110115        unsigned position;
     
    112117        void setUnlinked() { callee = 0; }
    113118        bool isLinked() { return callee; }
     119
     120        bool seenOnce()
     121        {
     122            return ownerCodeBlock.isFlagSet(hasSeenShouldRepatch);
     123        }
     124
     125        void setSeen()
     126        {
     127            ownerCodeBlock.setFlag(hasSeenShouldRepatch);
     128        }
    114129    };
    115130
     
    117132        MethodCallLinkInfo()
    118133            : cachedStructure(0)
    119             , cachedPrototypeStructure(0)
    120         {
     134        {
     135        }
     136
     137        bool seenOnce()
     138        {
     139            return cachedPrototypeStructure.isFlagSet(hasSeenShouldRepatch);
     140        }
     141
     142        void setSeen()
     143        {
     144            cachedPrototypeStructure.setFlag(hasSeenShouldRepatch);
    121145        }
    122146
     
    124148        CodeLocationDataLabelPtr structureLabel;
    125149        Structure* cachedStructure;
    126         Structure* cachedPrototypeStructure;
     150        PtrAndFlags<Structure, HasSeenShouldRepatch> cachedPrototypeStructure;
    127151    };
    128152
  • trunk/JavaScriptCore/bytecode/StructureStubInfo.cpp

    r46620 r46879  
    3232void StructureStubInfo::deref()
    3333{
    34     switch (opcodeID) {
    35     case op_get_by_id_self:
     34    switch (accessType) {
     35    case access_get_by_id_self:
    3636        u.getByIdSelf.baseObjectStructure->deref();
    3737        return;
    38     case op_get_by_id_proto:
     38    case access_get_by_id_proto:
    3939        u.getByIdProto.baseObjectStructure->deref();
    4040        u.getByIdProto.prototypeStructure->deref();
    4141        return;
    42     case op_get_by_id_chain:
     42    case access_get_by_id_chain:
    4343        u.getByIdChain.baseObjectStructure->deref();
    4444        u.getByIdChain.chain->deref();
    4545        return;
    46     case op_get_by_id_self_list: {
     46    case access_get_by_id_self_list: {
    4747        PolymorphicAccessStructureList* polymorphicStructures = u.getByIdSelfList.structureList;
    4848        polymorphicStructures->derefStructures(u.getByIdSelfList.listSize);
     
    5050        return;
    5151    }
    52     case op_get_by_id_proto_list: {
     52    case access_get_by_id_proto_list: {
    5353        PolymorphicAccessStructureList* polymorphicStructures = u.getByIdProtoList.structureList;
    5454        polymorphicStructures->derefStructures(u.getByIdProtoList.listSize);
     
    5656        return;
    5757    }
    58     case op_put_by_id_transition:
     58    case access_put_by_id_transition:
    5959        u.putByIdTransition.previousStructure->deref();
    6060        u.putByIdTransition.structure->deref();
    6161        u.putByIdTransition.chain->deref();
    6262        return;
    63     case op_put_by_id_replace:
     63    case access_put_by_id_replace:
    6464        u.putByIdReplace.baseObjectStructure->deref();
    6565        return;
    66     case op_get_by_id:
    67     case op_put_by_id:
    68     case op_get_by_id_generic:
    69     case op_put_by_id_generic:
    70     case op_get_array_length:
    71     case op_get_string_length:
     66    case access_get_by_id:
     67    case access_put_by_id:
     68    case access_get_by_id_generic:
     69    case access_put_by_id_generic:
     70    case access_get_array_length:
     71    case access_get_string_length:
    7272        // These instructions don't ref their Structures.
    7373        return;
  • trunk/JavaScriptCore/bytecode/StructureStubInfo.h

    r46620 r46879  
    3636namespace JSC {
    3737
     38    enum AccessType {
     39        access_get_by_id_self,
     40        access_get_by_id_proto,
     41        access_get_by_id_chain,
     42        access_get_by_id_self_list,
     43        access_get_by_id_proto_list,
     44        access_put_by_id_transition,
     45        access_put_by_id_replace,
     46        access_get_by_id,
     47        access_put_by_id,
     48        access_get_by_id_generic,
     49        access_put_by_id_generic,
     50        access_get_array_length,
     51        access_get_string_length,
     52    };
     53
    3854    struct StructureStubInfo {
    39         StructureStubInfo(OpcodeID opcodeID)
    40             : opcodeID(opcodeID)
     55        StructureStubInfo(AccessType accessType)
     56            : accessType(accessType)
     57            , seen(false)
    4158        {
    4259        }
     
    4461        void initGetByIdSelf(Structure* baseObjectStructure)
    4562        {
    46             opcodeID = op_get_by_id_self;
     63            accessType = access_get_by_id_self;
    4764
    4865            u.getByIdSelf.baseObjectStructure = baseObjectStructure;
     
    5269        void initGetByIdProto(Structure* baseObjectStructure, Structure* prototypeStructure)
    5370        {
    54             opcodeID = op_get_by_id_proto;
     71            accessType = access_get_by_id_proto;
    5572
    5673            u.getByIdProto.baseObjectStructure = baseObjectStructure;
     
    6380        void initGetByIdChain(Structure* baseObjectStructure, StructureChain* chain)
    6481        {
    65             opcodeID = op_get_by_id_chain;
     82            accessType = access_get_by_id_chain;
    6683
    6784            u.getByIdChain.baseObjectStructure = baseObjectStructure;
     
    7491        void initGetByIdSelfList(PolymorphicAccessStructureList* structureList, int listSize)
    7592        {
    76             opcodeID = op_get_by_id_self_list;
     93            accessType = access_get_by_id_self_list;
    7794
    7895            u.getByIdProtoList.structureList = structureList;
     
    8299        void initGetByIdProtoList(PolymorphicAccessStructureList* structureList, int listSize)
    83100        {
    84             opcodeID = op_get_by_id_proto_list;
     101            accessType = access_get_by_id_proto_list;
    85102
    86103            u.getByIdProtoList.structureList = structureList;
     
    92109        void initPutByIdTransition(Structure* previousStructure, Structure* structure, StructureChain* chain)
    93110        {
    94             opcodeID = op_put_by_id_transition;
     111            accessType = access_put_by_id_transition;
    95112
    96113            u.putByIdTransition.previousStructure = previousStructure;
     
    106123        void initPutByIdReplace(Structure* baseObjectStructure)
    107124        {
    108             opcodeID = op_put_by_id_replace;
     125            accessType = access_put_by_id_replace;
    109126   
    110127            u.putByIdReplace.baseObjectStructure = baseObjectStructure;
     
    114131        void deref();
    115132
    116         OpcodeID opcodeID;
     133        bool seenOnce()
     134        {
     135            return seen;
     136        }
     137
     138        void setSeen()
     139        {
     140            seen = true;
     141        }
     142
     143        int accessType : 31;
     144        int seen : 1;
     145
    117146        union {
    118147            struct {
  • trunk/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp

    r46620 r46879  
    11911191{
    11921192#if ENABLE(JIT)
    1193     m_codeBlock->addStructureStubInfo(StructureStubInfo(op_get_by_id));
     1193    m_codeBlock->addStructureStubInfo(StructureStubInfo(access_get_by_id));
    11941194#else
    11951195    m_codeBlock->addPropertyAccessInstruction(instructions().size());
     
    12101210{
    12111211#if ENABLE(JIT)
    1212     m_codeBlock->addStructureStubInfo(StructureStubInfo(op_put_by_id));
     1212    m_codeBlock->addStructureStubInfo(StructureStubInfo(access_put_by_id));
    12131213#else
    12141214    m_codeBlock->addPropertyAccessInstruction(instructions().size());
  • trunk/JavaScriptCore/jit/JIT.cpp

    r46620 r46879  
    578578    // (and, if a new JSFunction happened to be constructed at the same location, we could get a false positive
    579579    // match).  Reset the check so it no longer matches.
    580     RepatchBuffer repatchBuffer(callLinkInfo->ownerCodeBlock);
     580    RepatchBuffer repatchBuffer(callLinkInfo->ownerCodeBlock.get());
    581581#if USE(JSVALUE32_64)
    582582    repatchBuffer.repatch(callLinkInfo->hotPathBegin, 0);
  • trunk/JavaScriptCore/jit/JIT.h

    r46832 r46879  
    318318        }
    319319
    320         static void compileCTIMachineTrampolines(JSGlobalData* globalData, RefPtr<ExecutablePool>* executablePool, CodePtr* ctiStringLengthTrampoline, CodePtr* ctiVirtualCallPreLink, CodePtr* ctiVirtualCallLink, CodePtr* ctiVirtualCall, CodePtr* ctiNativeCallThunk)
     320        static void compileCTIMachineTrampolines(JSGlobalData* globalData, RefPtr<ExecutablePool>* executablePool, CodePtr* ctiStringLengthTrampoline, CodePtr* ctiVirtualCallLink, CodePtr* ctiVirtualCall, CodePtr* ctiNativeCallThunk)
    321321        {
    322322            JIT jit(globalData);
    323             jit.privateCompileCTIMachineTrampolines(executablePool, globalData, ctiStringLengthTrampoline, ctiVirtualCallPreLink, ctiVirtualCallLink, ctiVirtualCall, ctiNativeCallThunk);
     323            jit.privateCompileCTIMachineTrampolines(executablePool, globalData, ctiStringLengthTrampoline, ctiVirtualCallLink, ctiVirtualCall, ctiNativeCallThunk);
    324324        }
    325325
    326326        static void patchGetByIdSelf(CodeBlock* codeblock, StructureStubInfo*, Structure*, size_t cachedOffset, ReturnAddressPtr returnAddress);
    327327        static void patchPutByIdReplace(CodeBlock* codeblock, StructureStubInfo*, Structure*, size_t cachedOffset, ReturnAddressPtr returnAddress);
    328         static void patchMethodCallProto(CodeBlock* codeblock, MethodCallLinkInfo&, JSFunction*, Structure*, JSObject*);
     328        static void patchMethodCallProto(CodeBlock* codeblock, MethodCallLinkInfo&, JSFunction*, Structure*, JSObject*, ReturnAddressPtr);
    329329
    330330        static void compilePatchGetArrayLength(JSGlobalData* globalData, CodeBlock* codeBlock, ReturnAddressPtr returnAddress)
     
    362362        void privateCompilePutByIdTransition(StructureStubInfo*, Structure*, Structure*, size_t cachedOffset, StructureChain*, ReturnAddressPtr returnAddress);
    363363
    364         void privateCompileCTIMachineTrampolines(RefPtr<ExecutablePool>* executablePool, JSGlobalData* data, CodePtr* ctiStringLengthTrampoline, CodePtr* ctiVirtualCallPreLink, CodePtr* ctiVirtualCallLink, CodePtr* ctiVirtualCall, CodePtr* ctiNativeCallThunk);
     364        void privateCompileCTIMachineTrampolines(RefPtr<ExecutablePool>* executablePool, JSGlobalData* data, CodePtr* ctiStringLengthTrampoline, CodePtr* ctiVirtualCallLink, CodePtr* ctiVirtualCall, CodePtr* ctiNativeCallThunk);
    365365        void privateCompilePatchGetArrayLength(ReturnAddressPtr returnAddress);
    366366
  • trunk/JavaScriptCore/jit/JITCall.cpp

    r46620 r46879  
    406406    move(Imm32(argCount), regT1);
    407407
    408     m_callStructureStubCompilationInfo[callLinkInfoIndex].callReturnLocation = emitNakedCall(m_globalData->jitStubs.ctiVirtualCallPreLink());
     408    m_callStructureStubCompilationInfo[callLinkInfoIndex].callReturnLocation = emitNakedCall(m_globalData->jitStubs.ctiVirtualCallLink());
    409409
    410410    // Put the return value in dst.
     
    689689    move(Imm32(argCount), regT1);
    690690
    691     m_callStructureStubCompilationInfo[callLinkInfoIndex].callReturnLocation = emitNakedCall(m_globalData->jitStubs.ctiVirtualCallPreLink());
     691    m_callStructureStubCompilationInfo[callLinkInfoIndex].callReturnLocation = emitNakedCall(m_globalData->jitStubs.ctiVirtualCallLink());
    692692
    693693    // Put the return value in dst.
  • trunk/JavaScriptCore/jit/JITOpcodes.cpp

    r46831 r46879  
    4040#if USE(JSVALUE32_64)
    4141
    42 void JIT::privateCompileCTIMachineTrampolines(RefPtr<ExecutablePool>* executablePool, JSGlobalData* globalData, CodePtr* ctiStringLengthTrampoline, CodePtr* ctiVirtualCallPreLink, CodePtr* ctiVirtualCallLink, CodePtr* ctiVirtualCall, CodePtr* ctiNativeCallThunk)
     42void JIT::privateCompileCTIMachineTrampolines(RefPtr<ExecutablePool>* executablePool, JSGlobalData* globalData, CodePtr* ctiStringLengthTrampoline, CodePtr* ctiVirtualCallLink, CodePtr* ctiVirtualCall, CodePtr* ctiNativeCallThunk)
    4343{
    4444#if ENABLE(JIT_OPTIMIZE_PROPERTY_ACCESS)
     
    6565
    6666#if ENABLE(JIT_OPTIMIZE_CALL)
    67     /* VirtualCallPreLink Trampoline */
    68     Label virtualCallPreLinkBegin = align();
    69 
    70     // regT0 holds callee, regT1 holds argCount.
    71     loadPtr(Address(regT0, OBJECT_OFFSETOF(JSFunction, m_body)), regT2);
    72     loadPtr(Address(regT2, OBJECT_OFFSETOF(FunctionBodyNode, m_code)), regT2);
    73     Jump hasCodeBlock1 = branchTestPtr(NonZero, regT2);
    74 
    75     // Lazily generate a CodeBlock.
    76     preserveReturnAddressAfterCall(regT3); // return address
    77     restoreArgumentReference();
    78     Call callJSFunction1 = call();
    79     move(regT0, regT2);
    80     emitGetJITStubArg(1, regT0); // callee
    81     emitGetJITStubArg(5, regT1); // argCount
    82     restoreReturnAddressBeforeReturn(regT3); // return address
    83     hasCodeBlock1.link(this);
    84 
    85     // regT2 holds codeBlock.
    86     Jump isNativeFunc1 = branch32(Equal, Address(regT2, OBJECT_OFFSETOF(CodeBlock, m_codeType)), Imm32(NativeCode));
    87 
    88     // Check argCount matches callee arity.
    89     Jump arityCheckOkay1 = branch32(Equal, Address(regT2, OBJECT_OFFSETOF(CodeBlock, m_numParameters)), regT1);
    90     preserveReturnAddressAfterCall(regT3);
    91     emitPutJITStubArg(regT3, 3); // return address
    92     emitPutJITStubArg(regT2, 7); // codeBlock
    93     restoreArgumentReference();
    94     Call callArityCheck1 = call();
    95     move(regT1, callFrameRegister);
    96     emitGetJITStubArg(1, regT0); // callee
    97     emitGetJITStubArg(5, regT1); // argCount
    98     restoreReturnAddressBeforeReturn(regT3); // return address
    99 
    100     arityCheckOkay1.link(this);
    101     isNativeFunc1.link(this);
    102    
    103     compileOpCallInitializeCallFrame();
    104 
    105     preserveReturnAddressAfterCall(regT3);
    106     emitPutJITStubArg(regT3, 3);
    107     restoreArgumentReference();
    108     Call callDontLazyLinkCall = call();
    109     restoreReturnAddressBeforeReturn(regT3);
    110     jump(regT0);
    111 
    11267    /* VirtualCallLink Trampoline */
    11368    Label virtualCallLinkBegin = align();
     
    167122    preserveReturnAddressAfterCall(regT3); // return address
    168123    restoreArgumentReference();
    169     Call callJSFunction3 = call();
     124    Call callJSFunction1 = call();
    170125    move(regT0, regT2);
    171126    emitGetJITStubArg(1, regT0); // callee
     
    183138    emitPutJITStubArg(regT2, 7); // codeBlock
    184139    restoreArgumentReference();
    185     Call callArityCheck3 = call();
     140    Call callArityCheck1 = call();
    186141    move(regT1, callFrameRegister);
    187142    emitGetJITStubArg(1, regT0); // callee
     
    355310    patchBuffer.link(string_failureCases3Call, FunctionPtr(cti_op_get_by_id_string_fail));
    356311#endif
    357 #if ENABLE(JIT_OPTIMIZE_CALL)
    358312    patchBuffer.link(callArityCheck1, FunctionPtr(cti_op_call_arityCheck));
    359313    patchBuffer.link(callJSFunction1, FunctionPtr(cti_op_call_JSFunction));
     314#if ENABLE(JIT_OPTIMIZE_CALL)
    360315    patchBuffer.link(callArityCheck2, FunctionPtr(cti_op_call_arityCheck));
    361316    patchBuffer.link(callJSFunction2, FunctionPtr(cti_op_call_JSFunction));
    362     patchBuffer.link(callDontLazyLinkCall, FunctionPtr(cti_vm_dontLazyLinkCall));
    363317    patchBuffer.link(callLazyLinkCall, FunctionPtr(cti_vm_lazyLinkCall));
    364318#endif
    365     patchBuffer.link(callArityCheck3, FunctionPtr(cti_op_call_arityCheck));
    366     patchBuffer.link(callJSFunction3, FunctionPtr(cti_op_call_JSFunction));
    367319
    368320    CodeRef finalCode = patchBuffer.finalizeCode();
     
    377329#endif
    378330#if ENABLE(JIT_OPTIMIZE_CALL)
    379     *ctiVirtualCallPreLink = trampolineAt(finalCode, virtualCallPreLinkBegin);
    380331    *ctiVirtualCallLink = trampolineAt(finalCode, virtualCallLinkBegin);
    381332#else
    382     UNUSED_PARAM(ctiVirtualCallPreLink);
    383333    UNUSED_PARAM(ctiVirtualCallLink);
    384334#endif
     
    15101460   do { m_labels[m_bytecodeIndex + (targetOffset)].used(); } while (false)
    15111461
    1512 void JIT::privateCompileCTIMachineTrampolines(RefPtr<ExecutablePool>* executablePool, JSGlobalData* globalData, CodePtr* ctiStringLengthTrampoline, CodePtr* ctiVirtualCallPreLink, CodePtr* ctiVirtualCallLink, CodePtr* ctiVirtualCall, CodePtr* ctiNativeCallThunk)
     1462void JIT::privateCompileCTIMachineTrampolines(RefPtr<ExecutablePool>* executablePool, JSGlobalData* globalData, CodePtr* ctiStringLengthTrampoline, CodePtr* ctiVirtualCallLink, CodePtr* ctiVirtualCall, CodePtr* ctiNativeCallThunk)
    15131463{
    15141464#if ENABLE(JIT_OPTIMIZE_PROPERTY_ACCESS)
     
    15341484    // (3) Trampolines for the slow cases of op_call / op_call_eval / op_construct.
    15351485    COMPILE_ASSERT(sizeof(CodeType) == 4, CodeTypeEnumMustBe32Bit);
    1536 
    1537     Label virtualCallPreLinkBegin = align();
    1538 
    1539     // Load the callee CodeBlock* into eax
    1540     loadPtr(Address(regT2, OBJECT_OFFSETOF(JSFunction, m_body)), regT3);
    1541     loadPtr(Address(regT3, OBJECT_OFFSETOF(FunctionBodyNode, m_code)), regT0);
    1542     Jump hasCodeBlock1 = branchTestPtr(NonZero, regT0);
    1543     preserveReturnAddressAfterCall(regT3);
    1544     restoreArgumentReference();
    1545     Call callJSFunction1 = call();
    1546     emitGetJITStubArg(1, regT2);
    1547     emitGetJITStubArg(3, regT1);
    1548     restoreReturnAddressBeforeReturn(regT3);
    1549     hasCodeBlock1.link(this);
    1550 
    1551     Jump isNativeFunc1 = branch32(Equal, Address(regT0, OBJECT_OFFSETOF(CodeBlock, m_codeType)), Imm32(NativeCode));
    1552 
    1553     // Check argCount matches callee arity.
    1554     Jump arityCheckOkay1 = branch32(Equal, Address(regT0, OBJECT_OFFSETOF(CodeBlock, m_numParameters)), regT1);
    1555     preserveReturnAddressAfterCall(regT3);
    1556     emitPutJITStubArg(regT3, 2);
    1557     emitPutJITStubArg(regT0, 4);
    1558     restoreArgumentReference();
    1559     Call callArityCheck1 = call();
    1560     move(regT1, callFrameRegister);
    1561     emitGetJITStubArg(1, regT2);
    1562     emitGetJITStubArg(3, regT1);
    1563     restoreReturnAddressBeforeReturn(regT3);
    1564     arityCheckOkay1.link(this);
    1565     isNativeFunc1.link(this);
    1566    
    1567     compileOpCallInitializeCallFrame();
    1568 
    1569     preserveReturnAddressAfterCall(regT3);
    1570     emitPutJITStubArg(regT3, 2);
    1571     restoreArgumentReference();
    1572     Call callDontLazyLinkCall = call();
    1573     emitGetJITStubArg(1, regT2);
    1574     restoreReturnAddressBeforeReturn(regT3);
    1575 
    1576     jump(regT0);
    15771486
    15781487    Label virtualCallLinkBegin = align();
     
    16241533    preserveReturnAddressAfterCall(regT3);
    16251534    restoreArgumentReference();
    1626     Call callJSFunction3 = call();
     1535    Call callJSFunction1 = call();
    16271536    emitGetJITStubArg(1, regT2);
    16281537    emitGetJITStubArg(3, regT1);
     
    16391548    emitPutJITStubArg(regT0, 4);
    16401549    restoreArgumentReference();
    1641     Call callArityCheck3 = call();
     1550    Call callArityCheck1 = call();
    16421551    move(regT1, callFrameRegister);
    16431552    emitGetJITStubArg(1, regT2);
     
    18821791    patchBuffer.link(string_failureCases3Call, FunctionPtr(cti_op_get_by_id_string_fail));
    18831792#endif
     1793    patchBuffer.link(callArityCheck1, FunctionPtr(cti_op_call_arityCheck));
     1794    patchBuffer.link(callJSFunction1, FunctionPtr(cti_op_call_JSFunction));
    18841795#if ENABLE(JIT_OPTIMIZE_CALL)
    1885     patchBuffer.link(callArityCheck1, FunctionPtr(cti_op_call_arityCheck));
    18861796    patchBuffer.link(callArityCheck2, FunctionPtr(cti_op_call_arityCheck));
    1887     patchBuffer.link(callJSFunction1, FunctionPtr(cti_op_call_JSFunction));
    18881797    patchBuffer.link(callJSFunction2, FunctionPtr(cti_op_call_JSFunction));
    1889     patchBuffer.link(callDontLazyLinkCall, FunctionPtr(cti_vm_dontLazyLinkCall));
    18901798    patchBuffer.link(callLazyLinkCall, FunctionPtr(cti_vm_lazyLinkCall));
    18911799#endif
    1892     patchBuffer.link(callArityCheck3, FunctionPtr(cti_op_call_arityCheck));
    1893     patchBuffer.link(callJSFunction3, FunctionPtr(cti_op_call_JSFunction));
    18941800
    18951801    CodeRef finalCode = patchBuffer.finalizeCode();
    18961802    *executablePool = finalCode.m_executablePool;
    18971803
    1898     *ctiVirtualCallPreLink = trampolineAt(finalCode, virtualCallPreLinkBegin);
    18991804    *ctiVirtualCallLink = trampolineAt(finalCode, virtualCallLinkBegin);
    19001805    *ctiVirtualCall = trampolineAt(finalCode, virtualCallBegin);
  • trunk/JavaScriptCore/jit/JITPropertyAccess.cpp

    r46598 r46879  
    635635}
    636636
    637 void JIT::patchMethodCallProto(CodeBlock* codeBlock, MethodCallLinkInfo& methodCallLinkInfo, JSFunction* callee, Structure* structure, JSObject* proto)
     637void JIT::patchMethodCallProto(CodeBlock* codeBlock, MethodCallLinkInfo& methodCallLinkInfo, JSFunction* callee, Structure* structure, JSObject* proto, ReturnAddressPtr returnAddress)
    638638{
    639639    RepatchBuffer repatchBuffer(codeBlock);
     
    652652    repatchBuffer.repatch(methodCallLinkInfo.structureLabel.dataLabelPtrAtOffset(patchOffsetMethodCheckProtoStruct), prototypeStructure);
    653653    repatchBuffer.repatch(methodCallLinkInfo.structureLabel.dataLabelPtrAtOffset(patchOffsetMethodCheckPutFunction), callee);
     654
     655    repatchBuffer.relinkCallerToFunction(returnAddress, FunctionPtr(cti_op_get_by_id));
    654656}
    655657
     
    14371439}
    14381440
    1439 void JIT::patchMethodCallProto(CodeBlock* codeBlock, MethodCallLinkInfo& methodCallLinkInfo, JSFunction* callee, Structure* structure, JSObject* proto)
     1441void JIT::patchMethodCallProto(CodeBlock* codeBlock, MethodCallLinkInfo& methodCallLinkInfo, JSFunction* callee, Structure* structure, JSObject* proto, ReturnAddressPtr returnAddress)
    14401442{
    14411443    RepatchBuffer repatchBuffer(codeBlock);
     
    14541456    repatchBuffer.repatch(methodCallLinkInfo.structureLabel.dataLabelPtrAtOffset(patchOffsetMethodCheckProtoStruct), prototypeStructure);
    14551457    repatchBuffer.repatch(methodCallLinkInfo.structureLabel.dataLabelPtrAtOffset(patchOffsetMethodCheckPutFunction), callee);
     1458
     1459    repatchBuffer.relinkCallerToFunction(returnAddress, FunctionPtr(cti_op_get_by_id));
    14561460}
    14571461
  • trunk/JavaScriptCore/jit/JITStubs.cpp

    r46831 r46879  
    635635JITThunks::JITThunks(JSGlobalData* globalData)
    636636{
    637     JIT::compileCTIMachineTrampolines(globalData, &m_executablePool, &m_ctiStringLengthTrampoline, &m_ctiVirtualCallPreLink, &m_ctiVirtualCallLink, &m_ctiVirtualCall, &m_ctiNativeCallThunk);
     637    JIT::compileCTIMachineTrampolines(globalData, &m_executablePool, &m_ctiStringLengthTrampoline, &m_ctiVirtualCallLink, &m_ctiVirtualCall, &m_ctiNativeCallThunk);
    638638
    639639#if PLATFORM_ARM_ARCH(7)
     
    658658#if ENABLE(JIT_OPTIMIZE_PROPERTY_ACCESS)
    659659
    660 NEVER_INLINE void JITThunks::tryCachePutByID(CallFrame* callFrame, CodeBlock* codeBlock, ReturnAddressPtr returnAddress, JSValue baseValue, const PutPropertySlot& slot)
     660NEVER_INLINE void JITThunks::tryCachePutByID(CallFrame* callFrame, CodeBlock* codeBlock, ReturnAddressPtr returnAddress, JSValue baseValue, const PutPropertySlot& slot, StructureStubInfo* stubInfo)
    661661{
    662662    // The interpreter checks for recursion here; I do not believe this can occur in CTI.
     
    684684        return;
    685685    }
    686 
    687     StructureStubInfo* stubInfo = &codeBlock->getStubInfo(returnAddress);
    688686
    689687    // Cache hit: Specialize instruction and ref Structures.
     
    706704}
    707705
    708 NEVER_INLINE void JITThunks::tryCacheGetByID(CallFrame* callFrame, CodeBlock* codeBlock, ReturnAddressPtr returnAddress, JSValue baseValue, const Identifier& propertyName, const PropertySlot& slot)
     706NEVER_INLINE void JITThunks::tryCacheGetByID(CallFrame* callFrame, CodeBlock* codeBlock, ReturnAddressPtr returnAddress, JSValue baseValue, const Identifier& propertyName, const PropertySlot& slot, StructureStubInfo* stubInfo)
    709707{
    710708    // FIXME: Write a test that proves we need to check for recursion here just
     
    744742        return;
    745743    }
    746 
    747     // In the interpreter the last structure is trapped here; in CTI we use the
    748     // *_second method to achieve a similar (but not quite the same) effect.
    749 
    750     StructureStubInfo* stubInfo = &codeBlock->getStubInfo(returnAddress);
    751744
    752745    // Cache hit: Specialize instruction and ref Structures.
     
    778771    size_t count = countPrototypeChainEntriesAndCheckForProxies(callFrame, baseValue, slot);
    779772    if (!count) {
    780         stubInfo->opcodeID = op_get_by_id_generic;
     773        stubInfo->accessType = access_get_by_id_generic;
    781774        return;
    782775    }
     
    10771070{
    10781071    STUB_INIT_STACK_FRAME(stackFrame);
    1079 
    10801072    CallFrame* callFrame = stackFrame.callFrame;
    10811073    Identifier& ident = stackFrame.args[1].identifier();
     
    10841076    stackFrame.args[0].jsValue().put(callFrame, ident, stackFrame.args[2].jsValue(), slot);
    10851077
    1086     ctiPatchCallByReturnAddress(callFrame->codeBlock(), STUB_RETURN_ADDRESS, FunctionPtr(cti_op_put_by_id_second));
    1087 
    1088     CHECK_FOR_EXCEPTION_AT_END();
    1089 }
    1090 
    1091 DEFINE_STUB_FUNCTION(void, op_put_by_id_second)
    1092 {
    1093     STUB_INIT_STACK_FRAME(stackFrame);
    1094 
    1095     PutPropertySlot slot;
    1096     stackFrame.args[0].jsValue().put(stackFrame.callFrame, stackFrame.args[1].identifier(), stackFrame.args[2].jsValue(), slot);
    1097     JITThunks::tryCachePutByID(stackFrame.callFrame, stackFrame.callFrame->codeBlock(), STUB_RETURN_ADDRESS, stackFrame.args[0].jsValue(), slot);
     1078    CodeBlock* codeBlock = stackFrame.callFrame->codeBlock();
     1079    StructureStubInfo* stubInfo = &codeBlock->getStubInfo(STUB_RETURN_ADDRESS);
     1080    if (!stubInfo->seenOnce())
     1081        stubInfo->setSeen();
     1082    else
     1083        JITThunks::tryCachePutByID(callFrame, codeBlock, STUB_RETURN_ADDRESS, stackFrame.args[0].jsValue(), slot, stubInfo);
     1084
    10981085    CHECK_FOR_EXCEPTION_AT_END();
    10991086}
     
    11271114}
    11281115
    1129 DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id)
     1116DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_method_check)
    11301117{
    11311118    STUB_INIT_STACK_FRAME(stackFrame);
     
    11371124    PropertySlot slot(baseValue);
    11381125    JSValue result = baseValue.get(callFrame, ident, slot);
    1139 
    1140     ctiPatchCallByReturnAddress(callFrame->codeBlock(), STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_id_second));
    1141 
    1142     CHECK_FOR_EXCEPTION_AT_END();
    1143     return JSValue::encode(result);
    1144 }
    1145 
    1146 DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_method_check)
    1147 {
    1148     STUB_INIT_STACK_FRAME(stackFrame);
    1149 
    1150     CallFrame* callFrame = stackFrame.callFrame;
    1151     Identifier& ident = stackFrame.args[1].identifier();
    1152 
    1153     JSValue baseValue = stackFrame.args[0].jsValue();
    1154     PropertySlot slot(baseValue);
    1155     JSValue result = baseValue.get(callFrame, ident, slot);
    1156 
    1157     ctiPatchCallByReturnAddress(callFrame->codeBlock(), STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_id_method_check_second));
    1158 
    1159     CHECK_FOR_EXCEPTION_AT_END();
    1160     return JSValue::encode(result);
    1161 }
    1162 
    1163 DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_method_check_second)
    1164 {
    1165     STUB_INIT_STACK_FRAME(stackFrame);
    1166 
    1167     CallFrame* callFrame = stackFrame.callFrame;
    1168     Identifier& ident = stackFrame.args[1].identifier();
    1169 
    1170     JSValue baseValue = stackFrame.args[0].jsValue();
    1171     PropertySlot slot(baseValue);
    1172     JSValue result = baseValue.get(callFrame, ident, slot);
    1173 
    11741126    CHECK_FOR_EXCEPTION();
     1127
     1128    CodeBlock* codeBlock = stackFrame.callFrame->codeBlock();
     1129    MethodCallLinkInfo& methodCallLinkInfo = codeBlock->getMethodCallLinkInfo(STUB_RETURN_ADDRESS);
     1130
     1131    if (!methodCallLinkInfo.seenOnce()) {
     1132        methodCallLinkInfo.setSeen();
     1133        return JSValue::encode(result);
     1134    }
    11751135
    11761136    // If we successfully got something, then the base from which it is being accessed must
     
    12031163        // The result fetched should always be the callee!
    12041164        ASSERT(result == JSValue(callee));
    1205         MethodCallLinkInfo& methodCallLinkInfo = callFrame->codeBlock()->getMethodCallLinkInfo(STUB_RETURN_ADDRESS);
    12061165
    12071166        // Check to see if the function is on the object's prototype.  Patch up the code to optimize.
    1208         if (slot.slotBase() == structure->prototypeForLookup(callFrame))
    1209             JIT::patchMethodCallProto(callFrame->codeBlock(), methodCallLinkInfo, callee, structure, slotBaseObject);
     1167        if (slot.slotBase() == structure->prototypeForLookup(callFrame)) {
     1168            JIT::patchMethodCallProto(codeBlock, methodCallLinkInfo, callee, structure, slotBaseObject, STUB_RETURN_ADDRESS);
     1169            return JSValue::encode(result);
     1170        }
     1171
    12101172        // Check to see if the function is on the object itself.
    12111173        // Since we generate the method-check to check both the structure and a prototype-structure (since this
     
    12141176        // for now.  For now it performs a check on a special object on the global object only used for this
    12151177        // purpose.  The object is in no way exposed, and as such the check will always pass.
    1216         else if (slot.slotBase() == baseValue)
    1217             JIT::patchMethodCallProto(callFrame->codeBlock(), methodCallLinkInfo, callee, structure, callFrame->scopeChain()->globalObject()->methodCallDummy());
    1218 
    1219         // For now let any other case be cached as a normal get_by_id.
     1178        if (slot.slotBase() == baseValue) {
     1179            JIT::patchMethodCallProto(codeBlock, methodCallLinkInfo, callee, structure, callFrame->scopeChain()->globalObject()->methodCallDummy(), STUB_RETURN_ADDRESS);
     1180            return JSValue::encode(result);
     1181        }
    12201182    }
    12211183
    12221184    // Revert the get_by_id op back to being a regular get_by_id - allow it to cache like normal, if it needs to.
    1223     ctiPatchCallByReturnAddress(callFrame->codeBlock(), STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_id));
    1224 
    1225     return JSValue::encode(result);
    1226 }
    1227 
    1228 DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_second)
    1229 {
    1230     STUB_INIT_STACK_FRAME(stackFrame);
    1231 
     1185    ctiPatchCallByReturnAddress(codeBlock, STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_id));
     1186    return JSValue::encode(result);
     1187}
     1188
     1189DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id)
     1190{
     1191    STUB_INIT_STACK_FRAME(stackFrame);
    12321192    CallFrame* callFrame = stackFrame.callFrame;
    12331193    Identifier& ident = stackFrame.args[1].identifier();
     
    12371197    JSValue result = baseValue.get(callFrame, ident, slot);
    12381198
    1239     JITThunks::tryCacheGetByID(callFrame, callFrame->codeBlock(), STUB_RETURN_ADDRESS, baseValue, ident, slot);
     1199    CodeBlock* codeBlock = stackFrame.callFrame->codeBlock();
     1200    StructureStubInfo* stubInfo = &codeBlock->getStubInfo(STUB_RETURN_ADDRESS);
     1201    if (!stubInfo->seenOnce())
     1202        stubInfo->setSeen();
     1203    else
     1204        JITThunks::tryCacheGetByID(callFrame, codeBlock, STUB_RETURN_ADDRESS, baseValue, ident, slot, stubInfo);
    12401205
    12411206    CHECK_FOR_EXCEPTION_AT_END();
     
    12691234        int listIndex = 1;
    12701235
    1271         if (stubInfo->opcodeID == op_get_by_id_self) {
     1236        if (stubInfo->accessType == access_get_by_id_self) {
    12721237            ASSERT(!stubInfo->stubRoutine);
    12731238            polymorphicStructureList = new PolymorphicAccessStructureList(CodeLocationLabel(), stubInfo->u.getByIdSelf.baseObjectStructure);
     
    12931258    listIndex = 1;
    12941259
    1295     switch (stubInfo->opcodeID) {
    1296     case op_get_by_id_proto:
     1260    switch (stubInfo->accessType) {
     1261    case access_get_by_id_proto:
    12971262        prototypeStructureList = new PolymorphicAccessStructureList(stubInfo->stubRoutine, stubInfo->u.getByIdProto.baseObjectStructure, stubInfo->u.getByIdProto.prototypeStructure);
    12981263        stubInfo->stubRoutine = CodeLocationLabel();
    12991264        stubInfo->initGetByIdProtoList(prototypeStructureList, 2);
    13001265        break;
    1301     case op_get_by_id_chain:
     1266    case access_get_by_id_chain:
    13021267        prototypeStructureList = new PolymorphicAccessStructureList(stubInfo->stubRoutine, stubInfo->u.getByIdChain.baseObjectStructure, stubInfo->u.getByIdChain.chain);
    13031268        stubInfo->stubRoutine = CodeLocationLabel();
    13041269        stubInfo->initGetByIdProtoList(prototypeStructureList, 2);
    13051270        break;
    1306     case op_get_by_id_proto_list:
     1271    case access_get_by_id_proto_list:
    13071272        prototypeStructureList = stubInfo->u.getByIdProtoList.structureList;
    13081273        listIndex = stubInfo->u.getByIdProtoList.listSize;
     
    15711536
    15721537#if ENABLE(JIT_OPTIMIZE_CALL)
    1573 DEFINE_STUB_FUNCTION(void*, vm_dontLazyLinkCall)
    1574 {
    1575     STUB_INIT_STACK_FRAME(stackFrame);
    1576 
    1577     JSGlobalData* globalData = stackFrame.globalData;
    1578     JSFunction* callee = asFunction(stackFrame.args[0].jsValue());
    1579 
    1580     ctiPatchNearCallByReturnAddress(stackFrame.callFrame->callerFrame()->codeBlock(), stackFrame.args[1].returnAddress(), globalData->jitStubs.ctiVirtualCallLink());
    1581 
    1582     return callee->body()->generatedJITCode().addressForCall().executableAddress();
    1583 }
    1584 
    15851538DEFINE_STUB_FUNCTION(void*, vm_lazyLinkCall)
    15861539{
    15871540    STUB_INIT_STACK_FRAME(stackFrame);
    1588 
    15891541    JSFunction* callee = asFunction(stackFrame.args[0].jsValue());
    15901542    JITCode& jitCode = callee->body()->generatedJITCode();
     
    15951547    else
    15961548        codeBlock = &callee->body()->generatedBytecode();
    1597 
    15981549    CallLinkInfo* callLinkInfo = &stackFrame.callFrame->callerFrame()->codeBlock()->getCallLinkInfo(stackFrame.args[1].returnAddress());
    1599     JIT::linkCall(callee, stackFrame.callFrame->callerFrame()->codeBlock(), codeBlock, jitCode, callLinkInfo, stackFrame.args[2].int32(), stackFrame.globalData);
     1550
     1551    if (!callLinkInfo->seenOnce())
     1552        callLinkInfo->setSeen();
     1553    else
     1554        JIT::linkCall(callee, stackFrame.callFrame->callerFrame()->codeBlock(), codeBlock, jitCode, callLinkInfo, stackFrame.args[2].int32(), stackFrame.globalData);
    16001555
    16011556    return jitCode.addressForCall().executableAddress();
  • trunk/JavaScriptCore/jit/JITStubs.h

    r46831 r46879  
    3939namespace JSC {
    4040
     41    struct StructureStubInfo;
     42
    4143    class CodeBlock;
    4244    class ExecutablePool;
     
    228230        JITThunks(JSGlobalData*);
    229231
    230         static void tryCacheGetByID(CallFrame*, CodeBlock*, ReturnAddressPtr returnAddress, JSValue baseValue, const Identifier& propertyName, const PropertySlot&);
    231         static void tryCachePutByID(CallFrame*, CodeBlock*, ReturnAddressPtr returnAddress, JSValue baseValue, const PutPropertySlot&);
    232        
     232        static void tryCacheGetByID(CallFrame*, CodeBlock*, ReturnAddressPtr returnAddress, JSValue baseValue, const Identifier& propertyName, const PropertySlot&, StructureStubInfo* stubInfo);
     233        static void tryCachePutByID(CallFrame*, CodeBlock*, ReturnAddressPtr returnAddress, JSValue baseValue, const PutPropertySlot&, StructureStubInfo* stubInfo);
     234
    233235        MacroAssemblerCodePtr ctiStringLengthTrampoline() { return m_ctiStringLengthTrampoline; }
    234         MacroAssemblerCodePtr ctiVirtualCallPreLink() { return m_ctiVirtualCallPreLink; }
    235236        MacroAssemblerCodePtr ctiVirtualCallLink() { return m_ctiVirtualCallLink; }
    236237        MacroAssemblerCodePtr ctiVirtualCall() { return m_ctiVirtualCall; }
     
    241242
    242243        MacroAssemblerCodePtr m_ctiStringLengthTrampoline;
    243         MacroAssemblerCodePtr m_ctiVirtualCallPreLink;
    244244        MacroAssemblerCodePtr m_ctiVirtualCallLink;
    245245        MacroAssemblerCodePtr m_ctiVirtualCall;
     
    264264    EncodedJSValue JIT_STUB cti_op_get_by_id_generic(STUB_ARGS_DECLARATION);
    265265    EncodedJSValue JIT_STUB cti_op_get_by_id_method_check(STUB_ARGS_DECLARATION);
    266     EncodedJSValue JIT_STUB cti_op_get_by_id_method_check_second(STUB_ARGS_DECLARATION);
    267266    EncodedJSValue JIT_STUB cti_op_get_by_id_proto_fail(STUB_ARGS_DECLARATION);
    268267    EncodedJSValue JIT_STUB cti_op_get_by_id_proto_list(STUB_ARGS_DECLARATION);
    269268    EncodedJSValue JIT_STUB cti_op_get_by_id_proto_list_full(STUB_ARGS_DECLARATION);
    270     EncodedJSValue JIT_STUB cti_op_get_by_id_second(STUB_ARGS_DECLARATION);
    271269    EncodedJSValue JIT_STUB cti_op_get_by_id_self_fail(STUB_ARGS_DECLARATION);
    272270    EncodedJSValue JIT_STUB cti_op_get_by_id_string_fail(STUB_ARGS_DECLARATION);
     
    346344    void JIT_STUB cti_op_put_by_id_fail(STUB_ARGS_DECLARATION);
    347345    void JIT_STUB cti_op_put_by_id_generic(STUB_ARGS_DECLARATION);
    348     void JIT_STUB cti_op_put_by_id_second(STUB_ARGS_DECLARATION);
    349346    void JIT_STUB cti_op_put_by_index(STUB_ARGS_DECLARATION);
    350347    void JIT_STUB cti_op_put_by_val(STUB_ARGS_DECLARATION);
     
    361358    void* JIT_STUB cti_op_switch_imm(STUB_ARGS_DECLARATION);
    362359    void* JIT_STUB cti_op_switch_string(STUB_ARGS_DECLARATION);
    363     void* JIT_STUB cti_vm_dontLazyLinkCall(STUB_ARGS_DECLARATION);
    364360    void* JIT_STUB cti_vm_lazyLinkCall(STUB_ARGS_DECLARATION);
    365361} // extern "C"
  • trunk/JavaScriptCore/wtf/PtrAndFlags.h

    r46620 r46879  
    3838    public:
    3939        PtrAndFlags() : m_ptrAndFlags(0) {}
     40        PtrAndFlags(T* ptr) : m_ptrAndFlags(0) { set(ptr); }
    4041
    4142        bool isFlagSet(FlagEnum flagNumber) const { ASSERT(flagNumber < 2); return m_ptrAndFlags & (1 << flagNumber); }
     
    5253        }
    5354
     55        bool operator!() const { return !get(); }
     56        T* operator->() const { return reinterpret_cast<T*>(m_ptrAndFlags & ~3); }
     57
    5458    private:
    5559        intptr_t m_ptrAndFlags;
Note: See TracChangeset for help on using the changeset viewer.