Commit 6a6388f0 authored by bbudge's avatar bbudge Committed by Commit bot

Revert of Add SIMD 128 alignment support to Heap. (patchset #3 id:40001 of...

Revert of Add SIMD 128 alignment support to Heap. (patchset #3 id:40001 of https://codereview.chromium.org/1159453004/)

Reason for revert:
Breaks Linux - arm64 - sim - MSAN
TBR=jochen

Original issue's description:
> Add SIMD 128 alignment support to Heap.
> Adds SIMD 128 alignment sizes and masks.
> Adds support in Heap for SIMD alignments and fills.
> Reworks cctest so that each test independently aligns its allocation address, rather than depending on the previous tests ending state. Adds test cases for SIMD.
>
> LOG=N
> BUG=v8:4124

TBR=hpayer@chromium.org,jochen@chromium.org
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true
BUG=v8:4124

Review URL: https://codereview.chromium.org/1169453003

Cr-Commit-Position: refs/heads/master@{#28768}
parent 4347d56a
...@@ -197,8 +197,6 @@ typedef int32_t uc32; ...@@ -197,8 +197,6 @@ typedef int32_t uc32;
const int kOneByteSize = kCharSize; const int kOneByteSize = kCharSize;
const int kUC16Size = sizeof(uc16); // NOLINT const int kUC16Size = sizeof(uc16); // NOLINT
// 128 bit SIMD value size.
const int kSimd128Size = 16;
// Round up n to be a multiple of sz, where sz is a power of 2. // Round up n to be a multiple of sz, where sz is a power of 2.
#define ROUND_UP(n, sz) (((n) + ((sz) - 1)) & ~((sz) - 1)) #define ROUND_UP(n, sz) (((n) + ((sz) - 1)) & ~((sz) - 1))
...@@ -311,10 +309,6 @@ const intptr_t kPointerAlignmentMask = kPointerAlignment - 1; ...@@ -311,10 +309,6 @@ const intptr_t kPointerAlignmentMask = kPointerAlignment - 1;
const intptr_t kDoubleAlignment = 8; const intptr_t kDoubleAlignment = 8;
const intptr_t kDoubleAlignmentMask = kDoubleAlignment - 1; const intptr_t kDoubleAlignmentMask = kDoubleAlignment - 1;
// Desired alignment for 128 bit SIMD values.
const intptr_t kSimd128Alignment = 16;
const intptr_t kSimd128AlignmentMask = kSimd128Alignment - 1;
// Desired alignment for generated code is 32 bytes (to improve cache line // Desired alignment for generated code is 32 bytes (to improve cache line
// utilization). // utilization).
const int kCodeAlignmentBits = 5; const int kCodeAlignmentBits = 5;
...@@ -455,12 +449,7 @@ enum AllocationSpace { ...@@ -455,12 +449,7 @@ enum AllocationSpace {
const int kSpaceTagSize = 3; const int kSpaceTagSize = 3;
const int kSpaceTagMask = (1 << kSpaceTagSize) - 1; const int kSpaceTagMask = (1 << kSpaceTagSize) - 1;
enum AllocationAlignment { enum AllocationAlignment { kWordAligned, kDoubleAligned, kDoubleUnaligned };
kWordAligned,
kDoubleAligned,
kDoubleUnaligned,
kSimd128Unaligned
};
// A flag that indicates whether objects should be pretenured when // A flag that indicates whether objects should be pretenured when
// allocated (allocated directly into the old generation) or not // allocated (allocated directly into the old generation) or not
......
...@@ -1995,8 +1995,6 @@ int Heap::GetMaximumFillToAlign(AllocationAlignment alignment) { ...@@ -1995,8 +1995,6 @@ int Heap::GetMaximumFillToAlign(AllocationAlignment alignment) {
case kDoubleAligned: case kDoubleAligned:
case kDoubleUnaligned: case kDoubleUnaligned:
return kDoubleSize - kPointerSize; return kDoubleSize - kPointerSize;
case kSimd128Unaligned:
return kSimd128Size - kPointerSize;
default: default:
UNREACHABLE(); UNREACHABLE();
} }
...@@ -2010,10 +2008,6 @@ int Heap::GetFillToAlign(Address address, AllocationAlignment alignment) { ...@@ -2010,10 +2008,6 @@ int Heap::GetFillToAlign(Address address, AllocationAlignment alignment) {
return kPointerSize; return kPointerSize;
if (alignment == kDoubleUnaligned && (offset & kDoubleAlignmentMask) == 0) if (alignment == kDoubleUnaligned && (offset & kDoubleAlignmentMask) == 0)
return kDoubleSize - kPointerSize; // No fill if double is always aligned. return kDoubleSize - kPointerSize; // No fill if double is always aligned.
if (alignment == kSimd128Unaligned) {
return (kSimd128Size - (static_cast<int>(offset) + kPointerSize)) &
kSimd128AlignmentMask;
}
return 0; return 0;
} }
......
...@@ -1784,18 +1784,14 @@ TEST(TestSizeOfObjects) { ...@@ -1784,18 +1784,14 @@ TEST(TestSizeOfObjects) {
TEST(TestAlignmentCalculations) { TEST(TestAlignmentCalculations) {
// Maximum fill amounts are consistent. // Maximum fill amounts should be consistent.
int maximum_double_misalignment = kDoubleSize - kPointerSize; int maximum_double_misalignment = kDoubleSize - kPointerSize;
int maximum_simd128_misalignment = kSimd128Size - kPointerSize;
int max_word_fill = Heap::GetMaximumFillToAlign(kWordAligned); int max_word_fill = Heap::GetMaximumFillToAlign(kWordAligned);
CHECK_EQ(0, max_word_fill); CHECK_EQ(0, max_word_fill);
int max_double_fill = Heap::GetMaximumFillToAlign(kDoubleAligned); int max_double_fill = Heap::GetMaximumFillToAlign(kDoubleAligned);
CHECK_EQ(maximum_double_misalignment, max_double_fill); CHECK_EQ(maximum_double_misalignment, max_double_fill);
int max_double_unaligned_fill = Heap::GetMaximumFillToAlign(kDoubleUnaligned); int max_double_unaligned_fill = Heap::GetMaximumFillToAlign(kDoubleUnaligned);
CHECK_EQ(maximum_double_misalignment, max_double_unaligned_fill); 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); Address base = reinterpret_cast<Address>(NULL);
int fill = 0; int fill = 0;
...@@ -1817,16 +1813,6 @@ TEST(TestAlignmentCalculations) { ...@@ -1817,16 +1813,6 @@ TEST(TestAlignmentCalculations) {
CHECK_EQ(maximum_double_misalignment, fill); CHECK_EQ(maximum_double_misalignment, fill);
fill = Heap::GetFillToAlign(base + kPointerSize, kDoubleUnaligned); fill = Heap::GetFillToAlign(base + kPointerSize, kDoubleUnaligned);
CHECK_EQ(0, fill); 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);
} }
...@@ -1842,97 +1828,68 @@ static HeapObject* NewSpaceAllocateAligned(int size, ...@@ -1842,97 +1828,68 @@ 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) { TEST(TestAlignedAllocation) {
// Double misalignment is 4 on 32-bit platforms, 0 on 64-bit ones. // Double misalignment is 4 on 32-bit platforms, 0 on 64-bit ones.
const intptr_t double_misalignment = kDoubleSize - kPointerSize; 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) { if (double_misalignment) {
// Allocate a pointer sized object that must be double aligned at an Address* top_addr = CcTest::heap()->new_space()->allocation_top_address();
// aligned address. // Align the top for the first test.
start = AlignNewSpace(kDoubleAligned, 0); if (!IsAddressAligned(*top_addr, kDoubleAlignment))
obj = NewSpaceAllocateAligned(kPointerSize, kDoubleAligned); NewSpaceAllocateAligned(kPointerSize, kWordAligned);
CHECK(IsAddressAligned(obj->address(), kDoubleAlignment));
// There is no filler. // 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.
CHECK_EQ(kPointerSize, *top_addr - start); CHECK_EQ(kPointerSize, *top_addr - start);
// top is now misaligned.
// Allocate a second pointer sized object that must be double aligned at an // Allocate a second pointer sized object that must be double aligned.
// unaligned address. HeapObject* obj2 = NewSpaceAllocateAligned(kPointerSize, kDoubleAligned);
start = AlignNewSpace(kDoubleAligned, kPointerSize); CHECK(IsAddressAligned(obj2->address(), kDoubleAlignment));
obj = NewSpaceAllocateAligned(kPointerSize, kDoubleAligned); // There should be a filler object in between the two objects.
CHECK(IsAddressAligned(obj->address(), kDoubleAlignment)); CHECK(HeapObject::FromAddress(start + kPointerSize)->IsFiller());
// There is a filler object before the object. // Two objects and a filler object were allocated.
filler = HeapObject::FromAddress(start); CHECK_EQ(2 * kPointerSize + double_misalignment, *top_addr - start);
CHECK(obj != filler && filler->IsFiller() &&
filler->Size() == kPointerSize); // Similarly for kDoubleUnaligned. top is misaligned.
CHECK_EQ(kPointerSize + double_misalignment, *top_addr - start); start = *top_addr;
obj1 = NewSpaceAllocateAligned(kPointerSize, kDoubleUnaligned);
// Similarly for kDoubleUnaligned. CHECK(IsAddressAligned(obj1->address(), kDoubleAlignment, kPointerSize));
start = AlignNewSpace(kDoubleUnaligned, 0);
obj = NewSpaceAllocateAligned(kPointerSize, kDoubleUnaligned);
CHECK(IsAddressAligned(obj->address(), kDoubleAlignment, kPointerSize));
CHECK_EQ(kPointerSize, *top_addr - start); CHECK_EQ(kPointerSize, *top_addr - start);
start = AlignNewSpace(kDoubleUnaligned, kPointerSize); obj2 = NewSpaceAllocateAligned(kPointerSize, kDoubleUnaligned);
obj = NewSpaceAllocateAligned(kPointerSize, kDoubleUnaligned); CHECK(IsAddressAligned(obj2->address(), kDoubleAlignment, kPointerSize));
CHECK(IsAddressAligned(obj->address(), kDoubleAlignment, kPointerSize)); CHECK(HeapObject::FromAddress(start + kPointerSize)->IsFiller());
// There is a filler object before the object. CHECK_EQ(2 * kPointerSize + double_misalignment, *top_addr - start);
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);
} }
} }
// 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;
}
static HeapObject* OldSpaceAllocateAligned(int size, static HeapObject* OldSpaceAllocateAligned(int size,
AllocationAlignment alignment) { AllocationAlignment alignment) {
Heap* heap = CcTest::heap(); Heap* heap = CcTest::heap();
...@@ -1945,105 +1902,38 @@ static HeapObject* OldSpaceAllocateAligned(int size, ...@@ -1945,105 +1902,38 @@ 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 // Test the case where allocation must be done from the free list, so filler
// may precede or follow the object. // may precede or follow the object.
TEST(TestAlignedOverAllocation) { TEST(TestAlignedOverAllocation) {
// Double misalignment is 4 on 32-bit platforms, 0 on 64-bit ones. // Double misalignment is 4 on 32-bit platforms, 0 on 64-bit ones.
const intptr_t double_misalignment = kDoubleSize - kPointerSize; const intptr_t double_misalignment = kDoubleSize - kPointerSize;
Address start;
HeapObject* obj;
HeapObject* filler1;
HeapObject* filler2;
if (double_misalignment) { if (double_misalignment) {
start = AlignOldSpace(kDoubleAligned, 0); Address start = SetUpFreeListAllocation(0);
obj = OldSpaceAllocateAligned(kPointerSize, kDoubleAligned); HeapObject* obj1 = OldSpaceAllocateAligned(kPointerSize, kDoubleAligned);
// The object is aligned, and a filler object is created after. // The object should be aligned, and a filler object should be created.
CHECK(IsAddressAligned(obj->address(), kDoubleAlignment)); CHECK(IsAddressAligned(obj1->address(), kDoubleAlignment));
filler1 = HeapObject::FromAddress(start + kPointerSize); CHECK(HeapObject::FromAddress(start)->IsFiller() &&
CHECK(obj != filler1 && filler1->IsFiller() && HeapObject::FromAddress(start + kPointerSize)->IsFiller());
filler1->Size() == kPointerSize);
// Try the opposite alignment case. // Try the opposite alignment case.
start = AlignOldSpace(kDoubleAligned, kPointerSize); start = SetUpFreeListAllocation(kPointerSize);
obj = OldSpaceAllocateAligned(kPointerSize, kDoubleAligned); HeapObject* obj2 = OldSpaceAllocateAligned(kPointerSize, kDoubleAligned);
CHECK(IsAddressAligned(obj->address(), kDoubleAlignment)); CHECK(IsAddressAligned(obj2->address(), kDoubleAlignment));
filler1 = HeapObject::FromAddress(start); CHECK(HeapObject::FromAddress(start)->IsFiller() &&
CHECK(obj != filler1); HeapObject::FromAddress(start + kPointerSize)->IsFiller());
CHECK(filler1->IsFiller());
CHECK(filler1->Size() == kPointerSize);
CHECK(obj != filler1 && filler1->IsFiller() &&
filler1->Size() == kPointerSize);
// Similarly for kDoubleUnaligned. // Similarly for kDoubleUnaligned.
start = AlignOldSpace(kDoubleUnaligned, 0); start = SetUpFreeListAllocation(0);
obj = OldSpaceAllocateAligned(kPointerSize, kDoubleUnaligned); obj1 = OldSpaceAllocateAligned(kPointerSize, kDoubleUnaligned);
// The object is aligned, and a filler object is created after. // The object should be aligned, and a filler object should be created.
CHECK(IsAddressAligned(obj->address(), kDoubleAlignment, kPointerSize)); CHECK(IsAddressAligned(obj1->address(), kDoubleAlignment, kPointerSize));
filler1 = HeapObject::FromAddress(start + kPointerSize); CHECK(HeapObject::FromAddress(start)->IsFiller() &&
CHECK(obj != filler1 && filler1->IsFiller() && HeapObject::FromAddress(start + kPointerSize)->IsFiller());
filler1->Size() == kPointerSize);
// Try the opposite alignment case. // Try the opposite alignment case.
start = AlignOldSpace(kDoubleUnaligned, kPointerSize); start = SetUpFreeListAllocation(kPointerSize);
obj = OldSpaceAllocateAligned(kPointerSize, kDoubleUnaligned); obj2 = OldSpaceAllocateAligned(kPointerSize, kDoubleUnaligned);
CHECK(IsAddressAligned(obj->address(), kDoubleAlignment, kPointerSize)); CHECK(IsAddressAligned(obj2->address(), kDoubleAlignment, kPointerSize));
filler1 = HeapObject::FromAddress(start); CHECK(HeapObject::FromAddress(start)->IsFiller() &&
CHECK(obj != filler1 && filler1->IsFiller() && HeapObject::FromAddress(start + kPointerSize)->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);
} }
} }
......
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