Ignore:
Timestamp:
Mar 1, 2022, 7:42:50 AM (3 years ago)
Author:
[email protected]
Message:

[JSC] Port EXTRA_CTI_THUNKS to all platforms
https://bugs.webkit.org/show_bug.cgi?id=233822

Patch by Geza Lore <Geza Lore> on 2022-03-01
Reviewed by Saam Barati.

Source/JavaScriptCore:

Port and enable all code paths under #ifdef ENABLE(EXTRA_CTI_THUNKS)
on all platforms, and remove the now unused code paths.

To port the extra thunks to all platforms, it was necessary to enable
them to do function calls to C++ slow path operations, which on some
platforms require passing arguments on the stack. To enable this,
CCallHelpers::emitCTIThunkPrologue and
CCallHelpers::emitCTIThunkEpilogue are introduced that allocate some
additional stack space on platforms where this is necessary.

Additionally, the thunks that require subsequent exception checking
now tail call directly to the exception check thunk, rather than
returning to the baseline code and do a separate call to the exception
check thunk. This saves an extra call site in the generated baseline
ops and reduces code size on all platforms (~1.5% reduction on x86_64).

Also factored out the statically allocated register definitions for
baseline ops into BaselineJITRegisters.h, as there are now quite a lot
of them and some are somewhat elaborate. This necessitates moving the
noOverlap and preferredArgumentGPR/preferredArgumentJSR constexpr
functions out from their previous place, so these now live in
GPRInfo.h

Enabling the extra CTI thunks on ARMv7/Thumb-2 saves about 25%
baseline code size, according to --dumpLinkBufferStats.

  • assembler/MacroAssembler.h:

(JSC::MacroAssembler::subPtr):

  • assembler/MacroAssemblerARMv7.h:

(JSC::MacroAssemblerARMv7::scratchRegister):

  • assembler/MacroAssemblerX86_64.h:

(JSC::MacroAssemblerX86_64::sub64):

  • bytecode/PolymorphicAccess.cpp:

(JSC::AccessGenerationState::emitExplicitExceptionHandler):

  • bytecode/StructureStubInfo.cpp:

(JSC::StructureStubInfo::initializeFromUnlinkedStructureStubInfo):

  • dfg/DFGJITCompiler.cpp:

(JSC::DFG::JITCompiler::link):
(JSC::DFG::JITCompiler::compile):
(JSC::DFG::JITCompiler::compileFunction):

  • dfg/DFGJITCompiler.h:
  • ftl/FTLCompile.cpp:

(JSC::FTL::compile):

  • ftl/FTLLink.cpp:

(JSC::FTL::link):

  • jit/CCallHelpers.h:

(JSC::CCallHelpers::emitCTIThunkPrologue):
(JSC::CCallHelpers::emitCTIThunkEpilogue):

  • jit/JIT.cpp:

(JSC::JIT::emitSlowCaseCall):
(JSC::JIT::privateCompileSlowCases):
(JSC::JIT::compileAndLinkWithoutFinalizing):
(JSC::JIT::link):

  • jit/JIT.h:
  • jit/JITArithmetic.cpp:

(JSC::JIT::emitSlow_op_mod):
(JSC::JIT::emit_op_mod):
(JSC::JIT::emit_op_div):

  • jit/JITCall.cpp:

(JSC::JIT::emit_op_iterator_open):
(JSC::JIT::emit_op_iterator_next):
(JSC::JIT::emitSlow_op_iterator_next):

  • jit/JITInlineCacheGenerator.cpp:

(JSC::JITGetByIdGenerator::generateBaselineDataICFastPath):
(JSC::JITGetByIdWithThisGenerator::generateBaselineDataICFastPath):
(JSC::JITPutByIdGenerator::generateBaselineDataICFastPath):

  • jit/JITInlineCacheGenerator.h:
  • jit/JITOpcodes.cpp:

(JSC::JIT::emit_op_jfalse):
(JSC::JIT::valueIsFalseyGenerator):
(JSC::JIT::emit_op_jtrue):
(JSC::JIT::valueIsTruthyGenerator):
(JSC::JIT::emit_op_throw):
(JSC::JIT::op_throw_handlerGenerator):
(JSC::JIT::emit_op_enter):
(JSC::JIT::op_enter_handlerGenerator):
(JSC::JIT::emitSlow_op_check_traps):
(JSC::JIT::op_check_traps_handlerGenerator):

  • jit/JITPropertyAccess.cpp:

