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 initialStringHeap()104 gc::InitialHeap initialStringHeap() const { 105 return stringsCanBeInNursery_ ? gc::DefaultHeap : gc::TenuredHeap; 106 } 107 initialBigIntHeap()108 gc::InitialHeap initialBigIntHeap() const { 109 return bigIntsCanBeInNursery_ ? gc::DefaultHeap : gc::TenuredHeap; 110 } 111 112 // Whether the main thread is trying to cancel this build. shouldCancel(const char * why)113 bool shouldCancel(const char* why) { return cancelBuild_; } cancel()114 void cancel() { cancelBuild_ = true; } 115 compilingWasm()116 bool compilingWasm() const { return outerInfo_->compilingWasm(); } 117 wasmMaxStackArgBytes()118 uint32_t wasmMaxStackArgBytes() const { 119 MOZ_ASSERT(compilingWasm()); 120 return wasmMaxStackArgBytes_; 121 } initWasmMaxStackArgBytes(uint32_t n)122 void initWasmMaxStackArgBytes(uint32_t n) { 123 MOZ_ASSERT(compilingWasm()); 124 MOZ_ASSERT(wasmMaxStackArgBytes_ == 0); 125 wasmMaxStackArgBytes_ = n; 126 } minWasmHeapLength()127 uint64_t minWasmHeapLength() const { return minWasmHeapLength_; } 128 setNeedsOverrecursedCheck()129 void setNeedsOverrecursedCheck() { needsOverrecursedCheck_ = true; } needsOverrecursedCheck()130 bool needsOverrecursedCheck() const { return needsOverrecursedCheck_; } 131 setNeedsStaticStackAlignment()132 void setNeedsStaticStackAlignment() { needsStaticStackAlignment_ = true; } needsStaticStackAlignment()133 bool needsStaticStackAlignment() const { return needsStaticStackAlignment_; } 134 135 public: 136 CompileRealm* realm; 137 CompileRuntime* runtime; 138 139 private: 140 // The CompileInfo for the outermost script. 141 const CompileInfo* outerInfo_; 142 143 const OptimizationInfo* optimizationInfo_; 144 TempAllocator* alloc_; 145 MIRGraph* graph_; 146 AbortReasonOr<Ok> offThreadStatus_; 147 mozilla::Atomic<bool, mozilla::Relaxed> cancelBuild_; 148 149 uint32_t wasmMaxStackArgBytes_; 150 bool needsOverrecursedCheck_; 151 bool needsStaticStackAlignment_; 152 153 bool instrumentedProfiling_; 154 bool instrumentedProfilingIsCached_; 155 bool stringsCanBeInNursery_; 156 bool bigIntsCanBeInNursery_; 157 158 uint64_t minWasmHeapLength_; 159 160 #if defined(JS_ION_PERF) 161 WasmPerfSpewer wasmPerfSpewer_; 162 163 public: perfSpewer()164 WasmPerfSpewer& perfSpewer() { return wasmPerfSpewer_; } 165 #endif 166 167 public: 168 const JitCompileOptions options; 169 170 private: 171 GraphSpewer gs_; 172 173 public: graphSpewer()174 GraphSpewer& graphSpewer() { return gs_; } 175 }; 176 177 } // namespace jit 178 } // namespace js 179 180 #endif /* jit_MIRGenerator_h */ 181