BaselineCompileTask.h (5408B)
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/. */ 6 7 #ifndef jit_BaselineCompileTask_h 8 #define jit_BaselineCompileTask_h 9 10 #include "mozilla/LinkedList.h" 11 #include "mozilla/Maybe.h" 12 13 #include "jit/BaselineCodeGen.h" 14 #include "jit/JitScript.h" 15 #include "jit/OffthreadSnapshot.h" 16 #include "vm/HelperThreadTask.h" 17 18 namespace js::jit { 19 20 class BaselineSnapshot { 21 OffthreadGCPtr<JSScript*> script_; 22 OffthreadGCPtr<GlobalLexicalEnvironmentObject*> globalLexical_; 23 OffthreadGCPtr<JSObject*> globalThis_; 24 OffthreadGCPtr<CallObject*> callObjectTemplate_; 25 OffthreadGCPtr<NamedLambdaObject*> namedLambdaTemplate_; 26 size_t nargs_; 27 uint32_t baseWarmUpThreshold_; 28 bool isIonCompileable_; 29 bool compileDebugInstrumentation_; 30 31 public: 32 BaselineSnapshot(JSScript* script, 33 GlobalLexicalEnvironmentObject* globalLexical, 34 JSObject* globalThis, uint32_t baseWarmUpThreshold, 35 bool isIonCompileable, bool compileDebugInstrumentation) 36 : script_(script), 37 globalLexical_(globalLexical), 38 globalThis_(globalThis), 39 callObjectTemplate_(nullptr), 40 namedLambdaTemplate_(nullptr), 41 nargs_(script->function() ? script->function()->nargs() : 0), 42 baseWarmUpThreshold_(baseWarmUpThreshold), 43 isIonCompileable_(isIonCompileable), 44 compileDebugInstrumentation_(compileDebugInstrumentation) { 45 if (script->needsFunctionEnvironmentObjects()) { 46 auto [callObjectTemplate, namedLambdaTemplate] = 47 script->jitScript()->functionEnvironmentTemplates(script->function()); 48 callObjectTemplate_.init(callObjectTemplate); 49 namedLambdaTemplate_.init(namedLambdaTemplate); 50 } 51 } 52 53 JSScript* script() const { return script_; } 54 GlobalLexicalEnvironmentObject* globalLexical() const { 55 return globalLexical_; 56 } 57 JSObject* globalThis() const { return globalThis_; } 58 CallObject* callObjectTemplate() const { return callObjectTemplate_; } 59 NamedLambdaObject* namedLambdaTemplate() const { 60 return namedLambdaTemplate_; 61 } 62 size_t nargs() const { return nargs_; } 63 uint32_t baseWarmUpThreshold() const { return baseWarmUpThreshold_; } 64 bool isIonCompileable() const { return isIonCompileable_; } 65 bool compileDebugInstrumentation() const { 66 return compileDebugInstrumentation_; 67 } 68 void trace(JSTracer* trc); 69 }; 70 71 class OffThreadBaselineSnapshot 72 : public BaselineSnapshot, 73 public mozilla::LinkedListElement<OffThreadBaselineSnapshot> { 74 public: 75 OffThreadBaselineSnapshot(JSScript* script, 76 GlobalLexicalEnvironmentObject* globalLexical, 77 JSObject* globalThis, uint32_t baseWarmUpThreshold, 78 bool isIonCompileable, 79 bool compileDebugInstrumentation) 80 : BaselineSnapshot(script, globalLexical, globalThis, baseWarmUpThreshold, 81 isIonCompileable, compileDebugInstrumentation) {} 82 explicit OffThreadBaselineSnapshot(BaselineSnapshot other) 83 : BaselineSnapshot(other) {} 84 85 bool compileOffThread(TempAllocator& temp, CompileRealm* realm); 86 87 private: 88 mozilla::Maybe<OffThreadMacroAssembler> masm_; 89 mozilla::Maybe<BaselineCompiler> compiler_; 90 91 friend class BaselineCompileTask; 92 }; 93 94 using BaselineSnapshotList = mozilla::LinkedList<OffThreadBaselineSnapshot>; 95 96 class BaselineCompileTask final : public HelperThreadTask { 97 public: 98 BaselineCompileTask(CompileRealm* realm, LifoAlloc* alloc, 99 BaselineSnapshotList&& snapshots) 100 : realm_(realm), alloc_(alloc), snapshots_(std::move(snapshots)) { 101 #ifdef DEBUG 102 for (auto* snapshot : snapshots_) { 103 MOZ_ASSERT(CompileRealm::get(snapshot->script()->realm()) == realm); 104 } 105 #endif 106 } 107 108 static bool OffThreadBaselineCompilationAvailable(JSContext* cx, 109 JSScript* script, 110 bool isEager = false); 111 112 ThreadType threadType() override { return THREAD_TYPE_BASELINE; } 113 void runTask(); 114 void runHelperThreadTask(AutoLockHelperThreadState& locked) override; 115 116 void markScriptsAsCompiling(); 117 118 void finishOnMainThread(JSContext* cx); 119 120 JSRuntime* runtimeFromAnyThread() const { 121 return firstScript()->runtimeFromAnyThread(); 122 } 123 Zone* zoneFromAnyThread() const { return firstScript()->zoneFromAnyThread(); } 124 bool scriptMatches(JSScript* script) { 125 for (auto* snapshot : snapshots_) { 126 if (snapshot->script() == script) { 127 return true; 128 } 129 } 130 return false; 131 } 132 133 const char* getName() override { return "BaselineCompileTask"; } 134 135 void trace(JSTracer* trc); 136 137 static void FinishOffThreadTask(BaselineCompileTask* task); 138 139 bool failed() const { return failed_; } 140 141 private: 142 // All scripts are in the same realm, so we can use an arbitrary script 143 // to access the realm/zone/runtime. 144 JSScript* firstScript() const { return snapshots_.getFirst()->script(); } 145 146 CompileRealm* realm_; 147 LifoAlloc* alloc_; 148 BaselineSnapshotList snapshots_; 149 150 bool failed_ = false; 151 }; 152 153 } // namespace js::jit 154 155 #endif /* jit_BaselineCompileTask_h */