Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(166)

Side by Side Diff: src/compiler.h

Issue 2284313003: Separate CompilationInfo into its own file. (Closed)
Patch Set: fix Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/compilation-info.cc ('k') | src/compiler.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #ifndef V8_COMPILER_H_ 5 #ifndef V8_COMPILER_H_
6 #define V8_COMPILER_H_ 6 #define V8_COMPILER_H_
7 7
8 #include <memory> 8 #include <memory>
9 9
10 #include "src/allocation.h" 10 #include "src/allocation.h"
11 #include "src/bailout-reason.h" 11 #include "src/bailout-reason.h"
12 #include "src/compilation-dependencies.h"
13 #include "src/contexts.h" 12 #include "src/contexts.h"
14 #include "src/frames.h"
15 #include "src/isolate.h" 13 #include "src/isolate.h"
16 #include "src/source-position-table.h"
17 #include "src/source-position.h"
18 #include "src/zone.h" 14 #include "src/zone.h"
19 15
20 namespace v8 { 16 namespace v8 {
21 namespace internal { 17 namespace internal {
22 18
23 // Forward declarations. 19 // Forward declarations.
24 class CompilationInfo; 20 class CompilationInfo;
25 class CompilationJob; 21 class CompilationJob;
26 class JavaScriptFrame; 22 class JavaScriptFrame;
27 class ParseInfo; 23 class ParseInfo;
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
134 // Please note this interface is the only part dealing with {Code} objects 130 // Please note this interface is the only part dealing with {Code} objects
135 // directly. Other methods are agnostic to {Code} and can use an interpreter 131 // directly. Other methods are agnostic to {Code} and can use an interpreter
136 // instead of generating JIT code for a function at all. 132 // instead of generating JIT code for a function at all.
137 133
138 // Generate and return optimized code for OSR, or empty handle on failure. 134 // Generate and return optimized code for OSR, or empty handle on failure.
139 MUST_USE_RESULT static MaybeHandle<Code> GetOptimizedCodeForOSR( 135 MUST_USE_RESULT static MaybeHandle<Code> GetOptimizedCodeForOSR(
140 Handle<JSFunction> function, BailoutId osr_ast_id, 136 Handle<JSFunction> function, BailoutId osr_ast_id,
141 JavaScriptFrame* osr_frame); 137 JavaScriptFrame* osr_frame);
142 }; 138 };
143 139
144
145 // CompilationInfo encapsulates some information known at compile time. It
146 // is constructed based on the resources available at compile-time.
147 class CompilationInfo final {
148 public:
149 // Various configuration flags for a compilation, as well as some properties
150 // of the compiled code produced by a compilation.
151 enum Flag {
152 kDeferredCalling = 1 << 0,
153 kNonDeferredCalling = 1 << 1,
154 kSavesCallerDoubles = 1 << 2,
155 kRequiresFrame = 1 << 3,
156 kMustNotHaveEagerFrame = 1 << 4,
157 kDeoptimizationSupport = 1 << 5,
158 kDebug = 1 << 6,
159 kSerializing = 1 << 7,
160 kFunctionContextSpecializing = 1 << 8,
161 kFrameSpecializing = 1 << 9,
162 kNativeContextSpecializing = 1 << 10,
163 kInliningEnabled = 1 << 11,
164 kDisableFutureOptimization = 1 << 12,
165 kSplittingEnabled = 1 << 13,
166 kDeoptimizationEnabled = 1 << 14,
167 kSourcePositionsEnabled = 1 << 15,
168 kBailoutOnUninitialized = 1 << 16,
169 kOptimizeFromBytecode = 1 << 17,
170 kTypeFeedbackEnabled = 1 << 18,
171 kAccessorInliningEnabled = 1 << 19,
172 };
173
174 CompilationInfo(ParseInfo* parse_info, Handle<JSFunction> closure);
175 CompilationInfo(Vector<const char> debug_name, Isolate* isolate, Zone* zone,
176 Code::Flags code_flags);
177 ~CompilationInfo();
178
179 ParseInfo* parse_info() const { return parse_info_; }
180
181 // -----------------------------------------------------------
182 // TODO(titzer): inline and delete accessors of ParseInfo
183 // -----------------------------------------------------------
184 Handle<Script> script() const;
185 FunctionLiteral* literal() const;
186 DeclarationScope* scope() const;
187 Handle<Context> context() const;
188 Handle<SharedFunctionInfo> shared_info() const;
189 bool has_shared_info() const;
190 // -----------------------------------------------------------
191
192 Isolate* isolate() const {
193 return isolate_;
194 }
195 Zone* zone() { return zone_; }
196 bool is_osr() const { return !osr_ast_id_.IsNone(); }
197 Handle<JSFunction> closure() const { return closure_; }
198 Handle<Code> code() const { return code_; }
199 Code::Flags code_flags() const { return code_flags_; }
200 BailoutId osr_ast_id() const { return osr_ast_id_; }
201 JavaScriptFrame* osr_frame() const { return osr_frame_; }
202 int num_parameters() const;
203 int num_parameters_including_this() const;
204 bool is_this_defined() const;
205
206 void set_parameter_count(int parameter_count) {
207 DCHECK(IsStub());
208 parameter_count_ = parameter_count;
209 }
210
211 bool has_bytecode_array() const { return !bytecode_array_.is_null(); }
212 Handle<BytecodeArray> bytecode_array() const { return bytecode_array_; }
213
214 bool is_tracking_positions() const { return track_positions_; }
215
216 bool is_calling() const {
217 return GetFlag(kDeferredCalling) || GetFlag(kNonDeferredCalling);
218 }
219
220 void MarkAsDeferredCalling() { SetFlag(kDeferredCalling); }
221
222 bool is_deferred_calling() const { return GetFlag(kDeferredCalling); }
223
224 void MarkAsNonDeferredCalling() { SetFlag(kNonDeferredCalling); }
225
226 bool is_non_deferred_calling() const { return GetFlag(kNonDeferredCalling); }
227
228 void MarkAsSavesCallerDoubles() { SetFlag(kSavesCallerDoubles); }
229
230 bool saves_caller_doubles() const { return GetFlag(kSavesCallerDoubles); }
231
232 void MarkAsRequiresFrame() { SetFlag(kRequiresFrame); }
233
234 bool requires_frame() const { return GetFlag(kRequiresFrame); }
235
236 void MarkMustNotHaveEagerFrame() { SetFlag(kMustNotHaveEagerFrame); }
237
238 bool GetMustNotHaveEagerFrame() const {
239 return GetFlag(kMustNotHaveEagerFrame);
240 }
241
242 // Compiles marked as debug produce unoptimized code with debug break slots.
243 // Inner functions that cannot be compiled w/o context are compiled eagerly.
244 // Always include deoptimization support to avoid having to recompile again.
245 void MarkAsDebug() {
246 SetFlag(kDebug);
247 SetFlag(kDeoptimizationSupport);
248 }
249
250 bool is_debug() const { return GetFlag(kDebug); }
251
252 void PrepareForSerializing() { SetFlag(kSerializing); }
253
254 bool will_serialize() const { return GetFlag(kSerializing); }
255
256 void MarkAsFunctionContextSpecializing() {
257 SetFlag(kFunctionContextSpecializing);
258 }
259
260 bool is_function_context_specializing() const {
261 return GetFlag(kFunctionContextSpecializing);
262 }
263
264 void MarkAsFrameSpecializing() { SetFlag(kFrameSpecializing); }
265
266 bool is_frame_specializing() const { return GetFlag(kFrameSpecializing); }
267
268 void MarkAsNativeContextSpecializing() {
269 SetFlag(kNativeContextSpecializing);
270 }
271
272 bool is_native_context_specializing() const {
273 return GetFlag(kNativeContextSpecializing);
274 }
275
276 void MarkAsDeoptimizationEnabled() { SetFlag(kDeoptimizationEnabled); }
277
278 bool is_deoptimization_enabled() const {
279 return GetFlag(kDeoptimizationEnabled);
280 }
281
282 void MarkAsTypeFeedbackEnabled() { SetFlag(kTypeFeedbackEnabled); }
283
284 bool is_type_feedback_enabled() const {
285 return GetFlag(kTypeFeedbackEnabled);
286 }
287
288 void MarkAsAccessorInliningEnabled() { SetFlag(kAccessorInliningEnabled); }
289
290 bool is_accessor_inlining_enabled() const {
291 return GetFlag(kAccessorInliningEnabled);
292 }
293
294 void MarkAsSourcePositionsEnabled() { SetFlag(kSourcePositionsEnabled); }
295
296 bool is_source_positions_enabled() const {
297 return GetFlag(kSourcePositionsEnabled);
298 }
299
300 void MarkAsInliningEnabled() { SetFlag(kInliningEnabled); }
301
302 bool is_inlining_enabled() const { return GetFlag(kInliningEnabled); }
303
304 void MarkAsSplittingEnabled() { SetFlag(kSplittingEnabled); }
305
306 bool is_splitting_enabled() const { return GetFlag(kSplittingEnabled); }
307
308 void MarkAsBailoutOnUninitialized() { SetFlag(kBailoutOnUninitialized); }
309
310 bool is_bailout_on_uninitialized() const {
311 return GetFlag(kBailoutOnUninitialized);
312 }
313
314 void MarkAsOptimizeFromBytecode() { SetFlag(kOptimizeFromBytecode); }
315
316 bool is_optimizing_from_bytecode() const {
317 return GetFlag(kOptimizeFromBytecode);
318 }
319
320 bool GeneratePreagedPrologue() const {
321 // Generate a pre-aged prologue if we are optimizing for size, which
322 // will make code flushing more aggressive. Only apply to Code::FUNCTION,
323 // since StaticMarkingVisitor::IsFlushable only flushes proper functions.
324 return FLAG_optimize_for_size && FLAG_age_code && !is_debug() &&
325 output_code_kind() == Code::FUNCTION;
326 }
327
328 void SetCode(Handle<Code> code) { code_ = code; }
329
330 void SetBytecodeArray(Handle<BytecodeArray> bytecode_array) {
331 bytecode_array_ = bytecode_array;
332 }
333
334 bool ShouldTrapOnDeopt() const {
335 return (FLAG_trap_on_deopt && IsOptimizing()) ||
336 (FLAG_trap_on_stub_deopt && IsStub());
337 }
338
339 bool has_native_context() const;
340 Context* native_context() const;
341
342 bool has_global_object() const;
343 JSGlobalObject* global_object() const;
344
345 // Accessors for the different compilation modes.
346 bool IsOptimizing() const { return mode_ == OPTIMIZE; }
347 bool IsStub() const { return mode_ == STUB; }
348 void SetOptimizing() {
349 DCHECK(has_shared_info());
350 SetMode(OPTIMIZE);
351 optimization_id_ = isolate()->NextOptimizationId();
352 code_flags_ =
353 Code::KindField::update(code_flags_, Code::OPTIMIZED_FUNCTION);
354 }
355 void SetOptimizingForOsr(BailoutId osr_ast_id, JavaScriptFrame* osr_frame) {
356 SetOptimizing();
357 osr_ast_id_ = osr_ast_id;
358 osr_frame_ = osr_frame;
359 }
360
361 // Deoptimization support.
362 bool HasDeoptimizationSupport() const {
363 return GetFlag(kDeoptimizationSupport);
364 }
365 void EnableDeoptimizationSupport() {
366 DCHECK_EQ(BASE, mode_);
367 SetFlag(kDeoptimizationSupport);
368 }
369 bool ShouldEnsureSpaceForLazyDeopt() { return !IsStub(); }
370
371 bool ExpectsJSReceiverAsReceiver();
372
373 // Determines whether or not to insert a self-optimization header.
374 bool ShouldSelfOptimize();
375
376 void set_deferred_handles(DeferredHandles* deferred_handles) {
377 DCHECK(deferred_handles_ == NULL);
378 deferred_handles_ = deferred_handles;
379 }
380
381 void ReopenHandlesInNewHandleScope();
382
383 void AbortOptimization(BailoutReason reason) {
384 DCHECK(reason != kNoReason);
385 if (bailout_reason_ == kNoReason) bailout_reason_ = reason;
386 SetFlag(kDisableFutureOptimization);
387 }
388
389 void RetryOptimization(BailoutReason reason) {
390 DCHECK(reason != kNoReason);
391 if (GetFlag(kDisableFutureOptimization)) return;
392 bailout_reason_ = reason;
393 }
394
395 BailoutReason bailout_reason() const { return bailout_reason_; }
396
397 int prologue_offset() const {
398 DCHECK_NE(Code::kPrologueOffsetNotSet, prologue_offset_);
399 return prologue_offset_;
400 }
401
402 void set_prologue_offset(int prologue_offset) {
403 DCHECK_EQ(Code::kPrologueOffsetNotSet, prologue_offset_);
404 prologue_offset_ = prologue_offset;
405 }
406
407 CompilationDependencies* dependencies() { return &dependencies_; }
408
409 int optimization_id() const { return optimization_id_; }
410
411 int osr_expr_stack_height() { return osr_expr_stack_height_; }
412 void set_osr_expr_stack_height(int height) {
413 DCHECK(height >= 0);
414 osr_expr_stack_height_ = height;
415 }
416
417 bool has_simple_parameters();
418
419 struct InlinedFunctionHolder {
420 Handle<SharedFunctionInfo> shared_info;
421
422 // Root that holds the unoptimized code of the inlined function alive
423 // (and out of reach of code flushing) until we finish compilation.
424 // Do not remove.
425 Handle<Code> inlined_code_object_root;
426
427 InlinedFunctionHolder(Handle<SharedFunctionInfo> inlined_shared_info,
428 Handle<Code> inlined_code_object_root)
429 : shared_info(inlined_shared_info),
430 inlined_code_object_root(inlined_code_object_root) {}
431 };
432
433 typedef std::vector<InlinedFunctionHolder> InlinedFunctionList;
434 InlinedFunctionList const& inlined_functions() const {
435 return inlined_functions_;
436 }
437
438 void AddInlinedFunction(Handle<SharedFunctionInfo> inlined_function);
439
440 std::unique_ptr<char[]> GetDebugName() const;
441
442 Code::Kind output_code_kind() const;
443
444 StackFrame::Type GetOutputStackFrameType() const;
445
446 int GetDeclareGlobalsFlags() const;
447
448 SourcePositionTableBuilder::RecordingMode SourcePositionRecordingMode() const;
449
450 private:
451 // Compilation mode.
452 // BASE is generated by the full codegen, optionally prepared for bailouts.
453 // OPTIMIZE is optimized code generated by the Hydrogen-based backend.
454 enum Mode {
455 BASE,
456 OPTIMIZE,
457 STUB
458 };
459
460 CompilationInfo(ParseInfo* parse_info, Vector<const char> debug_name,
461 Code::Flags code_flags, Mode mode, Isolate* isolate,
462 Zone* zone);
463
464 ParseInfo* parse_info_;
465 Isolate* isolate_;
466
467 void SetMode(Mode mode) {
468 mode_ = mode;
469 }
470
471 void SetFlag(Flag flag) { flags_ |= flag; }
472
473 void SetFlag(Flag flag, bool value) {
474 flags_ = value ? flags_ | flag : flags_ & ~flag;
475 }
476
477 bool GetFlag(Flag flag) const { return (flags_ & flag) != 0; }
478
479 unsigned flags_;
480
481 Code::Flags code_flags_;
482
483 Handle<JSFunction> closure_;
484
485 // The compiled code.
486 Handle<Code> code_;
487
488 // Compilation mode flag and whether deoptimization is allowed.
489 Mode mode_;
490 BailoutId osr_ast_id_;
491
492 // Holds the bytecode array generated by the interpreter.
493 // TODO(rmcilroy/mstarzinger): Temporary work-around until compiler.cc is
494 // refactored to avoid us needing to carry the BytcodeArray around.
495 Handle<BytecodeArray> bytecode_array_;
496
497 // The zone from which the compilation pipeline working on this
498 // CompilationInfo allocates.
499 Zone* zone_;
500
501 DeferredHandles* deferred_handles_;
502
503 // Dependencies for this compilation, e.g. stable maps.
504 CompilationDependencies dependencies_;
505
506 BailoutReason bailout_reason_;
507
508 int prologue_offset_;
509
510 bool track_positions_;
511
512 InlinedFunctionList inlined_functions_;
513
514 // Number of parameters used for compilation of stubs that require arguments.
515 int parameter_count_;
516
517 int optimization_id_;
518
519 int osr_expr_stack_height_;
520
521 // The current OSR frame for specialization or {nullptr}.
522 JavaScriptFrame* osr_frame_ = nullptr;
523
524 Vector<const char> debug_name_;
525
526 DISALLOW_COPY_AND_ASSIGN(CompilationInfo);
527 };
528
529 // A base class for compilation jobs intended to run concurrent to the main 140 // A base class for compilation jobs intended to run concurrent to the main
530 // thread. The job is split into three phases which are called in sequence on 141 // thread. The job is split into three phases which are called in sequence on
531 // different threads and with different limitations: 142 // different threads and with different limitations:
532 // 1) PrepareJob: Runs on main thread. No major limitations. 143 // 1) PrepareJob: Runs on main thread. No major limitations.
533 // 2) ExecuteJob: Runs concurrently. No heap allocation or handle derefs. 144 // 2) ExecuteJob: Runs concurrently. No heap allocation or handle derefs.
534 // 3) FinalizeJob: Runs on main thread. No dependency changes. 145 // 3) FinalizeJob: Runs on main thread. No dependency changes.
535 // 146 //
536 // Each of the three phases can either fail or succeed. The current state of 147 // Each of the three phases can either fail or succeed. The current state of
537 // the job can be checked using {state()}. 148 // the job can be checked using {state()}.
538 class CompilationJob { 149 class CompilationJob {
(...skipping 21 matching lines...) Expand all
560 171
561 // Executes the compile job. Can be called on a background thread if 172 // Executes the compile job. Can be called on a background thread if
562 // can_execute_on_background_thread() returns true. 173 // can_execute_on_background_thread() returns true.
563 MUST_USE_RESULT Status ExecuteJob(); 174 MUST_USE_RESULT Status ExecuteJob();
564 175
565 // Finalizes the compile job. Must be called on the main thread. 176 // Finalizes the compile job. Must be called on the main thread.
566 MUST_USE_RESULT Status FinalizeJob(); 177 MUST_USE_RESULT Status FinalizeJob();
567 178
568 // Report a transient failure, try again next time. Should only be called on 179 // Report a transient failure, try again next time. Should only be called on
569 // optimization compilation jobs. 180 // optimization compilation jobs.
570 Status RetryOptimization(BailoutReason reason) { 181 Status RetryOptimization(BailoutReason reason);
571 DCHECK(info_->IsOptimizing());
572 info_->RetryOptimization(reason);
573 state_ = State::kFailed;
574 return FAILED;
575 }
576 182
577 // Report a persistent failure, disable future optimization on the function. 183 // Report a persistent failure, disable future optimization on the function.
578 // Should only be called on optimization compilation jobs. 184 // Should only be called on optimization compilation jobs.
579 Status AbortOptimization(BailoutReason reason) { 185 Status AbortOptimization(BailoutReason reason);
580 DCHECK(info_->IsOptimizing());
581 info_->AbortOptimization(reason);
582 state_ = State::kFailed;
583 return FAILED;
584 }
585 186
586 void RecordOptimizedCompilationStats() const; 187 void RecordOptimizedCompilationStats() const;
587 void RecordUnoptimizedCompilationStats() const; 188 void RecordUnoptimizedCompilationStats() const;
588 189
589 virtual bool can_execute_on_background_thread() const { return true; } 190 virtual bool can_execute_on_background_thread() const { return true; }
590 191
591 void set_stack_limit(uintptr_t stack_limit) { stack_limit_ = stack_limit; } 192 void set_stack_limit(uintptr_t stack_limit) { stack_limit_ = stack_limit; }
592 uintptr_t stack_limit() const { return stack_limit_; } 193 uintptr_t stack_limit() const { return stack_limit_; }
593 194
594 State state() const { return state_; } 195 State state() const { return state_; }
595 CompilationInfo* info() const { return info_; } 196 CompilationInfo* info() const { return info_; }
596 Isolate* isolate() const { return info()->isolate(); } 197 Isolate* isolate() const;
597 198
598 protected: 199 protected:
599 // Overridden by the actual implementation. 200 // Overridden by the actual implementation.
600 virtual Status PrepareJobImpl() = 0; 201 virtual Status PrepareJobImpl() = 0;
601 virtual Status ExecuteJobImpl() = 0; 202 virtual Status ExecuteJobImpl() = 0;
602 virtual Status FinalizeJobImpl() = 0; 203 virtual Status FinalizeJobImpl() = 0;
603 204
604 // Registers weak object to optimized code dependencies. 205 // Registers weak object to optimized code dependencies.
605 // TODO(turbofan): Move this to pipeline.cc once Crankshaft dies. 206 // TODO(turbofan): Move this to pipeline.cc once Crankshaft dies.
606 void RegisterWeakObjectsInOptimizedCode(Handle<Code> code); 207 void RegisterWeakObjectsInOptimizedCode(Handle<Code> code);
(...skipping 14 matching lines...) Expand all
621 state_ = State::kFailed; 222 state_ = State::kFailed;
622 } 223 }
623 return status; 224 return status;
624 } 225 }
625 }; 226 };
626 227
627 } // namespace internal 228 } // namespace internal
628 } // namespace v8 229 } // namespace v8
629 230
630 #endif // V8_COMPILER_H_ 231 #endif // V8_COMPILER_H_
OLDNEW
« no previous file with comments | « src/compilation-info.cc ('k') | src/compiler.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698