Commit 57cdda9e authored by Dominik Inführ's avatar Dominik Inführ Committed by Commit Bot

[heap] Test aborting evacuation with invalidation

When aborting evacuation of a page, the GC also needs to take care
of invalidated objects and recorded slots on the page. Add a test
to ensure that future changes do not break this behavior.

Bug: chromium:1012081
Change-Id: I110db67157e4b8c7fdb4d1061e9df6955b532a70
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1855758Reviewed-by: 's avatarUlan Degenbaev <ulan@chromium.org>
Commit-Queue: Dominik Inführ <dinfuehr@chromium.org>
Cr-Commit-Position: refs/heads/master@{#64234}
parent 0cd2f082
......@@ -35,6 +35,7 @@ bool InvalidatedSlotsFilter::IsValid(Address slot) {
HeapObject invalidated_object = HeapObject::FromAddress(invalidated_start_);
if (invalidated_size_ == 0) {
DCHECK(invalidated_object.map().IsMap());
invalidated_size_ = invalidated_object.Size();
}
......
......@@ -14,6 +14,7 @@
V(CompactionFullAbortedPage) \
V(CompactionPartiallyAbortedPage) \
V(CompactionPartiallyAbortedPageIntraAbortedPointers) \
V(CompactionPartiallyAbortedPageWithInvalidatedSlots) \
V(CompactionPartiallyAbortedPageWithStoreBufferEntries) \
V(CompactionSpaceDivideMultiplePages) \
V(CompactionSpaceDivideSinglePage) \
......
......@@ -6,6 +6,7 @@
#include "src/heap/factory.h"
#include "src/heap/heap-inl.h"
#include "src/heap/mark-compact.h"
#include "src/heap/remembered-set.h"
#include "src/objects/objects-inl.h"
#include "test/cctest/cctest.h"
#include "test/cctest/heap/heap-tester.h"
......@@ -171,6 +172,81 @@ HEAP_TEST(CompactionPartiallyAbortedPage) {
}
}
HEAP_TEST(CompactionPartiallyAbortedPageWithInvalidatedSlots) {
if (FLAG_never_compact) return;
// Test evacuating a page partially when it contains recorded
// slots and invalidated objects.
// Disable concurrent sweeping to ensure memory is in an expected state, i.e.,
// we can reach the state of a half aborted page.
ManualGCScope manual_gc_scope;
FLAG_manual_evacuation_candidates_selection = true;
const int objects_per_page = 10;
const int object_size = GetObjectSize(objects_per_page);
CcTest::InitializeVM();
Isolate* isolate = CcTest::i_isolate();
Heap* heap = isolate->heap();
{
HandleScope scope1(isolate);
heap::SealCurrentObjects(heap);
{
HandleScope scope2(isolate);
// Fill another page with objects of size {object_size} (last one is
// properly adjusted).
CHECK(heap->old_space()->Expand());
auto compaction_page_handles = heap::CreatePadding(
heap,
static_cast<int>(MemoryChunkLayout::AllocatableMemoryInDataPage()),
AllocationType::kOld, object_size);
Page* to_be_aborted_page =
Page::FromHeapObject(*compaction_page_handles.front());
for (Handle<FixedArray> object : compaction_page_handles) {
CHECK_EQ(Page::FromHeapObject(*object), to_be_aborted_page);
for (int i = 0; i < object->length(); i++) {
RememberedSet<OLD_TO_NEW>::Insert<AccessMode::ATOMIC>(
to_be_aborted_page, object->RawFieldOfElementAt(i).address());
}
}
// First object is going to be evacuated.
to_be_aborted_page->RegisterObjectWithInvalidatedSlots<OLD_TO_NEW>(
*compaction_page_handles.front());
// Last object is NOT going to be evacuated.
// This happens since not all objects fit on the only other page in the
// old space, the GC isn't allowed to allocate another page.
to_be_aborted_page->RegisterObjectWithInvalidatedSlots<OLD_TO_NEW>(
*compaction_page_handles.back());
to_be_aborted_page->SetFlag(
MemoryChunk::FORCE_EVACUATION_CANDIDATE_FOR_TESTING);
{
// Add another page that is filled with {num_objects} objects of size
// {object_size}.
HandleScope scope3(isolate);
CHECK(heap->old_space()->Expand());
const int num_objects = 3;
std::vector<Handle<FixedArray>> page_to_fill_handles =
heap::CreatePadding(heap, object_size * num_objects,
AllocationType::kOld, object_size);
Page* page_to_fill =
Page::FromAddress(page_to_fill_handles.front()->address());
heap->set_force_oom(true);
CcTest::CollectAllGarbage();
heap->mark_compact_collector()->EnsureSweepingCompleted();
CHECK_EQ(Page::FromHeapObject(*compaction_page_handles.front()),
page_to_fill);
CHECK_EQ(Page::FromHeapObject(*compaction_page_handles.back()),
to_be_aborted_page);
}
}
}
}
HEAP_TEST(CompactionPartiallyAbortedPageIntraAbortedPointers) {
if (FLAG_never_compact) return;
......
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