Reland "[heap] Allow LocalHeap on the main thread"
This is a reland of bebb2bdc06
Original change's description:
> [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/+/2289983
> Reviewed-by: Dominik Inführ <dinfuehr@chromium.org>
> Commit-Queue: Ulan Degenbaev <ulan@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#68769}
Bug: v8:10315
Tbr: dinfuehr@chromium.org
Change-Id: I1974d8b6ffffbf3244e7ede2d20d9b2d623df150
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2290851
Commit-Queue: Ulan Degenbaev <ulan@chromium.org>
Reviewed-by: Ulan Degenbaev <ulan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#68785}
This commit is contained in:
parent
921c247694
commit
e4e57d16b9
@ -23,17 +23,25 @@ void GlobalSafepoint::EnterSafepointScope() {
|
||||
if (!FLAG_local_heaps) return;
|
||||
|
||||
if (++active_safepoint_scopes_ > 1) return;
|
||||
|
||||
local_heaps_mutex_.Lock();
|
||||
local_heap_of_this_thread_ = LocalHeap::Current();
|
||||
|
||||
barrier_.Arm();
|
||||
|
||||
for (LocalHeap* current = local_heaps_head_; current;
|
||||
current = current->next_) {
|
||||
if (current == local_heap_of_this_thread_) {
|
||||
continue;
|
||||
}
|
||||
current->RequestSafepoint();
|
||||
}
|
||||
|
||||
for (LocalHeap* current = local_heaps_head_; current;
|
||||
current = current->next_) {
|
||||
if (current == local_heap_of_this_thread_) {
|
||||
continue;
|
||||
}
|
||||
current->state_mutex_.Lock();
|
||||
|
||||
while (current->state_ == LocalHeap::ThreadState::Running) {
|
||||
@ -48,13 +56,19 @@ void GlobalSafepoint::LeaveSafepointScope() {
|
||||
DCHECK_GT(active_safepoint_scopes_, 0);
|
||||
if (--active_safepoint_scopes_ > 0) return;
|
||||
|
||||
DCHECK_EQ(local_heap_of_this_thread_, LocalHeap::Current());
|
||||
|
||||
for (LocalHeap* current = local_heaps_head_; current;
|
||||
current = current->next_) {
|
||||
if (current == local_heap_of_this_thread_) {
|
||||
continue;
|
||||
}
|
||||
current->state_mutex_.Unlock();
|
||||
}
|
||||
|
||||
barrier_.Disarm();
|
||||
|
||||
local_heap_of_this_thread_ = nullptr;
|
||||
local_heaps_mutex_.Unlock();
|
||||
}
|
||||
|
||||
|
@ -77,6 +77,8 @@ class GlobalSafepoint {
|
||||
|
||||
int active_safepoint_scopes_;
|
||||
|
||||
LocalHeap* local_heap_of_this_thread_;
|
||||
|
||||
friend class SafepointScope;
|
||||
friend class LocalHeap;
|
||||
friend class PersistentHandles;
|
||||
|
@ -6770,7 +6770,7 @@ UNINITIALIZED_TEST(OutOfMemorySmallObjects) {
|
||||
#ifdef VERIFY_HEAP
|
||||
if (FLAG_verify_heap) return;
|
||||
#endif
|
||||
const size_t kOldGenerationLimit = 300 * MB;
|
||||
const size_t kOldGenerationLimit = 50 * MB;
|
||||
FLAG_max_old_space_size = kOldGenerationLimit / MB;
|
||||
v8::Isolate::CreateParams create_params;
|
||||
create_params.array_buffer_allocator = CcTest::array_buffer_allocator();
|
||||
@ -6804,7 +6804,7 @@ UNINITIALIZED_TEST(OutOfMemoryLargeObjects) {
|
||||
#ifdef VERIFY_HEAP
|
||||
if (FLAG_verify_heap) return;
|
||||
#endif
|
||||
const size_t kOldGenerationLimit = 300 * MB;
|
||||
const size_t kOldGenerationLimit = 50 * MB;
|
||||
FLAG_max_old_space_size = kOldGenerationLimit / MB;
|
||||
v8::Isolate::CreateParams create_params;
|
||||
create_params.array_buffer_allocator = CcTest::array_buffer_allocator();
|
||||
@ -6842,7 +6842,7 @@ UNINITIALIZED_TEST(RestoreHeapLimit) {
|
||||
if (FLAG_verify_heap) return;
|
||||
#endif
|
||||
ManualGCScope manual_gc_scope;
|
||||
const size_t kOldGenerationLimit = 300 * MB;
|
||||
const size_t kOldGenerationLimit = 50 * MB;
|
||||
FLAG_max_old_space_size = kOldGenerationLimit / MB;
|
||||
v8::Isolate::CreateParams create_params;
|
||||
create_params.array_buffer_allocator = CcTest::array_buffer_allocator();
|
||||
@ -7141,6 +7141,19 @@ HEAP_TEST(GCDuringOffThreadMergeWithTransferHandle) {
|
||||
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);
|
||||
}
|
||||
|
||||
} // namespace heap
|
||||
} // namespace internal
|
||||
} // namespace v8
|
||||
|
@ -138,5 +138,24 @@ TEST_F(SafepointTest, StopRunningThreads) {
|
||||
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 v8
|
||||
|
Loading…
Reference in New Issue
Block a user