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;
using UnoptimizedCompilationJobList =
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.
//
// This is the central hub for dispatching to the various compilers within V8.
......@@ -68,7 +83,8 @@ class V8_EXPORT_PRIVATE Compiler : public AllStatic {
IsCompiledScope* is_compiled_scope);
static bool Compile(Handle<JSFunction> function, ClearExceptionFlag flag,
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
// bytecode, but for which source positions were not collected (e.g. because
......
......@@ -995,7 +995,8 @@ class PipelineCompilationJob final : public OptimizedCompilationJob {
PipelineCompilationJob(Isolate* isolate,
Handle<SharedFunctionInfo> shared_info,
Handle<JSFunction> function, BailoutId osr_offset,
JavaScriptFrame* osr_frame);
JavaScriptFrame* osr_frame,
bool native_context_independent);
~PipelineCompilationJob() final;
protected:
......@@ -1023,7 +1024,7 @@ class PipelineCompilationJob final : public OptimizedCompilationJob {
PipelineCompilationJob::PipelineCompilationJob(
Isolate* isolate, Handle<SharedFunctionInfo> shared_info,
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
// we pass it to the CompilationJob constructor, but it is not
// dereferenced there.
......@@ -1032,7 +1033,7 @@ PipelineCompilationJob::PipelineCompilationJob(
kPipelineCompilationJobZoneName),
zone_stats_(function->GetIsolate()->allocator()),
compilation_info_(&zone_, function->GetIsolate(), shared_info, function,
FLAG_turbo_nci),
native_context_independent),
pipeline_statistics_(CreatePipelineStatistics(
handle(Script::cast(shared_info->script()), isolate),
compilation_info(), function->GetIsolate(), &zone_stats_)),
......@@ -2915,11 +2916,13 @@ MaybeHandle<Code> Pipeline::GenerateCodeForTesting(
// static
std::unique_ptr<OptimizedCompilationJob> Pipeline::NewCompilationJob(
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(function->shared(), function->GetIsolate());
return std::make_unique<PipelineCompilationJob>(isolate, shared, function,
osr_offset, osr_frame);
osr_offset, osr_frame,
native_context_independent);
}
// static
......
......@@ -47,7 +47,8 @@ class Pipeline : public AllStatic {
static std::unique_ptr<OptimizedCompilationJob> NewCompilationJob(
Isolate* isolate, Handle<JSFunction> function, bool has_script,
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.
static void GenerateCodeForWasmFunction(
......
......@@ -57,21 +57,43 @@ RUNTIME_FUNCTION(Runtime_CompileLazy) {
return function->code();
}
RUNTIME_FUNCTION(Runtime_CompileOptimized_Concurrent) {
HandleScope scope(isolate);
DCHECK_EQ(1, args.length());
CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
namespace {
Object CompileOptimized(Isolate* isolate, Handle<JSFunction> function,
ConcurrencyMode mode) {
StackLimitCheck check(isolate);
if (check.JsHasOverflowed(kStackSpaceRequiredForCompilation * KB)) {
return isolate->StackOverflow();
}
if (!Compiler::CompileOptimized(function, ConcurrencyMode::kConcurrent)) {
if (!Compiler::CompileOptimized(function, mode, DefaultCompilationTarget())) {
return ReadOnlyRoots(isolate).exception();
}
if (ShouldSpawnExtraNativeContextIndependentCompilationJob()) {
if (!Compiler::CompileOptimized(
function, mode, CompilationTarget::kNativeContextIndependent)) {
return ReadOnlyRoots(isolate).exception();
}
}
DCHECK(function->is_compiled());
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) {
HandleScope scope(isolate);
StackLimitCheck check(isolate);
......@@ -91,21 +113,6 @@ RUNTIME_FUNCTION(Runtime_FunctionFirstExecution) {
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) {
SealHandleScope scope(isolate);
DCHECK_EQ(1, args.length());
......
......@@ -4378,6 +4378,7 @@ static int GetCodeChainLength(Code code) {
TEST(NextCodeLinkIsWeak) {
FLAG_always_opt = false;
FLAG_allow_natives_syntax = true;
FLAG_turbo_nci = false; // Additional compile tasks muck with test logic.
CcTest::InitializeVM();
Isolate* isolate = CcTest::i_isolate();
v8::internal::Heap* heap = CcTest::heap();
......@@ -4408,6 +4409,7 @@ TEST(NextCodeLinkIsWeak) {
TEST(NextCodeLinkInCodeDataContainerIsCleared) {
FLAG_always_opt = false;
FLAG_allow_natives_syntax = true;
FLAG_turbo_nci = false; // Additional compile tasks muck with test logic.
CcTest::InitializeVM();
Isolate* isolate = CcTest::i_isolate();
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