Commit 286d3394 authored by Irina Yatsenko's avatar Irina Yatsenko Committed by Commit Bot

Three basic cctests for tracking of old to new pointers

Change-Id: I162b3cac024fba180ff191c8497da9a958c38167
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1797657
Commit-Queue: Irina Yatsenko <irinayat@microsoft.com>
Reviewed-by: 's avatarDominik Inführ <dinfuehr@chromium.org>
Reviewed-by: 's avatarMichael Lippautz <mlippautz@chromium.org>
Cr-Commit-Position: refs/heads/master@{#63731}
parent 9a2bc761
......@@ -849,7 +849,7 @@ class Heap {
void SetIsMarkingFlag(uint8_t flag) { is_marking_flag_ = flag; }
Address* store_buffer_top_address();
V8_EXPORT_PRIVATE Address* store_buffer_top_address();
static intptr_t store_buffer_mask_constant();
static Address store_buffer_overflow_function_address();
......
......@@ -42,6 +42,9 @@
V(Promotion) \
V(Regression39128) \
V(ResetWeakHandle) \
V(StoreBuffer_CreateFromOldToYoung) \
V(StoreBuffer_Overflow) \
V(StoreBuffer_NotUsedOnAgingObjectWithRefsToYounger) \
V(StressHandles) \
V(TestMemoryReducerSampleJsCalls) \
V(TestSizeOfObjects) \
......
......@@ -10,6 +10,7 @@
#include "src/heap/heap.h"
#include "src/heap/invalidated-slots-inl.h"
#include "src/heap/invalidated-slots.h"
#include "src/heap/store-buffer.h"
#include "test/cctest/cctest.h"
#include "test/cctest/heap/heap-tester.h"
#include "test/cctest/heap/heap-utils.h"
......@@ -48,6 +49,113 @@ Page* HeapTester::AllocateByteArraysOnPage(
return page;
}
// Fill new space with objects that become garbage immediately. This ensures
// that the next Scavenge has work to do but after it there is still available
// new space.
static void SimulateReclaimableFullNewSpace(Isolate* isolate) {
HandleScope scope_temp(isolate);
heap::SimulateFullSpace(isolate->heap()->new_space());
}
HEAP_TEST(StoreBuffer_CreateFromOldToYoung) {
CcTest::InitializeVM();
Isolate* isolate = CcTest::i_isolate();
Factory* factory = isolate->factory();
Heap* heap = isolate->heap();
HandleScope scope(isolate);
const int n = 10;
Handle<FixedArray> old = factory->NewFixedArray(n, AllocationType::kOld);
// Fill the array with refs to both old and new targets.
{
const auto prev_top = *(heap->store_buffer_top_address());
HandleScope scope_inner(isolate);
intptr_t expected_slots_count = 0;
// Add refs from old to new.
for (int i = 0; i < n / 2; i++) {
Handle<Object> number = factory->NewHeapNumber(i);
old->set(i, *number);
expected_slots_count++;
}
// Add refs from old to old.
for (int i = n / 2; i < n; i++) {
Handle<Object> number = factory->NewHeapNumber(i, AllocationType::kOld);
old->set(i, *number);
}
// All old to new refs should have been captured and only them.
const auto new_top = *(heap->store_buffer_top_address());
const intptr_t added_slots_count =
(new_top - prev_top) / kSystemPointerSize;
CHECK_EQ(expected_slots_count, added_slots_count);
}
// The old to new refs serve as roots during scavenge.
SimulateReclaimableFullNewSpace(isolate);
CcTest::CollectGarbage(i::NEW_SPACE);
CHECK(old->get(0).IsHeapNumber());
// GC flushes the store buffer into remembered sets.
CHECK(heap->store_buffer()->Empty());
}
HEAP_TEST(StoreBuffer_Overflow) {
CcTest::InitializeVM();
Isolate* isolate = CcTest::i_isolate();
Factory* factory = isolate->factory();
// Add enough refs from old to new to cause overflow of both buffer chunks.
const int n = 2 * StoreBuffer::kStoreBufferSize / kSystemPointerSize + 1;
HandleScope scope(isolate);
Handle<FixedArray> old = factory->NewFixedArray(n, AllocationType::kOld);
for (int i = 0; i < n; i++) {
Handle<Object> number = factory->NewHeapNumber(i);
old->set(i, *number);
}
// No test validations, the buffer flipping code triggered by the overflow
// self-validates with asserts.
}
HEAP_TEST(StoreBuffer_NotUsedOnAgingObjectWithRefsToYounger) {
CcTest::InitializeVM();
Isolate* isolate = CcTest::i_isolate();
Factory* factory = isolate->factory();
Heap* heap = isolate->heap();
const int n = 10;
HandleScope scope(isolate);
Handle<FixedArray> arr = factory->NewFixedArray(n);
// Transition the array into the older new tier.
SimulateReclaimableFullNewSpace(isolate);
CcTest::CollectGarbage(i::NEW_SPACE);
CHECK(Heap::InYoungGeneration(*arr));
// Fill the array with younger objects.
{
const auto prev_top = *(heap->store_buffer_top_address());
HandleScope scope_inner(isolate);
for (int i = 0; i < n; i++) {
Handle<Object> number = factory->NewHeapNumber(i);
arr->set(i, *number);
}
// The references aren't crossing generations yet so none should be tracked.
CHECK_EQ(prev_top, *(heap->store_buffer_top_address()));
}
// Promote the array into old, its elements are still in new, the old to new
// refs are inserted directly into the remembered sets during GC.
SimulateReclaimableFullNewSpace(isolate);
CcTest::CollectGarbage(i::NEW_SPACE);
CHECK(!Heap::InYoungGeneration(*arr));
CHECK(Heap::InYoungGeneration(arr->get(n / 2)));
CHECK(heap->store_buffer()->Empty());
}
HEAP_TEST(InvalidatedSlotsNoInvalidatedRanges) {
CcTest::InitializeVM();
Heap* heap = CcTest::heap();
......
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