⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 283288 in webkit


Ignore:
Timestamp:
Sep 29, 2021, 5:47:41 PM (5 years ago)
Author:
sbarati@apple.com
Message:

We need to load the baseline JIT's constant pool register after OSR exit to checkpoints if we return to baseline code
https://bugs.webkit.org/show_bug.cgi?id=230972
<rdar://83659469>

Reviewed by Mark Lam and Yusuke Suzuki.

JSTests:

  • stress/checkpoint-osr-exit-needs-to-reload-baseline-jit-constant-pool-gpr.js: Added.

(empty):
(empty2):
(test):

Source/JavaScriptCore:

Consider the following:

  • We have a CodeBlock A.
  • DFG or FTL compiles an exit to A when A is still LLInt code. This means the OSR exit code will materialize registers as if A is LLInt.
  • We tier up A to Baseline JIT code.
  • Now, we take the exit to A as if it's LLInt. But the checkpoint OSR exit code will actually jump to the tiered up baseline code when it's done, because it determines where to jump at runtime. Because of this, when we return from the checkpoint code, and if we are jumping into baseline code, we must always load the constant pool register.
  • There's no need to load the metadata register because that register is shared with LLInt code, and will already contain the right value.
  • jit/JIT.cpp:

(JSC::JIT::privateCompileMainPass):

  • llint/LLIntSlowPaths.cpp:

(JSC::LLInt::dispatchToNextInstructionDuringExit):
(JSC::LLInt::llint_slow_path_checkpoint_osr_exit_from_inlined_call):
(JSC::LLInt::llint_slow_path_checkpoint_osr_exit):
(JSC::LLInt::dispatchToNextInstruction): Deleted.

  • llint/LowLevelInterpreter.asm:
  • llint/LowLevelInterpreter64.asm:
