OLD | NEW |
---|---|
1 // Copyright 2014 the V8 project authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef V8_BASE_MACROS_H_ | 5 #ifndef V8_BASE_MACROS_H_ |
6 #define V8_BASE_MACROS_H_ | 6 #define V8_BASE_MACROS_H_ |
7 | 7 |
8 #include "include/v8stdint.h" | 8 #include "include/v8stdint.h" |
9 #include "src/base/build_config.h" | 9 #include "src/base/build_config.h" |
10 #include "src/base/logging.h" | |
10 | 11 |
11 | 12 |
12 // The expression OFFSET_OF(type, field) computes the byte-offset | 13 // The expression OFFSET_OF(type, field) computes the byte-offset |
13 // of the specified field relative to the containing type. This | 14 // of the specified field relative to the containing type. This |
14 // corresponds to 'offsetof' (in stddef.h), except that it doesn't | 15 // corresponds to 'offsetof' (in stddef.h), except that it doesn't |
15 // use 0 or NULL, which causes a problem with the compiler warnings | 16 // use 0 or NULL, which causes a problem with the compiler warnings |
16 // we have enabled (which is also why 'offsetof' doesn't seem to work). | 17 // we have enabled (which is also why 'offsetof' doesn't seem to work). |
17 // Here we simply use the non-zero value 4, which seems to work. | 18 // Here we simply use the non-zero value 4, which seems to work. |
18 #define OFFSET_OF(type, field) \ | 19 #define OFFSET_OF(type, field) \ |
19 (reinterpret_cast<intptr_t>(&(reinterpret_cast<type*>(4)->field)) - 4) | 20 (reinterpret_cast<intptr_t>(&(reinterpret_cast<type*>(4)->field)) - 4) |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
107 | 108 |
108 // The USE(x) template is used to silence C++ compiler warnings | 109 // The USE(x) template is used to silence C++ compiler warnings |
109 // issued for (yet) unused variables (typically parameters). | 110 // issued for (yet) unused variables (typically parameters). |
110 template <typename T> | 111 template <typename T> |
111 inline void USE(T) { } | 112 inline void USE(T) { } |
112 | 113 |
113 | 114 |
114 #define IS_POWER_OF_TWO(x) ((x) != 0 && (((x) & ((x) - 1)) == 0)) | 115 #define IS_POWER_OF_TWO(x) ((x) != 0 && (((x) & ((x) - 1)) == 0)) |
115 | 116 |
116 | 117 |
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); | |
tfarina
2014/07/01 16:01:32
Do we need to have the macro version?
Sven Panne
2014/07/02 08:18:41
Yes, because it is used in STATIC_ASSERTs. When we
| |
123 } | |
124 | |
125 | |
117 // Define our own macros for writing 64-bit constants. This is less fragile | 126 // Define our own macros for writing 64-bit constants. This is less fragile |
118 // than defining __STDC_CONSTANT_MACROS before including <stdint.h>, and it | 127 // than defining __STDC_CONSTANT_MACROS before including <stdint.h>, and it |
119 // works on compilers that don't have it (like MSVC). | 128 // works on compilers that don't have it (like MSVC). |
120 #if V8_CC_MSVC | 129 #if V8_CC_MSVC |
121 # define V8_UINT64_C(x) (x ## UI64) | 130 # define V8_UINT64_C(x) (x ## UI64) |
122 # define V8_INT64_C(x) (x ## I64) | 131 # define V8_INT64_C(x) (x ## I64) |
123 # if V8_HOST_ARCH_64_BIT | 132 # if V8_HOST_ARCH_64_BIT |
124 # define V8_INTPTR_C(x) (x ## I64) | 133 # define V8_INTPTR_C(x) (x ## I64) |
125 # define V8_PTR_PREFIX "ll" | 134 # define V8_PTR_PREFIX "ll" |
126 # else | 135 # else |
(...skipping 30 matching lines...) Expand all Loading... | |
157 #if V8_OS_MACOSX | 166 #if V8_OS_MACOSX |
158 #undef V8PRIxPTR | 167 #undef V8PRIxPTR |
159 #define V8PRIxPTR "lx" | 168 #define V8PRIxPTR "lx" |
160 #endif | 169 #endif |
161 | 170 |
162 // The following macro works on both 32 and 64-bit platforms. | 171 // The following macro works on both 32 and 64-bit platforms. |
163 // Usage: instead of writing 0x1234567890123456 | 172 // Usage: instead of writing 0x1234567890123456 |
164 // write V8_2PART_UINT64_C(0x12345678,90123456); | 173 // write V8_2PART_UINT64_C(0x12345678,90123456); |
165 #define V8_2PART_UINT64_C(a, b) (((static_cast<uint64_t>(a) << 32) + 0x##b##u)) | 174 #define V8_2PART_UINT64_C(a, b) (((static_cast<uint64_t>(a) << 32) + 0x##b##u)) |
166 | 175 |
176 | |
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); | |
183 } | |
184 | |
185 | |
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 | |
188 // integral types. | |
189 template <typename T> | |
190 inline T AddressFrom(intptr_t x) { | |
191 return static_cast<T>(static_cast<T>(0) + x); | |
192 } | |
193 | |
194 | |
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); | |
200 } | |
201 | |
202 | |
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); | |
207 } | |
208 | |
209 | |
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. | |
213 template<class T> | |
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)); | |
218 } | |
219 | |
220 | |
221 template <typename T, typename U> | |
222 inline bool IsAligned(T value, U alignment) { | |
223 return (value & (alignment - 1)) == 0; | |
224 } | |
225 | |
226 | |
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); | |
233 x = x - 1; | |
234 x = x | (x >> 1); | |
235 x = x | (x >> 2); | |
236 x = x | (x >> 4); | |
237 x = x | (x >> 8); | |
238 x = x | (x >> 16); | |
239 return x + 1; | |
240 } | |
241 | |
242 | |
243 inline uint32_t RoundDownToPowerOf2(uint32_t x) { | |
244 uint32_t rounded_up = RoundUpToPowerOf2(x); | |
245 if (rounded_up > x) return rounded_up >> 1; | |
246 return rounded_up; | |
247 } | |
248 | |
167 #endif // V8_BASE_MACROS_H_ | 249 #endif // V8_BASE_MACROS_H_ |
OLD | NEW |