diff options
Diffstat (limited to 'deps/v8/src/compiler.cc')
-rw-r--r-- | deps/v8/src/compiler.cc | 113 |
1 files changed, 99 insertions, 14 deletions
diff --git a/deps/v8/src/compiler.cc b/deps/v8/src/compiler.cc index 5fc107f943..8edb41d724 100644 --- a/deps/v8/src/compiler.cc +++ b/deps/v8/src/compiler.cc @@ -32,6 +32,7 @@ #include "bootstrapper.h" #include "codegen.h" #include "compilation-cache.h" +#include "cpu-profiler.h" #include "debug.h" #include "deoptimizer.h" #include "full-codegen.h" @@ -53,7 +54,8 @@ namespace v8 { namespace internal { -CompilationInfo::CompilationInfo(Handle<Script> script, Zone* zone) +CompilationInfo::CompilationInfo(Handle<Script> script, + Zone* zone) : flags_(LanguageModeField::encode(CLASSIC_MODE)), script_(script), osr_ast_id_(BailoutId::None()) { @@ -71,7 +73,8 @@ CompilationInfo::CompilationInfo(Handle<SharedFunctionInfo> shared_info, } -CompilationInfo::CompilationInfo(Handle<JSFunction> closure, Zone* zone) +CompilationInfo::CompilationInfo(Handle<JSFunction> closure, + Zone* zone) : flags_(LanguageModeField::encode(CLASSIC_MODE) | IsLazy::encode(true)), closure_(closure), shared_info_(Handle<SharedFunctionInfo>(closure->shared())), @@ -83,7 +86,8 @@ CompilationInfo::CompilationInfo(Handle<JSFunction> closure, Zone* zone) CompilationInfo::CompilationInfo(HydrogenCodeStub* stub, - Isolate* isolate, Zone* zone) + Isolate* isolate, + Zone* zone) : flags_(LanguageModeField::encode(CLASSIC_MODE) | IsLazy::encode(true)), osr_ast_id_(BailoutId::None()) { @@ -92,7 +96,9 @@ CompilationInfo::CompilationInfo(HydrogenCodeStub* stub, } -void CompilationInfo::Initialize(Isolate* isolate, Mode mode, Zone* zone) { +void CompilationInfo::Initialize(Isolate* isolate, + Mode mode, + Zone* zone) { isolate_ = isolate; function_ = NULL; scope_ = NULL; @@ -106,6 +112,9 @@ void CompilationInfo::Initialize(Isolate* isolate, Mode mode, Zone* zone) { opt_count_ = shared_info().is_null() ? 0 : shared_info()->opt_count(); no_frame_ranges_ = isolate->cpu_profiler()->is_profiling() ? new List<OffsetRange>(2) : NULL; + for (int i = 0; i < DependentCode::kGroupCount; i++) { + dependencies_[i] = NULL; + } if (mode == STUB) { mode_ = STUB; return; @@ -125,6 +134,47 @@ void CompilationInfo::Initialize(Isolate* isolate, Mode mode, Zone* zone) { CompilationInfo::~CompilationInfo() { delete deferred_handles_; delete no_frame_ranges_; +#ifdef DEBUG + // Check that no dependent maps have been added or added dependent maps have + // been rolled back or committed. + for (int i = 0; i < DependentCode::kGroupCount; i++) { + ASSERT_EQ(NULL, dependencies_[i]); + } +#endif // DEBUG +} + + +void CompilationInfo::CommitDependencies(Handle<Code> code) { + for (int i = 0; i < DependentCode::kGroupCount; i++) { + ZoneList<Handle<HeapObject> >* group_objects = dependencies_[i]; + if (group_objects == NULL) continue; + ASSERT(!object_wrapper_.is_null()); + for (int j = 0; j < group_objects->length(); j++) { + DependentCode::DependencyGroup group = + static_cast<DependentCode::DependencyGroup>(i); + DependentCode* dependent_code = + DependentCode::ForObject(group_objects->at(j), group); + dependent_code->UpdateToFinishedCode(group, this, *code); + } + dependencies_[i] = NULL; // Zone-allocated, no need to delete. + } +} + + +void CompilationInfo::RollbackDependencies() { + // Unregister from all dependent maps if not yet committed. + for (int i = 0; i < DependentCode::kGroupCount; i++) { + ZoneList<Handle<HeapObject> >* group_objects = dependencies_[i]; + if (group_objects == NULL) continue; + for (int j = 0; j < group_objects->length(); j++) { + DependentCode::DependencyGroup group = + static_cast<DependentCode::DependencyGroup>(i); + DependentCode* dependent_code = + DependentCode::ForObject(group_objects->at(j), group); + dependent_code->RemoveCompilationInfo(group, this); + } + dependencies_[i] = NULL; // Zone-allocated, no need to delete. + } } @@ -329,7 +379,10 @@ OptimizingCompiler::Status OptimizingCompiler::CreateGraph() { // performance of the hydrogen-based compiler. bool should_recompile = !info()->shared_info()->has_deoptimization_support(); if (should_recompile || FLAG_hydrogen_stats) { - HPhase phase(HPhase::kFullCodeGen, isolate()); + int64_t start_ticks = 0; + if (FLAG_hydrogen_stats) { + start_ticks = OS::Ticks(); + } CompilationInfoWithZone unoptimized(info()->shared_info()); // Note that we use the same AST that we will use for generating the // optimized code. @@ -346,6 +399,10 @@ OptimizingCompiler::Status OptimizingCompiler::CreateGraph() { Compiler::RecordFunctionCompilation( Logger::LAZY_COMPILE_TAG, &unoptimized, shared); } + if (FLAG_hydrogen_stats) { + int64_t ticks = OS::Ticks() - start_ticks; + isolate()->GetHStatistics()->IncrementFullCodeGen(ticks); + } } // Check that the unoptimized, shared code is ready for @@ -364,7 +421,7 @@ OptimizingCompiler::Status OptimizingCompiler::CreateGraph() { } // Type-check the function. - AstTyper::Type(info()); + AstTyper::Run(info()); graph_builder_ = new(info()->zone()) HOptimizedGraphBuilder(info()); @@ -490,7 +547,6 @@ static bool DebuggerWantsEagerCompilation(CompilationInfo* info, static Handle<SharedFunctionInfo> MakeFunctionInfo(CompilationInfo* info) { Isolate* isolate = info->isolate(); - ZoneScope zone_scope(info->zone(), DELETE_ON_EXIT); PostponeInterruptsScope postpone(isolate); ASSERT(!isolate->native_context().is_null()); @@ -773,7 +829,6 @@ static bool InstallFullCode(CompilationInfo* info) { // Check the function has compiled code. ASSERT(shared->is_compiled()); - shared->set_code_age(0); shared->set_dont_optimize(lit->flags()->Contains(kDontOptimize)); shared->set_dont_inline(lit->flags()->Contains(kDontInline)); shared->set_ast_node_count(lit->ast_node_count()); @@ -855,8 +910,6 @@ static bool InstallCodeFromOptimizedCodeMap(CompilationInfo* info) { bool Compiler::CompileLazy(CompilationInfo* info) { Isolate* isolate = info->isolate(); - ZoneScope zone_scope(info->zone(), DELETE_ON_EXIT); - // The VM is in the COMPILER state until exiting this function. VMState<COMPILER> state(isolate); @@ -982,7 +1035,7 @@ void Compiler::InstallOptimizedCode(OptimizingCompiler* optimizing_compiler) { // The function may have already been optimized by OSR. Simply continue. // Except when OSR already disabled optimization for some reason. if (info->shared_info()->optimization_disabled()) { - info->SetCode(Handle<Code>(info->shared_info()->code())); + info->AbortOptimization(); InstallFullCode(*info); if (FLAG_trace_parallel_recompilation) { PrintF(" ** aborting optimization for "); @@ -1000,9 +1053,14 @@ void Compiler::InstallOptimizedCode(OptimizingCompiler* optimizing_compiler) { // If crankshaft succeeded, install the optimized code else install // the unoptimized code. OptimizingCompiler::Status status = optimizing_compiler->last_status(); - if (status != OptimizingCompiler::SUCCEEDED) { - optimizing_compiler->info()->set_bailout_reason( - "failed/bailed out last time"); + if (info->HasAbortedDueToDependencyChange()) { + info->set_bailout_reason("bailed out due to dependent map"); + status = optimizing_compiler->AbortOptimization(); + } else if (status != OptimizingCompiler::SUCCEEDED) { + info->set_bailout_reason("failed/bailed out last time"); + status = optimizing_compiler->AbortOptimization(); + } else if (isolate->DebuggerHasBreakPoints()) { + info->set_bailout_reason("debugger is active"); status = optimizing_compiler->AbortOptimization(); } else { status = optimizing_compiler->GenerateAndInstallCode(); @@ -1167,4 +1225,31 @@ void Compiler::RecordFunctionCompilation(Logger::LogEventsAndTags tag, info)); } + +CompilationPhase::CompilationPhase(const char* name, CompilationInfo* info) + : name_(name), info_(info), zone_(info->isolate()) { + if (FLAG_hydrogen_stats) { + info_zone_start_allocation_size_ = info->zone()->allocation_size(); + start_ticks_ = OS::Ticks(); + } +} + + +CompilationPhase::~CompilationPhase() { + if (FLAG_hydrogen_stats) { + unsigned size = zone()->allocation_size(); + size += info_->zone()->allocation_size() - info_zone_start_allocation_size_; + int64_t ticks = OS::Ticks() - start_ticks_; + isolate()->GetHStatistics()->SaveTiming(name_, ticks, size); + } +} + + +bool CompilationPhase::ShouldProduceTraceOutput() const { + // Produce trace output if flag is set so that the first letter of the + // phase name matches the command line parameter FLAG_trace_phase. + return (FLAG_trace_hydrogen && + OS::StrChr(const_cast<char*>(FLAG_trace_phase), name_[0]) != NULL); +} + } } // namespace v8::internal |