mirror of
https://github.com/roytam1/basilisk55.git
synced 2026-05-26 15:02:46 +00:00
ported from UXP: Issue #3075 - Backport bug 1377238 - Free finished IonBuilders off-thread. (57f841bf)
This commit is contained in:
@@ -68,6 +68,7 @@ enum ThreadType {
|
||||
THREAD_TYPE_GCHELPER, // 6
|
||||
THREAD_TYPE_GCPARALLEL, // 7
|
||||
THREAD_TYPE_PROMISE_TASK, // 8
|
||||
THREAD_TYPE_ION_FREE, // 9
|
||||
THREAD_TYPE_MAX // Used to check shell function arguments
|
||||
};
|
||||
|
||||
|
||||
+14
-6
@@ -474,6 +474,17 @@ JitCompartment::ensureIonStubsExist(JSContext* cx)
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
jit::FreeIonBuilder(IonBuilder* builder)
|
||||
{
|
||||
// The builder is allocated into its LifoAlloc, so destroying that will
|
||||
// destroy the builder and all other data accumulated during compilation,
|
||||
// except any final codegen (which includes an assembler and needs to be
|
||||
// explicitly destroyed).
|
||||
js_delete(builder->backgroundCodegen());
|
||||
js_delete(builder->alloc().lifoAlloc());
|
||||
}
|
||||
|
||||
void
|
||||
jit::FinishOffThreadBuilder(JSRuntime* runtime, IonBuilder* builder,
|
||||
const AutoLockHelperThreadState& locked)
|
||||
@@ -505,12 +516,9 @@ jit::FinishOffThreadBuilder(JSRuntime* runtime, IonBuilder* builder,
|
||||
builder->script()->setIonScript(runtime, ion);
|
||||
}
|
||||
|
||||
// The builder is allocated into its LifoAlloc, so destroying that will
|
||||
// destroy the builder and all other data accumulated during compilation,
|
||||
// except any final codegen (which includes an assembler and needs to be
|
||||
// explicitly destroyed).
|
||||
js_delete(builder->backgroundCodegen());
|
||||
js_delete(builder->alloc().lifoAlloc());
|
||||
// Free Ion LifoAlloc off-thread. Free on the main thread if this OOMs.
|
||||
if (!StartOffThreadIonFree(builder, locked))
|
||||
FreeIonBuilder(builder);
|
||||
}
|
||||
|
||||
static bool
|
||||
|
||||
@@ -171,6 +171,7 @@ CodeGenerator* CompileBackEnd(MIRGenerator* mir);
|
||||
void AttachFinishedCompilations(JSContext* cx);
|
||||
void FinishOffThreadBuilder(JSRuntime* runtime, IonBuilder* builder,
|
||||
const AutoLockHelperThreadState& lock);
|
||||
void FreeIonBuilder(IonBuilder* builder);
|
||||
|
||||
void LinkIonScript(JSContext* cx, HandleScript calleescript);
|
||||
uint8_t* LazyLinkTopActivation(JSContext* cx);
|
||||
|
||||
@@ -110,6 +110,18 @@ js::StartOffThreadIonCompile(JSContext* cx, jit::IonBuilder* builder)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
js::StartOffThreadIonFree(jit::IonBuilder* builder, const AutoLockHelperThreadState& lock)
|
||||
{
|
||||
MOZ_ASSERT(CanUseExtraThreads());
|
||||
|
||||
if (!HelperThreadState().ionFreeList(lock).append(builder))
|
||||
return false;
|
||||
|
||||
HelperThreadState().notifyOne(GlobalHelperThreadState::PRODUCER, lock);
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Move an IonBuilder for which compilation has either finished, failed, or
|
||||
* been cancelled into the global finished compilation list. All off thread
|
||||
@@ -784,6 +796,14 @@ void
|
||||
GlobalHelperThreadState::finish()
|
||||
{
|
||||
finishThreads();
|
||||
|
||||
// Make sure there are no Ion free tasks left. We check this here because,
|
||||
// unlike the other tasks, we don't explicitly block on this when
|
||||
// destroying a runtime.
|
||||
AutoLockHelperThreadState lock;
|
||||
auto& freeList = ionFreeList(lock);
|
||||
while (!freeList.empty())
|
||||
jit::FreeIonBuilder(freeList.popCopy());
|
||||
}
|
||||
|
||||
void
|
||||
@@ -994,6 +1014,12 @@ GlobalHelperThreadState::canStartIonCompile(const AutoLockHelperThreadState& loc
|
||||
checkTaskThreadLimit<jit::IonBuilder*>(maxIonCompilationThreads());
|
||||
}
|
||||
|
||||
bool
|
||||
GlobalHelperThreadState::canStartIonFreeTask(const AutoLockHelperThreadState& lock)
|
||||
{
|
||||
return !ionFreeList(lock).empty();
|
||||
}
|
||||
|
||||
jit::IonBuilder*
|
||||
GlobalHelperThreadState::highestPriorityPendingIonCompile(const AutoLockHelperThreadState& lock,
|
||||
bool remove /* = false */)
|
||||
@@ -1610,6 +1636,21 @@ CurrentHelperThread()
|
||||
return thread;
|
||||
}
|
||||
|
||||
void
|
||||
HelperThread::handleIonFreeWorkload(AutoLockHelperThreadState& locked)
|
||||
{
|
||||
MOZ_ASSERT(idle());
|
||||
MOZ_ASSERT(HelperThreadState().canStartIonFreeTask(locked));
|
||||
|
||||
auto& freeList = HelperThreadState().ionFreeList(locked);
|
||||
|
||||
jit::IonBuilder* builder = freeList.popCopy();
|
||||
{
|
||||
AutoUnlockHelperThreadState unlock(locked);
|
||||
FreeIonBuilder(builder);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
js::PauseCurrentHelperThread()
|
||||
{
|
||||
@@ -1925,6 +1966,8 @@ HelperThread::threadLoop()
|
||||
task = js::oom::THREAD_TYPE_PARSE;
|
||||
else if (HelperThreadState().canStartCompressionTask(lock))
|
||||
task = js::oom::THREAD_TYPE_COMPRESS;
|
||||
else if (HelperThreadState().canStartIonFreeTask(lock))
|
||||
task = js::oom::THREAD_TYPE_ION_FREE;
|
||||
else
|
||||
task = js::oom::THREAD_TYPE_NONE;
|
||||
|
||||
@@ -1957,6 +2000,9 @@ HelperThread::threadLoop()
|
||||
case js::oom::THREAD_TYPE_COMPRESS:
|
||||
handleCompressionWorkload(lock);
|
||||
break;
|
||||
case js::oom::THREAD_TYPE_ION_FREE:
|
||||
handleIonFreeWorkload(lock);
|
||||
break;
|
||||
default:
|
||||
MOZ_CRASH("No task to perform");
|
||||
}
|
||||
|
||||
@@ -84,7 +84,7 @@ class GlobalHelperThreadState
|
||||
// The lists below are all protected by |lock|.
|
||||
|
||||
// Ion compilation worklist and finished jobs.
|
||||
IonBuilderVector ionWorklist_, ionFinishedList_;
|
||||
IonBuilderVector ionWorklist_, ionFinishedList_, ionFreeList_;
|
||||
|
||||
// wasm worklist and finished jobs.
|
||||
wasm::CompileTaskPtrVector wasmWorklist_, wasmFinishedList_;
|
||||
@@ -165,6 +165,9 @@ class GlobalHelperThreadState
|
||||
IonBuilderVector& ionFinishedList(const AutoLockHelperThreadState&) {
|
||||
return ionFinishedList_;
|
||||
}
|
||||
IonBuilderVector& ionFreeList(const AutoLockHelperThreadState&) {
|
||||
return ionFreeList_;
|
||||
}
|
||||
|
||||
wasm::CompileTaskPtrVector& wasmWorklist(const AutoLockHelperThreadState&) {
|
||||
return wasmWorklist_;
|
||||
@@ -202,6 +205,7 @@ class GlobalHelperThreadState
|
||||
bool canStartWasmCompile(const AutoLockHelperThreadState& lock);
|
||||
bool canStartPromiseTask(const AutoLockHelperThreadState& lock);
|
||||
bool canStartIonCompile(const AutoLockHelperThreadState& lock);
|
||||
bool canStartIonFreeTask(const AutoLockHelperThreadState& lock);
|
||||
bool canStartParseTask(const AutoLockHelperThreadState& lock);
|
||||
bool canStartCompressionTask(const AutoLockHelperThreadState& lock);
|
||||
bool canStartGCHelperTask(const AutoLockHelperThreadState& lock);
|
||||
@@ -382,6 +386,7 @@ struct HelperThread
|
||||
void handleWasmWorkload(AutoLockHelperThreadState& locked);
|
||||
void handlePromiseTaskWorkload(AutoLockHelperThreadState& locked);
|
||||
void handleIonWorkload(AutoLockHelperThreadState& locked);
|
||||
void handleIonFreeWorkload(AutoLockHelperThreadState& locked);
|
||||
void handleParseWorkload(AutoLockHelperThreadState& locked, uintptr_t stackLimit);
|
||||
void handleCompressionWorkload(AutoLockHelperThreadState& locked);
|
||||
void handleGCHelperWorkload(AutoLockHelperThreadState& locked);
|
||||
@@ -439,6 +444,12 @@ StartPromiseTask(JSContext* cx, UniquePtr<PromiseTask> task);
|
||||
bool
|
||||
StartOffThreadIonCompile(JSContext* cx, jit::IonBuilder* builder);
|
||||
|
||||
/*
|
||||
* Schedule deletion of Ion compilation data.
|
||||
*/
|
||||
bool
|
||||
StartOffThreadIonFree(jit::IonBuilder* builder, const AutoLockHelperThreadState& lock);
|
||||
|
||||
struct AllCompilations {};
|
||||
struct ZonesInState { JSRuntime* runtime; JS::Zone::GCState state; };
|
||||
|
||||
|
||||
Reference in New Issue
Block a user