[offthread] Add InOffThreadSpace checks for Isolate access

Make sure we can't get the Isolate for writable off-thread space
objects, to avoid leaking the Isolate into off-thread compilation.

Bug: chromium:1011762
Change-Id: I5c4316e751736b8c8235fdcc8949d52b78313f38
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2043791
Commit-Queue: Leszek Swirski <leszeks@chromium.org>
Commit-Queue: Igor Sheludko <ishell@chromium.org>
Auto-Submit: Leszek Swirski <leszeks@chromium.org>
Reviewed-by: Igor Sheludko <ishell@chromium.org>
Reviewed-by: Ulan Degenbaev <ulan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#66194}
This commit is contained in:
Leszek Swirski 2020-02-10 10:23:49 +01:00 committed by Commit Bot
parent 4b1447e4bb
commit 98129efc92
6 changed files with 50 additions and 9 deletions

View File

@ -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

View File

@ -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();
}

View File

@ -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<PagedSpace*>(owner)->is_off_thread_space();
}
if (owner->identity() == LO_SPACE) {
return static_cast<LargeObjectSpace*>(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.

View File

@ -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);

View File

@ -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);

View File

@ -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<ObjectIterator> 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;