diff --git a/src/compiler.cc b/src/compiler.cc index b40c153684..7ef75a1642 100644 --- a/src/compiler.cc +++ b/src/compiler.cc @@ -708,14 +708,21 @@ bool GetOptimizedCodeNow(CompilationInfo* info) { TimerEventScope optimize_code_timer(isolate); TRACE_EVENT0("v8", "V8.OptimizeCode"); - if (!Compiler::ParseAndAnalyze(info->parse_info())) return false; + bool use_turbofan = UseTurboFan(info); + OptimizedCompileJob* job = use_turbofan + ? compiler::Pipeline::NewCompilationJob(info) + : new (info->zone()) HCompilationJob(info); + + // Parsing is not required when optimizing from existing bytecode. + if (!use_turbofan || !info->shared_info()->HasBytecodeArray()) { + if (!Compiler::ParseAndAnalyze(info->parse_info())) return false; + } else { + info->MarkAsOptimizeFromBytecode(); + } TimerEventScope timer(isolate); TRACE_EVENT0("v8", "V8.RecompileSynchronous"); - OptimizedCompileJob* job = UseTurboFan(info) - ? compiler::Pipeline::NewCompilationJob(info) - : new (info->zone()) HCompilationJob(info); if (job->CreateGraph() != OptimizedCompileJob::SUCCEEDED || job->OptimizeGraph() != OptimizedCompileJob::SUCCEEDED || job->GenerateCode() != OptimizedCompileJob::SUCCEEDED) { @@ -751,8 +758,21 @@ bool GetOptimizedCodeLater(CompilationInfo* info) { return false; } + bool use_turbofan = UseTurboFan(info); + OptimizedCompileJob* job = use_turbofan + ? compiler::Pipeline::NewCompilationJob(info) + : new (info->zone()) HCompilationJob(info); + + // All handles below this point will be allocated in a deferred handle scope + // that is detached and handed off to the background thread when we return. CompilationHandleScope handle_scope(info); - if (!Compiler::ParseAndAnalyze(info->parse_info())) return false; + + // Parsing is not required when optimizing from existing bytecode. + if (!use_turbofan || !info->shared_info()->HasBytecodeArray()) { + if (!Compiler::ParseAndAnalyze(info->parse_info())) return false; + } else { + info->MarkAsOptimizeFromBytecode(); + } // Reopen handles in the new CompilationHandleScope. info->ReopenHandlesInNewHandleScope(); @@ -761,11 +781,7 @@ bool GetOptimizedCodeLater(CompilationInfo* info) { TimerEventScope timer(info->isolate()); TRACE_EVENT0("v8", "V8.RecompileSynchronous"); - OptimizedCompileJob* job = UseTurboFan(info) - ? compiler::Pipeline::NewCompilationJob(info) - : new (info->zone()) HCompilationJob(info); - OptimizedCompileJob::Status status = job->CreateGraph(); - if (status != OptimizedCompileJob::SUCCEEDED) return false; + if (job->CreateGraph() != OptimizedCompileJob::SUCCEEDED) return false; isolate->optimizing_compile_dispatcher()->QueueForOptimization(job); if (FLAG_trace_concurrent_recompilation) { diff --git a/src/compiler.h b/src/compiler.h index d6905cf4d3..47613d3b55 100644 --- a/src/compiler.h +++ b/src/compiler.h @@ -160,6 +160,7 @@ class CompilationInfo { kSourcePositionsEnabled = 1 << 15, kEffectSchedulingEnabled = 1 << 16, kBailoutOnUninitialized = 1 << 17, + kOptimizeFromBytecode = 1 << 18, }; CompilationInfo(ParseInfo* parse_info, Handle closure); @@ -304,6 +305,12 @@ class CompilationInfo { return GetFlag(kBailoutOnUninitialized); } + void MarkAsOptimizeFromBytecode() { SetFlag(kOptimizeFromBytecode); } + + bool is_optimizing_from_bytecode() const { + return GetFlag(kOptimizeFromBytecode); + } + bool GeneratePreagedPrologue() const { // Generate a pre-aged prologue if we are optimizing for size, which // will make code flushing more aggressive. Only apply to Code::FUNCTION, diff --git a/src/compiler/pipeline.cc b/src/compiler/pipeline.cc index 182b8142c8..dd5f9614db 100644 --- a/src/compiler/pipeline.cc +++ b/src/compiler/pipeline.cc @@ -561,9 +561,11 @@ struct LoopAssignmentAnalysisPhase { static const char* phase_name() { return "loop assignment analysis"; } void Run(PipelineData* data, Zone* temp_zone) { - AstLoopAssignmentAnalyzer analyzer(data->graph_zone(), data->info()); - LoopAssignmentAnalysis* loop_assignment = analyzer.Analyze(); - data->set_loop_assignment(loop_assignment); + if (!data->info()->is_optimizing_from_bytecode()) { + AstLoopAssignmentAnalyzer analyzer(data->graph_zone(), data->info()); + LoopAssignmentAnalysis* loop_assignment = analyzer.Analyze(); + data->set_loop_assignment(loop_assignment); + } } }; @@ -572,10 +574,12 @@ struct TypeHintAnalysisPhase { static const char* phase_name() { return "type hint analysis"; } void Run(PipelineData* data, Zone* temp_zone) { - TypeHintAnalyzer analyzer(data->graph_zone()); - Handle code(data->info()->shared_info()->code(), data->isolate()); - TypeHintAnalysis* type_hint_analysis = analyzer.Analyze(code); - data->set_type_hint_analysis(type_hint_analysis); + if (!data->info()->is_optimizing_from_bytecode()) { + TypeHintAnalyzer analyzer(data->graph_zone()); + Handle code(data->info()->shared_info()->code(), data->isolate()); + TypeHintAnalysis* type_hint_analysis = analyzer.Analyze(code); + data->set_type_hint_analysis(type_hint_analysis); + } } }; @@ -587,7 +591,7 @@ struct GraphBuilderPhase { bool stack_check = !data->info()->IsStub(); bool succeeded = false; - if (data->info()->shared_info()->HasBytecodeArray()) { + if (data->info()->is_optimizing_from_bytecode()) { BytecodeGraphBuilder graph_builder(temp_zone, data->info(), data->jsgraph()); succeeded = graph_builder.CreateGraph(); diff --git a/test/cctest/compiler/function-tester.h b/test/cctest/compiler/function-tester.h index d71969ec1c..b94d818081 100644 --- a/test/cctest/compiler/function-tester.h +++ b/test/cctest/compiler/function-tester.h @@ -188,6 +188,9 @@ class FunctionTester : public InitializedHandleScope { if (flags_ & CompilationInfo::kInliningEnabled) { info.MarkAsInliningEnabled(); } + if (function->shared()->HasBytecodeArray()) { + info.MarkAsOptimizeFromBytecode(); + } CHECK(Compiler::Analyze(info.parse_info())); CHECK(Compiler::EnsureDeoptimizationSupport(&info)); diff --git a/test/cctest/compiler/test-run-bytecode-graph-builder.cc b/test/cctest/compiler/test-run-bytecode-graph-builder.cc index 96234f8fac..580e3b1e44 100644 --- a/test/cctest/compiler/test-run-bytecode-graph-builder.cc +++ b/test/cctest/compiler/test-run-bytecode-graph-builder.cc @@ -128,6 +128,7 @@ class BytecodeGraphTester { CompilationInfo compilation_info(&parse_info, function); compilation_info.SetOptimizing(); compilation_info.MarkAsDeoptimizationEnabled(); + compilation_info.MarkAsOptimizeFromBytecode(); compiler::Pipeline pipeline(&compilation_info); Handle code = pipeline.GenerateCode(); function->ReplaceCode(*code);