v8  3.14.5(node0.10.28)
V8 is Google's open source JavaScript engine
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
compiler.h
Go to the documentation of this file.
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 
40 // CompilationInfo encapsulates some information known at compile time. It
41 // is constructed based on the resources available at compile-time.
43  public:
47 
48  virtual ~CompilationInfo();
49 
51  ASSERT(Isolate::Current() == isolate_);
52  return isolate_;
53  }
54  Zone* zone() {
55  return zone_;
56  }
57  bool is_lazy() const { return IsLazy::decode(flags_); }
58  bool is_eval() const { return IsEval::decode(flags_); }
59  bool is_global() const { return IsGlobal::decode(flags_); }
60  bool is_classic_mode() const { return language_mode() == CLASSIC_MODE; }
61  bool is_extended_mode() const { return language_mode() == EXTENDED_MODE; }
63  return LanguageModeField::decode(flags_);
64  }
65  bool is_in_loop() const { return IsInLoop::decode(flags_); }
66  FunctionLiteral* function() const { return function_; }
67  Scope* scope() const { return scope_; }
68  Scope* global_scope() const { return global_scope_; }
69  Handle<Code> code() const { return code_; }
70  Handle<JSFunction> closure() const { return closure_; }
71  Handle<SharedFunctionInfo> shared_info() const { return shared_info_; }
72  Handle<Script> script() const { return script_; }
73  v8::Extension* extension() const { return extension_; }
74  ScriptDataImpl* pre_parse_data() const { return pre_parse_data_; }
75  Handle<Context> context() const { return context_; }
76  BailoutId osr_ast_id() const { return osr_ast_id_; }
77 
78  void MarkAsEval() {
79  ASSERT(!is_lazy());
80  flags_ |= IsEval::encode(true);
81  }
82  void MarkAsGlobal() {
83  ASSERT(!is_lazy());
84  flags_ |= IsGlobal::encode(true);
85  }
87  ASSERT(this->language_mode() == CLASSIC_MODE ||
88  this->language_mode() == language_mode ||
89  language_mode == EXTENDED_MODE);
90  flags_ = LanguageModeField::update(flags_, language_mode);
91  }
92  void MarkAsInLoop() {
93  ASSERT(is_lazy());
94  flags_ |= IsInLoop::encode(true);
95  }
96  void MarkAsNative() {
97  flags_ |= IsNative::encode(true);
98  }
99  bool is_native() const {
100  return IsNative::decode(flags_);
101  }
102  void SetFunction(FunctionLiteral* literal) {
103  ASSERT(function_ == NULL);
104  function_ = literal;
105  }
107  ASSERT(scope_ == NULL);
108  scope_ = scope;
109  }
111  ASSERT(global_scope_ == NULL);
112  global_scope_ = global_scope;
113  }
114  void SetCode(Handle<Code> code) { code_ = code; }
116  ASSERT(!is_lazy());
117  extension_ = extension;
118  }
120  ASSERT(!is_lazy());
121  pre_parse_data_ = pre_parse_data;
122  }
124  context_ = context;
125  }
127  ASSERT(mode_ != OPTIMIZE);
128  ASSERT(current_code->kind() == Code::FUNCTION);
129  flags_ |= IsCompilingForDebugging::encode(true);
130  if (current_code->is_compiled_optimizable()) {
132  } else {
133  mode_ = CompilationInfo::NONOPT;
134  }
135  }
137  return IsCompilingForDebugging::decode(flags_);
138  }
139 
140  bool has_global_object() const {
141  return !closure().is_null() &&
142  (closure()->context()->global_object() != NULL);
143  }
144 
146  return has_global_object() ? closure()->context()->global_object() : NULL;
147  }
148 
149  // Accessors for the different compilation modes.
150  bool IsOptimizing() const { return mode_ == OPTIMIZE; }
151  bool IsOptimizable() const { return mode_ == BASE; }
153  SetMode(OPTIMIZE);
154  osr_ast_id_ = osr_ast_id;
155  }
156  void DisableOptimization();
157 
158  // Deoptimization support.
160  return SupportsDeoptimization::decode(flags_);
161  }
164  flags_ |= SupportsDeoptimization::encode(true);
165  }
166 
167  // Determines whether or not to insert a self-optimization header.
168  bool ShouldSelfOptimize();
169 
170  // Disable all optimization attempts of this info for the rest of the
171  // current compilation pipeline.
172  void AbortOptimization();
173 
174  void set_deferred_handles(DeferredHandles* deferred_handles) {
175  ASSERT(deferred_handles_ == NULL);
176  deferred_handles_ = deferred_handles;
177  }
178 
179  void SaveHandles() {
180  SaveHandle(&closure_);
181  SaveHandle(&shared_info_);
182  SaveHandle(&context_);
183  SaveHandle(&script_);
184  }
185 
186  const char* bailout_reason() const { return bailout_reason_; }
187  void set_bailout_reason(const char* reason) { bailout_reason_ = reason; }
188 
189  private:
190  Isolate* isolate_;
191 
192  // Compilation mode.
193  // BASE is generated by the full codegen, optionally prepared for bailouts.
194  // OPTIMIZE is optimized code generated by the Hydrogen-based backend.
195  // NONOPT is generated by the full codegen and is not prepared for
196  // recompilation/bailouts. These functions are never recompiled.
197  enum Mode {
198  BASE,
199  OPTIMIZE,
200  NONOPT
201  };
202 
203  void Initialize(Mode mode) {
204  mode_ = V8::UseCrankshaft() ? mode : NONOPT;
205  ASSERT(!script_.is_null());
206  if (script_->type()->value() == Script::TYPE_NATIVE) {
207  MarkAsNative();
208  }
209  if (!shared_info_.is_null()) {
211  SetLanguageMode(shared_info_->language_mode());
212  }
213  set_bailout_reason("unknown");
214  }
215 
216  void SetMode(Mode mode) {
218  mode_ = mode;
219  }
220 
221  // Flags using template class BitField<type, start, length>. All are
222  // false by default.
223  //
224  // Compilation is either eager or lazy.
225  class IsLazy: public BitField<bool, 0, 1> {};
226  // Flags that can be set for eager compilation.
227  class IsEval: public BitField<bool, 1, 1> {};
228  class IsGlobal: public BitField<bool, 2, 1> {};
229  // Flags that can be set for lazy compilation.
230  class IsInLoop: public BitField<bool, 3, 1> {};
231  // Strict mode - used in eager compilation.
232  class LanguageModeField: public BitField<LanguageMode, 4, 2> {};
233  // Is this a function from our natives.
234  class IsNative: public BitField<bool, 6, 1> {};
235  // Is this code being compiled with support for deoptimization..
236  class SupportsDeoptimization: public BitField<bool, 7, 1> {};
237  // If compiling for debugging produce just full code matching the
238  // initial mode setting.
239  class IsCompilingForDebugging: public BitField<bool, 8, 1> {};
240 
241 
242  unsigned flags_;
243 
244  // Fields filled in by the compilation pipeline.
245  // AST filled in by the parser.
246  FunctionLiteral* function_;
247  // The scope of the function literal as a convenience. Set to indicate
248  // that scopes have been analyzed.
249  Scope* scope_;
250  // The global scope provided as a convenience.
251  Scope* global_scope_;
252  // The compiled code.
253  Handle<Code> code_;
254 
255  // Possible initial inputs to the compilation process.
256  Handle<JSFunction> closure_;
257  Handle<SharedFunctionInfo> shared_info_;
258  Handle<Script> script_;
259 
260  // Fields possibly needed for eager compilation, NULL by default.
261  v8::Extension* extension_;
262  ScriptDataImpl* pre_parse_data_;
263 
264  // The context of the caller for eval code, and the global context for a
265  // global script. Will be a null handle otherwise.
266  Handle<Context> context_;
267 
268  // Compilation mode flag and whether deoptimization is allowed.
269  Mode mode_;
270  BailoutId osr_ast_id_;
271 
272  // The zone from which the compilation pipeline working on this
273  // CompilationInfo allocates.
274  Zone* zone_;
275 
276  DeferredHandles* deferred_handles_;
277 
278  template<typename T>
279  void SaveHandle(Handle<T> *object) {
280  if (!object->is_null()) {
281  Handle<T> handle(*(*object));
282  *object = handle;
283  }
284  }
285 
286  const char* bailout_reason_;
287 
288  DISALLOW_COPY_AND_ASSIGN(CompilationInfo);
289 };
290 
291 
292 // Exactly like a CompilationInfo, except also creates and enters a
293 // Zone on construction and deallocates it on exit.
295  public:
297  : CompilationInfo(script, &zone_),
298  zone_(script->GetIsolate()),
299  zone_scope_(&zone_, DELETE_ON_EXIT) {}
301  : CompilationInfo(shared_info, &zone_),
302  zone_(shared_info->GetIsolate()),
303  zone_scope_(&zone_, DELETE_ON_EXIT) {}
305  : CompilationInfo(closure, &zone_),
306  zone_(closure->GetIsolate()),
307  zone_scope_(&zone_, DELETE_ON_EXIT) {}
308 
309  private:
310  Zone zone_;
311  ZoneScope zone_scope_;
312 };
313 
314 
315 // A wrapper around a CompilationInfo that detaches the Handles from
316 // the underlying DeferredHandleScope and stores them in info_ on
317 // destruction.
318 class CompilationHandleScope BASE_EMBEDDED {
319  public:
321  : deferred_(info->isolate()), info_(info) {}
323  info_->set_deferred_handles(deferred_.Detach());
324  }
325 
326  private:
327  DeferredHandleScope deferred_;
328  CompilationInfo* info_;
329 };
330 
331 
332 class HGraph;
333 class HGraphBuilder;
334 class LChunk;
335 
336 // A helper class that calls the three compilation phases in
337 // Crankshaft and keeps track of its state. The three phases
338 // CreateGraph, OptimizeGraph and GenerateAndInstallCode can either
339 // fail, bail-out to the full code generator or succeed. Apart from
340 // their return value, the status of the phase last run can be checked
341 // using last_status().
343  public:
345  : info_(info),
346  oracle_(NULL),
347  graph_builder_(NULL),
348  graph_(NULL),
349  chunk_(NULL),
350  time_taken_to_create_graph_(0),
351  time_taken_to_optimize_(0),
352  time_taken_to_codegen_(0),
353  last_status_(FAILED) { }
354 
355  enum Status {
357  };
358 
362 
363  Status last_status() const { return last_status_; }
364  CompilationInfo* info() const { return info_; }
365 
367  info_->AbortOptimization();
368  info_->shared_info()->DisableOptimization(info_->bailout_reason());
369  return SetLastStatus(BAILED_OUT);
370  }
371 
372  private:
373  CompilationInfo* info_;
374  TypeFeedbackOracle* oracle_;
375  HGraphBuilder* graph_builder_;
376  HGraph* graph_;
377  LChunk* chunk_;
378  int64_t time_taken_to_create_graph_;
379  int64_t time_taken_to_optimize_;
380  int64_t time_taken_to_codegen_;
381  Status last_status_;
382 
383  MUST_USE_RESULT Status SetLastStatus(Status status) {
384  last_status_ = status;
385  return last_status_;
386  }
387  void RecordOptimizationStats();
388 
389  struct Timer {
390  Timer(OptimizingCompiler* compiler, int64_t* location)
391  : compiler_(compiler),
392  start_(OS::Ticks()),
393  location_(location) { }
394 
395  ~Timer() {
396  *location_ += (OS::Ticks() - start_);
397  }
398 
399  OptimizingCompiler* compiler_;
400  int64_t start_;
401  int64_t* location_;
402  };
403 };
404 
405 
406 // The V8 compiler
407 //
408 // General strategy: Source code is translated into an anonymous function w/o
409 // parameters which then can be executed. If the source code contains other
410 // functions, they will be compiled and allocated as part of the compilation
411 // of the source code.
412 
413 // Please note this interface returns shared function infos. This means you
414 // need to call Factory::NewFunctionFromSharedFunctionInfo before you have a
415 // real function with a context.
416 
417 class Compiler : public AllStatic {
418  public:
419  static const int kMaxInliningLevels = 3;
420 
421  // Call count before primitive functions trigger their own optimization.
422  static const int kCallsUntilPrimitiveOpt = 200;
423 
424  // All routines return a SharedFunctionInfo.
425  // If an error occurs an exception is raised and the return handle
426  // contains NULL.
427 
428  // Compile a String source within a context.
430  Handle<Object> script_name,
431  int line_offset,
432  int column_offset,
433  Handle<Context> context,
434  v8::Extension* extension,
435  ScriptDataImpl* pre_data,
436  Handle<Object> script_data,
437  NativesFlag is_natives_code);
438 
439  // Compile a String source within a context for Eval.
441  Handle<Context> context,
442  bool is_global,
443  LanguageMode language_mode,
444  int scope_position);
445 
446  // Compile from function info (used for lazy compilation). Returns true on
447  // success and false if the compilation resulted in a stack overflow.
448  static bool CompileLazy(CompilationInfo* info);
449 
450  static void RecompileParallel(Handle<JSFunction> function);
451 
452  // Compile a shared function info object (the function is possibly lazily
453  // compiled).
455  Handle<Script> script);
456 
457  // Set the function info for a newly compiled function.
458  static void SetFunctionInfo(Handle<SharedFunctionInfo> function_info,
459  FunctionLiteral* lit,
460  bool is_toplevel,
461  Handle<Script> script);
462 
463  static void InstallOptimizedCode(OptimizingCompiler* info);
464 
465 #ifdef ENABLE_DEBUGGER_SUPPORT
466  static bool MakeCodeForLiveEdit(CompilationInfo* info);
467 #endif
468 
470  CompilationInfo* info,
472 };
473 
474 
475 } } // namespace v8::internal
476 
477 #endif // V8_COMPILER_H_
CompilationInfoWithZone(Handle< SharedFunctionInfo > shared_info)
Definition: compiler.h:300
const char * bailout_reason() const
Definition: compiler.h:186
void MarkCompilingForDebugging(Handle< Code > current_code)
Definition: compiler.h:126
MUST_USE_RESULT Status CreateGraph()
Definition: compiler.cc:219
LanguageMode language_mode() const
Definition: compiler.h:62
bool HasDeoptimizationSupport() const
Definition: compiler.h:159
static bool UseCrankshaft()
Definition: v8.h:86
void SetScope(Scope *scope)
Definition: compiler.h:106
void SetCode(Handle< Code > code)
Definition: compiler.h:114
static int64_t Ticks()
ScriptDataImpl * pre_parse_data() const
Definition: compiler.h:74
CompilationInfo * info() const
Definition: compiler.h:364
CompilationInfoWithZone(Handle< JSFunction > closure)
Definition: compiler.h:304
Handle< Script > script() const
Definition: compiler.h:72
kPropertyAccessorsOffset kNamedPropertyHandlerOffset kInstanceTemplateOffset kAccessCheckInfoOffset kEvalFrominstructionsOffsetOffset kInstanceClassNameOffset kHiddenPrototypeBit kReadOnlyPrototypeBit is_toplevel
Definition: objects-inl.h:3932
void SetPreParseData(ScriptDataImpl *pre_parse_data)
Definition: compiler.h:119
#define ASSERT(condition)
Definition: checks.h:270
void SetExtension(v8::Extension *extension)
Definition: compiler.h:115
void SetLanguageMode(LanguageMode language_mode)
Definition: compiler.h:86
bool IsOptimizing() const
Definition: compiler.h:150
bool IsOptimizable() const
Definition: compiler.h:151
static Handle< SharedFunctionInfo > CompileEval(Handle< String > source, Handle< Context > context, bool is_global, LanguageMode language_mode, int scope_position)
Definition: compiler.cc:619
static void RecompileParallel(Handle< JSFunction > function)
Definition: compiler.cc:839
MUST_USE_RESULT Status AbortOptimization()
Definition: compiler.h:366
CompilationInfoWithZone(Handle< Script > script)
Definition: compiler.h:296
static void InstallOptimizedCode(OptimizingCompiler *info)
Definition: compiler.cc:895
void SetOptimizing(BailoutId osr_ast_id)
Definition: compiler.h:152
v8::Extension * extension() const
Definition: compiler.h:73
BailoutId osr_ast_id() const
Definition: compiler.h:76
CompilationInfo(Handle< Script > script, Zone *zone)
Definition: compiler.cc:54
#define MUST_USE_RESULT
Definition: globals.h:346
CompilationHandleScope(CompilationInfo *info)
Definition: compiler.h:320
Handle< Code > code() const
Definition: compiler.h:69
MUST_USE_RESULT Status GenerateAndInstallCode()
Definition: compiler.cc:372
Scope * global_scope() const
Definition: compiler.h:68
static void SetFunctionInfo(Handle< SharedFunctionInfo > function_info, FunctionLiteral *lit, bool is_toplevel, Handle< Script > script)
Definition: compiler.cc:986
#define BASE_EMBEDDED
Definition: allocation.h:68
Handle< JSFunction > closure() const
Definition: compiler.h:70
bool is_classic_mode() const
Definition: compiler.h:60
void SetContext(Handle< Context > context)
Definition: compiler.h:123
static Handle< SharedFunctionInfo > Compile(Handle< String > source, Handle< Object > script_name, int line_offset, int column_offset, Handle< Context > context, v8::Extension *extension, ScriptDataImpl *pre_data, Handle< Object > script_data, NativesFlag is_natives_code)
Definition: compiler.cc:542
Handle< Context > context() const
Definition: compiler.h:75
void set_bailout_reason(const char *reason)
Definition: compiler.h:187
bool is_extended_mode() const
Definition: compiler.h:61
Handle< SharedFunctionInfo > shared_info() const
Definition: compiler.h:71
OptimizingCompiler(CompilationInfo *info)
Definition: compiler.h:344
static Handle< SharedFunctionInfo > BuildFunctionInfo(FunctionLiteral *node, Handle< Script > script)
Definition: compiler.cc:926
static bool CompileLazy(CompilationInfo *info)
Definition: compiler.cc:786
activate correct semantics for inheriting readonliness enable harmony semantics for typeof enable harmony enable harmony proxies enable all harmony harmony_scoping harmony_proxies harmony_scoping tracks arrays with only smi values automatically unbox arrays of doubles use crankshaft use hydrogen range analysis use hydrogen global value numbering use function inlining maximum number of AST nodes considered for a single inlining loop invariant code motion print statistics for hydrogen trace generated IR for specified phases trace register allocator trace range analysis trace representation types environment for every instruction put a break point before deoptimizing polymorphic inlining perform array bounds checks elimination use dead code elimination trace on stack replacement optimize closures cache optimized code for closures functions with arguments object loop weight for representation inference allow uint32 values on optimize frames if they are used only in safe operations track parallel recompilation enable all profiler experiments number of stack frames inspected by the profiler call recompile stub directly when self optimizing trigger profiler ticks based on counting instead of timing weight back edges by jump distance for interrupt triggering percentage of ICs that must have type info to allow optimization watch_ic_patching retry_self_opt interrupt_at_exit extra verbose compilation tracing generate extra emit comments in code disassembly enable use of SSE3 instructions if available enable use of CMOV instruction if available enable use of SAHF instruction if enable use of VFP3 instructions if available this implies enabling ARMv7 and VFP2 enable use of VFP2 instructions if available enable use of SDIV and UDIV instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of MIPS FPU instructions if NULL
Definition: flags.cc:301
GlobalObject * global_object() const
Definition: compiler.h:145
static const int kMaxInliningLevels
Definition: compiler.h:419
bool has_global_object() const
Definition: compiler.h:140
bool is_in_loop() const
Definition: compiler.h:65
MUST_USE_RESULT Status OptimizeGraph()
Definition: compiler.cc:351
static void RecordFunctionCompilation(Logger::LogEventsAndTags tag, CompilationInfo *info, Handle< SharedFunctionInfo > shared)
Definition: compiler.cc:1017
void SetGlobalScope(Scope *global_scope)
Definition: compiler.h:110
void SetFunction(FunctionLiteral *literal)
Definition: compiler.h:102
static const int kCallsUntilPrimitiveOpt
Definition: compiler.h:422
void set_deferred_handles(DeferredHandles *deferred_handles)
Definition: compiler.h:174
Scope * scope() const
Definition: compiler.h:67