diff --git a/src/execution/isolate-utils-inl.h b/src/execution/isolate-utils-inl.h index 16bc1da8fa..b3132a2591 100644 --- a/src/execution/isolate-utils-inl.h +++ b/src/execution/isolate-utils-inl.h @@ -23,8 +23,15 @@ inline const Isolate* GetIsolateForPtrCompr(HeapObject object) { } V8_INLINE Heap* GetHeapFromWritableObject(HeapObject object) { -#if defined V8_COMPRESS_POINTERS || defined V8_ENABLE_THIRD_PARTY_HEAP - return GetIsolateFromWritableObject(object)->heap(); + // Avoid using the below GetIsolateFromWritableObject because we want to be + // able to get the heap, but not the isolate, for off-thread objects. + +#if defined V8_ENABLE_THIRD_PARTY_HEAP + return Heap::GetIsolateFromWritableObject(obj)->heap(); +#elif defined V8_COMPRESS_POINTERS + Isolate* isolate = Isolate::FromRoot(GetIsolateRoot(object.ptr())); + DCHECK_NOT_NULL(isolate); + return isolate->heap(); #else heap_internals::MemoryChunk* chunk = heap_internals::MemoryChunk::FromHeapObject(object); @@ -33,6 +40,9 @@ V8_INLINE Heap* GetHeapFromWritableObject(HeapObject object) { } V8_INLINE Isolate* GetIsolateFromWritableObject(HeapObject object) { + // We don't want to allow accessing the isolate off-thread. + DCHECK(!Heap::InOffThreadSpace(object)); + #ifdef V8_ENABLE_THIRD_PARTY_HEAP return Heap::GetIsolateFromWritableObject(object); #elif defined V8_COMPRESS_POINTERS diff --git a/src/handles/handles.cc b/src/handles/handles.cc index 87c435061e..321fc0b1ba 100644 --- a/src/handles/handles.cc +++ b/src/handles/handles.cc @@ -34,11 +34,13 @@ bool HandleBase::IsDereferenceAllowed() const { if (object.IsSmi()) return true; HeapObject heap_object = HeapObject::cast(object); if (IsReadOnlyHeapObject(heap_object)) return true; - Isolate* isolate = GetIsolateFromWritableObject(heap_object); - RootIndex root_index; - if (isolate->roots_table().IsRootHandleLocation(location_, &root_index) && - RootsTable::IsImmortalImmovable(root_index)) { - return true; + if (!Heap::InOffThreadSpace(heap_object)) { + Isolate* isolate = GetIsolateFromWritableObject(heap_object); + RootIndex root_index; + if (isolate->roots_table().IsRootHandleLocation(location_, &root_index) && + RootsTable::IsImmortalImmovable(root_index)) { + return true; + } } return AllowHandleDereference::IsAllowed(); } diff --git a/src/heap/heap.cc b/src/heap/heap.cc index 3db9256bab..a82eca4ce9 100644 --- a/src/heap/heap.cc +++ b/src/heap/heap.cc @@ -2958,6 +2958,19 @@ bool Heap::CanMoveObjectStart(HeapObject object) { return Page::FromHeapObject(object)->SweepingDone(); } +// static +bool Heap::InOffThreadSpace(HeapObject heap_object) { + Space* owner = MemoryChunk::FromHeapObject(heap_object)->owner(); + if (owner->identity() == OLD_SPACE) { + // TODO(leszeks): Should we exclude compaction spaces here? + return static_cast(owner)->is_off_thread_space(); + } + if (owner->identity() == LO_SPACE) { + return static_cast(owner)->is_off_thread(); + } + return false; +} + bool Heap::IsImmovable(HeapObject object) { if (V8_ENABLE_THIRD_PARTY_HEAP_BOOL) { // TODO(steveblackburn): For now all objects are immovable. diff --git a/src/heap/heap.h b/src/heap/heap.h index 73203653d4..f98a33eb46 100644 --- a/src/heap/heap.h +++ b/src/heap/heap.h @@ -1045,6 +1045,8 @@ class Heap { static inline bool InToPage(MaybeObject object); static inline bool InToPage(HeapObject heap_object); + V8_EXPORT_PRIVATE static bool InOffThreadSpace(HeapObject heap_object); + // Returns whether the object resides in old space. inline bool InOldSpace(Object object); diff --git a/src/heap/spaces.cc b/src/heap/spaces.cc index bfa568dd29..45a9da82fc 100644 --- a/src/heap/spaces.cc +++ b/src/heap/spaces.cc @@ -4487,7 +4487,12 @@ void CodeLargeObjectSpace::RemovePage(LargePage* page, size_t object_size) { } OffThreadLargeObjectSpace::OffThreadLargeObjectSpace(Heap* heap) - : LargeObjectSpace(heap, LO_SPACE) {} + : LargeObjectSpace(heap, LO_SPACE) { +#ifdef V8_ENABLE_THIRD_PARTY_HEAP + // OffThreadLargeObjectSpace doesn't work with third-party heap. + UNREACHABLE(); +#endif +} AllocationResult OffThreadLargeObjectSpace::AllocateRaw(int object_size) { LargePage* page = AllocateLargePage(object_size, NOT_EXECUTABLE); diff --git a/src/heap/spaces.h b/src/heap/spaces.h index 9d0de53f82..003f06847c 100644 --- a/src/heap/spaces.h +++ b/src/heap/spaces.h @@ -3184,7 +3184,12 @@ class V8_EXPORT_PRIVATE OffThreadSpace : public LocalSpace { public: explicit OffThreadSpace(Heap* heap) : LocalSpace(heap, OLD_SPACE, NOT_EXECUTABLE, - LocalSpaceKind::kOffThreadSpace) {} + LocalSpaceKind::kOffThreadSpace) { +#ifdef V8_ENABLE_THIRD_PARTY_HEAP + // OffThreadSpace doesn't work with third-party heap. + UNREACHABLE(); +#endif + } protected: V8_WARN_UNUSED_RESULT bool SlowRefillLinearAllocationArea( @@ -3289,6 +3294,8 @@ class V8_EXPORT_PRIVATE LargeObjectSpace : public Space { std::unique_ptr GetObjectIterator(Heap* heap) override; + virtual bool is_off_thread() const { return false; } + #ifdef VERIFY_HEAP virtual void Verify(Isolate* isolate); #endif @@ -3393,6 +3400,8 @@ class V8_EXPORT_PRIVATE OffThreadLargeObjectSpace : public LargeObjectSpace { void FreeUnmarkedObjects() override; + bool is_off_thread() const override { return true; } + protected: // OldLargeObjectSpace can mess with OffThreadLargeObjectSpace during merging. friend class OldLargeObjectSpace;