9617afc9f3c8729a5e375f8a99f2b9bc677012d3
[platform/framework/web/crosswalk.git] / src / v8 / src / compiler.h
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
3 // found in the LICENSE file.
4
5 #ifndef V8_COMPILER_H_
6 #define V8_COMPILER_H_
7
8 #include "src/allocation.h"
9 #include "src/ast.h"
10 #include "src/bailout-reason.h"
11 #include "src/zone.h"
12
13 namespace v8 {
14 namespace internal {
15
16 class AstValueFactory;
17 class HydrogenCodeStub;
18
19 // ParseRestriction is used to restrict the set of valid statements in a
20 // unit of compilation.  Restriction violations cause a syntax error.
21 enum ParseRestriction {
22   NO_PARSE_RESTRICTION,         // All expressions are allowed.
23   ONLY_SINGLE_FUNCTION_LITERAL  // Only a single FunctionLiteral expression.
24 };
25
26 struct OffsetRange {
27   OffsetRange(int from, int to) : from(from), to(to) {}
28   int from;
29   int to;
30 };
31
32
33 class ScriptData {
34  public:
35   ScriptData(const byte* data, int length);
36   ~ScriptData() {
37     if (owns_data_) DeleteArray(data_);
38   }
39
40   const byte* data() const { return data_; }
41   int length() const { return length_; }
42
43   void AcquireDataOwnership() {
44     DCHECK(!owns_data_);
45     owns_data_ = true;
46   }
47
48   void ReleaseDataOwnership() {
49     DCHECK(owns_data_);
50     owns_data_ = false;
51   }
52
53  private:
54   bool owns_data_;
55   const byte* data_;
56   int length_;
57
58   DISALLOW_COPY_AND_ASSIGN(ScriptData);
59 };
60
61 // CompilationInfo encapsulates some information known at compile time.  It
62 // is constructed based on the resources available at compile-time.
63 class CompilationInfo {
64  public:
65   // Various configuration flags for a compilation, as well as some properties
66   // of the compiled code produced by a compilation.
67   enum Flag {
68     kLazy = 1 << 0,
69     kEval = 1 << 1,
70     kGlobal = 1 << 2,
71     kStrictMode = 1 << 3,
72     kThisHasUses = 1 << 4,
73     kNative = 1 << 5,
74     kDeferredCalling = 1 << 6,
75     kNonDeferredCalling = 1 << 7,
76     kSavesCallerDoubles = 1 << 8,
77     kRequiresFrame = 1 << 9,
78     kMustNotHaveEagerFrame = 1 << 10,
79     kDeoptimizationSupport = 1 << 11,
80     kDebug = 1 << 12,
81     kCompilingForDebugging = 1 << 13,
82     kParseRestriction = 1 << 14,
83     kSerializing = 1 << 15,
84     kContextSpecializing = 1 << 16,
85     kInliningEnabled = 1 << 17,
86     kTypingEnabled = 1 << 18,
87     kDisableFutureOptimization = 1 << 19,
88     kAbortedDueToDependency = 1 << 20
89   };
90
91   CompilationInfo(Handle<JSFunction> closure, Zone* zone);
92   CompilationInfo(Isolate* isolate, Zone* zone);
93   virtual ~CompilationInfo();
94
95   Isolate* isolate() const {
96     return isolate_;
97   }
98   Zone* zone() { return zone_; }
99   bool is_osr() const { return !osr_ast_id_.IsNone(); }
100   bool is_lazy() const { return GetFlag(kLazy); }
101   bool is_eval() const { return GetFlag(kEval); }
102   bool is_global() const { return GetFlag(kGlobal); }
103   StrictMode strict_mode() const {
104     return GetFlag(kStrictMode) ? STRICT : SLOPPY;
105   }
106   FunctionLiteral* function() const { return function_; }
107   Scope* scope() const { return scope_; }
108   Scope* global_scope() const { return global_scope_; }
109   Handle<Code> code() const { return code_; }
110   Handle<JSFunction> closure() const { return closure_; }
111   Handle<SharedFunctionInfo> shared_info() const { return shared_info_; }
112   Handle<Script> script() const { return script_; }
113   void set_script(Handle<Script> script) { script_ = script; }
114   HydrogenCodeStub* code_stub() const {return code_stub_; }
115   v8::Extension* extension() const { return extension_; }
116   ScriptData** cached_data() const { return cached_data_; }
117   ScriptCompiler::CompileOptions compile_options() const {
118     return compile_options_;
119   }
120   ScriptCompiler::ExternalSourceStream* source_stream() const {
121     return source_stream_;
122   }
123   ScriptCompiler::StreamedSource::Encoding source_stream_encoding() const {
124     return source_stream_encoding_;
125   }
126   Handle<Context> context() const { return context_; }
127   BailoutId osr_ast_id() const { return osr_ast_id_; }
128   Handle<Code> unoptimized_code() const { return unoptimized_code_; }
129   int opt_count() const { return opt_count_; }
130   int num_parameters() const;
131   int num_heap_slots() const;
132   Code::Flags flags() const;
133
134   void MarkAsEval() {
135     DCHECK(!is_lazy());
136     SetFlag(kEval);
137   }
138
139   void MarkAsGlobal() {
140     DCHECK(!is_lazy());
141     SetFlag(kGlobal);
142   }
143
144   void set_parameter_count(int parameter_count) {
145     DCHECK(IsStub());
146     parameter_count_ = parameter_count;
147   }
148
149   void set_this_has_uses(bool has_no_uses) {
150     SetFlag(kThisHasUses, has_no_uses);
151   }
152
153   bool this_has_uses() { return GetFlag(kThisHasUses); }
154
155   void SetStrictMode(StrictMode strict_mode) {
156     SetFlag(kStrictMode, strict_mode == STRICT);
157   }
158
159   void MarkAsNative() { SetFlag(kNative); }
160
161   bool is_native() const { return GetFlag(kNative); }
162
163   bool is_calling() const {
164     return GetFlag(kDeferredCalling) || GetFlag(kNonDeferredCalling);
165   }
166
167   void MarkAsDeferredCalling() { SetFlag(kDeferredCalling); }
168
169   bool is_deferred_calling() const { return GetFlag(kDeferredCalling); }
170
171   void MarkAsNonDeferredCalling() { SetFlag(kNonDeferredCalling); }
172
173   bool is_non_deferred_calling() const { return GetFlag(kNonDeferredCalling); }
174
175   void MarkAsSavesCallerDoubles() { SetFlag(kSavesCallerDoubles); }
176
177   bool saves_caller_doubles() const { return GetFlag(kSavesCallerDoubles); }
178
179   void MarkAsRequiresFrame() { SetFlag(kRequiresFrame); }
180
181   bool requires_frame() const { return GetFlag(kRequiresFrame); }
182
183   void MarkMustNotHaveEagerFrame() { SetFlag(kMustNotHaveEagerFrame); }
184
185   bool GetMustNotHaveEagerFrame() const {
186     return GetFlag(kMustNotHaveEagerFrame);
187   }
188
189   void MarkAsDebug() { SetFlag(kDebug); }
190
191   bool is_debug() const { return GetFlag(kDebug); }
192
193   void PrepareForSerializing() { SetFlag(kSerializing); }
194
195   bool will_serialize() const { return GetFlag(kSerializing); }
196
197   void MarkAsContextSpecializing() { SetFlag(kContextSpecializing); }
198
199   bool is_context_specializing() const { return GetFlag(kContextSpecializing); }
200
201   void MarkAsInliningEnabled() { SetFlag(kInliningEnabled); }
202
203   void MarkAsInliningDisabled() { SetFlag(kInliningEnabled, false); }
204
205   bool is_inlining_enabled() const { return GetFlag(kInliningEnabled); }
206
207   void MarkAsTypingEnabled() { SetFlag(kTypingEnabled); }
208
209   bool is_typing_enabled() const { return GetFlag(kTypingEnabled); }
210
211   bool IsCodePreAgingActive() const {
212     return FLAG_optimize_for_size && FLAG_age_code && !will_serialize() &&
213            !is_debug();
214   }
215
216   void SetParseRestriction(ParseRestriction restriction) {
217     SetFlag(kParseRestriction, restriction != NO_PARSE_RESTRICTION);
218   }
219
220   ParseRestriction parse_restriction() const {
221     return GetFlag(kParseRestriction) ? ONLY_SINGLE_FUNCTION_LITERAL
222                                       : NO_PARSE_RESTRICTION;
223   }
224
225   void SetFunction(FunctionLiteral* literal) {
226     DCHECK(function_ == NULL);
227     function_ = literal;
228   }
229   void PrepareForCompilation(Scope* scope);
230   void SetGlobalScope(Scope* global_scope) {
231     DCHECK(global_scope_ == NULL);
232     global_scope_ = global_scope;
233   }
234   Handle<TypeFeedbackVector> feedback_vector() const {
235     return feedback_vector_;
236   }
237   void SetCode(Handle<Code> code) { code_ = code; }
238   void SetExtension(v8::Extension* extension) {
239     DCHECK(!is_lazy());
240     extension_ = extension;
241   }
242   void SetCachedData(ScriptData** cached_data,
243                      ScriptCompiler::CompileOptions compile_options) {
244     compile_options_ = compile_options;
245     if (compile_options == ScriptCompiler::kNoCompileOptions) {
246       cached_data_ = NULL;
247     } else {
248       DCHECK(!is_lazy());
249       cached_data_ = cached_data;
250     }
251   }
252   void SetContext(Handle<Context> context) {
253     context_ = context;
254   }
255
256   void MarkCompilingForDebugging() { SetFlag(kCompilingForDebugging); }
257   bool IsCompilingForDebugging() { return GetFlag(kCompilingForDebugging); }
258   void MarkNonOptimizable() {
259     SetMode(CompilationInfo::NONOPT);
260   }
261
262   bool ShouldTrapOnDeopt() const {
263     return (FLAG_trap_on_deopt && IsOptimizing()) ||
264         (FLAG_trap_on_stub_deopt && IsStub());
265   }
266
267   bool has_global_object() const {
268     return !closure().is_null() &&
269         (closure()->context()->global_object() != NULL);
270   }
271
272   GlobalObject* global_object() const {
273     return has_global_object() ? closure()->context()->global_object() : NULL;
274   }
275
276   // Accessors for the different compilation modes.
277   bool IsOptimizing() const { return mode_ == OPTIMIZE; }
278   bool IsOptimizable() const { return mode_ == BASE; }
279   bool IsStub() const { return mode_ == STUB; }
280   void SetOptimizing(BailoutId osr_ast_id, Handle<Code> unoptimized) {
281     DCHECK(!shared_info_.is_null());
282     SetMode(OPTIMIZE);
283     osr_ast_id_ = osr_ast_id;
284     unoptimized_code_ = unoptimized;
285     optimization_id_ = isolate()->NextOptimizationId();
286   }
287
288   // Deoptimization support.
289   bool HasDeoptimizationSupport() const {
290     return GetFlag(kDeoptimizationSupport);
291   }
292   void EnableDeoptimizationSupport() {
293     DCHECK(IsOptimizable());
294     SetFlag(kDeoptimizationSupport);
295   }
296
297   // Determines whether or not to insert a self-optimization header.
298   bool ShouldSelfOptimize();
299
300   void set_deferred_handles(DeferredHandles* deferred_handles) {
301     DCHECK(deferred_handles_ == NULL);
302     deferred_handles_ = deferred_handles;
303   }
304
305   ZoneList<Handle<HeapObject> >* dependencies(
306       DependentCode::DependencyGroup group) {
307     if (dependencies_[group] == NULL) {
308       dependencies_[group] = new(zone_) ZoneList<Handle<HeapObject> >(2, zone_);
309     }
310     return dependencies_[group];
311   }
312
313   void CommitDependencies(Handle<Code> code);
314
315   void RollbackDependencies();
316
317   void SaveHandles() {
318     SaveHandle(&closure_);
319     SaveHandle(&shared_info_);
320     SaveHandle(&context_);
321     SaveHandle(&script_);
322     SaveHandle(&unoptimized_code_);
323   }
324
325   void AbortOptimization(BailoutReason reason) {
326     if (bailout_reason_ != kNoReason) bailout_reason_ = reason;
327     SetFlag(kDisableFutureOptimization);
328   }
329
330   void RetryOptimization(BailoutReason reason) {
331     if (bailout_reason_ != kNoReason) bailout_reason_ = reason;
332   }
333
334   BailoutReason bailout_reason() const { return bailout_reason_; }
335
336   int prologue_offset() const {
337     DCHECK_NE(Code::kPrologueOffsetNotSet, prologue_offset_);
338     return prologue_offset_;
339   }
340
341   void set_prologue_offset(int prologue_offset) {
342     DCHECK_EQ(Code::kPrologueOffsetNotSet, prologue_offset_);
343     prologue_offset_ = prologue_offset;
344   }
345
346   // Adds offset range [from, to) where fp register does not point
347   // to the current frame base. Used in CPU profiler to detect stack
348   // samples where top frame is not set up.
349   inline void AddNoFrameRange(int from, int to) {
350     if (no_frame_ranges_) no_frame_ranges_->Add(OffsetRange(from, to));
351   }
352
353   List<OffsetRange>* ReleaseNoFrameRanges() {
354     List<OffsetRange>* result = no_frame_ranges_;
355     no_frame_ranges_ = NULL;
356     return result;
357   }
358
359   Handle<Foreign> object_wrapper() {
360     if (object_wrapper_.is_null()) {
361       object_wrapper_ =
362           isolate()->factory()->NewForeign(reinterpret_cast<Address>(this));
363     }
364     return object_wrapper_;
365   }
366
367   void AbortDueToDependencyChange() {
368     DCHECK(!OptimizingCompilerThread::IsOptimizerThread(isolate()));
369     SetFlag(kAbortedDueToDependency);
370   }
371
372   bool HasAbortedDueToDependencyChange() const {
373     DCHECK(!OptimizingCompilerThread::IsOptimizerThread(isolate()));
374     return GetFlag(kAbortedDueToDependency);
375   }
376
377   bool HasSameOsrEntry(Handle<JSFunction> function, BailoutId osr_ast_id) {
378     return osr_ast_id_ == osr_ast_id && function.is_identical_to(closure_);
379   }
380
381   int optimization_id() const { return optimization_id_; }
382
383   AstValueFactory* ast_value_factory() const { return ast_value_factory_; }
384   void SetAstValueFactory(AstValueFactory* ast_value_factory,
385                           bool owned = true) {
386     ast_value_factory_ = ast_value_factory;
387     ast_value_factory_owned_ = owned;
388   }
389
390   AstNode::IdGen* ast_node_id_gen() { return &ast_node_id_gen_; }
391
392  protected:
393   CompilationInfo(Handle<Script> script,
394                   Zone* zone);
395   CompilationInfo(Handle<SharedFunctionInfo> shared_info,
396                   Zone* zone);
397   CompilationInfo(HydrogenCodeStub* stub,
398                   Isolate* isolate,
399                   Zone* zone);
400   CompilationInfo(ScriptCompiler::ExternalSourceStream* source_stream,
401                   ScriptCompiler::StreamedSource::Encoding encoding,
402                   Isolate* isolate, Zone* zone);
403
404
405  private:
406   Isolate* isolate_;
407
408   // Compilation mode.
409   // BASE is generated by the full codegen, optionally prepared for bailouts.
410   // OPTIMIZE is optimized code generated by the Hydrogen-based backend.
411   // NONOPT is generated by the full codegen and is not prepared for
412   //   recompilation/bailouts.  These functions are never recompiled.
413   enum Mode {
414     BASE,
415     OPTIMIZE,
416     NONOPT,
417     STUB
418   };
419
420   void Initialize(Isolate* isolate, Mode mode, Zone* zone);
421
422   void SetMode(Mode mode) {
423     mode_ = mode;
424   }
425
426   void SetFlag(Flag flag) { flags_ |= flag; }
427
428   void SetFlag(Flag flag, bool value) {
429     flags_ = value ? flags_ | flag : flags_ & ~flag;
430   }
431
432   bool GetFlag(Flag flag) const { return (flags_ & flag) != 0; }
433
434   unsigned flags_;
435
436   // Fields filled in by the compilation pipeline.
437   // AST filled in by the parser.
438   FunctionLiteral* function_;
439   // The scope of the function literal as a convenience.  Set to indicate
440   // that scopes have been analyzed.
441   Scope* scope_;
442   // The global scope provided as a convenience.
443   Scope* global_scope_;
444   // For compiled stubs, the stub object
445   HydrogenCodeStub* code_stub_;
446   // The compiled code.
447   Handle<Code> code_;
448
449   // Possible initial inputs to the compilation process.
450   Handle<JSFunction> closure_;
451   Handle<SharedFunctionInfo> shared_info_;
452   Handle<Script> script_;
453   ScriptCompiler::ExternalSourceStream* source_stream_;  // Not owned.
454   ScriptCompiler::StreamedSource::Encoding source_stream_encoding_;
455
456   // Fields possibly needed for eager compilation, NULL by default.
457   v8::Extension* extension_;
458   ScriptData** cached_data_;
459   ScriptCompiler::CompileOptions compile_options_;
460
461   // The context of the caller for eval code, and the global context for a
462   // global script. Will be a null handle otherwise.
463   Handle<Context> context_;
464
465   // Used by codegen, ultimately kept rooted by the SharedFunctionInfo.
466   Handle<TypeFeedbackVector> feedback_vector_;
467
468   // Compilation mode flag and whether deoptimization is allowed.
469   Mode mode_;
470   BailoutId osr_ast_id_;
471   // The unoptimized code we patched for OSR may not be the shared code
472   // afterwards, since we may need to compile it again to include deoptimization
473   // data.  Keep track which code we patched.
474   Handle<Code> unoptimized_code_;
475
476   // The zone from which the compilation pipeline working on this
477   // CompilationInfo allocates.
478   Zone* zone_;
479
480   DeferredHandles* deferred_handles_;
481
482   ZoneList<Handle<HeapObject> >* dependencies_[DependentCode::kGroupCount];
483
484   template<typename T>
485   void SaveHandle(Handle<T> *object) {
486     if (!object->is_null()) {
487       Handle<T> handle(*(*object));
488       *object = handle;
489     }
490   }
491
492   BailoutReason bailout_reason_;
493
494   int prologue_offset_;
495
496   List<OffsetRange>* no_frame_ranges_;
497
498   // A copy of shared_info()->opt_count() to avoid handle deref
499   // during graph optimization.
500   int opt_count_;
501
502   // Number of parameters used for compilation of stubs that require arguments.
503   int parameter_count_;
504
505   Handle<Foreign> object_wrapper_;
506
507   int optimization_id_;
508
509   AstValueFactory* ast_value_factory_;
510   bool ast_value_factory_owned_;
511   AstNode::IdGen ast_node_id_gen_;
512
513   DISALLOW_COPY_AND_ASSIGN(CompilationInfo);
514 };
515
516
517 // Exactly like a CompilationInfo, except also creates and enters a
518 // Zone on construction and deallocates it on exit.
519 class CompilationInfoWithZone: public CompilationInfo {
520  public:
521   explicit CompilationInfoWithZone(Handle<Script> script)
522       : CompilationInfo(script, &zone_),
523         zone_(script->GetIsolate()) {}
524   explicit CompilationInfoWithZone(Handle<SharedFunctionInfo> shared_info)
525       : CompilationInfo(shared_info, &zone_),
526         zone_(shared_info->GetIsolate()) {}
527   explicit CompilationInfoWithZone(Handle<JSFunction> closure)
528       : CompilationInfo(closure, &zone_),
529         zone_(closure->GetIsolate()) {}
530   CompilationInfoWithZone(HydrogenCodeStub* stub, Isolate* isolate)
531       : CompilationInfo(stub, isolate, &zone_),
532         zone_(isolate) {}
533   CompilationInfoWithZone(ScriptCompiler::ExternalSourceStream* stream,
534                           ScriptCompiler::StreamedSource::Encoding encoding,
535                           Isolate* isolate)
536       : CompilationInfo(stream, encoding, isolate, &zone_), zone_(isolate) {}
537
538   // Virtual destructor because a CompilationInfoWithZone has to exit the
539   // zone scope and get rid of dependent maps even when the destructor is
540   // called when cast as a CompilationInfo.
541   virtual ~CompilationInfoWithZone() {
542     RollbackDependencies();
543   }
544
545  private:
546   Zone zone_;
547 };
548
549
550 // A wrapper around a CompilationInfo that detaches the Handles from
551 // the underlying DeferredHandleScope and stores them in info_ on
552 // destruction.
553 class CompilationHandleScope BASE_EMBEDDED {
554  public:
555   explicit CompilationHandleScope(CompilationInfo* info)
556       : deferred_(info->isolate()), info_(info) {}
557   ~CompilationHandleScope() {
558     info_->set_deferred_handles(deferred_.Detach());
559   }
560
561  private:
562   DeferredHandleScope deferred_;
563   CompilationInfo* info_;
564 };
565
566
567 class HGraph;
568 class HOptimizedGraphBuilder;
569 class LChunk;
570
571 // A helper class that calls the three compilation phases in
572 // Crankshaft and keeps track of its state.  The three phases
573 // CreateGraph, OptimizeGraph and GenerateAndInstallCode can either
574 // fail, bail-out to the full code generator or succeed.  Apart from
575 // their return value, the status of the phase last run can be checked
576 // using last_status().
577 class OptimizedCompileJob: public ZoneObject {
578  public:
579   explicit OptimizedCompileJob(CompilationInfo* info)
580       : info_(info),
581         graph_builder_(NULL),
582         graph_(NULL),
583         chunk_(NULL),
584         last_status_(FAILED),
585         awaiting_install_(false) { }
586
587   enum Status {
588     FAILED, BAILED_OUT, SUCCEEDED
589   };
590
591   MUST_USE_RESULT Status CreateGraph();
592   MUST_USE_RESULT Status OptimizeGraph();
593   MUST_USE_RESULT Status GenerateCode();
594
595   Status last_status() const { return last_status_; }
596   CompilationInfo* info() const { return info_; }
597   Isolate* isolate() const { return info()->isolate(); }
598
599   Status RetryOptimization(BailoutReason reason) {
600     info_->RetryOptimization(reason);
601     return SetLastStatus(BAILED_OUT);
602   }
603
604   Status AbortOptimization(BailoutReason reason) {
605     info_->AbortOptimization(reason);
606     return SetLastStatus(BAILED_OUT);
607   }
608
609   void WaitForInstall() {
610     DCHECK(info_->is_osr());
611     awaiting_install_ = true;
612   }
613
614   bool IsWaitingForInstall() { return awaiting_install_; }
615
616  private:
617   CompilationInfo* info_;
618   HOptimizedGraphBuilder* graph_builder_;
619   HGraph* graph_;
620   LChunk* chunk_;
621   base::TimeDelta time_taken_to_create_graph_;
622   base::TimeDelta time_taken_to_optimize_;
623   base::TimeDelta time_taken_to_codegen_;
624   Status last_status_;
625   bool awaiting_install_;
626
627   MUST_USE_RESULT Status SetLastStatus(Status status) {
628     last_status_ = status;
629     return last_status_;
630   }
631   void RecordOptimizationStats();
632
633   struct Timer {
634     Timer(OptimizedCompileJob* job, base::TimeDelta* location)
635         : job_(job), location_(location) {
636       DCHECK(location_ != NULL);
637       timer_.Start();
638     }
639
640     ~Timer() {
641       *location_ += timer_.Elapsed();
642     }
643
644     OptimizedCompileJob* job_;
645     base::ElapsedTimer timer_;
646     base::TimeDelta* location_;
647   };
648 };
649
650
651 // The V8 compiler
652 //
653 // General strategy: Source code is translated into an anonymous function w/o
654 // parameters which then can be executed. If the source code contains other
655 // functions, they will be compiled and allocated as part of the compilation
656 // of the source code.
657
658 // Please note this interface returns shared function infos.  This means you
659 // need to call Factory::NewFunctionFromSharedFunctionInfo before you have a
660 // real function with a context.
661
662 class Compiler : public AllStatic {
663  public:
664   MUST_USE_RESULT static MaybeHandle<Code> GetUnoptimizedCode(
665       Handle<JSFunction> function);
666   MUST_USE_RESULT static MaybeHandle<Code> GetLazyCode(
667       Handle<JSFunction> function);
668   MUST_USE_RESULT static MaybeHandle<Code> GetUnoptimizedCode(
669       Handle<SharedFunctionInfo> shared);
670   MUST_USE_RESULT static MaybeHandle<Code> GetDebugCode(
671       Handle<JSFunction> function);
672
673   static bool EnsureCompiled(Handle<JSFunction> function,
674                              ClearExceptionFlag flag);
675
676   static bool EnsureDeoptimizationSupport(CompilationInfo* info);
677
678   static void CompileForLiveEdit(Handle<Script> script);
679
680   // Compile a String source within a context for eval.
681   MUST_USE_RESULT static MaybeHandle<JSFunction> GetFunctionFromEval(
682       Handle<String> source,
683       Handle<Context> context,
684       StrictMode strict_mode,
685       ParseRestriction restriction,
686       int scope_position);
687
688   // Compile a String source within a context.
689   static Handle<SharedFunctionInfo> CompileScript(
690       Handle<String> source, Handle<Object> script_name, int line_offset,
691       int column_offset, bool is_shared_cross_origin, Handle<Context> context,
692       v8::Extension* extension, ScriptData** cached_data,
693       ScriptCompiler::CompileOptions compile_options,
694       NativesFlag is_natives_code);
695
696   static Handle<SharedFunctionInfo> CompileStreamedScript(CompilationInfo* info,
697                                                           int source_length);
698
699   // Create a shared function info object (the code may be lazily compiled).
700   static Handle<SharedFunctionInfo> BuildFunctionInfo(FunctionLiteral* node,
701                                                       Handle<Script> script,
702                                                       CompilationInfo* outer);
703
704   enum ConcurrencyMode { NOT_CONCURRENT, CONCURRENT };
705
706   // Generate and return optimized code or start a concurrent optimization job.
707   // In the latter case, return the InOptimizationQueue builtin.  On failure,
708   // return the empty handle.
709   MUST_USE_RESULT static MaybeHandle<Code> GetOptimizedCode(
710       Handle<JSFunction> function,
711       Handle<Code> current_code,
712       ConcurrencyMode mode,
713       BailoutId osr_ast_id = BailoutId::None());
714
715   // Generate and return code from previously queued optimization job.
716   // On failure, return the empty handle.
717   static Handle<Code> GetConcurrentlyOptimizedCode(OptimizedCompileJob* job);
718
719   static bool DebuggerWantsEagerCompilation(
720       CompilationInfo* info, bool allow_lazy_without_ctx = false);
721 };
722
723
724 class CompilationPhase BASE_EMBEDDED {
725  public:
726   CompilationPhase(const char* name, CompilationInfo* info);
727   ~CompilationPhase();
728
729  protected:
730   bool ShouldProduceTraceOutput() const;
731
732   const char* name() const { return name_; }
733   CompilationInfo* info() const { return info_; }
734   Isolate* isolate() const { return info()->isolate(); }
735   Zone* zone() { return &zone_; }
736
737  private:
738   const char* name_;
739   CompilationInfo* info_;
740   Zone zone_;
741   unsigned info_zone_start_allocation_size_;
742   base::ElapsedTimer timer_;
743
744   DISALLOW_COPY_AND_ASSIGN(CompilationPhase);
745 };
746
747 } }  // namespace v8::internal
748
749 #endif  // V8_COMPILER_H_