Add V8_ALIGNOF() and use that in lazy-instance.h.
authorbmeurer@chromium.org <bmeurer@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Mon, 26 Aug 2013 08:06:15 +0000 (08:06 +0000)
committerbmeurer@chromium.org <bmeurer@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Mon, 26 Aug 2013 08:06:15 +0000 (08:06 +0000)
Also fix the inconsistent attribute naming, and make V8_GNUC_PREREQ() test work for GCC compatible compilers.

R=svenpanne@chromium.org

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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@16311 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

include/v8config.h
src/lazy-instance.h

index aa24eeb..4f6cf7b 100644 (file)
 #endif
 
 
+// This macro checks for a required GCC version. It also works with compilers
+// that pretend to be GCC, i.e. Clang, ICC or the ARM compiler with the --gnu
+// flag.
+// Use like this if you want to check for a GCC compatible version:
+//   #if V8_GNUC_PREREQ(x, y, z)
+//    ...
+//   #endif
+//
+// Use like ths if you want to check for a specific GCC version:
+//   #if V8_CC_GNU && V8_GNUC_PREREQ(x, y, z)
+//    ...
+//  #endif
+#if defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__GNUC_PATCHLEVEL__)
+# define V8_GNUC_PREREQ(major, minor, patchlevel)                         \
+    ((__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) >=   \
+     ((major) * 10000 + (minor) * 100 + (patchlevel)))
+#elif defined(__GNUC__) && defined(__GNUC_MINOR__)
+# define V8_GNUC_PREREQ(major, minor, patchlevel)       \
+    ((__GNUC__ * 10000 + __GNUC_MINOR__ * 100) >=       \
+     ((major) * 10000 + (minor) * 100 + (patchlevel)))
+#else
+# define V8_GNUC_PREREQ(major, minor, patchlevel) 0
+#endif
+
+
 // -----------------------------------------------------------------------------
 // Compiler detection
 //
 // C++11 feature detection
 //
 //  V8_HAS_CXX11_ALIGNAS        - alignas specifier supported
+//  V8_HAS_CXX11_ALIGNOF        - alignas operator supported
 //  V8_HAS_CXX11_STATIC_ASSERT  - static_assert() supported
 //  V8_HAS_CXX11_DELETE         - deleted functions supported
 //  V8_HAS_CXX11_FINAL          - final marker supported
 //
 // Compiler-specific feature detection
 //
-//  V8_HAS_ATTRIBUTE___ALIGNED__    - __attribute__((__aligned__(n))) supported
+//  V8_HAS___ALIGNOF                - __alignof(t) operator supported
+//  V8_HAS___ALIGNOF__              - __alignof__(t) operator supported
+//  V8_HAS_ATTRIBUTE_ALIGNED        - __attribute__((aligned(n))) supported
 //  V8_HAS_ATTRIBUTE_ALWAYS_INLINE  - __attribute__((always_inline)) supported
 //  V8_HAS_ATTRIBUTE_DEPRECATED     - __attribute__((deprecated)) supported
 //  V8_HAS_ATTRIBUTE_VISIBILITY     - __attribute__((visibility)) supported
 
 #if defined(__clang__)
 
-// Don't treat clang as GCC.
-# define V8_GNUC_PREREQ(major, minor, patchlevel) 0
-
 # define V8_CC_CLANG 1
 
-# define V8_HAS_ATTRIBUTE___ALIGNED__ (__has_attribute(__aligned__))
+# define V8_HAS___ALIGNOF__ (V8_GNUC_PREREQ(2, 95, 0))
+
+# define V8_HAS_ATTRIBUTE_ALIGNED (__has_attribute(aligned))
 # define V8_HAS_ATTRIBUTE_ALWAYS_INLINE (__has_attribute(always_inline))
 # define V8_HAS_ATTRIBUTE_DEPRECATED (__has_attribute(deprecated))
 # define V8_HAS_ATTRIBUTE_VISIBILITY (__has_attribute(visibility))
 
 #elif defined(__GNUC__)
 
-# define V8_GNUC_PREREQ(major, minor, patchlevel)                         \
-    ((__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) >=   \
-     ((major) * 10000 + (minor) * 100 + (patchlevel)))
-
 # define V8_CC_GNU 1
 # if defined(__MINGW32__)
 #  define V8_CC_MINGW 1
 # endif
 
