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.
5 #ifndef V8_BASE_MACROS_H_
6 #define V8_BASE_MACROS_H_
8 #include "include/v8stdint.h"
9 #include "src/base/build_config.h"
10 #include "src/base/logging.h"
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)
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
27 #define ARRAY_SIZE(a) \
28 ((sizeof(a) / sizeof(*(a))) / \
29 static_cast<size_t>(!(sizeof(a) % sizeof(*(a)))))
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
39 // A macro to disallow all the implicit constructors, namely the
40 // default constructor, copy constructor and operator= functions.
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)
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
55 // Newly written code should use V8_WARN_UNUSED_RESULT.
56 #define MUST_USE_RESULT V8_WARN_UNUSED_RESULT
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
66 // Define DISABLE_ASAN macros.
67 #ifdef V8_USE_ADDRESS_SANITIZER
68 #define DISABLE_ASAN __attribute__((no_sanitize_address))
75 #define V8_IMMEDIATE_CRASH() __builtin_trap()
77 #define V8_IMMEDIATE_CRASH() ((void(*)())0)()
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)
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) \
103 StaticAssertionHelper<sizeof(StaticAssertion<static_cast<bool>((test))>)> \
104 SEMI_STATIC_JOIN(__StaticAssertTypedef__, __LINE__) V8_UNUSED
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) { }
115 #define IS_POWER_OF_TWO(x) ((x) != 0 && (((x) & ((x) - 1)) == 0))
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);
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).
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"
136 # define V8_INTPTR_C(x) (x)
137 # define V8_PTR_PREFIX ""
138 # endif // V8_HOST_ARCH_64_BIT
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
146 # define V8_UINT64_C(x) (x ## ULL)
147 # define V8_INT64_C(x) (x ## LL)
149 # define V8_UINT64_C(x) (x ## UL)
150 # define V8_INT64_C(x) (x ## L)
152 # define V8_INTPTR_C(x) (x ## L)
153 # define V8_PTR_PREFIX "l"
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 ""
161 #define V8PRIxPTR V8_PTR_PREFIX "x"
162 #define V8PRIdPTR V8_PTR_PREFIX "d"
163 #define V8PRIuPTR V8_PTR_PREFIX "u"
165 // Fix for Mac OS X defining uintptr_t as "unsigned long":
168 #define V8PRIxPTR "lx"
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))
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);
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
189 template <typename T>
190 inline T AddressFrom(intptr_t x) {
191 return static_cast<T>(static_cast<T>(0) + x);
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);
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);
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.
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));
221 template <typename T, typename U>
222 inline bool IsAligned(T value, U alignment) {
223 return (value & (alignment - 1)) == 0;
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);
243 inline uint32_t RoundDownToPowerOf2(uint32_t x) {
244 uint32_t rounded_up = RoundUpToPowerOf2(x);
245 if (rounded_up > x) return rounded_up >> 1;
249 #endif // V8_BASE_MACROS_H_