Commit fc2d1d09 authored by Jake Hughes's avatar Jake Hughes Committed by Commit Bot

[heap] Add flag for pinning pages

In order to support conservative stack scanning, we need to be able to
pin pages if they're pointed to by an ambiguous pointer. This CL lets us
do this by providing an IS_PINNED flag which, when enabled, prevents a
page from being selected as an evacuation candidate during compaction.

Bug: v8:10614
Change-Id: I45d1c74b83aad1b56e078cc270749a0aee804716
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2278465
Commit-Queue: Jake Hughes <jakehughes@google.com>
Reviewed-by: 's avatarMichael Lippautz <mlippautz@chromium.org>
Reviewed-by: 's avatarAnton Bikineev <bikineev@chromium.org>
Reviewed-by: 's avatarUlan Degenbaev <ulan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#68815}
parent ce4755a1
......@@ -101,6 +101,11 @@ class BasicMemoryChunk {
// in garbage collection. This is used instead of owner for identity
// checking since read-only chunks have no owner once they are detached.
READ_ONLY_HEAP = 1u << 21,
// The memory chunk is pinned in memory and can't be moved. This is likely
// because there exists a potential pointer to somewhere in the chunk which
// can't be updated.
PINNED = 1u << 22,
};
static const intptr_t kAlignment =
......@@ -245,6 +250,8 @@ class BasicMemoryChunk {
return !InReadOnlySpace() || heap_ != nullptr;
}
bool IsPinned() const { return IsFlagSet(PINNED); }
bool Contains(Address addr) const {
return addr >= area_start() && addr < area_end();
}
......
......@@ -711,6 +711,13 @@ void MarkCompactCollector::CollectEvacuationCandidates(PagedSpace* space) {
if (p->NeverEvacuate() || (p == owner_of_linear_allocation_area) ||
!p->CanAllocate())
continue;
if (p->IsPinned()) {
DCHECK(
!p->IsFlagSet(MemoryChunk::FORCE_EVACUATION_CANDIDATE_FOR_TESTING));
continue;
}
// Invariant: Evacuation candidates are just created when marking is
// started. This means that sweeping has finished. Furthermore, at the end
// of a GC all evacuation candidates are cleared and their slot buffers are
......
......@@ -61,7 +61,8 @@
V(RegressMissingWriteBarrierInAllocate) \
V(WriteBarrier_Marking) \
V(WriteBarrier_MarkingExtension) \
V(WriteBarriersInCopyJSObject)
V(WriteBarriersInCopyJSObject) \
V(DoNotEvacuatePinnedPages)
#define HEAP_TEST(Name) \
CcTest register_test_##Name(v8::internal::heap::HeapTester::Test##Name, \
......
......@@ -207,6 +207,47 @@ HEAP_TEST(MarkCompactCollector) {
}
}
HEAP_TEST(DoNotEvacuatePinnedPages) {
if (FLAG_never_compact || !FLAG_single_generation) return;
FLAG_always_compact = true;
CcTest::InitializeVM();
Isolate* isolate = CcTest::i_isolate();
v8::HandleScope sc(CcTest::isolate());
Heap* heap = isolate->heap();
heap::SealCurrentObjects(heap);
auto handles = heap::CreatePadding(
heap, static_cast<int>(MemoryChunkLayout::AllocatableMemoryInDataPage()),
AllocationType::kOld);
Page* page = Page::FromHeapObject(*handles.front());
CHECK(heap->InSpace(*handles.front(), OLD_SPACE));
page->SetFlag(MemoryChunk::PINNED);
CcTest::CollectAllGarbage();
heap->mark_compact_collector()->EnsureSweepingCompleted();
// The pinned flag should prevent the page from moving.
for (Handle<FixedArray> object : handles) {
CHECK_EQ(page, Page::FromHeapObject(*object));
}
page->ClearFlag(MemoryChunk::PINNED);
CcTest::CollectAllGarbage();
heap->mark_compact_collector()->EnsureSweepingCompleted();
// always_compact ensures that this page is an evacuation candidate, so with
// the pin flag cleared compaction should now move it.
for (Handle<FixedArray> object : handles) {
CHECK_NE(page, Page::FromHeapObject(*object));
}
}
// TODO(1600): compaction of map space is temporary removed from GC.
#if 0
......
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