| Index: test/cctest/heap/test-lab.cc
|
| diff --git a/test/cctest/heap/test-lab.cc b/test/cctest/heap/test-lab.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..f008e421b331aaab2a44d14fc8afb9fb93f12012
|
| --- /dev/null
|
| +++ b/test/cctest/heap/test-lab.cc
|
| @@ -0,0 +1,211 @@
|
| +// Copyright 2015 the V8 project authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +// TODO(jochen): Remove this after the setting is turned on globally.
|
| +#define V8_IMMINENT_DEPRECATION_WARNINGS
|
| +
|
| +#include <vector>
|
| +
|
| +
|
| +#include "src/globals.h"
|
| +#include "src/heap/heap.h"
|
| +#include "src/heap/spaces.h"
|
| +#include "src/heap/spaces-inl.h"
|
| +#include "test/cctest/cctest.h"
|
| +
|
| +
|
| +namespace v8 {
|
| +namespace internal {
|
| +
|
| +static Address AllocateLabBackingStore(intptr_t size_in_bytes) {
|
| + char* base = reinterpret_cast<char*>(malloc(size_in_bytes));
|
| + CHECK_EQ(reinterpret_cast<intptr_t>(base) % sizeof(void*), 0);
|
| + memset(base, 0xAA, size_in_bytes);
|
| + return reinterpret_cast<Address>(base);
|
| +}
|
| +
|
| +
|
| +static void FreeLabBackingStore(Address base) { free(base); }
|
| +
|
| +
|
| +static void VerifyIterable(v8::internal::Address base,
|
| + v8::internal::Address limit,
|
| + std::vector<intptr_t> expected_size) {
|
| + CHECK_LE(reinterpret_cast<intptr_t>(base), reinterpret_cast<intptr_t>(limit));
|
| + HeapObject* object = nullptr;
|
| + int counter = 0;
|
| + while (base < limit) {
|
| + object = HeapObject::FromAddress(base);
|
| + CHECK(object->IsFiller());
|
| + CHECK_LT(counter, expected_size.size());
|
| + CHECK_EQ(expected_size[counter], object->Size());
|
| + base += object->Size();
|
| + counter++;
|
| + }
|
| +}
|
| +
|
| +
|
| +static bool AllocateFromLab(Heap* heap, LocalAllocationBuffer* lab,
|
| + intptr_t size_in_bytes,
|
| + AllocationAlignment alignment = kWordAligned) {
|
| + HeapObject* obj;
|
| + AllocationResult result =
|
| + lab->AllocateRawAligned(static_cast<int>(size_in_bytes), alignment);
|
| + if (result.To(&obj)) {
|
| + heap->CreateFillerObjectAt(obj->address(), static_cast<int>(size_in_bytes));
|
| + return true;
|
| + }
|
| + return false;
|
| +}
|
| +
|
| +
|
| +TEST(InvalidLab) {
|
| + LocalAllocationBuffer lab = LocalAllocationBuffer::InvalidBuffer();
|
| + CHECK(!lab.IsValid());
|
| +}
|
| +
|
| +
|
| +TEST(UnusedLabImplicitClose) {
|
| + CcTest::InitializeVM();
|
| + Heap* heap = CcTest::heap();
|
| + heap->root(Heap::kOnePointerFillerMapRootIndex);
|
| + const int kLabSize = 4 * KB;
|
| + Address base = AllocateLabBackingStore(kLabSize);
|
| + Address limit = base + kLabSize;
|
| + intptr_t expected_sizes_raw[1] = {kLabSize};
|
| + std::vector<intptr_t> expected_sizes(expected_sizes_raw,
|
| + expected_sizes_raw + 1);
|
| + {
|
| + AllocationResult lab_backing_store(HeapObject::FromAddress(base));
|
| + LocalAllocationBuffer lab =
|
| + LocalAllocationBuffer::FromResult(heap, lab_backing_store, kLabSize);
|
| + CHECK(lab.IsValid());
|
| + }
|
| + VerifyIterable(base, limit, expected_sizes);
|
| + FreeLabBackingStore(base);
|
| +}
|
| +
|
| +
|
| +TEST(SimpleAllocate) {
|
| + CcTest::InitializeVM();
|
| + Heap* heap = CcTest::heap();
|
| + const int kLabSize = 4 * KB;
|
| + Address base = AllocateLabBackingStore(kLabSize);
|
| + Address limit = base + kLabSize;
|
| + intptr_t sizes_raw[1] = {128};
|
| + intptr_t expected_sizes_raw[2] = {128, kLabSize - 128};
|
| + std::vector<intptr_t> sizes(sizes_raw, sizes_raw + 1);
|
| + std::vector<intptr_t> expected_sizes(expected_sizes_raw,
|
| + expected_sizes_raw + 2);
|
| + {
|
| + AllocationResult lab_backing_store(HeapObject::FromAddress(base));
|
| + LocalAllocationBuffer lab =
|
| + LocalAllocationBuffer::FromResult(heap, lab_backing_store, kLabSize);
|
| + CHECK(lab.IsValid());
|
| + intptr_t sum = 0;
|
| + for (auto size : sizes) {
|
| + if (AllocateFromLab(heap, &lab, size)) {
|
| + sum += size;
|
| + }
|
| + }
|
| + }
|
| + VerifyIterable(base, limit, expected_sizes);
|
| + FreeLabBackingStore(base);
|
| +}
|
| +
|
| +
|
| +TEST(AllocateUntilLabOOM) {
|
| + CcTest::InitializeVM();
|
| + Heap* heap = CcTest::heap();
|
| + const int kLabSize = 2 * KB;
|
| + Address base = AllocateLabBackingStore(kLabSize);
|
| + Address limit = base + kLabSize;
|
| + // The following objects won't fit in {kLabSize}.
|
| + intptr_t sizes_raw[5] = {512, 512, 128, 512, 512};
|
| + intptr_t expected_sizes_raw[5] = {512, 512, 128, 512, 384 /* left over */};
|
| + std::vector<intptr_t> sizes(sizes_raw, sizes_raw + 5);
|
| + std::vector<intptr_t> expected_sizes(expected_sizes_raw,
|
| + expected_sizes_raw + 5);
|
| + intptr_t sum = 0;
|
| + {
|
| + AllocationResult lab_backing_store(HeapObject::FromAddress(base));
|
| + LocalAllocationBuffer lab =
|
| + LocalAllocationBuffer::FromResult(heap, lab_backing_store, kLabSize);
|
| + CHECK(lab.IsValid());
|
| + for (auto size : sizes) {
|
| + if (AllocateFromLab(heap, &lab, size)) {
|
| + sum += size;
|
| + }
|
| + }
|
| + CHECK_EQ(kLabSize - sum, 384);
|
| + }
|
| + VerifyIterable(base, limit, expected_sizes);
|
| + FreeLabBackingStore(base);
|
| +}
|
| +
|
| +
|
| +TEST(AllocateExactlyUntilLimit) {
|
| + CcTest::InitializeVM();
|
| + Heap* heap = CcTest::heap();
|
| + const int kLabSize = 2 * KB;
|
| + Address base = AllocateLabBackingStore(kLabSize);
|
| + Address limit = base + kLabSize;
|
| + intptr_t sizes_raw[4] = {512, 512, 512, 512};
|
| + intptr_t expected_sizes_raw[5] = {512, 512, 512, 512, 0};
|
| + std::vector<intptr_t> sizes(sizes_raw, sizes_raw + 4);
|
| + std::vector<intptr_t> expected_sizes(expected_sizes_raw,
|
| + expected_sizes_raw + 5);
|
| + {
|
| + AllocationResult lab_backing_store(HeapObject::FromAddress(base));
|
| + LocalAllocationBuffer lab =
|
| + LocalAllocationBuffer::FromResult(heap, lab_backing_store, kLabSize);
|
| + CHECK(lab.IsValid());
|
| + intptr_t sum = 0;
|
| + for (auto size : sizes) {
|
| + if (AllocateFromLab(heap, &lab, size)) {
|
| + sum += size;
|
| + } else {
|
| + break;
|
| + }
|
| + }
|
| + CHECK_EQ(kLabSize - sum, 0);
|
| + }
|
| + VerifyIterable(base, limit, expected_sizes);
|
| + FreeLabBackingStore(base);
|
| +}
|
| +
|
| +
|
| +#ifdef V8_HOST_ARCH_32_BIT
|
| +TEST(AllocateAligned) {
|
| + CcTest::InitializeVM();
|
| + Heap* heap = CcTest::heap();
|
| + const int kLabSize = 2 * KB;
|
| + Address base = AllocateLabBackingStore(kLabSize);
|
| + Address limit = base + kLabSize;
|
| + std::pair<intptr_t, AllocationAlignment> sizes_raw[2] = {
|
| + std::make_pair(116, kWordAligned), std::make_pair(64, kDoubleAligned)};
|
| + std::vector<std::pair<intptr_t, AllocationAlignment>> sizes(sizes_raw,
|
| + sizes_raw + 2);
|
| + intptr_t expected_sizes_raw[4] = {116, 4, 64, 1864};
|
| + std::vector<intptr_t> expected_sizes(expected_sizes_raw,
|
| + expected_sizes_raw + 4);
|
| +
|
| + {
|
| + AllocationResult lab_backing_store(HeapObject::FromAddress(base));
|
| + LocalAllocationBuffer lab =
|
| + LocalAllocationBuffer::FromResult(heap, lab_backing_store, kLabSize);
|
| + CHECK(lab.IsValid());
|
| + for (auto pair : sizes) {
|
| + if (!AllocateFromLab(heap, &lab, pair.first, pair.second)) {
|
| + break;
|
| + }
|
| + }
|
| + }
|
| + VerifyIterable(base, limit, expected_sizes);
|
| + FreeLabBackingStore(base);
|
| +}
|
| +#endif // V8_HOST_ARCH_32_BIT
|
| +
|
| +} // namespace internal
|
| +} // namespace v8
|
|
|