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();