| Index: test/cctest/heap/test-spaces.cc
|
| diff --git a/test/cctest/heap/test-spaces.cc b/test/cctest/heap/test-spaces.cc
|
| index 818716a53dda21da98a30616fa9529f1086ba2d8..f485e7ffef9372f5ad5f3a1909808339e71afdb3 100644
|
| --- a/test/cctest/heap/test-spaces.cc
|
| +++ b/test/cctest/heap/test-spaces.cc
|
| @@ -36,6 +36,7 @@
|
| #include "src/v8.h"
|
| #include "test/cctest/cctest.h"
|
| #include "test/cctest/heap/heap-tester.h"
|
| +#include "test/cctest/heap/heap-utils.h"
|
|
|
| namespace v8 {
|
| namespace internal {
|
| @@ -482,8 +483,7 @@ TEST(LargeObjectSpace) {
|
| CHECK(lo->AllocateRaw(lo_size, NOT_EXECUTABLE).IsRetry());
|
| }
|
|
|
| -
|
| -TEST(SizeOfFirstPageIsLargeEnough) {
|
| +TEST(SizeOfInitialHeap) {
|
| if (i::FLAG_always_opt) return;
|
| // Bootstrapping without a snapshot causes more allocations.
|
| CcTest::InitializeVM();
|
| @@ -499,22 +499,31 @@ TEST(SizeOfFirstPageIsLargeEnough) {
|
| return;
|
| }
|
|
|
| - // If this test fails due to enabling experimental natives that are not part
|
| - // of the snapshot, we may need to adjust CalculateFirstPageSizes.
|
| + // The limit for each space for an empty isolate containing just the
|
| + // snapshot.
|
| + const size_t kMaxInitialSizePerSpace = 2 * MB;
|
|
|
| - // Freshly initialized VM gets by with one page per space.
|
| + // Freshly initialized VM gets by with the snapshot size (which is below
|
| + // kMaxInitialSizePerSpace per space).
|
| + Heap* heap = isolate->heap();
|
| + int page_count[LAST_PAGED_SPACE + 1] = {0, 0, 0, 0};
|
| for (int i = FIRST_PAGED_SPACE; i <= LAST_PAGED_SPACE; i++) {
|
| // Debug code can be very large, so skip CODE_SPACE if we are generating it.
|
| if (i == CODE_SPACE && i::FLAG_debug_code) continue;
|
| - CHECK_EQ(1, isolate->heap()->paged_space(i)->CountTotalPages());
|
| +
|
| + page_count[i] = heap->paged_space(i)->CountTotalPages();
|
| + // Check that the initial heap is also below the limit.
|
| + CHECK_LT(static_cast<size_t>(heap->paged_space(i)->CommittedMemory()),
|
| + kMaxInitialSizePerSpace);
|
| }
|
|
|
| - // Executing the empty script gets by with one page per space.
|
| + // Executing the empty script gets by with the same number of pages, i.e.,
|
| + // requires no extra space.
|
| CompileRun("/*empty*/");
|
| for (int i = FIRST_PAGED_SPACE; i <= LAST_PAGED_SPACE; i++) {
|
| // Debug code can be very large, so skip CODE_SPACE if we are generating it.
|
| if (i == CODE_SPACE && i::FLAG_debug_code) continue;
|
| - CHECK_EQ(1, isolate->heap()->paged_space(i)->CountTotalPages());
|
| + CHECK_EQ(page_count[i], isolate->heap()->paged_space(i)->CountTotalPages());
|
| }
|
|
|
| // No large objects required to perform the above steps.
|
| @@ -685,5 +694,104 @@ UNINITIALIZED_TEST(InlineAllocationObserverCadence) {
|
| isolate->Dispose();
|
| }
|
|
|
| +TEST(ShrinkPageToHighWaterMarkFreeSpaceEnd) {
|
| + CcTest::InitializeVM();
|
| + Isolate* isolate = CcTest::i_isolate();
|
| + HandleScope scope(isolate);
|
| +
|
| + heap::SealCurrentObjects(CcTest::heap());
|
| +
|
| + // Prepare page that only contains a single object and a trailing FreeSpace
|
| + // filler.
|
| + Handle<FixedArray> array = isolate->factory()->NewFixedArray(128, TENURED);
|
| + Page* page = Page::FromAddress(array->address());
|
| +
|
| + // Reset space so high water mark is consistent.
|
| + CcTest::heap()->old_space()->ResetFreeList();
|
| + CcTest::heap()->old_space()->EmptyAllocationInfo();
|
| +
|
| + HeapObject* filler =
|
| + HeapObject::FromAddress(array->address() + array->Size());
|
| + CHECK(filler->IsFreeSpace());
|
| + size_t shrinked = page->ShrinkToHighWaterMark();
|
| + size_t should_have_shrinked =
|
| + RoundDown(static_cast<size_t>(Page::kAllocatableMemory - array->Size()),
|
| + base::OS::CommitPageSize());
|
| + CHECK_EQ(should_have_shrinked, shrinked);
|
| +}
|
| +
|
| +TEST(ShrinkPageToHighWaterMarkNoFiller) {
|
| + CcTest::InitializeVM();
|
| + Isolate* isolate = CcTest::i_isolate();
|
| + HandleScope scope(isolate);
|
| + heap::SealCurrentObjects(CcTest::heap());
|
| +
|
| + const int kFillerSize = 0;
|
| + std::vector<Handle<FixedArray>> arrays =
|
| + heap::FillOldSpacePageWithFixedArrays(CcTest::heap(), kFillerSize);
|
| + Handle<FixedArray> array = arrays.back();
|
| + Page* page = Page::FromAddress(array->address());
|
| + CHECK_EQ(page->area_end(), array->address() + array->Size() + kFillerSize);
|
| +
|
| + // Reset space so high water mark and fillers are consistent.
|
| + CcTest::heap()->old_space()->ResetFreeList();
|
| + CcTest::heap()->old_space()->EmptyAllocationInfo();
|
| +
|
| + const size_t shrinked = page->ShrinkToHighWaterMark();
|
| + CHECK_EQ(0, shrinked);
|
| +}
|
| +
|
| +TEST(ShrinkPageToHighWaterMarkOneWordFiller) {
|
| + CcTest::InitializeVM();
|
| + Isolate* isolate = CcTest::i_isolate();
|
| + HandleScope scope(isolate);
|
| +
|
| + heap::SealCurrentObjects(CcTest::heap());
|
| +
|
| + const int kFillerSize = kPointerSize;
|
| + std::vector<Handle<FixedArray>> arrays =
|
| + heap::FillOldSpacePageWithFixedArrays(CcTest::heap(), kFillerSize);
|
| + Handle<FixedArray> array = arrays.back();
|
| + Page* page = Page::FromAddress(array->address());
|
| + CHECK_EQ(page->area_end(), array->address() + array->Size() + kFillerSize);
|
| +
|
| + // Reset space so high water mark and fillers are consistent.
|
| + CcTest::heap()->old_space()->ResetFreeList();
|
| + CcTest::heap()->old_space()->EmptyAllocationInfo();
|
| +
|
| + HeapObject* filler =
|
| + HeapObject::FromAddress(array->address() + array->Size());
|
| + CHECK_EQ(filler->map(), CcTest::heap()->one_pointer_filler_map());
|
| +
|
| + const size_t shrinked = page->ShrinkToHighWaterMark();
|
| + CHECK_EQ(0, shrinked);
|
| +}
|
| +
|
| +TEST(ShrinkPageToHighWaterMarkTwoWordFiller) {
|
| + CcTest::InitializeVM();
|
| + Isolate* isolate = CcTest::i_isolate();
|
| + HandleScope scope(isolate);
|
| +
|
| + heap::SealCurrentObjects(CcTest::heap());
|
| +
|
| + const int kFillerSize = 2 * kPointerSize;
|
| + std::vector<Handle<FixedArray>> arrays =
|
| + heap::FillOldSpacePageWithFixedArrays(CcTest::heap(), kFillerSize);
|
| + Handle<FixedArray> array = arrays.back();
|
| + Page* page = Page::FromAddress(array->address());
|
| + CHECK_EQ(page->area_end(), array->address() + array->Size() + kFillerSize);
|
| +
|
| + // Reset space so high water mark and fillers are consistent.
|
| + CcTest::heap()->old_space()->ResetFreeList();
|
| + CcTest::heap()->old_space()->EmptyAllocationInfo();
|
| +
|
| + HeapObject* filler =
|
| + HeapObject::FromAddress(array->address() + array->Size());
|
| + CHECK_EQ(filler->map(), CcTest::heap()->two_pointer_filler_map());
|
| +
|
| + const size_t shrinked = page->ShrinkToHighWaterMark();
|
| + CHECK_EQ(0, shrinked);
|
| +}
|
| +
|
| } // namespace internal
|
| } // namespace v8
|
|
|