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 "src/base/compiler-specific.h"
9 #include "src/base/format-macros.h"
10 #include "src/base/logging.h"
11
12
13 // TODO(all) Replace all uses of this macro with C++'s offsetof. To do that, we
14 // have to make sure that only standard-layout types and simple field
15 // designators are used.
16 #define OFFSET_OF(type, field) \
17 (reinterpret_cast<intptr_t>(&(reinterpret_cast<type*>(16)->field)) - 16)
18
19
20 // The arraysize(arr) macro returns the # of elements in an array arr.
21 // The expression is a compile-time constant, and therefore can be
22 // used in defining new arrays, for example. If you use arraysize on
23 // a pointer by mistake, you will get a compile-time error.
24 #define arraysize(array) (sizeof(ArraySizeHelper(array)))
25
26
27 // This template function declaration is used in defining arraysize.
28 // Note that the function doesn't need an implementation, as we only
29 // use its type.
30 template <typename T, size_t N>
31 char (&ArraySizeHelper(T (&array)[N]))[N];
32
33
34 #if !V8_CC_MSVC
35 // That gcc wants both of these prototypes seems mysterious. VC, for
36 // its part, can't decide which to use (another mystery). Matching of
37 // template overloads: the final frontier.
38 template <typename T, size_t N>
39 char (&ArraySizeHelper(const T (&array)[N]))[N];
40 #endif
41
42
43 // bit_cast<Dest,Source> is a template function that implements the
44 // equivalent of "*reinterpret_cast<Dest*>(&source)". We need this in
45 // very low-level functions like the protobuf library and fast math
46 // support.
47 //
48 // float f = 3.14159265358979;
49 // int i = bit_cast<int32>(f);
50 // // i = 0x40490fdb
51 //
52 // The classical address-casting method is:
53 //
54 // // WRONG
55 // float f = 3.14159265358979; // WRONG
56 // int i = * reinterpret_cast<int*>(&f); // WRONG
57 //
58 // The address-casting method actually produces undefined behavior
59 // according to ISO C++ specification section 3.10 -15 -. Roughly, this
60 // section says: if an object in memory has one type, and a program
61 // accesses it with a different type, then the result is undefined
62 // behavior for most values of "different type".
63 //
64 // This is true for any cast syntax, either *(int*)&f or
65 // *reinterpret_cast<int*>(&f). And it is particularly true for
66 // conversions between integral lvalues and floating-point lvalues.
67 //
68 // The purpose of 3.10 -15- is to allow optimizing compilers to assume
69 // that expressions with different types refer to different memory. gcc
70 // 4.0.1 has an optimizer that takes advantage of this. So a
71 // non-conforming program quietly produces wildly incorrect output.
72 //
73 // The problem is not the use of reinterpret_cast. The problem is type
74 // punning: holding an object in memory of one type and reading its bits
75 // back using a different type.
76 //
77 // The C++ standard is more subtle and complex than this, but that
78 // is the basic idea.
79 //
80 // Anyways ...
81 //
82 // bit_cast<> calls memcpy() which is blessed by the standard,
83 // especially by the example in section 3.9 . Also, of course,
84 // bit_cast<> wraps up the nasty logic in one place.
85 //
86 // Fortunately memcpy() is very fast. In optimized mode, with a
87 // constant size, gcc 2.95.3, gcc 4.0.1, and msvc 7.1 produce inline
88 // code with the minimal amount of data movement. On a 32-bit system,
89 // memcpy(d,s,4) compiles to one load and one store, and memcpy(d,s,8)
90 // compiles to two loads and two stores.
91 //
92 // I tested this code with gcc 2.95.3, gcc 4.0.1, icc 8.1, and msvc 7.1.
93 //
94 // WARNING: if Dest or Source is a non-POD type, the result of the memcpy
95 // is likely to surprise you.
96 template <class Dest, class Source>
bit_cast(Source const & source)97 V8_INLINE Dest bit_cast(Source const& source) {
98 static_assert(sizeof(Dest) == sizeof(Source),
99 "source and dest must be same size");
100 Dest dest;
101 memcpy(&dest, &source, sizeof(dest));
102 return dest;
103 }
104
105
106 // Put this in the private: declarations for a class to be unassignable.
107 #define DISALLOW_ASSIGN(TypeName) void operator=(const TypeName&)
108
109
110 // A macro to disallow the evil copy constructor and operator= functions
111 // This should be used in the private: declarations for a class
112 #define DISALLOW_COPY_AND_ASSIGN(TypeName) \
113 TypeName(const TypeName&) = delete; \
114 void operator=(const TypeName&) = delete
115
116
117 // A macro to disallow all the implicit constructors, namely the
118 // default constructor, copy constructor and operator= functions.
119 //
120 // This should be used in the private: declarations for a class
121 // that wants to prevent anyone from instantiating it. This is
122 // especially useful for classes containing only static methods.
123 #define DISALLOW_IMPLICIT_CONSTRUCTORS(TypeName) \
124 TypeName() = delete; \
125 DISALLOW_COPY_AND_ASSIGN(TypeName)
126
127
128 // Newly written code should use V8_INLINE and V8_NOINLINE directly.
129 #define INLINE(declarator) V8_INLINE declarator
130 #define NO_INLINE(declarator) V8_NOINLINE declarator
131
132
133 // Newly written code should use WARN_UNUSED_RESULT.
134 #define MUST_USE_RESULT WARN_UNUSED_RESULT
135
136
137 // Define V8_USE_ADDRESS_SANITIZER macros.
138 #if defined(__has_feature)
139 #if __has_feature(address_sanitizer)
140 #define V8_USE_ADDRESS_SANITIZER 1
141 #endif
142 #endif
143
144 // Define DISABLE_ASAN macros.
145 #ifdef V8_USE_ADDRESS_SANITIZER
146 #define DISABLE_ASAN __attribute__((no_sanitize_address))
147 #else
148 #define DISABLE_ASAN
149 #endif
150
151 // DISABLE_CFI_PERF -- Disable Control Flow Integrity checks for Perf reasons.
152 #if !defined(DISABLE_CFI_PERF)
153 #if defined(__clang__) && defined(__has_attribute)
154 #if __has_attribute(no_sanitize)
155 #define DISABLE_CFI_PERF __attribute__((no_sanitize("cfi")))
156 #endif
157 #endif
158 #endif
159 #if !defined(DISABLE_CFI_PERF)
160 #define DISABLE_CFI_PERF
161 #endif
162
163 #if V8_CC_GNU
164 #define V8_IMMEDIATE_CRASH() __builtin_trap()
165 #else
166 #define V8_IMMEDIATE_CRASH() ((void(*)())0)()
167 #endif
168
169
170 // TODO(all) Replace all uses of this macro with static_assert, remove macro.
171 #define STATIC_ASSERT(test) static_assert(test, #test)
172
173
174 // The USE(x) template is used to silence C++ compiler warnings
175 // issued for (yet) unused variables (typically parameters).
176 template <typename T>
USE(T)177 inline void USE(T) { }
178
179
180 #define IS_POWER_OF_TWO(x) ((x) != 0 && (((x) & ((x) - 1)) == 0))
181
182
183 // Define our own macros for writing 64-bit constants. This is less fragile
184 // than defining __STDC_CONSTANT_MACROS before including <stdint.h>, and it
185 // works on compilers that don't have it (like MSVC).
186 #if V8_CC_MSVC
187 # define V8_UINT64_C(x) (x ## UI64)
188 # define V8_INT64_C(x) (x ## I64)
189 # if V8_HOST_ARCH_64_BIT
190 # define V8_INTPTR_C(x) (x ## I64)
191 # define V8_PTR_PREFIX "ll"
192 # else
193 # define V8_INTPTR_C(x) (x)
194 # define V8_PTR_PREFIX ""
195 # endif // V8_HOST_ARCH_64_BIT
196 #elif V8_CC_MINGW64
197 # define V8_UINT64_C(x) (x ## ULL)
198 # define V8_INT64_C(x) (x ## LL)
199 # define V8_INTPTR_C(x) (x ## LL)
200 # define V8_PTR_PREFIX "I64"
201 #elif V8_HOST_ARCH_64_BIT
202 # if V8_OS_MACOSX || V8_OS_OPENBSD
203 # define V8_UINT64_C(x) (x ## ULL)
204 # define V8_INT64_C(x) (x ## LL)
205 # else
206 # define V8_UINT64_C(x) (x ## UL)
207 # define V8_INT64_C(x) (x ## L)
208 # endif
209 # define V8_INTPTR_C(x) (x ## L)
210 # define V8_PTR_PREFIX "l"
211 #else
212 # define V8_UINT64_C(x) (x ## ULL)
213 # define V8_INT64_C(x) (x ## LL)
214 # define V8_INTPTR_C(x) (x)
215 #if V8_OS_AIX
216 #define V8_PTR_PREFIX "l"
217 #else
218 # define V8_PTR_PREFIX ""
219 #endif
220 #endif
221
222 #define V8PRIxPTR V8_PTR_PREFIX "x"
223 #define V8PRIdPTR V8_PTR_PREFIX "d"
224 #define V8PRIuPTR V8_PTR_PREFIX "u"
225
226 // ptrdiff_t is 't' according to the standard, but MSVC uses 'I'.
227 #if V8_CC_MSVC
228 #define V8PRIxPTRDIFF "Ix"
229 #define V8PRIdPTRDIFF "Id"
230 #define V8PRIuPTRDIFF "Iu"
231 #else
232 #define V8PRIxPTRDIFF "tx"
233 #define V8PRIdPTRDIFF "td"
234 #define V8PRIuPTRDIFF "tu"
235 #endif
236
237 // Fix for Mac OS X defining uintptr_t as "unsigned long":
238 #if V8_OS_MACOSX
239 #undef V8PRIxPTR
240 #define V8PRIxPTR "lx"
241 #undef V8PRIdPTR
242 #define V8PRIdPTR "ld"
243 #undef V8PRIuPTR
244 #define V8PRIuPTR "lxu"
245 #endif
246
247 // The following macro works on both 32 and 64-bit platforms.
248 // Usage: instead of writing 0x1234567890123456
249 // write V8_2PART_UINT64_C(0x12345678,90123456);
250 #define V8_2PART_UINT64_C(a, b) (((static_cast<uint64_t>(a) << 32) + 0x##b##u))
251
252
253 // Compute the 0-relative offset of some absolute value x of type T.
254 // This allows conversion of Addresses and integral types into
255 // 0-relative int offsets.
256 template <typename T>
OffsetFrom(T x)257 inline intptr_t OffsetFrom(T x) {
258 return x - static_cast<T>(0);
259 }
260
261
262 // Compute the absolute value of type T for some 0-relative offset x.
263 // This allows conversion of 0-relative int offsets into Addresses and
264 // integral types.
265 template <typename T>
AddressFrom(intptr_t x)266 inline T AddressFrom(intptr_t x) {
267 return static_cast<T>(static_cast<T>(0) + x);
268 }
269
270
271 // Return the largest multiple of m which is <= x.
272 template <typename T>
RoundDown(T x,intptr_t m)273 inline T RoundDown(T x, intptr_t m) {
274 DCHECK(IS_POWER_OF_TWO(m));
275 return AddressFrom<T>(OffsetFrom(x) & -m);
276 }
277
278
279 // Return the smallest multiple of m which is >= x.
280 template <typename T>
RoundUp(T x,intptr_t m)281 inline T RoundUp(T x, intptr_t m) {
282 return RoundDown<T>(static_cast<T>(x + m - 1), m);
283 }
284
285 #endif // V8_BASE_MACROS_H_
286