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