Bug N - Use alignas instead of union hack in nsTArray/SegmentedVector
authorBirunthan Mohanathas <birunthan@mohanathas.com>
Thu, 02 Jun 2016 17:02:34 +0300
changeset 775100 9761692294413e84878046507303b54935b5c52e
parent 775099 6bf88be59a98a30a9aa6f935c133ba74d28adf11
child 775101 c6735163c16e8d2bcadeec3e951b029035baa84d
push id128147
push userbirunthan@mohanathas.com
push dateThu, 02 Jun 2016 14:04:55 +0000
treeherdertry@333eadb08860 [default view] [failures only]
milestone49.0a1
Bug N - Use alignas instead of union hack in nsTArray/SegmentedVector
mfbt/SegmentedVector.h
xpcom/glue/nsTArray.h
--- a/mfbt/SegmentedVector.h
+++ b/mfbt/SegmentedVector.h
@@ -15,17 +15,16 @@
 //
 // - In the case where you know the final size in advance and so can set the
 //   capacity appropriately, using SegmentedVector still avoids the need for
 //   large allocations (which can trigger OOMs).
 
 #ifndef mozilla_SegmentedVector_h
 #define mozilla_SegmentedVector_h
 
-#include "mozilla/Alignment.h"
 #include "mozilla/AllocPolicy.h"
 #include "mozilla/Array.h"
 #include "mozilla/LinkedList.h"
 #include "mozilla/MemoryReporting.h"
 #include "mozilla/Move.h"
 #include "mozilla/TypeTraits.h"
 
 #include <new>  // for placement new
@@ -63,17 +62,17 @@ class SegmentedVector : private AllocPol
     {
       for (uint32_t i = 0; i < mLength; i++) {
         (*this)[i].~T();
       }
     }
 
     uint32_t Length() const { return mLength; }
 
-    T* Elems() { return reinterpret_cast<T*>(&mStorage.mBuf); }
+    T* Elems() { return reinterpret_cast<T*>(&mBuf); }
 
     T& operator[](size_t aIndex)
     {
       MOZ_ASSERT(aIndex < mLength);
       return Elems()[aIndex];
     }
 
     const T& operator[](size_t aIndex) const
@@ -95,26 +94,17 @@ class SegmentedVector : private AllocPol
     void PopLast()
     {
       MOZ_ASSERT(mLength > 0);
       (*this)[mLength - 1].~T();
       mLength--;
     }
 
     uint32_t mLength;
-
-    // The union ensures that the elements are appropriately aligned.
-    union Storage
-    {
-      char mBuf[sizeof(T) * SegmentCapacity];
-      mozilla::AlignedElem<alignof(T)> mAlign;
-    } mStorage;
-
-    static_assert(alignof(T) == alignof(Storage),
-                  "SegmentedVector provides incorrect alignment");
+    alignas(alignof(T)) char mBuf[sizeof(T) * SegmentCapacity];
   };
 
   // See how many we elements we can fit in a segment of IdealSegmentSize. If
   // IdealSegmentSize is too small, it'll be just one. The +1 is because
   // kSingleElementSegmentSize already accounts for one element.
   static const size_t kSingleElementSegmentSize = sizeof(SegmentImpl<1>);
   static const size_t kSegmentCapacity =
     kSingleElementSegmentSize <= IdealSegmentSize
--- a/xpcom/glue/nsTArray.h
+++ b/xpcom/glue/nsTArray.h
@@ -2272,27 +2272,20 @@ private:
     (*phdr)->mCapacity = N;
     (*phdr)->mIsAutoArray = 1;
 
     MOZ_ASSERT(base_type::GetAutoArrayBuffer(alignof(elem_type)) ==
                reinterpret_cast<Header*>(&mAutoBuf),
                "GetAutoArrayBuffer needs to be fixed");
   }
 
-  // Declare mAutoBuf aligned to the maximum of the header's alignment and
-  // elem_type's alignment.  We need to use a union rather than
-  // MOZ_ALIGNED_DECL because GCC is picky about what goes into
-  // __attribute__((aligned(foo))).
-  union
-  {
-    char mAutoBuf[sizeof(nsTArrayHeader) + N * sizeof(elem_type)];
-    // Do the max operation inline to ensure that it is a compile-time constant.
-    mozilla::AlignedElem<(alignof(Header) > alignof(elem_type)) ?
-                         alignof(Header) : alignof(elem_type)> mAlign;
-  };
+  static const size_t kAlign = (alignof(Header) > alignof(elem_type))
+                                  ? alignof(Header)
+                                  : alignof(elem_type);
+  alignas(kAlign) char mAutoBuf[sizeof(nsTArrayHeader) + N * sizeof(elem_type)];
 };
 
 //
 // Specialization of AutoTArray<E, N> for the case where N == 0.
 // AutoTArray<E, 0> behaves exactly like nsTArray<E>, but without this
 // specialization, it stores a useless inline header.
 //
 // We do have many AutoTArray<E, 0> objects in memory: about 2,000 per tab as