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> 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> 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> 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> 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> 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> 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