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