Bug 1391103 - Align Maybe::mStorage like when the type is in a struct. r=froydnj
authorXidorn Quan <me@upsuper.org>
Thu, 17 Aug 2017 09:49:19 +1000
changeset 376079 06d2f579a7f39ee0b2f20f43ec7e570fded37872
parent 376078 e534cb50417cc13d1231a310b92a94301fc7ba97
child 376080 6d2fe35e5c6347e9fbdf85f964f563bb8898bf2d
push id94023
push userarchaeopteryx@coole-files.de
push dateTue, 22 Aug 2017 09:51:45 +0000
treeherdermozilla-inbound@2b5a763e1ccd [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersfroydnj
bugs1391103
milestone57.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1391103 - Align Maybe::mStorage like when the type is in a struct. r=froydnj MozReview-Commit-ID: 6ArNhZA4Wdf
mfbt/Alignment.h
mfbt/Maybe.h
--- a/mfbt/Alignment.h
+++ b/mfbt/Alignment.h
@@ -29,16 +29,36 @@ class AlignmentFinder
   };
 
 public:
   static const size_t alignment = sizeof(Aligner) - sizeof(T);
 };
 
 #define MOZ_ALIGNOF(T) mozilla::AlignmentFinder<T>::alignment
 
+namespace detail {
+template<typename T>
+struct AlignasHelper
+{
+  T mT;
+};
+} // namespace detail
+
+/*
+ * Use this instead of alignof to align struct field as if it is inside
+ * a struct. On some platforms, there exist types which have different
+ * alignment between when it is used on its own and when it is used on
+ * a struct field.
+ *
+ * Known examples are 64bit types (uint64_t, double) on 32bit Linux,
+ * where they have 8byte alignment on their own, and 4byte alignment
+ * when in struct.
+ */
+#define MOZ_ALIGNAS_IN_STRUCT(T) alignas(mozilla::detail::AlignasHelper<T>)
+
 /*
  * Declare the MOZ_ALIGNED_DECL macro for declaring aligned types.
  *
  * For instance,
  *
  *   MOZ_ALIGNED_DECL(char arr[2], 8);
  *
  * will declare a two-character array |arr| aligned to 8 bytes.
--- a/mfbt/Maybe.h
+++ b/mfbt/Maybe.h
@@ -80,17 +80,17 @@ struct Nothing { };
  *
  * N.B. GCC has missed optimizations with Maybe in the past and may generate
  * extra branches/loads/stores. Use with caution on hot paths; it's not known
  * whether or not this is still a problem.
  */
 template<class T>
 class MOZ_NON_PARAM MOZ_INHERIT_TYPE_ANNOTATIONS_FROM_TEMPLATE_ARGS Maybe
 {
-  alignas(T) unsigned char mStorage[sizeof(T)];
+  MOZ_ALIGNAS_IN_STRUCT(T) unsigned char mStorage[sizeof(T)];
   char mIsSome; // not bool -- guarantees minimal space consumption
 
   // GCC fails due to -Werror=strict-aliasing if |mStorage| is directly cast to
   // T*.  Indirecting through these functions addresses the problem.
   void* data() { return mStorage; }
   const void* data() const { return mStorage; }
 
 public: