[heap] Make shared space iterable in Heap::MakeHeapIterable

In order to be able to iterate all objects in the heap (including
SHARED_SPACE), all LABs in the shared space need to be iterable. For this reason the HeapObjectIterator needs to perform a global safepoint for the shared heap isolate.

Bug: v8:13267
Change-Id: I2b7583fac0564f8b98b74607404be851fde1281f
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3978091
Reviewed-by: Michael Lippautz <mlippautz@chromium.org>
Commit-Queue: Dominik Inführ <dinfuehr@chromium.org>
Cr-Commit-Position: refs/heads/main@{#83939}
This commit is contained in:
Dominik Inführ 2022-10-25 18:41:25 +02:00 committed by V8 LUCI CQ
parent b45f353ccd
commit dca313554b
5 changed files with 48 additions and 5 deletions

View File

@ -3554,6 +3554,12 @@ void Heap::MakeHeapIterable() {
local_heap->MakeLinearAllocationAreaIterable();
});
if (isolate()->is_shared_space_isolate()) {
isolate()->global_safepoint()->IterateClientIsolates([](Isolate* client) {
client->heap()->MakeSharedLinearAllocationAreasIterable();
});
}
PagedSpaceIterator spaces(this);
for (PagedSpace* space = spaces.Next(); space != nullptr;
space = spaces.Next()) {
@ -3602,6 +3608,20 @@ void Heap::FreeMainThreadSharedLinearAllocationAreas() {
main_thread_local_heap()->FreeSharedLinearAllocationArea();
}
void Heap::MakeSharedLinearAllocationAreasIterable() {
if (!isolate()->has_shared_heap()) return;
safepoint()->IterateLocalHeaps([](LocalHeap* local_heap) {
local_heap->MakeSharedLinearAllocationAreaIterable();
});
if (v8_flags.shared_space && shared_space_allocator_) {
shared_space_allocator_->MakeLinearAllocationAreaIterable();
}
main_thread_local_heap()->MakeSharedLinearAllocationAreaIterable();
}
void Heap::MarkSharedLinearAllocationAreasBlack() {
DCHECK(v8_flags.shared_space);
if (shared_space_allocator_) {
@ -4425,6 +4445,7 @@ bool Heap::IsValidAllocationSpace(AllocationSpace space) {
#ifdef DEBUG
void Heap::VerifyCountersAfterSweeping() {
MakeHeapIterable();
PagedSpaceIterator spaces(this);
for (PagedSpace* space = spaces.Next(); space != nullptr;
space = spaces.Next()) {
@ -6398,7 +6419,10 @@ class UnreachableObjectsFilter : public HeapObjectsFilter {
HeapObjectIterator::HeapObjectIterator(
Heap* heap, HeapObjectIterator::HeapObjectsFiltering filtering)
: heap_(heap),
safepoint_scope_(std::make_unique<IsolateSafepointScope>(heap)),
safepoint_scope_(std::make_unique<SafepointScope>(
heap->isolate(), heap->isolate()->is_shared_heap_isolate()
? SafepointKind::kGlobal
: SafepointKind::kIsolate)),
filtering_(filtering),
filter_(nullptr),
space_iterator_(nullptr),

View File

@ -105,7 +105,6 @@ class HeapObjectAllocationTracker;
class HeapObjectsFilter;
class HeapStats;
class Isolate;
class IsolateSafepointScope;
class JSFinalizationRegistry;
class LinearAllocationArea;
class LocalEmbedderHeapTracer;
@ -124,6 +123,7 @@ class PagedNewSpace;
class ReadOnlyHeap;
class RootVisitor;
class RwxMemoryWriteScope;
class SafepointScope;
class ScavengeJob;
class Scavenger;
class ScavengerCollector;
@ -1777,6 +1777,9 @@ class Heap {
// Free all shared LABs.
void FreeSharedLinearAllocationAreas();
// Makes all shared LABs iterable.
void MakeSharedLinearAllocationAreasIterable();
// Free all shared LABs of main thread.
void FreeMainThreadSharedLinearAllocationAreas();
@ -2751,7 +2754,7 @@ class V8_EXPORT_PRIVATE HeapObjectIterator {
HeapObject NextObject();
Heap* heap_;
std::unique_ptr<IsolateSafepointScope> safepoint_scope_;
std::unique_ptr<SafepointScope> safepoint_scope_;
HeapObjectsFiltering filtering_;
HeapObjectsFilter* filter_;
// Space iterator for iterating all the spaces.

View File

@ -358,6 +358,12 @@ void LocalHeap::MakeLinearAllocationAreaIterable() {
code_space_allocator_->MakeLinearAllocationAreaIterable();
}
void LocalHeap::MakeSharedLinearAllocationAreaIterable() {
if (shared_old_space_allocator_) {
shared_old_space_allocator_->MakeLinearAllocationAreaIterable();
}
}
void LocalHeap::MarkLinearAllocationAreaBlack() {
old_space_allocator_->MarkLinearAllocationAreaBlack();
code_space_allocator_->MarkLinearAllocationAreaBlack();

View File

@ -130,6 +130,9 @@ class V8_EXPORT_PRIVATE LocalHeap {
// iterable heap.
void MakeLinearAllocationAreaIterable();
// Makes the shared LAB iterable.
void MakeSharedLinearAllocationAreaIterable();
// Fetches a pointer to the local heap from the thread local storage.
// It is intended to be used in handle and write barrier code where it is
// difficult to get a pointer to the current instance of local heap otherwise.

View File

@ -5113,8 +5113,15 @@ UNINITIALIZED_TEST(SharedStrings) {
Isolate* i_isolate2 = reinterpret_cast<Isolate*>(isolate2);
CHECK_EQ(i_isolate1->string_table(), i_isolate2->string_table());
CheckObjectsAreInSharedHeap(i_isolate1);
CheckObjectsAreInSharedHeap(i_isolate2);
{
ParkedScope parked(i_isolate2->main_thread_local_heap());
CheckObjectsAreInSharedHeap(i_isolate1);
}
{
ParkedScope parked(i_isolate1->main_thread_local_heap());
CheckObjectsAreInSharedHeap(i_isolate2);
}
{
// Because both isolate1 and isolate2 are considered running on the main