diff --git a/include/v8-internal.h b/include/v8-internal.h index 3814d13895..3f2a594750 100644 --- a/include/v8-internal.h +++ b/include/v8-internal.h @@ -308,10 +308,10 @@ constexpr uint64_t kExternalPointerTagShift = 48; enum ExternalPointerTag : uint64_t { kExternalPointerNullTag = MAKE_TAG(0b0000000000000000), kExternalPointerFreeEntryTag = MAKE_TAG(0b0111111100000000), - kWaiterQueueNodeTag = MAKE_TAG(0b1000000111111111), // Begin shared external object tags // Update kSharedExternalObjectMask and kSharedExternalObjectTag when new // tags are shared. + kWaiterQueueNodeTag = MAKE_TAG(0b1000000111111111), kExternalStringResourceTag = MAKE_TAG(0b1000001011111111), kExternalStringResourceDataTag = MAKE_TAG(0b1000001101111111), // End shared external object tags @@ -330,8 +330,8 @@ enum ExternalPointerTag : uint64_t { // Shared external pointers can be access from shared isolates. They are stored // in a shared external pointer table. -constexpr uint64_t kSharedExternalObjectMask = MAKE_TAG(0b1111111001111111); -constexpr uint64_t kSharedExternalObjectTag = MAKE_TAG(0b1000001001111111); +constexpr uint64_t kSharedExternalObjectMask = MAKE_TAG(0b1111110001111111); +constexpr uint64_t kSharedExternalObjectTag = MAKE_TAG(0b1000000001111111); #undef MAKE_TAG diff --git a/src/execution/isolate.cc b/src/execution/isolate.cc index 9d804eb033..ffb5c26519 100644 --- a/src/execution/isolate.cc +++ b/src/execution/isolate.cc @@ -3559,7 +3559,7 @@ void Isolate::Deinit() { #ifdef V8_SANDBOXED_EXTERNAL_POINTERS external_pointer_table().TearDown(); - if (OwnsStringTables()) { + if (owns_shareable_data()) { shared_external_pointer_table().TearDown(); delete isolate_data_.shared_external_pointer_table_; isolate_data_.shared_external_pointer_table_ = nullptr; @@ -4120,7 +4120,7 @@ bool Isolate::Init(SnapshotData* startup_snapshot_data, #ifdef V8_SANDBOXED_EXTERNAL_POINTERS external_pointer_table().Init(this); - if (OwnsStringTables()) { + if (owns_shareable_data()) { isolate_data_.shared_external_pointer_table_ = new ExternalPointerTable(); shared_external_pointer_table().Init(this); } else { @@ -5762,19 +5762,18 @@ void Isolate::DetachFromSharedIsolate() { ExternalPointer_t Isolate::EncodeWaiterQueueNodeAsExternalPointer( Address node) { DCHECK_NE(kNullAddress, node); - Isolate* shared = shared_isolate(); uint32_t index; ExternalPointer_t ext; if (waiter_queue_node_external_pointer_.IsJust()) { ext = waiter_queue_node_external_pointer_.FromJust(); index = ext >> kExternalPointerIndexShift; } else { - index = shared->external_pointer_table().Allocate(); + index = shared_external_pointer_table().Allocate(); ext = index << kExternalPointerIndexShift; waiter_queue_node_external_pointer_ = Just(ext); } DCHECK_NE(0, index); - shared->external_pointer_table().Set(index, node, kWaiterQueueNodeTag); + shared_external_pointer_table().Set(index, node, kWaiterQueueNodeTag); return ext; } #endif // V8_SANDBOXED_EXTERNAL_POINTERS diff --git a/src/execution/isolate.h b/src/execution/isolate.h index ddf81b352b..1eaa0b3c69 100644 --- a/src/execution/isolate.h +++ b/src/execution/isolate.h @@ -2002,10 +2002,14 @@ class V8_EXPORT_PRIVATE Isolate final : private HiddenFactory { DCHECK_NULL(shared_isolate_); DCHECK(!attached_to_shared_isolate_); shared_isolate_ = shared_isolate; + owns_shareable_data_ = false; } GlobalSafepoint* global_safepoint() const { return global_safepoint_.get(); } + bool owns_shareable_data() { return owns_shareable_data_; } + // TODO(pthier): Unify with owns_shareable_data() once the flag + // --shared-string-table is removed. bool OwnsStringTables() { return !FLAG_shared_string_table || is_shared(); } #if USE_SIMULATOR @@ -2271,6 +2275,10 @@ class V8_EXPORT_PRIVATE Isolate final : private HiddenFactory { // favor memory over runtime performance. bool memory_savings_mode_active_ = false; + // Indicates wether the isolate owns shareable data. + // Only false for client isolates attached to a shared isolate. + bool owns_shareable_data_ = true; + #ifdef V8_EXTERNAL_CODE_SPACE // Base address of the pointer compression cage containing external code // space, when external code space is enabled. diff --git a/src/heap/mark-compact.cc b/src/heap/mark-compact.cc index 7ff30f2fa9..004ce5d33c 100644 --- a/src/heap/mark-compact.cc +++ b/src/heap/mark-compact.cc @@ -2083,11 +2083,11 @@ void MarkCompactCollector::MarkObjectsFromClientHeaps() { // Custom marking for the external pointer table entry used to hold // client Isolates' WaiterQueueNode, which is used by JS mutexes and // condition variables. - DCHECK(!IsExternalPointerTagShareable(kWaiterQueueNodeTag)); + DCHECK(IsExternalPointerTagShareable(kWaiterQueueNodeTag)); ExternalPointer_t waiter_queue_ext; if (client->GetWaiterQueueNodeExternalPointer().To(&waiter_queue_ext)) { uint32_t index = waiter_queue_ext >> kExternalPointerIndexShift; - client->shared_isolate()->external_pointer_table().Mark(index); + client->shared_external_pointer_table().Mark(index); } #endif // V8_SANDBOXED_EXTERNAL_POINTERS }); @@ -2747,7 +2747,7 @@ void MarkCompactCollector::ClearNonLiveReferences() { TRACE_GC(heap()->tracer(), GCTracer::Scope::MC_SWEEP_EXTERNAL_POINTER_TABLE); isolate()->external_pointer_table().Sweep(isolate()); - if (isolate()->OwnsStringTables()) { + if (isolate()->owns_shareable_data()) { isolate()->shared_external_pointer_table().Sweep(isolate()); } } diff --git a/src/objects/js-atomics-synchronization.cc b/src/objects/js-atomics-synchronization.cc index ae229c54a4..6db6927494 100644 --- a/src/objects/js-atomics-synchronization.cc +++ b/src/objects/js-atomics-synchronization.cc @@ -22,7 +22,7 @@ namespace detail { // list per waiter (i.e. mutex or condition variable). There is a per-thread // node allocated on the stack when the thread goes to sleep during waiting. In // the case of sandboxed pointers, the access to the on-stack node is indirected -// through the shared Isolate's external pointer table. +// through the shared external pointer table. class V8_NODISCARD WaiterQueueNode final { public: template @@ -47,14 +47,13 @@ class V8_NODISCARD WaiterQueueNode final { static WaiterQueueNode* DestructivelyDecodeHead(Isolate* requester, typename T::StateT state) { #ifdef V8_SANDBOXED_EXTERNAL_POINTERS - Isolate* shared_isolate = requester->shared_isolate(); ExternalPointer_t ptr = static_cast(state & T::kWaiterQueueHeadMask); if (ptr == 0) return nullptr; // The external pointer is cleared after decoding to prevent reuse by // multiple mutexes in case of heap corruption. - return reinterpret_cast(DecodeAndClearExternalPointer( - shared_isolate, ptr, kWaiterQueueNodeTag)); + return reinterpret_cast( + DecodeAndClearExternalPointer(requester, ptr, kWaiterQueueNodeTag)); #else return base::bit_cast(state & T::kWaiterQueueHeadMask); #endif // V8_SANDBOXED_EXTERNAL_POINTERS