blob: 4d7644c7ff4d5d620a72d718da95b8d1320bdef3 [file] [log] [blame]
yangguo@chromium.org56454712012-02-16 15:33:53 +00001// Copyright 2012 the V8 project authors. All rights reserved.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002// Redistribution and use in source and binary forms, with or without
3// modification, are permitted provided that the following conditions are
4// met:
5//
6// * Redistributions of source code must retain the above copyright
7// notice, this list of conditions and the following disclaimer.
8// * Redistributions in binary form must reproduce the above
9// copyright notice, this list of conditions and the following
10// disclaimer in the documentation and/or other materials provided
11// with the distribution.
12// * Neither the name of Google Inc. nor the names of its
13// contributors may be used to endorse or promote products derived
14// from this software without specific prior written permission.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28#ifndef V8_COMPILER_H_
29#define V8_COMPILER_H_
30
lrn@chromium.org1c092762011-05-09 09:42:16 +000031#include "allocation.h"
ager@chromium.org5c838252010-02-19 08:53:10 +000032#include "ast.h"
kasperl@chromium.orgb3284ad2009-05-18 06:12:45 +000033#include "zone.h"
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000034
kasperl@chromium.org71affb52009-05-26 05:44:31 +000035namespace v8 {
36namespace internal {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000037
svenpanne@chromium.org83130cf2012-11-30 10:13:25 +000038static const int kPrologueOffsetNotSet = -1;
39
ricow@chromium.orgeb7c1442010-10-04 08:54:21 +000040class ScriptDataImpl;
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +000041class HydrogenCodeStub;
ricow@chromium.orgeb7c1442010-10-04 08:54:21 +000042
ager@chromium.org5c838252010-02-19 08:53:10 +000043// CompilationInfo encapsulates some information known at compile time. It
44// is constructed based on the resources available at compile-time.
yangguo@chromium.org304cc332012-07-24 07:59:48 +000045class CompilationInfo {
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +000046 public:
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +000047 CompilationInfo(Handle<Script> script, Zone* zone);
48 CompilationInfo(Handle<SharedFunctionInfo> shared_info, Zone* zone);
49 CompilationInfo(Handle<JSFunction> closure, Zone* zone);
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +000050 CompilationInfo(HydrogenCodeStub* stub, Isolate* isolate, Zone* zone);
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +000051
verwaest@chromium.org178fb152012-07-18 11:21:48 +000052 virtual ~CompilationInfo();
yangguo@chromium.org99aa4902012-07-06 16:21:55 +000053
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000054 Isolate* isolate() {
55 ASSERT(Isolate::Current() == isolate_);
56 return isolate_;
57 }
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +000058 Zone* zone() {
59 return zone_;
60 }
kmillikin@chromium.org83e16822011-09-13 08:21:47 +000061 bool is_lazy() const { return IsLazy::decode(flags_); }
62 bool is_eval() const { return IsEval::decode(flags_); }
63 bool is_global() const { return IsGlobal::decode(flags_); }
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +000064 bool is_classic_mode() const { return language_mode() == CLASSIC_MODE; }
65 bool is_extended_mode() const { return language_mode() == EXTENDED_MODE; }
66 LanguageMode language_mode() const {
67 return LanguageModeField::decode(flags_);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +000068 }
kmillikin@chromium.org83e16822011-09-13 08:21:47 +000069 bool is_in_loop() const { return IsInLoop::decode(flags_); }
ager@chromium.orgb61a0d12010-10-13 08:35:23 +000070 FunctionLiteral* function() const { return function_; }
71 Scope* scope() const { return scope_; }
ricow@chromium.org27bf2882011-11-17 08:34:43 +000072 Scope* global_scope() const { return global_scope_; }
ager@chromium.orgb61a0d12010-10-13 08:35:23 +000073 Handle<Code> code() const { return code_; }
74 Handle<JSFunction> closure() const { return closure_; }
75 Handle<SharedFunctionInfo> shared_info() const { return shared_info_; }
76 Handle<Script> script() const { return script_; }
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +000077 HydrogenCodeStub* code_stub() {return code_stub_; }
ager@chromium.orgb61a0d12010-10-13 08:35:23 +000078 v8::Extension* extension() const { return extension_; }
79 ScriptDataImpl* pre_parse_data() const { return pre_parse_data_; }
yangguo@chromium.org355cfd12012-08-29 15:32:24 +000080 Handle<Context> context() const { return context_; }
mstarzinger@chromium.org471f2f12012-08-10 14:46:33 +000081 BailoutId osr_ast_id() const { return osr_ast_id_; }
yangguo@chromium.org003650e2013-01-24 16:31:08 +000082 int opt_count() const { return opt_count_; }
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +000083 int num_parameters() const;
84 int num_heap_slots() const;
85 Code::Flags flags() const;
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +000086
ager@chromium.orgb61a0d12010-10-13 08:35:23 +000087 void MarkAsEval() {
88 ASSERT(!is_lazy());
89 flags_ |= IsEval::encode(true);
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +000090 }
ager@chromium.orgb61a0d12010-10-13 08:35:23 +000091 void MarkAsGlobal() {
92 ASSERT(!is_lazy());
93 flags_ |= IsGlobal::encode(true);
ager@chromium.org5c838252010-02-19 08:53:10 +000094 }
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +000095 void SetLanguageMode(LanguageMode language_mode) {
96 ASSERT(this->language_mode() == CLASSIC_MODE ||
97 this->language_mode() == language_mode ||
98 language_mode == EXTENDED_MODE);
99 flags_ = LanguageModeField::update(flags_, language_mode);
ricow@chromium.org83aa5492011-02-07 12:42:56 +0000100 }
ager@chromium.orgb61a0d12010-10-13 08:35:23 +0000101 void MarkAsInLoop() {
102 ASSERT(is_lazy());
103 flags_ |= IsInLoop::encode(true);
104 }
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000105 void MarkAsNative() {
106 flags_ |= IsNative::encode(true);
107 }
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +0000108
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000109 bool is_native() const {
110 return IsNative::decode(flags_);
111 }
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +0000112
113 bool is_calling() const {
114 return is_deferred_calling() || is_non_deferred_calling();
115 }
116
117 void MarkAsDeferredCalling() {
118 flags_ |= IsDeferredCalling::encode(true);
119 }
120
121 bool is_deferred_calling() const {
122 return IsDeferredCalling::decode(flags_);
123 }
124
125 void MarkAsNonDeferredCalling() {
126 flags_ |= IsNonDeferredCalling::encode(true);
127 }
128
129 bool is_non_deferred_calling() const {
130 return IsNonDeferredCalling::decode(flags_);
131 }
132
danno@chromium.org94b0d6f2013-02-04 13:33:20 +0000133 void MarkAsSavesCallerDoubles() {
134 flags_ |= SavesCallerDoubles::encode(true);
135 }
136
137 bool saves_caller_doubles() const {
138 return SavesCallerDoubles::decode(flags_);
139 }
140
ager@chromium.orgb61a0d12010-10-13 08:35:23 +0000141 void SetFunction(FunctionLiteral* literal) {
142 ASSERT(function_ == NULL);
143 function_ = literal;
144 }
145 void SetScope(Scope* scope) {
146 ASSERT(scope_ == NULL);
147 scope_ = scope;
148 }
ricow@chromium.org27bf2882011-11-17 08:34:43 +0000149 void SetGlobalScope(Scope* global_scope) {
150 ASSERT(global_scope_ == NULL);
151 global_scope_ = global_scope;
152 }
ager@chromium.orgb61a0d12010-10-13 08:35:23 +0000153 void SetCode(Handle<Code> code) { code_ = code; }
154 void SetExtension(v8::Extension* extension) {
155 ASSERT(!is_lazy());
156 extension_ = extension;
157 }
158 void SetPreParseData(ScriptDataImpl* pre_parse_data) {
159 ASSERT(!is_lazy());
160 pre_parse_data_ = pre_parse_data;
161 }
yangguo@chromium.org355cfd12012-08-29 15:32:24 +0000162 void SetContext(Handle<Context> context) {
163 context_ = context;
ager@chromium.orgb61a0d12010-10-13 08:35:23 +0000164 }
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000165 void MarkCompilingForDebugging(Handle<Code> current_code) {
166 ASSERT(mode_ != OPTIMIZE);
167 ASSERT(current_code->kind() == Code::FUNCTION);
168 flags_ |= IsCompilingForDebugging::encode(true);
169 if (current_code->is_compiled_optimizable()) {
170 EnableDeoptimizationSupport();
171 } else {
172 mode_ = CompilationInfo::NONOPT;
173 }
174 }
175 bool IsCompilingForDebugging() {
176 return IsCompilingForDebugging::decode(flags_);
177 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000178
179 bool has_global_object() const {
yangguo@chromium.org46839fb2012-08-28 09:06:19 +0000180 return !closure().is_null() &&
181 (closure()->context()->global_object() != NULL);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000182 }
183
184 GlobalObject* global_object() const {
yangguo@chromium.org46839fb2012-08-28 09:06:19 +0000185 return has_global_object() ? closure()->context()->global_object() : NULL;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000186 }
187
188 // Accessors for the different compilation modes.
189 bool IsOptimizing() const { return mode_ == OPTIMIZE; }
190 bool IsOptimizable() const { return mode_ == BASE; }
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +0000191 bool IsStub() const { return mode_ == STUB; }
mstarzinger@chromium.org471f2f12012-08-10 14:46:33 +0000192 void SetOptimizing(BailoutId osr_ast_id) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000193 SetMode(OPTIMIZE);
194 osr_ast_id_ = osr_ast_id;
195 }
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000196 void DisableOptimization();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000197
198 // Deoptimization support.
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000199 bool HasDeoptimizationSupport() const {
200 return SupportsDeoptimization::decode(flags_);
201 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000202 void EnableDeoptimizationSupport() {
203 ASSERT(IsOptimizable());
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000204 flags_ |= SupportsDeoptimization::encode(true);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000205 }
206
yangguo@chromium.org78d1ad42012-02-09 13:53:47 +0000207 // Determines whether or not to insert a self-optimization header.
208 bool ShouldSelfOptimize();
209
ager@chromium.orgea91cc52011-05-23 06:06:11 +0000210 // Disable all optimization attempts of this info for the rest of the
211 // current compilation pipeline.
212 void AbortOptimization();
213
yangguo@chromium.org99aa4902012-07-06 16:21:55 +0000214 void set_deferred_handles(DeferredHandles* deferred_handles) {
215 ASSERT(deferred_handles_ == NULL);
216 deferred_handles_ = deferred_handles;
217 }
218
yangguo@chromium.org304cc332012-07-24 07:59:48 +0000219 void SaveHandles() {
220 SaveHandle(&closure_);
221 SaveHandle(&shared_info_);
yangguo@chromium.org355cfd12012-08-29 15:32:24 +0000222 SaveHandle(&context_);
yangguo@chromium.org304cc332012-07-24 07:59:48 +0000223 SaveHandle(&script_);
224 }
225
yangguo@chromium.org46839fb2012-08-28 09:06:19 +0000226 const char* bailout_reason() const { return bailout_reason_; }
227 void set_bailout_reason(const char* reason) { bailout_reason_ = reason; }
228
svenpanne@chromium.org83130cf2012-11-30 10:13:25 +0000229 int prologue_offset() const {
230 ASSERT_NE(kPrologueOffsetNotSet, prologue_offset_);
231 return prologue_offset_;
232 }
233
234 void set_prologue_offset(int prologue_offset) {
235 ASSERT_EQ(kPrologueOffsetNotSet, prologue_offset_);
236 prologue_offset_ = prologue_offset;
237 }
238
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +0000239 private:
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000240 Isolate* isolate_;
241
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000242 // Compilation mode.
243 // BASE is generated by the full codegen, optionally prepared for bailouts.
244 // OPTIMIZE is optimized code generated by the Hydrogen-based backend.
yangguo@chromium.org56454712012-02-16 15:33:53 +0000245 // NONOPT is generated by the full codegen and is not prepared for
246 // recompilation/bailouts. These functions are never recompiled.
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000247 enum Mode {
248 BASE,
249 OPTIMIZE,
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +0000250 NONOPT,
251 STUB
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000252 };
253
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +0000254 void Initialize(Isolate* isolate, Mode mode, Zone* zone);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000255
256 void SetMode(Mode mode) {
257 ASSERT(V8::UseCrankshaft());
258 mode_ = mode;
259 }
260
ager@chromium.orgb61a0d12010-10-13 08:35:23 +0000261 // Flags using template class BitField<type, start, length>. All are
262 // false by default.
263 //
264 // Compilation is either eager or lazy.
265 class IsLazy: public BitField<bool, 0, 1> {};
266 // Flags that can be set for eager compilation.
267 class IsEval: public BitField<bool, 1, 1> {};
268 class IsGlobal: public BitField<bool, 2, 1> {};
ager@chromium.orgb61a0d12010-10-13 08:35:23 +0000269 // Flags that can be set for lazy compilation.
fschneider@chromium.orge03fb642010-11-01 12:34:09 +0000270 class IsInLoop: public BitField<bool, 3, 1> {};
ricow@chromium.org83aa5492011-02-07 12:42:56 +0000271 // Strict mode - used in eager compilation.
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +0000272 class LanguageModeField: public BitField<LanguageMode, 4, 2> {};
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000273 // Is this a function from our natives.
274 class IsNative: public BitField<bool, 6, 1> {};
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000275 // Is this code being compiled with support for deoptimization..
276 class SupportsDeoptimization: public BitField<bool, 7, 1> {};
277 // If compiling for debugging produce just full code matching the
278 // initial mode setting.
279 class IsCompilingForDebugging: public BitField<bool, 8, 1> {};
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +0000280 // If the compiled code contains calls that require building a frame
281 class IsCalling: public BitField<bool, 9, 1> {};
282 // If the compiled code contains calls that require building a frame
283 class IsDeferredCalling: public BitField<bool, 10, 1> {};
284 // If the compiled code contains calls that require building a frame
285 class IsNonDeferredCalling: public BitField<bool, 11, 1> {};
danno@chromium.org94b0d6f2013-02-04 13:33:20 +0000286 // If the compiled code saves double caller registers that it clobbers.
287 class SavesCallerDoubles: public BitField<bool, 12, 1> {};
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000288
ager@chromium.orgb61a0d12010-10-13 08:35:23 +0000289
290 unsigned flags_;
291
292 // Fields filled in by the compilation pipeline.
293 // AST filled in by the parser.
ager@chromium.org5c838252010-02-19 08:53:10 +0000294 FunctionLiteral* function_;
fschneider@chromium.orge03fb642010-11-01 12:34:09 +0000295 // The scope of the function literal as a convenience. Set to indicate
ager@chromium.orgb61a0d12010-10-13 08:35:23 +0000296 // that scopes have been analyzed.
297 Scope* scope_;
ricow@chromium.org27bf2882011-11-17 08:34:43 +0000298 // The global scope provided as a convenience.
299 Scope* global_scope_;
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +0000300 // For compiled stubs, the stub object
301 HydrogenCodeStub* code_stub_;
ager@chromium.orgb61a0d12010-10-13 08:35:23 +0000302 // The compiled code.
303 Handle<Code> code_;
304
305 // Possible initial inputs to the compilation process.
306 Handle<JSFunction> closure_;
307 Handle<SharedFunctionInfo> shared_info_;
308 Handle<Script> script_;
309
310 // Fields possibly needed for eager compilation, NULL by default.
311 v8::Extension* extension_;
312 ScriptDataImpl* pre_parse_data_;
313
yangguo@chromium.org355cfd12012-08-29 15:32:24 +0000314 // The context of the caller for eval code, and the global context for a
315 // global script. Will be a null handle otherwise.
316 Handle<Context> context_;
ager@chromium.org5c838252010-02-19 08:53:10 +0000317
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000318 // Compilation mode flag and whether deoptimization is allowed.
319 Mode mode_;
mstarzinger@chromium.org471f2f12012-08-10 14:46:33 +0000320 BailoutId osr_ast_id_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000321
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +0000322 // The zone from which the compilation pipeline working on this
323 // CompilationInfo allocates.
324 Zone* zone_;
325
yangguo@chromium.org99aa4902012-07-06 16:21:55 +0000326 DeferredHandles* deferred_handles_;
327
yangguo@chromium.org304cc332012-07-24 07:59:48 +0000328 template<typename T>
329 void SaveHandle(Handle<T> *object) {
330 if (!object->is_null()) {
331 Handle<T> handle(*(*object));
332 *object = handle;
333 }
334 }
335
yangguo@chromium.org46839fb2012-08-28 09:06:19 +0000336 const char* bailout_reason_;
337
svenpanne@chromium.org83130cf2012-11-30 10:13:25 +0000338 int prologue_offset_;
339
yangguo@chromium.org003650e2013-01-24 16:31:08 +0000340 // A copy of shared_info()->opt_count() to avoid handle deref
341 // during graph optimization.
342 int opt_count_;
343
ager@chromium.org5c838252010-02-19 08:53:10 +0000344 DISALLOW_COPY_AND_ASSIGN(CompilationInfo);
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +0000345};
346
347
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +0000348// Exactly like a CompilationInfo, except also creates and enters a
349// Zone on construction and deallocates it on exit.
350class CompilationInfoWithZone: public CompilationInfo {
351 public:
danno@chromium.org1f34ad32012-11-26 14:53:56 +0000352 INLINE(void* operator new(size_t size)) { return Malloced::New(size); }
353
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +0000354 explicit CompilationInfoWithZone(Handle<Script> script)
355 : CompilationInfo(script, &zone_),
356 zone_(script->GetIsolate()),
357 zone_scope_(&zone_, DELETE_ON_EXIT) {}
358 explicit CompilationInfoWithZone(Handle<SharedFunctionInfo> shared_info)
359 : CompilationInfo(shared_info, &zone_),
360 zone_(shared_info->GetIsolate()),
361 zone_scope_(&zone_, DELETE_ON_EXIT) {}
362 explicit CompilationInfoWithZone(Handle<JSFunction> closure)
363 : CompilationInfo(closure, &zone_),
364 zone_(closure->GetIsolate()),
365 zone_scope_(&zone_, DELETE_ON_EXIT) {}
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +0000366 explicit CompilationInfoWithZone(HydrogenCodeStub* stub, Isolate* isolate)
367 : CompilationInfo(stub, isolate, &zone_),
368 zone_(isolate),
369 zone_scope_(&zone_, DELETE_ON_EXIT) {}
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +0000370
371 private:
372 Zone zone_;
373 ZoneScope zone_scope_;
374};
375
376
yangguo@chromium.org99aa4902012-07-06 16:21:55 +0000377// A wrapper around a CompilationInfo that detaches the Handles from
378// the underlying DeferredHandleScope and stores them in info_ on
379// destruction.
380class CompilationHandleScope BASE_EMBEDDED {
381 public:
382 explicit CompilationHandleScope(CompilationInfo* info)
383 : deferred_(info->isolate()), info_(info) {}
384 ~CompilationHandleScope() {
385 info_->set_deferred_handles(deferred_.Detach());
386 }
387
388 private:
389 DeferredHandleScope deferred_;
390 CompilationInfo* info_;
391};
392
393
verwaest@chromium.org178fb152012-07-18 11:21:48 +0000394class HGraph;
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +0000395class HOptimizedGraphBuilder;
verwaest@chromium.org178fb152012-07-18 11:21:48 +0000396class LChunk;
397
398// A helper class that calls the three compilation phases in
399// Crankshaft and keeps track of its state. The three phases
400// CreateGraph, OptimizeGraph and GenerateAndInstallCode can either
401// fail, bail-out to the full code generator or succeed. Apart from
402// their return value, the status of the phase last run can be checked
403// using last_status().
404class OptimizingCompiler: public ZoneObject {
405 public:
406 explicit OptimizingCompiler(CompilationInfo* info)
407 : info_(info),
408 oracle_(NULL),
409 graph_builder_(NULL),
410 graph_(NULL),
411 chunk_(NULL),
412 time_taken_to_create_graph_(0),
413 time_taken_to_optimize_(0),
414 time_taken_to_codegen_(0),
415 last_status_(FAILED) { }
416
417 enum Status {
418 FAILED, BAILED_OUT, SUCCEEDED
419 };
420
421 MUST_USE_RESULT Status CreateGraph();
422 MUST_USE_RESULT Status OptimizeGraph();
423 MUST_USE_RESULT Status GenerateAndInstallCode();
424
425 Status last_status() const { return last_status_; }
426 CompilationInfo* info() const { return info_; }
ulan@chromium.org09d7ab52013-02-25 15:50:35 +0000427 Isolate* isolate() const { return info()->isolate(); }
verwaest@chromium.org178fb152012-07-18 11:21:48 +0000428
yangguo@chromium.org304cc332012-07-24 07:59:48 +0000429 MUST_USE_RESULT Status AbortOptimization() {
430 info_->AbortOptimization();
yangguo@chromium.org46839fb2012-08-28 09:06:19 +0000431 info_->shared_info()->DisableOptimization(info_->bailout_reason());
yangguo@chromium.org304cc332012-07-24 07:59:48 +0000432 return SetLastStatus(BAILED_OUT);
433 }
434
verwaest@chromium.org178fb152012-07-18 11:21:48 +0000435 private:
436 CompilationInfo* info_;
437 TypeFeedbackOracle* oracle_;
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +0000438 HOptimizedGraphBuilder* graph_builder_;
verwaest@chromium.org178fb152012-07-18 11:21:48 +0000439 HGraph* graph_;
440 LChunk* chunk_;
441 int64_t time_taken_to_create_graph_;
442 int64_t time_taken_to_optimize_;
443 int64_t time_taken_to_codegen_;
444 Status last_status_;
445
446 MUST_USE_RESULT Status SetLastStatus(Status status) {
447 last_status_ = status;
448 return last_status_;
449 }
450 void RecordOptimizationStats();
verwaest@chromium.org178fb152012-07-18 11:21:48 +0000451
452 struct Timer {
453 Timer(OptimizingCompiler* compiler, int64_t* location)
454 : compiler_(compiler),
455 start_(OS::Ticks()),
456 location_(location) { }
457
458 ~Timer() {
459 *location_ += (OS::Ticks() - start_);
460 }
461
462 OptimizingCompiler* compiler_;
463 int64_t start_;
464 int64_t* location_;
465 };
466};
467
468
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000469// The V8 compiler
470//
471// General strategy: Source code is translated into an anonymous function w/o
472// parameters which then can be executed. If the source code contains other
473// functions, they will be compiled and allocated as part of the compilation
474// of the source code.
475
ager@chromium.orgb61a0d12010-10-13 08:35:23 +0000476// Please note this interface returns shared function infos. This means you
477// need to call Factory::NewFunctionFromSharedFunctionInfo before you have a
478// real function with a context.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000479
480class Compiler : public AllStatic {
481 public:
vegorov@chromium.org74f333b2011-04-06 11:17:46 +0000482 static const int kMaxInliningLevels = 3;
483
yangguo@chromium.org78d1ad42012-02-09 13:53:47 +0000484 // Call count before primitive functions trigger their own optimization.
485 static const int kCallsUntilPrimitiveOpt = 200;
486
erik.corry@gmail.com0511e242011-01-19 11:11:08 +0000487 // All routines return a SharedFunctionInfo.
488 // If an error occurs an exception is raised and the return handle
489 // contains NULL.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000490
491 // Compile a String source within a context.
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +0000492 static Handle<SharedFunctionInfo> Compile(Handle<String> source,
493 Handle<Object> script_name,
494 int line_offset,
495 int column_offset,
yangguo@chromium.org355cfd12012-08-29 15:32:24 +0000496 Handle<Context> context,
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +0000497 v8::Extension* extension,
498 ScriptDataImpl* pre_data,
499 Handle<Object> script_data,
500 NativesFlag is_natives_code);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000501
502 // Compile a String source within a context for Eval.
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +0000503 static Handle<SharedFunctionInfo> CompileEval(Handle<String> source,
504 Handle<Context> context,
ricow@chromium.org83aa5492011-02-07 12:42:56 +0000505 bool is_global,
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +0000506 LanguageMode language_mode,
jkummerow@chromium.org04e4f1e2011-11-14 13:36:17 +0000507 int scope_position);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000508
ager@chromium.orgb61a0d12010-10-13 08:35:23 +0000509 // Compile from function info (used for lazy compilation). Returns true on
510 // success and false if the compilation resulted in a stack overflow.
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +0000511 static bool CompileLazy(CompilationInfo* info);
ager@chromium.orgc4c92722009-11-18 14:12:51 +0000512
yangguo@chromium.org304cc332012-07-24 07:59:48 +0000513 static void RecompileParallel(Handle<JSFunction> function);
514
ager@chromium.orgb61a0d12010-10-13 08:35:23 +0000515 // Compile a shared function info object (the function is possibly lazily
516 // compiled).
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +0000517 static Handle<SharedFunctionInfo> BuildFunctionInfo(FunctionLiteral* node,
ager@chromium.orgb61a0d12010-10-13 08:35:23 +0000518 Handle<Script> script);
ager@chromium.orgc4c92722009-11-18 14:12:51 +0000519
520 // Set the function info for a newly compiled function.
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +0000521 static void SetFunctionInfo(Handle<SharedFunctionInfo> function_info,
ager@chromium.orgc4c92722009-11-18 14:12:51 +0000522 FunctionLiteral* lit,
523 bool is_toplevel,
524 Handle<Script> script);
ager@chromium.org5c838252010-02-19 08:53:10 +0000525
yangguo@chromium.org304cc332012-07-24 07:59:48 +0000526 static void InstallOptimizedCode(OptimizingCompiler* info);
527
ager@chromium.orgb61a0d12010-10-13 08:35:23 +0000528#ifdef ENABLE_DEBUGGER_SUPPORT
529 static bool MakeCodeForLiveEdit(CompilationInfo* info);
530#endif
531
ager@chromium.orgb26c50a2010-03-26 09:27:16 +0000532 static void RecordFunctionCompilation(Logger::LogEventsAndTags tag,
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000533 CompilationInfo* info,
534 Handle<SharedFunctionInfo> shared);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000535};
536
kasperl@chromium.orgb3284ad2009-05-18 06:12:45 +0000537
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000538} } // namespace v8::internal
539
540#endif // V8_COMPILER_H_