(JSC::JIT::emit_op_get_by_val):
(JSC::JIT::generateGetByValSlowCase):
(JSC::JIT::slow_op_get_by_val_callSlowOperationThenCheckExceptionGenerator):
(JSC::JIT::emit_op_get_private_name):
(JSC::JIT::emitSlow_op_get_private_name):
(JSC::JIT::slow_op_get_private_name_callSlowOperationThenCheckExceptionGenerator):
(JSC::JIT::emit_op_set_private_brand):
(JSC::JIT::emitSlow_op_set_private_brand):
(JSC::JIT::emit_op_check_private_brand):
(JSC::JIT::emitSlow_op_check_private_brand):
(JSC::JIT::emit_op_put_by_val):
(JSC::JIT::emitSlow_op_put_by_val):
(JSC::JIT::slow_op_put_by_val_callSlowOperationThenCheckExceptionGenerator):
(JSC::JIT::emit_op_put_private_name):
(JSC::JIT::emitSlow_op_put_private_name):
(JSC::JIT::slow_op_put_private_name_callSlowOperationThenCheckExceptionGenerator):
(JSC::JIT::emit_op_del_by_id):
(JSC::JIT::emitSlow_op_del_by_id):
(JSC::JIT::slow_op_del_by_id_callSlowOperationThenCheckExceptionGenerator):
(JSC::JIT::emit_op_del_by_val):
(JSC::JIT::emitSlow_op_del_by_val):
(JSC::JIT::slow_op_del_by_val_callSlowOperationThenCheckExceptionGenerator):
(JSC::JIT::emit_op_try_get_by_id):
(JSC::JIT::emitSlow_op_try_get_by_id):
(JSC::JIT::emit_op_get_by_id_direct):
(JSC::JIT::emitSlow_op_get_by_id_direct):
(JSC::JIT::emit_op_get_by_id):
(JSC::JIT::emitSlow_op_get_by_id):
(JSC::JIT::slow_op_get_by_id_callSlowOperationThenCheckExceptionGenerator):
(JSC::JIT::emit_op_get_by_id_with_this):
(JSC::JIT::emitSlow_op_get_by_id_with_this):
(JSC::JIT::slow_op_get_by_id_with_this_callSlowOperationThenCheckExceptionGenerator):
(JSC::JIT::emit_op_put_by_id):
(JSC::JIT::emitSlow_op_put_by_id):
(JSC::JIT::slow_op_put_by_id_callSlowOperationThenCheckExceptionGenerator):
(JSC::JIT::emitSlow_op_in_by_id):
(JSC::JIT::emitSlow_op_in_by_val):
(JSC::JIT::emitHasPrivateSlow):
(JSC::JIT::emitSlow_op_has_private_name):
(JSC::JIT::emitSlow_op_has_private_brand):
(JSC::JIT::emitSlow_op_put_to_scope):
(JSC::JIT::slow_op_put_to_scopeGenerator):
(JSC::JIT::emit_op_get_property_enumerator):
(JSC::JIT::emit_op_enumerator_next):
(JSC::JIT::emit_enumerator_has_propertyImpl):
(JSC::JIT::emit_op_enumerator_get_by_val):
(JSC::JIT::emit_op_enumerator_in_by_val):
(JSC::JIT::emit_op_enumerator_has_own_property):

  • jit/JITThunks.cpp:
  • jit/JITThunks.h:
  • jit/SlowPathCall.cpp:

(JSC::JITSlowPathCall::call):
(JSC::JITSlowPathCall::generateThunk):

  • jit/SlowPathCall.h:

(JSC::JITSlowPathCall::JITSlowPathCall):

  • jit/ThunkGenerators.cpp:

(JSC::handleExceptionGenerator):
(JSC::checkExceptionGenerator):

  • jit/ThunkGenerators.h:

Source/WTF:

  • wtf/PlatformEnable.h:

