blob: e26484a4a6771c811e07e2595b70bb5086f9f217 [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 Murdoch62ed6312017-06-06 11:06:27 +010025template <typename T>
26class ThreadedList;
27template <typename T>
28class ThreadedListZoneEntry;
Ben Murdochb8a8cc12014-11-26 15:28:44 +000029
Ben Murdoch3b9bc312016-06-02 14:46:10 +010030// The V8 compiler API.
31//
32// This is the central hub for dispatching to the various compilers within V8.
33// Logic for which compiler to choose and how to wire compilation results into
34// the object heap should be kept inside this class.
35//
36// General strategy: Scripts are translated into anonymous functions w/o
37// parameters which then can be executed. If the source code contains other
38// functions, they might be compiled and allocated as part of the compilation
39// of the source code or deferred for lazy compilation at a later point.
Ben Murdoch62ed6312017-06-06 11:06:27 +010040class V8_EXPORT_PRIVATE Compiler : public AllStatic {
Ben Murdoch3b9bc312016-06-02 14:46:10 +010041 public:
42 enum ClearExceptionFlag { KEEP_EXCEPTION, CLEAR_EXCEPTION };
43 enum ConcurrencyMode { NOT_CONCURRENT, CONCURRENT };
Ben Murdochf91f0612016-11-29 16:50:11 +000044 enum CompilationTier { INTERPRETED, BASELINE, OPTIMIZED };
Ben Murdoch3b9bc312016-06-02 14:46:10 +010045
46 // ===========================================================================
47 // The following family of methods ensures a given function is compiled. The
48 // general contract is that failures will be reported by returning {false},
49 // whereas successful compilation ensures the {is_compiled} predicate on the
50 // given function holds (except for live-edit, which compiles the world).
51
52 static bool Compile(Handle<JSFunction> function, ClearExceptionFlag flag);
Ben Murdochbcf72ee2016-08-08 18:44:38 +010053 static bool CompileBaseline(Handle<JSFunction> function);
Ben Murdoch3b9bc312016-06-02 14:46:10 +010054 static bool CompileOptimized(Handle<JSFunction> function, ConcurrencyMode);
Ben Murdoch3b9bc312016-06-02 14:46:10 +010055 static bool CompileDebugCode(Handle<SharedFunctionInfo> shared);
Ben Murdochbcf72ee2016-08-08 18:44:38 +010056 static MaybeHandle<JSArray> CompileForLiveEdit(Handle<Script> script);
Ben Murdoch3b9bc312016-06-02 14:46:10 +010057
Ben Murdochf3b273f2017-01-17 12:11:28 +000058 // Prepare a compilation job for unoptimized code. Requires ParseAndAnalyse.
59 static CompilationJob* PrepareUnoptimizedCompilationJob(
60 CompilationInfo* info);
61
Ben Murdochbcf72ee2016-08-08 18:44:38 +010062 // Generate and install code from previously queued compilation job.
Ben Murdochf3b273f2017-01-17 12:11:28 +000063 static bool FinalizeCompilationJob(CompilationJob* job);
Ben Murdoch3b9bc312016-06-02 14:46:10 +010064
65 // Give the compiler a chance to perform low-latency initialization tasks of
66 // the given {function} on its instantiation. Note that only the runtime will
67 // offer this chance, optimized closure instantiation will not call this.
68 static void PostInstantiation(Handle<JSFunction> function, PretenureFlag);
69
Ben Murdoch62ed6312017-06-06 11:06:27 +010070 typedef ThreadedList<ThreadedListZoneEntry<FunctionLiteral*>>
71 EagerInnerFunctionLiterals;
72
Ben Murdoch3b9bc312016-06-02 14:46:10 +010073 // Parser::Parse, then Compiler::Analyze.
74 static bool ParseAndAnalyze(ParseInfo* info);
Ben Murdoch62ed6312017-06-06 11:06:27 +010075 // Rewrite, analyze scopes, and renumber. If |eager_literals| is non-null, it
76 // is appended with inner function literals which should be eagerly compiled.
77 static bool Analyze(ParseInfo* info,
78 EagerInnerFunctionLiterals* eager_literals = nullptr);
Ben Murdoch3b9bc312016-06-02 14:46:10 +010079 // Adds deoptimization support, requires ParseAndAnalyze.
80 static bool EnsureDeoptimizationSupport(CompilationInfo* info);
Ben Murdochf91f0612016-11-29 16:50:11 +000081 // Ensures that bytecode is generated, calls ParseAndAnalyze internally.
82 static bool EnsureBytecode(CompilationInfo* info);
83
84 // The next compilation tier which the function should be compiled to for
85 // optimization. This is used as a hint by the runtime profiler.
86 static CompilationTier NextCompilationTier(JSFunction* function);
Ben Murdoch3b9bc312016-06-02 14:46:10 +010087
88 // ===========================================================================
89 // The following family of methods instantiates new functions for scripts or
90 // function literals. The decision whether those functions will be compiled,
91 // is left to the discretion of the compiler.
92 //
93 // Please note this interface returns shared function infos. This means you
94 // need to call Factory::NewFunctionFromSharedFunctionInfo before you have a
95 // real function with a context.
96
97 // Create a (bound) function for a String source within a context for eval.
98 MUST_USE_RESULT static MaybeHandle<JSFunction> GetFunctionFromEval(
99 Handle<String> source, Handle<SharedFunctionInfo> outer_info,
100 Handle<Context> context, LanguageMode language_mode,
Ben Murdoch62ed6312017-06-06 11:06:27 +0100101 ParseRestriction restriction, int parameters_end_pos,
102 int eval_scope_position, int eval_position, int line_offset = 0,
103 int column_offset = 0, Handle<Object> script_name = Handle<Object>(),
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100104 ScriptOriginOptions options = ScriptOriginOptions());
105
Ben Murdochf91f0612016-11-29 16:50:11 +0000106 // Create a (bound) function for a String source within a context for eval.
107 MUST_USE_RESULT static MaybeHandle<JSFunction> GetFunctionFromString(
108 Handle<Context> context, Handle<String> source,
Ben Murdoch62ed6312017-06-06 11:06:27 +0100109 ParseRestriction restriction, int parameters_end_pos);
Ben Murdochf91f0612016-11-29 16:50:11 +0000110
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100111 // Create a shared function info object for a String source within a context.
112 static Handle<SharedFunctionInfo> GetSharedFunctionInfoForScript(
113 Handle<String> source, Handle<Object> script_name, int line_offset,
114 int column_offset, ScriptOriginOptions resource_options,
115 Handle<Object> source_map_url, Handle<Context> context,
116 v8::Extension* extension, ScriptData** cached_data,
117 ScriptCompiler::CompileOptions compile_options,
Ben Murdoch62ed6312017-06-06 11:06:27 +0100118 NativesFlag is_natives_code);
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100119
120 // Create a shared function info object for a Script that has already been
121 // parsed while the script was being loaded from a streamed source.
122 static Handle<SharedFunctionInfo> GetSharedFunctionInfoForStreamedScript(
123 Handle<Script> script, ParseInfo* info, int source_length);
124
125 // Create a shared function info object (the code may be lazily compiled).
126 static Handle<SharedFunctionInfo> GetSharedFunctionInfo(
127 FunctionLiteral* node, Handle<Script> script, CompilationInfo* outer);
128
129 // Create a shared function info object for a native function literal.
130 static Handle<SharedFunctionInfo> GetSharedFunctionInfoForNative(
131 v8::Extension* extension, Handle<String> name);
132
133 // ===========================================================================
134 // The following family of methods provides support for OSR. Code generated
135 // for entry via OSR might not be suitable for normal entry, hence will be
136 // returned directly to the caller.
137 //
138 // Please note this interface is the only part dealing with {Code} objects
139 // directly. Other methods are agnostic to {Code} and can use an interpreter
140 // instead of generating JIT code for a function at all.
141
142 // Generate and return optimized code for OSR, or empty handle on failure.
143 MUST_USE_RESULT static MaybeHandle<Code> GetOptimizedCodeForOSR(
144 Handle<JSFunction> function, BailoutId osr_ast_id,
145 JavaScriptFrame* osr_frame);
146};
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000147
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100148// A base class for compilation jobs intended to run concurrent to the main
149// thread. The job is split into three phases which are called in sequence on
150// different threads and with different limitations:
Ben Murdochf91f0612016-11-29 16:50:11 +0000151// 1) PrepareJob: Runs on main thread. No major limitations.
152// 2) ExecuteJob: Runs concurrently. No heap allocation or handle derefs.
153// 3) FinalizeJob: Runs on main thread. No dependency changes.
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100154//
Ben Murdochf91f0612016-11-29 16:50:11 +0000155// Each of the three phases can either fail or succeed. The current state of
156// the job can be checked using {state()}.
Ben Murdoch62ed6312017-06-06 11:06:27 +0100157class V8_EXPORT_PRIVATE CompilationJob {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000158 public:
Ben Murdochf91f0612016-11-29 16:50:11 +0000159 enum Status { SUCCEEDED, FAILED };
160 enum class State {
161 kReadyToPrepare,
162 kReadyToExecute,
163 kReadyToFinalize,
164 kSucceeded,
165 kFailed,
166 };
167
Ben Murdochf3b273f2017-01-17 12:11:28 +0000168 CompilationJob(Isolate* isolate, CompilationInfo* info,
169 const char* compiler_name,
Ben Murdoch62ed6312017-06-06 11:06:27 +0100170 State initial_state = State::kReadyToPrepare);
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100171 virtual ~CompilationJob() {}
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000172
Ben Murdochf91f0612016-11-29 16:50:11 +0000173 // Prepare the compile job. Must be called on the main thread.
174 MUST_USE_RESULT Status PrepareJob();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000175
Ben Murdochf3b273f2017-01-17 12:11:28 +0000176 // Executes the compile job. Can be called on a background thread if
177 // can_execute_on_background_thread() returns true.
Ben Murdochf91f0612016-11-29 16:50:11 +0000178 MUST_USE_RESULT Status ExecuteJob();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000179
Ben Murdochf91f0612016-11-29 16:50:11 +0000180 // Finalizes the compile job. Must be called on the main thread.
181 MUST_USE_RESULT Status FinalizeJob();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000182
Ben Murdochf91f0612016-11-29 16:50:11 +0000183 // Report a transient failure, try again next time. Should only be called on
184 // optimization compilation jobs.
Ben Murdochf3b273f2017-01-17 12:11:28 +0000185 Status RetryOptimization(BailoutReason reason);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000186
Ben Murdochf91f0612016-11-29 16:50:11 +0000187 // Report a persistent failure, disable future optimization on the function.
188 // Should only be called on optimization compilation jobs.
Ben Murdochf3b273f2017-01-17 12:11:28 +0000189 Status AbortOptimization(BailoutReason reason);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000190
Ben Murdochf3b273f2017-01-17 12:11:28 +0000191 void RecordOptimizedCompilationStats() const;
192 void RecordUnoptimizedCompilationStats() const;
193
194 virtual bool can_execute_on_background_thread() const { return true; }
195
196 void set_stack_limit(uintptr_t stack_limit) { stack_limit_ = stack_limit; }
197 uintptr_t stack_limit() const { return stack_limit_; }
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100198
Ben Murdoch62ed6312017-06-06 11:06:27 +0100199 bool executed_on_background_thread() const {
200 DCHECK_IMPLIES(!can_execute_on_background_thread(),
201 !executed_on_background_thread_);
202 return executed_on_background_thread_;
203 }
Ben Murdochf91f0612016-11-29 16:50:11 +0000204 State state() const { return state_; }
205 CompilationInfo* info() const { return info_; }
Ben Murdochf3b273f2017-01-17 12:11:28 +0000206 Isolate* isolate() const;
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100207
Ben Murdochf91f0612016-11-29 16:50:11 +0000208 protected:
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100209 // Overridden by the actual implementation.
Ben Murdochf91f0612016-11-29 16:50:11 +0000210 virtual Status PrepareJobImpl() = 0;
211 virtual Status ExecuteJobImpl() = 0;
212 virtual Status FinalizeJobImpl() = 0;
213
214 // Registers weak object to optimized code dependencies.
215 // TODO(turbofan): Move this to pipeline.cc once Crankshaft dies.
216 void RegisterWeakObjectsInOptimizedCode(Handle<Code> code);
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100217
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000218 private:
219 CompilationInfo* info_;
Ben Murdoch62ed6312017-06-06 11:06:27 +0100220 ThreadId isolate_thread_id_;
Ben Murdochf91f0612016-11-29 16:50:11 +0000221 base::TimeDelta time_taken_to_prepare_;
222 base::TimeDelta time_taken_to_execute_;
223 base::TimeDelta time_taken_to_finalize_;
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100224 const char* compiler_name_;
Ben Murdochf91f0612016-11-29 16:50:11 +0000225 State state_;
Ben Murdochf3b273f2017-01-17 12:11:28 +0000226 uintptr_t stack_limit_;
Ben Murdoch62ed6312017-06-06 11:06:27 +0100227 bool executed_on_background_thread_;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000228
Ben Murdochf91f0612016-11-29 16:50:11 +0000229 MUST_USE_RESULT Status UpdateState(Status status, State next_state) {
230 if (status == SUCCEEDED) {
231 state_ = next_state;
232 } else {
233 state_ = State::kFailed;
234 }
235 return status;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000236 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000237};
238
Ben Murdoch014dc512016-03-22 12:00:34 +0000239} // namespace internal
240} // namespace v8
Steve Blocka7e24c12009-10-30 11:49:00 +0000241
242#endif // V8_COMPILER_H_