| Index: test/cctest/test-heap.cc
|
| diff --git a/test/cctest/test-heap.cc b/test/cctest/test-heap.cc
|
| index a9cb60e985d3c96c2d99e6d2cacdcca6ab764c23..9e3c80ec39b766ec35892dba25cbe134d2b21cc2 100644
|
| --- a/test/cctest/test-heap.cc
|
| +++ b/test/cctest/test-heap.cc
|
| @@ -1784,14 +1784,18 @@ TEST(TestSizeOfObjects) {
|
|
|
|
|
| TEST(TestAlignmentCalculations) {
|
| - // Maximum fill amounts should be consistent.
|
| + // Maximum fill amounts are consistent.
|
| int maximum_double_misalignment = kDoubleSize - kPointerSize;
|
| + int maximum_simd128_misalignment = kSimd128Size - kPointerSize;
|
| int max_word_fill = Heap::GetMaximumFillToAlign(kWordAligned);
|
| CHECK_EQ(0, max_word_fill);
|
| int max_double_fill = Heap::GetMaximumFillToAlign(kDoubleAligned);
|
| CHECK_EQ(maximum_double_misalignment, max_double_fill);
|
| int max_double_unaligned_fill = Heap::GetMaximumFillToAlign(kDoubleUnaligned);
|
| CHECK_EQ(maximum_double_misalignment, max_double_unaligned_fill);
|
| + int max_simd128_unaligned_fill =
|
| + Heap::GetMaximumFillToAlign(kSimd128Unaligned);
|
| + CHECK_EQ(maximum_simd128_misalignment, max_simd128_unaligned_fill);
|
|
|
| Address base = reinterpret_cast<Address>(NULL);
|
| int fill = 0;
|
| @@ -1813,6 +1817,16 @@ TEST(TestAlignmentCalculations) {
|
| CHECK_EQ(maximum_double_misalignment, fill);
|
| fill = Heap::GetFillToAlign(base + kPointerSize, kDoubleUnaligned);
|
| CHECK_EQ(0, fill);
|
| +
|
| + // 128 bit SIMD types have 2 or 4 possible alignments, depending on platform.
|
| + fill = Heap::GetFillToAlign(base, kSimd128Unaligned);
|
| + CHECK_EQ((3 * kPointerSize) & kSimd128AlignmentMask, fill);
|
| + fill = Heap::GetFillToAlign(base + kPointerSize, kSimd128Unaligned);
|
| + CHECK_EQ((2 * kPointerSize) & kSimd128AlignmentMask, fill);
|
| + fill = Heap::GetFillToAlign(base + 2 * kPointerSize, kSimd128Unaligned);
|
| + CHECK_EQ(kPointerSize, fill);
|
| + fill = Heap::GetFillToAlign(base + 3 * kPointerSize, kSimd128Unaligned);
|
| + CHECK_EQ(0, fill);
|
| }
|
|
|
|
|
| @@ -1828,65 +1842,94 @@ static HeapObject* NewSpaceAllocateAligned(int size,
|
| }
|
|
|
|
|
| +// Get new space allocation into the desired alignment.
|
| +static Address AlignNewSpace(AllocationAlignment alignment, int offset) {
|
| + Address* top_addr = CcTest::heap()->new_space()->allocation_top_address();
|
| + int fill = Heap::GetFillToAlign(*top_addr, alignment);
|
| + if (fill) {
|
| + NewSpaceAllocateAligned(fill + offset, kWordAligned);
|
| + }
|
| + return *top_addr;
|
| +}
|
| +
|
| +
|
| TEST(TestAlignedAllocation) {
|
| // Double misalignment is 4 on 32-bit platforms, 0 on 64-bit ones.
|
| const intptr_t double_misalignment = kDoubleSize - kPointerSize;
|
| + Address* top_addr = CcTest::heap()->new_space()->allocation_top_address();
|
| + Address start;
|
| + HeapObject* obj;
|
| + HeapObject* filler;
|
| if (double_misalignment) {
|
| - Address* top_addr = CcTest::heap()->new_space()->allocation_top_address();
|
| - // Align the top for the first test.
|
| - if (!IsAddressAligned(*top_addr, kDoubleAlignment))
|
| - NewSpaceAllocateAligned(kPointerSize, kWordAligned);
|
| -
|
| - // Allocate a pointer sized object that must be double aligned.
|
| - Address start = *top_addr;
|
| - HeapObject* obj1 = NewSpaceAllocateAligned(kPointerSize, kDoubleAligned);
|
| - CHECK(IsAddressAligned(obj1->address(), kDoubleAlignment));
|
| - // Only the object was allocated.
|
| + // Allocate a pointer sized object that must be double aligned at an
|
| + // aligned address.
|
| + start = AlignNewSpace(kDoubleAligned, 0);
|
| + obj = NewSpaceAllocateAligned(kPointerSize, kDoubleAligned);
|
| + CHECK(IsAddressAligned(obj->address(), kDoubleAlignment));
|
| + // There is no filler.
|
| CHECK_EQ(kPointerSize, *top_addr - start);
|
| - // top is now misaligned.
|
| - // Allocate a second pointer sized object that must be double aligned.
|
| - HeapObject* obj2 = NewSpaceAllocateAligned(kPointerSize, kDoubleAligned);
|
| - CHECK(IsAddressAligned(obj2->address(), kDoubleAlignment));
|
| - // There should be a filler object in between the two objects.
|
| - CHECK(HeapObject::FromAddress(start + kPointerSize)->IsFiller());
|
| - // Two objects and a filler object were allocated.
|
| - CHECK_EQ(2 * kPointerSize + double_misalignment, *top_addr - start);
|
| -
|
| - // Similarly for kDoubleUnaligned. top is misaligned.
|
| - start = *top_addr;
|
| - obj1 = NewSpaceAllocateAligned(kPointerSize, kDoubleUnaligned);
|
| - CHECK(IsAddressAligned(obj1->address(), kDoubleAlignment, kPointerSize));
|
| - CHECK_EQ(kPointerSize, *top_addr - start);
|
| - obj2 = NewSpaceAllocateAligned(kPointerSize, kDoubleUnaligned);
|
| - CHECK(IsAddressAligned(obj2->address(), kDoubleAlignment, kPointerSize));
|
| - CHECK(HeapObject::FromAddress(start + kPointerSize)->IsFiller());
|
| - CHECK_EQ(2 * kPointerSize + double_misalignment, *top_addr - start);
|
| - }
|
| -}
|
|
|
| + // Allocate a second pointer sized object that must be double aligned at an
|
| + // unaligned address.
|
| + start = AlignNewSpace(kDoubleAligned, kPointerSize);
|
| + obj = NewSpaceAllocateAligned(kPointerSize, kDoubleAligned);
|
| + CHECK(IsAddressAligned(obj->address(), kDoubleAlignment));
|
| + // There is a filler object before the object.
|
| + filler = HeapObject::FromAddress(start);
|
| + CHECK(obj != filler && filler->IsFiller() &&
|
| + filler->Size() == kPointerSize);
|
| + CHECK_EQ(kPointerSize + double_misalignment, *top_addr - start);
|
|
|
| -// Force allocation to happen from the free list, at a desired misalignment.
|
| -static Address SetUpFreeListAllocation(int misalignment) {
|
| - Heap* heap = CcTest::heap();
|
| - OldSpace* old_space = heap->old_space();
|
| - Address top = old_space->top();
|
| - // First, allocate enough filler to get the linear area into the desired
|
| - // misalignment.
|
| - const intptr_t maximum_misalignment = 2 * kPointerSize;
|
| - const intptr_t maximum_misalignment_mask = maximum_misalignment - 1;
|
| - intptr_t top_alignment = OffsetFrom(top) & maximum_misalignment_mask;
|
| - int filler_size = misalignment - static_cast<int>(top_alignment);
|
| - if (filler_size < 0) filler_size += maximum_misalignment;
|
| - if (filler_size) {
|
| - // Create the filler object.
|
| - AllocationResult allocation = old_space->AllocateRawUnaligned(filler_size);
|
| - HeapObject* obj = NULL;
|
| - allocation.To(&obj);
|
| - heap->CreateFillerObjectAt(obj->address(), filler_size);
|
| - }
|
| - top = old_space->top();
|
| - old_space->EmptyAllocationInfo();
|
| - return top;
|
| + // Similarly for kDoubleUnaligned.
|
| + start = AlignNewSpace(kDoubleUnaligned, 0);
|
| + obj = NewSpaceAllocateAligned(kPointerSize, kDoubleUnaligned);
|
| + CHECK(IsAddressAligned(obj->address(), kDoubleAlignment, kPointerSize));
|
| + CHECK_EQ(kPointerSize, *top_addr - start);
|
| + start = AlignNewSpace(kDoubleUnaligned, kPointerSize);
|
| + obj = NewSpaceAllocateAligned(kPointerSize, kDoubleUnaligned);
|
| + CHECK(IsAddressAligned(obj->address(), kDoubleAlignment, kPointerSize));
|
| + // There is a filler object before the object.
|
| + filler = HeapObject::FromAddress(start);
|
| + CHECK(obj != filler && filler->IsFiller() &&
|
| + filler->Size() == kPointerSize);
|
| + CHECK_EQ(kPointerSize + double_misalignment, *top_addr - start);
|
| + }
|
| +
|
| + // Now test SIMD alignment. There are 2 or 4 possible alignments, depending
|
| + // on platform.
|
| + start = AlignNewSpace(kSimd128Unaligned, 0);
|
| + obj = NewSpaceAllocateAligned(kPointerSize, kSimd128Unaligned);
|
| + CHECK(IsAddressAligned(obj->address(), kSimd128Alignment, kPointerSize));
|
| + // There is no filler.
|
| + CHECK_EQ(kPointerSize, *top_addr - start);
|
| + start = AlignNewSpace(kSimd128Unaligned, kPointerSize);
|
| + obj = NewSpaceAllocateAligned(kPointerSize, kSimd128Unaligned);
|
| + CHECK(IsAddressAligned(obj->address(), kSimd128Alignment, kPointerSize));
|
| + // There is a filler object before the object.
|
| + filler = HeapObject::FromAddress(start);
|
| + CHECK(obj != filler && filler->IsFiller() &&
|
| + filler->Size() == kSimd128Size - kPointerSize);
|
| + CHECK_EQ(kPointerSize + kSimd128Size - kPointerSize, *top_addr - start);
|
| +
|
| + if (double_misalignment) {
|
| + // Test the 2 other alignments possible on 32 bit platforms.
|
| + start = AlignNewSpace(kSimd128Unaligned, 2 * kPointerSize);
|
| + obj = NewSpaceAllocateAligned(kPointerSize, kSimd128Unaligned);
|
| + CHECK(IsAddressAligned(obj->address(), kSimd128Alignment, kPointerSize));
|
| + // There is a filler object before the object.
|
| + filler = HeapObject::FromAddress(start);
|
| + CHECK(obj != filler && filler->IsFiller() &&
|
| + filler->Size() == 2 * kPointerSize);
|
| + CHECK_EQ(kPointerSize + 2 * kPointerSize, *top_addr - start);
|
| + start = AlignNewSpace(kSimd128Unaligned, 3 * kPointerSize);
|
| + obj = NewSpaceAllocateAligned(kPointerSize, kSimd128Unaligned);
|
| + CHECK(IsAddressAligned(obj->address(), kSimd128Alignment, kPointerSize));
|
| + // There is a filler object before the object.
|
| + filler = HeapObject::FromAddress(start);
|
| + CHECK(obj != filler && filler->IsFiller() &&
|
| + filler->Size() == kPointerSize);
|
| + CHECK_EQ(kPointerSize + kPointerSize, *top_addr - start);
|
| + }
|
| }
|
|
|
|
|
| @@ -1902,38 +1945,105 @@ static HeapObject* OldSpaceAllocateAligned(int size,
|
| }
|
|
|
|
|
| +// Get old space allocation into the desired alignment.
|
| +static Address AlignOldSpace(AllocationAlignment alignment, int offset) {
|
| + Address* top_addr = CcTest::heap()->old_space()->allocation_top_address();
|
| + int fill = Heap::GetFillToAlign(*top_addr, alignment);
|
| + int allocation = fill + offset;
|
| + if (allocation) {
|
| + OldSpaceAllocateAligned(allocation, kWordAligned);
|
| + }
|
| + Address top = *top_addr;
|
| + // Now force the remaining allocation onto the free list.
|
| + CcTest::heap()->old_space()->EmptyAllocationInfo();
|
| + return top;
|
| +}
|
| +
|
| +
|
| // Test the case where allocation must be done from the free list, so filler
|
| // may precede or follow the object.
|
| TEST(TestAlignedOverAllocation) {
|
| // Double misalignment is 4 on 32-bit platforms, 0 on 64-bit ones.
|
| const intptr_t double_misalignment = kDoubleSize - kPointerSize;
|
| + Address start;
|
| + HeapObject* obj;
|
| + HeapObject* filler1;
|
| + HeapObject* filler2;
|
| if (double_misalignment) {
|
| - Address start = SetUpFreeListAllocation(0);
|
| - HeapObject* obj1 = OldSpaceAllocateAligned(kPointerSize, kDoubleAligned);
|
| - // The object should be aligned, and a filler object should be created.
|
| - CHECK(IsAddressAligned(obj1->address(), kDoubleAlignment));
|
| - CHECK(HeapObject::FromAddress(start)->IsFiller() &&
|
| - HeapObject::FromAddress(start + kPointerSize)->IsFiller());
|
| + start = AlignOldSpace(kDoubleAligned, 0);
|
| + obj = OldSpaceAllocateAligned(kPointerSize, kDoubleAligned);
|
| + // The object is aligned, and a filler object is created after.
|
| + CHECK(IsAddressAligned(obj->address(), kDoubleAlignment));
|
| + filler1 = HeapObject::FromAddress(start + kPointerSize);
|
| + CHECK(obj != filler1 && filler1->IsFiller() &&
|
| + filler1->Size() == kPointerSize);
|
| // Try the opposite alignment case.
|
| - start = SetUpFreeListAllocation(kPointerSize);
|
| - HeapObject* obj2 = OldSpaceAllocateAligned(kPointerSize, kDoubleAligned);
|
| - CHECK(IsAddressAligned(obj2->address(), kDoubleAlignment));
|
| - CHECK(HeapObject::FromAddress(start)->IsFiller() &&
|
| - HeapObject::FromAddress(start + kPointerSize)->IsFiller());
|
| + start = AlignOldSpace(kDoubleAligned, kPointerSize);
|
| + obj = OldSpaceAllocateAligned(kPointerSize, kDoubleAligned);
|
| + CHECK(IsAddressAligned(obj->address(), kDoubleAlignment));
|
| + filler1 = HeapObject::FromAddress(start);
|
| + CHECK(obj != filler1);
|
| + CHECK(filler1->IsFiller());
|
| + CHECK(filler1->Size() == kPointerSize);
|
| + CHECK(obj != filler1 && filler1->IsFiller() &&
|
| + filler1->Size() == kPointerSize);
|
|
|
| // Similarly for kDoubleUnaligned.
|
| - start = SetUpFreeListAllocation(0);
|
| - obj1 = OldSpaceAllocateAligned(kPointerSize, kDoubleUnaligned);
|
| - // The object should be aligned, and a filler object should be created.
|
| - CHECK(IsAddressAligned(obj1->address(), kDoubleAlignment, kPointerSize));
|
| - CHECK(HeapObject::FromAddress(start)->IsFiller() &&
|
| - HeapObject::FromAddress(start + kPointerSize)->IsFiller());
|
| + start = AlignOldSpace(kDoubleUnaligned, 0);
|
| + obj = OldSpaceAllocateAligned(kPointerSize, kDoubleUnaligned);
|
| + // The object is aligned, and a filler object is created after.
|
| + CHECK(IsAddressAligned(obj->address(), kDoubleAlignment, kPointerSize));
|
| + filler1 = HeapObject::FromAddress(start + kPointerSize);
|
| + CHECK(obj != filler1 && filler1->IsFiller() &&
|
| + filler1->Size() == kPointerSize);
|
| // Try the opposite alignment case.
|
| - start = SetUpFreeListAllocation(kPointerSize);
|
| - obj2 = OldSpaceAllocateAligned(kPointerSize, kDoubleUnaligned);
|
| - CHECK(IsAddressAligned(obj2->address(), kDoubleAlignment, kPointerSize));
|
| - CHECK(HeapObject::FromAddress(start)->IsFiller() &&
|
| - HeapObject::FromAddress(start + kPointerSize)->IsFiller());
|
| + start = AlignOldSpace(kDoubleUnaligned, kPointerSize);
|
| + obj = OldSpaceAllocateAligned(kPointerSize, kDoubleUnaligned);
|
| + CHECK(IsAddressAligned(obj->address(), kDoubleAlignment, kPointerSize));
|
| + filler1 = HeapObject::FromAddress(start);
|
| + CHECK(obj != filler1 && filler1->IsFiller() &&
|
| + filler1->Size() == kPointerSize);
|
| + }
|
| +
|
| + // Now test SIMD alignment. There are 2 or 4 possible alignments, depending
|
| + // on platform.
|
| + start = AlignOldSpace(kSimd128Unaligned, 0);
|
| + obj = OldSpaceAllocateAligned(kPointerSize, kSimd128Unaligned);
|
| + CHECK(IsAddressAligned(obj->address(), kSimd128Alignment, kPointerSize));
|
| + // There is a filler object after the object.
|
| + filler1 = HeapObject::FromAddress(start + kPointerSize);
|
| + CHECK(obj != filler1 && filler1->IsFiller() &&
|
| + filler1->Size() == kSimd128Size - kPointerSize);
|
| + start = AlignOldSpace(kSimd128Unaligned, kPointerSize);
|
| + obj = OldSpaceAllocateAligned(kPointerSize, kSimd128Unaligned);
|
| + CHECK(IsAddressAligned(obj->address(), kSimd128Alignment, kPointerSize));
|
| + // There is a filler object before the object.
|
| + filler1 = HeapObject::FromAddress(start);
|
| + CHECK(obj != filler1 && filler1->IsFiller() &&
|
| + filler1->Size() == kSimd128Size - kPointerSize);
|
| +
|
| + if (double_misalignment) {
|
| + // Test the 2 other alignments possible on 32 bit platforms.
|
| + start = AlignOldSpace(kSimd128Unaligned, 2 * kPointerSize);
|
| + obj = OldSpaceAllocateAligned(kPointerSize, kSimd128Unaligned);
|
| + CHECK(IsAddressAligned(obj->address(), kSimd128Alignment, kPointerSize));
|
| + // There are filler objects before and after the object.
|
| + filler1 = HeapObject::FromAddress(start);
|
| + CHECK(obj != filler1 && filler1->IsFiller() &&
|
| + filler1->Size() == 2 * kPointerSize);
|
| + filler2 = HeapObject::FromAddress(start + 3 * kPointerSize);
|
| + CHECK(obj != filler2 && filler2->IsFiller() &&
|
| + filler2->Size() == kPointerSize);
|
| + start = AlignOldSpace(kSimd128Unaligned, 3 * kPointerSize);
|
| + obj = OldSpaceAllocateAligned(kPointerSize, kSimd128Unaligned);
|
| + CHECK(IsAddressAligned(obj->address(), kSimd128Alignment, kPointerSize));
|
| + // There are filler objects before and after the object.
|
| + filler1 = HeapObject::FromAddress(start);
|
| + CHECK(obj != filler1 && filler1->IsFiller() &&
|
| + filler1->Size() == kPointerSize);
|
| + filler2 = HeapObject::FromAddress(start + 2 * kPointerSize);
|
| + CHECK(obj != filler2 && filler2->IsFiller() &&
|
| + filler2->Size() == 2 * kPointerSize);
|
| }
|
| }
|
|
|
|
|