Commit bebb2bdc authored by Ulan Degenbaev's avatar Ulan Degenbaev Committed by Commit Bot

[heap] Allow LocalHeap on the main thread

This changes the safepoint scope to skip LocalHeap that is active
for the current thread to avoid deadlocking.

Bug: v8:10315
Change-Id: I45e80ae66d0dbbe768107aa9cf0603204c644d9f
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2289983Reviewed-by: 's avatarDominik Inführ <dinfuehr@chromium.org>
Commit-Queue: Ulan Degenbaev <ulan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#68769}
parent 72bd81c0
...@@ -23,17 +23,25 @@ void GlobalSafepoint::EnterSafepointScope() { ...@@ -23,17 +23,25 @@ void GlobalSafepoint::EnterSafepointScope() {
if (!FLAG_local_heaps) return; if (!FLAG_local_heaps) return;
if (++active_safepoint_scopes_ > 1) return; if (++active_safepoint_scopes_ > 1) return;
local_heaps_mutex_.Lock(); local_heaps_mutex_.Lock();
local_heap_of_this_thread_ = LocalHeap::Current();
barrier_.Arm(); barrier_.Arm();
for (LocalHeap* current = local_heaps_head_; current; for (LocalHeap* current = local_heaps_head_; current;
current = current->next_) { current = current->next_) {
if (current == local_heap_of_this_thread_) {
continue;
}
current->RequestSafepoint(); current->RequestSafepoint();
} }
for (LocalHeap* current = local_heaps_head_; current; for (LocalHeap* current = local_heaps_head_; current;
current = current->next_) { current = current->next_) {
if (current == local_heap_of_this_thread_) {
continue;
}
current->state_mutex_.Lock(); current->state_mutex_.Lock();
while (current->state_ == LocalHeap::ThreadState::Running) { while (current->state_ == LocalHeap::ThreadState::Running) {
...@@ -48,13 +56,19 @@ void GlobalSafepoint::LeaveSafepointScope() { ...@@ -48,13 +56,19 @@ void GlobalSafepoint::LeaveSafepointScope() {
DCHECK_GT(active_safepoint_scopes_, 0); DCHECK_GT(active_safepoint_scopes_, 0);
if (--active_safepoint_scopes_ > 0) return; if (--active_safepoint_scopes_ > 0) return;
DCHECK_EQ(local_heap_of_this_thread_, LocalHeap::Current());
for (LocalHeap* current = local_heaps_head_; current; for (LocalHeap* current = local_heaps_head_; current;
current = current->next_) { current = current->next_) {
if (current == local_heap_of_this_thread_) {
continue;
}
current->state_mutex_.Unlock(); current->state_mutex_.Unlock();
} }
barrier_.Disarm(); barrier_.Disarm();
local_heap_of_this_thread_ = nullptr;
local_heaps_mutex_.Unlock(); local_heaps_mutex_.Unlock();
} }
......
...@@ -77,6 +77,8 @@ class GlobalSafepoint { ...@@ -77,6 +77,8 @@ class GlobalSafepoint {
int active_safepoint_scopes_; int active_safepoint_scopes_;
LocalHeap* local_heap_of_this_thread_;
friend class SafepointScope; friend class SafepointScope;
friend class LocalHeap; friend class LocalHeap;
friend class PersistentHandles; friend class PersistentHandles;
......
...@@ -7141,6 +7141,22 @@ HEAP_TEST(GCDuringOffThreadMergeWithTransferHandle) { ...@@ -7141,6 +7141,22 @@ HEAP_TEST(GCDuringOffThreadMergeWithTransferHandle) {
CHECK_EQ(transfer_handle.ToHandle()->length(), 10); CHECK_EQ(transfer_handle.ToHandle()->length(), 10);
} }
TEST(GarbageCollectionWithLocalHeap) {
FLAG_local_heaps = true;
ManualGCScope manual_gc_scope;
CcTest::InitializeVM();
Heap* heap = CcTest::i_isolate()->heap();
LocalHeap local_heap(heap);
CcTest::CollectGarbage(OLD_SPACE);
{
ParkedScope parked_scope(&local_heap);
CcTest::CollectGarbage(OLD_SPACE);
}
CcTest::CollectGarbage(OLD_SPACE);
}
} // namespace heap } // namespace heap
} // namespace internal } // namespace internal
} // namespace v8 } // namespace v8
......
...@@ -138,5 +138,24 @@ TEST_F(SafepointTest, StopRunningThreads) { ...@@ -138,5 +138,24 @@ TEST_F(SafepointTest, StopRunningThreads) {
CHECK_EQ(safepoint_count, kRuns * kSafepoints); CHECK_EQ(safepoint_count, kRuns * kSafepoints);
} }
TEST_F(SafepointTest, SkipLocalHeapOfThisThread) {
Heap* heap = i_isolate()->heap();
FLAG_local_heaps = true;
LocalHeap local_heap(heap);
{
SafepointScope scope(heap);
local_heap.Safepoint();
}
{
ParkedScope parked_scope(&local_heap);
SafepointScope scope(heap);
local_heap.Safepoint();
}
{
SafepointScope scope(heap);
local_heap.Safepoint();
}
}
} // namespace internal } // namespace internal
} // namespace v8 } // namespace v8
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