Line data Source code
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_COMPILATION_INFO_H_
6 : #define V8_COMPILATION_INFO_H_
7 :
8 : #include <memory>
9 :
10 : #include "src/compilation-dependencies.h"
11 : #include "src/feedback-vector.h"
12 : #include "src/frames.h"
13 : #include "src/globals.h"
14 : #include "src/handles.h"
15 : #include "src/objects.h"
16 : #include "src/source-position-table.h"
17 : #include "src/utils.h"
18 : #include "src/vector.h"
19 :
20 : namespace v8 {
21 : namespace internal {
22 :
23 : class CoverageInfo;
24 : class DeclarationScope;
25 : class DeferredHandles;
26 : class FunctionLiteral;
27 : class Isolate;
28 : class JavaScriptFrame;
29 : class ParseInfo;
30 : class SourceRangeMap;
31 : class Zone;
32 :
33 : // CompilationInfo encapsulates some information known at compile time. It
34 : // is constructed based on the resources available at compile-time.
35 : class V8_EXPORT_PRIVATE CompilationInfo final {
36 : public:
37 : // Various configuration flags for a compilation, as well as some properties
38 : // of the compiled code produced by a compilation.
39 : enum Flag {
40 : kIsEval = 1 << 0,
41 : kIsNative = 1 << 1,
42 : kSerializing = 1 << 2,
43 : kCollectTypeProfile = 1 << 3,
44 : kAccessorInliningEnabled = 1 << 4,
45 : kFunctionContextSpecializing = 1 << 5,
46 : kInliningEnabled = 1 << 6,
47 : kDisableFutureOptimization = 1 << 7,
48 : kSplittingEnabled = 1 << 8,
49 : kSourcePositionsEnabled = 1 << 9,
50 : kBailoutOnUninitialized = 1 << 10,
51 : kLoopPeelingEnabled = 1 << 11,
52 : };
53 :
54 : // Construct a compilation info for unoptimized compilation.
55 : CompilationInfo(Zone* zone, Isolate* isolate, ParseInfo* parse_info,
56 : FunctionLiteral* literal);
57 : // Construct a compilation info for optimized compilation.
58 : CompilationInfo(Zone* zone, Isolate* isolate,
59 : Handle<SharedFunctionInfo> shared,
60 : Handle<JSFunction> closure);
61 : // Construct a compilation info for stub compilation (or testing).
62 : CompilationInfo(Vector<const char> debug_name, Isolate* isolate, Zone* zone,
63 : Code::Kind code_kind);
64 : ~CompilationInfo();
65 :
66 : FunctionLiteral* literal() const { return literal_; }
67 : void set_literal(FunctionLiteral* literal) {
68 : DCHECK_NOT_NULL(literal);
69 : literal_ = literal;
70 : }
71 :
72 : bool has_source_range_map() const { return source_range_map_ != nullptr; }
73 : SourceRangeMap* source_range_map() const { return source_range_map_; }
74 : void set_source_range_map(SourceRangeMap* source_range_map) {
75 : source_range_map_ = source_range_map;
76 : }
77 :
78 : DeclarationScope* scope() const;
79 :
80 : Isolate* isolate() const { return isolate_; }
81 : Zone* zone() { return zone_; }
82 1744926 : bool is_osr() const { return !osr_offset_.IsNone(); }
83 : Handle<SharedFunctionInfo> shared_info() const { return shared_info_; }
84 : void set_shared_info(Handle<SharedFunctionInfo> shared_info) {
85 2134858 : shared_info_ = shared_info;
86 : }
87 : bool has_shared_info() const { return !shared_info().is_null(); }
88 : Handle<JSFunction> closure() const { return closure_; }
89 : Handle<Code> code() const { return code_; }
90 : Code::Kind code_kind() const { return code_kind_; }
91 : BailoutId osr_offset() const { return osr_offset_; }
92 : JavaScriptFrame* osr_frame() const { return osr_frame_; }
93 : int num_parameters() const;
94 : int num_parameters_including_this() const;
95 : bool is_this_defined() const;
96 :
97 : void set_parameter_count(int parameter_count) {
98 : DCHECK(IsStub());
99 : parameter_count_ = parameter_count;
100 : }
101 :
102 : bool has_bytecode_array() const { return !bytecode_array_.is_null(); }
103 : Handle<BytecodeArray> bytecode_array() const { return bytecode_array_; }
104 :
105 : bool has_asm_wasm_data() const { return !asm_wasm_data_.is_null(); }
106 : Handle<FixedArray> asm_wasm_data() const { return asm_wasm_data_; }
107 :
108 : // Flags used by unoptimized compilation.
109 :
110 : void MarkAsSerializing() { SetFlag(kSerializing); }
111 1301543 : bool will_serialize() const { return GetFlag(kSerializing); }
112 :
113 : void MarkAsEval() { SetFlag(kIsEval); }
114 1643755 : bool is_eval() const { return GetFlag(kIsEval); }
115 :
116 : void MarkAsNative() { SetFlag(kIsNative); }
117 3432843 : bool is_native() const { return GetFlag(kIsNative); }
118 :
119 : void MarkAsCollectTypeProfile() { SetFlag(kCollectTypeProfile); }
120 4718049 : bool collect_type_profile() const { return GetFlag(kCollectTypeProfile); }
121 :
122 : // Flags used by optimized compilation.
123 :
124 : void MarkAsFunctionContextSpecializing() {
125 : SetFlag(kFunctionContextSpecializing);
126 : }
127 1324982 : bool is_function_context_specializing() const {
128 : return GetFlag(kFunctionContextSpecializing);
129 : }
130 :
131 : void MarkAsAccessorInliningEnabled() { SetFlag(kAccessorInliningEnabled); }
132 443382 : bool is_accessor_inlining_enabled() const {
133 : return GetFlag(kAccessorInliningEnabled);
134 : }
135 :
136 : void MarkAsSourcePositionsEnabled() { SetFlag(kSourcePositionsEnabled); }
137 23028533 : bool is_source_positions_enabled() const {
138 : return GetFlag(kSourcePositionsEnabled);
139 : }
140 :
141 : void MarkAsInliningEnabled() { SetFlag(kInliningEnabled); }
142 443382 : bool is_inlining_enabled() const { return GetFlag(kInliningEnabled); }
143 :
144 : void MarkAsSplittingEnabled() { SetFlag(kSplittingEnabled); }
145 1012917 : bool is_splitting_enabled() const { return GetFlag(kSplittingEnabled); }
146 :
147 : void MarkAsBailoutOnUninitialized() { SetFlag(kBailoutOnUninitialized); }
148 948291 : bool is_bailout_on_uninitialized() const {
149 : return GetFlag(kBailoutOnUninitialized);
150 : }
151 :
152 : void MarkAsLoopPeelingEnabled() { SetFlag(kLoopPeelingEnabled); }
153 443359 : bool is_loop_peeling_enabled() const { return GetFlag(kLoopPeelingEnabled); }
154 :
155 : // Code getters and setters.
156 :
157 3873581 : void SetCode(Handle<Code> code) { code_ = code; }
158 :
159 : void SetBytecodeArray(Handle<BytecodeArray> bytecode_array) {
160 2131308 : bytecode_array_ = bytecode_array;
161 : }
162 :
163 : void SetAsmWasmData(Handle<FixedArray> asm_wasm_data) {
164 3547 : asm_wasm_data_ = asm_wasm_data;
165 : }
166 :
167 : FeedbackVectorSpec* feedback_vector_spec() { return &feedback_vector_spec_; }
168 :
169 : bool has_context() const;
170 : Context* context() const;
171 :
172 : bool has_native_context() const;
173 : Context* native_context() const;
174 :
175 : bool has_global_object() const;
176 : JSGlobalObject* global_object() const;
177 :
178 : // Accessors for the different compilation modes.
179 : bool IsOptimizing() const { return mode_ == OPTIMIZE; }
180 0 : bool IsStub() const { return mode_ == STUB; }
181 634717 : bool IsWasm() const { return code_kind() == Code::WASM_FUNCTION; }
182 : void SetOptimizingForOsr(BailoutId osr_offset, JavaScriptFrame* osr_frame) {
183 : DCHECK(IsOptimizing());
184 457030 : osr_offset_ = osr_offset;
185 457030 : osr_frame_ = osr_frame;
186 : }
187 :
188 : void set_deferred_handles(std::shared_ptr<DeferredHandles> deferred_handles);
189 : void set_deferred_handles(DeferredHandles* deferred_handles);
190 : std::shared_ptr<DeferredHandles> deferred_handles() {
191 : return deferred_handles_;
192 : }
193 :
194 : void ReopenHandlesInNewHandleScope();
195 :
196 : void AbortOptimization(BailoutReason reason) {
197 : DCHECK_NE(reason, kNoReason);
198 17967 : if (bailout_reason_ == kNoReason) bailout_reason_ = reason;
199 : SetFlag(kDisableFutureOptimization);
200 : }
201 :
202 41 : void RetryOptimization(BailoutReason reason) {
203 : DCHECK_NE(reason, kNoReason);
204 41 : if (GetFlag(kDisableFutureOptimization)) return;
205 41 : bailout_reason_ = reason;
206 : }
207 :
208 : BailoutReason bailout_reason() const { return bailout_reason_; }
209 :
210 : CompilationDependencies* dependencies() { return &dependencies_; }
211 :
212 : int optimization_id() const {
213 : DCHECK(IsOptimizing());
214 : return optimization_id_;
215 : }
216 :
217 : int osr_expr_stack_height() {
218 : DCHECK_GE(osr_expr_stack_height_, 0);
219 : return osr_expr_stack_height_;
220 : }
221 : void set_osr_expr_stack_height(int height) {
222 : DCHECK_EQ(osr_expr_stack_height_, -1);
223 : osr_expr_stack_height_ = height;
224 : DCHECK_GE(osr_expr_stack_height_, 0);
225 : }
226 :
227 : bool has_simple_parameters();
228 :
229 : struct InlinedFunctionHolder {
230 : Handle<SharedFunctionInfo> shared_info;
231 :
232 : InliningPosition position;
233 :
234 : InlinedFunctionHolder(Handle<SharedFunctionInfo> inlined_shared_info,
235 : SourcePosition pos)
236 61528 : : shared_info(inlined_shared_info) {
237 61528 : position.position = pos;
238 : // initialized when generating the deoptimization literals
239 61528 : position.inlined_function_id = DeoptimizationData::kNotInlinedIndex;
240 : }
241 :
242 : void RegisterInlinedFunctionId(size_t inlined_function_id) {
243 61472 : position.inlined_function_id = static_cast<int>(inlined_function_id);
244 : }
245 : };
246 :
247 : typedef std::vector<InlinedFunctionHolder> InlinedFunctionList;
248 : InlinedFunctionList& inlined_functions() { return inlined_functions_; }
249 :
250 : // Returns the inlining id for source position tracking.
251 : int AddInlinedFunction(Handle<SharedFunctionInfo> inlined_function,
252 : SourcePosition pos);
253 :
254 : std::unique_ptr<char[]> GetDebugName() const;
255 :
256 : StackFrame::Type GetOutputStackFrameType() const;
257 :
258 : int GetDeclareGlobalsFlags() const;
259 :
260 : SourcePositionTableBuilder::RecordingMode SourcePositionRecordingMode() const;
261 :
262 : bool has_coverage_info() const { return !coverage_info_.is_null(); }
263 : Handle<CoverageInfo> coverage_info() const { return coverage_info_; }
264 : void set_coverage_info(Handle<CoverageInfo> coverage_info) {
265 781 : coverage_info_ = coverage_info;
266 : }
267 :
268 : private:
269 : // Compilation mode.
270 : // BASE is generated by the full codegen, optionally prepared for bailouts.
271 : // OPTIMIZE is optimized code generated by the Hydrogen-based backend.
272 : enum Mode { BASE, OPTIMIZE, STUB };
273 :
274 : CompilationInfo(Vector<const char> debug_name, Code::Kind code_kind,
275 : Mode mode, Isolate* isolate, Zone* zone);
276 :
277 : void SetMode(Mode mode) { mode_ = mode; }
278 :
279 4100529 : void SetFlag(Flag flag) { flags_ |= flag; }
280 :
281 : void SetFlag(Flag flag, bool value) {
282 : flags_ = value ? flags_ | flag : flags_ & ~flag;
283 : }
284 :
285 43070372 : bool GetFlag(Flag flag) const { return (flags_ & flag) != 0; }
286 :
287 : Isolate* isolate_;
288 : FunctionLiteral* literal_;
289 : SourceRangeMap* source_range_map_; // Used when block coverage is enabled.
290 :
291 : unsigned flags_;
292 :
293 : Code::Kind code_kind_;
294 :
295 : Handle<SharedFunctionInfo> shared_info_;
296 :
297 : Handle<JSFunction> closure_;
298 :
299 : // The compiled code.
300 : Handle<Code> code_;
301 :
302 : // Compilation mode flag and whether deoptimization is allowed.
303 : Mode mode_;
304 : BailoutId osr_offset_;
305 :
306 : // Holds the bytecode array generated by the interpreter.
307 : // TODO(rmcilroy/mstarzinger): Temporary work-around until compiler.cc is
308 : // refactored to avoid us needing to carry the BytcodeArray around.
309 : Handle<BytecodeArray> bytecode_array_;
310 :
311 : // Holds the asm_wasm array generated by the asmjs compiler.
312 : Handle<FixedArray> asm_wasm_data_;
313 :
314 : // Holds the feedback vector spec generated during compilation
315 : FeedbackVectorSpec feedback_vector_spec_;
316 :
317 : // The zone from which the compilation pipeline working on this
318 : // CompilationInfo allocates.
319 : Zone* zone_;
320 :
321 : std::shared_ptr<DeferredHandles> deferred_handles_;
322 :
323 : // Dependencies for this compilation, e.g. stable maps.
324 : CompilationDependencies dependencies_;
325 :
326 : BailoutReason bailout_reason_;
327 :
328 : InlinedFunctionList inlined_functions_;
329 :
330 : // Number of parameters used for compilation of stubs that require arguments.
331 : int parameter_count_;
332 :
333 : int optimization_id_;
334 :
335 : int osr_expr_stack_height_;
336 :
337 : // The current OSR frame for specialization or {nullptr}.
338 : JavaScriptFrame* osr_frame_ = nullptr;
339 :
340 : Vector<const char> debug_name_;
341 :
342 : // Encapsulates coverage information gathered by the bytecode generator.
343 : // Needs to be stored on the shared function info once compilation completes.
344 : Handle<CoverageInfo> coverage_info_;
345 :
346 : DISALLOW_COPY_AND_ASSIGN(CompilationInfo);
347 : };
348 :
349 : } // namespace internal
350 : } // namespace v8
351 :
352 : #endif // V8_COMPILATION_INFO_H_
|