Changeset 277725 in webkit


Ignore:
Timestamp:
May 19, 2021, 9:34:52 AM (4 years ago)
Author:
sbarati@apple.com
Message:

Link Baseline JIT code off the main thread
https://bugs.webkit.org/show_bug.cgi?id=225940

Reviewed by Yusuke Suzuki.

This patch makes JIT::link() able to run on compiler threads.
Most of what the function was already doing happily remains the
same. This patch moves a few operations to JIT::finalizeOnMainThread
for things that can't happen on the compiler thread:

  • Adding data to some global hash tables which aren't synchronized.
  • Setting the JITCode.
  • Setting the code pointer for exception handlers.
  • Some other metadata the Sampling Profiler looks at.
  • jit/JIT.cpp:

(JSC::JIT::compileAndLinkWithoutFinalizing):
(JSC::JIT::link):
(JSC::JIT::finalizeOnMainThread):
(JSC::JIT::privateCompile):
(JSC::JIT::compileWithoutLinking): Deleted.

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

(JSC::JITWorklist::Plan::compileInThread):
(JSC::JITWorklist::Plan::finalize):
(JSC::JITWorklist::Plan::compileOnMainThreadNow):
(JSC::JITWorklist::compileLater):
(JSC::JITWorklist::compileOnMainThreadNow):
(JSC::JITWorklist::finalizePlans):
(JSC::JITWorklist::Plan::compileNow): Deleted.
(JSC::JITWorklist::compileNow): Deleted.

  • jit/JITWorklist.h:
Location:
trunk/Source/JavaScriptCore
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r277716 r277725  
     12021-05-19  Saam Barati  <sbarati@apple.com>
     2
     3        Link Baseline JIT code off the main thread
     4        https://bugs.webkit.org/show_bug.cgi?id=225940
     5
     6        Reviewed by Yusuke Suzuki.
     7
     8        This patch makes JIT::link() able to run on compiler threads.
     9        Most of what the function was already doing happily remains the
     10        same. This patch moves a few operations to JIT::finalizeOnMainThread
     11        for things that can't happen on the compiler thread:
     12        - Adding data to some global hash tables which aren't synchronized.
     13        - Setting the JITCode.
     14        - Setting the code pointer for exception handlers.
     15        - Some other metadata the Sampling Profiler looks at.
     16
     17        * jit/JIT.cpp:
     18        (JSC::JIT::compileAndLinkWithoutFinalizing):
     19        (JSC::JIT::link):
     20        (JSC::JIT::finalizeOnMainThread):
     21        (JSC::JIT::privateCompile):
     22        (JSC::JIT::compileWithoutLinking): Deleted.
     23        * jit/JIT.h:
     24        * jit/JITWorklist.cpp:
     25        (JSC::JITWorklist::Plan::compileInThread):
     26        (JSC::JITWorklist::Plan::finalize):
     27        (JSC::JITWorklist::Plan::compileOnMainThreadNow):
     28        (JSC::JITWorklist::compileLater):
     29        (JSC::JITWorklist::compileOnMainThreadNow):
     30        (JSC::JITWorklist::finalizePlans):
     31        (JSC::JITWorklist::Plan::compileNow): Deleted.
     32        (JSC::JITWorklist::compileNow): Deleted.
     33        * jit/JITWorklist.h:
     34
    1352021-05-18  Ross Kirsling  <ross.kirsling@sony.com>
    236
  • trunk/Source/JavaScriptCore/jit/JIT.cpp

    r277680 r277725  
    673673}
    674674
    675 void JIT::compileWithoutLinking(JITCompilationEffort effort)
     675void JIT::compileAndLinkWithoutFinalizing(JITCompilationEffort effort)
    676676{
    677677    MonotonicTime before { };
     
    847847        dataLog("Optimized ", codeBlockName, " with Baseline JIT into ", m_linkBuffer->size(), " bytes in ", (after - before).milliseconds(), " ms.\n");
    848848    }
    849 }
    850 
    851 CompilationResult JIT::link()
     849
     850    link();
     851}
     852
     853void JIT::link()
    852854{
    853855    LinkBuffer& patchBuffer = *m_linkBuffer;
    854856   
    855857    if (patchBuffer.didFailToAllocate())
    856         return CompilationFailed;
     858        return;
    857859
    858860    // Translate vPC offsets into addresses in JIT generated code, for switch tables.
     
    892894    }
    893895
    894     for (size_t i = 0; i < m_codeBlock->numberOfExceptionHandlers(); ++i) {
    895         HandlerInfo& handler = m_codeBlock->exceptionHandler(i);
    896         // FIXME: <rdar://problem/39433318>.
    897         handler.nativeCode = patchBuffer.locationOf<ExceptionHandlerPtrTag>(m_labels[handler.target]);
    898     }
    899 
    900896#if ENABLE(EXTRA_CTI_THUNKS)
    901897    if (!m_exceptionChecks.empty())
     
    978974    }
    979975
    980     MacroAssemblerCodePtr<JSEntryPtrTag> withArityCheck = patchBuffer.locationOf<JSEntryPtrTag>(m_arityCheck);
    981 
    982976    if (UNLIKELY(Options::dumpDisassembly())) {
    983977        m_disassembler->dump(patchBuffer);
    984978        patchBuffer.didAlreadyDisassemble();
    985979    }
     980
    986981    if (UNLIKELY(m_compilation)) {
    987982        if (Options::disassembleBaselineForProfiler())
     
    991986
    992987    if (m_pcToCodeOriginMapBuilder.didBuildMapping())
    993         m_codeBlock->setPCToCodeOriginMap(makeUnique<PCToCodeOriginMap>(WTFMove(m_pcToCodeOriginMapBuilder), patchBuffer));
     988        m_pcToCodeOriginMap = makeUnique<PCToCodeOriginMap>(WTFMove(m_pcToCodeOriginMapBuilder), patchBuffer);
    994989   
    995990    CodeRef<JSEntryPtrTag> result = FINALIZE_CODE(
     
    997992        "Baseline JIT code for %s", toCString(CodeBlockWithJITType(m_codeBlock, JITType::BaselineJIT)).data());
    998993   
    999     m_vm->machineCodeBytesPerBytecodeWordForBaselineJIT->add(
    1000         static_cast<double>(result.size()) /
    1001         static_cast<double>(m_codeBlock->instructionsSize()));
    1002 
    1003994    {
    1004995        ConcurrentJSLocker locker(m_codeBlock->m_lock);
    1005996        m_codeBlock->shrinkToFit(locker, CodeBlock::ShrinkMode::LateShrink);
    1006997    }
    1007     m_codeBlock->setJITCode(
    1008         adoptRef(*new DirectJITCode(result, withArityCheck, JITType::BaselineJIT)));
     998
     999    MacroAssemblerCodePtr<JSEntryPtrTag> withArityCheck = patchBuffer.locationOf<JSEntryPtrTag>(m_arityCheck);
     1000    m_jitCode = adoptRef(*new DirectJITCode(result, withArityCheck, JITType::BaselineJIT));
    10091001
    10101002    if (JITInternal::verbose)
    10111003        dataLogF("JIT generated code for %p at [%p, %p).\n", m_codeBlock, result.executableMemory()->start().untaggedPtr(), result.executableMemory()->end().untaggedPtr());
     1004}
     1005
     1006CompilationResult JIT::finalizeOnMainThread()
     1007{
     1008    RELEASE_ASSERT(!isCompilationThread());
     1009
     1010    if (!m_jitCode)
     1011        return CompilationFailed;
     1012
     1013    for (size_t i = 0; i < m_codeBlock->numberOfExceptionHandlers(); ++i) {
     1014        HandlerInfo& handler = m_codeBlock->exceptionHandler(i);
     1015        // FIXME: <rdar://problem/39433318>.
     1016        handler.nativeCode = m_codeBlock->jitCodeMap().find(BytecodeIndex(handler.target)).retagged<ExceptionHandlerPtrTag>();
     1017    }
     1018
     1019    if (m_pcToCodeOriginMap)
     1020        m_codeBlock->setPCToCodeOriginMap(WTFMove(m_pcToCodeOriginMap));
     1021
     1022    m_vm->machineCodeBytesPerBytecodeWordForBaselineJIT->add(
     1023        static_cast<double>(m_jitCode->size()) /
     1024        static_cast<double>(m_codeBlock->instructionsSize()));
     1025
     1026    m_codeBlock->setJITCode(m_jitCode.releaseNonNull());
    10121027
    10131028    return CompilationSuccessful;
     
    10171032{
    10181033    doMainThreadPreparationBeforeCompile();
    1019     compileWithoutLinking(effort);
    1020     return link();
     1034    compileAndLinkWithoutFinalizing(effort);
     1035    return finalizeOnMainThread();
    10211036}
    10221037
  • trunk/Source/JavaScriptCore/jit/JIT.h

    r277680 r277725  
    215215        VM& vm() { return *JSInterfaceJIT::vm(); }
    216216
    217         void compileWithoutLinking(JITCompilationEffort);
    218         CompilationResult link();
     217        void compileAndLinkWithoutFinalizing(JITCompilationEffort);
     218        CompilationResult finalizeOnMainThread();
    219219
    220220        void doMainThreadPreparationBeforeCompile();
     
    271271        void privateCompileLinkPass();
    272272        void privateCompileSlowCases();
     273        void link();
    273274        CompilationResult privateCompile(JITCompilationEffort);
    274275       
     
    10451046
    10461047        PCToCodeOriginMapBuilder m_pcToCodeOriginMapBuilder;
     1048        std::unique_ptr<PCToCodeOriginMap> m_pcToCodeOriginMap;
    10471049
    10481050        HashMap<const Instruction*, void*> m_instructionToMathIC;
     
    10531055        bool m_shouldEmitProfiling;
    10541056        BytecodeIndex m_loopOSREntryBytecodeIndex;
     1057
     1058        RefPtr<DirectJITCode> m_jitCode;
    10551059    };
    10561060
  • trunk/Source/JavaScriptCore/jit/JITWorklist.cpp

    r273138 r277725  
    4545    void compileInThread()
    4646    {
    47         m_jit.compileWithoutLinking(JITCompilationCanFail);
     47        m_jit.compileAndLinkWithoutFinalizing(JITCompilationCanFail);
    4848       
    4949        LockHolder locker(m_lock);
     
    5151    }
    5252   
    53     void finalize()
    54     {
    55         CompilationResult result = m_jit.link();
     53    void finalize(bool needsFence)
     54    {
     55        CompilationResult result = m_jit.finalizeOnMainThread();
    5656        switch (result) {
    5757        case CompilationFailed:
     
    6262            return;
    6363        case CompilationSuccessful:
     64            if (needsFence)
     65                WTF::crossModifyingCodeFence();
    6466            dataLogLnIf(Options::verboseOSR(), "    JIT compilation successful.");
    6567            m_codeBlock->ownerExecutable()->installCode(m_codeBlock);
     
    8183    }
    8284   
    83     static void compileNow(CodeBlock* codeBlock, BytecodeIndex loopOSREntryBytecodeIndex)
     85    static void compileOnMainThreadNow(CodeBlock* codeBlock, BytecodeIndex loopOSREntryBytecodeIndex)
    8486    {
    8587        Plan plan(codeBlock, loopOSREntryBytecodeIndex);
    8688        plan.compileInThread();
    87         plan.finalize();
     89        plan.finalize(false);
    8890    }
    8991   
     
    236238   
    237239    if (!Options::useConcurrentJIT()) {
    238         Plan::compileNow(codeBlock, loopOSREntryBytecodeIndex);
     240        Plan::compileOnMainThreadNow(codeBlock, loopOSREntryBytecodeIndex);
    239241        return;
    240242    }
     
    274276    // thread compiles. This is probably not as good as if we had multiple JIT threads. Maybe we
    275277    // can do that someday.
    276     Plan::compileNow(codeBlock, loopOSREntryBytecodeIndex);
    277 }
    278 
    279 void JITWorklist::compileNow(CodeBlock* codeBlock, BytecodeIndex loopOSREntryBytecodeIndex)
    280 {
    281     VM& vm = codeBlock->vm();
    282     DeferGC deferGC(vm.heap);
    283     if (codeBlock->jitType() != JITType::InterpreterThunk)
    284         return;
    285    
    286     bool isPlanned;
    287     {
    288         LockHolder locker(*m_lock);
    289         isPlanned = m_planned.contains(codeBlock);
    290     }
    291    
    292     if (isPlanned) {
    293         RELEASE_ASSERT(Options::useConcurrentJIT());
    294         // This is expensive, but probably good enough.
    295         completeAllForVM(vm);
    296     }
    297    
    298     // Now it might be compiled!
    299     if (codeBlock->jitType() != JITType::InterpreterThunk)
    300         return;
    301    
    302     // We do this in case we had previously attempted, and then failed, to compile with the
    303     // baseline JIT.
    304     codeBlock->resetJITData();
    305    
    306     // OK, just compile it.
    307     JIT::compile(vm, codeBlock, JITCompilationMustSucceed, loopOSREntryBytecodeIndex);
    308     codeBlock->ownerExecutable()->installCode(codeBlock);
     278    Plan::compileOnMainThreadNow(codeBlock, loopOSREntryBytecodeIndex);
    309279}
    310280
     
    312282{
    313283    for (RefPtr<Plan>& plan : myPlans) {
    314         plan->finalize();
     284        plan->finalize(true);
    315285       
    316286        LockHolder locker(*m_lock);
  • trunk/Source/JavaScriptCore/jit/JITWorklist.h

    r251690 r277725  
    5656   
    5757    void compileLater(CodeBlock*, BytecodeIndex loopOSREntryBytecodeIndex = BytecodeIndex(0));
    58     void compileNow(CodeBlock*, BytecodeIndex loopOSREntryBytecodeIndex = BytecodeIndex(0));
    5958   
    6059    static JITWorklist& ensureGlobalWorklist();
Note: See TracChangeset for help on using the changeset viewer.