-# define V8_HAS_ATTRIBUTE___ALIGNED__ (V8_GNUC_PREREQ(2, 95, 0))
+# define V8_HAS___ALIGNOF__ (V8_GNUC_PREREQ(2, 95, 0))
+
+# define V8_HAS_ATTRIBUTE_ALIGNED (V8_GNUC_PREREQ(2, 95, 0))
 // always_inline is available in gcc 4.0 but not very reliable until 4.4.
 // Works around "sorry, unimplemented: inlining failed" build errors with
 // older compilers.
 // both for forward compatibility.
 # if defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103L
 #  define V8_HAS_CXX11_ALIGNAS (V8_GNUC_PREREQ(4, 8, 0))
+#  define V8_HAS_CXX11_ALIGNOF (V8_GNUC_PREREQ(4, 5, 0))
 #  define V8_HAS_CXX11_STATIC_ASSERT (V8_GNUC_PREREQ(4, 3, 0))
 #  define V8_HAS_CXX11_DELETE (V8_GNUC_PREREQ(4, 4, 0))
 #  define V8_HAS_CXX11_OVERRIDE (V8_GNUC_PREREQ(4, 7, 0))
 
 #elif defined(_MSC_VER)
 
-# define V8_GNUC_PREREQ(major, minor, patchlevel) 0
-
 # define V8_CC_MSVC 1
 
 // Override control was added with Visual Studio 2005, but
 # define V8_HAS_DECLSPEC_ALIGN 1
 # define V8_HAS_DECLSPEC_DEPRECATED (_MSC_VER >= 1300)
 
+# define V8_HAS___ALIGNOF 1
 # define V8_HAS___FORCEINLINE 1
 
 #endif
 //   V8_ALIGNAS(32) int array[42];
 #if V8_HAS_CXX11_ALIGNAS
 # define V8_ALIGNAS(n) alignas(n)
-#elif V8_HAS_ATTRIBUTE___ALIGNED__
-# define V8_ALIGNAS(n) __attribute__((__aligned__(n)))
+#elif V8_HAS_ATTRIBUTE_ALIGNED
+# define V8_ALIGNAS(n) __attribute__((aligned(n)))
 #elif V8_HAS_DECLSPEC_ALIGN
 # define V8_ALIGNAS(n) __declspec(align(n))
 #else
 # define V8_ALIGNAS(n) /* NOT SUPPORTED */
 #endif
 
+// This macro takes a type and returns the power of 2 byte boundary on which
+// the type instances must be allocated.
+// Use like:
+//   size_t alignment = V8_ALIGNOF(double);
+//   V8_ALIGNAS(V8_ALIGNOF(void*)) int x;
+#if V8_HAS_CXX11_ALIGNOF
+# define V8_ALIGNOF(t) alignof(t)
+#elif V8_HAS___ALIGNOF
+# define V8_ALIGNOF(t) __alignof(t)
+#elif V8_HAS___ALIGNOF__
+# define V8_ALIGNOF(t) __alignof__(t)
+#else
+namespace v8 { template <typename T> struct AlignOfHelper { char x; T t; }; }
+# define V8_ALIGNOF(t) (sizeof(::v8::AlignOfHelper<t>) - sizeof(t))
+#endif
+
 #endif  // V8CONFIG_H_
index 9d68b8c..cdde225 100644 (file)
@@ -111,17 +111,9 @@ struct LeakyInstanceTrait {
 
 // Traits that define how an instance is allocated and accessed.
 
-// TODO(kalmard): __alignof__ is only defined for GCC > 4.2. Fix alignment issue
-// on MIPS with other compilers.
-#if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 2))
-#define LAZY_ALIGN(x) __attribute__((aligned(__alignof__(x))))
-#else
-#define LAZY_ALIGN(x)
-#endif
-
 template <typename T>
 struct StaticallyAllocatedInstanceTrait {
-  typedef char StorageType[sizeof(T)] LAZY_ALIGN(T);
+  typedef char StorageType[sizeof(T)] V8_ALIGNAS(V8_ALIGNOF(T));
 
   static T* MutableInstance(StorageType* storage) {
     return reinterpret_cast<T*>(storage);
@@ -133,8 +125,6 @@ struct StaticallyAllocatedInstanceTrait {
   }
 };
 
-#undef LAZY_ALIGN
-
 
 template <typename T>
 struct DynamicallyAllocatedInstanceTrait {