Index: src/compiler.cc |
diff --git a/src/compiler.cc b/src/compiler.cc |
index e4eedf59e3124286dad244ea639a4a45e852a593..3a53761b1fe8cd15cefdce0bd4a6dc1922ec51dc 100644 |
--- a/src/compiler.cc |
+++ b/src/compiler.cc |
@@ -278,11 +278,36 @@ CompilationJob::Status CompilationJob::FinalizeJob() { |
// Delegate to the underlying implementation. |
DCHECK(state() == State::kReadyToFinalize); |
- ScopedTimer t(&time_taken_to_finalize_); |
- return UpdateState(FinalizeJobImpl(), State::kSucceeded); |
+ Status status; |
+ { |
+ ScopedTimer t(&time_taken_to_finalize_); |
+ status = FinalizeJobImpl(); |
+ if (status == SUCCEEDED) { |
+ RecordCompilationStats(); |
+ } |
+ } |
+ return UpdateState(status, State::kSucceeded); |
+} |
+ |
+void CompilationJob::RecordUnoptimizedCompilationStats() const { |
+ DCHECK(!info()->IsOptimizing()); |
+ |
+ int code_size; |
+ if (info()->has_bytecode_array()) { |
+ code_size = info()->bytecode_array()->SizeIncludingMetadata(); |
+ } else { |
+ code_size = info()->code()->SizeIncludingMetadata(); |
+ } |
+ |
+ Counters* counters = isolate()->counters(); |
+ // TODO(4280): Rename counters from "baseline" to "unoptimized" eventually. |
+ counters->total_baseline_code_size()->Increment(code_size); |
+ counters->total_baseline_compile_count()->Increment(1); |
+ |
+ // TODO(5203): Add timers for each phase of compilation. |
} |
-void CompilationJob::RecordOptimizationStats() { |
+void CompilationJob::RecordOptimizedCompilationStats() const { |
DCHECK(info()->IsOptimizing()); |
Handle<JSFunction> function = info()->closure(); |
if (!function->IsOptimized()) { |
@@ -409,16 +434,23 @@ bool ShouldUseIgnition(CompilationInfo* info) { |
return info->shared_info()->PassesFilter(FLAG_ignition_filter); |
} |
-int CodeAndMetadataSize(CompilationInfo* info) { |
- if (info->has_bytecode_array()) { |
- return info->bytecode_array()->SizeIncludingMetadata(); |
+CompilationJob* GetUnoptimizedCompilationJob(CompilationInfo* info) { |
+ // Function should have been parsed and analyzed before creating a compilation |
+ // job. |
+ DCHECK_NOT_NULL(info->literal()); |
+ DCHECK_NOT_NULL(info->scope()); |
+ DCHECK(!(FLAG_validate_asm && info->scope()->asm_module())); |
+ |
+ EnsureFeedbackMetadata(info); |
+ |
+ if (ShouldUseIgnition(info)) { |
+ return interpreter::Interpreter::NewCompilationJob(info); |
+ } else { |
+ return FullCodeGenerator::NewCompilationJob(info); |
} |
- return info->code()->SizeIncludingMetadata(); |
} |
bool GenerateUnoptimizedCode(CompilationInfo* info) { |
- bool success; |
- EnsureFeedbackMetadata(info); |
if (FLAG_validate_asm && info->scope()->asm_module()) { |
MaybeHandle<FixedArray> wasm_data; |
wasm_data = AsmJs::ConvertAsmToWasm(info->parse_info()); |
@@ -428,19 +460,12 @@ bool GenerateUnoptimizedCode(CompilationInfo* info) { |
return true; |
} |
} |
- if (ShouldUseIgnition(info)) { |
- success = interpreter::Interpreter::MakeBytecode(info); |
- } else { |
- success = FullCodeGenerator::MakeCode(info); |
- } |
- if (success) { |
- Isolate* isolate = info->isolate(); |
- Counters* counters = isolate->counters(); |
- // TODO(4280): Rename counters from "baseline" to "unoptimized" eventually. |
- counters->total_baseline_code_size()->Increment(CodeAndMetadataSize(info)); |
- counters->total_baseline_compile_count()->Increment(1); |
- } |
- return success; |
+ |
+ std::unique_ptr<CompilationJob> job(GetUnoptimizedCompilationJob(info)); |
+ if (job->PrepareJob() != CompilationJob::SUCCEEDED) return false; |
+ if (job->ExecuteJob() != CompilationJob::SUCCEEDED) return false; |
+ if (job->FinalizeJob() != CompilationJob::SUCCEEDED) return false; |
+ return true; |
} |
bool CompileUnoptimizedCode(CompilationInfo* info) { |
@@ -477,6 +502,19 @@ void InstallSharedCompilationResult(CompilationInfo* info, |
} |
} |
+void InstallUnoptimizedCode(CompilationInfo* info) { |
+ Handle<SharedFunctionInfo> shared = info->shared_info(); |
+ |
+ // Update the shared function info with the scope info. |
+ InstallSharedScopeInfo(info, shared); |
+ |
+ // Install compilation result on the shared function info |
+ InstallSharedCompilationResult(info, shared); |
+ |
+ // Record the function compilation event. |
+ RecordFunctionCompilation(CodeEventListener::LAZY_COMPILE_TAG, info); |
+} |
+ |
MUST_USE_RESULT MaybeHandle<Code> GetUnoptimizedCode(CompilationInfo* info) { |
VMState<COMPILER> state(info->isolate()); |
PostponeInterruptsScope postpone(info->isolate()); |
@@ -488,24 +526,25 @@ MUST_USE_RESULT MaybeHandle<Code> GetUnoptimizedCode(CompilationInfo* info) { |
// Parse and update CompilationInfo with the results. |
if (!Parser::ParseStatic(info->parse_info())) return MaybeHandle<Code>(); |
- Handle<SharedFunctionInfo> shared = info->shared_info(); |
- DCHECK_EQ(shared->language_mode(), info->literal()->language_mode()); |
+ DCHECK_EQ(info->shared_info()->language_mode(), |
+ info->literal()->language_mode()); |
// Compile either unoptimized code or bytecode for the interpreter. |
if (!CompileUnoptimizedCode(info)) return MaybeHandle<Code>(); |
- // Update the shared function info with the scope info. |
- InstallSharedScopeInfo(info, shared); |
- |
- // Install compilation result on the shared function info |
- InstallSharedCompilationResult(info, shared); |
- |
- // Record the function compilation event. |
- RecordFunctionCompilation(CodeEventListener::LAZY_COMPILE_TAG, info); |
+ InstallUnoptimizedCode(info); |
return info->code(); |
} |
+CompilationJob::Status FinalizeUnoptimizedCompilationJob(CompilationJob* job) { |
+ CompilationJob::Status status = job->FinalizeJob(); |
+ if (status == CompilationJob::SUCCEEDED) { |
+ InstallUnoptimizedCode(job->info()); |
+ } |
+ return status; |
+} |
+ |
MUST_USE_RESULT MaybeHandle<Code> GetCodeFromOptimizedCodeMap( |
Handle<JSFunction> function, BailoutId osr_ast_id) { |
Handle<SharedFunctionInfo> shared(function->shared()); |
@@ -627,7 +666,6 @@ bool GetOptimizedCodeNow(CompilationJob* job) { |
} |
// Success! |
- job->RecordOptimizationStats(); |
DCHECK(!isolate->has_pending_exception()); |
InsertCodeIntoOptimizedCodeMap(info); |
RecordFunctionCompilation(CodeEventListener::LAZY_COMPILE_TAG, info); |
@@ -787,6 +825,57 @@ MaybeHandle<Code> GetOptimizedCode(Handle<JSFunction> function, |
return MaybeHandle<Code>(); |
} |
+CompilationJob::Status FinalizeOptimizedCompilationJob(CompilationJob* job) { |
+ CompilationInfo* info = job->info(); |
+ Isolate* isolate = info->isolate(); |
+ |
+ TimerEventScope<TimerEventRecompileSynchronous> timer(info->isolate()); |
+ RuntimeCallTimerScope runtimeTimer(isolate, |
+ &RuntimeCallStats::RecompileSynchronous); |
+ TRACE_EVENT_RUNTIME_CALL_STATS_TRACING_SCOPED( |
+ isolate, &tracing::TraceEventStatsTable::RecompileSynchronous); |
+ |
+ Handle<SharedFunctionInfo> shared = info->shared_info(); |
+ shared->code()->set_profiler_ticks(0); |
+ |
+ DCHECK(!shared->HasDebugInfo()); |
+ |
+ // 1) Optimization on the concurrent thread may have failed. |
+ // 2) The function may have already been optimized by OSR. Simply continue. |
+ // Except when OSR already disabled optimization for some reason. |
+ // 3) The code may have already been invalidated due to dependency change. |
+ // 4) Code generation may have failed. |
+ if (job->state() == CompilationJob::State::kReadyToFinalize) { |
+ if (shared->optimization_disabled()) { |
+ job->RetryOptimization(kOptimizationDisabled); |
+ } else if (info->dependencies()->HasAborted()) { |
+ job->RetryOptimization(kBailedOutDueToDependencyChange); |
+ } else if (job->FinalizeJob() == CompilationJob::SUCCEEDED) { |
+ RecordFunctionCompilation(CodeEventListener::LAZY_COMPILE_TAG, info); |
+ if (shared->SearchOptimizedCodeMap(info->context()->native_context(), |
+ info->osr_ast_id()).code == nullptr) { |
+ InsertCodeIntoOptimizedCodeMap(info); |
+ } |
+ if (FLAG_trace_opt) { |
+ PrintF("[completed optimizing "); |
+ info->closure()->ShortPrint(); |
+ PrintF("]\n"); |
+ } |
+ info->closure()->ReplaceCode(*info->code()); |
+ return CompilationJob::SUCCEEDED; |
+ } |
+ } |
+ |
+ DCHECK(job->state() == CompilationJob::State::kFailed); |
+ if (FLAG_trace_opt) { |
+ PrintF("[aborted optimizing "); |
+ info->closure()->ShortPrint(); |
+ PrintF(" because: %s]\n", GetBailoutReason(info->bailout_reason())); |
+ } |
+ info->closure()->ReplaceCode(shared->code()); |
+ return CompilationJob::FAILED; |
+} |
+ |
class InterpreterActivationsFinder : public ThreadVisitor, |
public OptimizedFunctionVisitor { |
public: |
@@ -1821,58 +1910,28 @@ MaybeHandle<Code> Compiler::GetOptimizedCodeForOSR(Handle<JSFunction> function, |
return GetOptimizedCode(function, NOT_CONCURRENT, osr_ast_id, osr_frame); |
} |
-void Compiler::FinalizeCompilationJob(CompilationJob* raw_job) { |
+CompilationJob* Compiler::PrepareUnoptimizedCompilationJob( |
+ CompilationInfo* info) { |
+ VMState<COMPILER> state(info->isolate()); |
+ std::unique_ptr<CompilationJob> job(GetUnoptimizedCompilationJob(info)); |
+ if (job->PrepareJob() != CompilationJob::SUCCEEDED) { |
+ return nullptr; |
+ } |
+ return job.release(); |
+} |
+ |
+bool Compiler::FinalizeCompilationJob(CompilationJob* raw_job) { |
// Take ownership of compilation job. Deleting job also tears down the zone. |
std::unique_ptr<CompilationJob> job(raw_job); |
- CompilationInfo* info = job->info(); |
- Isolate* isolate = info->isolate(); |
- VMState<COMPILER> state(isolate); |
- TimerEventScope<TimerEventRecompileSynchronous> timer(info->isolate()); |
- RuntimeCallTimerScope runtimeTimer(isolate, |
- &RuntimeCallStats::RecompileSynchronous); |
- TRACE_EVENT_RUNTIME_CALL_STATS_TRACING_SCOPED( |
- isolate, &tracing::TraceEventStatsTable::RecompileSynchronous); |
- |
- Handle<SharedFunctionInfo> shared = info->shared_info(); |
- shared->code()->set_profiler_ticks(0); |
- |
- DCHECK(!shared->HasDebugInfo()); |
- |
- // 1) Optimization on the concurrent thread may have failed. |
- // 2) The function may have already been optimized by OSR. Simply continue. |
- // Except when OSR already disabled optimization for some reason. |
- // 3) The code may have already been invalidated due to dependency change. |
- // 4) Code generation may have failed. |
- if (job->state() == CompilationJob::State::kReadyToFinalize) { |
- if (shared->optimization_disabled()) { |
- job->RetryOptimization(kOptimizationDisabled); |
- } else if (info->dependencies()->HasAborted()) { |
- job->RetryOptimization(kBailedOutDueToDependencyChange); |
- } else if (job->FinalizeJob() == CompilationJob::SUCCEEDED) { |
- job->RecordOptimizationStats(); |
- RecordFunctionCompilation(CodeEventListener::LAZY_COMPILE_TAG, info); |
- if (shared->SearchOptimizedCodeMap(info->context()->native_context(), |
- info->osr_ast_id()).code == nullptr) { |
- InsertCodeIntoOptimizedCodeMap(info); |
- } |
- if (FLAG_trace_opt) { |
- PrintF("[completed optimizing "); |
- info->closure()->ShortPrint(); |
- PrintF("]\n"); |
- } |
- info->closure()->ReplaceCode(*info->code()); |
- return; |
- } |
- } |
- |
- DCHECK(job->state() == CompilationJob::State::kFailed); |
- if (FLAG_trace_opt) { |
- PrintF("[aborted optimizing "); |
- info->closure()->ShortPrint(); |
- PrintF(" because: %s]\n", GetBailoutReason(info->bailout_reason())); |
+ VMState<COMPILER> state(job->info()->isolate()); |
+ if (job->info()->IsOptimizing()) { |
+ return FinalizeOptimizedCompilationJob(job.get()) == |
+ CompilationJob::SUCCEEDED; |
+ } else { |
+ return FinalizeUnoptimizedCompilationJob(job.get()) == |
+ CompilationJob::SUCCEEDED; |
} |
- info->closure()->ReplaceCode(shared->code()); |
} |
void Compiler::PostInstantiation(Handle<JSFunction> function, |