| 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,
|
|
|