blob: 64bc88d4981d510be7d5039ede91714c6c58e96f [file] [log] [blame]
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001// Copyright 2012 the V8 project authors. All rights reserved.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
Steve Blocka7e24c12009-10-30 11:49:00 +00004
5#ifndef V8_COMPILER_H_
6#define V8_COMPILER_H_
7
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008#include "src/allocation.h"
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009#include "src/ast/ast.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010#include "src/bailout-reason.h"
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000011#include "src/compilation-dependencies.h"
Ben Murdoch097c5b22016-05-18 11:27:45 +010012#include "src/source-position.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +000013#include "src/zone.h"
Steve Blocka7e24c12009-10-30 11:49:00 +000014
15namespace v8 {
16namespace internal {
17
Ben Murdoch097c5b22016-05-18 11:27:45 +010018// Forward declarations.
Ben Murdochda12d292016-06-02 14:46:10 +010019class CompilationInfo;
Ben Murdochc5610432016-08-08 18:44:38 +010020class CompilationJob;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000021class JavaScriptFrame;
22class ParseInfo;
23class ScriptData;
Ben Murdochb8a8cc12014-11-26 15:28:44 +000024
Ben Murdochda12d292016-06-02 14:46:10 +010025// The V8 compiler API.
26//
27// This is the central hub for dispatching to the various compilers within V8.
28// Logic for which compiler to choose and how to wire compilation results into
29// the object heap should be kept inside this class.
30//
31// General strategy: Scripts are translated into anonymous functions w/o
32// parameters which then can be executed. If the source code contains other
33// functions, they might be compiled and allocated as part of the compilation
34// of the source code or deferred for lazy compilation at a later point.
35class Compiler : public AllStatic {
36 public:
37 enum ClearExceptionFlag { KEEP_EXCEPTION, CLEAR_EXCEPTION };
38 enum ConcurrencyMode { NOT_CONCURRENT, CONCURRENT };
39
40 // ===========================================================================
41 // The following family of methods ensures a given function is compiled. The
42 // general contract is that failures will be reported by returning {false},
43 // whereas successful compilation ensures the {is_compiled} predicate on the
44 // given function holds (except for live-edit, which compiles the world).
45
46 static bool Compile(Handle<JSFunction> function, ClearExceptionFlag flag);
Ben Murdochc5610432016-08-08 18:44:38 +010047 static bool CompileBaseline(Handle<JSFunction> function);
Ben Murdochda12d292016-06-02 14:46:10 +010048 static bool CompileOptimized(Handle<JSFunction> function, ConcurrencyMode);
49 static bool CompileDebugCode(Handle<JSFunction> function);
50 static bool CompileDebugCode(Handle<SharedFunctionInfo> shared);
Ben Murdochc5610432016-08-08 18:44:38 +010051 static MaybeHandle<JSArray> CompileForLiveEdit(Handle<Script> script);
Ben Murdochda12d292016-06-02 14:46:10 +010052
Ben Murdochc5610432016-08-08 18:44:38 +010053 // Generate and install code from previously queued compilation job.
54 static void FinalizeCompilationJob(CompilationJob* job);
Ben Murdochda12d292016-06-02 14:46:10 +010055
56 // Give the compiler a chance to perform low-latency initialization tasks of
57 // the given {function} on its instantiation. Note that only the runtime will
58 // offer this chance, optimized closure instantiation will not call this.
59 static void PostInstantiation(Handle<JSFunction> function, PretenureFlag);
60
61 // Parser::Parse, then Compiler::Analyze.
62 static bool ParseAndAnalyze(ParseInfo* info);
63 // Rewrite, analyze scopes, and renumber.
64 static bool Analyze(ParseInfo* info);
65 // Adds deoptimization support, requires ParseAndAnalyze.
66 static bool EnsureDeoptimizationSupport(CompilationInfo* info);
67
68 // ===========================================================================
69 // The following family of methods instantiates new functions for scripts or
70 // function literals. The decision whether those functions will be compiled,
71 // is left to the discretion of the compiler.
72 //
73 // Please note this interface returns shared function infos. This means you
74 // need to call Factory::NewFunctionFromSharedFunctionInfo before you have a
75 // real function with a context.
76
77 // Create a (bound) function for a String source within a context for eval.
78 MUST_USE_RESULT static MaybeHandle<JSFunction> GetFunctionFromEval(
79 Handle<String> source, Handle<SharedFunctionInfo> outer_info,
80 Handle<Context> context, LanguageMode language_mode,
Ben Murdochc5610432016-08-08 18:44:38 +010081 ParseRestriction restriction, int eval_scope_position, int eval_position,
82 int line_offset = 0, int column_offset = 0,
Ben Murdochda12d292016-06-02 14:46:10 +010083 Handle<Object> script_name = Handle<Object>(),
84 ScriptOriginOptions options = ScriptOriginOptions());
85
86 // Create a shared function info object for a String source within a context.
87 static Handle<SharedFunctionInfo> GetSharedFunctionInfoForScript(
88 Handle<String> source, Handle<Object> script_name, int line_offset,
89 int column_offset, ScriptOriginOptions resource_options,
90 Handle<Object> source_map_url, Handle<Context> context,
91 v8::Extension* extension, ScriptData** cached_data,
92 ScriptCompiler::CompileOptions compile_options,
93 NativesFlag is_natives_code, bool is_module);
94
95 // Create a shared function info object for a Script that has already been
96 // parsed while the script was being loaded from a streamed source.
97 static Handle<SharedFunctionInfo> GetSharedFunctionInfoForStreamedScript(
98 Handle<Script> script, ParseInfo* info, int source_length);
99
100 // Create a shared function info object (the code may be lazily compiled).
101 static Handle<SharedFunctionInfo> GetSharedFunctionInfo(
102 FunctionLiteral* node, Handle<Script> script, CompilationInfo* outer);
103
104 // Create a shared function info object for a native function literal.
105 static Handle<SharedFunctionInfo> GetSharedFunctionInfoForNative(
106 v8::Extension* extension, Handle<String> name);
107
108 // ===========================================================================
109 // The following family of methods provides support for OSR. Code generated
110 // for entry via OSR might not be suitable for normal entry, hence will be
111 // returned directly to the caller.
112 //
113 // Please note this interface is the only part dealing with {Code} objects
114 // directly. Other methods are agnostic to {Code} and can use an interpreter
115 // instead of generating JIT code for a function at all.
116
117 // Generate and return optimized code for OSR, or empty handle on failure.
118 MUST_USE_RESULT static MaybeHandle<Code> GetOptimizedCodeForOSR(
119 Handle<JSFunction> function, BailoutId osr_ast_id,
120 JavaScriptFrame* osr_frame);
121};
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000122
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000123
Andrei Popescu31002712010-02-23 13:46:05 +0000124// CompilationInfo encapsulates some information known at compile time. It
125// is constructed based on the resources available at compile-time.
Ben Murdochc5610432016-08-08 18:44:38 +0100126class CompilationInfo final {
Leon Clarke4515c472010-02-03 11:58:03 +0000127 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000128 // Various configuration flags for a compilation, as well as some properties
129 // of the compiled code produced by a compilation.
130 enum Flag {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000131 kDeferredCalling = 1 << 0,
132 kNonDeferredCalling = 1 << 1,
133 kSavesCallerDoubles = 1 << 2,
134 kRequiresFrame = 1 << 3,
135 kMustNotHaveEagerFrame = 1 << 4,
136 kDeoptimizationSupport = 1 << 5,
137 kDebug = 1 << 6,
138 kSerializing = 1 << 7,
139 kFunctionContextSpecializing = 1 << 8,
140 kFrameSpecializing = 1 << 9,
141 kNativeContextSpecializing = 1 << 10,
142 kInliningEnabled = 1 << 11,
Ben Murdochc5610432016-08-08 18:44:38 +0100143 kDisableFutureOptimization = 1 << 12,
144 kSplittingEnabled = 1 << 13,
145 kDeoptimizationEnabled = 1 << 14,
146 kSourcePositionsEnabled = 1 << 15,
147 kBailoutOnUninitialized = 1 << 16,
148 kOptimizeFromBytecode = 1 << 17,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000149 };
Ben Murdochf87a2032010-10-22 12:50:53 +0100150
Ben Murdochc5610432016-08-08 18:44:38 +0100151 CompilationInfo(ParseInfo* parse_info, Handle<JSFunction> closure);
152 CompilationInfo(Vector<const char> debug_name, Isolate* isolate, Zone* zone,
Ben Murdoch097c5b22016-05-18 11:27:45 +0100153 Code::Flags code_flags = Code::ComputeFlags(Code::STUB));
Ben Murdochc5610432016-08-08 18:44:38 +0100154 ~CompilationInfo();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000155
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000156 ParseInfo* parse_info() const { return parse_info_; }
157
158 // -----------------------------------------------------------
159 // TODO(titzer): inline and delete accessors of ParseInfo
160 // -----------------------------------------------------------
161 Handle<Script> script() const;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000162 FunctionLiteral* literal() const;
163 Scope* scope() const;
164 Handle<Context> context() const;
165 Handle<SharedFunctionInfo> shared_info() const;
166 bool has_shared_info() const;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000167 // -----------------------------------------------------------
168
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000169 Isolate* isolate() const {
Steve Block44f0eee2011-05-26 01:26:41 +0100170 return isolate_;
171 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000172 Zone* zone() { return zone_; }
173 bool is_osr() const { return !osr_ast_id_.IsNone(); }
Ben Murdochc5610432016-08-08 18:44:38 +0100174 Handle<JSFunction> closure() const { return closure_; }
Ben Murdochf87a2032010-10-22 12:50:53 +0100175 Handle<Code> code() const { return code_; }
Ben Murdoch097c5b22016-05-18 11:27:45 +0100176 Code::Flags code_flags() const { return code_flags_; }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000177 BailoutId osr_ast_id() const { return osr_ast_id_; }
Ben Murdochc5610432016-08-08 18:44:38 +0100178 JavaScriptFrame* osr_frame() const { return osr_frame_; }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000179 int num_parameters() const;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000180 int num_parameters_including_this() const;
181 bool is_this_defined() const;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000182
183 void set_parameter_count(int parameter_count) {
184 DCHECK(IsStub());
185 parameter_count_ = parameter_count;
Steve Block1e0659c2011-05-24 12:43:12 +0100186 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000187
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000188 bool has_bytecode_array() const { return !bytecode_array_.is_null(); }
189 Handle<BytecodeArray> bytecode_array() const { return bytecode_array_; }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000190
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000191 bool is_tracking_positions() const { return track_positions_; }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000192
193 bool is_calling() const {
194 return GetFlag(kDeferredCalling) || GetFlag(kNonDeferredCalling);
Steve Block44f0eee2011-05-26 01:26:41 +0100195 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000196
197 void MarkAsDeferredCalling() { SetFlag(kDeferredCalling); }
198
199 bool is_deferred_calling() const { return GetFlag(kDeferredCalling); }
200
201 void MarkAsNonDeferredCalling() { SetFlag(kNonDeferredCalling); }
202
203 bool is_non_deferred_calling() const { return GetFlag(kNonDeferredCalling); }
204
205 void MarkAsSavesCallerDoubles() { SetFlag(kSavesCallerDoubles); }
206
207 bool saves_caller_doubles() const { return GetFlag(kSavesCallerDoubles); }
208
209 void MarkAsRequiresFrame() { SetFlag(kRequiresFrame); }
210
211 bool requires_frame() const { return GetFlag(kRequiresFrame); }
212
213 void MarkMustNotHaveEagerFrame() { SetFlag(kMustNotHaveEagerFrame); }
214
215 bool GetMustNotHaveEagerFrame() const {
216 return GetFlag(kMustNotHaveEagerFrame);
217 }
218
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000219 // Compiles marked as debug produce unoptimized code with debug break slots.
220 // Inner functions that cannot be compiled w/o context are compiled eagerly.
221 // Always include deoptimization support to avoid having to recompile again.
222 void MarkAsDebug() {
223 SetFlag(kDebug);
224 SetFlag(kDeoptimizationSupport);
225 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000226
227 bool is_debug() const { return GetFlag(kDebug); }
228
229 void PrepareForSerializing() { SetFlag(kSerializing); }
230
231 bool will_serialize() const { return GetFlag(kSerializing); }
232
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000233 void MarkAsFunctionContextSpecializing() {
234 SetFlag(kFunctionContextSpecializing);
235 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000236
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000237 bool is_function_context_specializing() const {
238 return GetFlag(kFunctionContextSpecializing);
239 }
240
241 void MarkAsFrameSpecializing() { SetFlag(kFrameSpecializing); }
242
243 bool is_frame_specializing() const { return GetFlag(kFrameSpecializing); }
244
245 void MarkAsNativeContextSpecializing() {
246 SetFlag(kNativeContextSpecializing);
247 }
248
249 bool is_native_context_specializing() const {
250 return GetFlag(kNativeContextSpecializing);
251 }
252
253 void MarkAsDeoptimizationEnabled() { SetFlag(kDeoptimizationEnabled); }
254
255 bool is_deoptimization_enabled() const {
256 return GetFlag(kDeoptimizationEnabled);
257 }
258
259 void MarkAsSourcePositionsEnabled() { SetFlag(kSourcePositionsEnabled); }
260
261 bool is_source_positions_enabled() const {
262 return GetFlag(kSourcePositionsEnabled);
263 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000264
265 void MarkAsInliningEnabled() { SetFlag(kInliningEnabled); }
266
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000267 bool is_inlining_enabled() const { return GetFlag(kInliningEnabled); }
268
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000269 void MarkAsSplittingEnabled() { SetFlag(kSplittingEnabled); }
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400270
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000271 bool is_splitting_enabled() const { return GetFlag(kSplittingEnabled); }
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400272
Ben Murdoch097c5b22016-05-18 11:27:45 +0100273 void MarkAsBailoutOnUninitialized() { SetFlag(kBailoutOnUninitialized); }
274
275 bool is_bailout_on_uninitialized() const {
276 return GetFlag(kBailoutOnUninitialized);
277 }
278
Ben Murdochc5610432016-08-08 18:44:38 +0100279 void MarkAsOptimizeFromBytecode() { SetFlag(kOptimizeFromBytecode); }
280
281 bool is_optimizing_from_bytecode() const {
282 return GetFlag(kOptimizeFromBytecode);
283 }
284
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000285 bool GeneratePreagedPrologue() const {
286 // Generate a pre-aged prologue if we are optimizing for size, which
287 // will make code flushing more aggressive. Only apply to Code::FUNCTION,
288 // since StaticMarkingVisitor::IsFlushable only flushes proper functions.
Ben Murdochda12d292016-06-02 14:46:10 +0100289 return FLAG_optimize_for_size && FLAG_age_code && !is_debug() &&
290 output_code_kind() == Code::FUNCTION;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000291 }
292
Ben Murdochf87a2032010-10-22 12:50:53 +0100293 void SetCode(Handle<Code> code) { code_ = code; }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000294
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000295 void SetBytecodeArray(Handle<BytecodeArray> bytecode_array) {
296 bytecode_array_ = bytecode_array;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000297 }
298
299 bool ShouldTrapOnDeopt() const {
300 return (FLAG_trap_on_deopt && IsOptimizing()) ||
301 (FLAG_trap_on_stub_deopt && IsStub());
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100302 }
Ben Murdochb0fe1622011-05-05 13:52:32 +0100303
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000304 bool has_native_context() const {
305 return !closure().is_null() && (closure()->native_context() != nullptr);
Ben Murdochb0fe1622011-05-05 13:52:32 +0100306 }
307
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000308 Context* native_context() const {
309 return has_native_context() ? closure()->native_context() : nullptr;
310 }
311
312 bool has_global_object() const { return has_native_context(); }
313
314 JSGlobalObject* global_object() const {
315 return has_global_object() ? native_context()->global_object() : nullptr;
Ben Murdochb0fe1622011-05-05 13:52:32 +0100316 }
317
318 // Accessors for the different compilation modes.
319 bool IsOptimizing() const { return mode_ == OPTIMIZE; }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000320 bool IsStub() const { return mode_ == STUB; }
Ben Murdoch097c5b22016-05-18 11:27:45 +0100321 void SetOptimizing() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000322 DCHECK(has_shared_info());
Ben Murdochb0fe1622011-05-05 13:52:32 +0100323 SetMode(OPTIMIZE);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100324 optimization_id_ = isolate()->NextOptimizationId();
325 code_flags_ =
326 Code::KindField::update(code_flags_, Code::OPTIMIZED_FUNCTION);
327 }
Ben Murdochc5610432016-08-08 18:44:38 +0100328 void SetOptimizingForOsr(BailoutId osr_ast_id, JavaScriptFrame* osr_frame) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100329 SetOptimizing();
Ben Murdochb0fe1622011-05-05 13:52:32 +0100330 osr_ast_id_ = osr_ast_id;
Ben Murdochc5610432016-08-08 18:44:38 +0100331 osr_frame_ = osr_frame;
Ben Murdochb0fe1622011-05-05 13:52:32 +0100332 }
Ben Murdochb0fe1622011-05-05 13:52:32 +0100333
334 // Deoptimization support.
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100335 bool HasDeoptimizationSupport() const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000336 return GetFlag(kDeoptimizationSupport);
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100337 }
Ben Murdochb0fe1622011-05-05 13:52:32 +0100338 void EnableDeoptimizationSupport() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000339 DCHECK_EQ(BASE, mode_);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000340 SetFlag(kDeoptimizationSupport);
Ben Murdochb0fe1622011-05-05 13:52:32 +0100341 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000342 bool ShouldEnsureSpaceForLazyDeopt() { return !IsStub(); }
343
344 bool ExpectsJSReceiverAsReceiver();
Ben Murdochb0fe1622011-05-05 13:52:32 +0100345
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100346 // Determines whether or not to insert a self-optimization header.
347 bool ShouldSelfOptimize();
Andrei Popescu31002712010-02-23 13:46:05 +0000348
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000349 void set_deferred_handles(DeferredHandles* deferred_handles) {
350 DCHECK(deferred_handles_ == NULL);
351 deferred_handles_ = deferred_handles;
352 }
353
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000354 void ReopenHandlesInNewHandleScope() {
Ben Murdochc5610432016-08-08 18:44:38 +0100355 closure_ = Handle<JSFunction>(*closure_);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000356 }
357
358 void AbortOptimization(BailoutReason reason) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000359 DCHECK(reason != kNoReason);
360 if (bailout_reason_ == kNoReason) bailout_reason_ = reason;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000361 SetFlag(kDisableFutureOptimization);
362 }
363
364 void RetryOptimization(BailoutReason reason) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000365 DCHECK(reason != kNoReason);
366 if (GetFlag(kDisableFutureOptimization)) return;
367 bailout_reason_ = reason;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000368 }
369
370 BailoutReason bailout_reason() const { return bailout_reason_; }
371
372 int prologue_offset() const {
373 DCHECK_NE(Code::kPrologueOffsetNotSet, prologue_offset_);
374 return prologue_offset_;
375 }
376
377 void set_prologue_offset(int prologue_offset) {
378 DCHECK_EQ(Code::kPrologueOffsetNotSet, prologue_offset_);
379 prologue_offset_ = prologue_offset;
380 }
381
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000382 CompilationDependencies* dependencies() { return &dependencies_; }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000383
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000384 int optimization_id() const { return optimization_id_; }
385
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000386 int osr_expr_stack_height() { return osr_expr_stack_height_; }
387 void set_osr_expr_stack_height(int height) {
388 DCHECK(height >= 0);
389 osr_expr_stack_height_ = height;
390 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000391
392#if DEBUG
393 void PrintAstForTesting();
394#endif
395
396 bool has_simple_parameters();
397
398 struct InlinedFunctionHolder {
399 Handle<SharedFunctionInfo> shared_info;
400
401 // Root that holds the unoptimized code of the inlined function alive
402 // (and out of reach of code flushing) until we finish compilation.
403 // Do not remove.
404 Handle<Code> inlined_code_object_root;
405
406 explicit InlinedFunctionHolder(
407 Handle<SharedFunctionInfo> inlined_shared_info)
408 : shared_info(inlined_shared_info),
409 inlined_code_object_root(inlined_shared_info->code()) {}
410 };
411
412 typedef std::vector<InlinedFunctionHolder> InlinedFunctionList;
413 InlinedFunctionList const& inlined_functions() const {
414 return inlined_functions_;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000415 }
416
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000417 void AddInlinedFunction(Handle<SharedFunctionInfo> inlined_function) {
418 inlined_functions_.push_back(InlinedFunctionHolder(inlined_function));
419 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000420
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000421 base::SmartArrayPointer<char> GetDebugName() const;
422
Ben Murdoch097c5b22016-05-18 11:27:45 +0100423 Code::Kind output_code_kind() const {
424 return Code::ExtractKindFromFlags(code_flags_);
425 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000426
Ben Murdochda12d292016-06-02 14:46:10 +0100427 StackFrame::Type GetOutputStackFrameType() const;
428
Ben Murdochc5610432016-08-08 18:44:38 +0100429 int GetDeclareGlobalsFlags() const;
430
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000431 protected:
432 ParseInfo* parse_info_;
433
434 void DisableFutureOptimization() {
435 if (GetFlag(kDisableFutureOptimization) && has_shared_info()) {
Ben Murdochda12d292016-06-02 14:46:10 +0100436 // If Crankshaft tried to optimize this function, bailed out, and
437 // doesn't want to try again, then use TurboFan next time.
438 if (!shared_info()->dont_crankshaft() &&
439 bailout_reason() != kOptimizedTooManyTimes) {
440 shared_info()->set_dont_crankshaft(true);
441 if (FLAG_trace_opt) {
442 PrintF("[disabled Crankshaft for ");
443 shared_info()->ShortPrint();
444 PrintF(", reason: %s]\n", GetBailoutReason(bailout_reason()));
445 }
446 } else {
447 shared_info()->DisableOptimization(bailout_reason());
448 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000449 }
450 }
Ben Murdoch257744e2011-11-30 15:57:28 +0000451
Leon Clarke4515c472010-02-03 11:58:03 +0000452 private:
Ben Murdochb0fe1622011-05-05 13:52:32 +0100453 // Compilation mode.
454 // BASE is generated by the full codegen, optionally prepared for bailouts.
455 // OPTIMIZE is optimized code generated by the Hydrogen-based backend.
Ben Murdochb0fe1622011-05-05 13:52:32 +0100456 enum Mode {
457 BASE,
458 OPTIMIZE,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000459 STUB
Ben Murdochb0fe1622011-05-05 13:52:32 +0100460 };
461
Ben Murdochc5610432016-08-08 18:44:38 +0100462 CompilationInfo(ParseInfo* parse_info, Vector<const char> debug_name,
Ben Murdoch097c5b22016-05-18 11:27:45 +0100463 Code::Flags code_flags, Mode mode, Isolate* isolate,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000464 Zone* zone);
465
466 Isolate* isolate_;
Ben Murdochb0fe1622011-05-05 13:52:32 +0100467
468 void SetMode(Mode mode) {
Ben Murdochb0fe1622011-05-05 13:52:32 +0100469 mode_ = mode;
470 }
471
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000472 void SetFlag(Flag flag) { flags_ |= flag; }
Andrei Popescu31002712010-02-23 13:46:05 +0000473
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000474 void SetFlag(Flag flag, bool value) {
475 flags_ = value ? flags_ | flag : flags_ & ~flag;
476 }
477
478 bool GetFlag(Flag flag) const { return (flags_ & flag) != 0; }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000479
Ben Murdochf87a2032010-10-22 12:50:53 +0100480 unsigned flags_;
481
Ben Murdoch097c5b22016-05-18 11:27:45 +0100482 Code::Flags code_flags_;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000483
Ben Murdochc5610432016-08-08 18:44:38 +0100484 Handle<JSFunction> closure_;
485
Ben Murdochf87a2032010-10-22 12:50:53 +0100486 // The compiled code.
487 Handle<Code> code_;
488
Ben Murdochb0fe1622011-05-05 13:52:32 +0100489 // Compilation mode flag and whether deoptimization is allowed.
490 Mode mode_;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000491 BailoutId osr_ast_id_;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000492
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000493 // Holds the bytecode array generated by the interpreter.
494 // TODO(rmcilroy/mstarzinger): Temporary work-around until compiler.cc is
495 // refactored to avoid us needing to carry the BytcodeArray around.
496 Handle<BytecodeArray> bytecode_array_;
497
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000498 // The zone from which the compilation pipeline working on this
499 // CompilationInfo allocates.
500 Zone* zone_;
501
502 DeferredHandles* deferred_handles_;
503
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000504 // Dependencies for this compilation, e.g. stable maps.
505 CompilationDependencies dependencies_;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000506
507 BailoutReason bailout_reason_;
508
509 int prologue_offset_;
510
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000511 bool track_positions_;
512
513 InlinedFunctionList inlined_functions_;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000514
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000515 // Number of parameters used for compilation of stubs that require arguments.
516 int parameter_count_;
517
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000518 int optimization_id_;
519
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000520 int osr_expr_stack_height_;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000521
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000522 // The current OSR frame for specialization or {nullptr}.
523 JavaScriptFrame* osr_frame_ = nullptr;
524
Ben Murdochc5610432016-08-08 18:44:38 +0100525 Vector<const char> debug_name_;
Ben Murdochb0fe1622011-05-05 13:52:32 +0100526
Andrei Popescu31002712010-02-23 13:46:05 +0000527 DISALLOW_COPY_AND_ASSIGN(CompilationInfo);
Leon Clarke4515c472010-02-03 11:58:03 +0000528};
529
Ben Murdochc5610432016-08-08 18:44:38 +0100530// A base class for compilation jobs intended to run concurrent to the main
531// thread. The job is split into three phases which are called in sequence on
532// different threads and with different limitations:
533// 1) CreateGraph: Runs on main thread. No major limitations.
534// 2) OptimizeGraph: Runs concurrently. No heap allocation or handle derefs.
535// 3) GenerateCode: Runs on main thread. No dependency changes.
536//
537// Each of the three phases can either fail or succeed. Apart from their return
538// value, the status of the phase last run can be checked using {last_status()}
539// as well. When failing we distinguish between the following levels:
540// a) AbortOptimization: Persistent failure, disable future optimization.
541// b) RetryOptimzation: Transient failure, try again next time.
542class CompilationJob {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000543 public:
Ben Murdochc5610432016-08-08 18:44:38 +0100544 explicit CompilationJob(CompilationInfo* info, const char* compiler_name)
545 : info_(info), compiler_name_(compiler_name), last_status_(SUCCEEDED) {}
546 virtual ~CompilationJob() {}
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000547
Ben Murdochc5610432016-08-08 18:44:38 +0100548 enum Status { FAILED, SUCCEEDED };
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000549
550 MUST_USE_RESULT Status CreateGraph();
551 MUST_USE_RESULT Status OptimizeGraph();
552 MUST_USE_RESULT Status GenerateCode();
553
554 Status last_status() const { return last_status_; }
555 CompilationInfo* info() const { return info_; }
556 Isolate* isolate() const { return info()->isolate(); }
557
558 Status RetryOptimization(BailoutReason reason) {
559 info_->RetryOptimization(reason);
Ben Murdochc5610432016-08-08 18:44:38 +0100560 return SetLastStatus(FAILED);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000561 }
562
563 Status AbortOptimization(BailoutReason reason) {
564 info_->AbortOptimization(reason);
Ben Murdochc5610432016-08-08 18:44:38 +0100565 return SetLastStatus(FAILED);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000566 }
567
Ben Murdochc5610432016-08-08 18:44:38 +0100568 void RecordOptimizationStats();
569
570 protected:
571 void RegisterWeakObjectsInOptimizedCode(Handle<Code> code);
572
573 // Overridden by the actual implementation.
574 virtual Status CreateGraphImpl() = 0;
575 virtual Status OptimizeGraphImpl() = 0;
576 virtual Status GenerateCodeImpl() = 0;
577
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000578 private:
579 CompilationInfo* info_;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000580 base::TimeDelta time_taken_to_create_graph_;
581 base::TimeDelta time_taken_to_optimize_;
582 base::TimeDelta time_taken_to_codegen_;
Ben Murdochc5610432016-08-08 18:44:38 +0100583 const char* compiler_name_;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000584 Status last_status_;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000585
586 MUST_USE_RESULT Status SetLastStatus(Status status) {
587 last_status_ = status;
588 return last_status_;
589 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000590};
591
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000592} // namespace internal
593} // namespace v8
Steve Blocka7e24c12009-10-30 11:49:00 +0000594
595#endif // V8_COMPILER_H_