MIRGenerator.h (6194B)
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_MIRGenerator_h 8 #define jit_MIRGenerator_h 9 10 // This file declares the data structures used to build a control-flow graph 11 // containing MIR. 12 13 #include "mozilla/Assertions.h" 14 #include "mozilla/Atomics.h" 15 #include "mozilla/Attributes.h" 16 #include "mozilla/Result.h" 17 18 #include <stdarg.h> 19 #include <stddef.h> 20 #include <stdint.h> 21 22 #include "jit/CompilationDependencyTracker.h" 23 #include "jit/CompileInfo.h" 24 #include "jit/CompileWrappers.h" 25 #include "jit/JitAllocPolicy.h" 26 #include "jit/JitContext.h" 27 #include "jit/JitSpewer.h" 28 #include "jit/PerfSpewer.h" 29 #include "js/Utility.h" 30 #include "vm/GeckoProfiler.h" 31 32 namespace js { 33 namespace jit { 34 35 class BacktrackingAllocator; 36 class JitRuntime; 37 class MIRGraph; 38 class OptimizationInfo; 39 40 class MIRGenerator final { 41 public: 42 MIRGenerator(CompileRealm* realm, const JitCompileOptions& options, 43 TempAllocator* alloc, MIRGraph* graph, 44 const CompileInfo* outerInfo, 45 const OptimizationInfo* optimizationInfo, 46 const wasm::CodeMetadata* wasmCodeMeta = nullptr); 47 48 TempAllocator& alloc() { return *alloc_; } 49 MIRGraph& graph() { return *graph_; } 50 [[nodiscard]] bool ensureBallast() { return alloc().ensureBallast(); } 51 const JitRuntime* jitRuntime() const { return runtime->jitRuntime(); } 52 const CompileInfo& outerInfo() const { return *outerInfo_; } 53 const OptimizationInfo& optimizationInfo() const { 54 return *optimizationInfo_; 55 } 56 bool hasProfilingScripts() const { 57 return runtime && runtime->profilingScripts(); 58 } 59 60 template <typename T> 61 js::lifo_alloc_pointer<T*> allocate(size_t count = 1) { 62 size_t bytes; 63 if (MOZ_UNLIKELY(!CalculateAllocSize<T>(count, &bytes))) { 64 return nullptr; 65 } 66 return static_cast<T*>(alloc().allocate(bytes)); 67 } 68 69 // Set an error state and prints a message. Returns false so errors can be 70 // propagated up. 71 mozilla::GenericErrorResult<AbortReason> abort(AbortReason r); 72 mozilla::GenericErrorResult<AbortReason> abort(AbortReason r, 73 const char* message, ...) 74 MOZ_FORMAT_PRINTF(3, 4); 75 76 mozilla::GenericErrorResult<AbortReason> abortFmt(AbortReason r, 77 const char* message, 78 va_list ap) 79 MOZ_FORMAT_PRINTF(3, 0); 80 81 // Collect the evaluation result of phases after WarpOracle, such that 82 // off-thread compilation can report what error got encountered. 83 void setOffThreadStatus(AbortReasonOr<Ok>&& result) { 84 MOZ_ASSERT(offThreadStatus_.isOk()); 85 offThreadStatus_ = std::move(result); 86 } 87 const AbortReasonOr<Ok>& getOffThreadStatus() const { 88 return offThreadStatus_; 89 } 90 91 [[nodiscard]] bool instrumentedProfiling() { 92 if (!instrumentedProfilingIsCached_) { 93 instrumentedProfiling_ = runtime->geckoProfiler().enabled(); 94 instrumentedProfilingIsCached_ = true; 95 } 96 return instrumentedProfiling_; 97 } 98 99 bool isProfilerInstrumentationEnabled() { 100 return !compilingWasm() && instrumentedProfiling(); 101 } 102 103 gc::Heap initialStringHeap() const { 104 return stringsCanBeInNursery_ ? gc::Heap::Default : gc::Heap::Tenured; 105 } 106 107 gc::Heap initialBigIntHeap() const { 108 return bigIntsCanBeInNursery_ ? gc::Heap::Default : gc::Heap::Tenured; 109 } 110 111 // Whether the main thread is trying to cancel this build. 112 bool shouldCancel(const char* why) const { return cancelBuild_; } 113 void cancel() { cancelBuild_ = true; } 114 115 bool compilingWasm() const { return outerInfo_->compilingWasm(); } 116 117 uint32_t wasmMaxStackArgBytes() const { 118 MOZ_ASSERT(compilingWasm()); 119 return wasmMaxStackArgBytes_; 120 } 121 void accumulateWasmMaxStackArgBytes(uint32_t n) { 122 MOZ_ASSERT(compilingWasm()); 123 wasmMaxStackArgBytes_ = std::max(n, wasmMaxStackArgBytes_); 124 } 125 126 void setNeedsOverrecursedCheck() { needsOverrecursedCheck_ = true; } 127 bool needsOverrecursedCheck() const { return needsOverrecursedCheck_; } 128 129 void setNeedsStaticStackAlignment() { needsStaticStackAlignment_ = true; } 130 bool needsStaticStackAlignment() const { return needsStaticStackAlignment_; } 131 132 public: 133 CompileRealm* realm; 134 CompileRuntime* runtime; 135 136 private: 137 // The CompileInfo for the outermost script. 138 const CompileInfo* outerInfo_; 139 const OptimizationInfo* optimizationInfo_; 140 const wasm::CodeMetadata* wasmCodeMeta_; 141 142 TempAllocator* alloc_; 143 MIRGraph* graph_; 144 AbortReasonOr<Ok> offThreadStatus_; 145 mozilla::Atomic<bool, mozilla::Relaxed> cancelBuild_; 146 147 uint32_t wasmMaxStackArgBytes_; 148 bool needsOverrecursedCheck_; 149 bool needsStaticStackAlignment_; 150 151 bool instrumentedProfiling_; 152 bool instrumentedProfilingIsCached_; 153 bool stringsCanBeInNursery_; 154 bool bigIntsCanBeInNursery_; 155 156 bool disableLICM_ = false; 157 158 public: 159 void disableLICM() { disableLICM_ = true; } 160 bool licmEnabled() const; 161 bool branchHintingEnabled() const; 162 163 const wasm::CodeMetadata* wasmCodeMeta() const { 164 MOZ_ASSERT(wasmCodeMeta_); 165 return wasmCodeMeta_; 166 } 167 168 public: 169 const JitCompileOptions options; 170 171 private: 172 #ifdef JS_JITSPEW 173 GraphSpewer* graphSpewer_ = nullptr; 174 #endif 175 JitSpewGraphSpewer jitSpewer_; 176 IonPerfSpewer perfSpewer_; 177 178 public: 179 #ifdef JS_JITSPEW 180 void setGraphSpewer(GraphSpewer* graphSpewer) { 181 MOZ_ASSERT(!graphSpewer_); 182 graphSpewer_ = graphSpewer; 183 } 184 #endif 185 IonPerfSpewer& perfSpewer() { return perfSpewer_; } 186 187 void spewBeginFunction(JSScript* function); 188 void spewBeginWasmFunction(unsigned funcIndex); 189 void spewPass(const char* name, BacktrackingAllocator* ra = nullptr); 190 void spewEndFunction(); 191 192 CompilationDependencyTracker tracker; 193 }; 194 195 class AutoSpewEndFunction { 196 private: 197 MIRGenerator* mir_; 198 199 public: 200 explicit AutoSpewEndFunction(MIRGenerator* mir) : mir_(mir) {} 201 ~AutoSpewEndFunction(); 202 }; 203 204 } // namespace jit 205 } // namespace js 206 207 #endif /* jit_MIRGenerator_h */