Commit 34b0b686 authored by Ulan Degenbaev's avatar Ulan Degenbaev Committed by Commit Bot

[heap] Allow dereferencing of persistent handles owned by LocalHeap

Bug: v8:10315
Change-Id: I6be83e742a3ef488e09ac44a379e028592a5ff64
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2287493
Commit-Queue: Ulan Degenbaev <ulan@chromium.org>
Reviewed-by: 's avatarDominik Inführ <dinfuehr@chromium.org>
Cr-Commit-Position: refs/heads/master@{#68736}
parent c681125c
......@@ -35,6 +35,13 @@ bool HandleBase::IsDereferenceAllowed() const {
HeapObject heap_object = HeapObject::cast(object);
if (IsReadOnlyHeapObject(heap_object)) return true;
if (Heap::InOffThreadSpace(heap_object)) return true;
LocalHeap* local_heap = LocalHeap::Current();
if (V8_UNLIKELY(local_heap)) {
if (local_heap->ContainsPersistentHandle(location_)) {
// The current thread owns the handle and thus can dereference it.
return true;
}
}
Isolate* isolate = GetIsolateFromWritableObject(heap_object);
RootIndex root_index;
......
......@@ -40,6 +40,19 @@ void PersistentHandles::Detach() {
DCHECK_NOT_NULL(owner_);
owner_ = nullptr;
}
bool PersistentHandles::Contains(Address* location) {
auto it = ordered_blocks_.upper_bound(location);
if (it == ordered_blocks_.begin()) return false;
--it;
DCHECK_LE(*it, location);
if (*it == blocks_.back()) {
// The last block is a special case because it may have
// less than block_size_ handles.
return location < block_next_;
}
return location < *it + block_size_;
}
#endif
void PersistentHandles::AddBlock() {
......@@ -50,6 +63,10 @@ void PersistentHandles::AddBlock() {
block_next_ = block_start;
block_limit_ = block_start + block_size_;
#ifdef DEBUG
ordered_blocks_.insert(block_start);
#endif
}
Handle<Object> PersistentHandles::NewHandle(Address value) {
......
......@@ -33,6 +33,10 @@ class PersistentHandles {
V8_EXPORT_PRIVATE Handle<Object> NewHandle(Address value);
#ifdef DEBUG
bool Contains(Address* location);
#endif
private:
void AddBlock();
Address* GetHandle(Address value);
......@@ -58,6 +62,10 @@ class PersistentHandles {
PersistentHandles* prev_;
PersistentHandles* next_;
#ifdef DEBUG
std::set<Address*> ordered_blocks_;
#endif
friend class PersistentHandlesList;
friend class LocalHeap;
};
......
......@@ -65,6 +65,12 @@ std::unique_ptr<PersistentHandles> LocalHeap::DetachPersistentHandles() {
return std::move(persistent_handles_);
}
#ifdef DEBUG
bool LocalHeap::ContainsPersistentHandle(Address* location) {
return persistent_handles_ ? persistent_handles_->Contains(location) : false;
}
#endif
bool LocalHeap::IsParked() {
base::MutexGuard guard(&state_mutex_);
return state_ == ThreadState::Parked;
......
......@@ -39,6 +39,9 @@ class V8_EXPORT_PRIVATE LocalHeap {
Handle<Object> NewPersistentHandle(Address value);
std::unique_ptr<PersistentHandles> DetachPersistentHandles();
#ifdef DEBUG
bool ContainsPersistentHandle(Address* location);
#endif
bool IsParked();
......
......@@ -112,6 +112,26 @@ TEST(CreatePersistentHandles) {
ph->NewHandle(number->ptr());
}
TEST(DereferencePersistentHandle) {
CcTest::InitializeVM();
FLAG_local_heaps = true;
Isolate* isolate = CcTest::i_isolate();
std::unique_ptr<PersistentHandles> phs = isolate->NewPersistentHandles();
Handle<HeapNumber> ph;
{
HandleScope handle_scope(isolate);
Handle<HeapNumber> number = isolate->factory()->NewHeapNumber(42.0);
ph = Handle<HeapNumber>::cast(phs->NewHandle(number->ptr()));
}
{
LocalHeap local_heap(isolate->heap(), std::move(phs));
CHECK_EQ(42, ph->value());
DisallowHandleDereference disallow_scope;
CHECK_EQ(42, ph->value());
}
}
} // anonymous namespace
} // namespace internal
......
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