1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 /* Functionality related to memory alignment. */
9 #ifndef mozilla_Alignment_h
10 #define mozilla_Alignment_h
12 #include "mozilla/Attributes.h"
19 * This class, and the corresponding macro MOZ_ALIGNOF, figures out how many
20 * bytes of alignment a given type needs.
23 class AlignmentFinder
{
28 // Aligner may be used to check alignment of types with deleted dtors. This
29 // results in such specializations having implicitly deleted dtors, which
30 // causes fatal warnings on MSVC (see bug 1481005). As we don't create
31 // Aligners, we can avoid this warning by explicitly deleting the dtor.
36 static const size_t alignment
= sizeof(Aligner
) - sizeof(T
);
39 #define MOZ_ALIGNOF(T) mozilla::AlignmentFinder<T>::alignment
43 struct AlignasHelper
{
49 * Use this instead of alignof to align struct field as if it is inside
50 * a struct. On some platforms, there exist types which have different
51 * alignment between when it is used on its own and when it is used on
54 * Known examples are 64bit types (uint64_t, double) on 32bit Linux,
55 * where they have 8byte alignment on their own, and 4byte alignment
58 #define MOZ_ALIGNAS_IN_STRUCT(T) alignas(mozilla::detail::AlignasHelper<T>)
61 * Declare the MOZ_ALIGNED_DECL macro for declaring aligned types.
65 * MOZ_ALIGNED_DECL(8, char arr[2]);
67 * will declare a two-character array |arr| aligned to 8 bytes.
71 # define MOZ_ALIGNED_DECL(_align, _type) _type __attribute__((aligned(_align)))
72 #elif defined(_MSC_VER)
73 # define MOZ_ALIGNED_DECL(_align, _type) __declspec(align(_align)) _type
75 # warning "We don't know how to align variables on this compiler."
76 # define MOZ_ALIGNED_DECL(_align, _type) _type
80 * AlignedElem<N> is a structure whose alignment is guaranteed to be at least N
83 * We support 1, 2, 4, 8, and 16-byte alignment.
85 template <size_t Align
>
89 * We have to specialize this template because GCC doesn't like
90 * __attribute__((aligned(foo))) where foo is a template parameter.
94 struct AlignedElem
<1> {
95 MOZ_ALIGNED_DECL(1, uint8_t elem
);
99 struct AlignedElem
<2> {
100 MOZ_ALIGNED_DECL(2, uint8_t elem
);
104 struct AlignedElem
<4> {
105 MOZ_ALIGNED_DECL(4, uint8_t elem
);
109 struct AlignedElem
<8> {
110 MOZ_ALIGNED_DECL(8, uint8_t elem
);
114 struct AlignedElem
<16> {
115 MOZ_ALIGNED_DECL(16, uint8_t elem
);
118 template <typename T
>
119 struct MOZ_INHERIT_TYPE_ANNOTATIONS_FROM_TEMPLATE_ARGS AlignedStorage2
{
121 char mBytes
[sizeof(T
)];
125 const T
* addr() const { return reinterpret_cast<const T
*>(u
.mBytes
); }
126 T
* addr() { return static_cast<T
*>(static_cast<void*>(u
.mBytes
)); }
128 AlignedStorage2() = default;
130 // AlignedStorage2 is non-copyable: the default copy constructor violates
131 // strict aliasing rules, per bug 1269319.
132 AlignedStorage2(const AlignedStorage2
&) = delete;
133 void operator=(const AlignedStorage2
&) = delete;
136 } /* namespace mozilla */
138 #endif /* mozilla_Alignment_h */