summaryrefslogtreecommitdiffstats
path: root/js/src/jit/MIRGenerator.h
blob: 4026a69117026ceb3f0a685c8fc487ea8d6bdee9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
 * vim: set ts=8 sts=2 et sw=2 tw=80:
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#ifndef jit_MIRGenerator_h
#define jit_MIRGenerator_h

// This file declares the data structures used to build a control-flow graph
// containing MIR.

#include "mozilla/Assertions.h"
#include "mozilla/Atomics.h"
#include "mozilla/Attributes.h"
#include "mozilla/Result.h"

#include <stdarg.h>
#include <stddef.h>
#include <stdint.h>

#include "jit/CompileInfo.h"
#include "jit/CompileWrappers.h"
#include "jit/JitAllocPolicy.h"
#include "jit/JitContext.h"
#include "jit/JitSpewer.h"
#include "jit/PerfSpewer.h"
#include "js/Utility.h"
#include "vm/GeckoProfiler.h"

namespace js {
namespace jit {

class JitRuntime;
class MIRGraph;
class OptimizationInfo;

class MIRGenerator final {
 public:
  MIRGenerator(CompileRealm* realm, const JitCompileOptions& options,
               TempAllocator* alloc, MIRGraph* graph,
               const CompileInfo* outerInfo,
               const OptimizationInfo* optimizationInfo);

  void initMinWasmHeapLength(uint64_t init) { minWasmHeapLength_ = init; }

  TempAllocator& alloc() { return *alloc_; }
  MIRGraph& graph() { return *graph_; }
  [[nodiscard]] bool ensureBallast() { return alloc().ensureBallast(); }
  const JitRuntime* jitRuntime() const { return runtime->jitRuntime(); }
  const CompileInfo& outerInfo() const { return *outerInfo_; }
  const OptimizationInfo& optimizationInfo() const {
    return *optimizationInfo_;
  }
  bool hasProfilingScripts() const {
    return runtime && runtime->profilingScripts();
  }

  template <typename T>
  T* allocate(size_t count = 1) {
    size_t bytes;
    if (MOZ_UNLIKELY(!CalculateAllocSize<T>(count, &bytes))) {
      return nullptr;
    }
    return static_cast<T*>(alloc().allocate(bytes));
  }

  // Set an error state and prints a message. Returns false so errors can be
  // propagated up.
  mozilla::GenericErrorResult<AbortReason> abort(AbortReason r);
  mozilla::GenericErrorResult<AbortReason> abort(AbortReason r,
                                                 const char* message, ...)
      MOZ_FORMAT_PRINTF(3, 4);

  mozilla::GenericErrorResult<AbortReason> abortFmt(AbortReason r,
                                                    const char* message,
                                                    va_list ap)
      MOZ_FORMAT_PRINTF(3, 0);

  // Collect the evaluation result of phases after WarpOracle, such that
  // off-thread compilation can report what error got encountered.
  void setOffThreadStatus(AbortReasonOr<Ok>&& result) {
    MOZ_ASSERT(offThreadStatus_.isOk());
    offThreadStatus_ = std::move(result);
  }
  const AbortReasonOr<Ok>& getOffThreadStatus() const {
    return offThreadStatus_;
  }

  [[nodiscard]] bool instrumentedProfiling() {
    if (!instrumentedProfilingIsCached_) {
      instrumentedProfiling_ = runtime->geckoProfiler().enabled();
      instrumentedProfilingIsCached_ = true;
    }
    return instrumentedProfiling_;
  }

  bool isProfilerInstrumentationEnabled() {
    return !compilingWasm() && instrumentedProfiling();
  }

  gc::Heap initialStringHeap() const {
    return stringsCanBeInNursery_ ? gc::Heap::Default : gc::Heap::Tenured;
  }

  gc::Heap initialBigIntHeap() const {
    return bigIntsCanBeInNursery_ ? gc::Heap::Default : gc::Heap::Tenured;
  }

  // Whether the main thread is trying to cancel this build.
  bool shouldCancel(const char* why) { return cancelBuild_; }
  void cancel() { cancelBuild_ = true; }

  bool compilingWasm() const { return outerInfo_->compilingWasm(); }

  uint32_t wasmMaxStackArgBytes() const {
    MOZ_ASSERT(compilingWasm());
    return wasmMaxStackArgBytes_;
  }
  void initWasmMaxStackArgBytes(uint32_t n) {
    MOZ_ASSERT(compilingWasm());
    MOZ_ASSERT(wasmMaxStackArgBytes_ == 0);
    wasmMaxStackArgBytes_ = n;
  }
  uint64_t minWasmHeapLength() const { return minWasmHeapLength_; }

  void setNeedsOverrecursedCheck() { needsOverrecursedCheck_ = true; }
  bool needsOverrecursedCheck() const { return needsOverrecursedCheck_; }

  void setNeedsStaticStackAlignment() { needsStaticStackAlignment_ = true; }
  bool needsStaticStackAlignment() const { return needsStaticStackAlignment_; }

 public:
  CompileRealm* realm;
  CompileRuntime* runtime;

 private:
  // The CompileInfo for the outermost script.
  const CompileInfo* outerInfo_;

  const OptimizationInfo* optimizationInfo_;
  TempAllocator* alloc_;
  MIRGraph* graph_;
  AbortReasonOr<Ok> offThreadStatus_;
  mozilla::Atomic<bool, mozilla::Relaxed> cancelBuild_;

  uint32_t wasmMaxStackArgBytes_;
  bool needsOverrecursedCheck_;
  bool needsStaticStackAlignment_;

  bool instrumentedProfiling_;
  bool instrumentedProfilingIsCached_;
  bool stringsCanBeInNursery_;
  bool bigIntsCanBeInNursery_;

  bool disableLICM_ = false;

 public:
  void disableLICM() { disableLICM_ = true; }
  bool licmEnabled() const;

 private:
  uint64_t minWasmHeapLength_;

  IonPerfSpewer wasmPerfSpewer_;

 public:
  IonPerfSpewer& perfSpewer() { return wasmPerfSpewer_; }

 public:
  const JitCompileOptions options;

 private:
  GraphSpewer gs_;

 public:
  GraphSpewer& graphSpewer() { return gs_; }
};

}  // namespace jit
}  // namespace js

#endif /* jit_MIRGenerator_h */