blob: bfeaa8e7c336f739514de2d8db7b39d7ad2fdff2 [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 Murdochf91f0612016-11-29 16:50:11 +00008#include <memory>
9
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010#include "src/allocation.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +000011#include "src/bailout-reason.h"
Ben Murdochf91f0612016-11-29 16:50:11 +000012#include "src/contexts.h"
Ben Murdochf91f0612016-11-29 16:50:11 +000013#include "src/isolate.h"
Ben Murdochf3b273f2017-01-17 12:11:28 +000014#include "src/zone/zone.h"
Steve Blocka7e24c12009-10-30 11:49:00 +000015
16namespace v8 {
17namespace internal {
18
Ben Murdoch109988c2016-05-18 11:27:45 +010019// Forward declarations.
Ben Murdoch3b9bc312016-06-02 14:46:10 +010020class CompilationInfo;
Ben Murdochbcf72ee2016-08-08 18:44:38 +010021class CompilationJob;
Ben Murdoch014dc512016-03-22 12:00:34 +000022class JavaScriptFrame;
23class ParseInfo;
24class ScriptData;
Ben Murdochb8a8cc12014-11-26 15:28:44 +000025
Ben Murdoch3b9bc312016-06-02 14:46:10 +010026// The V8 compiler API.
27//
28// This is the central hub for dispatching to the various compilers within V8.
29// Logic for which compiler to choose and how to wire compilation results into
30// the object heap should be kept inside this class.
31//
32// General strategy: Scripts are translated into anonymous functions w/o
33// parameters which then can be executed. If the source code contains other
34// functions, they might be compiled and allocated as part of the compilation
35// of the source code or deferred for lazy compilation at a later point.
36class Compiler : public AllStatic {
37 public:
38 enum ClearExceptionFlag { KEEP_EXCEPTION, CLEAR_EXCEPTION };
39 enum ConcurrencyMode { NOT_CONCURRENT, CONCURRENT };
Ben Murdochf91f0612016-11-29 16:50:11 +000040 enum CompilationTier { INTERPRETED, BASELINE, OPTIMIZED };
Ben Murdoch3b9bc312016-06-02 14:46:10 +010041
42 // ===========================================================================
43 // The following family of methods ensures a given function is compiled. The
44 // general contract is that failures will be reported by returning {false},
45 // whereas successful compilation ensures the {is_compiled} predicate on the
46 // given function holds (except for live-edit, which compiles the world).
47
48 static bool Compile(Handle<JSFunction> function, ClearExceptionFlag flag);
Ben Murdochbcf72ee2016-08-08 18:44:38 +010049 static bool CompileBaseline(Handle<JSFunction> function);
Ben Murdoch3b9bc312016-06-02 14:46:10 +010050 static bool CompileOptimized(Handle<JSFunction> function, ConcurrencyMode);
51 static bool CompileDebugCode(Handle<JSFunction> function);
52 static bool CompileDebugCode(Handle<SharedFunctionInfo> shared);
Ben Murdochbcf72ee2016-08-08 18:44:38 +010053 static MaybeHandle<JSArray> CompileForLiveEdit(Handle<Script> script);
Ben Murdoch3b9bc312016-06-02 14:46:10 +010054
Ben Murdochf3b273f2017-01-17 12:11:28 +000055 // Prepare a compilation job for unoptimized code. Requires ParseAndAnalyse.
56 static CompilationJob* PrepareUnoptimizedCompilationJob(
57 CompilationInfo* info);
58
Ben Murdochbcf72ee2016-08-08 18:44:38 +010059 // Generate and install code from previously queued compilation job.
Ben Murdochf3b273f2017-01-17 12:11:28 +000060 static bool FinalizeCompilationJob(CompilationJob* job);
Ben Murdoch3b9bc312016-06-02 14:46:10 +010061
62 // Give the compiler a chance to perform low-latency initialization tasks of
63 // the given {function} on its instantiation. Note that only the runtime will
64 // offer this chance, optimized closure instantiation will not call this.
65 static void PostInstantiation(Handle<JSFunction> function, PretenureFlag);
66
67 // Parser::Parse, then Compiler::Analyze.
68 static bool ParseAndAnalyze(ParseInfo* info);
69 // Rewrite, analyze scopes, and renumber.
70 static bool Analyze(ParseInfo* info);
71 // Adds deoptimization support, requires ParseAndAnalyze.
72 static bool EnsureDeoptimizationSupport(CompilationInfo* info);
Ben Murdochf91f0612016-11-29 16:50:11 +000073 // Ensures that bytecode is generated, calls ParseAndAnalyze internally.
74 static bool EnsureBytecode(CompilationInfo* info);
75
76 // The next compilation tier which the function should be compiled to for
77 // optimization. This is used as a hint by the runtime profiler.
78 static CompilationTier NextCompilationTier(JSFunction* function);
Ben Murdoch3b9bc312016-06-02 14:46:10 +010079
80 // ===========================================================================
81 // The following family of methods instantiates new functions for scripts or
82 // function literals. The decision whether those functions will be compiled,
83 // is left to the discretion of the compiler.
84 //
85 // Please note this interface returns shared function infos. This means you
86 // need to call Factory::NewFunctionFromSharedFunctionInfo before you have a
87 // real function with a context.
88
89 // Create a (bound) function for a String source within a context for eval.
90 MUST_USE_RESULT static MaybeHandle<JSFunction> GetFunctionFromEval(
91 Handle<String> source, Handle<SharedFunctionInfo> outer_info,
92 Handle<Context> context, LanguageMode language_mode,
Ben Murdochbcf72ee2016-08-08 18:44:38 +010093 ParseRestriction restriction, int eval_scope_position, int eval_position,
94 int line_offset = 0, int column_offset = 0,
Ben Murdoch3b9bc312016-06-02 14:46:10 +010095 Handle<Object> script_name = Handle<Object>(),
96 ScriptOriginOptions options = ScriptOriginOptions());
97
Ben Murdochf91f0612016-11-29 16:50:11 +000098 // Create a (bound) function for a String source within a context for eval.
99 MUST_USE_RESULT static MaybeHandle<JSFunction> GetFunctionFromString(
100 Handle<Context> context, Handle<String> source,
101 ParseRestriction restriction);
102
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100103 // Create a shared function info object for a String source within a context.
104 static Handle<SharedFunctionInfo> GetSharedFunctionInfoForScript(
105 Handle<String> source, Handle<Object> script_name, int line_offset,
106 int column_offset, ScriptOriginOptions resource_options,
107 Handle<Object> source_map_url, Handle<Context> context,
108 v8::Extension* extension, ScriptData** cached_data,
109 ScriptCompiler::CompileOptions compile_options,
110 NativesFlag is_natives_code, bool is_module);
111
112 // Create a shared function info object for a Script that has already been
113 // parsed while the script was being loaded from a streamed source.
114 static Handle<SharedFunctionInfo> GetSharedFunctionInfoForStreamedScript(
115 Handle<Script> script, ParseInfo* info, int source_length);
116
117 // Create a shared function info object (the code may be lazily compiled).
118 static Handle<SharedFunctionInfo> GetSharedFunctionInfo(
119 FunctionLiteral* node, Handle<Script> script, CompilationInfo* outer);
120
121 // Create a shared function info object for a native function literal.
122 static Handle<SharedFunctionInfo> GetSharedFunctionInfoForNative(
123 v8::Extension* extension, Handle<String> name);
124
125 // ===========================================================================
126 // The following family of methods provides support for OSR. Code generated
127 // for entry via OSR might not be suitable for normal entry, hence will be
128 // returned directly to the caller.
129 //
130 // Please note this interface is the only part dealing with {Code} objects
131 // directly. Other methods are agnostic to {Code} and can use an interpreter
132 // instead of generating JIT code for a function at all.
133
134 // Generate and return optimized code for OSR, or empty handle on failure.
135 MUST_USE_RESULT static MaybeHandle<Code> GetOptimizedCodeForOSR(
136 Handle<JSFunction> function, BailoutId osr_ast_id,
137 JavaScriptFrame* osr_frame);
138};
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000139
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100140// A base class for compilation jobs intended to run concurrent to the main
141// thread. The job is split into three phases which are called in sequence on
142// different threads and with different limitations:
Ben Murdochf91f0612016-11-29 16:50:11 +0000143// 1) PrepareJob: Runs on main thread. No major limitations.
144// 2) ExecuteJob: Runs concurrently. No heap allocation or handle derefs.
145// 3) FinalizeJob: Runs on main thread. No dependency changes.
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100146//
Ben Murdochf91f0612016-11-29 16:50:11 +0000147// Each of the three phases can either fail or succeed. The current state of
148// the job can be checked using {state()}.
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100149class CompilationJob {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000150 public:
Ben Murdochf91f0612016-11-29 16:50:11 +0000151 enum Status { SUCCEEDED, FAILED };
152 enum class State {
153 kReadyToPrepare,
154 kReadyToExecute,
155 kReadyToFinalize,
156 kSucceeded,
157 kFailed,
158 };
159
Ben Murdochf3b273f2017-01-17 12:11:28 +0000160 CompilationJob(Isolate* isolate, CompilationInfo* info,
161 const char* compiler_name,
162 State initial_state = State::kReadyToPrepare)
163 : info_(info),
164 compiler_name_(compiler_name),
165 state_(initial_state),
166 stack_limit_(isolate->stack_guard()->real_climit()) {}
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100167 virtual ~CompilationJob() {}
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000168
Ben Murdochf91f0612016-11-29 16:50:11 +0000169 // Prepare the compile job. Must be called on the main thread.
170 MUST_USE_RESULT Status PrepareJob();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000171
Ben Murdochf3b273f2017-01-17 12:11:28 +0000172 // Executes the compile job. Can be called on a background thread if
173 // can_execute_on_background_thread() returns true.
Ben Murdochf91f0612016-11-29 16:50:11 +0000174 MUST_USE_RESULT Status ExecuteJob();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000175
Ben Murdochf91f0612016-11-29 16:50:11 +0000176 // Finalizes the compile job. Must be called on the main thread.
177 MUST_USE_RESULT Status FinalizeJob();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000178
Ben Murdochf91f0612016-11-29 16:50:11 +0000179 // Report a transient failure, try again next time. Should only be called on
180 // optimization compilation jobs.
Ben Murdochf3b273f2017-01-17 12:11:28 +0000181 Status RetryOptimization(BailoutReason reason);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000182
Ben Murdochf91f0612016-11-29 16:50:11 +0000183 // Report a persistent failure, disable future optimization on the function.
184 // Should only be called on optimization compilation jobs.
Ben Murdochf3b273f2017-01-17 12:11:28 +0000185 Status AbortOptimization(BailoutReason reason);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000186
Ben Murdochf3b273f2017-01-17 12:11:28 +0000187 void RecordOptimizedCompilationStats() const;
188 void RecordUnoptimizedCompilationStats() const;
189
190 virtual bool can_execute_on_background_thread() const { return true; }
191
192 void set_stack_limit(uintptr_t stack_limit) { stack_limit_ = stack_limit; }
193 uintptr_t stack_limit() const { return stack_limit_; }
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100194
Ben Murdochf91f0612016-11-29 16:50:11 +0000195 State state() const { return state_; }
196 CompilationInfo* info() const { return info_; }
Ben Murdochf3b273f2017-01-17 12:11:28 +0000197 Isolate* isolate() const;
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100198
Ben Murdochf91f0612016-11-29 16:50:11 +0000199 protected:
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100200 // Overridden by the actual implementation.
Ben Murdochf91f0612016-11-29 16:50:11 +0000201 virtual Status PrepareJobImpl() = 0;
202 virtual Status ExecuteJobImpl() = 0;
203 virtual Status FinalizeJobImpl() = 0;
204
205 // Registers weak object to optimized code dependencies.
206 // TODO(turbofan): Move this to pipeline.cc once Crankshaft dies.
207 void RegisterWeakObjectsInOptimizedCode(Handle<Code> code);
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100208
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000209 private:
210 CompilationInfo* info_;
Ben Murdochf91f0612016-11-29 16:50:11 +0000211 base::TimeDelta time_taken_to_prepare_;
212 base::TimeDelta time_taken_to_execute_;
213 base::TimeDelta time_taken_to_finalize_;
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100214 const char* compiler_name_;
Ben Murdochf91f0612016-11-29 16:50:11 +0000215 State state_;
Ben Murdochf3b273f2017-01-17 12:11:28 +0000216 uintptr_t stack_limit_;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000217
Ben Murdochf91f0612016-11-29 16:50:11 +0000218 MUST_USE_RESULT Status UpdateState(Status status, State next_state) {
219 if (status == SUCCEEDED) {
220 state_ = next_state;
221 } else {
222 state_ = State::kFailed;
223 }
224 return status;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000225 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000226};
227
Ben Murdoch014dc512016-03-22 12:00:34 +0000228} // namespace internal
229} // namespace v8
Steve Blocka7e24c12009-10-30 11:49:00 +0000230
231#endif // V8_COMPILER_H_