Revision f230a1cf deps/v8/src/compiler.cc

View differences:

deps/v8/src/compiler.cc
112 112
  zone_ = zone;
113 113
  deferred_handles_ = NULL;
114 114
  code_stub_ = NULL;
115
  prologue_offset_ = kPrologueOffsetNotSet;
115
  prologue_offset_ = Code::kPrologueOffsetNotSet;
116 116
  opt_count_ = shared_info().is_null() ? 0 : shared_info()->opt_count();
117 117
  no_frame_ranges_ = isolate->cpu_profiler()->is_profiling()
118 118
                   ? new List<OffsetRange>(2) : NULL;
......
123 123
    mode_ = STUB;
124 124
    return;
125 125
  }
126
  mode_ = isolate->use_crankshaft() ? mode : NONOPT;
126
  mode_ = mode;
127 127
  abort_due_to_dependency_ = false;
128 128
  if (script_->type()->value() == Script::TYPE_NATIVE) {
129 129
    MarkAsNative();
......
260 260
}
261 261

  
262 262

  
263
void OptimizingCompiler::RecordOptimizationStats() {
263
void RecompileJob::RecordOptimizationStats() {
264 264
  Handle<JSFunction> function = info()->closure();
265 265
  int opt_count = function->shared()->opt_count();
266 266
  function->shared()->set_opt_count(opt_count + 1);
......
297 297
// A return value of true indicates the compilation pipeline is still
298 298
// going, not necessarily that we optimized the code.
299 299
static bool MakeCrankshaftCode(CompilationInfo* info) {
300
  OptimizingCompiler compiler(info);
301
  OptimizingCompiler::Status status = compiler.CreateGraph();
300
  RecompileJob job(info);
301
  RecompileJob::Status status = job.CreateGraph();
302 302

  
303
  if (status != OptimizingCompiler::SUCCEEDED) {
304
    return status != OptimizingCompiler::FAILED;
303
  if (status != RecompileJob::SUCCEEDED) {
304
    return status != RecompileJob::FAILED;
305 305
  }
306
  status = compiler.OptimizeGraph();
307
  if (status != OptimizingCompiler::SUCCEEDED) {
308
    status = compiler.AbortOptimization();
309
    return status != OptimizingCompiler::FAILED;
306
  status = job.OptimizeGraph();
307
  if (status != RecompileJob::SUCCEEDED) {
308
    status = job.AbortOptimization();
309
    return status != RecompileJob::FAILED;
310 310
  }
311
  status = compiler.GenerateAndInstallCode();
312
  return status != OptimizingCompiler::FAILED;
311
  status = job.GenerateAndInstallCode();
312
  return status != RecompileJob::FAILED;
313 313
}
314 314

  
315 315

  
316
OptimizingCompiler::Status OptimizingCompiler::CreateGraph() {
316
class HOptimizedGraphBuilderWithPotisions: public HOptimizedGraphBuilder {
317
 public:
318
  explicit HOptimizedGraphBuilderWithPotisions(CompilationInfo* info)
319
      : HOptimizedGraphBuilder(info) {
320
  }
321

  
322
#define DEF_VISIT(type)                                 \
323
  virtual void Visit##type(type* node) V8_OVERRIDE {    \
324
    if (node->position() != RelocInfo::kNoPosition) {   \
325
      SetSourcePosition(node->position());              \
326
    }                                                   \
327
    HOptimizedGraphBuilder::Visit##type(node);          \
328
  }
329
  EXPRESSION_NODE_LIST(DEF_VISIT)
330
#undef DEF_VISIT
331

  
332
#define DEF_VISIT(type)                                          \
333
  virtual void Visit##type(type* node) V8_OVERRIDE {             \
334
    if (node->position() != RelocInfo::kNoPosition) {            \
335
      SetSourcePosition(node->position());                       \
336
    }                                                            \
337
    HOptimizedGraphBuilder::Visit##type(node);                   \
338
  }
339
  STATEMENT_NODE_LIST(DEF_VISIT)
340
#undef DEF_VISIT
341

  
342
#define DEF_VISIT(type)                                            \
343
  virtual void Visit##type(type* node) V8_OVERRIDE {               \
344
    HOptimizedGraphBuilder::Visit##type(node);                     \
345
  }
346
  MODULE_NODE_LIST(DEF_VISIT)
347
  DECLARATION_NODE_LIST(DEF_VISIT)
348
  AUXILIARY_NODE_LIST(DEF_VISIT)
349
#undef DEF_VISIT
350
};
351

  
352

  
353
RecompileJob::Status RecompileJob::CreateGraph() {
317 354
  ASSERT(isolate()->use_crankshaft());
318 355
  ASSERT(info()->IsOptimizing());
319 356
  ASSERT(!info()->IsCompilingForDebugging());
......
419 456
  // Type-check the function.
420 457
  AstTyper::Run(info());
421 458

  
422
  graph_builder_ = new(info()->zone()) HOptimizedGraphBuilder(info());
459
  graph_builder_ = FLAG_emit_opt_code_positions
460
      ? new(info()->zone()) HOptimizedGraphBuilderWithPotisions(info())
461
      : new(info()->zone()) HOptimizedGraphBuilder(info());
423 462

  
424 463
  Timer t(this, &time_taken_to_create_graph_);
425 464
  graph_ = graph_builder_->CreateGraph();
......
452 491
}
453 492

  
454 493

  
455
OptimizingCompiler::Status OptimizingCompiler::OptimizeGraph() {
494
RecompileJob::Status RecompileJob::OptimizeGraph() {
456 495
  DisallowHeapAllocation no_allocation;
457 496
  DisallowHandleAllocation no_handles;
458 497
  DisallowHandleDereference no_deref;
......
475 514
}
476 515

  
477 516

  
478
OptimizingCompiler::Status OptimizingCompiler::GenerateAndInstallCode() {
517
RecompileJob::Status RecompileJob::GenerateAndInstallCode() {
479 518
  ASSERT(last_status() == SUCCEEDED);
480 519
  ASSERT(!info()->HasAbortedDueToDependencyChange());
481 520
  DisallowCodeDependencyChange no_dependency_change;
......
555 594
}
556 595

  
557 596

  
597
// Sets the expected number of properties based on estimate from compiler.
598
void SetExpectedNofPropertiesFromEstimate(Handle<SharedFunctionInfo> shared,
599
                                          int estimate) {
600
  // See the comment in SetExpectedNofProperties.
601
  if (shared->live_objects_may_exist()) return;
602

  
603
  // If no properties are added in the constructor, they are more likely
604
  // to be added later.
605
  if (estimate == 0) estimate = 2;
606

  
607
  // TODO(yangguo): check whether those heuristics are still up-to-date.
608
  // We do not shrink objects that go into a snapshot (yet), so we adjust
609
  // the estimate conservatively.
610
  if (Serializer::enabled()) {
611
    estimate += 2;
612
  } else if (FLAG_clever_optimizations) {
613
    // Inobject slack tracking will reclaim redundant inobject space later,
614
    // so we can afford to adjust the estimate generously.
615
    estimate += 8;
616
  } else {
617
    estimate += 3;
618
  }
619

  
620
  shared->set_expected_nof_properties(estimate);
621
}
622

  
623

  
558 624
static Handle<SharedFunctionInfo> MakeFunctionInfo(CompilationInfo* info) {
559 625
  Isolate* isolate = info->isolate();
560 626
  PostponeInterruptsScope postpone(isolate);
......
599 665
    }
600 666
  }
601 667

  
602
  // Measure how long it takes to do the compilation; only take the
603
  // rest of the function into account to avoid overlap with the
604
  // parsing statistics.
605
  HistogramTimer* rate = info->is_eval()
606
      ? info->isolate()->counters()->compile_eval()
607
      : info->isolate()->counters()->compile();
608
  HistogramTimerScope timer(rate);
609

  
610
  // Compile the code.
611 668
  FunctionLiteral* lit = info->function();
612 669
  LiveEditFunctionTracker live_edit_tracker(isolate, lit);
613
  if (!MakeCode(info)) {
614
    if (!isolate->has_pending_exception()) isolate->StackOverflow();
615
    return Handle<SharedFunctionInfo>::null();
616
  }
670
  Handle<SharedFunctionInfo> result;
671
  {
672
    // Measure how long it takes to do the compilation; only take the
673
    // rest of the function into account to avoid overlap with the
674
    // parsing statistics.
675
    HistogramTimer* rate = info->is_eval()
676
          ? info->isolate()->counters()->compile_eval()
677
          : info->isolate()->counters()->compile();
678
    HistogramTimerScope timer(rate);
617 679

  
618
  // Allocate function.
619
  ASSERT(!info->code().is_null());
620
  Handle<SharedFunctionInfo> result =
621
      isolate->factory()->NewSharedFunctionInfo(
622
          lit->name(),
623
          lit->materialized_literal_count(),
624
          lit->is_generator(),
625
          info->code(),
626
          ScopeInfo::Create(info->scope(), info->zone()));
627

  
628
  ASSERT_EQ(RelocInfo::kNoPosition, lit->function_token_position());
629
  Compiler::SetFunctionInfo(result, lit, true, script);
630

  
631
  if (script->name()->IsString()) {
632
    PROFILE(isolate, CodeCreateEvent(
633
        info->is_eval()
634
            ? Logger::EVAL_TAG
635
            : Logger::ToNativeByScript(Logger::SCRIPT_TAG, *script),
636
        *info->code(),
637
        *result,
638
        info,
639
        String::cast(script->name())));
640
    GDBJIT(AddCode(Handle<String>(String::cast(script->name())),
641
                   script,
642
                   info->code(),
643
                   info));
644
  } else {
645
    PROFILE(isolate, CodeCreateEvent(
646
        info->is_eval()
647
            ? Logger::EVAL_TAG
648
            : Logger::ToNativeByScript(Logger::SCRIPT_TAG, *script),
649
        *info->code(),
650
        *result,
651
        info,
652
        isolate->heap()->empty_string()));
653
    GDBJIT(AddCode(Handle<String>(), script, info->code(), info));
654
  }
680
    // Compile the code.
681
    if (!MakeCode(info)) {
682
      if (!isolate->has_pending_exception()) isolate->StackOverflow();
683
      return Handle<SharedFunctionInfo>::null();
684
    }
685

  
686
    // Allocate function.
687
    ASSERT(!info->code().is_null());
688
    result =
689
        isolate->factory()->NewSharedFunctionInfo(
690
            lit->name(),
691
            lit->materialized_literal_count(),
692
            lit->is_generator(),
693
            info->code(),
694
            ScopeInfo::Create(info->scope(), info->zone()));
695

  
696
    ASSERT_EQ(RelocInfo::kNoPosition, lit->function_token_position());
697
    Compiler::SetFunctionInfo(result, lit, true, script);
698

  
699
    if (script->name()->IsString()) {
700
      PROFILE(isolate, CodeCreateEvent(
701
          info->is_eval()
702
          ? Logger::EVAL_TAG
703
              : Logger::ToNativeByScript(Logger::SCRIPT_TAG, *script),
704
                *info->code(),
705
                *result,
706
                info,
707
                String::cast(script->name())));
708
      GDBJIT(AddCode(Handle<String>(String::cast(script->name())),
709
                     script,
710
                     info->code(),
711
                     info));
712
    } else {
713
      PROFILE(isolate, CodeCreateEvent(
714
          info->is_eval()
715
          ? Logger::EVAL_TAG
716
              : Logger::ToNativeByScript(Logger::SCRIPT_TAG, *script),
717
                *info->code(),
718
                *result,
719
                info,
720
                isolate->heap()->empty_string()));
721
      GDBJIT(AddCode(Handle<String>(), script, info->code(), info));
722
    }
655 723

  
656
  // Hint to the runtime system used when allocating space for initial
657
  // property space by setting the expected number of properties for
658
  // the instances of the function.
659
  SetExpectedNofPropertiesFromEstimate(result, lit->expected_property_count());
724
    // Hint to the runtime system used when allocating space for initial
725
    // property space by setting the expected number of properties for
726
    // the instances of the function.
727
    SetExpectedNofPropertiesFromEstimate(result,
728
                                         lit->expected_property_count());
660 729

  
661
  script->set_compilation_state(Script::COMPILATION_STATE_COMPILED);
730
    script->set_compilation_state(Script::COMPILATION_STATE_COMPILED);
731
  }
662 732

  
663 733
#ifdef ENABLE_DEBUGGER_SUPPORT
664 734
  // Notify debugger
......
1032 1102
      info->SaveHandles();
1033 1103

  
1034 1104
      if (Rewriter::Rewrite(*info) && Scope::Analyze(*info)) {
1035
        OptimizingCompiler* compiler =
1036
            new(info->zone()) OptimizingCompiler(*info);
1037
        OptimizingCompiler::Status status = compiler->CreateGraph();
1038
        if (status == OptimizingCompiler::SUCCEEDED) {
1105
        RecompileJob* job = new(info->zone()) RecompileJob(*info);
1106
        RecompileJob::Status status = job->CreateGraph();
1107
        if (status == RecompileJob::SUCCEEDED) {
1039 1108
          info.Detach();
1040 1109
          shared->code()->set_profiler_ticks(0);
1041
          isolate->optimizing_compiler_thread()->QueueForOptimization(compiler);
1110
          isolate->optimizing_compiler_thread()->QueueForOptimization(job);
1042 1111
          ASSERT(!isolate->has_pending_exception());
1043 1112
          return true;
1044
        } else if (status == OptimizingCompiler::BAILED_OUT) {
1113
        } else if (status == RecompileJob::BAILED_OUT) {
1045 1114
          isolate->clear_pending_exception();
1046 1115
          InstallFullCode(*info);
1047 1116
        }
......
1054 1123
}
1055 1124

  
1056 1125

  
1057
Handle<Code> Compiler::InstallOptimizedCode(
1058
    OptimizingCompiler* optimizing_compiler) {
1059
  SmartPointer<CompilationInfo> info(optimizing_compiler->info());
1126
Handle<Code> Compiler::InstallOptimizedCode(RecompileJob* job) {
1127
  SmartPointer<CompilationInfo> info(job->info());
1060 1128
  // The function may have already been optimized by OSR.  Simply continue.
1061 1129
  // Except when OSR already disabled optimization for some reason.
1062 1130
  if (info->shared_info()->optimization_disabled()) {
......
1077 1145
      isolate, Logger::TimerEventScope::v8_recompile_synchronous);
1078 1146
  // If crankshaft succeeded, install the optimized code else install
1079 1147
  // the unoptimized code.
1080
  OptimizingCompiler::Status status = optimizing_compiler->last_status();
1148
  RecompileJob::Status status = job->last_status();
1081 1149
  if (info->HasAbortedDueToDependencyChange()) {
1082 1150
    info->set_bailout_reason(kBailedOutDueToDependencyChange);
1083
    status = optimizing_compiler->AbortOptimization();
1084
  } else if (status != OptimizingCompiler::SUCCEEDED) {
1151
    status = job->AbortOptimization();
1152
  } else if (status != RecompileJob::SUCCEEDED) {
1085 1153
    info->set_bailout_reason(kFailedBailedOutLastTime);
1086
    status = optimizing_compiler->AbortOptimization();
1154
    status = job->AbortOptimization();
1087 1155
  } else if (isolate->DebuggerHasBreakPoints()) {
1088 1156
    info->set_bailout_reason(kDebuggerIsActive);
1089
    status = optimizing_compiler->AbortOptimization();
1157
    status = job->AbortOptimization();
1090 1158
  } else {
1091
    status = optimizing_compiler->GenerateAndInstallCode();
1092
    ASSERT(status == OptimizingCompiler::SUCCEEDED ||
1093
           status == OptimizingCompiler::BAILED_OUT);
1159
    status = job->GenerateAndInstallCode();
1160
    ASSERT(status == RecompileJob::SUCCEEDED ||
1161
           status == RecompileJob::BAILED_OUT);
1094 1162
  }
1095 1163

  
1096 1164
  InstallCodeCommon(*info);
1097
  if (status == OptimizingCompiler::SUCCEEDED) {
1165
  if (status == RecompileJob::SUCCEEDED) {
1098 1166
    Handle<Code> code = info->code();
1099 1167
    ASSERT(info->shared_info()->scope_info() != ScopeInfo::Empty(isolate));
1100 1168
    info->closure()->ReplaceCode(*code);
......
1115 1183
  // profiler ticks to prevent too soon re-opt after a deopt.
1116 1184
  info->shared_info()->code()->set_profiler_ticks(0);
1117 1185
  ASSERT(!info->closure()->IsInRecompileQueue());
1118
  return (status == OptimizingCompiler::SUCCEEDED) ? info->code()
1119
                                                   : Handle<Code>::null();
1186
  return (status == RecompileJob::SUCCEEDED) ? info->code()
1187
                                             : Handle<Code>::null();
1120 1188
}
1121 1189

  
1122 1190

  

Also available in: Unified diff