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/CompileInfo.h" 23 #include "jit/CompileWrappers.h" 24 #include "jit/JitAllocPolicy.h" 25 #include "jit/JitContext.h" 26 #include "jit/JitSpewer.h" 27 #ifdef JS_ION_PERF 28 # include "jit/PerfSpewer.h" 29 #endif 30 #include "js/Utility.h" 31 #include "vm/GeckoProfiler.h" 32 33 namespace js { 34 namespace jit { 35 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 initMinWasmHeapLength(uint64_t init)47 void initMinWasmHeapLength(uint64_t init) { minWasmHeapLength_ = init; } 48 alloc()49 TempAllocator& alloc() { return *alloc_; } graph()50 MIRGraph& graph() { return *graph_; } ensureBallast()51 [[nodiscard]] bool ensureBallast() { return alloc().ensureBallast(); } jitRuntime()52 const JitRuntime* jitRuntime() const { return runtime->jitRuntime(); } outerInfo()53 const CompileInfo& outerInfo() const { return *outerInfo_; } optimizationInfo()54 const OptimizationInfo& optimizationInfo() const { 55 return *optimizationInfo_; 56 } hasProfilingScripts()57 bool hasProfilingScripts() const { 58 return runtime && runtime->profilingScripts(); 59 } 60 61 template <typename T> 62 T* allocate(size_t count = 1) { 63 size_t bytes; 64 if (MOZ_UNLIKELY(!CalculateAllocSize<T>(count, &bytes))) { 65 return nullptr; 66 } 67 return static_cast<T*>(alloc().allocate(bytes)); 68 } 69 70 // Set an error state and prints a message. Returns false so errors can be 71 // propagated up. 72 mozilla::GenericErrorResult<AbortReason> abort(AbortReason r); 73 mozilla::GenericErrorResult<AbortReason> abort(AbortReason r, 74 const char* message, ...) 75 MOZ_FORMAT_PRINTF(3, 4); 76 77 mozilla::GenericErrorResult<AbortReason> abortFmt(AbortReason r, 78 const char* message, 79 va_list ap) 80 MOZ_FORMAT_PRINTF(3, 0); 81 82 // Collect the evaluation result of phases after WarpOracle, such that 83 // off-thread compilation can report what error got encountered. setOffThreadStatus(AbortReasonOr<Ok> && result)84 void setOffThreadStatus(AbortReasonOr<Ok>&& result) { 85 MOZ_ASSERT(offThreadStatus_.isOk()); 86 offThreadStatus_ = std::move(result); 87 } getOffThreadStatus()88 const AbortReasonOr<Ok>& getOffThreadStatus() const { 89 return offThreadStatus_; 90 } 91 instrumentedProfiling()92 [[nodiscard]] bool instrumentedProfiling() { 93 if (!instrumentedProfilingIsCached_) { 94 instrumentedProfiling_ = runtime->geckoProfiler().enabled(); 95 instrumentedProfilingIsCached_ = true; 96 } 97 return instrumentedProfiling_; 98 } 99 isProfilerInstrumentationEnabled()100 bool isProfilerInstrumentationEnabled() { 101 return !compilingWasm() && instrumentedProfiling(); 102 } 103 stringsCanBeInNursery()104 bool stringsCanBeInNursery() const { return stringsCanBeInNursery_; } 105 bigIntsCanBeInNursery()106 bool bigIntsCanBeInNursery() const { return bigIntsCanBeInNursery_; } 107 108 // Whether the main thread is trying to cancel this build. shouldCancel(const char * why)109 bool shouldCancel(const char* why) { return cancelBuild_; } cancel()110 void cancel() { cancelBuild_ = true; } 111 compilingWasm()112 bool compilingWasm() const { return outerInfo_->compilingWasm(); } 113 wasmMaxStackArgBytes()114 uint32_t wasmMaxStackArgBytes() const { 115 MOZ_ASSERT(compilingWasm()); 116 return wasmMaxStackArgBytes_; 117 } initWasmMaxStackArgBytes(uint32_t n)118 void initWasmMaxStackArgBytes(uint32_t n) { 119 MOZ_ASSERT(compilingWasm()); 120 MOZ_ASSERT(wasmMaxStackArgBytes_ == 0); 121 wasmMaxStackArgBytes_ = n; 122 } minWasmHeapLength()123 uint64_t minWasmHeapLength() const { return minWasmHeapLength_; } 124 setNeedsOverrecursedCheck()125 void setNeedsOverrecursedCheck() { needsOverrecursedCheck_ = true; } needsOverrecursedCheck()126 bool needsOverrecursedCheck() const { return needsOverrecursedCheck_; } 127 setNeedsStaticStackAlignment()128 void setNeedsStaticStackAlignment() { needsStaticStackAlignment_ = true; } needsStaticStackAlignment()129 bool needsStaticStackAlignment() const { return needsStaticStackAlignment_; } 130 131 public: 132 CompileRealm* realm; 133 CompileRuntime* runtime; 134 135 private: 136 // The CompileInfo for the outermost script. 137 const CompileInfo* outerInfo_; 138 139 const OptimizationInfo* optimizationInfo_; 140 TempAllocator* alloc_; 141 MIRGraph* graph_; 142 AbortReasonOr<Ok> offThreadStatus_; 143 mozilla::Atomic<bool, mozilla::Relaxed> cancelBuild_; 144 145 uint32_t wasmMaxStackArgBytes_; 146 bool needsOverrecursedCheck_; 147 bool needsStaticStackAlignment_; 148 149 bool instrumentedProfiling_; 150 bool instrumentedProfilingIsCached_; 151 bool stringsCanBeInNursery_; 152 bool bigIntsCanBeInNursery_; 153 154 uint64_t minWasmHeapLength_; 155 156 #if defined(JS_ION_PERF) 157 WasmPerfSpewer wasmPerfSpewer_; 158 159 public: perfSpewer()160 WasmPerfSpewer& perfSpewer() { return wasmPerfSpewer_; } 161 #endif 162 163 public: 164 const JitCompileOptions options; 165 166 private: 167 GraphSpewer gs_; 168 169 public: graphSpewer()170 GraphSpewer& graphSpewer() { return gs_; } 171 }; 172 173 } // namespace jit 174 } // namespace js 175 176 #endif /* jit_MIRGenerator_h */ 177