diff --git a/BUILD.gn b/BUILD.gn index 687ae18d08..0c983ad026 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -125,9 +125,9 @@ declare_args() { v8_enable_v8_checks = "" # Sets -dV8_TRACE_UNOPTIMIZED. - v8_enable_trace_unoptimized = false + v8_enable_trace_unoptimized = "" v8_enable_trace_ignition = false - v8_enable_trace_baseline = false + v8_enable_trace_baseline_exec = false # Sets -dV8_TRACE_FEEDBACK_UPDATES. v8_enable_trace_feedback_updates = false @@ -358,11 +358,11 @@ assert(!v8_enable_concurrent_marking || v8_enable_atomic_marking_state, "Concurrent marking requires atomic marking state.") if (v8_enable_trace_unoptimized == "") { v8_enable_trace_unoptimized = - v8_enable_trace_ignition || v8_enable_trace_baseline + v8_enable_trace_ignition || v8_enable_trace_baseline_exec } assert(!v8_enable_trace_ignition || v8_enable_trace_unoptimized, "Ignition tracing requires unoptimized tracing to be enabled.") -assert(!v8_enable_trace_baseline || v8_enable_trace_unoptimized, +assert(!v8_enable_trace_baseline_exec || v8_enable_trace_unoptimized, "Baseline tracing requires unoptimized tracing to be enabled.") # Toggle pointer compression for correctness fuzzing when building the diff --git a/src/baseline/baseline-compiler.cc b/src/baseline/baseline-compiler.cc index 25afc657a2..c13cc63076 100644 --- a/src/baseline/baseline-compiler.cc +++ b/src/baseline/baseline-compiler.cc @@ -551,7 +551,7 @@ void BaselineCompiler::VerifyFrame() { #ifdef V8_TRACE_UNOPTIMIZED void BaselineCompiler::TraceBytecode(Runtime::FunctionId function_id) { - if (!FLAG_trace_baseline) return; + if (!FLAG_trace_baseline_exec) return; __ RecordComment(function_id == Runtime::kTraceUnoptimizedBytecodeEntry ? "[ Trace bytecode entry" diff --git a/src/baseline/baseline.cc b/src/baseline/baseline.cc index 118521c84d..b54d6be589 100644 --- a/src/baseline/baseline.cc +++ b/src/baseline/baseline.cc @@ -17,62 +17,18 @@ namespace v8 { namespace internal { -Handle CompileWithBaseline( - Isolate* isolate, Handle shared_function_info, - Handle bytecode) { +Handle GenerateBaselineCode(Isolate* isolate, + Handle shared) { RuntimeCallTimerScope runtimeTimer(isolate, RuntimeCallCounterId::kCompileBaseline); - baseline::BaselineCompiler compiler(isolate, shared_function_info, bytecode); + baseline::BaselineCompiler compiler( + isolate, shared, handle(shared->GetBytecodeArray(isolate), isolate)); compiler.GenerateCode(); - - return compiler.Build(isolate); -} - -// TODO(v8:11429): This can be the basis of Compiler::CompileBaseline -Handle CompileWithBaseline(Isolate* isolate, - Handle shared) { - if (shared->HasBaselineData()) { - return handle(shared->baseline_data().baseline_code(), isolate); - } - - if (FLAG_trace_opt) { - PrintF("[compiling method "); - shared->ShortPrint(); - PrintF(" using Baseline]\n"); - } - - base::ElapsedTimer timer; - timer.Start(); - - Handle code = CompileWithBaseline( - isolate, shared, handle(shared->GetBytecodeArray(isolate), isolate)); - Handle function_data = - handle(HeapObject::cast(shared->function_data(kAcquireLoad)), isolate); - Handle baseline_data = - isolate->factory()->NewBaselineData(code, function_data); - shared->set_baseline_data(*baseline_data); - + Handle code = compiler.Build(isolate); if (FLAG_print_code) { code->Print(); } - - if (shared->script().IsScript()) { - Compiler::LogFunctionCompilation( - isolate, CodeEventListener::FUNCTION_TAG, shared, - handle(Script::cast(shared->script()), isolate), - Handle::cast(code), CodeKind::BASELINE, - timer.Elapsed().InMillisecondsF()); - } - - if (FLAG_trace_opt) { - // TODO(v8:11429): Move to Compiler. - PrintF("[completed compiling "); - shared->ShortPrint(); - PrintF(" using Sparkplug - took %0.3f ms]\n", - timer.Elapsed().InMillisecondsF()); - } - return code; } @@ -84,8 +40,8 @@ Handle CompileWithBaseline(Isolate* isolate, namespace v8 { namespace internal { -Handle CompileWithBaseline(Isolate* isolate, - Handle shared) { +Handle GenerateBaselineCode(Isolate* isolate, + Handle shared) { UNREACHABLE(); } diff --git a/src/baseline/baseline.h b/src/baseline/baseline.h index d98e659ba2..a11baad36e 100644 --- a/src/baseline/baseline.h +++ b/src/baseline/baseline.h @@ -15,8 +15,8 @@ class SharedFunctionInfo; class BytecodeArray; // TODO(v8:11429): Restrict header visibility to just this file. -Handle CompileWithBaseline(Isolate* isolate, - Handle shared); +Handle GenerateBaselineCode(Isolate* isolate, + Handle shared); } // namespace internal } // namespace v8 diff --git a/src/codegen/compiler.cc b/src/codegen/compiler.cc index ce1f0bb064..dce441ad96 100644 --- a/src/codegen/compiler.cc +++ b/src/codegen/compiler.cc @@ -13,6 +13,7 @@ #include "src/ast/scopes.h" #include "src/base/logging.h" #include "src/base/optional.h" +#include "src/base/platform/time.h" #include "src/baseline/baseline.h" #include "src/codegen/assembler-inl.h" #include "src/codegen/compilation-cache.h" @@ -65,24 +66,6 @@ namespace { class CompilerTracer : public AllStatic { public: - static void PrintTracePrefix(const CodeTracer::Scope& scope, - const char* header, - OptimizedCompilationInfo* info) { - PrintTracePrefix(scope, header, info->closure(), info->code_kind()); - } - - static void PrintTracePrefix(const CodeTracer::Scope& scope, - const char* header, Handle function, - CodeKind code_kind) { - PrintF(scope.file(), "[%s ", header); - function->ShortPrint(scope.file()); - PrintF(scope.file(), " (target %s)", CodeKindToString(code_kind)); - } - - static void PrintTraceSuffix(const CodeTracer::Scope& scope) { - PrintF(scope.file(), "]\n"); - } - static void TracePrepareJob(Isolate* isolate, OptimizedCompilationInfo* info, const char* compiler_name) { if (!FLAG_trace_opt || !info->IsOptimizing()) return; @@ -93,6 +76,15 @@ class CompilerTracer : public AllStatic { PrintTraceSuffix(scope); } + static void TraceStartBaselineCompile(Isolate* isolate, + Handle shared) { + if (!FLAG_trace_baseline) return; + CodeTracer::Scope scope(isolate->GetCodeTracer()); + PrintTracePrefix(scope, "compiling method", shared, CodeKind::BASELINE); + PrintF(scope.file(), " using Sparkplug"); + PrintTraceSuffix(scope); + } + static void TraceCompilationStats(Isolate* isolate, OptimizedCompilationInfo* info, double ms_creategraph, double ms_optimize, @@ -105,6 +97,16 @@ class CompilerTracer : public AllStatic { PrintTraceSuffix(scope); } + static void TraceFinishBaselineCompile(Isolate* isolate, + Handle shared, + double ms_timetaken) { + if (!FLAG_trace_baseline) return; + CodeTracer::Scope scope(isolate->GetCodeTracer()); + PrintTracePrefix(scope, "compiling", shared, CodeKind::BASELINE); + PrintF(scope.file(), " - took %0.3f ms", ms_timetaken); + PrintTraceSuffix(scope); + } + static void TraceCompletedJob(Isolate* isolate, OptimizedCompilationInfo* info) { if (!FLAG_trace_opt) return; @@ -155,6 +157,34 @@ class CompilerTracer : public AllStatic { PrintF(scope.file(), " for optimized recompilation because --always-opt"); PrintF(scope.file(), "]\n"); } + + private: + static void PrintTracePrefix(const CodeTracer::Scope& scope, + const char* header, + OptimizedCompilationInfo* info) { + PrintTracePrefix(scope, header, info->closure(), info->code_kind()); + } + + static void PrintTracePrefix(const CodeTracer::Scope& scope, + const char* header, Handle function, + CodeKind code_kind) { + PrintF(scope.file(), "[%s ", header); + function->ShortPrint(scope.file()); + PrintF(scope.file(), " (target %s)", CodeKindToString(code_kind)); + } + + static void PrintTracePrefix(const CodeTracer::Scope& scope, + const char* header, + Handle shared, + CodeKind code_kind) { + PrintF(scope.file(), "[%s ", header); + shared->ShortPrint(scope.file()); + PrintF(scope.file(), " (target %s)", CodeKindToString(code_kind)); + } + + static void PrintTraceSuffix(const CodeTracer::Scope& scope) { + PrintF(scope.file(), "]\n"); + } }; } // namespace @@ -606,6 +636,58 @@ void UpdateSharedFunctionFlagsAfterCompilation(FunctionLiteral* literal, shared_info.SetScopeInfo(*literal->scope()->scope_info()); } +bool CompileSharedWithBaseline(Isolate* isolate, + Handle shared, + Compiler::ClearExceptionFlag flag, + IsCompiledScope* is_compiled_scope) { + DCHECK(FLAG_sparkplug); + DCHECK(is_compiled_scope->is_compiled()); + + if (shared->HasBaselineData()) return true; + + StackLimitCheck check(isolate); + if (check.JsHasOverflowed(kStackSpaceRequiredForCompilation * KB)) { + if (flag == Compiler::KEEP_EXCEPTION) { + isolate->StackOverflow(); + } + return false; + } + + // Check if we actually have bytecode. + if (!shared->HasBytecodeArray()) return false; + + // Do not optimize when debugger needs to hook into every call. + if (isolate->debug()->needs_check_on_function_call()) return false; + + // Functions with breakpoints have to stay interpreted. + if (shared->HasBreakInfo()) return false; + + CompilerTracer::TraceStartBaselineCompile(isolate, shared); + Handle code; + base::TimeDelta time_taken; + { + ScopedTimer timer(&time_taken); + code = GenerateBaselineCode(isolate, shared); + + Handle function_data = + handle(HeapObject::cast(shared->function_data(kAcquireLoad)), isolate); + Handle baseline_data = + isolate->factory()->NewBaselineData(code, function_data); + shared->set_baseline_data(*baseline_data); + } + double time_taken_ms = time_taken.InMillisecondsF(); + + CompilerTracer::TraceFinishBaselineCompile(isolate, shared, time_taken_ms); + + if (shared->script().IsScript()) { + Compiler::LogFunctionCompilation( + isolate, CodeEventListener::FUNCTION_TAG, shared, + handle(Script::cast(shared->script()), isolate), + Handle::cast(code), CodeKind::BASELINE, time_taken_ms); + } + return true; +} + // Finalize a single compilation job. This function can return // RETRY_ON_MAIN_THREAD if the job cannot be finalized off-thread, in which case // it should be safe to call it again on the main thread with the same job. @@ -1237,10 +1319,9 @@ void FinalizeUnoptimizedCompilation( if (FLAG_interpreted_frames_native_stack) { InstallInterpreterTrampolineCopy(isolate, shared_info); } - if (FLAG_always_sparkplug && shared_info->HasBytecodeArray() && - !shared_info->HasBreakInfo()) { - // TODO(v8:11429) Extract to Compiler::CompileX - CompileWithBaseline(isolate, shared_info); + if (FLAG_always_sparkplug) { + CompileSharedWithBaseline(isolate, shared_info, Compiler::KEEP_EXCEPTION, + &is_compiled_scope); } Handle coverage_info; if (finalize_data.coverage_info().ToHandle(&coverage_info)) { @@ -1888,6 +1969,25 @@ bool Compiler::Compile(Isolate* isolate, Handle function, return true; } +// static +bool Compiler::CompileBaseline(Isolate* isolate, Handle function, + ClearExceptionFlag flag, + IsCompiledScope* is_compiled_scope) { + Handle shared(function->shared(isolate), isolate); + if (!CompileSharedWithBaseline(isolate, shared, flag, is_compiled_scope)) { + return false; + } + + // Baseline code needs a feedback vector. + JSFunction::EnsureFeedbackVector(function, is_compiled_scope); + + Code baseline_code = shared->baseline_data().baseline_code(isolate); + DCHECK_EQ(baseline_code.kind(), CodeKind::BASELINE); + function->set_code(baseline_code); + + return true; +} + // static MaybeHandle Compiler::CompileToplevel( ParseInfo* parse_info, Handle