Line data Source code
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 <limits>
9 :
10 : #include "src/base/compiler-specific.h"
11 : #include "src/base/format-macros.h"
12 : #include "src/base/logging.h"
13 :
14 : // No-op macro which is used to work around MSVC's funky VA_ARGS support.
15 : #define EXPAND(x) x
16 :
17 : // This macro does nothing. That's all.
18 : #define NOTHING(...)
19 :
20 : // TODO(all) Replace all uses of this macro with C++'s offsetof. To do that, we
21 : // have to make sure that only standard-layout types and simple field
22 : // designators are used.
23 : #define OFFSET_OF(type, field) \
24 : (reinterpret_cast<intptr_t>(&(reinterpret_cast<type*>(16)->field)) - 16)
25 :
26 :
27 : // The arraysize(arr) macro returns the # of elements in an array arr.
28 : // The expression is a compile-time constant, and therefore can be
29 : // used in defining new arrays, for example. If you use arraysize on
30 : // a pointer by mistake, you will get a compile-time error.
31 : #define arraysize(array) (sizeof(ArraySizeHelper(array)))
32 :
33 :
34 : // This template function declaration is used in defining arraysize.
35 : // Note that the function doesn't need an implementation, as we only
36 : // use its type.
37 : template <typename T, size_t N>
38 : char (&ArraySizeHelper(T (&array)[N]))[N];
39 :
40 :
41 : #if !V8_CC_MSVC
42 : // That gcc wants both of these prototypes seems mysterious. VC, for
43 : // its part, can't decide which to use (another mystery). Matching of
44 : // template overloads: the final frontier.
45 : template <typename T, size_t N>
46 : char (&ArraySizeHelper(const T (&array)[N]))[N];
47 : #endif
48 :
49 : // bit_cast<Dest,Source> is a template function that implements the
50 : // equivalent of "*reinterpret_cast<Dest*>(&source)". We need this in
51 : // very low-level functions like the protobuf library and fast math
52 : // support.
53 : //
54 : // float f = 3.14159265358979;
55 : // int i = bit_cast<int32>(f);
56 : // // i = 0x40490fdb
57 : //
58 : // The classical address-casting method is:
59 : //
60 : // // WRONG
61 : // float f = 3.14159265358979; // WRONG
62 : // int i = * reinterpret_cast<int*>(&f); // WRONG
63 : //
64 : // The address-casting method actually produces undefined behavior
65 : // according to ISO C++ specification section 3.10 -15 -. Roughly, this
66 : // section says: if an object in memory has one type, and a program
67 : // accesses it with a different type, then the result is undefined
68 : // behavior for most values of "different type".
69 : //
70 : // This is true for any cast syntax, either *(int*)&f or
71 : // *reinterpret_cast<int*>(&f). And it is particularly true for
72 : // conversions between integral lvalues and floating-point lvalues.
73 : //
74 : // The purpose of 3.10 -15- is to allow optimizing compilers to assume
75 : // that expressions with different types refer to different memory. gcc
76 : // 4.0.1 has an optimizer that takes advantage of this. So a
77 : // non-conforming program quietly produces wildly incorrect output.
78 : //
79 : // The problem is not the use of reinterpret_cast. The problem is type
80 : // punning: holding an object in memory of one type and reading its bits
81 : // back using a different type.
82 : //
83 : // The C++ standard is more subtle and complex than this, but that
84 : // is the basic idea.
85 : //
86 : // Anyways ...
87 : //
88 : // bit_cast<> calls memcpy() which is blessed by the standard,
89 : // especially by the example in section 3.9 . Also, of course,
90 : // bit_cast<> wraps up the nasty logic in one place.
91 : //
92 : // Fortunately memcpy() is very fast. In optimized mode, with a
93 : // constant size, gcc 2.95.3, gcc 4.0.1, and msvc 7.1 produce inline
94 : // code with the minimal amount of data movement. On a 32-bit system,
95 : // memcpy(d,s,4) compiles to one load and one store, and memcpy(d,s,8)
96 : // compiles to two loads and two stores.
97 : //
98 : // I tested this code with gcc 2.95.3, gcc 4.0.1, icc 8.1, and msvc 7.1.
99 : //
100 : // WARNING: if Dest or Source is a non-POD type, the result of the memcpy
101 : // is likely to surprise you.
102 : template <class Dest, class Source>
103 : V8_INLINE Dest bit_cast(Source const& source) {
104 : static_assert(sizeof(Dest) == sizeof(Source),
105 : "source and dest must be same size");
106 6433214 : Dest dest;
107 : memcpy(&dest, &source, sizeof(dest));
108 : return dest;
109 : }
110 :
111 : // Explicitly declare the assignment operator as deleted.
112 : #define DISALLOW_ASSIGN(TypeName) TypeName& operator=(const TypeName&) = delete
113 :
114 : // Explicitly declare the copy constructor and assignment operator as deleted.
115 : // This also deletes the implicit move constructor and implicit move assignment
116 : // operator, but still allows to manually define them.
117 : #define DISALLOW_COPY_AND_ASSIGN(TypeName) \
118 : TypeName(const TypeName&) = delete; \
119 : DISALLOW_ASSIGN(TypeName)
120 :
121 : // Explicitly declare all implicit constructors as deleted, namely the
122 : // default constructor, copy constructor and operator= functions.
123 : // This is especially useful for classes containing only static methods.
124 : #define DISALLOW_IMPLICIT_CONSTRUCTORS(TypeName) \
125 : TypeName() = delete; \
126 : DISALLOW_COPY_AND_ASSIGN(TypeName)
127 :
128 : // Disallow copying a type, but provide default construction, move construction
129 : // and move assignment. Especially useful for move-only structs.
130 : #define MOVE_ONLY_WITH_DEFAULT_CONSTRUCTORS(TypeName) \
131 : TypeName() = default; \
132 : MOVE_ONLY_NO_DEFAULT_CONSTRUCTOR(TypeName)
133 :
134 : // Disallow copying a type, and only provide move construction and move
135 : // assignment. Especially useful for move-only structs.
136 : #define MOVE_ONLY_NO_DEFAULT_CONSTRUCTOR(TypeName) \
137 : TypeName(TypeName&&) V8_NOEXCEPT = default; \
138 : TypeName& operator=(TypeName&&) V8_NOEXCEPT = default; \
139 : DISALLOW_COPY_AND_ASSIGN(TypeName)
140 :
141 : // A macro to disallow the dynamic allocation.
142 : // This should be used in the private: declarations for a class
143 : // Declaring operator new and delete as deleted is not spec compliant.
144 : // Extract from 3.2.2 of C++11 spec:
145 : // [...] A non-placement deallocation function for a class is
146 : // odr-used by the definition of the destructor of that class, [...]
147 : #define DISALLOW_NEW_AND_DELETE() \
148 : void* operator new(size_t) { base::OS::Abort(); } \
149 : void* operator new[](size_t) { base::OS::Abort(); } \
150 : void operator delete(void*, size_t) { base::OS::Abort(); } \
151 : void operator delete[](void*, size_t) { base::OS::Abort(); }
152 :
153 : // Define V8_USE_ADDRESS_SANITIZER macro.
154 : #if defined(__has_feature)
155 : #if __has_feature(address_sanitizer)
156 : #define V8_USE_ADDRESS_SANITIZER 1
157 : #endif
158 : #endif
159 :
160 : // Define DISABLE_ASAN macro.
161 : #ifdef V8_USE_ADDRESS_SANITIZER
162 : #define DISABLE_ASAN __attribute__((no_sanitize_address))
163 : #else
164 : #define DISABLE_ASAN
165 : #endif
166 :
167 : // Define V8_USE_MEMORY_SANITIZER macro.
168 : #if defined(__has_feature)
169 : #if __has_feature(memory_sanitizer)
170 : #define V8_USE_MEMORY_SANITIZER 1
171 : #endif
172 : #endif
173 :
174 : // Helper macro to define no_sanitize attributes only with clang.
175 : #if defined(__clang__) && defined(__has_attribute)
176 : #if __has_attribute(no_sanitize)
177 : #define CLANG_NO_SANITIZE(what) __attribute__((no_sanitize(what)))
178 : #endif
179 : #endif
180 : #if !defined(CLANG_NO_SANITIZE)
181 : #define CLANG_NO_SANITIZE(what)
182 : #endif
183 :
184 : // DISABLE_CFI_PERF -- Disable Control Flow Integrity checks for Perf reasons.
185 : #define DISABLE_CFI_PERF CLANG_NO_SANITIZE("cfi")
186 :
187 : // DISABLE_CFI_ICALL -- Disable Control Flow Integrity indirect call checks,
188 : // useful because calls into JITed code can not be CFI verified.
189 : #define DISABLE_CFI_ICALL CLANG_NO_SANITIZE("cfi-icall")
190 :
191 : #if V8_CC_GNU
192 : #define V8_IMMEDIATE_CRASH() __builtin_trap()
193 : #else
194 : #define V8_IMMEDIATE_CRASH() ((void(*)())0)()
195 : #endif
196 :
197 : // A convenience wrapper around static_assert without a string message argument.
198 : // Once C++17 becomes the default, this macro can be removed in favor of the
199 : // new static_assert(condition) overload.
200 : #define STATIC_ASSERT(test) static_assert(test, #test)
201 :
202 : namespace v8 {
203 : namespace base {
204 :
205 : // Note that some implementations of std::is_trivially_copyable mandate that at
206 : // least one of the copy constructor, move constructor, copy assignment or move
207 : // assignment is non-deleted, while others do not. Be aware that also
208 : // base::is_trivially_copyable will differ for these cases.
209 : template <typename T>
210 : struct is_trivially_copyable {
211 : #if V8_CC_MSVC
212 : // Unfortunately, MSVC 2015 is broken in that std::is_trivially_copyable can
213 : // be false even though it should be true according to the standard.
214 : // (status at 2018-02-26, observed on the msvc waterfall bot).
215 : // Interestingly, the lower-level primitives used below are working as
216 : // intended, so we reimplement this according to the standard.
217 : // See also https://developercommunity.visualstudio.com/content/problem/
218 : // 170883/msvc-type-traits-stdis-trivial-is-bugged.html.
219 : static constexpr bool value =
220 : // Copy constructor is trivial or deleted.
221 : (std::is_trivially_copy_constructible<T>::value ||
222 : !std::is_copy_constructible<T>::value) &&
223 : // Copy assignment operator is trivial or deleted.
224 : (std::is_trivially_copy_assignable<T>::value ||
225 : !std::is_copy_assignable<T>::value) &&
226 : // Move constructor is trivial or deleted.
227 : (std::is_trivially_move_constructible<T>::value ||
228 : !std::is_move_constructible<T>::value) &&
229 : // Move assignment operator is trivial or deleted.
230 : (std::is_trivially_move_assignable<T>::value ||
231 : !std::is_move_assignable<T>::value) &&
232 : // (Some implementations mandate that one of the above is non-deleted, but
233 : // the standard does not, so let's skip this check.)
234 : // Trivial non-deleted destructor.
235 : std::is_trivially_destructible<T>::value;
236 :
237 : #elif defined(__GNUC__) && __GNUC__ < 5
238 : // WARNING:
239 : // On older libstdc++ versions, there is no way to correctly implement
240 : // is_trivially_copyable. The workaround below is an approximation (neither
241 : // over- nor underapproximation). E.g. it wrongly returns true if the move
242 : // constructor is non-trivial, and it wrongly returns false if the copy
243 : // constructor is deleted, but copy assignment is trivial.
244 : // TODO(rongjie) Remove this workaround once we require gcc >= 5.0
245 : static constexpr bool value =
246 : __has_trivial_copy(T) && __has_trivial_destructor(T);
247 :
248 : #else
249 : static constexpr bool value = std::is_trivially_copyable<T>::value;
250 : #endif
251 : };
252 : #if defined(__GNUC__) && __GNUC__ < 5
253 : // On older libstdc++ versions, base::is_trivially_copyable<T>::value is only an
254 : // approximation (see above), so make ASSERT_{NOT_,}TRIVIALLY_COPYABLE a noop.
255 : #define ASSERT_TRIVIALLY_COPYABLE(T) static_assert(true, "check disabled")
256 : #define ASSERT_NOT_TRIVIALLY_COPYABLE(T) static_assert(true, "check disabled")
257 : #else
258 : #define ASSERT_TRIVIALLY_COPYABLE(T) \
259 : static_assert(::v8::base::is_trivially_copyable<T>::value, \
260 : #T " should be trivially copyable")
261 : #define ASSERT_NOT_TRIVIALLY_COPYABLE(T) \
262 : static_assert(!::v8::base::is_trivially_copyable<T>::value, \
263 : #T " should not be trivially copyable")
264 : #endif
265 :
266 : // The USE(x, ...) template is used to silence C++ compiler warnings
267 : // issued for (yet) unused variables (typically parameters).
268 : // The arguments are guaranteed to be evaluated from left to right.
269 : struct Use {
270 : template <typename T>
271 496417650 : Use(T&&) {} // NOLINT(runtime/explicit)
272 : };
273 : #define USE(...) \
274 : do { \
275 : ::v8::base::Use unused_tmp_array_for_use_macro[]{__VA_ARGS__}; \
276 : (void)unused_tmp_array_for_use_macro; \
277 : } while (false)
278 :
279 : // Evaluate the instantiations of an expression with parameter packs.
280 : // Since USE has left-to-right evaluation order of it's arguments,
281 : // the parameter pack is iterated from left to right and side effects
282 : // have defined behavior.
283 : #define ITERATE_PACK(...) USE(0, ((__VA_ARGS__), 0)...)
284 :
285 : } // namespace base
286 : } // namespace v8
287 :
288 : // implicit_cast<A>(x) triggers an implicit cast from {x} to type {A}. This is
289 : // useful in situations where static_cast<A>(x) would do too much.
290 : // Only use this for cheap-to-copy types, or use move semantics explicitly.
291 : template <class A>
292 : V8_INLINE A implicit_cast(A x) {
293 : return x;
294 : }
295 :
296 : // Define our own macros for writing 64-bit constants. This is less fragile
297 : // than defining __STDC_CONSTANT_MACROS before including <stdint.h>, and it
298 : // works on compilers that don't have it (like MSVC).
299 : #if V8_CC_MSVC
300 : # if V8_HOST_ARCH_64_BIT
301 : # define V8_PTR_PREFIX "ll"
302 : # else
303 : # define V8_PTR_PREFIX ""
304 : # endif // V8_HOST_ARCH_64_BIT
305 : #elif V8_CC_MINGW64
306 : # define V8_PTR_PREFIX "I64"
307 : #elif V8_HOST_ARCH_64_BIT
308 : # define V8_PTR_PREFIX "l"
309 : #else
310 : #if V8_OS_AIX
311 : #define V8_PTR_PREFIX "l"
312 : #else
313 : # define V8_PTR_PREFIX ""
314 : #endif
315 : #endif
316 :
317 : #define V8PRIxPTR V8_PTR_PREFIX "x"
318 : #define V8PRIdPTR V8_PTR_PREFIX "d"
319 : #define V8PRIuPTR V8_PTR_PREFIX "u"
320 :
321 : #if V8_TARGET_ARCH_64_BIT
322 : #define V8_PTR_HEX_DIGITS 12
323 : #define V8PRIxPTR_FMT "0x%012" V8PRIxPTR
324 : #else
325 : #define V8_PTR_HEX_DIGITS 8
326 : #define V8PRIxPTR_FMT "0x%08" V8PRIxPTR
327 : #endif
328 :
329 : // ptrdiff_t is 't' according to the standard, but MSVC uses 'I'.
330 : #if V8_CC_MSVC
331 : #define V8PRIxPTRDIFF "Ix"
332 : #define V8PRIdPTRDIFF "Id"
333 : #define V8PRIuPTRDIFF "Iu"
334 : #else
335 : #define V8PRIxPTRDIFF "tx"
336 : #define V8PRIdPTRDIFF "td"
337 : #define V8PRIuPTRDIFF "tu"
338 : #endif
339 :
340 : // Fix for Mac OS X defining uintptr_t as "unsigned long":
341 : #if V8_OS_MACOSX
342 : #undef V8PRIxPTR
343 : #define V8PRIxPTR "lx"
344 : #undef V8PRIdPTR
345 : #define V8PRIdPTR "ld"
346 : #undef V8PRIuPTR
347 : #define V8PRIuPTR "lxu"
348 : #endif
349 :
350 : // The following macro works on both 32 and 64-bit platforms.
351 : // Usage: instead of writing 0x1234567890123456
352 : // write V8_2PART_UINT64_C(0x12345678,90123456);
353 : #define V8_2PART_UINT64_C(a, b) (((static_cast<uint64_t>(a) << 32) + 0x##b##u))
354 :
355 : // Return the largest multiple of m which is <= x.
356 : template <typename T>
357 : inline T RoundDown(T x, intptr_t m) {
358 : STATIC_ASSERT(std::is_integral<T>::value);
359 : // m must be a power of two.
360 : DCHECK(m != 0 && ((m & (m - 1)) == 0));
361 4359672627 : return x & -m;
362 : }
363 : template <intptr_t m, typename T>
364 : constexpr inline T RoundDown(T x) {
365 : STATIC_ASSERT(std::is_integral<T>::value);
366 : // m must be a power of two.
367 : STATIC_ASSERT(m != 0 && ((m & (m - 1)) == 0));
368 15527460 : return x & -m;
369 : }
370 :
371 : // Return the smallest multiple of m which is >= x.
372 : template <typename T>
373 310 : inline T RoundUp(T x, intptr_t m) {
374 : STATIC_ASSERT(std::is_integral<T>::value);
375 4336469002 : return RoundDown<T>(static_cast<T>(x + m - 1), m);
376 : }
377 : template <intptr_t m, typename T>
378 : constexpr inline T RoundUp(T x) {
379 : STATIC_ASSERT(std::is_integral<T>::value);
380 15527460 : return RoundDown<m, T>(static_cast<T>(x + (m - 1)));
381 : }
382 :
383 : template <typename T, typename U>
384 : constexpr inline bool IsAligned(T value, U alignment) {
385 40035222 : return (value & (alignment - 1)) == 0;
386 : }
387 :
388 : inline void* AlignedAddress(void* address, size_t alignment) {
389 : // The alignment must be a power of two.
390 : DCHECK_EQ(alignment & (alignment - 1), 0u);
391 3313726 : return reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(address) &
392 3313726 : ~static_cast<uintptr_t>(alignment - 1));
393 : }
394 :
395 : // Bounds checks for float to integer conversions, which does truncation. Hence,
396 : // the range of legal values is (min - 1, max + 1).
397 : template <typename int_t, typename float_t, typename biggest_int_t = int64_t>
398 : bool is_inbounds(float_t v) {
399 : static_assert(sizeof(int_t) < sizeof(biggest_int_t),
400 : "int_t can't be bounds checked by the compiler");
401 : constexpr float_t kLowerBound =
402 : static_cast<float_t>(std::numeric_limits<int_t>::min()) - 1;
403 : constexpr float_t kUpperBound =
404 : static_cast<float_t>(std::numeric_limits<int_t>::max()) + 1;
405 : constexpr bool kLowerBoundIsMin =
406 : static_cast<biggest_int_t>(kLowerBound) ==
407 : static_cast<biggest_int_t>(std::numeric_limits<int_t>::min());
408 : constexpr bool kUpperBoundIsMax =
409 : static_cast<biggest_int_t>(kUpperBound) ==
410 : static_cast<biggest_int_t>(std::numeric_limits<int_t>::max());
411 : return (kLowerBoundIsMin ? (kLowerBound <= v) : (kLowerBound < v)) &&
412 10648 : (kUpperBoundIsMax ? (v <= kUpperBound) : (v < kUpperBound));
413 : }
414 :
415 : #ifdef V8_OS_WIN
416 :
417 : // Setup for Windows shared library export.
418 : #ifdef BUILDING_V8_SHARED
419 : #define V8_EXPORT_PRIVATE __declspec(dllexport)
420 : #elif USING_V8_SHARED
421 : #define V8_EXPORT_PRIVATE __declspec(dllimport)
422 : #else
423 : #define V8_EXPORT_PRIVATE
424 : #endif // BUILDING_V8_SHARED
425 :
426 : #else // V8_OS_WIN
427 :
428 : // Setup for Linux shared library export.
429 : #if V8_HAS_ATTRIBUTE_VISIBILITY
430 : #ifdef BUILDING_V8_SHARED
431 : #define V8_EXPORT_PRIVATE __attribute__((visibility("default")))
432 : #else
433 : #define V8_EXPORT_PRIVATE
434 : #endif
435 : #else
436 : #define V8_EXPORT_PRIVATE
437 : #endif
438 :
439 : #endif // V8_OS_WIN
440 :
441 : #endif // V8_BASE_MACROS_H_
|