Commit 991fc239 authored by Jakob Gruber's avatar Jakob Gruber Committed by Commit Bot

[nci] Spawn dedicated NCI compilation jobs

This CL introduces a new pipeline mode in which each optimization
triggers both a Turbofan and an NCI compilation job. The TF code is
installed, the NCI code is inserted into the code cache for future
consumption by other contexts.

--turbo-nci enables this mode.

The old configuration (with NCI replacing TF) is still available under
the --turbo-nci-as-highest-tier flag. This flag remains useful for
testing purposes.

Drive-by: Refactor tracing in compiler.cc.

Bug: v8:8888
Change-Id: I62522e61788762250ff717eef84eae914e266f3b
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2299360
Commit-Queue: Jakob Gruber <jgruber@chromium.org>
Reviewed-by: 's avatarRoss McIlroy <rmcilroy@chromium.org>
Reviewed-by: 's avatarMythri Alle <mythria@chromium.org>
Cr-Commit-Position: refs/heads/master@{#68983}
parent 1f5cc247
This diff is collapsed.
...@@ -43,6 +43,21 @@ class WorkerThreadRuntimeCallStats; ...@@ -43,6 +43,21 @@ class WorkerThreadRuntimeCallStats;
using UnoptimizedCompilationJobList = using UnoptimizedCompilationJobList =
std::forward_list<std::unique_ptr<UnoptimizedCompilationJob>>; std::forward_list<std::unique_ptr<UnoptimizedCompilationJob>>;
enum class CompilationTarget : uint8_t {
kTurbofan,
kNativeContextIndependent,
};
inline CompilationTarget DefaultCompilationTarget() {
return FLAG_turbo_nci_as_highest_tier
? CompilationTarget::kNativeContextIndependent
: CompilationTarget::kTurbofan;
}
inline bool ShouldSpawnExtraNativeContextIndependentCompilationJob() {
return FLAG_turbo_nci && !FLAG_turbo_nci_as_highest_tier;
}
// The V8 compiler API. // The V8 compiler API.
// //
// This is the central hub for dispatching to the various compilers within V8. // This is the central hub for dispatching to the various compilers within V8.
...@@ -68,7 +83,8 @@ class V8_EXPORT_PRIVATE Compiler : public AllStatic { ...@@ -68,7 +83,8 @@ class V8_EXPORT_PRIVATE Compiler : public AllStatic {
IsCompiledScope* is_compiled_scope); IsCompiledScope* is_compiled_scope);
static bool Compile(Handle<JSFunction> function, ClearExceptionFlag flag, static bool Compile(Handle<JSFunction> function, ClearExceptionFlag flag,
IsCompiledScope* is_compiled_scope); IsCompiledScope* is_compiled_scope);
static bool CompileOptimized(Handle<JSFunction> function, ConcurrencyMode); static bool CompileOptimized(Handle<JSFunction> function,
ConcurrencyMode mode, CompilationTarget target);
// Collect source positions for a function that has already been compiled to // Collect source positions for a function that has already been compiled to
// bytecode, but for which source positions were not collected (e.g. because // bytecode, but for which source positions were not collected (e.g. because
......
...@@ -995,7 +995,8 @@ class PipelineCompilationJob final : public OptimizedCompilationJob { ...@@ -995,7 +995,8 @@ class PipelineCompilationJob final : public OptimizedCompilationJob {
PipelineCompilationJob(Isolate* isolate, PipelineCompilationJob(Isolate* isolate,
Handle<SharedFunctionInfo> shared_info, Handle<SharedFunctionInfo> shared_info,
Handle<JSFunction> function, BailoutId osr_offset, Handle<JSFunction> function, BailoutId osr_offset,
JavaScriptFrame* osr_frame); JavaScriptFrame* osr_frame,
bool native_context_independent);
~PipelineCompilationJob() final; ~PipelineCompilationJob() final;
protected: protected:
...@@ -1023,7 +1024,7 @@ class PipelineCompilationJob final : public OptimizedCompilationJob { ...@@ -1023,7 +1024,7 @@ class PipelineCompilationJob final : public OptimizedCompilationJob {
PipelineCompilationJob::PipelineCompilationJob( PipelineCompilationJob::PipelineCompilationJob(
Isolate* isolate, Handle<SharedFunctionInfo> shared_info, Isolate* isolate, Handle<SharedFunctionInfo> shared_info,
Handle<JSFunction> function, BailoutId osr_offset, Handle<JSFunction> function, BailoutId osr_offset,
JavaScriptFrame* osr_frame) JavaScriptFrame* osr_frame, bool native_context_independent)
// Note that the OptimizedCompilationInfo is not initialized at the time // Note that the OptimizedCompilationInfo is not initialized at the time
// we pass it to the CompilationJob constructor, but it is not // we pass it to the CompilationJob constructor, but it is not
// dereferenced there. // dereferenced there.
...@@ -1032,7 +1033,7 @@ PipelineCompilationJob::PipelineCompilationJob( ...@@ -1032,7 +1033,7 @@ PipelineCompilationJob::PipelineCompilationJob(
kPipelineCompilationJobZoneName), kPipelineCompilationJobZoneName),
zone_stats_(function->GetIsolate()->allocator()), zone_stats_(function->GetIsolate()->allocator()),
compilation_info_(&zone_, function->GetIsolate(), shared_info, function, compilation_info_(&zone_, function->GetIsolate(), shared_info, function,
FLAG_turbo_nci), native_context_independent),
pipeline_statistics_(CreatePipelineStatistics( pipeline_statistics_(CreatePipelineStatistics(
handle(Script::cast(shared_info->script()), isolate), handle(Script::cast(shared_info->script()), isolate),
compilation_info(), function->GetIsolate(), &zone_stats_)), compilation_info(), function->GetIsolate(), &zone_stats_)),
...@@ -2915,11 +2916,13 @@ MaybeHandle<Code> Pipeline::GenerateCodeForTesting( ...@@ -2915,11 +2916,13 @@ MaybeHandle<Code> Pipeline::GenerateCodeForTesting(
// static // static
std::unique_ptr<OptimizedCompilationJob> Pipeline::NewCompilationJob( std::unique_ptr<OptimizedCompilationJob> Pipeline::NewCompilationJob(
Isolate* isolate, Handle<JSFunction> function, bool has_script, Isolate* isolate, Handle<JSFunction> function, bool has_script,
BailoutId osr_offset, JavaScriptFrame* osr_frame) { BailoutId osr_offset, JavaScriptFrame* osr_frame,
bool native_context_independent) {
Handle<SharedFunctionInfo> shared = Handle<SharedFunctionInfo> shared =
handle(function->shared(), function->GetIsolate()); handle(function->shared(), function->GetIsolate());
return std::make_unique<PipelineCompilationJob>(isolate, shared, function, return std::make_unique<PipelineCompilationJob>(isolate, shared, function,
osr_offset, osr_frame); osr_offset, osr_frame,
native_context_independent);
} }
// static // static
......
...@@ -47,7 +47,8 @@ class Pipeline : public AllStatic { ...@@ -47,7 +47,8 @@ class Pipeline : public AllStatic {
static std::unique_ptr<OptimizedCompilationJob> NewCompilationJob( static std::unique_ptr<OptimizedCompilationJob> NewCompilationJob(
Isolate* isolate, Handle<JSFunction> function, bool has_script, Isolate* isolate, Handle<JSFunction> function, bool has_script,
BailoutId osr_offset = BailoutId::None(), BailoutId osr_offset = BailoutId::None(),
JavaScriptFrame* osr_frame = nullptr); JavaScriptFrame* osr_frame = nullptr,
bool native_context_independent = false);
// Run the pipeline for the WebAssembly compilation info. // Run the pipeline for the WebAssembly compilation info.
static void GenerateCodeForWasmFunction( static void GenerateCodeForWasmFunction(
......
...@@ -57,21 +57,43 @@ RUNTIME_FUNCTION(Runtime_CompileLazy) { ...@@ -57,21 +57,43 @@ RUNTIME_FUNCTION(Runtime_CompileLazy) {
return function->code(); return function->code();
} }
RUNTIME_FUNCTION(Runtime_CompileOptimized_Concurrent) { namespace {
HandleScope scope(isolate);
DCHECK_EQ(1, args.length()); Object CompileOptimized(Isolate* isolate, Handle<JSFunction> function,
CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0); ConcurrencyMode mode) {
StackLimitCheck check(isolate); StackLimitCheck check(isolate);
if (check.JsHasOverflowed(kStackSpaceRequiredForCompilation * KB)) { if (check.JsHasOverflowed(kStackSpaceRequiredForCompilation * KB)) {
return isolate->StackOverflow(); return isolate->StackOverflow();
} }
if (!Compiler::CompileOptimized(function, ConcurrencyMode::kConcurrent)) { if (!Compiler::CompileOptimized(function, mode, DefaultCompilationTarget())) {
return ReadOnlyRoots(isolate).exception(); return ReadOnlyRoots(isolate).exception();
} }
if (ShouldSpawnExtraNativeContextIndependentCompilationJob()) {
if (!Compiler::CompileOptimized(
function, mode, CompilationTarget::kNativeContextIndependent)) {
return ReadOnlyRoots(isolate).exception();
}
}
DCHECK(function->is_compiled()); DCHECK(function->is_compiled());
return function->code(); return function->code();
} }
} // namespace
RUNTIME_FUNCTION(Runtime_CompileOptimized_Concurrent) {
HandleScope scope(isolate);
DCHECK_EQ(1, args.length());
CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
return CompileOptimized(isolate, function, ConcurrencyMode::kConcurrent);
}
RUNTIME_FUNCTION(Runtime_CompileOptimized_NotConcurrent) {
HandleScope scope(isolate);
DCHECK_EQ(1, args.length());
CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
return CompileOptimized(isolate, function, ConcurrencyMode::kNotConcurrent);
}
RUNTIME_FUNCTION(Runtime_FunctionFirstExecution) { RUNTIME_FUNCTION(Runtime_FunctionFirstExecution) {
HandleScope scope(isolate); HandleScope scope(isolate);
StackLimitCheck check(isolate); StackLimitCheck check(isolate);
...@@ -91,21 +113,6 @@ RUNTIME_FUNCTION(Runtime_FunctionFirstExecution) { ...@@ -91,21 +113,6 @@ RUNTIME_FUNCTION(Runtime_FunctionFirstExecution) {
return function->code(); return function->code();
} }
RUNTIME_FUNCTION(Runtime_CompileOptimized_NotConcurrent) {
HandleScope scope(isolate);
DCHECK_EQ(1, args.length());
CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
StackLimitCheck check(isolate);
if (check.JsHasOverflowed(kStackSpaceRequiredForCompilation * KB)) {
return isolate->StackOverflow();
}
if (!Compiler::CompileOptimized(function, ConcurrencyMode::kNotConcurrent)) {
return ReadOnlyRoots(isolate).exception();
}
DCHECK(function->is_compiled());
return function->code();
}
RUNTIME_FUNCTION(Runtime_EvictOptimizedCodeSlot) { RUNTIME_FUNCTION(Runtime_EvictOptimizedCodeSlot) {
SealHandleScope scope(isolate); SealHandleScope scope(isolate);
DCHECK_EQ(1, args.length()); DCHECK_EQ(1, args.length());
......
...@@ -4378,6 +4378,7 @@ static int GetCodeChainLength(Code code) { ...@@ -4378,6 +4378,7 @@ static int GetCodeChainLength(Code code) {
TEST(NextCodeLinkIsWeak) { TEST(NextCodeLinkIsWeak) {
FLAG_always_opt = false; FLAG_always_opt = false;
FLAG_allow_natives_syntax = true; FLAG_allow_natives_syntax = true;
FLAG_turbo_nci = false; // Additional compile tasks muck with test logic.
CcTest::InitializeVM(); CcTest::InitializeVM();
Isolate* isolate = CcTest::i_isolate(); Isolate* isolate = CcTest::i_isolate();
v8::internal::Heap* heap = CcTest::heap(); v8::internal::Heap* heap = CcTest::heap();
...@@ -4408,6 +4409,7 @@ TEST(NextCodeLinkIsWeak) { ...@@ -4408,6 +4409,7 @@ TEST(NextCodeLinkIsWeak) {
TEST(NextCodeLinkInCodeDataContainerIsCleared) { TEST(NextCodeLinkInCodeDataContainerIsCleared) {
FLAG_always_opt = false; FLAG_always_opt = false;
FLAG_allow_natives_syntax = true; FLAG_allow_natives_syntax = true;
FLAG_turbo_nci = false; // Additional compile tasks muck with test logic.
CcTest::InitializeVM(); CcTest::InitializeVM();
Isolate* isolate = CcTest::i_isolate(); Isolate* isolate = CcTest::i_isolate();
v8::internal::Heap* heap = CcTest::heap(); v8::internal::Heap* heap = CcTest::heap();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment