Revert of Add SIMD 128 alignment support to Heap. (patchset #3 id:40001 of https...
authorbbudge <bbudge@chromium.org>
Tue, 2 Jun 2015 21:13:14 +0000 (14:13 -0700)
committerCommit bot <commit-bot@chromium.org>
Tue, 2 Jun 2015 21:13:23 +0000 (21:13 +0000)
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}

src/globals.h
src/heap/heap.cc
test/cctest/test-heap.cc

index c73f395cb6808672ffc19863112facb8c32c4752..7fdcc26cea74de84912a03291a9ce9b4b1015b98 100644 (file)
@@ -197,8 +197,6 @@ typedef int32_t uc32;
 const int kOneByteSize    = kCharSize;
 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.
 #define ROUND_UP(n, sz) (((n) + ((sz) - 1)) & ~((sz) - 1))
@@ -311,10 +309,6 @@ const intptr_t kPointerAlignmentMask = kPointerAlignment - 1;
 const intptr_t kDoubleAlignment = 8;
 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
 // utilization).
 const int kCodeAlignmentBits = 5;
@@ -455,12 +449,7 @@ enum AllocationSpace {
 const int kSpaceTagSize = 3;
 const int kSpaceTagMask = (1 << kSpaceTagSize) - 1;
 
-enum AllocationAlignment {
-  kWordAligned,
-  kDoubleAligned,
-  kDoubleUnaligned,
-  kSimd128Unaligned
-};
+enum AllocationAlignment { kWordAligned, kDoubleAligned, kDoubleUnaligned };
 
 // A flag that indicates whether objects should be pretenured when
 // allocated (allocated directly into the old generation) or not
index 9e684927a86b862372c3d9a47b6c48bdfee11a02..ff9cc5b46b4cf1be4cb8eb636021ef1b00922d64 100644 (file)
@@ -1995,8 +1995,6 @@ int Heap::GetMaximumFillToAlign(AllocationAlignment alignment) {
     case kDoubleAligned:
     case kDoubleUnaligned:
       return kDoubleSize - kPointerSize;
-    case kSimd128Unaligned:
-      return kSimd128Size - kPointerSize;
     default:
       UNREACHABLE();
   }
@@ -2010,10 +2008,6 @@ int Heap::GetFillToAlign(Address address, AllocationAlignment alignment) {
     return kPointerSize;
   if (alignment == kDoubleUnaligned && (offset & kDoubleAlignmentMask) == 0)
     return kDoubleSize - kPointerSize;  // No fill if double is always aligned.
-  if (alignment == kSimd128Unaligned) {
-    return (kSimd128Size - (static_cast<int>(offset) + kPointerSize)) &
-           kSimd128AlignmentMask;
-  }
   return 0;
 }
 
index 9e3c80ec39b766ec35892dba25cbe134d2b21cc2..a9cb60e985d3c96c2d99e6d2cacdcca6ab764c23 100644 (file)
@@ -1784,18 +1784,14 @@ TEST(TestSizeOfObjects) {
 
 
 TEST(TestAlignmentCalculations) {
-  // Maximum fill amounts are consistent.
+  // Maximum fill amounts should be 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;
@@ -1817,16 +1813,6 @@ 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);
 }
 
 
@@ -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) {
   // 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) {
-    // 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.
+    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.
     CHECK_EQ(kPointerSize, *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);
-
-    // Similarly for kDoubleUnaligned.
-    start = AlignNewSpace(kDoubleUnaligned, 0);
-    obj = NewSpaceAllocateAligned(kPointerSize, kDoubleUnaligned);
-    CHECK(IsAddressAligned(obj->address(), kDoubleAlignment, kPointerSize));
+    // 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);
-    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);
+    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);
   }
 }
 
 
+// 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,
                                            AllocationAlignment alignment) {
   Heap* heap = CcTest::heap();
@@ -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
 // 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) {
-    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);
+    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());
     // Try the opposite alignment case.
-    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);
+    start = SetUpFreeListAllocation(kPointerSize);
+    HeapObject* obj2 = OldSpaceAllocateAligned(kPointerSize, kDoubleAligned);
+    CHECK(IsAddressAligned(obj2->address(), kDoubleAlignment));
+    CHECK(HeapObject::FromAddress(start)->IsFiller() &&
+          HeapObject::FromAddress(start + kPointerSize)->IsFiller());
 
     // Similarly for kDoubleUnaligned.
-    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);
+    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());
     // Try the opposite alignment case.
-    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);
+    start = SetUpFreeListAllocation(kPointerSize);
+    obj2 = OldSpaceAllocateAligned(kPointerSize, kDoubleUnaligned);
+    CHECK(IsAddressAligned(obj2->address(), kDoubleAlignment, kPointerSize));
+    CHECK(HeapObject::FromAddress(start)->IsFiller() &&
+          HeapObject::FromAddress(start + kPointerSize)->IsFiller());
   }
 }