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.cc
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 #include "v8.h"
29 
30 #include "compiler.h"
31 
32 #include "bootstrapper.h"
33 #include "codegen.h"
34 #include "compilation-cache.h"
35 #include "debug.h"
36 #include "full-codegen.h"
37 #include "gdb-jit.h"
38 #include "hydrogen.h"
39 #include "isolate-inl.h"
40 #include "lithium.h"
41 #include "liveedit.h"
42 #include "parser.h"
43 #include "rewriter.h"
44 #include "runtime-profiler.h"
46 #include "scopeinfo.h"
47 #include "scopes.h"
48 #include "vm-state-inl.h"
49 
50 namespace v8 {
51 namespace internal {
52 
53 
55  : isolate_(script->GetIsolate()),
56  flags_(LanguageModeField::encode(CLASSIC_MODE)),
57  function_(NULL),
58  scope_(NULL),
59  global_scope_(NULL),
60  script_(script),
61  extension_(NULL),
62  pre_parse_data_(NULL),
63  osr_ast_id_(BailoutId::None()),
64  zone_(zone),
65  deferred_handles_(NULL) {
66  Initialize(BASE);
67 }
68 
69 
71  Zone* zone)
72  : isolate_(shared_info->GetIsolate()),
73  flags_(LanguageModeField::encode(CLASSIC_MODE) |
74  IsLazy::encode(true)),
75  function_(NULL),
76  scope_(NULL),
77  global_scope_(NULL),
78  shared_info_(shared_info),
79  script_(Handle<Script>(Script::cast(shared_info->script()))),
80  extension_(NULL),
81  pre_parse_data_(NULL),
82  osr_ast_id_(BailoutId::None()),
83  zone_(zone),
84  deferred_handles_(NULL) {
85  Initialize(BASE);
86 }
87 
88 
90  : isolate_(closure->GetIsolate()),
91  flags_(LanguageModeField::encode(CLASSIC_MODE) |
92  IsLazy::encode(true)),
93  function_(NULL),
94  scope_(NULL),
95  global_scope_(NULL),
96  closure_(closure),
97  shared_info_(Handle<SharedFunctionInfo>(closure->shared())),
98  script_(Handle<Script>(Script::cast(shared_info_->script()))),
99  extension_(NULL),
100  pre_parse_data_(NULL),
101  context_(closure->context()),
102  osr_ast_id_(BailoutId::None()),
103  zone_(zone),
104  deferred_handles_(NULL) {
105  Initialize(BASE);
106 }
107 
108 
110  delete deferred_handles_;
111 }
112 
113 
114 // Disable optimization for the rest of the compilation pipeline.
116  bool is_optimizable_closure =
117  FLAG_optimize_closures &&
118  closure_.is_null() &&
119  !scope_->HasTrivialOuterContext() &&
121  !scope_->inside_with();
122  SetMode(is_optimizable_closure ? BASE : NONOPT);
123 }
124 
125 
126 // Primitive functions are unlikely to be picked up by the stack-walking
127 // profiler, so they trigger their own optimization when they're called
128 // for the SharedFunctionInfo::kCallsUntilPrimitiveOptimization-th time.
130  return FLAG_self_optimization &&
131  FLAG_crankshaft &&
132  !function()->flags()->Contains(kDontSelfOptimize) &&
133  !function()->flags()->Contains(kDontOptimize) &&
134  function()->scope()->AllowsLazyCompilation() &&
135  (shared_info().is_null() || !shared_info()->optimization_disabled());
136 }
137 
138 
141  SetCode(code);
142 }
143 
144 
145 // Determine whether to use the full compiler for all code. If the flag
146 // --always-full-compiler is specified this is the case. For the virtual frame
147 // based compiler the full compiler is also used if a debugger is connected, as
148 // the code from the full compiler supports mode precise break points. For the
149 // crankshaft adaptive compiler debugging the optimized code is not possible at
150 // all. However crankshaft support recompilation of functions, so in this case
151 // the full compiler need not be be used if a debugger is attached, but only if
152 // break points has actually been set.
153 static bool IsDebuggerActive(Isolate* isolate) {
154 #ifdef ENABLE_DEBUGGER_SUPPORT
155  return V8::UseCrankshaft() ?
156  isolate->debug()->has_break_points() :
157  isolate->debugger()->IsDebuggerActive();
158 #else
159  return false;
160 #endif
161 }
162 
163 
164 static bool AlwaysFullCompiler(Isolate* isolate) {
165  return FLAG_always_full_compiler || IsDebuggerActive(isolate);
166 }
167 
168 
169 void OptimizingCompiler::RecordOptimizationStats() {
170  Handle<JSFunction> function = info()->closure();
171  int opt_count = function->shared()->opt_count();
172  function->shared()->set_opt_count(opt_count + 1);
173  double ms_creategraph =
174  static_cast<double>(time_taken_to_create_graph_) / 1000;
175  double ms_optimize = static_cast<double>(time_taken_to_optimize_) / 1000;
176  double ms_codegen = static_cast<double>(time_taken_to_codegen_) / 1000;
177  if (FLAG_trace_opt) {
178  PrintF("[optimizing: ");
179  function->PrintName();
180  PrintF(" / %" V8PRIxPTR, reinterpret_cast<intptr_t>(*function));
181  PrintF(" - took %0.3f, %0.3f, %0.3f ms]\n", ms_creategraph, ms_optimize,
182  ms_codegen);
183  }
184  if (FLAG_trace_opt_stats) {
185  static double compilation_time = 0.0;
186  static int compiled_functions = 0;
187  static int code_size = 0;
188 
189  compilation_time += (ms_creategraph + ms_optimize + ms_codegen);
190  compiled_functions++;
191  code_size += function->shared()->SourceSize();
192  PrintF("Compiled: %d functions with %d byte source size in %fms.\n",
193  compiled_functions,
194  code_size,
195  compilation_time);
196  }
197 }
198 
199 
200 // A return value of true indicates the compilation pipeline is still
201 // going, not necessarily that we optimized the code.
202 static bool MakeCrankshaftCode(CompilationInfo* info) {
203  OptimizingCompiler compiler(info);
204  OptimizingCompiler::Status status = compiler.CreateGraph();
205 
206  if (status != OptimizingCompiler::SUCCEEDED) {
207  return status != OptimizingCompiler::FAILED;
208  }
209  status = compiler.OptimizeGraph();
210  if (status != OptimizingCompiler::SUCCEEDED) {
211  status = compiler.AbortOptimization();
212  return status != OptimizingCompiler::FAILED;
213  }
214  status = compiler.GenerateAndInstallCode();
215  return status != OptimizingCompiler::FAILED;
216 }
217 
218 
221  ASSERT(info()->IsOptimizing());
222  ASSERT(!info()->IsCompilingForDebugging());
223 
224  // We should never arrive here if there is no code object on the
225  // shared function object.
226  Handle<Code> code(info()->shared_info()->code());
227  ASSERT(code->kind() == Code::FUNCTION);
228 
229  // We should never arrive here if optimization has been disabled on the
230  // shared function info.
231  ASSERT(!info()->shared_info()->optimization_disabled());
232 
233  // Fall back to using the full code generator if it's not possible
234  // to use the Hydrogen-based optimizing compiler. We already have
235  // generated code for this from the shared function object.
236  if (AlwaysFullCompiler(info()->isolate())) {
237  info()->SetCode(code);
238  return SetLastStatus(BAILED_OUT);
239  }
240 
241  // Limit the number of times we re-compile a functions with
242  // the optimizing compiler.
243  const int kMaxOptCount =
244  FLAG_deopt_every_n_times == 0 ? FLAG_max_opt_count : 1000;
245  if (info()->shared_info()->opt_count() > kMaxOptCount) {
246  info()->set_bailout_reason("optimized too many times");
247  return AbortOptimization();
248  }
249 
250  // Due to an encoding limit on LUnallocated operands in the Lithium
251  // language, we cannot optimize functions with too many formal parameters
252  // or perform on-stack replacement for function with too many
253  // stack-allocated local variables.
254  //
255  // The encoding is as a signed value, with parameters and receiver using
256  // the negative indices and locals the non-negative ones.
257  const int parameter_limit = -LUnallocated::kMinFixedIndex;
258  Scope* scope = info()->scope();
259  if ((scope->num_parameters() + 1) > parameter_limit) {
260  info()->set_bailout_reason("too many parameters");
261  return AbortOptimization();
262  }
263 
264  const int locals_limit = LUnallocated::kMaxFixedIndex;
265  if (!info()->osr_ast_id().IsNone() &&
266  scope->num_parameters() + 1 + scope->num_stack_slots() > locals_limit) {
267  info()->set_bailout_reason("too many parameters/locals");
268  return AbortOptimization();
269  }
270 
271  // Take --hydrogen-filter into account.
272  Handle<String> name = info()->function()->debug_name();
273  if (*FLAG_hydrogen_filter != '\0') {
274  Vector<const char> filter = CStrVector(FLAG_hydrogen_filter);
275  if ((filter[0] == '-'
276  && name->IsEqualTo(filter.SubVector(1, filter.length())))
277  || (filter[0] != '-' && !name->IsEqualTo(filter))) {
278  info()->SetCode(code);
279  return SetLastStatus(BAILED_OUT);
280  }
281  }
282 
283  // Recompile the unoptimized version of the code if the current version
284  // doesn't have deoptimization support. Alternatively, we may decide to
285  // run the full code generator to get a baseline for the compile-time
286  // performance of the hydrogen-based compiler.
287  Timer t(this, &time_taken_to_create_graph_);
288  bool should_recompile = !info()->shared_info()->has_deoptimization_support();
289  if (should_recompile || FLAG_hydrogen_stats) {
290  HPhase phase(HPhase::kFullCodeGen);
291  CompilationInfoWithZone unoptimized(info()->shared_info());
292  // Note that we use the same AST that we will use for generating the
293  // optimized code.
294  unoptimized.SetFunction(info()->function());
295  unoptimized.SetScope(info()->scope());
296  unoptimized.SetContext(info()->context());
297  if (should_recompile) unoptimized.EnableDeoptimizationSupport();
298  bool succeeded = FullCodeGenerator::MakeCode(&unoptimized);
299  if (should_recompile) {
300  if (!succeeded) return SetLastStatus(FAILED);
302  shared->EnableDeoptimizationSupport(*unoptimized.code());
303  // The existing unoptimized code was replaced with the new one.
305  Logger::LAZY_COMPILE_TAG, &unoptimized, shared);
306  }
307  }
308 
309  // Check that the unoptimized, shared code is ready for
310  // optimizations. When using the always_opt flag we disregard the
311  // optimizable marker in the code object and optimize anyway. This
312  // is safe as long as the unoptimized code has deoptimization
313  // support.
314  ASSERT(FLAG_always_opt || code->optimizable());
315  ASSERT(info()->shared_info()->has_deoptimization_support());
316 
317  if (FLAG_trace_hydrogen) {
318  PrintF("-----------------------------------------------------------\n");
319  PrintF("Compiling method %s using hydrogen\n", *name->ToCString());
320  HTracer::Instance()->TraceCompilation(info()->function());
321  }
322  Handle<Context> native_context(
323  info()->closure()->context()->native_context());
324  oracle_ = new(info()->zone()) TypeFeedbackOracle(
325  code, native_context, info()->isolate(), info()->zone());
326  graph_builder_ = new(info()->zone()) HGraphBuilder(info(), oracle_);
327  HPhase phase(HPhase::kTotal);
328  graph_ = graph_builder_->CreateGraph();
329 
330  if (info()->isolate()->has_pending_exception()) {
332  return SetLastStatus(FAILED);
333  }
334 
335  // The function being compiled may have bailed out due to an inline
336  // candidate bailing out. In such a case, we don't disable
337  // optimization on the shared_info.
338  ASSERT(!graph_builder_->inline_bailout() || graph_ == NULL);
339  if (graph_ == NULL) {
340  if (graph_builder_->inline_bailout()) {
341  info_->AbortOptimization();
342  return SetLastStatus(BAILED_OUT);
343  } else {
344  return AbortOptimization();
345  }
346  }
347 
348  return SetLastStatus(SUCCEEDED);
349 }
350 
352  AssertNoAllocation no_gc;
353  NoHandleAllocation no_handles;
354 
356  Timer t(this, &time_taken_to_optimize_);
357  ASSERT(graph_ != NULL);
358  SmartArrayPointer<char> bailout_reason;
359  if (!graph_->Optimize(&bailout_reason)) {
360  if (!bailout_reason.is_empty()) graph_builder_->Bailout(*bailout_reason);
361  return SetLastStatus(BAILED_OUT);
362  } else {
363  chunk_ = LChunk::NewChunk(graph_);
364  if (chunk_ == NULL) {
365  return SetLastStatus(BAILED_OUT);
366  }
367  }
368  return SetLastStatus(SUCCEEDED);
369 }
370 
371 
374  Timer timer(this, &time_taken_to_codegen_);
375  ASSERT(chunk_ != NULL);
376  ASSERT(graph_ != NULL);
377  Handle<Code> optimized_code = chunk_->Codegen();
378  if (optimized_code.is_null()) {
379  info()->set_bailout_reason("code generation failed");
380  return AbortOptimization();
381  }
382  info()->SetCode(optimized_code);
383  RecordOptimizationStats();
384  return SetLastStatus(SUCCEEDED);
385 }
386 
387 
388 static bool GenerateCode(CompilationInfo* info) {
389  bool is_optimizing = V8::UseCrankshaft() &&
390  !info->IsCompilingForDebugging() &&
391  info->IsOptimizing();
392  if (is_optimizing) {
393  return MakeCrankshaftCode(info);
394  } else {
395  if (info->IsOptimizing()) {
396  // Have the CompilationInfo decide if the compilation should be
397  // BASE or NONOPT.
398  info->DisableOptimization();
399  }
400  return FullCodeGenerator::MakeCode(info);
401  }
402 }
403 
404 
405 static bool MakeCode(CompilationInfo* info) {
406  // Precondition: code has been parsed. Postcondition: the code field in
407  // the compilation info is set if compilation succeeded.
408  ASSERT(info->function() != NULL);
409  return Rewriter::Rewrite(info) && Scope::Analyze(info) && GenerateCode(info);
410 }
411 
412 
413 #ifdef ENABLE_DEBUGGER_SUPPORT
414 bool Compiler::MakeCodeForLiveEdit(CompilationInfo* info) {
415  // Precondition: code has been parsed. Postcondition: the code field in
416  // the compilation info is set if compilation succeeded.
417  bool succeeded = MakeCode(info);
418  if (!info->shared_info().is_null()) {
419  Handle<ScopeInfo> scope_info = ScopeInfo::Create(info->scope(),
420  info->zone());
421  info->shared_info()->set_scope_info(*scope_info);
422  }
423  return succeeded;
424 }
425 #endif
426 
427 
428 static Handle<SharedFunctionInfo> MakeFunctionInfo(CompilationInfo* info) {
429  Isolate* isolate = info->isolate();
430  ZoneScope zone_scope(info->zone(), DELETE_ON_EXIT);
431  PostponeInterruptsScope postpone(isolate);
432 
433  ASSERT(!isolate->native_context().is_null());
434  Handle<Script> script = info->script();
435  script->set_context_data((*isolate->native_context())->data());
436 
437 #ifdef ENABLE_DEBUGGER_SUPPORT
438  if (info->is_eval()) {
440  script->set_compilation_type(Smi::FromInt(compilation_type));
441  // For eval scripts add information on the function from which eval was
442  // called.
443  if (info->is_eval()) {
444  StackTraceFrameIterator it(isolate);
445  if (!it.done()) {
446  script->set_eval_from_shared(
447  JSFunction::cast(it.frame()->function())->shared());
448  Code* code = it.frame()->LookupCode();
449  int offset = static_cast<int>(
450  it.frame()->pc() - code->instruction_start());
451  script->set_eval_from_instructions_offset(Smi::FromInt(offset));
452  }
453  }
454  }
455 
456  // Notify debugger
457  isolate->debugger()->OnBeforeCompile(script);
458 #endif
459 
460  // Only allow non-global compiles for eval.
461  ASSERT(info->is_eval() || info->is_global());
463  if (info->pre_parse_data() != NULL ||
464  String::cast(script->source())->length() > FLAG_min_preparse_length) {
465  flags = kAllowLazy;
466  }
467  if (!ParserApi::Parse(info, flags)) {
469  }
470 
471  // Measure how long it takes to do the compilation; only take the
472  // rest of the function into account to avoid overlap with the
473  // parsing statistics.
474  HistogramTimer* rate = info->is_eval()
475  ? info->isolate()->counters()->compile_eval()
476  : info->isolate()->counters()->compile();
477  HistogramTimerScope timer(rate);
478 
479  // Compile the code.
480  FunctionLiteral* lit = info->function();
481  LiveEditFunctionTracker live_edit_tracker(isolate, lit);
482  if (!MakeCode(info)) {
483  if (!isolate->has_pending_exception()) isolate->StackOverflow();
485  }
486 
487  // Allocate function.
488  ASSERT(!info->code().is_null());
489  Handle<SharedFunctionInfo> result =
490  isolate->factory()->NewSharedFunctionInfo(
491  lit->name(),
492  lit->materialized_literal_count(),
493  info->code(),
494  ScopeInfo::Create(info->scope(), info->zone()));
495 
496  ASSERT_EQ(RelocInfo::kNoPosition, lit->function_token_position());
497  Compiler::SetFunctionInfo(result, lit, true, script);
498 
499  if (script->name()->IsString()) {
500  PROFILE(isolate, CodeCreateEvent(
501  info->is_eval()
502  ? Logger::EVAL_TAG
503  : Logger::ToNativeByScript(Logger::SCRIPT_TAG, *script),
504  *info->code(),
505  *result,
506  String::cast(script->name())));
507  GDBJIT(AddCode(Handle<String>(String::cast(script->name())),
508  script,
509  info->code(),
510  info));
511  } else {
512  PROFILE(isolate, CodeCreateEvent(
513  info->is_eval()
514  ? Logger::EVAL_TAG
515  : Logger::ToNativeByScript(Logger::SCRIPT_TAG, *script),
516  *info->code(),
517  *result,
518  isolate->heap()->empty_string()));
519  GDBJIT(AddCode(Handle<String>(), script, info->code(), info));
520  }
521 
522  // Hint to the runtime system used when allocating space for initial
523  // property space by setting the expected number of properties for
524  // the instances of the function.
525  SetExpectedNofPropertiesFromEstimate(result, lit->expected_property_count());
526 
527  script->set_compilation_state(
529 
530 #ifdef ENABLE_DEBUGGER_SUPPORT
531  // Notify debugger
532  isolate->debugger()->OnAfterCompile(
533  script, Debugger::NO_AFTER_COMPILE_FLAGS);
534 #endif
535 
536  live_edit_tracker.RecordFunctionInfo(result, lit, info->zone());
537 
538  return result;
539 }
540 
541 
543  Handle<Object> script_name,
544  int line_offset,
545  int column_offset,
546  Handle<Context> context,
547  v8::Extension* extension,
548  ScriptDataImpl* pre_data,
549  Handle<Object> script_data,
550  NativesFlag natives) {
551  Isolate* isolate = source->GetIsolate();
552  int source_length = source->length();
553  isolate->counters()->total_load_size()->Increment(source_length);
554  isolate->counters()->total_compile_size()->Increment(source_length);
555 
556  // The VM is in the COMPILER state until exiting this function.
557  VMState state(isolate, COMPILER);
558 
559  CompilationCache* compilation_cache = isolate->compilation_cache();
560 
561  // Do a lookup in the compilation cache but not for extensions.
563  if (extension == NULL) {
564  result = compilation_cache->LookupScript(source,
565  script_name,
566  line_offset,
567  column_offset,
568  context);
569  }
570 
571  if (result.is_null()) {
572  // No cache entry found. Do pre-parsing, if it makes sense, and compile
573  // the script.
574  // Building preparse data that is only used immediately after is only a
575  // saving if we might skip building the AST for lazily compiled functions.
576  // I.e., preparse data isn't relevant when the lazy flag is off, and
577  // for small sources, odds are that there aren't many functions
578  // that would be compiled lazily anyway, so we skip the preparse step
579  // in that case too.
580 
581  // Create a script object describing the script to be compiled.
582  Handle<Script> script = FACTORY->NewScript(source);
583  if (natives == NATIVES_CODE) {
584  script->set_type(Smi::FromInt(Script::TYPE_NATIVE));
585  }
586  if (!script_name.is_null()) {
587  script->set_name(*script_name);
588  script->set_line_offset(Smi::FromInt(line_offset));
589  script->set_column_offset(Smi::FromInt(column_offset));
590  }
591 
592  script->set_data(script_data.is_null() ? HEAP->undefined_value()
593  : *script_data);
594 
595  // Compile the function and add it to the cache.
596  CompilationInfoWithZone info(script);
597  info.MarkAsGlobal();
598  info.SetExtension(extension);
599  info.SetPreParseData(pre_data);
600  info.SetContext(context);
601  if (FLAG_use_strict) {
602  info.SetLanguageMode(FLAG_harmony_scoping ? EXTENDED_MODE : STRICT_MODE);
603  }
604  result = MakeFunctionInfo(&info);
605  if (extension == NULL && !result.is_null() && !result->dont_cache()) {
606  compilation_cache->PutScript(source, context, result);
607  }
608  } else {
609  if (result->ic_age() != HEAP->global_ic_age()) {
610  result->ResetForNewContext(HEAP->global_ic_age());
611  }
612  }
613 
614  if (result.is_null()) isolate->ReportPendingMessages();
615  return result;
616 }
617 
618 
620  Handle<Context> context,
621  bool is_global,
622  LanguageMode language_mode,
623  int scope_position) {
624  Isolate* isolate = source->GetIsolate();
625  int source_length = source->length();
626  isolate->counters()->total_eval_size()->Increment(source_length);
627  isolate->counters()->total_compile_size()->Increment(source_length);
628 
629  // The VM is in the COMPILER state until exiting this function.
630  VMState state(isolate, COMPILER);
631 
632  // Do a lookup in the compilation cache; if the entry is not there, invoke
633  // the compiler and add the result to the cache.
635  CompilationCache* compilation_cache = isolate->compilation_cache();
636  result = compilation_cache->LookupEval(source,
637  context,
638  is_global,
639  language_mode,
640  scope_position);
641 
642  if (result.is_null()) {
643  // Create a script object describing the script to be compiled.
644  Handle<Script> script = isolate->factory()->NewScript(source);
645  CompilationInfoWithZone info(script);
646  info.MarkAsEval();
647  if (is_global) info.MarkAsGlobal();
648  info.SetLanguageMode(language_mode);
649  info.SetContext(context);
650  result = MakeFunctionInfo(&info);
651  if (!result.is_null()) {
652  // Explicitly disable optimization for eval code. We're not yet prepared
653  // to handle eval-code in the optimizing compiler.
654  result->DisableOptimization("eval");
655 
656  // If caller is strict mode, the result must be in strict mode or
657  // extended mode as well, but not the other way around. Consider:
658  // eval("'use strict'; ...");
659  ASSERT(language_mode != STRICT_MODE || !result->is_classic_mode());
660  // If caller is in extended mode, the result must also be in
661  // extended mode.
662  ASSERT(language_mode != EXTENDED_MODE ||
663  result->is_extended_mode());
664  if (!result->dont_cache()) {
665  compilation_cache->PutEval(
666  source, context, is_global, result, scope_position);
667  }
668  }
669  } else {
670  if (result->ic_age() != HEAP->global_ic_age()) {
671  result->ResetForNewContext(HEAP->global_ic_age());
672  }
673  }
674 
675  return result;
676 }
677 
678 
679 static bool InstallFullCode(CompilationInfo* info) {
680  // Update the shared function info with the compiled code and the
681  // scope info. Please note, that the order of the shared function
682  // info initialization is important since set_scope_info might
683  // trigger a GC, causing the ASSERT below to be invalid if the code
684  // was flushed. By setting the code object last we avoid this.
685  Handle<SharedFunctionInfo> shared = info->shared_info();
686  Handle<Code> code = info->code();
687  Handle<JSFunction> function = info->closure();
688  Handle<ScopeInfo> scope_info =
689  ScopeInfo::Create(info->scope(), info->zone());
690  shared->set_scope_info(*scope_info);
691  shared->set_code(*code);
692  if (!function.is_null()) {
693  function->ReplaceCode(*code);
694  ASSERT(!function->IsOptimized());
695  }
696 
697  // Set the expected number of properties for instances.
698  FunctionLiteral* lit = info->function();
699  int expected = lit->expected_property_count();
700  SetExpectedNofPropertiesFromEstimate(shared, expected);
701 
702  // Set the optimization hints after performing lazy compilation, as
703  // these are not set when the function is set up as a lazily
704  // compiled function.
705  shared->SetThisPropertyAssignmentsInfo(
706  lit->has_only_simple_this_property_assignments(),
707  *lit->this_property_assignments());
708 
709  // Check the function has compiled code.
710  ASSERT(shared->is_compiled());
711  shared->set_code_age(0);
712  shared->set_dont_optimize(lit->flags()->Contains(kDontOptimize));
713  shared->set_dont_inline(lit->flags()->Contains(kDontInline));
714  shared->set_ast_node_count(lit->ast_node_count());
715 
716  if (V8::UseCrankshaft() &&
717  !function.is_null() &&
718  !shared->optimization_disabled()) {
719  // If we're asked to always optimize, we compile the optimized
720  // version of the function right away - unless the debugger is
721  // active as it makes no sense to compile optimized code then.
722  if (FLAG_always_opt &&
723  !Isolate::Current()->DebuggerHasBreakPoints()) {
724  CompilationInfoWithZone optimized(function);
725  optimized.SetOptimizing(BailoutId::None());
726  return Compiler::CompileLazy(&optimized);
727  }
728  }
729  return true;
730 }
731 
732 
733 static void InstallCodeCommon(CompilationInfo* info) {
734  Handle<SharedFunctionInfo> shared = info->shared_info();
735  Handle<Code> code = info->code();
736  ASSERT(!code.is_null());
737 
738  // Set optimizable to false if this is disallowed by the shared
739  // function info, e.g., we might have flushed the code and must
740  // reset this bit when lazy compiling the code again.
741  if (shared->optimization_disabled()) code->set_optimizable(false);
742 
743  Compiler::RecordFunctionCompilation(Logger::LAZY_COMPILE_TAG, info, shared);
744 }
745 
746 
747 static void InsertCodeIntoOptimizedCodeMap(CompilationInfo* info) {
748  Handle<Code> code = info->code();
749  if (FLAG_cache_optimized_code &&
750  info->osr_ast_id().IsNone() &&
751  code->kind() == Code::OPTIMIZED_FUNCTION) {
752  Handle<JSFunction> function = info->closure();
753  Handle<SharedFunctionInfo> shared(function->shared());
754  Handle<FixedArray> literals(function->literals());
755  Handle<Context> native_context(function->context()->native_context());
757  shared, native_context, code, literals);
758  }
759 }
760 
761 
762 static bool InstallCodeFromOptimizedCodeMap(CompilationInfo* info) {
763  if (FLAG_cache_optimized_code &&
764  info->osr_ast_id().IsNone() &&
765  info->IsOptimizing()) {
766  Handle<SharedFunctionInfo> shared = info->shared_info();
767  Handle<JSFunction> function = info->closure();
768  ASSERT(!function.is_null());
769  Handle<Context> native_context(function->context()->native_context());
770  int index = shared->SearchOptimizedCodeMap(*native_context);
771  if (index > 0) {
772  if (FLAG_trace_opt) {
773  PrintF("[found optimized code for: ");
774  function->PrintName();
775  PrintF(" / %" V8PRIxPTR "]\n", reinterpret_cast<intptr_t>(*function));
776  }
777  // Caching of optimized code enabled and optimized code found.
778  shared->InstallFromOptimizedCodeMap(*function, index);
779  return true;
780  }
781  }
782  return false;
783 }
784 
785 
787  Isolate* isolate = info->isolate();
788 
789  ZoneScope zone_scope(info->zone(), DELETE_ON_EXIT);
790 
791  // The VM is in the COMPILER state until exiting this function.
792  VMState state(isolate, COMPILER);
793 
794  PostponeInterruptsScope postpone(isolate);
795 
796  Handle<SharedFunctionInfo> shared = info->shared_info();
797  int compiled_size = shared->end_position() - shared->start_position();
798  isolate->counters()->total_compile_size()->Increment(compiled_size);
799 
800  if (InstallCodeFromOptimizedCodeMap(info)) return true;
801 
802  // Generate the AST for the lazily compiled function.
803  if (ParserApi::Parse(info, kNoParsingFlags)) {
804  // Measure how long it takes to do the lazy compilation; only take the
805  // rest of the function into account to avoid overlap with the lazy
806  // parsing statistics.
807  HistogramTimerScope timer(isolate->counters()->compile_lazy());
808 
809  // After parsing we know the function's language mode. Remember it.
810  LanguageMode language_mode = info->function()->language_mode();
811  info->SetLanguageMode(language_mode);
812  shared->set_language_mode(language_mode);
813 
814  // Compile the code.
815  if (!MakeCode(info)) {
816  if (!isolate->has_pending_exception()) {
817  isolate->StackOverflow();
818  }
819  } else {
820  InstallCodeCommon(info);
821 
822  if (info->IsOptimizing()) {
823  Handle<Code> code = info->code();
824  ASSERT(shared->scope_info() != ScopeInfo::Empty());
825  info->closure()->ReplaceCode(*code);
826  InsertCodeIntoOptimizedCodeMap(info);
827  return true;
828  } else {
829  return InstallFullCode(info);
830  }
831  }
832  }
833 
834  ASSERT(info->code().is_null());
835  return false;
836 }
837 
838 
840  if (closure->IsInRecompileQueue()) return;
841  ASSERT(closure->IsMarkedForParallelRecompilation());
842 
843  Isolate* isolate = closure->GetIsolate();
844  if (!isolate->optimizing_compiler_thread()->IsQueueAvailable()) {
845  if (FLAG_trace_parallel_recompilation) {
846  PrintF(" ** Compilation queue, will retry opting on next run.\n");
847  }
848  return;
849  }
850 
852  VMState state(isolate, PARALLEL_COMPILER_PROLOGUE);
853  PostponeInterruptsScope postpone(isolate);
854 
855  Handle<SharedFunctionInfo> shared = info->shared_info();
856  int compiled_size = shared->end_position() - shared->start_position();
857  isolate->counters()->total_compile_size()->Increment(compiled_size);
858  info->SetOptimizing(BailoutId::None());
859 
860  {
861  CompilationHandleScope handle_scope(*info);
862 
863  if (InstallCodeFromOptimizedCodeMap(*info)) return;
864 
865  if (ParserApi::Parse(*info, kNoParsingFlags)) {
866  LanguageMode language_mode = info->function()->language_mode();
867  info->SetLanguageMode(language_mode);
868  shared->set_language_mode(language_mode);
869  info->SaveHandles();
870 
871  if (Rewriter::Rewrite(*info) && Scope::Analyze(*info)) {
872  OptimizingCompiler* compiler =
873  new(info->zone()) OptimizingCompiler(*info);
874  OptimizingCompiler::Status status = compiler->CreateGraph();
875  if (status == OptimizingCompiler::SUCCEEDED) {
876  isolate->optimizing_compiler_thread()->QueueForOptimization(compiler);
877  shared->code()->set_profiler_ticks(0);
878  closure->ReplaceCode(isolate->builtins()->builtin(
879  Builtins::kInRecompileQueue));
880  info.Detach();
881  } else if (status == OptimizingCompiler::BAILED_OUT) {
882  isolate->clear_pending_exception();
883  InstallFullCode(*info);
884  }
885  }
886  }
887  }
888 
889  if (isolate->has_pending_exception()) {
890  isolate->clear_pending_exception();
891  }
892 }
893 
894 
896  SmartPointer<CompilationInfo> info(optimizing_compiler->info());
897  // If crankshaft succeeded, install the optimized code else install
898  // the unoptimized code.
899  OptimizingCompiler::Status status = optimizing_compiler->last_status();
900  if (status != OptimizingCompiler::SUCCEEDED) {
901  optimizing_compiler->info()->set_bailout_reason(
902  "failed/bailed out last time");
903  status = optimizing_compiler->AbortOptimization();
904  } else {
905  status = optimizing_compiler->GenerateAndInstallCode();
908  }
909 
910  InstallCodeCommon(*info);
911  if (status == OptimizingCompiler::SUCCEEDED) {
912  Handle<Code> code = info->code();
913  ASSERT(info->shared_info()->scope_info() != ScopeInfo::Empty());
914  info->closure()->ReplaceCode(*code);
915  if (info->shared_info()->SearchOptimizedCodeMap(
916  info->closure()->context()->native_context()) == -1) {
917  InsertCodeIntoOptimizedCodeMap(*info);
918  }
919  } else {
920  info->SetCode(Handle<Code>(info->shared_info()->code()));
921  InstallFullCode(*info);
922  }
923 }
924 
925 
927  Handle<Script> script) {
928  // Precondition: code has been parsed and scopes have been analyzed.
929  CompilationInfoWithZone info(script);
930  info.SetFunction(literal);
931  info.SetScope(literal->scope());
932  info.SetLanguageMode(literal->scope()->language_mode());
933 
934  LiveEditFunctionTracker live_edit_tracker(info.isolate(), literal);
935  // Determine if the function can be lazily compiled. This is necessary to
936  // allow some of our builtin JS files to be lazily compiled. These
937  // builtins cannot be handled lazily by the parser, since we have to know
938  // if a function uses the special natives syntax, which is something the
939  // parser records.
940  // If the debugger requests compilation for break points, we cannot be
941  // aggressive about lazy compilation, because it might trigger compilation
942  // of functions without an outer context when setting a breakpoint through
943  // Debug::FindSharedFunctionInfoInScript.
944  bool allow_lazy_without_ctx = literal->AllowsLazyCompilationWithoutContext();
945  bool allow_lazy = literal->AllowsLazyCompilation() &&
947  (!info.isolate()->DebuggerHasBreakPoints() || allow_lazy_without_ctx);
948 
949  Handle<ScopeInfo> scope_info(ScopeInfo::Empty());
950 
951  // Generate code
952  if (FLAG_lazy && allow_lazy && !literal->is_parenthesized()) {
953  Handle<Code> code = info.isolate()->builtins()->LazyCompile();
954  info.SetCode(code);
955  } else if (GenerateCode(&info)) {
956  ASSERT(!info.code().is_null());
957  scope_info = ScopeInfo::Create(info.scope(), info.zone());
958  } else {
960  }
961 
962  // Create a shared function info object.
964  FACTORY->NewSharedFunctionInfo(literal->name(),
965  literal->materialized_literal_count(),
966  info.code(),
967  scope_info);
968  SetFunctionInfo(result, literal, false, script);
969  RecordFunctionCompilation(Logger::FUNCTION_TAG, &info, result);
970  result->set_allows_lazy_compilation(allow_lazy);
971  result->set_allows_lazy_compilation_without_context(allow_lazy_without_ctx);
972 
973  // Set the expected number of properties for instances and return
974  // the resulting function.
976  literal->expected_property_count());
977  live_edit_tracker.RecordFunctionInfo(result, literal, info.zone());
978  return result;
979 }
980 
981 
982 // Sets the function info on a function.
983 // The start_position points to the first '(' character after the function name
984 // in the full script source. When counting characters in the script source the
985 // the first character is number 0 (not 1).
987  FunctionLiteral* lit,
988  bool is_toplevel,
989  Handle<Script> script) {
990  function_info->set_length(lit->parameter_count());
991  function_info->set_formal_parameter_count(lit->parameter_count());
992  function_info->set_script(*script);
993  function_info->set_function_token_position(lit->function_token_position());
994  function_info->set_start_position(lit->start_position());
995  function_info->set_end_position(lit->end_position());
996  function_info->set_is_expression(lit->is_expression());
997  function_info->set_is_anonymous(lit->is_anonymous());
998  function_info->set_is_toplevel(is_toplevel);
999  function_info->set_inferred_name(*lit->inferred_name());
1000  function_info->SetThisPropertyAssignmentsInfo(
1002  *lit->this_property_assignments());
1003  function_info->set_allows_lazy_compilation(lit->AllowsLazyCompilation());
1004  function_info->set_allows_lazy_compilation_without_context(
1006  function_info->set_language_mode(lit->language_mode());
1007  function_info->set_uses_arguments(lit->scope()->arguments() != NULL);
1008  function_info->set_has_duplicate_parameters(lit->has_duplicate_parameters());
1009  function_info->set_ast_node_count(lit->ast_node_count());
1010  function_info->set_is_function(lit->is_function());
1011  function_info->set_dont_optimize(lit->flags()->Contains(kDontOptimize));
1012  function_info->set_dont_inline(lit->flags()->Contains(kDontInline));
1013  function_info->set_dont_cache(lit->flags()->Contains(kDontCache));
1014 }
1015 
1016 
1018  CompilationInfo* info,
1019  Handle<SharedFunctionInfo> shared) {
1020  // SharedFunctionInfo is passed separately, because if CompilationInfo
1021  // was created using Script object, it will not have it.
1022 
1023  // Log the code generation. If source information is available include
1024  // script name and line number. Check explicitly whether logging is
1025  // enabled as finding the line number is not free.
1026  if (info->isolate()->logger()->is_logging_code_events() ||
1027  CpuProfiler::is_profiling(info->isolate())) {
1028  Handle<Script> script = info->script();
1029  Handle<Code> code = info->code();
1030  if (*code == info->isolate()->builtins()->builtin(Builtins::kLazyCompile))
1031  return;
1032  if (script->name()->IsString()) {
1033  int line_num = GetScriptLineNumber(script, shared->start_position()) + 1;
1034  USE(line_num);
1035  PROFILE(info->isolate(),
1036  CodeCreateEvent(Logger::ToNativeByScript(tag, *script),
1037  *code,
1038  *shared,
1039  String::cast(script->name()),
1040  line_num));
1041  } else {
1042  PROFILE(info->isolate(),
1043  CodeCreateEvent(Logger::ToNativeByScript(tag, *script),
1044  *code,
1045  *shared,
1046  shared->DebugName()));
1047  }
1048  }
1049 
1050  GDBJIT(AddCode(Handle<String>(shared->DebugName()),
1051  Handle<Script>(info->script()),
1052  Handle<Code>(info->code()),
1053  info));
1054 }
1055 
1056 } } // namespace v8::internal
Failure * StackOverflow()
Definition: isolate.cc:924
bool AllowsLazyCompilationWithoutContext()
Definition: ast.cc:156
Code * builtin(Name name)
Definition: builtins.h:320
Handle< FixedArray > this_property_assignments()
Definition: ast.h:1971
static bool IsActive(Isolate *isolate)
Definition: liveedit.cc:1922
#define V8PRIxPTR
Definition: globals.h:189
MUST_USE_RESULT Status CreateGraph()
Definition: compiler.cc:219
CompilationCache * compilation_cache()
Definition: isolate.h:827
void PrintF(const char *format,...)
Definition: v8utils.cc:40
static String * cast(Object *obj)
static bool UseCrankshaft()
Definition: v8.h:86
void SetScope(Scope *scope)
Definition: compiler.h:106
void SetCode(Handle< Code > code)
Definition: compiler.h:114
CompilationInfo * info() const
Definition: compiler.h:364
static Smi * FromInt(int value)
Definition: objects-inl.h:981
static bool MakeCode(CompilationInfo *info)
Handle< Script > NewScript(Handle< String > source)
Definition: factory.cc:374
bool outer_scope_calls_non_strict_eval() const
Definition: scopes.h:301
Handle< Script > script() const
Definition: compiler.h:72
static bool Analyze(CompilationInfo *info)
Definition: scopes.cc:274
bool is_expression() const
Definition: ast.h:1960
bool is_logging_code_events()
Definition: log.h:290
Vector< T > SubVector(int from, int to)
Definition: utils.h:376
Builtins * builtins()
Definition: isolate.h:924
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
Handle< Code > Codegen()
Definition: lithium.cc:417
#define ASSERT(condition)
Definition: checks.h:270
#define PROFILE(isolate, Call)
Definition: cpu-profiler.h:190
void PutEval(Handle< String > source, Handle< Context > context, bool is_global, Handle< SharedFunctionInfo > function_info, int scope_position)
bool has_only_simple_this_property_assignments()
Definition: ast.h:1968
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
Handle< String > debug_name() const
Definition: ast.h:1979
Factory * factory()
Definition: isolate.h:992
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
static Handle< ScopeInfo > Create(Scope *scope, Zone *zone)
Definition: scopeinfo.cc:41
void PutScript(Handle< String > source, Handle< Context > context, Handle< SharedFunctionInfo > function_info)
static bool Parse(CompilationInfo *info, int flags)
Definition: parser.cc:5944
MUST_USE_RESULT Status AbortOptimization()
Definition: compiler.h:366
bool HasTrivialOuterContext() const
Definition: scopes.cc:692
bool AllowsLazyCompilation() const
Definition: scopes.cc:725
Handle< SharedFunctionInfo > LookupEval(Handle< String > source, Handle< Context > context, bool is_global, LanguageMode language_mode, int scope_position)
static void InstallOptimizedCode(OptimizingCompiler *info)
Definition: compiler.cc:895
void ReportPendingMessages()
Definition: isolate.cc:1230
CompilationInfo(Handle< Script > script, Zone *zone)
Definition: compiler.cc:54
Variable * arguments() const
Definition: scopes.h:339
int num_stack_slots() const
Definition: scopes.h:366
static void AddToOptimizedCodeMap(Handle< SharedFunctionInfo > shared, Handle< Context > native_context, Handle< Code > code, Handle< FixedArray > literals)
Definition: objects.cc:7583
LanguageMode language_mode() const
Definition: ast.cc:171
int end_position() const
Definition: ast.cc:166
Handle< Code > code() const
Definition: compiler.h:69
int function_token_position() const
Definition: ast.h:1956
FunctionLiteral * function() const
Definition: compiler.h:66
static HTracer * Instance()
Definition: hydrogen.h:1415
Handle< String > inferred_name() const
Definition: ast.h:1984
MUST_USE_RESULT Status GenerateAndInstallCode()
Definition: compiler.cc:372
int length() const
Definition: utils.h:384
static void SetFunctionInfo(Handle< SharedFunctionInfo > function_info, FunctionLiteral *lit, bool is_toplevel, Handle< Script > script)
Definition: compiler.cc:986
static LChunk * NewChunk(HGraph *graph)
Definition: lithium.cc:393
int num_parameters() const
Definition: scopes.h:336
bool has_pending_exception()
Definition: isolate.h:561
static ScopeInfo * Empty()
Definition: scopeinfo.cc:152
Handle< JSFunction > closure() const
Definition: compiler.h:70
static BailoutId None()
Definition: utils.h:1014
Vector< const char > CStrVector(const char *data)
Definition: utils.h:526
bool is_anonymous() const
Definition: ast.h:1961
static const int kMaxFixedIndex
Definition: lithium.h:159
#define GDBJIT(action)
Definition: gdb-jit.h:141
Scope * scope() const
Definition: ast.h:1953
Definition: v8.h:1425
int GetScriptLineNumber(Handle< Script > script, int code_pos)
Definition: handles.cc:479
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
bool is_null() const
Definition: handles.h:87
void set_bailout_reason(const char *reason)
Definition: compiler.h:187
Handle< SharedFunctionInfo > shared_info() const
Definition: compiler.h:71
bool DebuggerHasBreakPoints()
Definition: isolate-inl.h:62
int start_position() const
Definition: ast.cc:161
static Handle< T > null()
Definition: handles.h:86
Handle< SharedFunctionInfo > LookupScript(Handle< String > source, Handle< Object > name, int line_offset, int column_offset, Handle< Context > context)
#define HEAP
Definition: isolate.h:1433
#define ASSERT_EQ(v1, v2)
Definition: checks.h:271
static Handle< SharedFunctionInfo > BuildFunctionInfo(FunctionLiteral *node, Handle< Script > script)
Definition: compiler.cc:926
void USE(T)
Definition: globals.h:289
bool inside_with() const
Definition: scopes.h:306
Handle< String > name() const
Definition: ast.h:1952
Counters * counters()
Definition: isolate.h:819
AstProperties::Flags * flags()
Definition: ast.h:2011
static bool CompileLazy(CompilationInfo *info)
Definition: compiler.cc:786
#define FACTORY
Definition: isolate.h:1434
Logger * logger()
Definition: isolate.h:828
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
void Bailout(const char *reason)
Definition: hydrogen.cc:3153
LanguageMode language_mode() const
Definition: scopes.h:317
void SetExpectedNofPropertiesFromEstimate(Handle< SharedFunctionInfo > shared, int estimate)
Definition: handles.cc:201
void TraceCompilation(FunctionLiteral *function)
Definition: hydrogen.cc:9663
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 code(assertions) for debugging") DEFINE_bool(code_comments
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 expose natives in global object expose gc extension number of stack frames to capture disable builtin natives files print a stack trace if an assertion failure occurs use random jit cookie to mask large constants trace lazy optimization use adaptive optimizations prepare for turning on always opt minimum length for automatic enable preparsing maximum number of optimization attempts before giving up cache prototype transitions automatically set the debug break flag when debugger commands are in the queue always cause a debug break before aborting maximum length of function source code printed in a stack trace max size of the new max size of the old max size of executable always perform global GCs print one trace line following each garbage collection do not print trace line after scavenger collection print more details following each garbage collection print amount of external allocated memory after each time it is adjusted flush code that we expect not to use again before full gc do incremental marking steps track object counts and memory usage use caching Perform compaction on every full GC Never perform compaction on full GC testing only Compact code space on full incremental collections Default seed for initializing random allows verbose printing trace parsing and preparsing Check icache flushes in ARM and MIPS simulator Stack alingment in bytes in print stack trace when throwing exceptions randomize hashes to avoid predictable hash Fixed seed to use to hash property activate a timer that switches between V8 threads testing_bool_flag float flag Seed used for threading test randomness A filename with extra code to be included in the Print usage including flags
Definition: flags.cc:495
static const int kMinFixedIndex
Definition: lithium.h:160
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 SetFunction(FunctionLiteral *literal)
Definition: compiler.h:102
static bool Rewrite(CompilationInfo *info)
Definition: rewriter.cc:235
bool Optimize(SmartArrayPointer< char > *bailout_reason)
Definition: hydrogen.cc:3287
Scope * scope() const
Definition: compiler.h:67
static JSFunction * cast(Object *obj)