Remove EXTRA_CTI_THUNKS define (now always on on all platforms)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/jit/SlowPathCall.cpp

    r277974 r290647  
    3737namespace JSC {
    3838
    39 #if ENABLE(EXTRA_CTI_THUNKS)
     39namespace {
     40    constexpr GPRReg bytecodeOffsetGPR = JIT::argumentGPR3;
     41}
    4042
    4143void JITSlowPathCall::call()
     
    4547    ASSERT(BytecodeIndex(bytecodeOffset) == m_jit->m_bytecodeIndex);
    4648
    47     UNUSED_VARIABLE(m_pc);
    48     constexpr GPRReg bytecodeOffsetReg = GPRInfo::argumentGPR1;
    49     m_jit->move(JIT::TrustedImm32(bytecodeOffset), bytecodeOffsetReg);
     49    m_jit->move(JIT::TrustedImm32(bytecodeOffset), bytecodeOffsetGPR);
    5050    m_jit->emitNakedNearCall(vm.jitStubs->ctiSlowPathFunctionStub(vm, m_slowPathFunction).retaggedCode<NoPtrTag>());
    5151}
     
    5555    CCallHelpers jit;
    5656
    57     constexpr GPRReg bytecodeOffsetReg = JIT::argumentGPR1;
     57    jit.emitCTIThunkPrologue();
    5858
    59 #if CPU(X86_64)
    60     jit.push(X86Registers::ebp);
    61 #elif CPU(ARM64)
    62     jit.tagReturnAddress();
    63     jit.pushPair(CCallHelpers::framePointerRegister, CCallHelpers::linkRegister);
     59    // Call slow operation
     60    jit.store32(bytecodeOffsetGPR, CCallHelpers::tagFor(CallFrameSlot::argumentCountIncludingThis));
     61    jit.prepareCallOperation(vm);
     62
     63#if OS(WINDOWS) && CPU(X86_64)
     64    // On Windows, return values larger than 8 bytes are retuened via an implicit pointer passed as
     65    // the first argument, and remaining arguments are shifted to the right. Make space for this.
     66    static_assert(sizeof(SlowPathReturnType) == 16, "Assumed by generated call site below");
     67    jit.subPtr(MacroAssembler::TrustedImm32(16), MacroAssembler::stackPointerRegister);
     68    jit.move(MacroAssembler::stackPointerRegister, GPRInfo::argumentGPR0);
     69    constexpr GPRReg callFrameArgGPR = GPRInfo::argumentGPR1;
     70    constexpr GPRReg pcArgGPR = GPRInfo::argumentGPR2;
     71    static_assert(noOverlap(GPRInfo::argumentGPR0, callFrameArgGPR, pcArgGPR, bytecodeOffsetGPR));
     72#else
     73    constexpr GPRReg callFrameArgGPR = GPRInfo::argumentGPR0;
     74    constexpr GPRReg pcArgGPR = GPRInfo::argumentGPR1;
     75    static_assert(noOverlap(callFrameArgGPR, pcArgGPR, bytecodeOffsetGPR));
     76#endif
     77    jit.move(GPRInfo::callFrameRegister, callFrameArgGPR);
     78    jit.loadPtr(CCallHelpers::addressFor(CallFrameSlot::codeBlock), pcArgGPR);
     79    jit.loadPtr(CCallHelpers::Address(pcArgGPR, CodeBlock::offsetOfInstructionsRawPointer()), pcArgGPR);
     80    jit.addPtr(bytecodeOffsetGPR, pcArgGPR);
     81
     82    CCallHelpers::Call call = jit.call(OperationPtrTag);
     83
     84#if OS(WINDOWS) && CPU(X86_64)
     85    jit.pop(GPRInfo::returnValueGPR); // pc
     86    jit.pop(GPRInfo::returnValueGPR2); // callFrame
    6487#endif
    6588
    66     jit.store32(bytecodeOffsetReg, CCallHelpers::tagFor(CallFrameSlot::argumentCountIncludingThis));
     89    jit.emitCTIThunkEpilogue();
    6790
    68     jit.loadPtr(CCallHelpers::addressFor(CallFrameSlot::codeBlock), GPRInfo::argumentGPR0);
    69 
    70     jit.prepareCallOperation(vm);
    71 
    72     jit.loadPtr(CCallHelpers::Address(GPRInfo::argumentGPR0, CodeBlock::offsetOfInstructionsRawPointer()), GPRInfo::argumentGPR0);
    73     static_assert(JIT::argumentGPR1 == bytecodeOffsetReg);
    74     jit.addPtr(GPRInfo::argumentGPR0, GPRInfo::argumentGPR1);
    75     jit.move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
    76 
    77     CCallHelpers::Call call = jit.call(OperationPtrTag);
    78     CCallHelpers::Jump exceptionCheck = jit.emitNonPatchableExceptionCheck(vm);
    79 
    80 #if CPU(X86_64)
    81     jit.pop(X86Registers::ebp);
    82 #elif CPU(ARM64)
    83     jit.popPair(CCallHelpers::framePointerRegister, CCallHelpers::linkRegister);
    84 #endif
    85     jit.ret();
    86 
    87     auto handler = vm.getCTIStub(popThunkStackPreservesAndHandleExceptionGenerator);
     91    // Tail call to exception check thunk
     92    CCallHelpers::Jump exceptionCheck = jit.jump();
    8893
    8994    LinkBuffer patchBuffer(jit, GLOBAL_THUNK_ID, LinkBuffer::Profile::ExtraCTIThunk);
    9095    patchBuffer.link(call, FunctionPtr<OperationPtrTag>(slowPathFunction));
    91     patchBuffer.link(exceptionCheck, CodeLocationLabel(handler.retaggedCode<NoPtrTag>()));
     96    patchBuffer.link(exceptionCheck, CodeLocationLabel(vm.getCTIStub(checkExceptionGenerator).retaggedCode<NoPtrTag>()));
    9297    return FINALIZE_CODE(patchBuffer, JITThunkPtrTag, "SlowPathCall");
    9398}
    94 
    95 #endif // ENABLE(EXTRA_CTI_THUNKS)
    9699
    97100} // namespace JSC
Note: See TracChangeset for help on using the changeset viewer.