Move platform abstraction to base library
[platform/upstream/v8.git] / src / base / macros.h
1 // Copyright 2014 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #ifndef V8_BASE_MACROS_H_
6 #define V8_BASE_MACROS_H_
7
8 #include "include/v8stdint.h"
9 #include "src/base/build_config.h"
10 #include "src/base/logging.h"
11
12
13 // The expression OFFSET_OF(type, field) computes the byte-offset
14 // of the specified field relative to the containing type. This
15 // corresponds to 'offsetof' (in stddef.h), except that it doesn't
16 // use 0 or NULL, which causes a problem with the compiler warnings
17 // we have enabled (which is also why 'offsetof' doesn't seem to work).
18 // Here we simply use the non-zero value 4, which seems to work.
19 #define OFFSET_OF(type, field)                                          \
20   (reinterpret_cast<intptr_t>(&(reinterpret_cast<type*>(4)->field)) - 4)
21
22
23 // The expression ARRAY_SIZE(a) is a compile-time constant of type
24 // size_t which represents the number of elements of the given
25 // array. You should only use ARRAY_SIZE on statically allocated
26 // arrays.
27 #define ARRAY_SIZE(a)                                   \
28   ((sizeof(a) / sizeof(*(a))) /                         \
29   static_cast<size_t>(!(sizeof(a) % sizeof(*(a)))))
30
31
32 // A macro to disallow the evil copy constructor and operator= functions
33 // This should be used in the private: declarations for a class
34 #define DISALLOW_COPY_AND_ASSIGN(TypeName)  \
35   TypeName(const TypeName&) V8_DELETE;      \
36   void operator=(const TypeName&) V8_DELETE
37
38
39 // A macro to disallow all the implicit constructors, namely the
40 // default constructor, copy constructor and operator= functions.
41 //
42 // This should be used in the private: declarations for a class
43 // that wants to prevent anyone from instantiating it. This is
44 // especially useful for classes containing only static methods.
45 #define DISALLOW_IMPLICIT_CONSTRUCTORS(TypeName)  \
46   TypeName() V8_DELETE;                           \
47   DISALLOW_COPY_AND_ASSIGN(TypeName)
48
49
50 // Newly written code should use V8_INLINE and V8_NOINLINE directly.
51 #define INLINE(declarator)    V8_INLINE declarator
52 #define NO_INLINE(declarator) V8_NOINLINE declarator
53
54
55 // Newly written code should use V8_WARN_UNUSED_RESULT.
56 #define MUST_USE_RESULT V8_WARN_UNUSED_RESULT
57
58
59 // Define V8_USE_ADDRESS_SANITIZER macros.
60 #if defined(__has_feature)
61 #if __has_feature(address_sanitizer)
62 #define V8_USE_ADDRESS_SANITIZER 1
63 #endif
64 #endif
65
66 // Define DISABLE_ASAN macros.
67 #ifdef V8_USE_ADDRESS_SANITIZER
68 #define DISABLE_ASAN __attribute__((no_sanitize_address))
69 #else
70 #define DISABLE_ASAN
71 #endif
72
73
74 #if V8_CC_GNU
75 #define V8_IMMEDIATE_CRASH() __builtin_trap()
76 #else
77 #define V8_IMMEDIATE_CRASH() ((void(*)())0)()
78 #endif
79
80
81 // Use C++11 static_assert if possible, which gives error
82 // messages that are easier to understand on first sight.
83 #if V8_HAS_CXX11_STATIC_ASSERT
84 #define STATIC_ASSERT(test) static_assert(test, #test)
85 #else
86 // This is inspired by the static assertion facility in boost.  This
87 // is pretty magical.  If it causes you trouble on a platform you may
88 // find a fix in the boost code.
89 template <bool> class StaticAssertion;
90 template <> class StaticAssertion<true> { };
91 // This macro joins two tokens.  If one of the tokens is a macro the
92 // helper call causes it to be resolved before joining.
93 #define SEMI_STATIC_JOIN(a, b) SEMI_STATIC_JOIN_HELPER(a, b)
94 #define SEMI_STATIC_JOIN_HELPER(a, b) a##b
95 // Causes an error during compilation of the condition is not
96 // statically known to be true.  It is formulated as a typedef so that
97 // it can be used wherever a typedef can be used.  Beware that this
98 // actually causes each use to introduce a new defined type with a
99 // name depending on the source line.
100 template <int> class StaticAssertionHelper { };
101 #define STATIC_ASSERT(test)                                                    \
102   typedef                                                                     \
103     StaticAssertionHelper<sizeof(StaticAssertion<static_cast<bool>((test))>)> \
104     SEMI_STATIC_JOIN(__StaticAssertTypedef__, __LINE__) V8_UNUSED
105
106 #endif
107
108
109 // The USE(x) template is used to silence C++ compiler warnings
110 // issued for (yet) unused variables (typically parameters).
111 template <typename T>
112 inline void USE(T) { }
113
114
115 #define IS_POWER_OF_TWO(x) ((x) != 0 && (((x) & ((x) - 1)) == 0))
116
117
118 // Returns true iff x is a power of 2. Cannot be used with the maximally
119 // negative value of the type T (the -1 overflows).
120 template <typename T>
121 inline bool IsPowerOf2(T x) {
122   return IS_POWER_OF_TWO(x);
123 }
124
125
126 // Define our own macros for writing 64-bit constants.  This is less fragile
127 // than defining __STDC_CONSTANT_MACROS before including <stdint.h>, and it
128 // works on compilers that don't have it (like MSVC).
129 #if V8_CC_MSVC
130 # define V8_UINT64_C(x)   (x ## UI64)
131 # define V8_INT64_C(x)    (x ## I64)
132 # if V8_HOST_ARCH_64_BIT
133 #  define V8_INTPTR_C(x)  (x ## I64)
134 #  define V8_PTR_PREFIX   "ll"
135 # else
136 #  define V8_INTPTR_C(x)  (x)
137 #  define V8_PTR_PREFIX   ""
138 # endif  // V8_HOST_ARCH_64_BIT
139 #elif V8_CC_MINGW64
140 # define V8_UINT64_C(x)   (x ## ULL)
141 # define V8_INT64_C(x)    (x ## LL)
142 # define V8_INTPTR_C(x)   (x ## LL)
143 # define V8_PTR_PREFIX    "I64"
144 #elif V8_HOST_ARCH_64_BIT
145 # if V8_OS_MACOSX
146 #  define V8_UINT64_C(x)   (x ## ULL)
147 #  define V8_INT64_C(x)    (x ## LL)
148 # else
149 #  define V8_UINT64_C(x)   (x ## UL)
150 #  define V8_INT64_C(x)    (x ## L)
151 # endif
152 # define V8_INTPTR_C(x)   (x ## L)
153 # define V8_PTR_PREFIX    "l"
154 #else
155 # define V8_UINT64_C(x)   (x ## ULL)
156 # define V8_INT64_C(x)    (x ## LL)
157 # define V8_INTPTR_C(x)   (x)
158 # define V8_PTR_PREFIX    ""
159 #endif
160
161 #define V8PRIxPTR V8_PTR_PREFIX "x"
162 #define V8PRIdPTR V8_PTR_PREFIX "d"
163 #define V8PRIuPTR V8_PTR_PREFIX "u"
164
165 // Fix for Mac OS X defining uintptr_t as "unsigned long":
166 #if V8_OS_MACOSX
167 #undef V8PRIxPTR
168 #define V8PRIxPTR "lx"
169 #endif
170
171 // The following macro works on both 32 and 64-bit platforms.
172 // Usage: instead of writing 0x1234567890123456
173 //      write V8_2PART_UINT64_C(0x12345678,90123456);
174 #define V8_2PART_UINT64_C(a, b) (((static_cast<uint64_t>(a) << 32) + 0x##b##u))
175
176
177 // Compute the 0-relative offset of some absolute value x of type T.
178 // This allows conversion of Addresses and integral types into
179 // 0-relative int offsets.
180 template <typename T>
181 inline intptr_t OffsetFrom(T x) {
182   return x - static_cast<T>(0);
183 }
184
185
186 // Compute the absolute value of type T for some 0-relative offset x.
187 // This allows conversion of 0-relative int offsets into Addresses and
188 // integral types.
189 template <typename T>
190 inline T AddressFrom(intptr_t x) {
191   return static_cast<T>(static_cast<T>(0) + x);
192 }
193
194
195 // Return the largest multiple of m which is <= x.
196 template <typename T>
197 inline T RoundDown(T x, intptr_t m) {
198   ASSERT(IsPowerOf2(m));
199   return AddressFrom<T>(OffsetFrom(x) & -m);
200 }
201
202
203 // Return the smallest multiple of m which is >= x.
204 template <typename T>
205 inline T RoundUp(T x, intptr_t m) {
206   return RoundDown<T>(static_cast<T>(x + m - 1), m);
207 }
208
209
210 // Increment a pointer until it has the specified alignment.
211 // This works like RoundUp, but it works correctly on pointer types where
212 // sizeof(*pointer) might not be 1.
213 template<class T>
214 T AlignUp(T pointer, size_t alignment) {
215   ASSERT(sizeof(pointer) == sizeof(uintptr_t));
216   uintptr_t pointer_raw = reinterpret_cast<uintptr_t>(pointer);
217   return reinterpret_cast<T>(RoundUp(pointer_raw, alignment));
218 }
219
220
221 template <typename T, typename U>
222 inline bool IsAligned(T value, U alignment) {
223   return (value & (alignment - 1)) == 0;
224 }
225
226
227 // Returns the smallest power of two which is >= x. If you pass in a
228 // number that is already a power of two, it is returned as is.
229 // Implementation is from "Hacker's Delight" by Henry S. Warren, Jr.,
230 // figure 3-3, page 48, where the function is called clp2.
231 inline uint32_t RoundUpToPowerOf2(uint32_t x) {
232   ASSERT(x <= 0x80000000u);
233   x = x - 1;
234   x = x | (x >> 1);
235   x = x | (x >> 2);
236   x = x | (x >> 4);
237   x = x | (x >> 8);
238   x = x | (x >> 16);
239   return x + 1;
240 }
241
242
243 inline uint32_t RoundDownToPowerOf2(uint32_t x) {
244   uint32_t rounded_up = RoundUpToPowerOf2(x);
245   if (rounded_up > x) return rounded_up >> 1;
246   return rounded_up;
247 }
248
249 #endif   // V8_BASE_MACROS_H_