V8 API Reference, 7.2.502.16 (for Deno 0.2.4)
optimized-compilation-info.h
1 // Copyright 2016 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef V8_OPTIMIZED_COMPILATION_INFO_H_
6 #define V8_OPTIMIZED_COMPILATION_INFO_H_
7 
8 #include <memory>
9 
10 #include "src/bailout-reason.h"
11 #include "src/frames.h"
12 #include "src/globals.h"
13 #include "src/handles.h"
14 #include "src/objects.h"
15 #include "src/source-position-table.h"
16 #include "src/utils.h"
17 #include "src/vector.h"
18 
19 namespace v8 {
20 namespace internal {
21 
22 class DeferredHandles;
23 class FunctionLiteral;
24 class Isolate;
25 class JavaScriptFrame;
26 class JSGlobalObject;
27 class Zone;
28 
29 // OptimizedCompilationInfo encapsulates the information needed to compile
30 // optimized code for a given function, and the results of the optimized
31 // compilation.
32 class V8_EXPORT_PRIVATE OptimizedCompilationInfo final {
33  public:
34  // Various configuration flags for a compilation, as well as some properties
35  // of the compiled code produced by a compilation.
36  enum Flag {
37  kAccessorInliningEnabled = 1 << 0,
38  kFunctionContextSpecializing = 1 << 1,
39  kInliningEnabled = 1 << 2,
40  kDisableFutureOptimization = 1 << 3,
41  kSplittingEnabled = 1 << 4,
42  kSourcePositionsEnabled = 1 << 5,
43  kBailoutOnUninitialized = 1 << 6,
44  kLoopPeelingEnabled = 1 << 7,
45  kUntrustedCodeMitigations = 1 << 8,
46  kSwitchJumpTableEnabled = 1 << 9,
47  kCalledWithCodeStartRegister = 1 << 10,
48  kPoisonRegisterArguments = 1 << 11,
49  kAllocationFoldingEnabled = 1 << 12,
50  kAnalyzeEnvironmentLiveness = 1 << 13,
51  kTraceTurboJson = 1 << 14,
52  kTraceTurboGraph = 1 << 15,
53  kTraceTurboScheduled = 1 << 16,
54  kWasmRuntimeExceptionSupport = 1 << 17
55  };
56 
57  // Construct a compilation info for optimized compilation.
58  OptimizedCompilationInfo(Zone* zone, Isolate* isolate,
60  Handle<JSFunction> closure);
61  // Construct a compilation info for stub compilation, Wasm, and testing.
63  Code::Kind code_kind);
64 
66 
67  Zone* zone() { return zone_; }
68  bool is_osr() const { return !osr_offset_.IsNone(); }
69  Handle<SharedFunctionInfo> shared_info() const { return shared_info_; }
70  bool has_shared_info() const { return !shared_info().is_null(); }
71  Handle<BytecodeArray> bytecode_array() const { return bytecode_array_; }
72  bool has_bytecode_array() const { return !bytecode_array_.is_null(); }
73  Handle<JSFunction> closure() const { return closure_; }
74  Handle<Code> code() const { return code_; }
75  Code::Kind code_kind() const { return code_kind_; }
76  uint32_t stub_key() const { return stub_key_; }
77  void set_stub_key(uint32_t stub_key) { stub_key_ = stub_key; }
78  int32_t builtin_index() const { return builtin_index_; }
79  void set_builtin_index(int32_t index) { builtin_index_ = index; }
80  BailoutId osr_offset() const { return osr_offset_; }
81  JavaScriptFrame* osr_frame() const { return osr_frame_; }
82 
83  // Flags used by optimized compilation.
84 
85  void MarkAsFunctionContextSpecializing() {
86  SetFlag(kFunctionContextSpecializing);
87  }
88  bool is_function_context_specializing() const {
89  return GetFlag(kFunctionContextSpecializing);
90  }
91 
92  void MarkAsAccessorInliningEnabled() { SetFlag(kAccessorInliningEnabled); }
93  bool is_accessor_inlining_enabled() const {
94  return GetFlag(kAccessorInliningEnabled);
95  }
96 
97  void MarkAsSourcePositionsEnabled() { SetFlag(kSourcePositionsEnabled); }
98  bool is_source_positions_enabled() const {
99  return GetFlag(kSourcePositionsEnabled);
100  }
101 
102  void MarkAsInliningEnabled() { SetFlag(kInliningEnabled); }
103  bool is_inlining_enabled() const { return GetFlag(kInliningEnabled); }
104 
105  void SetPoisoningMitigationLevel(PoisoningMitigationLevel poisoning_level) {
106  poisoning_level_ = poisoning_level;
107  }
108  PoisoningMitigationLevel GetPoisoningMitigationLevel() const {
109  return poisoning_level_;
110  }
111 
112  void MarkAsSplittingEnabled() { SetFlag(kSplittingEnabled); }
113  bool is_splitting_enabled() const { return GetFlag(kSplittingEnabled); }
114 
115  void MarkAsBailoutOnUninitialized() { SetFlag(kBailoutOnUninitialized); }
116  bool is_bailout_on_uninitialized() const {
117  return GetFlag(kBailoutOnUninitialized);
118  }
119 
120  void MarkAsLoopPeelingEnabled() { SetFlag(kLoopPeelingEnabled); }
121  bool is_loop_peeling_enabled() const { return GetFlag(kLoopPeelingEnabled); }
122 
123  bool has_untrusted_code_mitigations() const {
124  return GetFlag(kUntrustedCodeMitigations);
125  }
126 
127  bool switch_jump_table_enabled() const {
128  return GetFlag(kSwitchJumpTableEnabled);
129  }
130 
131  bool called_with_code_start_register() const {
132  bool enabled = GetFlag(kCalledWithCodeStartRegister);
133  return enabled;
134  }
135 
136  void MarkAsPoisoningRegisterArguments() {
137  DCHECK(has_untrusted_code_mitigations());
138  SetFlag(kPoisonRegisterArguments);
139  }
140  bool is_poisoning_register_arguments() const {
141  bool enabled = GetFlag(kPoisonRegisterArguments);
142  DCHECK_IMPLIES(enabled, has_untrusted_code_mitigations());
143  DCHECK_IMPLIES(enabled, called_with_code_start_register());
144  return enabled;
145  }
146 
147  void MarkAsAllocationFoldingEnabled() { SetFlag(kAllocationFoldingEnabled); }
148  bool is_allocation_folding_enabled() const {
149  return GetFlag(kAllocationFoldingEnabled);
150  }
151 
152  void MarkAsAnalyzeEnvironmentLiveness() {
153  SetFlag(kAnalyzeEnvironmentLiveness);
154  }
155  bool is_analyze_environment_liveness() const {
156  return GetFlag(kAnalyzeEnvironmentLiveness);
157  }
158 
159  void SetWasmRuntimeExceptionSupport() {
160  SetFlag(kWasmRuntimeExceptionSupport);
161  }
162 
163  bool wasm_runtime_exception_support() {
164  return GetFlag(kWasmRuntimeExceptionSupport);
165  }
166 
167  bool trace_turbo_json_enabled() const { return GetFlag(kTraceTurboJson); }
168 
169  bool trace_turbo_graph_enabled() const { return GetFlag(kTraceTurboGraph); }
170 
171  bool trace_turbo_scheduled_enabled() const {
172  return GetFlag(kTraceTurboScheduled);
173  }
174 
175  // Code getters and setters.
176 
177  void SetCode(Handle<Code> code) { code_ = code; }
178 
179  bool has_context() const;
180  Context context() const;
181 
182  bool has_native_context() const;
183  Context native_context() const;
184 
185  bool has_global_object() const;
186  JSGlobalObject* global_object() const;
187 
188  // Accessors for the different compilation modes.
189  bool IsOptimizing() const { return code_kind() == Code::OPTIMIZED_FUNCTION; }
190  bool IsWasm() const { return code_kind() == Code::WASM_FUNCTION; }
191  bool IsStub() const {
192  return code_kind() != Code::OPTIMIZED_FUNCTION &&
193  code_kind() != Code::WASM_FUNCTION;
194  }
195  void SetOptimizingForOsr(BailoutId osr_offset, JavaScriptFrame* osr_frame) {
196  DCHECK(IsOptimizing());
197  osr_offset_ = osr_offset;
198  osr_frame_ = osr_frame;
199  }
200 
201  void set_deferred_handles(std::shared_ptr<DeferredHandles> deferred_handles);
202  void set_deferred_handles(DeferredHandles* deferred_handles);
203  std::shared_ptr<DeferredHandles> deferred_handles() {
204  return deferred_handles_;
205  }
206 
207  void ReopenHandlesInNewHandleScope(Isolate* isolate);
208 
209  void AbortOptimization(BailoutReason reason) {
210  DCHECK_NE(reason, BailoutReason::kNoReason);
211  if (bailout_reason_ == BailoutReason::kNoReason) bailout_reason_ = reason;
212  SetFlag(kDisableFutureOptimization);
213  }
214 
215  void RetryOptimization(BailoutReason reason) {
216  DCHECK_NE(reason, BailoutReason::kNoReason);
217  if (GetFlag(kDisableFutureOptimization)) return;
218  bailout_reason_ = reason;
219  }
220 
221  BailoutReason bailout_reason() const { return bailout_reason_; }
222 
223  int optimization_id() const {
224  DCHECK(IsOptimizing());
225  return optimization_id_;
226  }
227 
229  Handle<SharedFunctionInfo> shared_info;
230  Handle<BytecodeArray> bytecode_array;
231 
232  InliningPosition position;
233 
235  Handle<BytecodeArray> inlined_bytecode,
236  SourcePosition pos)
237  : shared_info(inlined_shared_info), bytecode_array(inlined_bytecode) {
238  position.position = pos;
239  // initialized when generating the deoptimization literals
240  position.inlined_function_id = DeoptimizationData::kNotInlinedIndex;
241  }
242 
243  void RegisterInlinedFunctionId(size_t inlined_function_id) {
244  position.inlined_function_id = static_cast<int>(inlined_function_id);
245  }
246  };
247 
248  typedef std::vector<InlinedFunctionHolder> InlinedFunctionList;
249  InlinedFunctionList& inlined_functions() { return inlined_functions_; }
250 
251  // Returns the inlining id for source position tracking.
252  int AddInlinedFunction(Handle<SharedFunctionInfo> inlined_function,
253  Handle<BytecodeArray> inlined_bytecode,
254  SourcePosition pos);
255 
256  std::unique_ptr<char[]> GetDebugName() const;
257 
258  StackFrame::Type GetOutputStackFrameType() const;
259 
260  const char* trace_turbo_filename() const {
261  return trace_turbo_filename_.get();
262  }
263 
264  void set_trace_turbo_filename(std::unique_ptr<char[]> filename) {
265  trace_turbo_filename_ = std::move(filename);
266  }
267 
268  private:
269  OptimizedCompilationInfo(Code::Kind code_kind, Zone* zone);
270  void ConfigureFlags();
271 
272  void SetFlag(Flag flag) { flags_ |= flag; }
273  bool GetFlag(Flag flag) const { return (flags_ & flag) != 0; }
274 
275  void SetTracingFlags(bool passes_filter);
276 
277  // Compilation flags.
278  unsigned flags_ = 0;
279  PoisoningMitigationLevel poisoning_level_ =
280  PoisoningMitigationLevel::kDontPoison;
281 
282  Code::Kind code_kind_;
283  uint32_t stub_key_ = 0;
284  int32_t builtin_index_ = -1;
285 
286  // We retain a reference the bytecode array specifically to ensure it doesn't
287  // get flushed while we are optimizing the code.
288  Handle<BytecodeArray> bytecode_array_;
289 
290  Handle<SharedFunctionInfo> shared_info_;
291 
292  Handle<JSFunction> closure_;
293 
294  // The compiled code.
295  Handle<Code> code_;
296 
297  // Entry point when compiling for OSR, {BailoutId::None} otherwise.
298  BailoutId osr_offset_ = BailoutId::None();
299 
300  // The zone from which the compilation pipeline working on this
301  // OptimizedCompilationInfo allocates.
302  Zone* zone_;
303 
304  std::shared_ptr<DeferredHandles> deferred_handles_;
305 
306  BailoutReason bailout_reason_ = BailoutReason::kNoReason;
307 
308  InlinedFunctionList inlined_functions_;
309 
310  int optimization_id_ = -1;
311 
312  // The current OSR frame for specialization or {nullptr}.
313  JavaScriptFrame* osr_frame_ = nullptr;
314 
315  Vector<const char> debug_name_;
316  std::unique_ptr<char[]> trace_turbo_filename_;
317 
318  DISALLOW_COPY_AND_ASSIGN(OptimizedCompilationInfo);
319 };
320 
321 } // namespace internal
322 } // namespace v8
323 
324 #endif // V8_OPTIMIZED_COMPILATION_INFO_H_
Definition: libplatform.h:13