Location:
trunk
Files:
1 added
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/JSTests/ChangeLog

    r283232 r283288  
     12021-09-29  Saam Barati  <sbarati@apple.com>
     2
     3        We need to load the baseline JIT's constant pool register after OSR exit to checkpoints if we return to baseline code
     4        https://bugs.webkit.org/show_bug.cgi?id=230972
     5        <rdar://83659469>
     6
     7        Reviewed by Mark Lam and Yusuke Suzuki.
     8
     9        * stress/checkpoint-osr-exit-needs-to-reload-baseline-jit-constant-pool-gpr.js: Added.
     10        (empty):
     11        (empty2):
     12        (test):
     13
    1142021-09-29  Saam Barati  <sbarati@apple.com>
    215
  • trunk/Source/JavaScriptCore/ChangeLog

    r283287 r283288  
     12021-09-29  Saam Barati  <sbarati@apple.com>
     2
     3        We need to load the baseline JIT's constant pool register after OSR exit to checkpoints if we return to baseline code
     4        https://bugs.webkit.org/show_bug.cgi?id=230972
     5        <rdar://83659469>
     6
     7        Reviewed by Mark Lam and Yusuke Suzuki.
     8
     9        Consider the following:
     10        - We have a CodeBlock A.
     11        - DFG or FTL compiles an exit to A when A is still LLInt code. This means
     12          the OSR exit code will materialize registers as if A is LLInt.
     13        - We tier up A to Baseline JIT code.
     14        - Now, we take the exit to A as if it's LLInt. But the checkpoint OSR exit
     15          code will actually jump to the tiered up baseline code when it's done,
     16          because it determines where to jump at runtime. Because of this, when
     17          we return from the checkpoint code, and if we are jumping into baseline
     18          code, we must always load the constant pool register.
     19        - There's no need to load the metadata register because that register is
     20          shared with LLInt code, and will already contain the right value.
     21
     22        * jit/JIT.cpp:
     23        (JSC::JIT::privateCompileMainPass):
     24        * llint/LLIntSlowPaths.cpp:
     25        (JSC::LLInt::dispatchToNextInstructionDuringExit):
     26        (JSC::LLInt::llint_slow_path_checkpoint_osr_exit_from_inlined_call):
     27        (JSC::LLInt::llint_slow_path_checkpoint_osr_exit):
     28        (JSC::LLInt::dispatchToNextInstruction): Deleted.
     29        * llint/LowLevelInterpreter.asm:
     30        * llint/LowLevelInterpreter64.asm:
     31
    1322021-09-29  Basuke Suzuki  <basuke.suzuki@sony.com>
    233
  • trunk/Source/JavaScriptCore/jit/JIT.cpp

    r283229 r283288  
    270270            sizeMarker = m_vm->jitSizeStatistics->markStart(id, *this);
    271271        }
     272
     273#if ASSERT_ENABLED
     274        if (opcodeID != op_catch) {
     275            probeDebug([=] (Probe::Context& ctx) {
     276                CodeBlock* codeBlock = ctx.fp<CallFrame*>()->codeBlock();
     277                auto* constantPool = ctx.gpr<void*>(s_constantsGPR);
     278                RELEASE_ASSERT(codeBlock->baselineJITConstantPool() == constantPool);
     279                auto* metadata = ctx.gpr<void*>(s_metadataGPR);
     280                RELEASE_ASSERT(codeBlock->metadataTable() == metadata);
     281            });
     282        }
     283#endif
    272284
    273285        if (UNLIKELY(m_compilation)) {
  • trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp

    r283139 r283288  
    24102410}
    24112411
    2412 inline SlowPathReturnType dispatchToNextInstruction(ThrowScope& scope, CodeBlock* codeBlock, InstructionStream::Ref pc)
     2412inline SlowPathReturnType dispatchToNextInstructionDuringExit(ThrowScope& scope, CodeBlock* codeBlock, InstructionStream::Ref pc)
    24132413{
    24142414    if (scope.exception())
     
    24282428    BytecodeIndex nextBytecodeIndex = pc.next().index();
    24292429    auto nextBytecode = codeBlock->jitCodeMap().find(nextBytecodeIndex);
    2430     return encodeResult(nullptr, nextBytecode.executableAddress());
     2430    return encodeResult(bitwise_cast<void*>(static_cast<uintptr_t>(1)), nextBytecode.executableAddress());
    24312431#endif
    24322432    RELEASE_ASSERT_NOT_REACHED();
     
    24802480    }
    24812481
    2482     return dispatchToNextInstruction(scope, codeBlock, pc);
     2482    return dispatchToNextInstructionDuringExit(scope, codeBlock, pc);
    24832483}
    24842484
     
    25252525    }
    25262526
    2527     return dispatchToNextInstruction(scope, codeBlock, pc);
     2527    return dispatchToNextInstructionDuringExit(scope, codeBlock, pc);
    25282528}
    25292529
  • trunk/Source/JavaScriptCore/llint/LowLevelInterpreter.asm

    r283236 r283288  
    24832483
    24842484
     2485if JIT
     2486    macro loadBaselineJITConstantPool()
     2487        # Baseline uses LLInt's PB register for its JIT constant pool.
     2488        loadp CodeBlock[cfr], PB
     2489        loadp CodeBlock::m_jitData[PB], PB
     2490        loadp CodeBlock::JITData::m_jitConstantPool[PB], PB
     2491    end
     2492
     2493    macro setupReturnToBaselineAfterCheckpointExitIfNeeded()
     2494        # DFG or FTL OSR exit could have compiled an OSR exit to LLInt code.
     2495        # That means it set up registers as if execution would happen in the
     2496        # LLInt. However, during OSR exit for checkpoints, we might return to
     2497        # JIT code if it's already compiled. After the OSR exit gets compiled,
     2498        # we can tier up to JIT code. And checkpoint exit will jump to it.
     2499        # That means we always need to set up our constant pool GPR, because the OSR
     2500        # exit code might not have done it.
     2501        bpneq r0, 1, .notBaselineJIT
     2502        loadBaselineJITConstantPool()
     2503    .notBaselineJIT:
     2504
     2505    end
     2506else
     2507    macro setupReturnToBaselineAfterCheckpointExitIfNeeded()
     2508    end
     2509end
     2510
    24852511op(checkpoint_osr_exit_from_inlined_call_trampoline, macro ()
    24862512    if (JSVALUE64 and not (C_LOOP or C_LOOP_WIN)) or ARMv7 or MIPS
     
    25062532        end
    25072533
     2534        setupReturnToBaselineAfterCheckpointExitIfNeeded()
    25082535        restoreStateAfterCCall()
    25092536        branchIfException(_llint_throw_from_slow_path_trampoline)
     2537
    25102538        if ARM64E
    25112539            move r1, a0
     
    25292557        # We don't call saveStateForCCall() because we are going to use the bytecodeIndex from our side state.
    25302558        cCall2(_llint_slow_path_checkpoint_osr_exit)
     2559        setupReturnToBaselineAfterCheckpointExitIfNeeded()
    25312560        restoreStateAfterCCall()
    25322561        branchIfException(_llint_throw_from_slow_path_trampoline)
  • trunk/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm

    r283168 r283288  
    445445                move r1, sp
    446446
    447                 # Baseline uses LLInt's PB register for its JIT constant pool.
    448                 loadp CodeBlock[cfr], PB
    449                 loadp CodeBlock::m_jitData[PB], PB
    450                 loadp CodeBlock::JITData::m_jitConstantPool[PB], PB
     447                loadBaselineJITConstantPool()
    451448
    452449                if ARM64E
Note: See TracChangeset for help on using the changeset viewer.