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

Legend:

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