Commit c0ed24a0 authored by Santiago Aboy Solanes's avatar Santiago Aboy Solanes Committed by Commit Bot

[heap] Allow thread's own LocalHandles to be dereferenced

This CL allows LocalHandles to be dereferenced by the same thread that
created them, even if we have a DisallowHandleDereference scope.

Bug: v8:7790
Change-Id: Ie227aaa4152c887d0d9c913dfa35217166726614
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2316111Reviewed-by: 's avatarUlan Degenbaev <ulan@chromium.org>
Reviewed-by: 's avatarDominik Inführ <dinfuehr@chromium.org>
Commit-Queue: Santiago Aboy Solanes <solanes@chromium.org>
Cr-Commit-Position: refs/heads/master@{#69068}
parent 754368ca
...@@ -47,7 +47,8 @@ bool HandleBase::IsDereferenceAllowed() const { ...@@ -47,7 +47,8 @@ bool HandleBase::IsDereferenceAllowed() const {
// Local heap can't access handles when parked // Local heap can't access handles when parked
if (!local_heap->IsHandleDereferenceAllowed()) return false; if (!local_heap->IsHandleDereferenceAllowed()) return false;
if (local_heap->ContainsPersistentHandle(location_)) { if (local_heap->ContainsPersistentHandle(location_) ||
local_heap->ContainsLocalHandle(location_)) {
// The current thread owns the handle and thus can dereference it. // The current thread owns the handle and thus can dereference it.
return true; return true;
} }
......
...@@ -28,6 +28,24 @@ void LocalHandles::Iterate(RootVisitor* visitor) { ...@@ -28,6 +28,24 @@ void LocalHandles::Iterate(RootVisitor* visitor) {
} }
} }
#ifdef DEBUG
bool LocalHandles::Contains(Address* location) {
// We have to search in all blocks since they have no guarantee of order.
for (auto it = blocks_.begin(); it != blocks_.end(); ++it) {
Address* lower_bound = *it;
// The last block is a special case because it may have less than
// block_size_ handles.
Address* upper_bound = lower_bound != blocks_.back()
? lower_bound + kHandleBlockSize
: scope_.next;
if (lower_bound <= location && location < upper_bound) {
return true;
}
}
return false;
}
#endif
Address* LocalHandles::AddBlock() { Address* LocalHandles::AddBlock() {
DCHECK_EQ(scope_.next, scope_.limit); DCHECK_EQ(scope_.next, scope_.limit);
Address* block = NewArray<Address>(kHandleBlockSize); Address* block = NewArray<Address>(kHandleBlockSize);
......
...@@ -22,6 +22,10 @@ class LocalHandles { ...@@ -22,6 +22,10 @@ class LocalHandles {
void Iterate(RootVisitor* visitor); void Iterate(RootVisitor* visitor);
#ifdef DEBUG
bool Contains(Address* location);
#endif
private: private:
HandleScopeData scope_; HandleScopeData scope_;
std::vector<Address*> blocks_; std::vector<Address*> blocks_;
......
...@@ -69,6 +69,10 @@ bool LocalHeap::ContainsPersistentHandle(Address* location) { ...@@ -69,6 +69,10 @@ bool LocalHeap::ContainsPersistentHandle(Address* location) {
return persistent_handles_ ? persistent_handles_->Contains(location) : false; return persistent_handles_ ? persistent_handles_->Contains(location) : false;
} }
bool LocalHeap::ContainsLocalHandle(Address* location) {
return handles_ ? handles_->Contains(location) : false;
}
bool LocalHeap::IsHandleDereferenceAllowed() { bool LocalHeap::IsHandleDereferenceAllowed() {
DCHECK_EQ(LocalHeap::Current(), this); DCHECK_EQ(LocalHeap::Current(), this);
return state_ == ThreadState::Running; return state_ == ThreadState::Running;
......
...@@ -44,6 +44,7 @@ class V8_EXPORT_PRIVATE LocalHeap { ...@@ -44,6 +44,7 @@ class V8_EXPORT_PRIVATE LocalHeap {
std::unique_ptr<PersistentHandles> DetachPersistentHandles(); std::unique_ptr<PersistentHandles> DetachPersistentHandles();
#ifdef DEBUG #ifdef DEBUG
bool ContainsPersistentHandle(Address* location); bool ContainsPersistentHandle(Address* location);
bool ContainsLocalHandle(Address* location);
bool IsHandleDereferenceAllowed(); bool IsHandleDereferenceAllowed();
#endif #endif
......
...@@ -94,6 +94,30 @@ TEST(CreateLocalHandles) { ...@@ -94,6 +94,30 @@ TEST(CreateLocalHandles) {
thread->Join(); thread->Join();
} }
TEST(DereferenceLocalHandle) {
CcTest::InitializeVM();
FLAG_local_heaps = true;
Isolate* isolate = CcTest::i_isolate();
// Create a PersistentHandle to create the LocalHandle, and thus not have a
// HandleScope present to override the LocalHandleScope.
std::unique_ptr<PersistentHandles> phs = isolate->NewPersistentHandles();
Handle<HeapNumber> ph;
{
HandleScope handle_scope(isolate);
Handle<HeapNumber> number = isolate->factory()->NewHeapNumber(42.0);
ph = phs->NewHandle(number);
}
{
LocalHeap local_heap(isolate->heap(), std::move(phs));
LocalHandleScope scope(&local_heap);
Handle<HeapNumber> local_number = handle(*ph, &local_heap);
CHECK_EQ(42, local_number->value());
DisallowHandleDereference disallow_scope;
CHECK_EQ(42, local_number->value());
}
}
} // anonymous namespace } // anonymous namespace
} // namespace internal } // 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