• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // 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 
31 #include "allocation.h"
32 #include "ast.h"
33 #include "zone.h"
34 
35 namespace v8 {
36 namespace internal {
37 
38 class ScriptDataImpl;
39 class HydrogenCodeStub;
40 
41 // ParseRestriction is used to restrict the set of valid statements in a
42 // unit of compilation.  Restriction violations cause a syntax error.
43 enum ParseRestriction {
44   NO_PARSE_RESTRICTION,         // All expressions are allowed.
45   ONLY_SINGLE_FUNCTION_LITERAL  // Only a single FunctionLiteral expression.
46 };
47 
48 struct OffsetRange {
OffsetRangeOffsetRange49   OffsetRange(int from, int to) : from(from), to(to) {}
50   int from;
51   int to;
52 };
53 
54 // CompilationInfo encapsulates some information known at compile time.  It
55 // is constructed based on the resources available at compile-time.
56 class CompilationInfo {
57  public:
58   CompilationInfo(Handle<JSFunction> closure, Zone* zone);
59   virtual ~CompilationInfo();
60 
isolate()61   Isolate* isolate() const {
62     return isolate_;
63   }
zone()64   Zone* zone() { return zone_; }
is_osr()65   bool is_osr() const { return !osr_ast_id_.IsNone(); }
is_lazy()66   bool is_lazy() const { return IsLazy::decode(flags_); }
is_eval()67   bool is_eval() const { return IsEval::decode(flags_); }
is_global()68   bool is_global() const { return IsGlobal::decode(flags_); }
is_classic_mode()69   bool is_classic_mode() const { return language_mode() == CLASSIC_MODE; }
is_extended_mode()70   bool is_extended_mode() const { return language_mode() == EXTENDED_MODE; }
language_mode()71   LanguageMode language_mode() const {
72     return LanguageModeField::decode(flags_);
73   }
is_in_loop()74   bool is_in_loop() const { return IsInLoop::decode(flags_); }
function()75   FunctionLiteral* function() const { return function_; }
scope()76   Scope* scope() const { return scope_; }
global_scope()77   Scope* global_scope() const { return global_scope_; }
code()78   Handle<Code> code() const { return code_; }
closure()79   Handle<JSFunction> closure() const { return closure_; }
shared_info()80   Handle<SharedFunctionInfo> shared_info() const { return shared_info_; }
script()81   Handle<Script> script() const { return script_; }
code_stub()82   HydrogenCodeStub* code_stub() const {return code_stub_; }
extension()83   v8::Extension* extension() const { return extension_; }
pre_parse_data()84   ScriptDataImpl* pre_parse_data() const { return pre_parse_data_; }
context()85   Handle<Context> context() const { return context_; }
osr_ast_id()86   BailoutId osr_ast_id() const { return osr_ast_id_; }
osr_pc_offset()87   uint32_t osr_pc_offset() const { return osr_pc_offset_; }
opt_count()88   int opt_count() const { return opt_count_; }
89   int num_parameters() const;
90   int num_heap_slots() const;
91   Code::Flags flags() const;
92 
MarkAsEval()93   void MarkAsEval() {
94     ASSERT(!is_lazy());
95     flags_ |= IsEval::encode(true);
96   }
MarkAsGlobal()97   void MarkAsGlobal() {
98     ASSERT(!is_lazy());
99     flags_ |= IsGlobal::encode(true);
100   }
set_parameter_count(int parameter_count)101   void set_parameter_count(int parameter_count) {
102     ASSERT(IsStub());
103     parameter_count_ = parameter_count;
104   }
SetLanguageMode(LanguageMode language_mode)105   void SetLanguageMode(LanguageMode language_mode) {
106     ASSERT(this->language_mode() == CLASSIC_MODE ||
107            this->language_mode() == language_mode ||
108            language_mode == EXTENDED_MODE);
109     flags_ = LanguageModeField::update(flags_, language_mode);
110   }
MarkAsInLoop()111   void MarkAsInLoop() {
112     ASSERT(is_lazy());
113     flags_ |= IsInLoop::encode(true);
114   }
MarkAsNative()115   void MarkAsNative() {
116     flags_ |= IsNative::encode(true);
117   }
118 
is_native()119   bool is_native() const {
120     return IsNative::decode(flags_);
121   }
122 
is_calling()123   bool is_calling() const {
124     return is_deferred_calling() || is_non_deferred_calling();
125   }
126 
MarkAsDeferredCalling()127   void MarkAsDeferredCalling() {
128     flags_ |= IsDeferredCalling::encode(true);
129   }
130 
is_deferred_calling()131   bool is_deferred_calling() const {
132     return IsDeferredCalling::decode(flags_);
133   }
134 
MarkAsNonDeferredCalling()135   void MarkAsNonDeferredCalling() {
136     flags_ |= IsNonDeferredCalling::encode(true);
137   }
138 
is_non_deferred_calling()139   bool is_non_deferred_calling() const {
140     return IsNonDeferredCalling::decode(flags_);
141   }
142 
MarkAsSavesCallerDoubles()143   void MarkAsSavesCallerDoubles() {
144     flags_ |= SavesCallerDoubles::encode(true);
145   }
146 
saves_caller_doubles()147   bool saves_caller_doubles() const {
148     return SavesCallerDoubles::decode(flags_);
149   }
150 
MarkAsRequiresFrame()151   void MarkAsRequiresFrame() {
152     flags_ |= RequiresFrame::encode(true);
153   }
154 
requires_frame()155   bool requires_frame() const {
156     return RequiresFrame::decode(flags_);
157   }
158 
SetParseRestriction(ParseRestriction restriction)159   void SetParseRestriction(ParseRestriction restriction) {
160     flags_ = ParseRestricitonField::update(flags_, restriction);
161   }
162 
parse_restriction()163   ParseRestriction parse_restriction() const {
164     return ParseRestricitonField::decode(flags_);
165   }
166 
SetFunction(FunctionLiteral * literal)167   void SetFunction(FunctionLiteral* literal) {
168     ASSERT(function_ == NULL);
169     function_ = literal;
170   }
SetScope(Scope * scope)171   void SetScope(Scope* scope) {
172     ASSERT(scope_ == NULL);
173     scope_ = scope;
174   }
SetGlobalScope(Scope * global_scope)175   void SetGlobalScope(Scope* global_scope) {
176     ASSERT(global_scope_ == NULL);
177     global_scope_ = global_scope;
178   }
SetCode(Handle<Code> code)179   void SetCode(Handle<Code> code) { code_ = code; }
SetExtension(v8::Extension * extension)180   void SetExtension(v8::Extension* extension) {
181     ASSERT(!is_lazy());
182     extension_ = extension;
183   }
SetPreParseData(ScriptDataImpl * pre_parse_data)184   void SetPreParseData(ScriptDataImpl* pre_parse_data) {
185     ASSERT(!is_lazy());
186     pre_parse_data_ = pre_parse_data;
187   }
SetContext(Handle<Context> context)188   void SetContext(Handle<Context> context) {
189     context_ = context;
190   }
MarkCompilingForDebugging(Handle<Code> current_code)191   void MarkCompilingForDebugging(Handle<Code> current_code) {
192     ASSERT(mode_ != OPTIMIZE);
193     ASSERT(current_code->kind() == Code::FUNCTION);
194     flags_ |= IsCompilingForDebugging::encode(true);
195     if (current_code->is_compiled_optimizable()) {
196       EnableDeoptimizationSupport();
197     } else {
198       mode_ = CompilationInfo::NONOPT;
199     }
200   }
IsCompilingForDebugging()201   bool IsCompilingForDebugging() {
202     return IsCompilingForDebugging::decode(flags_);
203   }
204 
ShouldTrapOnDeopt()205   bool ShouldTrapOnDeopt() const {
206     return (FLAG_trap_on_deopt && IsOptimizing()) ||
207         (FLAG_trap_on_stub_deopt && IsStub());
208   }
209 
has_global_object()210   bool has_global_object() const {
211     return !closure().is_null() &&
212         (closure()->context()->global_object() != NULL);
213   }
214 
global_object()215   GlobalObject* global_object() const {
216     return has_global_object() ? closure()->context()->global_object() : NULL;
217   }
218 
219   // Accessors for the different compilation modes.
IsOptimizing()220   bool IsOptimizing() const { return mode_ == OPTIMIZE; }
IsOptimizable()221   bool IsOptimizable() const { return mode_ == BASE; }
IsStub()222   bool IsStub() const { return mode_ == STUB; }
SetOptimizing(BailoutId osr_ast_id)223   void SetOptimizing(BailoutId osr_ast_id) {
224     SetMode(OPTIMIZE);
225     osr_ast_id_ = osr_ast_id;
226   }
227   void DisableOptimization();
228 
229   // Deoptimization support.
HasDeoptimizationSupport()230   bool HasDeoptimizationSupport() const {
231     return SupportsDeoptimization::decode(flags_);
232   }
EnableDeoptimizationSupport()233   void EnableDeoptimizationSupport() {
234     ASSERT(IsOptimizable());
235     flags_ |= SupportsDeoptimization::encode(true);
236   }
237 
238   // Determines whether or not to insert a self-optimization header.
239   bool ShouldSelfOptimize();
240 
241   // Reset code to the unoptimized version when optimization is aborted.
AbortOptimization()242   void AbortOptimization() {
243     SetCode(handle(shared_info()->code()));
244   }
245 
set_deferred_handles(DeferredHandles * deferred_handles)246   void set_deferred_handles(DeferredHandles* deferred_handles) {
247     ASSERT(deferred_handles_ == NULL);
248     deferred_handles_ = deferred_handles;
249   }
250 
dependencies(DependentCode::DependencyGroup group)251   ZoneList<Handle<HeapObject> >* dependencies(
252       DependentCode::DependencyGroup group) {
253     if (dependencies_[group] == NULL) {
254       dependencies_[group] = new(zone_) ZoneList<Handle<HeapObject> >(2, zone_);
255     }
256     return dependencies_[group];
257   }
258 
259   void CommitDependencies(Handle<Code> code);
260 
261   void RollbackDependencies();
262 
SaveHandles()263   void SaveHandles() {
264     SaveHandle(&closure_);
265     SaveHandle(&shared_info_);
266     SaveHandle(&context_);
267     SaveHandle(&script_);
268   }
269 
bailout_reason()270   BailoutReason bailout_reason() const { return bailout_reason_; }
set_bailout_reason(BailoutReason reason)271   void set_bailout_reason(BailoutReason reason) { bailout_reason_ = reason; }
272 
prologue_offset()273   int prologue_offset() const {
274     ASSERT_NE(Code::kPrologueOffsetNotSet, prologue_offset_);
275     return prologue_offset_;
276   }
277 
set_prologue_offset(int prologue_offset)278   void set_prologue_offset(int prologue_offset) {
279     ASSERT_EQ(Code::kPrologueOffsetNotSet, prologue_offset_);
280     prologue_offset_ = prologue_offset;
281   }
282 
283   // Adds offset range [from, to) where fp register does not point
284   // to the current frame base. Used in CPU profiler to detect stack
285   // samples where top frame is not set up.
AddNoFrameRange(int from,int to)286   inline void AddNoFrameRange(int from, int to) {
287     if (no_frame_ranges_) no_frame_ranges_->Add(OffsetRange(from, to));
288   }
289 
ReleaseNoFrameRanges()290   List<OffsetRange>* ReleaseNoFrameRanges() {
291     List<OffsetRange>* result = no_frame_ranges_;
292     no_frame_ranges_ = NULL;
293     return result;
294   }
295 
object_wrapper()296   Handle<Foreign> object_wrapper() {
297     if (object_wrapper_.is_null()) {
298       object_wrapper_ =
299           isolate()->factory()->NewForeign(reinterpret_cast<Address>(this));
300     }
301     return object_wrapper_;
302   }
303 
AbortDueToDependencyChange()304   void AbortDueToDependencyChange() {
305     ASSERT(!OptimizingCompilerThread::IsOptimizerThread(isolate()));
306     abort_due_to_dependency_ = true;
307   }
308 
HasAbortedDueToDependencyChange()309   bool HasAbortedDueToDependencyChange() {
310     ASSERT(!OptimizingCompilerThread::IsOptimizerThread(isolate()));
311     return abort_due_to_dependency_;
312   }
313 
set_osr_pc_offset(uint32_t pc_offset)314   void set_osr_pc_offset(uint32_t pc_offset) {
315     osr_pc_offset_ = pc_offset;
316   }
317 
HasSameOsrEntry(Handle<JSFunction> function,uint32_t pc_offset)318   bool HasSameOsrEntry(Handle<JSFunction> function, uint32_t pc_offset) {
319     return osr_pc_offset_ == pc_offset && function.is_identical_to(closure_);
320   }
321 
322  protected:
323   CompilationInfo(Handle<Script> script,
324                   Zone* zone);
325   CompilationInfo(Handle<SharedFunctionInfo> shared_info,
326                   Zone* zone);
327   CompilationInfo(HydrogenCodeStub* stub,
328                   Isolate* isolate,
329                   Zone* zone);
330 
331  private:
332   Isolate* isolate_;
333 
334   // Compilation mode.
335   // BASE is generated by the full codegen, optionally prepared for bailouts.
336   // OPTIMIZE is optimized code generated by the Hydrogen-based backend.
337   // NONOPT is generated by the full codegen and is not prepared for
338   //   recompilation/bailouts.  These functions are never recompiled.
339   enum Mode {
340     BASE,
341     OPTIMIZE,
342     NONOPT,
343     STUB
344   };
345 
346   void Initialize(Isolate* isolate, Mode mode, Zone* zone);
347 
SetMode(Mode mode)348   void SetMode(Mode mode) {
349     ASSERT(isolate()->use_crankshaft());
350     mode_ = mode;
351   }
352 
353   // Flags using template class BitField<type, start, length>.  All are
354   // false by default.
355   //
356   // Compilation is either eager or lazy.
357   class IsLazy:   public BitField<bool, 0, 1> {};
358   // Flags that can be set for eager compilation.
359   class IsEval:   public BitField<bool, 1, 1> {};
360   class IsGlobal: public BitField<bool, 2, 1> {};
361   // Flags that can be set for lazy compilation.
362   class IsInLoop: public BitField<bool, 3, 1> {};
363   // Strict mode - used in eager compilation.
364   class LanguageModeField: public BitField<LanguageMode, 4, 2> {};
365   // Is this a function from our natives.
366   class IsNative: public BitField<bool, 6, 1> {};
367   // Is this code being compiled with support for deoptimization..
368   class SupportsDeoptimization: public BitField<bool, 7, 1> {};
369   // If compiling for debugging produce just full code matching the
370   // initial mode setting.
371   class IsCompilingForDebugging: public BitField<bool, 8, 1> {};
372   // If the compiled code contains calls that require building a frame
373   class IsCalling: public BitField<bool, 9, 1> {};
374   // If the compiled code contains calls that require building a frame
375   class IsDeferredCalling: public BitField<bool, 10, 1> {};
376   // If the compiled code contains calls that require building a frame
377   class IsNonDeferredCalling: public BitField<bool, 11, 1> {};
378   // If the compiled code saves double caller registers that it clobbers.
379   class SavesCallerDoubles: public BitField<bool, 12, 1> {};
380   // If the set of valid statements is restricted.
381   class ParseRestricitonField: public BitField<ParseRestriction, 13, 1> {};
382   // If the function requires a frame (for unspecified reasons)
383   class RequiresFrame: public BitField<bool, 14, 1> {};
384 
385   unsigned flags_;
386 
387   // Fields filled in by the compilation pipeline.
388   // AST filled in by the parser.
389   FunctionLiteral* function_;
390   // The scope of the function literal as a convenience.  Set to indicate
391   // that scopes have been analyzed.
392   Scope* scope_;
393   // The global scope provided as a convenience.
394   Scope* global_scope_;
395   // For compiled stubs, the stub object
396   HydrogenCodeStub* code_stub_;
397   // The compiled code.
398   Handle<Code> code_;
399 
400   // Possible initial inputs to the compilation process.
401   Handle<JSFunction> closure_;
402   Handle<SharedFunctionInfo> shared_info_;
403   Handle<Script> script_;
404 
405   // Fields possibly needed for eager compilation, NULL by default.
406   v8::Extension* extension_;
407   ScriptDataImpl* pre_parse_data_;
408 
409   // The context of the caller for eval code, and the global context for a
410   // global script. Will be a null handle otherwise.
411   Handle<Context> context_;
412 
413   // Compilation mode flag and whether deoptimization is allowed.
414   Mode mode_;
415   BailoutId osr_ast_id_;
416   // The pc_offset corresponding to osr_ast_id_ in unoptimized code.
417   // We can look this up in the back edge table, but cache it for quick access.
418   uint32_t osr_pc_offset_;
419 
420   // Flag whether compilation needs to be aborted due to dependency change.
421   bool abort_due_to_dependency_;
422 
423   // The zone from which the compilation pipeline working on this
424   // CompilationInfo allocates.
425   Zone* zone_;
426 
427   DeferredHandles* deferred_handles_;
428 
429   ZoneList<Handle<HeapObject> >* dependencies_[DependentCode::kGroupCount];
430 
431   template<typename T>
SaveHandle(Handle<T> * object)432   void SaveHandle(Handle<T> *object) {
433     if (!object->is_null()) {
434       Handle<T> handle(*(*object));
435       *object = handle;
436     }
437   }
438 
439   BailoutReason bailout_reason_;
440 
441   int prologue_offset_;
442 
443   List<OffsetRange>* no_frame_ranges_;
444 
445   // A copy of shared_info()->opt_count() to avoid handle deref
446   // during graph optimization.
447   int opt_count_;
448 
449   // Number of parameters used for compilation of stubs that require arguments.
450   int parameter_count_;
451 
452   Handle<Foreign> object_wrapper_;
453 
454   DISALLOW_COPY_AND_ASSIGN(CompilationInfo);
455 };
456 
457 
458 // Exactly like a CompilationInfo, except also creates and enters a
459 // Zone on construction and deallocates it on exit.
460 class CompilationInfoWithZone: public CompilationInfo {
461  public:
CompilationInfoWithZone(Handle<Script> script)462   explicit CompilationInfoWithZone(Handle<Script> script)
463       : CompilationInfo(script, &zone_),
464         zone_(script->GetIsolate()) {}
CompilationInfoWithZone(Handle<SharedFunctionInfo> shared_info)465   explicit CompilationInfoWithZone(Handle<SharedFunctionInfo> shared_info)
466       : CompilationInfo(shared_info, &zone_),
467         zone_(shared_info->GetIsolate()) {}
CompilationInfoWithZone(Handle<JSFunction> closure)468   explicit CompilationInfoWithZone(Handle<JSFunction> closure)
469       : CompilationInfo(closure, &zone_),
470         zone_(closure->GetIsolate()) {}
CompilationInfoWithZone(HydrogenCodeStub * stub,Isolate * isolate)471   CompilationInfoWithZone(HydrogenCodeStub* stub, Isolate* isolate)
472       : CompilationInfo(stub, isolate, &zone_),
473         zone_(isolate) {}
474 
475   // Virtual destructor because a CompilationInfoWithZone has to exit the
476   // zone scope and get rid of dependent maps even when the destructor is
477   // called when cast as a CompilationInfo.
~CompilationInfoWithZone()478   virtual ~CompilationInfoWithZone() {
479     RollbackDependencies();
480   }
481 
482  private:
483   Zone zone_;
484 };
485 
486 
487 // A wrapper around a CompilationInfo that detaches the Handles from
488 // the underlying DeferredHandleScope and stores them in info_ on
489 // destruction.
490 class CompilationHandleScope BASE_EMBEDDED {
491  public:
CompilationHandleScope(CompilationInfo * info)492   explicit CompilationHandleScope(CompilationInfo* info)
493       : deferred_(info->isolate()), info_(info) {}
~CompilationHandleScope()494   ~CompilationHandleScope() {
495     info_->set_deferred_handles(deferred_.Detach());
496   }
497 
498  private:
499   DeferredHandleScope deferred_;
500   CompilationInfo* info_;
501 };
502 
503 
504 class HGraph;
505 class HOptimizedGraphBuilder;
506 class LChunk;
507 
508 // A helper class that calls the three compilation phases in
509 // Crankshaft and keeps track of its state.  The three phases
510 // CreateGraph, OptimizeGraph and GenerateAndInstallCode can either
511 // fail, bail-out to the full code generator or succeed.  Apart from
512 // their return value, the status of the phase last run can be checked
513 // using last_status().
514 class RecompileJob: public ZoneObject {
515  public:
RecompileJob(CompilationInfo * info)516   explicit RecompileJob(CompilationInfo* info)
517       : info_(info),
518         graph_builder_(NULL),
519         graph_(NULL),
520         chunk_(NULL),
521         last_status_(FAILED),
522         awaiting_install_(false) { }
523 
524   enum Status {
525     FAILED, BAILED_OUT, SUCCEEDED
526   };
527 
528   MUST_USE_RESULT Status CreateGraph();
529   MUST_USE_RESULT Status OptimizeGraph();
530   MUST_USE_RESULT Status GenerateAndInstallCode();
531 
last_status()532   Status last_status() const { return last_status_; }
info()533   CompilationInfo* info() const { return info_; }
isolate()534   Isolate* isolate() const { return info()->isolate(); }
535 
AbortOptimization()536   MUST_USE_RESULT Status AbortOptimization() {
537     info_->AbortOptimization();
538     info_->shared_info()->DisableOptimization(info_->bailout_reason());
539     return SetLastStatus(BAILED_OUT);
540   }
541 
WaitForInstall()542   void WaitForInstall() {
543     ASSERT(info_->is_osr());
544     awaiting_install_ = true;
545   }
546 
IsWaitingForInstall()547   bool IsWaitingForInstall() { return awaiting_install_; }
548 
549  private:
550   CompilationInfo* info_;
551   HOptimizedGraphBuilder* graph_builder_;
552   HGraph* graph_;
553   LChunk* chunk_;
554   TimeDelta time_taken_to_create_graph_;
555   TimeDelta time_taken_to_optimize_;
556   TimeDelta time_taken_to_codegen_;
557   Status last_status_;
558   bool awaiting_install_;
559 
SetLastStatus(Status status)560   MUST_USE_RESULT Status SetLastStatus(Status status) {
561     last_status_ = status;
562     return last_status_;
563   }
564   void RecordOptimizationStats();
565 
566   struct Timer {
TimerTimer567     Timer(RecompileJob* job, TimeDelta* location)
568         : job_(job), location_(location) {
569       ASSERT(location_ != NULL);
570       timer_.Start();
571     }
572 
~TimerTimer573     ~Timer() {
574       *location_ += timer_.Elapsed();
575     }
576 
577     RecompileJob* job_;
578     ElapsedTimer timer_;
579     TimeDelta* location_;
580   };
581 };
582 
583 
584 // The V8 compiler
585 //
586 // General strategy: Source code is translated into an anonymous function w/o
587 // parameters which then can be executed. If the source code contains other
588 // functions, they will be compiled and allocated as part of the compilation
589 // of the source code.
590 
591 // Please note this interface returns shared function infos.  This means you
592 // need to call Factory::NewFunctionFromSharedFunctionInfo before you have a
593 // real function with a context.
594 
595 class Compiler : public AllStatic {
596  public:
597   // Call count before primitive functions trigger their own optimization.
598   static const int kCallsUntilPrimitiveOpt = 200;
599 
600   // All routines return a SharedFunctionInfo.
601   // If an error occurs an exception is raised and the return handle
602   // contains NULL.
603 
604   // Compile a String source within a context.
605   static Handle<SharedFunctionInfo> Compile(Handle<String> source,
606                                             Handle<Object> script_name,
607                                             int line_offset,
608                                             int column_offset,
609                                             bool is_shared_cross_origin,
610                                             Handle<Context> context,
611                                             v8::Extension* extension,
612                                             ScriptDataImpl* pre_data,
613                                             Handle<Object> script_data,
614                                             NativesFlag is_natives_code);
615 
616   // Compile a String source within a context for Eval.
617   static Handle<SharedFunctionInfo> CompileEval(Handle<String> source,
618                                                 Handle<Context> context,
619                                                 bool is_global,
620                                                 LanguageMode language_mode,
621                                                 ParseRestriction restriction,
622                                                 int scope_position);
623 
624   // Compile from function info (used for lazy compilation). Returns true on
625   // success and false if the compilation resulted in a stack overflow.
626   static bool CompileLazy(CompilationInfo* info);
627 
628   static bool RecompileConcurrent(Handle<JSFunction> function,
629                                   uint32_t osr_pc_offset = 0);
630 
631   // Compile a shared function info object (the function is possibly lazily
632   // compiled).
633   static Handle<SharedFunctionInfo> BuildFunctionInfo(FunctionLiteral* node,
634                                                       Handle<Script> script);
635 
636   // Set the function info for a newly compiled function.
637   static void SetFunctionInfo(Handle<SharedFunctionInfo> function_info,
638                               FunctionLiteral* lit,
639                               bool is_toplevel,
640                               Handle<Script> script);
641 
642   static Handle<Code> InstallOptimizedCode(RecompileJob* job);
643 
644 #ifdef ENABLE_DEBUGGER_SUPPORT
645   static bool MakeCodeForLiveEdit(CompilationInfo* info);
646 #endif
647 
648   static void RecordFunctionCompilation(Logger::LogEventsAndTags tag,
649                                         CompilationInfo* info,
650                                         Handle<SharedFunctionInfo> shared);
651 };
652 
653 
654 class CompilationPhase BASE_EMBEDDED {
655  public:
656   CompilationPhase(const char* name, CompilationInfo* info);
657   ~CompilationPhase();
658 
659  protected:
660   bool ShouldProduceTraceOutput() const;
661 
name()662   const char* name() const { return name_; }
info()663   CompilationInfo* info() const { return info_; }
isolate()664   Isolate* isolate() const { return info()->isolate(); }
zone()665   Zone* zone() { return &zone_; }
666 
667  private:
668   const char* name_;
669   CompilationInfo* info_;
670   Zone zone_;
671   unsigned info_zone_start_allocation_size_;
672   ElapsedTimer timer_;
673 
674   DISALLOW_COPY_AND_ASSIGN(CompilationPhase);
675 };
676 
677 
678 } }  // namespace v8::internal
679 
680 #endif  // V8_COMPILER_H_
681