Title: [277725] trunk/Source/_javascript_Core
Revision
277725
Author
sbar...@apple.com
Date
2021-05-19 09:34:52 -0700 (Wed, 19 May 2021)

Log 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:

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (277724 => 277725)


--- trunk/Source/_javascript_Core/ChangeLog	2021-05-19 16:23:57 UTC (rev 277724)
+++ trunk/Source/_javascript_Core/ChangeLog	2021-05-19 16:34:52 UTC (rev 277725)
@@ -1,3 +1,37 @@
+2021-05-19  Saam Barati  <sbar...@apple.com>
+
+        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:
+
 2021-05-18  Ross Kirsling  <ross.kirsl...@sony.com>
 
         [JSC] Prune CommonSlowPaths of JITPropertyAccess functions

Modified: trunk/Source/_javascript_Core/jit/JIT.cpp (277724 => 277725)


--- trunk/Source/_javascript_Core/jit/JIT.cpp	2021-05-19 16:23:57 UTC (rev 277724)
+++ trunk/Source/_javascript_Core/jit/JIT.cpp	2021-05-19 16:34:52 UTC (rev 277725)
@@ -672,7 +672,7 @@
 #endif
 }
 
-void JIT::compileWithoutLinking(JITCompilationEffort effort)
+void JIT::compileAndLinkWithoutFinalizing(JITCompilationEffort effort)
 {
     MonotonicTime before { };
     if (UNLIKELY(computeCompileTimes()))
@@ -846,14 +846,16 @@
         
         dataLog("Optimized ", codeBlockName, " with Baseline JIT into ", m_linkBuffer->size(), " bytes in ", (after - before).milliseconds(), " ms.\n");
     }
+
+    link();
 }
 
-CompilationResult JIT::link()
+void JIT::link()
 {
     LinkBuffer& patchBuffer = *m_linkBuffer;
     
     if (patchBuffer.didFailToAllocate())
-        return CompilationFailed;
+        return;
 
     // Translate vPC offsets into addresses in JIT generated code, for switch tables.
     for (auto& record : m_switches) {
@@ -891,12 +893,6 @@
         }
     }
 
-    for (size_t i = 0; i < m_codeBlock->numberOfExceptionHandlers(); ++i) {
-        HandlerInfo& handler = m_codeBlock->exceptionHandler(i);
-        // FIXME: <rdar://problem/39433318>.
-        handler.nativeCode = patchBuffer.locationOf<ExceptionHandlerPtrTag>(m_labels[handler.target]);
-    }
-
 #if ENABLE(EXTRA_CTI_THUNKS)
     if (!m_exceptionChecks.empty())
         patchBuffer.link(m_exceptionChecks, CodeLocationLabel(vm().getCTIStub(handleExceptionGenerator).retaggedCode<NoPtrTag>()));
@@ -977,12 +973,11 @@
         m_codeBlock->setJITCodeMap(jitCodeMapBuilder.finalize());
     }
 
-    MacroAssemblerCodePtr<JSEntryPtrTag> withArityCheck = patchBuffer.locationOf<JSEntryPtrTag>(m_arityCheck);
-
     if (UNLIKELY(Options::dumpDisassembly())) {
         m_disassembler->dump(patchBuffer);
         patchBuffer.didAlreadyDisassemble();
     }
+
     if (UNLIKELY(m_compilation)) {
         if (Options::disassembleBaselineForProfiler())
             m_disassembler->reportToProfiler(m_compilation.get(), patchBuffer);
@@ -990,26 +985,46 @@
     }
 
     if (m_pcToCodeOriginMapBuilder.didBuildMapping())
-        m_codeBlock->setPCToCodeOriginMap(makeUnique<PCToCodeOriginMap>(WTFMove(m_pcToCodeOriginMapBuilder), patchBuffer));
+        m_pcToCodeOriginMap = makeUnique<PCToCodeOriginMap>(WTFMove(m_pcToCodeOriginMapBuilder), patchBuffer);
     
     CodeRef<JSEntryPtrTag> result = FINALIZE_CODE(
         patchBuffer, JSEntryPtrTag,
         "Baseline JIT code for %s", toCString(CodeBlockWithJITType(m_codeBlock, JITType::BaselineJIT)).data());
     
-    m_vm->machineCodeBytesPerBytecodeWordForBaselineJIT->add(
-        static_cast<double>(result.size()) /
-        static_cast<double>(m_codeBlock->instructionsSize()));
-
     {
         ConcurrentJSLocker locker(m_codeBlock->m_lock);
         m_codeBlock->shrinkToFit(locker, CodeBlock::ShrinkMode::LateShrink);
     }
