1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 * vim: set ts=8 sts=2 et sw=2 tw=80:
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
8 * API for managing off-thread work.
11 #ifndef vm_HelperThreads_h
12 #define vm_HelperThreads_h
14 #include "mozilla/Variant.h"
16 #include "js/OffThreadScriptCompilation.h"
17 #include "js/shadow/Zone.h"
18 #include "js/Transcoding.h"
19 #include "js/UniquePtr.h"
20 #include "threading/LockGuard.h"
21 #include "threading/Mutex.h"
22 #include "wasm/WasmConstants.h"
29 class OffThreadToken
{};
30 class JS_PUBLIC_API ReadOnlyCompileOptions
;
31 class JS_PUBLIC_API ReadOnlyDecodeOptions
;
34 template <typename UnitT
>
40 class AutoLockHelperThreadState
;
41 struct PromiseHelperTask
;
42 class SourceCompressionTask
;
45 struct CompilationStencil
;
59 struct CompileTaskState
;
60 struct Tier2GeneratorTask
;
61 using UniqueTier2GeneratorTask
= UniquePtr
<Tier2GeneratorTask
>;
65 * Lock protecting all mutable shared state accessed by helper threads, and used
66 * by all condition variables.
68 extern Mutex gHelperThreadLock MOZ_UNANNOTATED
;
70 class MOZ_RAII AutoLockHelperThreadState
: public LockGuard
<Mutex
> {
71 using Base
= LockGuard
<Mutex
>;
74 explicit AutoLockHelperThreadState() : Base(gHelperThreadLock
) {}
77 class MOZ_RAII AutoUnlockHelperThreadState
: public UnlockGuard
<Mutex
> {
78 using Base
= UnlockGuard
<Mutex
>;
81 explicit AutoUnlockHelperThreadState(AutoLockHelperThreadState
& locked
)
85 // Create data structures used by helper threads.
86 bool CreateHelperThreadsState();
88 // Destroy data structures used by helper threads.
89 void DestroyHelperThreadsState();
91 // Initialize helper threads unless already initialized.
92 bool EnsureHelperThreadsInitialized();
94 size_t GetHelperThreadCount();
95 size_t GetHelperThreadCPUCount();
96 size_t GetMaxWasmCompilationThreads();
98 // This allows the JS shell to override GetCPUCount() when passed the
99 // --thread-count=N option.
100 bool SetFakeCPUCount(size_t count
);
102 // Enqueues a wasm compilation task.
103 bool StartOffThreadWasmCompile(wasm::CompileTask
* task
, wasm::CompileMode mode
);
105 // Remove any pending wasm compilation tasks queued with
106 // StartOffThreadWasmCompile that match the arguments. Return the number
108 size_t RemovePendingWasmCompileTasks(const wasm::CompileTaskState
& taskState
,
109 wasm::CompileMode mode
,
110 const AutoLockHelperThreadState
& lock
);
112 // Enqueues a wasm compilation task.
113 void StartOffThreadWasmTier2Generator(wasm::UniqueTier2GeneratorTask task
);
115 // Cancel all background Wasm Tier-2 compilations.
116 void CancelOffThreadWasmTier2Generator();
119 * If helper threads are available, call execute() then dispatchResolve() on the
120 * given task in a helper thread. If no helper threads are available, the given
121 * task is executed and resolved synchronously.
123 * This function takes ownership of task unconditionally; if it fails, task is
126 bool StartOffThreadPromiseHelperTask(JSContext
* cx
,
127 UniquePtr
<PromiseHelperTask
> task
);
130 * Like the JSContext-accepting version, but only safe to use when helper
131 * threads are available, so we can be sure we'll never need to fall back on
132 * synchronous execution.
134 * This function can be called from any thread, but takes ownership of the task
135 * only on success. On OOM, it is the caller's responsibility to arrange for the
136 * task to be cleaned up properly.
138 bool StartOffThreadPromiseHelperTask(PromiseHelperTask
* task
);
141 * Schedule an off-thread Ion compilation for a script, given a task.
143 bool StartOffThreadIonCompile(jit::IonCompileTask
* task
,
144 const AutoLockHelperThreadState
& lock
);
147 * Schedule deletion of Ion compilation data.
149 bool StartOffThreadIonFree(jit::IonCompileTask
* task
,
150 const AutoLockHelperThreadState
& lock
);
152 void FinishOffThreadIonCompile(jit::IonCompileTask
* task
,
153 const AutoLockHelperThreadState
& lock
);
155 struct ZonesInState
{
157 JS::shadow::Zone::GCState state
;
160 using CompilationSelector
=
161 mozilla::Variant
<JSScript
*, JS::Zone
*, ZonesInState
, JSRuntime
*>;
164 * Cancel scheduled or in progress Ion compilations.
166 void CancelOffThreadIonCompile(const CompilationSelector
& selector
);
168 inline void CancelOffThreadIonCompile(JSScript
* script
) {
169 CancelOffThreadIonCompile(CompilationSelector(script
));
172 inline void CancelOffThreadIonCompile(JS::Zone
* zone
) {
173 CancelOffThreadIonCompile(CompilationSelector(zone
));
176 inline void CancelOffThreadIonCompile(JSRuntime
* runtime
,
177 JS::shadow::Zone::GCState state
) {
178 CancelOffThreadIonCompile(CompilationSelector(ZonesInState
{runtime
, state
}));
181 inline void CancelOffThreadIonCompile(JSRuntime
* runtime
) {
182 CancelOffThreadIonCompile(CompilationSelector(runtime
));
186 bool HasOffThreadIonCompile(JS::Zone
* zone
);
190 * Cancel all scheduled, in progress or finished parses for runtime.
192 * Parse tasks which have completed but for which JS::FinishOffThreadScript (or
193 * equivalent) has not been called are removed from the system. This is only
194 * safe to do during shutdown, or if you know that the main thread isn't waiting
195 * for tasks to complete.
197 void CancelOffThreadParses(JSRuntime
* runtime
);
200 * Cancel all scheduled or in progress eager delazification phases for a
203 void CancelOffThreadDelazify(JSRuntime
* runtime
);
206 * Wait for all delazification to complete.
208 void WaitForAllDelazifyTasks(JSRuntime
* rt
);
211 * Start a parse/emit cycle for a stream of source. The characters must stay
212 * alive until the compilation finishes.
215 JS::OffThreadToken
* StartOffThreadCompileToStencil(
216 JSContext
* cx
, const JS::ReadOnlyCompileOptions
& options
,
217 JS::SourceText
<char16_t
>& srcBuf
, JS::OffThreadCompileCallback callback
,
219 JS::OffThreadToken
* StartOffThreadCompileToStencil(
220 JSContext
* cx
, const JS::ReadOnlyCompileOptions
& options
,
221 JS::SourceText
<mozilla::Utf8Unit
>& srcBuf
,
222 JS::OffThreadCompileCallback callback
, void* callbackData
);
224 JS::OffThreadToken
* StartOffThreadCompileModuleToStencil(
225 JSContext
* cx
, const JS::ReadOnlyCompileOptions
& options
,
226 JS::SourceText
<char16_t
>& srcBuf
, JS::OffThreadCompileCallback callback
,
228 JS::OffThreadToken
* StartOffThreadCompileModuleToStencil(
229 JSContext
* cx
, const JS::ReadOnlyCompileOptions
& options
,
230 JS::SourceText
<mozilla::Utf8Unit
>& srcBuf
,
231 JS::OffThreadCompileCallback callback
, void* callbackData
);
233 JS::OffThreadToken
* StartOffThreadDecodeStencil(
234 JSContext
* cx
, const JS::ReadOnlyDecodeOptions
& options
,
235 const JS::TranscodeRange
& range
, JS::OffThreadCompileCallback callback
,
238 // Start off-thread delazification task, to race the delazification of inner
240 void StartOffThreadDelazification(JSContext
* maybeCx
,
241 const JS::ReadOnlyCompileOptions
& options
,
242 const frontend::CompilationStencil
& stencil
);
244 // Drain the task queues and wait for all helper threads to finish running.
246 // Note that helper threads are shared between runtimes and it's possible that
247 // another runtime could saturate the helper thread system and cause this to
249 void WaitForAllHelperThreads();
250 void WaitForAllHelperThreads(AutoLockHelperThreadState
& lock
);
252 // Enqueue a compression job to be processed later. These are started at the
253 // start of the major GC after the next one.
254 bool EnqueueOffThreadCompression(JSContext
* cx
,
255 UniquePtr
<SourceCompressionTask
> task
);
257 // Start handling any compression tasks for this runtime. Called at the start of
259 void StartHandlingCompressionsOnGC(JSRuntime
* rt
);
261 // Cancel all scheduled, in progress, or finished compression tasks for
263 void CancelOffThreadCompressions(JSRuntime
* runtime
);
265 void AttachFinishedCompressions(JSRuntime
* runtime
,
266 AutoLockHelperThreadState
& lock
);
268 // Sweep pending tasks that are holding onto should-be-dead ScriptSources.
269 void SweepPendingCompressions(AutoLockHelperThreadState
& lock
);
271 // Run all pending source compression tasks synchronously, for testing purposes
272 void RunPendingSourceCompressions(JSRuntime
* runtime
);
274 // False if the off-thread source compression mechanism isn't being used. This
275 // happens on low core count machines where we are concerned about blocking
276 // main-thread execution.
277 bool IsOffThreadSourceCompressionEnabled();
281 #endif /* vm_HelperThreads_h */