Commit 8d6c969f authored by Dominik Inführ's avatar Dominik Inführ Committed by V8 LUCI CQ

[execution] Introduce Isolate::shared_space_isolate()

At the moment the shared heap is internally implemented as its own
isolate - the shared isolate. This CL prepares to remove the shared
isolate and replace it with shared spaces in the main isolate.

This CL introduces the --shared-space flag to opt-in into this shared
heap-approach. Isolate::is_shared_space_isolate() and
Isolate::shared_space_isolate() are added as well to identify the
main isolate (or shared space isolate).

Bug: v8:13267
Change-Id: I1a79c839de3b3b9cc988401e2e6e70ce3b02fa22
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3874928Reviewed-by: 's avatarIgor Sheludko <ishell@chromium.org>
Reviewed-by: 's avatarMichael Lippautz <mlippautz@chromium.org>
Reviewed-by: 's avatarShu-yu Guo <syg@chromium.org>
Commit-Queue: Dominik Inführ <dinfuehr@chromium.org>
Cr-Commit-Position: refs/heads/main@{#83050}
parent 7a6caf02
......@@ -503,6 +503,8 @@ base::LazyMutex Isolate::process_wide_shared_isolate_mutex_ =
LAZY_MUTEX_INITIALIZER;
Isolate* Isolate::process_wide_shared_isolate_{nullptr};
Isolate* Isolate::process_wide_shared_space_isolate_{nullptr};
base::Thread::LocalStorageKey Isolate::isolate_key_;
base::Thread::LocalStorageKey Isolate::per_isolate_thread_data_key_;
std::atomic<bool> Isolate::isolate_key_created_{false};
......@@ -3314,7 +3316,7 @@ void Isolate::DeleteProcessWideSharedIsolate() {
// static
Isolate* Isolate::New() {
Isolate* isolate = Allocate(false);
if (HasFlagThatRequiresSharedHeap()) {
if (HasFlagThatRequiresSharedHeap() && !v8_flags.shared_space) {
// The Isolate that creates the shared Isolate, which is usually the main
// thread Isolate, owns the lifetime of shared heap.
bool created;
......@@ -3460,10 +3462,6 @@ Isolate::Isolate(std::unique_ptr<i::IsolateAllocator> isolate_allocator,
InitializeDefaultEmbeddedBlob();
MicrotaskQueue::SetUpDefaultMicrotaskQueue(this);
if (is_shared_) {
global_safepoint_ = std::make_unique<GlobalSafepoint>(this);
}
}
void Isolate::CheckIsolateLayout() {
......@@ -3576,7 +3574,9 @@ void Isolate::Deinit() {
}
// All client isolates should already be detached.
if (is_shared()) global_safepoint()->AssertNoClientsOnTearDown();
if (is_shared() || is_shared_space_isolate()) {
global_safepoint()->AssertNoClientsOnTearDown();
}
if (v8_flags.print_deopt_stress) {
PrintF(stdout, "=== Stress deopt counter: %u\n", stress_deopt_count_);
......@@ -3623,6 +3623,7 @@ void Isolate::Deinit() {
// client isolate before it can actually detach from the shared isolate.
AllowGarbageCollection allow_shared_gc;
DetachFromSharedIsolate();
DetachFromSharedSpaceIsolate();
}
// Since there are no other threads left, we can lock this mutex without any
......@@ -4130,6 +4131,19 @@ bool Isolate::Init(SnapshotData* startup_snapshot_data,
time_millis_at_init_ = heap_.MonotonicallyIncreasingTimeInMs();
Isolate* attach_to_shared_space_isolate = nullptr;
if (HasFlagThatRequiresSharedHeap() && v8_flags.shared_space) {
if (process_wide_shared_space_isolate_) {
attach_to_shared_space_isolate = process_wide_shared_space_isolate_;
} else {
process_wide_shared_space_isolate_ = this;
is_shared_space_isolate_ = true;
}
}
CHECK_IMPLIES(is_shared_space_isolate_, V8_CAN_CREATE_SHARED_HEAP_BOOL);
stress_deopt_count_ = v8_flags.deopt_every_n_times;
force_slow_path_ = v8_flags.force_slow_path;
......@@ -4163,6 +4177,10 @@ bool Isolate::Init(SnapshotData* startup_snapshot_data,
interpreter_ = new interpreter::Interpreter(this);
bigint_processor_ = bigint::Processor::New(new BigIntPlatform(this));
if (is_shared_ || is_shared_space_isolate_) {
global_safepoint_ = std::make_unique<GlobalSafepoint>(this);
}
if (v8_flags.lazy_compile_dispatcher) {
lazy_compile_dispatcher_ = std::make_unique<LazyCompileDispatcher>(
this, V8::GetCurrentPlatform(), v8_flags.stack_size);
......@@ -4212,6 +4230,7 @@ bool Isolate::Init(SnapshotData* startup_snapshot_data,
// isolate. Otherwise a global safepoint would find an isolate without
// LocalHeaps and not wait until this thread is ready for a GC.
AttachToSharedIsolate();
AttachToSharedSpaceIsolate(attach_to_shared_space_isolate);
// SetUp the object heap.
DCHECK(!heap_.HasBeenSetUp());
......@@ -5936,6 +5955,23 @@ void Isolate::DetachFromSharedIsolate() {
#endif // DEBUG
}
void Isolate::AttachToSharedSpaceIsolate(Isolate* shared_space_isolate) {
DCHECK(!shared_space_isolate_.has_value());
shared_space_isolate_ = shared_space_isolate;
if (shared_space_isolate) {
shared_space_isolate->global_safepoint()->AppendClient(this);
}
}
void Isolate::DetachFromSharedSpaceIsolate() {
DCHECK(shared_space_isolate_.has_value());
Isolate* shared_space_isolate = shared_space_isolate_.value();
if (shared_space_isolate) {
shared_space_isolate->global_safepoint()->RemoveClient(this);
}
shared_space_isolate_.reset();
}
#ifdef V8_COMPRESS_POINTERS
ExternalPointerHandle Isolate::GetOrCreateWaiterQueueNodeExternalPointer() {
ExternalPointerHandle handle;
......
......@@ -1987,6 +1987,11 @@ class V8_EXPORT_PRIVATE Isolate final : private HiddenFactory {
return shared_isolate_;
}
bool is_shared_space_isolate() const { return is_shared_space_isolate_; }
Isolate* shared_space_isolate() const {
return shared_space_isolate_.value();
}
void set_shared_isolate(Isolate* shared_isolate) {
DCHECK(shared_isolate->is_shared());
DCHECK_NULL(shared_isolate_);
......@@ -2089,6 +2094,8 @@ class V8_EXPORT_PRIVATE Isolate final : private HiddenFactory {
static Isolate* GetProcessWideSharedIsolate(bool* created_shared_isolate);
static void DeleteProcessWideSharedIsolate();
static Isolate* process_wide_shared_space_isolate_;
static base::Thread::LocalStorageKey per_isolate_thread_data_key_;
static base::Thread::LocalStorageKey isolate_key_;
static std::atomic<bool> isolate_key_created_;
......@@ -2141,6 +2148,9 @@ class V8_EXPORT_PRIVATE Isolate final : private HiddenFactory {
void AttachToSharedIsolate();
void DetachFromSharedIsolate();
void AttachToSharedSpaceIsolate(Isolate* shared_space_isolate);
void DetachFromSharedSpaceIsolate();
// This class contains a collection of data accessible from both C++ runtime
// and compiled code (including assembly stubs, builtins, interpreter bytecode
// handlers and optimized code).
......@@ -2150,6 +2160,9 @@ class V8_EXPORT_PRIVATE Isolate final : private HiddenFactory {
// before Heap is constructed, as Heap's constructor consults it.
const bool is_shared_;
// Set to true if this isolate is used as main isolate with a shared space.
bool is_shared_space_isolate_{false};
std::unique_ptr<IsolateAllocator> isolate_allocator_;
Heap heap_;
ReadOnlyHeap* read_only_heap_ = nullptr;
......@@ -2457,6 +2470,9 @@ class V8_EXPORT_PRIVATE Isolate final : private HiddenFactory {
// When non-null, it is identical to process_wide_shared_isolate_.
Isolate* shared_isolate_ = nullptr;
// Stores the isolate containing the shared space.
base::Optional<Isolate*> shared_space_isolate_;
#ifdef V8_COMPRESS_POINTERS
// The external pointer handle to the Isolate's main thread's WaiterQueueNode.
// It is used to wait for JS-exposed mutex or condition variable.
......
......@@ -1219,6 +1219,8 @@ DEFINE_BOOL(separate_gc_phases, false,
DEFINE_BOOL(global_gc_scheduling, true,
"enable GC scheduling based on global memory")
DEFINE_BOOL(gc_global, false, "always perform global GCs")
DEFINE_BOOL(shared_space, false,
"Implement shared heap as shared space on a main isolate.")
// TODO(12950): The next two flags only have an effect if
// V8_ENABLE_ALLOCATION_TIMEOUT is set, so we should only define them in that
......
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