-    m_codeBlock->setJITCode(
-        adoptRef(*new DirectJITCode(result, withArityCheck, JITType::BaselineJIT)));
 
+    MacroAssemblerCodePtr<JSEntryPtrTag> withArityCheck = patchBuffer.locationOf<JSEntryPtrTag>(m_arityCheck);
+    m_jitCode = adoptRef(*new DirectJITCode(result, withArityCheck, JITType::BaselineJIT));
+
     if (JITInternal::verbose)
         dataLogF("JIT generated code for %p at [%p, %p).\n", m_codeBlock, result.executableMemory()->start().untaggedPtr(), result.executableMemory()->end().untaggedPtr());
+}
 
+CompilationResult JIT::finalizeOnMainThread()
+{
+    RELEASE_ASSERT(!isCompilationThread());
+
+    if (!m_jitCode)
+        return CompilationFailed;
+
+    for (size_t i = 0; i < m_codeBlock->numberOfExceptionHandlers(); ++i) {
+        HandlerInfo& handler = m_codeBlock->exceptionHandler(i);
+        // FIXME: <rdar://problem/39433318>.
+        handler.nativeCode = m_codeBlock->jitCodeMap().find(BytecodeIndex(handler.target)).retagged<ExceptionHandlerPtrTag>();
+    }
+
+    if (m_pcToCodeOriginMap)
+        m_codeBlock->setPCToCodeOriginMap(WTFMove(m_pcToCodeOriginMap));
+
+    m_vm->machineCodeBytesPerBytecodeWordForBaselineJIT->add(
+        static_cast<double>(m_jitCode->size()) /
+        static_cast<double>(m_codeBlock->instructionsSize()));
+
+    m_codeBlock->setJITCode(m_jitCode.releaseNonNull());
+
     return CompilationSuccessful;
 }
 
@@ -1016,8 +1031,8 @@
 CompilationResult JIT::privateCompile(JITCompilationEffort effort)
 {
     doMainThreadPreparationBeforeCompile();
-    compileWithoutLinking(effort);
-    return link();
+    compileAndLinkWithoutFinalizing(effort);
+    return finalizeOnMainThread();
 }
 
 void JIT::privateCompileExceptionHandlers()

Modified: trunk/Source/_javascript_Core/jit/JIT.h (277724 => 277725)


--- trunk/Source/_javascript_Core/jit/JIT.h	2021-05-19 16:23:57 UTC (rev 277724)
+++ trunk/Source/_javascript_Core/jit/JIT.h	2021-05-19 16:34:52 UTC (rev 277725)
@@ -214,8 +214,8 @@
 
         VM& vm() { return *JSInterfaceJIT::vm(); }
 
-        void compileWithoutLinking(JITCompilationEffort);
-        CompilationResult link();
+        void compileAndLinkWithoutFinalizing(JITCompilationEffort);
+        CompilationResult finalizeOnMainThread();
 
         void doMainThreadPreparationBeforeCompile();
         
@@ -270,6 +270,7 @@
         void privateCompileMainPass();
         void privateCompileLinkPass();
         void privateCompileSlowCases();
+        void link();
         CompilationResult privateCompile(JITCompilationEffort);
         
         void privateCompileGetByVal(const ConcurrentJSLocker&, ByValInfo*, ReturnAddressPtr, JITArrayMode);
@@ -1044,6 +1045,7 @@
         RefPtr<Profiler::Compilation> m_compilation;
 
         PCToCodeOriginMapBuilder m_pcToCodeOriginMapBuilder;
+        std::unique_ptr<PCToCodeOriginMap> m_pcToCodeOriginMap;
 
         HashMap<const Instruction*, void*> m_instructionToMathIC;
         HashMap<const Instruction*, UniqueRef<MathICGenerationState>> m_instructionToMathICGenerationState;
@@ -1052,6 +1054,8 @@
         bool m_canBeOptimizedOrInlined;
         bool m_shouldEmitProfiling;
         BytecodeIndex m_loopOSREntryBytecodeIndex;
+
+        RefPtr<DirectJITCode> m_jitCode;
     };
 
 } // namespace JSC

Modified: trunk/Source/_javascript_Core/jit/JITWorklist.cpp (277724 => 277725)


--- trunk/Source/_javascript_Core/jit/JITWorklist.cpp	2021-05-19 16:23:57 UTC (rev 277724)
+++ trunk/Source/_javascript_Core/jit/JITWorklist.cpp	2021-05-19 16:34:52 UTC (rev 277725)
@@ -44,15 +44,15 @@
     
     void compileInThread()
     {
-        m_jit.compileWithoutLinking(JITCompilationCanFail);
+        m_jit.compileAndLinkWithoutFinalizing(JITCompilationCanFail);
         
         LockHolder locker(m_lock);
         m_isFinishedCompiling = true;
     }
     
-    void finalize()
+    void finalize(bool needsFence)
     {
-        CompilationResult result = m_jit.link();
+        CompilationResult result = m_jit.finalizeOnMainThread();
         switch (result) {
         case CompilationFailed:
             CODEBLOCK_LOG_EVENT(m_codeBlock, "delayJITCompile", ("compilation failed"));
@@ -61,6 +61,8 @@
             m_codeBlock->m_didFailJITCompilation = true;
             return;
         case CompilationSuccessful:
+            if (needsFence)
+                WTF::crossModifyingCodeFence();
             dataLogLnIf(Options::verboseOSR(), "    JIT compilation successful.");
             m_codeBlock->ownerExecutable()->installCode(m_codeBlock);
             m_codeBlock->jitSoon();
@@ -80,11 +82,11 @@
         return m_isFinishedCompiling;
     }
     
-    static void compileNow(CodeBlock* codeBlock, BytecodeIndex loopOSREntryBytecodeIndex)
+    static void compileOnMainThreadNow(CodeBlock* codeBlock, BytecodeIndex loopOSREntryBytecodeIndex)
     {
         Plan plan(codeBlock, loopOSREntryBytecodeIndex);
         plan.compileInThread();
-        plan.finalize();
+        plan.finalize(false);
     }
     
 private:
@@ -235,7 +237,7 @@
     }
     
     if (!Options::useConcurrentJIT()) {
-        Plan::compileNow(codeBlock, loopOSREntryBytecodeIndex);
+        Plan::compileOnMainThreadNow(codeBlock, loopOSREntryBytecodeIndex);
         return;
     }
     
@@ -273,45 +275,13 @@
     // This works around the issue. If the concurrent JIT thread is convoyed, we revert to main
     // thread compiles. This is probably not as good as if we had multiple JIT threads. Maybe we
     // can do that someday.
-    Plan::compileNow(codeBlock, loopOSREntryBytecodeIndex);
+    Plan::compileOnMainThreadNow(codeBlock, loopOSREntryBytecodeIndex);
 }
 
-void JITWorklist::compileNow(CodeBlock* codeBlock, BytecodeIndex loopOSREntryBytecodeIndex)
-{
-    VM& vm = codeBlock->vm();
-    DeferGC deferGC(vm.heap);
-    if (codeBlock->jitType() != JITType::InterpreterThunk)
-        return;
-    
-    bool isPlanned;
-    {
-        LockHolder locker(*m_lock);
-        isPlanned = m_planned.contains(codeBlock);
-    }
-    
-    if (isPlanned) {
-        RELEASE_ASSERT(Options::useConcurrentJIT());
-        // This is expensive, but probably good enough.
-        completeAllForVM(vm);
-    }
-    
-    // Now it might be compiled!
-    if (codeBlock->jitType() != JITType::InterpreterThunk)
-        return;
-    
-    // We do this in case we had previously attempted, and then failed, to compile with the
-    // baseline JIT.
-    codeBlock->resetJITData();
-    
-    // OK, just compile it.
-    JIT::compile(vm, codeBlock, JITCompilationMustSucceed, loopOSREntryBytecodeIndex);
-    codeBlock->ownerExecutable()->installCode(codeBlock);
-}
-
 void JITWorklist::finalizePlans(Plans& myPlans)
 {
     for (RefPtr<Plan>& plan : myPlans) {
-        plan->finalize();
+        plan->finalize(true);
         
         LockHolder locker(*m_lock);
         m_planned.remove(plan->codeBlock());

Modified: trunk/Source/_javascript_Core/jit/JITWorklist.h (277724 => 277725)


--- trunk/Source/_javascript_Core/jit/JITWorklist.h	2021-05-19 16:23:57 UTC (rev 277724)
+++ trunk/Source/_javascript_Core/jit/JITWorklist.h	2021-05-19 16:34:52 UTC (rev 277725)
@@ -55,7 +55,6 @@
     void poll(VM&);
     
     void compileLater(CodeBlock*, BytecodeIndex loopOSREntryBytecodeIndex = BytecodeIndex(0));
-    void compileNow(CodeBlock*, BytecodeIndex loopOSREntryBytecodeIndex = BytecodeIndex(0));
     
     static JITWorklist& ensureGlobalWorklist();
     static JITWorklist* existingGlobalWorklistOrNull();
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to