diff --git a/js/public/RootingAPI.h b/js/public/RootingAPI.h index c283fd698426..514faff95daa 100644 --- a/js/public/RootingAPI.h +++ b/js/public/RootingAPI.h @@ -22,7 +22,6 @@ #include "js/GCAnnotations.h" #include "js/GCPolicyAPI.h" #include "js/GCTypeMacros.h" // JS_FOR_EACH_PUBLIC_{,TAGGED_}GC_POINTER_TYPE -#include "js/HashTable.h" #include "js/HeapAPI.h" #include "js/ProfilingStack.h" #include "js/Realm.h" diff --git a/js/public/StructuredClone.h b/js/public/StructuredClone.h index 79dddfd0ac8e..1b3bec9c7212 100644 --- a/js/public/StructuredClone.h +++ b/js/public/StructuredClone.h @@ -16,7 +16,6 @@ #include "jstypes.h" -#include "js/AllocPolicy.h" #include "js/RootingAPI.h" #include "js/TypeDecls.h" #include "js/Value.h" diff --git a/js/public/TracingAPI.h b/js/public/TracingAPI.h index 2375d12c0975..5bd47a53d9e5 100644 --- a/js/public/TracingAPI.h +++ b/js/public/TracingAPI.h @@ -7,7 +7,9 @@ #ifndef js_TracingAPI_h #define js_TracingAPI_h +#include "js/AllocPolicy.h" #include "js/GCTypeMacros.h" +#include "js/HashTable.h" #include "js/HeapAPI.h" #include "js/TraceKind.h" @@ -444,6 +446,20 @@ JS_DECLARE_UNSAFE_TRACE_ROOT(js::SavedFrame*) extern JS_PUBLIC_API void TraceChildren(JSTracer* trc, GCCellPtr thing); +using ZoneSet = + js::HashSet, js::SystemAllocPolicy>; +using CompartmentSet = + js::HashSet, + js::SystemAllocPolicy>; + +/** + * Trace every value within |compartments| that is wrapped by a + * cross-compartment wrapper from a compartment that is not an element of + * |compartments|. + */ +extern JS_PUBLIC_API void TraceIncomingCCWs( + JSTracer* trc, const JS::CompartmentSet& compartments); + } // namespace JS extern JS_PUBLIC_API void JS_GetTraceThingInfo(char* buf, size_t bufsize, diff --git a/js/public/UbiNode.h b/js/public/UbiNode.h index d1fc30201210..50c5e7eef12b 100644 --- a/js/public/UbiNode.h +++ b/js/public/UbiNode.h @@ -20,7 +20,6 @@ #include "jspubtd.h" -#include "js/AllocPolicy.h" #include "js/GCAPI.h" #include "js/HashTable.h" #include "js/RootingAPI.h" @@ -164,25 +163,23 @@ // structure of the snapshot file, the analyses should be prepared for ubi::Node // graphs constructed from snapshots to be even more bizarre. -namespace js { -class BaseScript; -} // namespace js - namespace JS { - -using ZoneSet = - js::HashSet, js::SystemAllocPolicy>; - -using CompartmentSet = - js::HashSet, - js::SystemAllocPolicy>; - namespace ubi { class Edge; class EdgeRange; class StackFrame; +} // namespace ubi +} // namespace JS + +namespace js { +class BaseScript; +} // namespace js + +namespace JS { +namespace ubi { + using mozilla::Maybe; using mozilla::RangedPtr; using mozilla::Variant; diff --git a/js/src/builtin/TestingFunctions.cpp b/js/src/builtin/TestingFunctions.cpp index ddc2120dfc43..a664683e7ba0 100644 --- a/js/src/builtin/TestingFunctions.cpp +++ b/js/src/builtin/TestingFunctions.cpp @@ -89,7 +89,6 @@ #include "vm/AsyncIteration.h" #include "vm/ErrorObject.h" #include "vm/GlobalObject.h" -#include "vm/HelperThreadState.h" #include "vm/Interpreter.h" #include "vm/Iteration.h" #include "vm/JSContext.h" diff --git a/js/src/debugger/Environment.cpp b/js/src/debugger/Environment.cpp index 05af9a29a3b1..f6e309fa4b97 100644 --- a/js/src/debugger/Environment.cpp +++ b/js/src/debugger/Environment.cpp @@ -24,6 +24,7 @@ #include "gc/Tracer.h" // for TraceManuallyBarrieredCrossCompartmentEdge #include "js/HeapAPI.h" // for IsInsideNursery #include "vm/Compartment.h" // for Compartment +#include "vm/EnvironmentObject.h" // for JSObject::is, DebugEnvironmentProxy #include "vm/JSAtom.h" // for Atomize, PinAtom #include "vm/JSContext.h" // for JSContext #include "vm/JSFunction.h" // for JSFunction diff --git a/js/src/debugger/Object.cpp b/js/src/debugger/Object.cpp index faa3d8be01fa..ce1fa4d7e4e2 100644 --- a/js/src/debugger/Object.cpp +++ b/js/src/debugger/Object.cpp @@ -35,7 +35,6 @@ #include "js/HeapAPI.h" // for IsInsideNursery #include "js/Promise.h" // for PromiseState #include "js/Proxy.h" // for PropertyDescriptor -#include "js/SourceText.h" // for SourceText #include "js/StableStringChars.h" // for AutoStableStringChars #include "js/String.h" // for JS::StringHasLatin1Chars #include "proxy/ScriptedProxyHandler.h" // for ScriptedProxyHandler diff --git a/js/src/debugger/Source.cpp b/js/src/debugger/Source.cpp index 3d0f563cc7c0..752e625869e9 100644 --- a/js/src/debugger/Source.cpp +++ b/js/src/debugger/Source.cpp @@ -22,7 +22,6 @@ #include "js/CompilationAndEvaluation.h" // for Compile #include "js/experimental/TypedData.h" // for JS_NewUint8Array #include "js/friend/ErrorMessages.h" // for GetErrorMessage, JSMSG_* -#include "js/SourceText.h" // for JS::SourceOwnership #include "vm/BytecodeUtil.h" // for JSDVG_SEARCH_STACK #include "vm/JSContext.h" // for JSContext (ptr only) #include "vm/JSObject.h" // for JSObject, RequireObject diff --git a/js/src/frontend/BytecodeCompiler.cpp b/js/src/frontend/BytecodeCompiler.cpp index e8d45a54a254..0b57e4f16892 100644 --- a/js/src/frontend/BytecodeCompiler.cpp +++ b/js/src/frontend/BytecodeCompiler.cpp @@ -26,7 +26,6 @@ #include "vm/FunctionFlags.h" // FunctionFlags #include "vm/GeneratorAndAsyncKind.h" // js::GeneratorKind, js::FunctionAsyncKind #include "vm/GlobalObject.h" -#include "vm/HelperThreadState.h" // ParseTask #include "vm/JSContext.h" #include "vm/JSScript.h" #include "vm/ModuleBuilder.h" // js::ModuleBuilder diff --git a/js/src/gc/AtomMarking-inl.h b/js/src/gc/AtomMarking-inl.h index 94d69f3935c8..8b5dbe693e79 100644 --- a/js/src/gc/AtomMarking-inl.h +++ b/js/src/gc/AtomMarking-inl.h @@ -11,7 +11,6 @@ #include #include "vm/Realm.h" -#include "vm/SymbolType.h" #include "gc/Heap-inl.h" @@ -83,14 +82,6 @@ MOZ_ALWAYS_INLINE bool AtomMarkingRuntime::inlinedMarkAtomInternal( return true; } -void AtomMarkingRuntime::markChildren(JSContext* cx, JSAtom*) {} - -void AtomMarkingRuntime::markChildren(JSContext* cx, JS::Symbol* symbol) { - if (JSAtom* description = symbol->description()) { - markAtom(cx, description); - } -} - template MOZ_ALWAYS_INLINE void AtomMarkingRuntime::inlinedMarkAtom(JSContext* cx, T* thing) { diff --git a/js/src/gc/AtomMarking.h b/js/src/gc/AtomMarking.h index d9186c7c8baf..05386e645de9 100644 --- a/js/src/gc/AtomMarking.h +++ b/js/src/gc/AtomMarking.h @@ -10,11 +10,9 @@ #include "NamespaceImports.h" #include "ds/Bitmap.h" #include "threading/ProtectedData.h" +#include "vm/SymbolType.h" namespace js { - -class AutoLockGC; - namespace gc { class Arena; @@ -25,8 +23,13 @@ class AtomMarkingRuntime { // Unused arena atom bitmap indexes. Protected by the GC lock. js::GCLockData> freeArenaIndexes; - inline void markChildren(JSContext* cx, JSAtom*); - inline void markChildren(JSContext* cx, JS::Symbol* symbol); + void markChildren(JSContext* cx, JSAtom*) {} + + void markChildren(JSContext* cx, JS::Symbol* symbol) { + if (JSAtom* description = symbol->description()) { + markAtom(cx, description); + } + } public: // The extent of all allocated and free words in atom mark bitmaps. diff --git a/js/src/gc/GC.cpp b/js/src/gc/GC.cpp index defa1f1c4fdf..cf63c6161dca 100644 --- a/js/src/gc/GC.cpp +++ b/js/src/gc/GC.cpp @@ -227,6 +227,7 @@ #include "jit/JitCode.h" #include "jit/JitcodeMap.h" #include "jit/JitRealm.h" +#include "jit/MacroAssembler.h" #include "js/Object.h" // JS::GetClass #include "js/SliceBudget.h" #include "proxy/DeadObjectProxy.h" @@ -234,7 +235,6 @@ #include "util/Windows.h" #include "vm/BigIntType.h" #include "vm/GeckoProfiler.h" -#include "vm/HelperThreadState.h" #include "vm/JSAtom.h" #include "vm/JSContext.h" #include "vm/JSObject.h" diff --git a/js/src/gc/GCMarker.h b/js/src/gc/GCMarker.h index 67f483df1817..bdda1745de95 100644 --- a/js/src/gc/GCMarker.h +++ b/js/src/gc/GCMarker.h @@ -11,7 +11,6 @@ #include "mozilla/Unused.h" #include "ds/OrderedHashTable.h" -#include "gc/Barrier.h" #include "js/SliceBudget.h" #include "js/TracingAPI.h" #include "js/TypeDecls.h" diff --git a/js/src/gc/GCParallelTask.cpp b/js/src/gc/GCParallelTask.cpp index ab11d4eb364d..2f7fd206b2a1 100644 --- a/js/src/gc/GCParallelTask.cpp +++ b/js/src/gc/GCParallelTask.cpp @@ -9,7 +9,7 @@ #include "mozilla/MathAlgorithms.h" #include "gc/ParallelWork.h" -#include "vm/HelperThreadState.h" +#include "vm/HelperThreads.h" #include "vm/Runtime.h" #include "vm/TraceLogging.h" diff --git a/js/src/gc/GCRuntime.h b/js/src/gc/GCRuntime.h index 17bbefeba790..812d3d5dd738 100644 --- a/js/src/gc/GCRuntime.h +++ b/js/src/gc/GCRuntime.h @@ -12,8 +12,6 @@ #include "mozilla/Maybe.h" #include "mozilla/TimeStamp.h" -#include "jsfriendapi.h" // For PerformanceHint - #include "gc/ArenaList.h" #include "gc/AtomMarking.h" #include "gc/GCMarker.h" diff --git a/js/src/gc/Marking.cpp b/js/src/gc/Marking.cpp index 7459f47d9144..b7d80fe1ff65 100644 --- a/js/src/gc/Marking.cpp +++ b/js/src/gc/Marking.cpp @@ -35,6 +35,7 @@ #include "vm/ArgumentsObject.h" #include "vm/ArrayObject.h" #include "vm/BigIntType.h" +#include "vm/EnvironmentObject.h" #include "vm/GeneratorObject.h" #include "vm/RegExpShared.h" #include "vm/Scope.h" diff --git a/js/src/gc/Nursery.cpp b/js/src/gc/Nursery.cpp index 940aaff462fe..ef765d247a61 100644 --- a/js/src/gc/Nursery.cpp +++ b/js/src/gc/Nursery.cpp @@ -27,6 +27,9 @@ #include "jit/JitRealm.h" #include "util/Poison.h" #include "vm/ArrayObject.h" +#if defined(DEBUG) +# include "vm/EnvironmentObject.h" +#endif #include "vm/JSONPrinter.h" #include "vm/Realm.h" #include "vm/Time.h" diff --git a/js/src/gc/Nursery.h b/js/src/gc/Nursery.h index 4daf2d16e0d0..50f2549396f1 100644 --- a/js/src/gc/Nursery.h +++ b/js/src/gc/Nursery.h @@ -14,7 +14,6 @@ #include "gc/GCParallelTask.h" #include "gc/Heap.h" -#include "js/AllocPolicy.h" #include "js/Class.h" #include "js/HeapAPI.h" #include "js/TracingAPI.h" diff --git a/js/src/gc/ParallelWork.h b/js/src/gc/ParallelWork.h index 60d68f810104..27c1781dff2a 100644 --- a/js/src/gc/ParallelWork.h +++ b/js/src/gc/ParallelWork.h @@ -12,7 +12,6 @@ #include "gc/GC.h" #include "gc/GCParallelTask.h" -#include "gc/GCRuntime.h" #include "js/SliceBudget.h" #include "vm/HelperThreads.h" @@ -114,7 +113,7 @@ class MOZ_RAII AutoRunParallelWork { } ~AutoRunParallelWork() { - MOZ_ASSERT(gHelperThreadLock.ownedByCurrentThread()); + MOZ_ASSERT(HelperThreadState().isLockedByCurrentThread()); for (size_t i = 0; i < tasksStarted; i++) { gc->joinTask(*tasks[i], phaseKind, lock); diff --git a/js/src/gc/RootMarking.cpp b/js/src/gc/RootMarking.cpp index 67305e97c29e..65561c3b067d 100644 --- a/js/src/gc/RootMarking.cpp +++ b/js/src/gc/RootMarking.cpp @@ -17,9 +17,9 @@ #include "gc/ClearEdgesTracer.h" #include "gc/GCInternals.h" #include "gc/Marking.h" +#include "jit/MacroAssembler.h" #include "js/HashTable.h" #include "js/ValueArray.h" -#include "vm/HelperThreadState.h" #include "vm/JSContext.h" #include "vm/JSONParser.h" diff --git a/js/src/gc/Tracer.cpp b/js/src/gc/Tracer.cpp index da2956f2e067..36ed3e0169aa 100644 --- a/js/src/gc/Tracer.cpp +++ b/js/src/gc/Tracer.cpp @@ -104,8 +104,8 @@ void js::TraceChildren(JSTracer* trc, void* thing, JS::TraceKind kind) { }); } -void js::gc::TraceIncomingCCWs(JSTracer* trc, - const JS::CompartmentSet& compartments) { +JS_PUBLIC_API void JS::TraceIncomingCCWs( + JSTracer* trc, const JS::CompartmentSet& compartments) { for (CompartmentsIter source(trc->runtime()); !source.done(); source.next()) { if (compartments.has(source)) { continue; diff --git a/js/src/gc/Tracer.h b/js/src/gc/Tracer.h index a97ec487ad65..988f156ba6b6 100644 --- a/js/src/gc/Tracer.h +++ b/js/src/gc/Tracer.h @@ -7,14 +7,9 @@ #ifndef js_Tracer_h #define js_Tracer_h -#include "gc/Barrier.h" -#include "js/HashTable.h" +#include "jsfriendapi.h" -namespace JS { -using CompartmentSet = - js::HashSet, - js::SystemAllocPolicy>; -} // namespace JS +#include "gc/Barrier.h" namespace js { @@ -311,13 +306,6 @@ namespace gc { void TraceCycleCollectorChildren(JS::CallbackTracer* trc, Shape* shape); void TraceCycleCollectorChildren(JS::CallbackTracer* trc, ObjectGroup* group); -/** - * Trace every value within |compartments| that is wrapped by a - * cross-compartment wrapper from a compartment that is not an element of - * |compartments|. - */ -void TraceIncomingCCWs(JSTracer* trc, const JS::CompartmentSet& compartments); - } // namespace gc } // namespace js diff --git a/js/src/gc/Verifier.cpp b/js/src/gc/Verifier.cpp index 0995a1ba83e3..838cfb314027 100644 --- a/js/src/gc/Verifier.cpp +++ b/js/src/gc/Verifier.cpp @@ -501,7 +501,7 @@ void js::gc::MarkingValidator::nonIncrementalMark(AutoGCSession& session) { MOZ_ASSERT(!gcmarker->isWeakMarking()); /* Wait for off-thread parsing which can allocate. */ - WaitForAllHelperThreads(); + HelperThreadState().waitForAllThreads(); gc->waitBackgroundAllocEnd(); gc->waitBackgroundSweepEnd(); diff --git a/js/src/gdb/tests/test-unwind.cpp b/js/src/gdb/tests/test-unwind.cpp index 13a82bf790b8..734666978189 100644 --- a/js/src/gdb/tests/test-unwind.cpp +++ b/js/src/gdb/tests/test-unwind.cpp @@ -1,6 +1,5 @@ #include "gdb-tests.h" #include "jsapi.h" // sundry symbols not moved to more-specific headers yet -#include "jsfriendapi.h" // JSFunctionSpecWithHelp #include "jit/JitOptions.h" // js::jit::JitOptions #include "js/CallArgs.h" // JS::CallArgs, JS::CallArgsFromVp diff --git a/js/src/jit/BaselineBailouts.cpp b/js/src/jit/BaselineBailouts.cpp index 76500608f119..ed45e08d7df6 100644 --- a/js/src/jit/BaselineBailouts.cpp +++ b/js/src/jit/BaselineBailouts.cpp @@ -6,7 +6,6 @@ #include "mozilla/ScopeExit.h" -#include "builtin/ModuleObject.h" #include "debugger/DebugAPI.h" #include "jit/arm/Simulator-arm.h" #include "jit/BaselineFrame.h" diff --git a/js/src/jit/BaselineFrame-inl.h b/js/src/jit/BaselineFrame-inl.h index 520c9cd1a772..e91c21e0a5d3 100644 --- a/js/src/jit/BaselineFrame-inl.h +++ b/js/src/jit/BaselineFrame-inl.h @@ -9,6 +9,7 @@ #include "jit/BaselineFrame.h" +#include "vm/EnvironmentObject.h" #include "vm/JSContext.h" #include "vm/Realm.h" diff --git a/js/src/jit/BaselineFrameInfo.h b/js/src/jit/BaselineFrameInfo.h index 49d1d6e87ba2..7938f3830648 100644 --- a/js/src/jit/BaselineFrameInfo.h +++ b/js/src/jit/BaselineFrameInfo.h @@ -14,13 +14,13 @@ #include "jit/BaselineFrame.h" #include "jit/BaselineJIT.h" #include "jit/FixedList.h" +#include "jit/MacroAssembler.h" #include "jit/SharedICRegisters.h" namespace js { namespace jit { struct BytecodeInfo; -class MacroAssembler; // [SMDOC] Baseline FrameInfo overview. // diff --git a/js/src/jit/BaselineIC.h b/js/src/jit/BaselineIC.h index 8df022e30480..38d9f8e7f351 100644 --- a/js/src/jit/BaselineIC.h +++ b/js/src/jit/BaselineIC.h @@ -21,7 +21,6 @@ #include "vm/ArrayObject.h" #include "vm/BytecodeUtil.h" #include "vm/JSContext.h" -#include "vm/ProxyObject.h" #include "vm/Realm.h" namespace js { diff --git a/js/src/jit/BaselineJIT.h b/js/src/jit/BaselineJIT.h index be4a7b3a8d7f..21fe50c36811 100644 --- a/js/src/jit/BaselineJIT.h +++ b/js/src/jit/BaselineJIT.h @@ -16,6 +16,7 @@ #include "jit/JitCode.h" #include "jit/shared/Assembler-shared.h" #include "util/TrailingArray.h" +#include "vm/EnvironmentObject.h" #include "vm/JSContext.h" #include "vm/Realm.h" #include "vm/TraceLogging.h" diff --git a/js/src/jit/CacheIR.cpp b/js/src/jit/CacheIR.cpp index 1820c5619f05..8325afcb37e7 100644 --- a/js/src/jit/CacheIR.cpp +++ b/js/src/jit/CacheIR.cpp @@ -12,7 +12,6 @@ #include "builtin/DataViewObject.h" #include "builtin/MapObject.h" -#include "builtin/ModuleObject.h" #include "jit/BaselineCacheIRCompiler.h" #include "jit/BaselineIC.h" #include "jit/CacheIRSpewer.h" diff --git a/js/src/jit/CacheIR.h b/js/src/jit/CacheIR.h index bc73cae6d4df..6dbf6d02ec03 100644 --- a/js/src/jit/CacheIR.h +++ b/js/src/jit/CacheIR.h @@ -13,11 +13,11 @@ #include "NamespaceImports.h" -#include "builtin/TypedObject.h" #include "gc/Rooting.h" #include "jit/CacheIROpsGenerated.h" #include "jit/CompactBuffer.h" #include "jit/ICState.h" +#include "jit/MacroAssembler.h" #include "jit/Simulator.h" #include "js/friend/XrayJitInfo.h" // JS::XrayJitInfo #include "js/ScalarType.h" // js::Scalar::Type @@ -30,10 +30,6 @@ namespace jit { enum class BaselineCacheIRStubKind; enum class InlinableNative : uint16_t; -class ICStub; -class Label; -class MacroAssembler; - // [SMDOC] CacheIR // // CacheIR is an (extremely simple) linear IR language for inline caches. diff --git a/js/src/jit/CacheIRHealth.h b/js/src/jit/CacheIRHealth.h index b217cf035f83..7495c176098d 100644 --- a/js/src/jit/CacheIRHealth.h +++ b/js/src/jit/CacheIRHealth.h @@ -16,8 +16,6 @@ namespace js { namespace jit { -class ICEntry; - // [SMDOC] CacheIR Health Rating // // The goal of CacheIR health rating is to make the costlier diff --git a/js/src/jit/CompileInfo.h b/js/src/jit/CompileInfo.h index d34c5bbff911..6f4699b8330e 100644 --- a/js/src/jit/CompileInfo.h +++ b/js/src/jit/CompileInfo.h @@ -14,6 +14,7 @@ #include "jit/JitAllocPolicy.h" #include "jit/JitFrames.h" #include "jit/Registers.h" +#include "vm/EnvironmentObject.h" #include "vm/JSFunction.h" namespace js { diff --git a/js/src/jit/Ion.cpp b/js/src/jit/Ion.cpp index 2807413faea5..ffebcf043f4c 100644 --- a/js/src/jit/Ion.cpp +++ b/js/src/jit/Ion.cpp @@ -54,7 +54,7 @@ #include "js/UniquePtr.h" #include "util/Memory.h" #include "util/Windows.h" -#include "vm/HelperThreadState.h" +#include "vm/HelperThreads.h" #include "vm/Realm.h" #include "vm/TraceLogging.h" #ifdef MOZ_VTUNE diff --git a/js/src/jit/IonBuilder.cpp b/js/src/jit/IonBuilder.cpp index 3a59c811c415..bed37e43a64e 100644 --- a/js/src/jit/IonBuilder.cpp +++ b/js/src/jit/IonBuilder.cpp @@ -12,7 +12,6 @@ #include #include "builtin/Eval.h" -#include "builtin/ModuleObject.h" #include "builtin/TypedObject.h" #include "frontend/SourceNotes.h" #include "jit/BaselineFrame.h" @@ -32,6 +31,7 @@ #include "vm/BytecodeIterator.h" #include "vm/BytecodeLocation.h" #include "vm/BytecodeUtil.h" +#include "vm/EnvironmentObject.h" #include "vm/Instrumentation.h" #include "vm/Opcodes.h" #include "vm/PlainObject.h" // js::PlainObject diff --git a/js/src/jit/IonCompileTask.cpp b/js/src/jit/IonCompileTask.cpp index d3da945a6c27..40dda976cfd3 100644 --- a/js/src/jit/IonCompileTask.cpp +++ b/js/src/jit/IonCompileTask.cpp @@ -9,7 +9,6 @@ #include "jit/CodeGenerator.h" #include "jit/JitScript.h" #include "jit/WarpSnapshot.h" -#include "vm/HelperThreadState.h" #include "vm/JSScript.h" #include "vm/JSScript-inl.h" diff --git a/js/src/jit/IonIC.h b/js/src/jit/IonIC.h index 7fd1bd2ba7d8..5d964702445b 100644 --- a/js/src/jit/IonIC.h +++ b/js/src/jit/IonIC.h @@ -8,7 +8,6 @@ #define jit_IonIC_h #include "jit/CacheIR.h" -#include "jit/shared/Assembler-shared.h" namespace js { namespace jit { diff --git a/js/src/jit/JitFrames.cpp b/js/src/jit/JitFrames.cpp index f24a75fcdecd..62a58efaf6d4 100644 --- a/js/src/jit/JitFrames.cpp +++ b/js/src/jit/JitFrames.cpp @@ -10,7 +10,6 @@ #include -#include "builtin/ModuleObject.h" #include "gc/Marking.h" #include "jit/BaselineDebugModeOSR.h" #include "jit/BaselineFrame.h" @@ -21,6 +20,7 @@ #include "jit/JitcodeMap.h" #include "jit/JitRealm.h" #include "jit/JitSpewer.h" +#include "jit/MacroAssembler.h" #include "jit/PcScriptCache.h" #include "jit/Recover.h" #include "jit/Safepoints.h" diff --git a/js/src/jit/JitScript.h b/js/src/jit/JitScript.h index 9402af33e55b..2a68100de91d 100644 --- a/js/src/jit/JitScript.h +++ b/js/src/jit/JitScript.h @@ -14,7 +14,6 @@ #include "jit/TrialInlining.h" #include "js/UniquePtr.h" #include "util/TrailingArray.h" -#include "vm/EnvironmentObject.h" #include "vm/TypeInference.h" class JS_PUBLIC_API JSScript; diff --git a/js/src/jit/Linker.h b/js/src/jit/Linker.h index 3a09b11e7282..59ce9ea47916 100644 --- a/js/src/jit/Linker.h +++ b/js/src/jit/Linker.h @@ -17,8 +17,6 @@ namespace js { namespace jit { -class MacroAssembler; - class Linker { MacroAssembler& masm; mozilla::Maybe awjcf; diff --git a/js/src/jit/MIR.h b/js/src/jit/MIR.h index d5112ef96c61..4be044deefb9 100644 --- a/js/src/jit/MIR.h +++ b/js/src/jit/MIR.h @@ -20,12 +20,12 @@ #include #include -#include "builtin/ModuleObject.h" #include "jit/AtomicOp.h" #include "jit/BaselineIC.h" #include "jit/FixedList.h" #include "jit/InlineList.h" #include "jit/JitAllocPolicy.h" +#include "jit/MacroAssembler.h" #include "jit/MOpcodesGenerated.h" #include "jit/TIOracle.h" #include "jit/TypePolicy.h" diff --git a/js/src/jit/MacroAssembler-inl.h b/js/src/jit/MacroAssembler-inl.h index f8546ea58594..253a491514a0 100644 --- a/js/src/jit/MacroAssembler-inl.h +++ b/js/src/jit/MacroAssembler-inl.h @@ -13,7 +13,6 @@ #include "mozilla/MathAlgorithms.h" #include "gc/Zone.h" -#include "vm/ProxyObject.h" #if defined(JS_CODEGEN_X86) # include "jit/x86/MacroAssembler-x86-inl.h" diff --git a/js/src/jit/MacroAssembler.h b/js/src/jit/MacroAssembler.h index 974cdf45cf1a..072d01f2bb3b 100644 --- a/js/src/jit/MacroAssembler.h +++ b/js/src/jit/MacroAssembler.h @@ -12,6 +12,8 @@ #include "mozilla/MathAlgorithms.h" #include "mozilla/Maybe.h" +#include "vm/Realm.h" + #if defined(JS_CODEGEN_X86) # include "jit/x86/MacroAssembler-x86.h" #elif defined(JS_CODEGEN_X64) @@ -37,6 +39,9 @@ #include "jit/VMFunctions.h" #include "js/ScalarType.h" // js::Scalar::Type #include "util/Memory.h" +#include "vm/ProxyObject.h" +#include "vm/Shape.h" +#include "vm/TypedArrayObject.h" // [SMDOC] MacroAssembler multi-platform overview // @@ -204,9 +209,6 @@ #endif namespace js { - -class TypedArrayObject; - namespace jit { // Defined in JitFrames.h diff --git a/js/src/jit/PerfSpewer.h b/js/src/jit/PerfSpewer.h index 5e3cb2394881..676c9705b691 100644 --- a/js/src/jit/PerfSpewer.h +++ b/js/src/jit/PerfSpewer.h @@ -9,6 +9,7 @@ #ifdef JS_ION_PERF # include +# include "jit/MacroAssembler.h" #endif namespace { diff --git a/js/src/jit/RematerializedFrame.h b/js/src/jit/RematerializedFrame.h index 2a305e4db430..d00fc966e8a7 100644 --- a/js/src/jit/RematerializedFrame.h +++ b/js/src/jit/RematerializedFrame.h @@ -12,13 +12,11 @@ #include "jit/JitFrames.h" #include "jit/JSJitFrameIter.h" #include "js/UniquePtr.h" +#include "vm/EnvironmentObject.h" #include "vm/JSFunction.h" #include "vm/Stack.h" namespace js { - -class CallObject; - namespace jit { // RematerializedFrame: An optimized frame that has been rematerialized with diff --git a/js/src/jit/TrialInlining.h b/js/src/jit/TrialInlining.h index 1f52b0f0c5c5..de18ef6d980e 100644 --- a/js/src/jit/TrialInlining.h +++ b/js/src/jit/TrialInlining.h @@ -8,7 +8,6 @@ #define jit_TrialInlining_h #include "jit/CacheIR.h" -#include "jit/ICStubSpace.h" #include "vm/BytecodeLocation.h" /* @@ -36,9 +35,6 @@ namespace js { namespace jit { -class ICEntry; -class ICScript; - /* * An InliningRoot is owned by a JitScript. In turn, it owns the set * of ICScripts that are candidates for being inlined in that JitScript. diff --git a/js/src/jit/VMFunctionList-inl.h b/js/src/jit/VMFunctionList-inl.h index b6bf26917020..6282af5816d3 100644 --- a/js/src/jit/VMFunctionList-inl.h +++ b/js/src/jit/VMFunctionList-inl.h @@ -8,7 +8,6 @@ #define jit_VMFunctionList_inl_h #include "builtin/Eval.h" -#include "builtin/ModuleObject.h" // js::GetOrCreateModuleMetaObject #include "builtin/Promise.h" // js::AsyncFunctionAwait #include "builtin/RegExp.h" #include "builtin/String.h" diff --git a/js/src/jit/WarpOracle.cpp b/js/src/jit/WarpOracle.cpp index 05db0cb90119..16de57bebdea 100644 --- a/js/src/jit/WarpOracle.cpp +++ b/js/src/jit/WarpOracle.cpp @@ -23,6 +23,7 @@ #include "vm/BuiltinObjectKind.h" #include "vm/BytecodeIterator.h" #include "vm/BytecodeLocation.h" +#include "vm/EnvironmentObject.h" #include "vm/Instrumentation.h" #include "vm/Opcodes.h" diff --git a/js/src/jit/WarpSnapshot.h b/js/src/jit/WarpSnapshot.h index 0f1f09227185..ab64366fec14 100644 --- a/js/src/jit/WarpSnapshot.h +++ b/js/src/jit/WarpSnapshot.h @@ -10,7 +10,6 @@ #include "mozilla/LinkedList.h" #include "mozilla/Variant.h" -#include "builtin/ModuleObject.h" #include "gc/Policy.h" #include "jit/JitAllocPolicy.h" #include "jit/JitContext.h" diff --git a/js/src/jsapi-tests/testGCMarking.cpp b/js/src/jsapi-tests/testGCMarking.cpp index 36a609a8c97b..bf4a973ffab7 100644 --- a/js/src/jsapi-tests/testGCMarking.cpp +++ b/js/src/jsapi-tests/testGCMarking.cpp @@ -130,7 +130,7 @@ BEGIN_TEST(testTracingIncomingCCWs) { void* thing = wrappee.get(); CCWTestTracer trc(cx, &thing, JS::TraceKind::Object); - js::gc::TraceIncomingCCWs(&trc, compartments); + JS::TraceIncomingCCWs(&trc, compartments); CHECK(trc.numberOfThingsTraced == 1); CHECK(trc.okay); diff --git a/js/src/jsnum.h b/js/src/jsnum.h index 707267ea6f9d..2e71e14bec4d 100644 --- a/js/src/jsnum.h +++ b/js/src/jsnum.h @@ -14,7 +14,6 @@ #include "NamespaceImports.h" #include "js/Conversions.h" -#include "js/friend/ErrorMessages.h" #include "vm/StringType.h" diff --git a/js/src/shell/js.cpp b/js/src/shell/js.cpp index 068867f3d56d..d38e024024e4 100644 --- a/js/src/shell/js.cpp +++ b/js/src/shell/js.cpp @@ -4761,7 +4761,7 @@ static bool SetJitCompilerOption(JSContext* cx, unsigned argc, Value* vp) { // JIT compiler options are process-wide, so we have to stop off-thread // compilations for all runtimes to avoid races. - WaitForAllHelperThreads(); + HelperThreadState().waitForAllThreads(); // Only release JIT code for the current runtime because there's no good // way to discard code for other runtimes. diff --git a/js/src/threading/ProtectedData.cpp b/js/src/threading/ProtectedData.cpp index cdccfe3db6fb..366d787f4de5 100644 --- a/js/src/threading/ProtectedData.cpp +++ b/js/src/threading/ProtectedData.cpp @@ -107,7 +107,7 @@ void CheckGlobalLock::check() const { TlsContext.get()->runtime()->currentThreadHasScriptDataAccess()); break; case GlobalLock::HelperThreadLock: - MOZ_ASSERT(gHelperThreadLock.ownedByCurrentThread()); + MOZ_ASSERT(HelperThreadState().isLockedByCurrentThread()); break; } } diff --git a/js/src/util/Utility.cpp b/js/src/util/Utility.cpp index d99783671727..039c8b3e469a 100644 --- a/js/src/util/Utility.cpp +++ b/js/src/util/Utility.cpp @@ -51,7 +51,7 @@ void FailureSimulator::simulateFailureAfter(Kind kind, uint64_t checks, Maybe lock; if (IsHelperThreadType(targetThread_) || IsHelperThreadType(thread)) { lock.emplace(); - WaitForAllHelperThreads(lock.ref()); + HelperThreadState().waitForAllThreadsLocked(lock.ref()); } MOZ_ASSERT(counter_ + checks > counter_); @@ -66,7 +66,7 @@ void FailureSimulator::reset() { Maybe lock; if (IsHelperThreadType(targetThread_)) { lock.emplace(); - WaitForAllHelperThreads(lock.ref()); + HelperThreadState().waitForAllThreadsLocked(lock.ref()); } targetThread_ = THREAD_TYPE_NONE; diff --git a/js/src/vm/CodeCoverage.h b/js/src/vm/CodeCoverage.h index 724e2ef35dac..9d766d6e6c42 100644 --- a/js/src/vm/CodeCoverage.h +++ b/js/src/vm/CodeCoverage.h @@ -11,7 +11,6 @@ #include "ds/LifoAlloc.h" -#include "js/AllocPolicy.h" #include "js/HashTable.h" #include "js/TypeDecls.h" #include "js/Utility.h" diff --git a/js/src/vm/EnvironmentObject.h b/js/src/vm/EnvironmentObject.h index cec3925e04f5..6b66c2992e90 100644 --- a/js/src/vm/EnvironmentObject.h +++ b/js/src/vm/EnvironmentObject.h @@ -9,11 +9,13 @@ #include +#include "builtin/ModuleObject.h" #include "frontend/NameAnalysisTypes.h" #include "gc/Barrier.h" #include "gc/WeakMap.h" #include "js/GCHashTable.h" #include "vm/ArgumentsObject.h" +#include "vm/GeneratorObject.h" #include "vm/GlobalObject.h" #include "vm/JSContext.h" #include "vm/JSObject.h" @@ -22,10 +24,7 @@ namespace js { -class AbstractGeneratorObject; -class IndirectBindingMap; class ModuleObject; - using HandleModuleObject = Handle; /* diff --git a/js/src/vm/HelperThreadState.h b/js/src/vm/HelperThreadState.h deleted file mode 100644 index 853ca702a3d0..000000000000 --- a/js/src/vm/HelperThreadState.h +++ /dev/null @@ -1,680 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * vim: set ts=8 sts=2 et sw=2 tw=80: - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* - * Definitions for managing off-thread work using a process wide list of - * worklist items and pool of threads. Worklist items are engine internal, and - * are distinct from e.g. web workers. - */ - -#ifndef vm_HelperThreadState_h -#define vm_HelperThreadState_h - -#include "mozilla/Attributes.h" -#include "mozilla/EnumeratedArray.h" -#include "mozilla/TimeStamp.h" - -#include "jsapi.h" - -#include "ds/Fifo.h" -#include "js/CompileOptions.h" -#include "js/TypeDecls.h" -#include "threading/ConditionVariable.h" -#include "threading/Thread.h" -#include "vm/HelperThreads.h" -#include "vm/HelperThreadTask.h" -#include "vm/JSContext.h" -#include "vm/OffThreadPromiseRuntimeState.h" // js::OffThreadPromiseTask - -namespace js { - -class AutoLockHelperThreadState; -class AutoUnlockHelperThreadState; -class CompileError; -struct ParseTask; -struct PromiseHelperTask; -class PromiseObject; - -namespace jit { -class IonCompileTask; -class IonFreeTask; -} // namespace jit - -namespace frontend { -struct CompilationInfo; -} // namespace frontend - -namespace wasm { -struct Tier2GeneratorTask; -} // namespace wasm - -enum class ParseTaskKind { Script, Module, ScriptDecode, MultiScriptsDecode }; -enum class StartEncoding { No, Yes }; - -namespace wasm { - -struct CompileTask; -typedef Fifo CompileTaskPtrFifo; - -struct Tier2GeneratorTask : public HelperThreadTask { - virtual ~Tier2GeneratorTask() = default; - virtual void cancel() = 0; -}; - -using UniqueTier2GeneratorTask = UniquePtr; -typedef Vector - Tier2GeneratorTaskPtrVector; - -} // namespace wasm - -// Per-process state for off thread work items. -class GlobalHelperThreadState { - friend class AutoLockHelperThreadState; - friend class AutoUnlockHelperThreadState; - - public: - // A single tier-2 ModuleGenerator job spawns many compilation jobs, and we - // do not want to allow more than one such ModuleGenerator to run at a time. - static const size_t MaxTier2GeneratorTasks = 1; - - // Number of CPUs to treat this machine as having when creating threads. - // May be accessed without locking. - size_t cpuCount; - - // Number of threads to create. May be accessed without locking. - size_t threadCount; - - typedef Vector - IonCompileTaskVector; - using IonFreeTaskVector = - Vector, 0, SystemAllocPolicy>; - typedef Vector, 0, SystemAllocPolicy> ParseTaskVector; - using ParseTaskList = mozilla::LinkedList; - typedef Vector, 0, SystemAllocPolicy> - SourceCompressionTaskVector; - using GCParallelTaskList = mozilla::LinkedList; - typedef Vector - PromiseHelperTaskVector; - typedef Vector ContextVector; - using HelperThreadVector = - Vector, 0, SystemAllocPolicy>; - - // Count of running task by each threadType. - mozilla::EnumeratedArray - runningTaskCount; - size_t totalCountRunningTasks; - - WriteOnceData registerThread; - WriteOnceData unregisterThread; - - private: - // The lists below are all protected by |lock|. - - // List of available helper threads. - HelperThreadVector threads_; - - // Ion compilation worklist and finished jobs. - IonCompileTaskVector ionWorklist_, ionFinishedList_; - IonFreeTaskVector ionFreeList_; - - // wasm worklists. - wasm::CompileTaskPtrFifo wasmWorklist_tier1_; - wasm::CompileTaskPtrFifo wasmWorklist_tier2_; - wasm::Tier2GeneratorTaskPtrVector wasmTier2GeneratorWorklist_; - - // Count of finished Tier2Generator tasks. - uint32_t wasmTier2GeneratorsFinished_; - - // Async tasks that, upon completion, are dispatched back to the JSContext's - // owner thread via embedding callbacks instead of a finished list. - PromiseHelperTaskVector promiseHelperTasks_; - - // Script parsing/emitting worklist and finished jobs. - ParseTaskVector parseWorklist_; - ParseTaskList parseFinishedList_; - - // Parse tasks waiting for an atoms-zone GC to complete. - ParseTaskVector parseWaitingOnGC_; - - // Source compression worklist of tasks that we do not yet know can start. - SourceCompressionTaskVector compressionPendingList_; - - // Source compression worklist of tasks that can start. - SourceCompressionTaskVector compressionWorklist_; - - // Finished source compression tasks. - SourceCompressionTaskVector compressionFinishedList_; - - // GC tasks needing to be done in parallel. - GCParallelTaskList gcParallelWorklist_; - size_t gcParallelThreadCount; - - // Global list of JSContext for GlobalHelperThreadState to use. - ContextVector helperContexts_; - - using HelperThreadTaskVector = - Vector; - // Vector of running HelperThreadTask. - // This is used to get the HelperThreadTask that are currently running. - HelperThreadTaskVector helperTasks_; - - ParseTask* removeFinishedParseTask(ParseTaskKind kind, - JS::OffThreadToken* token); - - public: - void addSizeOfIncludingThis(JS::GlobalStats* stats, - AutoLockHelperThreadState& lock) const; - - size_t maxIonCompilationThreads() const; - size_t maxWasmCompilationThreads() const; - size_t maxWasmTier2GeneratorThreads() const; - size_t maxPromiseHelperThreads() const; - size_t maxParseThreads() const; - size_t maxCompressionThreads() const; - size_t maxGCParallelThreads(const AutoLockHelperThreadState& lock) const; - - GlobalHelperThreadState(); - - HelperThreadVector& threads(const AutoLockHelperThreadState& lock) { - return threads_; - } - const HelperThreadVector& threads( - const AutoLockHelperThreadState& lock) const { - return threads_; - } - - bool ensureInitialized(); - bool ensureThreadCount(size_t count); - void finish(); - void finishThreads(); - - MOZ_MUST_USE bool ensureContextList(size_t count); - JSContext* getFirstUnusedContext(AutoLockHelperThreadState& locked); - void destroyHelperContexts(AutoLockHelperThreadState& lock); - -#ifdef DEBUG - bool isLockedByCurrentThread() const; -#endif - - enum CondVar { - // For notifying threads waiting for work that they may be able to make - // progress, ie, a work item has been completed by a helper thread and - // the thread that created the work item can now consume it. - CONSUMER, - - // For notifying helper threads doing the work that they may be able to - // make progress, ie, a work item has been enqueued and an idle helper - // thread may pick up up the work item and perform it. - PRODUCER, - }; - - void wait(AutoLockHelperThreadState& locked, CondVar which, - mozilla::TimeDuration timeout = mozilla::TimeDuration::Forever()); - void notifyAll(CondVar which, const AutoLockHelperThreadState&); - - private: - void notifyOne(CondVar which, const AutoLockHelperThreadState&); - - public: - // Helper method for removing items from the vectors below while iterating - // over them. - template - void remove(T& vector, size_t* index) { - // Self-moving is undefined behavior. - if (*index != vector.length() - 1) { - vector[*index] = std::move(vector.back()); - } - (*index)--; - vector.popBack(); - } - - IonCompileTaskVector& ionWorklist(const AutoLockHelperThreadState&) { - return ionWorklist_; - } - IonCompileTaskVector& ionFinishedList(const AutoLockHelperThreadState&) { - return ionFinishedList_; - } - IonFreeTaskVector& ionFreeList(const AutoLockHelperThreadState&) { - return ionFreeList_; - } - - wasm::CompileTaskPtrFifo& wasmWorklist(const AutoLockHelperThreadState&, - wasm::CompileMode m) { - switch (m) { - case wasm::CompileMode::Once: - case wasm::CompileMode::Tier1: - return wasmWorklist_tier1_; - case wasm::CompileMode::Tier2: - return wasmWorklist_tier2_; - default: - MOZ_CRASH(); - } - } - - wasm::Tier2GeneratorTaskPtrVector& wasmTier2GeneratorWorklist( - const AutoLockHelperThreadState&) { - return wasmTier2GeneratorWorklist_; - } - - void incWasmTier2GeneratorsFinished(const AutoLockHelperThreadState&) { - wasmTier2GeneratorsFinished_++; - } - - uint32_t wasmTier2GeneratorsFinished(const AutoLockHelperThreadState&) const { - return wasmTier2GeneratorsFinished_; - } - - PromiseHelperTaskVector& promiseHelperTasks( - const AutoLockHelperThreadState&) { - return promiseHelperTasks_; - } - - ParseTaskVector& parseWorklist(const AutoLockHelperThreadState&) { - return parseWorklist_; - } - ParseTaskList& parseFinishedList(const AutoLockHelperThreadState&) { - return parseFinishedList_; - } - ParseTaskVector& parseWaitingOnGC(const AutoLockHelperThreadState&) { - return parseWaitingOnGC_; - } - - SourceCompressionTaskVector& compressionPendingList( - const AutoLockHelperThreadState&) { - return compressionPendingList_; - } - - SourceCompressionTaskVector& compressionWorklist( - const AutoLockHelperThreadState&) { - return compressionWorklist_; - } - - SourceCompressionTaskVector& compressionFinishedList( - const AutoLockHelperThreadState&) { - return compressionFinishedList_; - } - - GCParallelTaskList& gcParallelWorklist(const AutoLockHelperThreadState&) { - return gcParallelWorklist_; - } - - void setGCParallelThreadCount(size_t count, - const AutoLockHelperThreadState&) { - MOZ_ASSERT(count >= 1); - MOZ_ASSERT(count <= threadCount); - gcParallelThreadCount = count; - } - - HelperThreadTaskVector& helperTasks(const AutoLockHelperThreadState&) { - return helperTasks_; - } - - HelperThreadTask* maybeGetWasmCompile(const AutoLockHelperThreadState& lock, - wasm::CompileMode mode); - - HelperThreadTask* maybeGetWasmTier1CompileTask( - const AutoLockHelperThreadState& lock); - HelperThreadTask* maybeGetWasmTier2CompileTask( - const AutoLockHelperThreadState& lock); - HelperThreadTask* maybeGetWasmTier2GeneratorTask( - const AutoLockHelperThreadState& lock); - HelperThreadTask* maybeGetPromiseHelperTask( - const AutoLockHelperThreadState& lock); - HelperThreadTask* maybeGetIonCompileTask( - const AutoLockHelperThreadState& lock); - HelperThreadTask* maybeGetIonFreeTask(const AutoLockHelperThreadState& lock); - HelperThreadTask* maybeGetParseTask(const AutoLockHelperThreadState& lock); - HelperThreadTask* maybeGetCompressionTask( - const AutoLockHelperThreadState& lock); - HelperThreadTask* maybeGetGCParallelTask( - const AutoLockHelperThreadState& lock); - - enum class ScheduleCompressionTask { GC, API }; - - // Used by a major GC to signal processing enqueued compression tasks. - void startHandlingCompressionTasks(const AutoLockHelperThreadState&, - ScheduleCompressionTask schedule); - - jit::IonCompileTask* highestPriorityPendingIonCompile( - const AutoLockHelperThreadState& lock); - - private: - void scheduleCompressionTasks(const AutoLockHelperThreadState&, - ScheduleCompressionTask schedule); - - UniquePtr finishParseTaskCommon(JSContext* cx, ParseTaskKind kind, - JS::OffThreadToken* token); - - JSScript* finishSingleParseTask( - JSContext* cx, ParseTaskKind kind, JS::OffThreadToken* token, - StartEncoding startEncoding = StartEncoding::No); - bool generateLCovSources(JSContext* cx, ParseTask* parseTask); - bool finishMultiParseTask(JSContext* cx, ParseTaskKind kind, - JS::OffThreadToken* token, - MutableHandle scripts); - - void mergeParseTaskRealm(JSContext* cx, ParseTask* parseTask, - JS::Realm* dest); - - public: - void cancelParseTask(JSRuntime* rt, ParseTaskKind kind, - JS::OffThreadToken* token); - void destroyParseTask(JSRuntime* rt, ParseTask* parseTask); - - void trace(JSTracer* trc); - - JSScript* finishScriptParseTask( - JSContext* cx, JS::OffThreadToken* token, - StartEncoding startEncoding = StartEncoding::No); - JSScript* finishScriptDecodeTask(JSContext* cx, JS::OffThreadToken* token); - bool finishMultiScriptsDecodeTask(JSContext* cx, JS::OffThreadToken* token, - MutableHandle scripts); - JSObject* finishModuleParseTask(JSContext* cx, JS::OffThreadToken* token); - - bool hasActiveThreads(const AutoLockHelperThreadState&); - void waitForAllThreads(); - void waitForAllThreadsLocked(AutoLockHelperThreadState&); - - bool checkTaskThreadLimit(ThreadType threadType, size_t maxThreads, - bool isMaster, - const AutoLockHelperThreadState& lock) const; - bool checkTaskThreadLimit(ThreadType threadType, size_t maxThreads, - const AutoLockHelperThreadState& lock) const { - return checkTaskThreadLimit(threadType, maxThreads, /* isMaster */ false, - lock); - } - - void triggerFreeUnusedMemory(); - - private: - /* Condvars for threads waiting/notifying each other. */ - js::ConditionVariable consumerWakeup; - js::ConditionVariable producerWakeup; - - js::ConditionVariable& whichWakeup(CondVar which) { - switch (which) { - case CONSUMER: - return consumerWakeup; - case PRODUCER: - return producerWakeup; - default: - MOZ_CRASH("Invalid CondVar in |whichWakeup|"); - } - } - - void dispatch(const AutoLockHelperThreadState& locked); - - public: - bool submitTask(wasm::UniqueTier2GeneratorTask task); - bool submitTask(wasm::CompileTask* task, wasm::CompileMode mode); - bool submitTask(UniquePtr task, - const AutoLockHelperThreadState& lock); - bool submitTask(jit::IonCompileTask* task, - const AutoLockHelperThreadState& locked); - bool submitTask(UniquePtr task, - const AutoLockHelperThreadState& locked); - bool submitTask(JSRuntime* rt, UniquePtr task, - const AutoLockHelperThreadState& locked); - bool submitTask(PromiseHelperTask* task); - bool submitTask(GCParallelTask* task, - const AutoLockHelperThreadState& locked); - void runTaskLocked(HelperThreadTask* task, AutoLockHelperThreadState& lock); -}; - -static inline GlobalHelperThreadState& HelperThreadState() { - extern GlobalHelperThreadState* gHelperThreadState; - - MOZ_ASSERT(gHelperThreadState); - return *gHelperThreadState; -} - -/* Individual helper thread, one allocated per core. */ -class HelperThread { - Thread thread; - - /* - * The profiling thread for this helper thread, which can be used to push - * and pop label frames. - * This field being non-null indicates that this thread has been registered - * and needs to be unregistered at shutdown. - */ - ProfilingStack* profilingStack = nullptr; - - /* - * Indicate to a thread that it should terminate itself. This is only read - * or written with the helper thread state lock held. - */ - bool terminate = false; - - public: - HelperThread(); - MOZ_MUST_USE bool init(); - - ThreadId threadId() { return thread.get_id(); } - - void setTerminate(const AutoLockHelperThreadState& lock); - void join(); - - static void ThreadMain(void* arg); - void threadLoop(); - - void ensureRegisteredWithProfiler(); - void unregisterWithProfilerIfNeeded(); - - private: - struct AutoProfilerLabel { - AutoProfilerLabel(HelperThread* helperThread, const char* label, - JS::ProfilingCategoryPair categoryPair); - ~AutoProfilerLabel(); - - private: - ProfilingStack* profilingStack; - }; - - using Selector = HelperThreadTask* ( - GlobalHelperThreadState::*)(const AutoLockHelperThreadState&); - static const Selector selectors[]; - - HelperThreadTask* findHighestPriorityTask( - const AutoLockHelperThreadState& locked); -}; - -struct MOZ_RAII AutoSetHelperThreadContext { - JSContext* cx; - explicit AutoSetHelperThreadContext(); - ~AutoSetHelperThreadContext() { - AutoLockHelperThreadState lock; - cx->tempLifoAlloc().releaseAll(); - if (cx->shouldFreeUnusedMemory()) { - cx->tempLifoAlloc().freeAll(); - cx->setFreeUnusedMemory(false); - } - cx->clearHelperThread(lock); - cx = nullptr; - } -}; - -struct MOZ_RAII AutoSetContextRuntime { - explicit AutoSetContextRuntime(JSRuntime* rt) { - TlsContext.get()->setRuntime(rt); - } - ~AutoSetContextRuntime() { TlsContext.get()->setRuntime(nullptr); } -}; - -struct ParseTask : public mozilla::LinkedListElement, - public JS::OffThreadToken, - public HelperThreadTask { - ParseTaskKind kind; - JS::OwningCompileOptions options; - - // HelperThreads are shared between all runtimes in the process so explicitly - // track which one we are associated with. - JSRuntime* runtime = nullptr; - - // The global object to use while parsing. - JSObject* parseGlobal; - - // Callback invoked off thread when the parse finishes. - JS::OffThreadCompileCallback callback; - void* callbackData; - - // Holds the final scripts between the invocation of the callback and the - // point where FinishOffThreadScript is called, which will destroy the - // ParseTask. - GCVector scripts; - - // Holds the ScriptSourceObjects generated for the script compilation. - GCVector sourceObjects; - - // Holds the CompilationInfo generated for the script compilation. - UniquePtr compilationInfo_; - - // Any errors or warnings produced during compilation. These are reported - // when finishing the script. - Vector, 0, SystemAllocPolicy> errors; - bool overRecursed; - bool outOfMemory; - - ParseTask(ParseTaskKind kind, JSContext* cx, - JS::OffThreadCompileCallback callback, void* callbackData); - virtual ~ParseTask(); - - bool init(JSContext* cx, const JS::ReadOnlyCompileOptions& options, - JSObject* global); - - void activate(JSRuntime* rt); - virtual void parse(JSContext* cx) = 0; - bool instantiateStencils(JSContext* cx); - - bool runtimeMatches(JSRuntime* rt) { return runtime == rt; } - - void trace(JSTracer* trc); - - size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const; - size_t sizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const { - return mallocSizeOf(this) + sizeOfExcludingThis(mallocSizeOf); - } - - void runHelperThreadTask(AutoLockHelperThreadState& locked) override; - void runTask(); - ThreadType threadType() override { return ThreadType::THREAD_TYPE_PARSE; } -}; - -struct ScriptDecodeTask : public ParseTask { - const JS::TranscodeRange range; - - ScriptDecodeTask(JSContext* cx, const JS::TranscodeRange& range, - JS::OffThreadCompileCallback callback, void* callbackData); - void parse(JSContext* cx) override; -}; - -struct MultiScriptsDecodeTask : public ParseTask { - JS::TranscodeSources* sources; - - MultiScriptsDecodeTask(JSContext* cx, JS::TranscodeSources& sources, - JS::OffThreadCompileCallback callback, - void* callbackData); - void parse(JSContext* cx) override; -}; - -// It is not desirable to eagerly compress: if lazy functions that are tied to -// the ScriptSource were to be executed relatively soon after parsing, they -// would need to block on decompression, which hurts responsiveness. -// -// To this end, compression tasks are heap allocated and enqueued in a pending -// list by ScriptSource::setSourceCopy. When a major GC occurs, we schedule -// pending compression tasks and move the ones that are ready to be compressed -// to the worklist. Currently, a compression task is considered ready 2 major -// GCs after being enqueued. Completed tasks are handled during the sweeping -// phase by AttachCompressedSourcesTask, which runs in parallel with other GC -// sweeping tasks. -class SourceCompressionTask : public HelperThreadTask { - friend class HelperThread; - friend class ScriptSource; - - // The runtime that the ScriptSource is associated with, in the sense that - // it uses the runtime's immutable string cache. - JSRuntime* runtime_; - - // The major GC number of the runtime when the task was enqueued. - uint64_t majorGCNumber_; - - // The source to be compressed. - ScriptSourceHolder sourceHolder_; - - // The resultant compressed string. If the compressed string is larger - // than the original, or we OOM'd during compression, or nothing else - // except the task is holding the ScriptSource alive when scheduled to - // compress, this will remain None upon completion. - mozilla::Maybe resultString_; - - public: - // The majorGCNumber is used for scheduling tasks. - SourceCompressionTask(JSRuntime* rt, ScriptSource* source) - : runtime_(rt), - majorGCNumber_(rt->gc.majorGCCount()), - sourceHolder_(source) {} - virtual ~SourceCompressionTask() = default; - - bool runtimeMatches(JSRuntime* runtime) const { return runtime == runtime_; } - bool shouldStart() const { - // We wait 2 major GCs to start compressing, in order to avoid - // immediate compression. - return runtime_->gc.majorGCCount() > majorGCNumber_ + 1; - } - - bool shouldCancel() const { - // If the refcount is exactly 1, then nothing else is holding on to the - // ScriptSource, so no reason to compress it and we should cancel the task. - return sourceHolder_.get()->refs == 1; - } - - void runTask(); - void runHelperThreadTask(AutoLockHelperThreadState& locked) override; - void complete(); - - ThreadType threadType() override { return ThreadType::THREAD_TYPE_COMPRESS; } - - private: - struct PerformTaskWork; - friend struct PerformTaskWork; - - // The work algorithm, aware whether it's compressing one-byte UTF-8 source - // text or UTF-16, for CharT either Utf8Unit or char16_t. Invoked by - // work() after doing a type-test of the ScriptSource*. - template - void workEncodingSpecific(); -}; - -// A PromiseHelperTask is an OffThreadPromiseTask that executes a single job on -// a helper thread. Call js::StartOffThreadPromiseHelperTask to submit a -// PromiseHelperTask for execution. -// -// Concrete subclasses must implement execute and OffThreadPromiseTask::resolve. -// The helper thread will call execute() to do the main work. Then, the thread -// of the JSContext used to create the PromiseHelperTask will call resolve() to -// resolve promise according to those results. -struct PromiseHelperTask : OffThreadPromiseTask, public HelperThreadTask { - PromiseHelperTask(JSContext* cx, Handle promise) - : OffThreadPromiseTask(cx, promise) {} - - // To be called on a helper thread and implemented by the derived class. - virtual void execute() = 0; - - // May be called in the absence of helper threads or off-thread promise - // support to synchronously execute and resolve a PromiseTask. - // - // Warning: After this function returns, 'this' can be deleted at any time, so - // the caller must immediately return from the stream callback. - void executeAndResolveAndDestroy(JSContext* cx); - - void runHelperThreadTask(AutoLockHelperThreadState& locked) override; - ThreadType threadType() override { return THREAD_TYPE_PROMISE_TASK; } -}; - -} /* namespace js */ - -#endif /* vm_HelperThreadState_h */ diff --git a/js/src/vm/HelperThreads.cpp b/js/src/vm/HelperThreads.cpp index f6021a7151cb..af48912d36a0 100644 --- a/js/src/vm/HelperThreads.cpp +++ b/js/src/vm/HelperThreads.cpp @@ -26,8 +26,6 @@ #include "threading/CpuCount.h" #include "util/NativeStack.h" #include "vm/ErrorReporting.h" -#include "vm/HelperThreadState.h" -#include "vm/MutexIDs.h" #include "vm/SharedImmutableStringsCache.h" #include "vm/Time.h" #include "vm/TraceLogging.h" @@ -55,7 +53,6 @@ using JS::ReadOnlyCompileOptions; namespace js { -Mutex gHelperThreadLock(mutexid::GlobalHelperThreadState); GlobalHelperThreadState* gHelperThreadState = nullptr; } // namespace js @@ -150,16 +147,6 @@ bool GlobalHelperThreadState::submitTask(wasm::CompileTask* task, return true; } -size_t js::RemovePendingWasmCompileTasks( - const wasm::CompileTaskState& taskState, wasm::CompileMode mode, - const AutoLockHelperThreadState& lock) { - wasm::CompileTaskPtrFifo& worklist = - HelperThreadState().wasmWorklist(lock, mode); - return worklist.eraseIf([&taskState](wasm::CompileTask* task) { - return &task->state == &taskState; - }); -} - void js::StartOffThreadWasmTier2Generator(wasm::UniqueTier2GeneratorTask task) { Unused << HelperThreadState().submitTask(std::move(task)); } @@ -1250,7 +1237,8 @@ GlobalHelperThreadState::GlobalHelperThreadState() totalCountRunningTasks(0), registerThread(nullptr), unregisterThread(nullptr), - wasmTier2GeneratorsFinished_(0) { + wasmTier2GeneratorsFinished_(0), + helperLock(mutexid::GlobalHelperThreadState) { cpuCount = ClampDefaultCPUCount(GetCPUCount()); threadCount = ThreadCountForCPUCount(cpuCount); gcParallelThreadCount = threadCount; @@ -1339,7 +1327,7 @@ void GlobalHelperThreadState::destroyHelperContexts( #ifdef DEBUG bool GlobalHelperThreadState::isLockedByCurrentThread() const { - return gHelperThreadLock.ownedByCurrentThread(); + return helperLock.ownedByCurrentThread(); } #endif // DEBUG @@ -1369,12 +1357,6 @@ bool GlobalHelperThreadState::hasActiveThreads( return !helperTasks(lock).empty(); } -void js::WaitForAllHelperThreads() { HelperThreadState().waitForAllThreads(); } - -void js::WaitForAllHelperThreads(AutoLockHelperThreadState& lock) { - HelperThreadState().waitForAllThreadsLocked(lock); -} - void GlobalHelperThreadState::waitForAllThreads() { AutoLockHelperThreadState lock; waitForAllThreadsLocked(lock); diff --git a/js/src/vm/HelperThreads.h b/js/src/vm/HelperThreads.h index ca5ff8b060aa..af8af4a23540 100644 --- a/js/src/vm/HelperThreads.h +++ b/js/src/vm/HelperThreads.h @@ -5,65 +5,496 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* - * API for managing off-thread work. + * Definitions for managing off-thread work using a process wide list + * of worklist items and pool of threads. Worklist items are engine internal, + * and are distinct from e.g. web workers. */ #ifndef vm_HelperThreads_h #define vm_HelperThreads_h -#include "NamespaceImports.h" +#include "mozilla/Attributes.h" +#include "mozilla/EnumeratedArray.h" +#include "mozilla/PodOperations.h" +#include "mozilla/TimeStamp.h" +#include "mozilla/Utf8.h" // mozilla::Utf8Unit -#include "js/OffThreadScriptCompilation.h" -#include "js/UniquePtr.h" -#include "threading/LockGuard.h" -#include "threading/Mutex.h" -#include "wasm/WasmConstants.h" +#include "jsapi.h" + +#include "ds/Fifo.h" +#include "frontend/CompilationInfo.h" // frontend::CompilationInfo +#include "jit/JitContext.h" +#include "js/CompileOptions.h" +#include "js/shadow/Zone.h" // JS::shadow::Zone::GCState +#include "js/SourceText.h" +#include "js/TypeDecls.h" +#include "threading/ConditionVariable.h" +#include "threading/Thread.h" +#include "vm/HelperThreadTask.h" +#include "vm/JSContext.h" +#include "vm/MutexIDs.h" +#include "vm/OffThreadPromiseRuntimeState.h" // js::OffThreadPromiseTask +#include "vm/PromiseObject.h" // js::PromiseObject namespace JS { class OffThreadToken {}; -class ReadOnlyCompileOptions; -class Zone; } // namespace JS namespace js { class AutoLockHelperThreadState; +class AutoUnlockHelperThreadState; +class CompileError; +struct ParseTask; struct PromiseHelperTask; -class SourceCompressionTask; namespace jit { class IonCompileTask; class IonFreeTask; } // namespace jit - namespace wasm { -struct CompileTask; -struct CompileTaskState; struct Tier2GeneratorTask; -using UniqueTier2GeneratorTask = UniquePtr; } // namespace wasm -/* - * Lock protecting all mutable shared state accessed by helper threads, and used - * by all condition variables. - */ -extern Mutex gHelperThreadLock; +enum class ParseTaskKind { Script, Module, ScriptDecode, MultiScriptsDecode }; +enum class StartEncoding { No, Yes }; -class MOZ_RAII AutoLockHelperThreadState : public LockGuard { - using Base = LockGuard; +namespace wasm { - public: - explicit AutoLockHelperThreadState() : Base(gHelperThreadLock) {} +struct CompileTask; +typedef Fifo CompileTaskPtrFifo; + +struct Tier2GeneratorTask : public HelperThreadTask { + virtual ~Tier2GeneratorTask() = default; + virtual void cancel() = 0; }; -class MOZ_RAII AutoUnlockHelperThreadState : public UnlockGuard { - using Base = UnlockGuard; +using UniqueTier2GeneratorTask = UniquePtr; +typedef Vector + Tier2GeneratorTaskPtrVector; + +} // namespace wasm + +// Per-process state for off thread work items. +class GlobalHelperThreadState { + friend class AutoLockHelperThreadState; + friend class AutoUnlockHelperThreadState; public: - explicit AutoUnlockHelperThreadState(AutoLockHelperThreadState& locked) - : Base(locked) {} + // A single tier-2 ModuleGenerator job spawns many compilation jobs, and we + // do not want to allow more than one such ModuleGenerator to run at a time. + static const size_t MaxTier2GeneratorTasks = 1; + + // Number of CPUs to treat this machine as having when creating threads. + // May be accessed without locking. + size_t cpuCount; + + // Number of threads to create. May be accessed without locking. + size_t threadCount; + + typedef Vector + IonCompileTaskVector; + using IonFreeTaskVector = + Vector, 0, SystemAllocPolicy>; + typedef Vector, 0, SystemAllocPolicy> ParseTaskVector; + using ParseTaskList = mozilla::LinkedList; + typedef Vector, 0, SystemAllocPolicy> + SourceCompressionTaskVector; + using GCParallelTaskList = mozilla::LinkedList; + typedef Vector + PromiseHelperTaskVector; + typedef Vector ContextVector; + using HelperThreadVector = + Vector, 0, SystemAllocPolicy>; + + // Count of running task by each threadType. + mozilla::EnumeratedArray + runningTaskCount; + size_t totalCountRunningTasks; + + WriteOnceData registerThread; + WriteOnceData unregisterThread; + + private: + // The lists below are all protected by |lock|. + + // List of available helper threads. + HelperThreadVector threads_; + + // Ion compilation worklist and finished jobs. + IonCompileTaskVector ionWorklist_, ionFinishedList_; + IonFreeTaskVector ionFreeList_; + + // wasm worklists. + wasm::CompileTaskPtrFifo wasmWorklist_tier1_; + wasm::CompileTaskPtrFifo wasmWorklist_tier2_; + wasm::Tier2GeneratorTaskPtrVector wasmTier2GeneratorWorklist_; + + // Count of finished Tier2Generator tasks. + uint32_t wasmTier2GeneratorsFinished_; + + // Async tasks that, upon completion, are dispatched back to the JSContext's + // owner thread via embedding callbacks instead of a finished list. + PromiseHelperTaskVector promiseHelperTasks_; + + // Script parsing/emitting worklist and finished jobs. + ParseTaskVector parseWorklist_; + ParseTaskList parseFinishedList_; + + // Parse tasks waiting for an atoms-zone GC to complete. + ParseTaskVector parseWaitingOnGC_; + + // Source compression worklist of tasks that we do not yet know can start. + SourceCompressionTaskVector compressionPendingList_; + + // Source compression worklist of tasks that can start. + SourceCompressionTaskVector compressionWorklist_; + + // Finished source compression tasks. + SourceCompressionTaskVector compressionFinishedList_; + + // GC tasks needing to be done in parallel. + GCParallelTaskList gcParallelWorklist_; + size_t gcParallelThreadCount; + + // Global list of JSContext for GlobalHelperThreadState to use. + ContextVector helperContexts_; + + using HelperThreadTaskVector = + Vector; + // Vector of running HelperThreadTask. + // This is used to get the HelperThreadTask that are currently running. + HelperThreadTaskVector helperTasks_; + + ParseTask* removeFinishedParseTask(ParseTaskKind kind, + JS::OffThreadToken* token); + + public: + void addSizeOfIncludingThis(JS::GlobalStats* stats, + AutoLockHelperThreadState& lock) const; + + size_t maxIonCompilationThreads() const; + size_t maxWasmCompilationThreads() const; + size_t maxWasmTier2GeneratorThreads() const; + size_t maxPromiseHelperThreads() const; + size_t maxParseThreads() const; + size_t maxCompressionThreads() const; + size_t maxGCParallelThreads(const AutoLockHelperThreadState& lock) const; + + GlobalHelperThreadState(); + + HelperThreadVector& threads(const AutoLockHelperThreadState& lock) { + return threads_; + } + const HelperThreadVector& threads( + const AutoLockHelperThreadState& lock) const { + return threads_; + } + + bool ensureInitialized(); + bool ensureThreadCount(size_t count); + void finish(); + void finishThreads(); + + MOZ_MUST_USE bool ensureContextList(size_t count); + JSContext* getFirstUnusedContext(AutoLockHelperThreadState& locked); + void destroyHelperContexts(AutoLockHelperThreadState& lock); + +#ifdef DEBUG + bool isLockedByCurrentThread() const; +#endif + + enum CondVar { + // For notifying threads waiting for work that they may be able to make + // progress, ie, a work item has been completed by a helper thread and + // the thread that created the work item can now consume it. + CONSUMER, + + // For notifying helper threads doing the work that they may be able to + // make progress, ie, a work item has been enqueued and an idle helper + // thread may pick up up the work item and perform it. + PRODUCER, + }; + + void wait(AutoLockHelperThreadState& locked, CondVar which, + mozilla::TimeDuration timeout = mozilla::TimeDuration::Forever()); + void notifyAll(CondVar which, const AutoLockHelperThreadState&); + + private: + void notifyOne(CondVar which, const AutoLockHelperThreadState&); + + public: + // Helper method for removing items from the vectors below while iterating + // over them. + template + void remove(T& vector, size_t* index) { + // Self-moving is undefined behavior. + if (*index != vector.length() - 1) { + vector[*index] = std::move(vector.back()); + } + (*index)--; + vector.popBack(); + } + + IonCompileTaskVector& ionWorklist(const AutoLockHelperThreadState&) { + return ionWorklist_; + } + IonCompileTaskVector& ionFinishedList(const AutoLockHelperThreadState&) { + return ionFinishedList_; + } + IonFreeTaskVector& ionFreeList(const AutoLockHelperThreadState&) { + return ionFreeList_; + } + + wasm::CompileTaskPtrFifo& wasmWorklist(const AutoLockHelperThreadState&, + wasm::CompileMode m) { + switch (m) { + case wasm::CompileMode::Once: + case wasm::CompileMode::Tier1: + return wasmWorklist_tier1_; + case wasm::CompileMode::Tier2: + return wasmWorklist_tier2_; + default: + MOZ_CRASH(); + } + } + + wasm::Tier2GeneratorTaskPtrVector& wasmTier2GeneratorWorklist( + const AutoLockHelperThreadState&) { + return wasmTier2GeneratorWorklist_; + } + + void incWasmTier2GeneratorsFinished(const AutoLockHelperThreadState&) { + wasmTier2GeneratorsFinished_++; + } + + uint32_t wasmTier2GeneratorsFinished(const AutoLockHelperThreadState&) const { + return wasmTier2GeneratorsFinished_; + } + + PromiseHelperTaskVector& promiseHelperTasks( + const AutoLockHelperThreadState&) { + return promiseHelperTasks_; + } + + ParseTaskVector& parseWorklist(const AutoLockHelperThreadState&) { + return parseWorklist_; + } + ParseTaskList& parseFinishedList(const AutoLockHelperThreadState&) { + return parseFinishedList_; + } + ParseTaskVector& parseWaitingOnGC(const AutoLockHelperThreadState&) { + return parseWaitingOnGC_; + } + + SourceCompressionTaskVector& compressionPendingList( + const AutoLockHelperThreadState&) { + return compressionPendingList_; + } + + SourceCompressionTaskVector& compressionWorklist( + const AutoLockHelperThreadState&) { + return compressionWorklist_; + } + + SourceCompressionTaskVector& compressionFinishedList( + const AutoLockHelperThreadState&) { + return compressionFinishedList_; + } + + GCParallelTaskList& gcParallelWorklist(const AutoLockHelperThreadState&) { + return gcParallelWorklist_; + } + + void setGCParallelThreadCount(size_t count, + const AutoLockHelperThreadState&) { + MOZ_ASSERT(count >= 1); + MOZ_ASSERT(count <= threadCount); + gcParallelThreadCount = count; + } + + HelperThreadTaskVector& helperTasks(const AutoLockHelperThreadState&) { + return helperTasks_; + } + + HelperThreadTask* maybeGetWasmCompile(const AutoLockHelperThreadState& lock, + wasm::CompileMode mode); + + HelperThreadTask* maybeGetWasmTier1CompileTask( + const AutoLockHelperThreadState& lock); + HelperThreadTask* maybeGetWasmTier2CompileTask( + const AutoLockHelperThreadState& lock); + HelperThreadTask* maybeGetWasmTier2GeneratorTask( + const AutoLockHelperThreadState& lock); + HelperThreadTask* maybeGetPromiseHelperTask( + const AutoLockHelperThreadState& lock); + HelperThreadTask* maybeGetIonCompileTask( + const AutoLockHelperThreadState& lock); + HelperThreadTask* maybeGetIonFreeTask(const AutoLockHelperThreadState& lock); + HelperThreadTask* maybeGetParseTask(const AutoLockHelperThreadState& lock); + HelperThreadTask* maybeGetCompressionTask( + const AutoLockHelperThreadState& lock); + HelperThreadTask* maybeGetGCParallelTask( + const AutoLockHelperThreadState& lock); + + enum class ScheduleCompressionTask { GC, API }; + + // Used by a major GC to signal processing enqueued compression tasks. + void startHandlingCompressionTasks(const AutoLockHelperThreadState&, + ScheduleCompressionTask schedule); + + jit::IonCompileTask* highestPriorityPendingIonCompile( + const AutoLockHelperThreadState& lock); + + private: + void scheduleCompressionTasks(const AutoLockHelperThreadState&, + ScheduleCompressionTask schedule); + + UniquePtr finishParseTaskCommon(JSContext* cx, ParseTaskKind kind, + JS::OffThreadToken* token); + + JSScript* finishSingleParseTask( + JSContext* cx, ParseTaskKind kind, JS::OffThreadToken* token, + StartEncoding startEncoding = StartEncoding::No); + bool generateLCovSources(JSContext* cx, ParseTask* parseTask); + bool finishMultiParseTask(JSContext* cx, ParseTaskKind kind, + JS::OffThreadToken* token, + MutableHandle scripts); + + void mergeParseTaskRealm(JSContext* cx, ParseTask* parseTask, + JS::Realm* dest); + + public: + void cancelParseTask(JSRuntime* rt, ParseTaskKind kind, + JS::OffThreadToken* token); + void destroyParseTask(JSRuntime* rt, ParseTask* parseTask); + + void trace(JSTracer* trc); + + JSScript* finishScriptParseTask( + JSContext* cx, JS::OffThreadToken* token, + StartEncoding startEncoding = StartEncoding::No); + JSScript* finishScriptDecodeTask(JSContext* cx, JS::OffThreadToken* token); + bool finishMultiScriptsDecodeTask(JSContext* cx, JS::OffThreadToken* token, + MutableHandle scripts); + JSObject* finishModuleParseTask(JSContext* cx, JS::OffThreadToken* token); + + bool hasActiveThreads(const AutoLockHelperThreadState&); + void waitForAllThreads(); + void waitForAllThreadsLocked(AutoLockHelperThreadState&); + + bool checkTaskThreadLimit(ThreadType threadType, size_t maxThreads, + bool isMaster, + const AutoLockHelperThreadState& lock) const; + bool checkTaskThreadLimit(ThreadType threadType, size_t maxThreads, + const AutoLockHelperThreadState& lock) const { + return checkTaskThreadLimit(threadType, maxThreads, /* isMaster */ false, + lock); + } + + void triggerFreeUnusedMemory(); + + private: + /* + * Lock protecting all mutable shared state accessed by helper threads, and + * used by all condition variables. + */ + js::Mutex helperLock; + + /* Condvars for threads waiting/notifying each other. */ + js::ConditionVariable consumerWakeup; + js::ConditionVariable producerWakeup; + + js::ConditionVariable& whichWakeup(CondVar which) { + switch (which) { + case CONSUMER: + return consumerWakeup; + case PRODUCER: + return producerWakeup; + default: + MOZ_CRASH("Invalid CondVar in |whichWakeup|"); + } + } + + void dispatch(const AutoLockHelperThreadState& locked); + + public: + bool submitTask(wasm::UniqueTier2GeneratorTask task); + bool submitTask(wasm::CompileTask* task, wasm::CompileMode mode); + bool submitTask(UniquePtr task, + const AutoLockHelperThreadState& lock); + bool submitTask(jit::IonCompileTask* task, + const AutoLockHelperThreadState& locked); + bool submitTask(UniquePtr task, + const AutoLockHelperThreadState& locked); + bool submitTask(JSRuntime* rt, UniquePtr task, + const AutoLockHelperThreadState& locked); + bool submitTask(PromiseHelperTask* task); + bool submitTask(GCParallelTask* task, + const AutoLockHelperThreadState& locked); + void runTaskLocked(HelperThreadTask* task, AutoLockHelperThreadState& lock); }; +static inline GlobalHelperThreadState& HelperThreadState() { + extern GlobalHelperThreadState* gHelperThreadState; + + MOZ_ASSERT(gHelperThreadState); + return *gHelperThreadState; +} + +/* Individual helper thread, one allocated per core. */ +class HelperThread { + Thread thread; + + /* + * The profiling thread for this helper thread, which can be used to push + * and pop label frames. + * This field being non-null indicates that this thread has been registered + * and needs to be unregistered at shutdown. + */ + ProfilingStack* profilingStack = nullptr; + + /* + * Indicate to a thread that it should terminate itself. This is only read + * or written with the helper thread state lock held. + */ + bool terminate = false; + + public: + HelperThread(); + MOZ_MUST_USE bool init(); + + ThreadId threadId() { return thread.get_id(); } + + void setTerminate(const AutoLockHelperThreadState& lock); + void join(); + + static void ThreadMain(void* arg); + void threadLoop(); + + void ensureRegisteredWithProfiler(); + void unregisterWithProfilerIfNeeded(); + + private: + struct AutoProfilerLabel { + AutoProfilerLabel(HelperThread* helperThread, const char* label, + JS::ProfilingCategoryPair categoryPair); + ~AutoProfilerLabel(); + + private: + ProfilingStack* profilingStack; + }; + + using Selector = HelperThreadTask* ( + GlobalHelperThreadState::*)(const AutoLockHelperThreadState&); + static const Selector selectors[]; + + HelperThreadTask* findHighestPriorityTask( + const AutoLockHelperThreadState& locked); +}; + +/* Methods for interacting with helper threads. */ + // Create data structures used by helper threads. bool CreateHelperThreadsState(); @@ -80,13 +511,6 @@ bool SetFakeCPUCount(size_t count); // Enqueues a wasm compilation task. bool StartOffThreadWasmCompile(wasm::CompileTask* task, wasm::CompileMode mode); -// Remove any pending wasm compilation tasks queued with -// StartOffThreadWasmCompile that match the arguments. Return the number -// removed. -size_t RemovePendingWasmCompileTasks(const wasm::CompileTaskState& taskState, - wasm::CompileMode mode, - const AutoLockHelperThreadState& lock); - // Enqueues a wasm compilation task. void StartOffThreadWasmTier2Generator(wasm::UniqueTier2GeneratorTask task); @@ -139,7 +563,7 @@ struct CompilationsUsingNursery { }; using CompilationSelector = - mozilla::Variant; /* @@ -155,7 +579,7 @@ inline void CancelOffThreadIonCompile(JS::Realm* realm) { CancelOffThreadIonCompile(CompilationSelector(realm)); } -inline void CancelOffThreadIonCompile(JS::Zone* zone) { +inline void CancelOffThreadIonCompile(Zone* zone) { CancelOffThreadIonCompile(CompilationSelector(zone)); } @@ -229,9 +653,6 @@ bool StartOffThreadDecodeMultiScripts(JSContext* cx, */ void EnqueuePendingParseTasksAfterGC(JSRuntime* rt); -void WaitForAllHelperThreads(); -void WaitForAllHelperThreads(AutoLockHelperThreadState& lock); - struct AutoEnqueuePendingParseTasksAfterGC { const gc::GCRuntime& gc_; explicit AutoEnqueuePendingParseTasksAfterGC(const gc::GCRuntime& gc) @@ -253,10 +674,218 @@ void AttachFinishedCompressions(JSRuntime* runtime, // Run all pending source compression tasks synchronously, for testing purposes void RunPendingSourceCompressions(JSRuntime* runtime); +class MOZ_RAII AutoLockHelperThreadState : public LockGuard { + using Base = LockGuard; + + public: + explicit AutoLockHelperThreadState() : Base(HelperThreadState().helperLock) {} +}; + +class MOZ_RAII AutoUnlockHelperThreadState : public UnlockGuard { + using Base = UnlockGuard; + + public: + explicit AutoUnlockHelperThreadState(AutoLockHelperThreadState& locked) + : Base(locked) {} +}; + +struct MOZ_RAII AutoSetHelperThreadContext { + JSContext* cx; + explicit AutoSetHelperThreadContext(); + ~AutoSetHelperThreadContext() { + AutoLockHelperThreadState lock; + cx->tempLifoAlloc().releaseAll(); + if (cx->shouldFreeUnusedMemory()) { + cx->tempLifoAlloc().freeAll(); + cx->setFreeUnusedMemory(false); + } + cx->clearHelperThread(lock); + cx = nullptr; + } +}; + +struct MOZ_RAII AutoSetContextRuntime { + explicit AutoSetContextRuntime(JSRuntime* rt) { + TlsContext.get()->setRuntime(rt); + } + ~AutoSetContextRuntime() { TlsContext.get()->setRuntime(nullptr); } +}; + +struct ParseTask : public mozilla::LinkedListElement, + public JS::OffThreadToken, + public HelperThreadTask { + ParseTaskKind kind; + JS::OwningCompileOptions options; + + // HelperThreads are shared between all runtimes in the process so explicitly + // track which one we are associated with. + JSRuntime* runtime = nullptr; + + // The global object to use while parsing. + JSObject* parseGlobal; + + // Callback invoked off thread when the parse finishes. + JS::OffThreadCompileCallback callback; + void* callbackData; + + // Holds the final scripts between the invocation of the callback and the + // point where FinishOffThreadScript is called, which will destroy the + // ParseTask. + GCVector scripts; + + // Holds the ScriptSourceObjects generated for the script compilation. + GCVector sourceObjects; + + // Holds the CompilationInfo generated for the script compilation. + UniquePtr compilationInfo_; + + // Any errors or warnings produced during compilation. These are reported + // when finishing the script. + Vector, 0, SystemAllocPolicy> errors; + bool overRecursed; + bool outOfMemory; + + ParseTask(ParseTaskKind kind, JSContext* cx, + JS::OffThreadCompileCallback callback, void* callbackData); + virtual ~ParseTask(); + + bool init(JSContext* cx, const JS::ReadOnlyCompileOptions& options, + JSObject* global); + + void activate(JSRuntime* rt); + virtual void parse(JSContext* cx) = 0; + bool instantiateStencils(JSContext* cx); + + bool runtimeMatches(JSRuntime* rt) { return runtime == rt; } + + void trace(JSTracer* trc); + + size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const; + size_t sizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const { + return mallocSizeOf(this) + sizeOfExcludingThis(mallocSizeOf); + } + + void runHelperThreadTask(AutoLockHelperThreadState& locked) override; + void runTask(); + ThreadType threadType() override { return ThreadType::THREAD_TYPE_PARSE; } +}; + +struct ScriptDecodeTask : public ParseTask { + const JS::TranscodeRange range; + + ScriptDecodeTask(JSContext* cx, const JS::TranscodeRange& range, + JS::OffThreadCompileCallback callback, void* callbackData); + void parse(JSContext* cx) override; +}; + +struct MultiScriptsDecodeTask : public ParseTask { + JS::TranscodeSources* sources; + + MultiScriptsDecodeTask(JSContext* cx, JS::TranscodeSources& sources, + JS::OffThreadCompileCallback callback, + void* callbackData); + void parse(JSContext* cx) override; +}; + // Return whether, if a new parse task was started, it would need to wait for // an in-progress GC to complete before starting. extern bool OffThreadParsingMustWaitForGC(JSRuntime* rt); -} // namespace js +// It is not desirable to eagerly compress: if lazy functions that are tied to +// the ScriptSource were to be executed relatively soon after parsing, they +// would need to block on decompression, which hurts responsiveness. +// +// To this end, compression tasks are heap allocated and enqueued in a pending +// list by ScriptSource::setSourceCopy. When a major GC occurs, we schedule +// pending compression tasks and move the ones that are ready to be compressed +// to the worklist. Currently, a compression task is considered ready 2 major +// GCs after being enqueued. Completed tasks are handled during the sweeping +// phase by AttachCompressedSourcesTask, which runs in parallel with other GC +// sweeping tasks. +class SourceCompressionTask : public HelperThreadTask { + friend class HelperThread; + friend class ScriptSource; + + // The runtime that the ScriptSource is associated with, in the sense that + // it uses the runtime's immutable string cache. + JSRuntime* runtime_; + + // The major GC number of the runtime when the task was enqueued. + uint64_t majorGCNumber_; + + // The source to be compressed. + ScriptSourceHolder sourceHolder_; + + // The resultant compressed string. If the compressed string is larger + // than the original, or we OOM'd during compression, or nothing else + // except the task is holding the ScriptSource alive when scheduled to + // compress, this will remain None upon completion. + mozilla::Maybe resultString_; + + public: + // The majorGCNumber is used for scheduling tasks. + SourceCompressionTask(JSRuntime* rt, ScriptSource* source) + : runtime_(rt), + majorGCNumber_(rt->gc.majorGCCount()), + sourceHolder_(source) {} + virtual ~SourceCompressionTask() = default; + + bool runtimeMatches(JSRuntime* runtime) const { return runtime == runtime_; } + bool shouldStart() const { + // We wait 2 major GCs to start compressing, in order to avoid + // immediate compression. + return runtime_->gc.majorGCCount() > majorGCNumber_ + 1; + } + + bool shouldCancel() const { + // If the refcount is exactly 1, then nothing else is holding on to the + // ScriptSource, so no reason to compress it and we should cancel the task. + return sourceHolder_.get()->refs == 1; + } + + void runTask(); + void runHelperThreadTask(AutoLockHelperThreadState& locked) override; + void complete(); + + ThreadType threadType() override { return ThreadType::THREAD_TYPE_COMPRESS; } + + private: + struct PerformTaskWork; + friend struct PerformTaskWork; + + // The work algorithm, aware whether it's compressing one-byte UTF-8 source + // text or UTF-16, for CharT either Utf8Unit or char16_t. Invoked by + // work() after doing a type-test of the ScriptSource*. + template + void workEncodingSpecific(); +}; + +// A PromiseHelperTask is an OffThreadPromiseTask that executes a single job on +// a helper thread. Call js::StartOffThreadPromiseHelperTask to submit a +// PromiseHelperTask for execution. +// +// Concrete subclasses must implement execute and OffThreadPromiseTask::resolve. +// The helper thread will call execute() to do the main work. Then, the thread +// of the JSContext used to create the PromiseHelperTask will call resolve() to +// resolve promise according to those results. +struct PromiseHelperTask : OffThreadPromiseTask, public HelperThreadTask { + PromiseHelperTask(JSContext* cx, Handle promise) + : OffThreadPromiseTask(cx, promise) {} + + // To be called on a helper thread and implemented by the derived class. + virtual void execute() = 0; + + // May be called in the absence of helper threads or off-thread promise + // support to synchronously execute and resolve a PromiseTask. + // + // Warning: After this function returns, 'this' can be deleted at any time, so + // the caller must immediately return from the stream callback. + void executeAndResolveAndDestroy(JSContext* cx); + + void runHelperThreadTask(AutoLockHelperThreadState& locked) override; + ThreadType threadType() override { return THREAD_TYPE_PROMISE_TASK; } +}; + +} /* namespace js */ #endif /* vm_HelperThreads_h */ diff --git a/js/src/vm/JSContext.cpp b/js/src/vm/JSContext.cpp index f7b6963fe9c4..823de263c36a 100644 --- a/js/src/vm/JSContext.cpp +++ b/js/src/vm/JSContext.cpp @@ -63,7 +63,7 @@ #include "vm/BytecodeUtil.h" // JSDVG_IGNORE_STACK #include "vm/ErrorObject.h" #include "vm/ErrorReporting.h" -#include "vm/HelperThreadState.h" +#include "vm/HelperThreads.h" #include "vm/Iteration.h" #include "vm/JSAtom.h" #include "vm/JSFunction.h" diff --git a/js/src/vm/JSScript-inl.h b/js/src/vm/JSScript-inl.h index 23d8e6c288f3..528cf3119f63 100644 --- a/js/src/vm/JSScript-inl.h +++ b/js/src/vm/JSScript-inl.h @@ -14,6 +14,7 @@ #include "jit/BaselineJIT.h" #include "jit/IonAnalysis.h" #include "jit/JitScript.h" +#include "vm/EnvironmentObject.h" #include "vm/RegExpObject.h" #include "wasm/AsmJS.h" diff --git a/js/src/vm/JSScript.cpp b/js/src/vm/JSScript.cpp index a2183289a73c..b845272ed1b7 100644 --- a/js/src/vm/JSScript.cpp +++ b/js/src/vm/JSScript.cpp @@ -59,7 +59,7 @@ #include "vm/BytecodeUtil.h" #include "vm/Compression.h" #include "vm/FunctionFlags.h" // js::FunctionFlags -#include "vm/HelperThreadState.h" // js::RunPendingSourceCompressions +#include "vm/HelperThreads.h" // js::RunPendingSourceCompressions #include "vm/JSAtom.h" #include "vm/JSContext.h" #include "vm/JSFunction.h" diff --git a/js/src/vm/MemoryMetrics.cpp b/js/src/vm/MemoryMetrics.cpp index 94fbc403ac5b..5a9a4e319598 100644 --- a/js/src/vm/MemoryMetrics.cpp +++ b/js/src/vm/MemoryMetrics.cpp @@ -16,7 +16,7 @@ #include "util/Text.h" #include "vm/ArrayObject.h" #include "vm/BigIntType.h" -#include "vm/HelperThreadState.h" +#include "vm/HelperThreads.h" #include "vm/JSObject.h" #include "vm/JSScript.h" #include "vm/Realm.h" diff --git a/js/src/vm/OffThreadPromiseRuntimeState.cpp b/js/src/vm/OffThreadPromiseRuntimeState.cpp index 9e097a71a94d..24acba8c9f8e 100644 --- a/js/src/vm/OffThreadPromiseRuntimeState.cpp +++ b/js/src/vm/OffThreadPromiseRuntimeState.cpp @@ -162,7 +162,7 @@ bool OffThreadPromiseRuntimeState::internalDispatchToEventLoop( OffThreadPromiseRuntimeState& state = *reinterpret_cast(closure); MOZ_ASSERT(state.usingInternalDispatchQueue()); - MOZ_ASSERT(gHelperThreadLock.ownedByCurrentThread()); + MOZ_ASSERT(HelperThreadState().isLockedByCurrentThread()); if (state.internalDispatchQueueClosed_) { return false; diff --git a/js/src/vm/OffThreadScriptCompilation.cpp b/js/src/vm/OffThreadScriptCompilation.cpp index 5e7442c79b39..d938780cb29a 100644 --- a/js/src/vm/OffThreadScriptCompilation.cpp +++ b/js/src/vm/OffThreadScriptCompilation.cpp @@ -17,8 +17,7 @@ #include "jstypes.h" // JS_PUBLIC_API #include "js/CompileOptions.h" // JS::ReadOnlyCompileOptions -#include "js/SourceText.h" // JS::SourceText -#include "vm/HelperThreadState.h" // js::OffThreadParsingMustWaitForGC, js::StartOffThreadParseScript +#include "vm/HelperThreads.h" // js::OffThreadParsingMustWaitForGC, js::StartOffThreadParseScript #include "vm/JSContext.h" // JSContext #include "vm/Runtime.h" // js::CanUseExtraThreads diff --git a/js/src/vm/UbiNode.cpp b/js/src/vm/UbiNode.cpp index d6978af745e3..b052d5831246 100644 --- a/js/src/vm/UbiNode.cpp +++ b/js/src/vm/UbiNode.cpp @@ -412,7 +412,7 @@ bool RootList::init(CompartmentSet& debuggees) { if (!tracer.okay) { return false; } - js::gc::TraceIncomingCCWs(&tracer, debuggees); + TraceIncomingCCWs(&tracer, debuggees); if (!tracer.okay) { return false; } diff --git a/js/src/vm/WindowProxy.cpp b/js/src/vm/WindowProxy.cpp index 460be974216b..95f25544c8ca 100644 --- a/js/src/vm/WindowProxy.cpp +++ b/js/src/vm/WindowProxy.cpp @@ -12,6 +12,7 @@ #include "jsapi.h" // js::AssertHeapIsIdle +#include "vm/EnvironmentObject.h" // js::LexicalEnvironmentObject #include "vm/GlobalObject.h" // js::GlobalObject #include "vm/JSContext.h" // JSContext, CHECK_THREAD #include "vm/JSObject.h" // JSObject diff --git a/js/src/vm/Xdr.cpp b/js/src/vm/Xdr.cpp index 19337dbc14cc..a85cee932ef5 100644 --- a/js/src/vm/Xdr.cpp +++ b/js/src/vm/Xdr.cpp @@ -17,9 +17,9 @@ #include "jsapi.h" -#include "builtin/ModuleObject.h" #include "debugger/DebugAPI.h" #include "js/BuildId.h" // JS::BuildIdCharVector +#include "vm/EnvironmentObject.h" #include "vm/JSContext.h" #include "vm/JSScript.h" #include "vm/TraceLogging.h" diff --git a/js/src/wasm/WasmBaselineCompile.cpp b/js/src/wasm/WasmBaselineCompile.cpp index 3da3a745fd4b..c96cfcb8eea8 100644 --- a/js/src/wasm/WasmBaselineCompile.cpp +++ b/js/src/wasm/WasmBaselineCompile.cpp @@ -118,6 +118,7 @@ #include "jit/IonTypes.h" #include "jit/JitAllocPolicy.h" #include "jit/Label.h" +#include "jit/MacroAssembler.h" #include "jit/MIR.h" #include "jit/RegisterAllocator.h" #include "jit/Registers.h" diff --git a/js/src/wasm/WasmCompile.cpp b/js/src/wasm/WasmCompile.cpp index 407b62cb8f36..1feb383ad12e 100644 --- a/js/src/wasm/WasmCompile.cpp +++ b/js/src/wasm/WasmCompile.cpp @@ -25,7 +25,6 @@ #include "jit/ProcessExecutableMemory.h" #include "util/Text.h" -#include "vm/HelperThreadState.h" #include "wasm/WasmBaselineCompile.h" #include "wasm/WasmCraneliftCompile.h" #include "wasm/WasmGenerator.h" diff --git a/js/src/wasm/WasmConstants.h b/js/src/wasm/WasmConstants.h index da77afd349e8..606be85a0d46 100644 --- a/js/src/wasm/WasmConstants.h +++ b/js/src/wasm/WasmConstants.h @@ -915,27 +915,6 @@ static const unsigned FailFP = 0xbad; static const unsigned MaxVarU32DecodedBytes = 5; -// Which backend to use in the case of the optimized tier. - -enum class OptimizedBackend { - Ion, - Cranelift, -}; - -// The CompileMode controls how compilation of a module is performed (notably, -// how many times we compile it). - -enum class CompileMode { Once, Tier1, Tier2 }; - -// Typed enum for whether debugging is enabled. - -enum class DebugEnabled { False, True }; - -// A wasm module can either use no memory, a unshared memory (ArrayBuffer) or -// shared memory (SharedArrayBuffer). - -enum class MemoryUsage { None = false, Unshared = 1, Shared = 2 }; - } // namespace wasm } // namespace js diff --git a/js/src/wasm/WasmGC.h b/js/src/wasm/WasmGC.h index 361c58542597..381a532e7548 100644 --- a/js/src/wasm/WasmGC.h +++ b/js/src/wasm/WasmGC.h @@ -19,19 +19,10 @@ #ifndef wasm_gc_h #define wasm_gc_h -#include "mozilla/BinarySearch.h" - -#include "jit/MacroAssembler.h" // For ABIArgIter -#include "js/AllocPolicy.h" -#include "js/Vector.h" +#include "jit/MacroAssembler.h" #include "util/Memory.h" namespace js { - -namespace jit { -class MacroAssembler; -} // namespace jit - namespace wasm { using namespace js::jit; @@ -236,8 +227,8 @@ class StackMaps { }; size_t result; - if (mozilla::BinarySearchIf(mapping_, 0, mapping_.length(), - Comparator(nextInsnAddr), &result)) { + if (BinarySearchIf(mapping_, 0, mapping_.length(), Comparator(nextInsnAddr), + &result)) { return mapping_[result].map; } diff --git a/js/src/wasm/WasmGenerator.cpp b/js/src/wasm/WasmGenerator.cpp index a4589f48972b..9de3ef86cf59 100644 --- a/js/src/wasm/WasmGenerator.cpp +++ b/js/src/wasm/WasmGenerator.cpp @@ -28,7 +28,6 @@ #include "util/Memory.h" #include "util/Text.h" -#include "vm/HelperThreadState.h" #include "vm/Time.h" #include "wasm/WasmBaselineCompile.h" #include "wasm/WasmCompile.h" @@ -109,7 +108,12 @@ ModuleGenerator::~ModuleGenerator() { AutoLockHelperThreadState lock; // Remove any pending compilation tasks from the worklist. - size_t removed = RemovePendingWasmCompileTasks(taskState_, mode(), lock); + CompileTaskPtrFifo& worklist = + HelperThreadState().wasmWorklist(lock, mode()); + auto pred = [this](CompileTask* task) { + return &task->state == &taskState_; + }; + size_t removed = worklist.eraseIf(pred); MOZ_ASSERT(outstanding_ >= removed); outstanding_ -= removed; diff --git a/js/src/wasm/WasmJS.cpp b/js/src/wasm/WasmJS.cpp index e8d74804deb2..252f8215a4d2 100644 --- a/js/src/wasm/WasmJS.cpp +++ b/js/src/wasm/WasmJS.cpp @@ -42,7 +42,6 @@ #include "vm/ErrorObject.h" #include "vm/FunctionFlags.h" // js::FunctionFlags #include "vm/GlobalObject.h" // js::GlobalObject -#include "vm/HelperThreadState.h" // js::PromiseHelperTask #include "vm/Interpreter.h" #include "vm/PlainObject.h" // js::PlainObject #include "vm/PromiseObject.h" // js::PromiseObject diff --git a/js/src/wasm/WasmModule.cpp b/js/src/wasm/WasmModule.cpp index 630777534e72..80b9782e5deb 100644 --- a/js/src/wasm/WasmModule.cpp +++ b/js/src/wasm/WasmModule.cpp @@ -26,7 +26,6 @@ #include "js/BuildId.h" // JS::BuildIdCharVector #include "js/experimental/TypedData.h" // JS_NewUint8Array #include "threading/LockGuard.h" -#include "vm/HelperThreadState.h" // Tier2GeneratorTask #include "vm/PlainObject.h" // js::PlainObject #include "wasm/WasmBaselineCompile.h" #include "wasm/WasmCompile.h" diff --git a/js/src/wasm/WasmTypes.h b/js/src/wasm/WasmTypes.h index d539f20464f4..35d94d4e7dfe 100644 --- a/js/src/wasm/WasmTypes.h +++ b/js/src/wasm/WasmTypes.h @@ -952,6 +952,27 @@ enum class Tier { Serialized = Optimized }; +// Which backend to use in the case of the optimized tier. + +enum class OptimizedBackend { + Ion, + Cranelift, +}; + +// The CompileMode controls how compilation of a module is performed (notably, +// how many times we compile it). + +enum class CompileMode { Once, Tier1, Tier2 }; + +// Typed enum for whether debugging is enabled. + +enum class DebugEnabled { False, True }; + +// A wasm module can either use no memory, a unshared memory (ArrayBuffer) or +// shared memory (SharedArrayBuffer). + +enum class MemoryUsage { None = false, Unshared = 1, Shared = 2 }; + // Iterator over tiers present in a tiered data structure. class Tiers {