Chromium Code Reviews| Index: src/base/macros.h |
| diff --git a/src/base/macros.h b/src/base/macros.h |
| index 381107b8603bdd9ca51c47e4b52a286f8d7c8b44..cb5bf7965cae5bbecbb28041d552a8335252ca5b 100644 |
| --- a/src/base/macros.h |
| +++ b/src/base/macros.h |
| @@ -7,6 +7,7 @@ |
| #include "include/v8stdint.h" |
| #include "src/base/build_config.h" |
| +#include "src/base/logging.h" |
| // The expression OFFSET_OF(type, field) computes the byte-offset |
| @@ -114,6 +115,14 @@ inline void USE(T) { } |
| #define IS_POWER_OF_TWO(x) ((x) != 0 && (((x) & ((x) - 1)) == 0)) |
| +// Returns true iff x is a power of 2. Cannot be used with the maximally |
| +// negative value of the type T (the -1 overflows). |
| +template <typename T> |
| +inline bool IsPowerOf2(T x) { |
| + 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
|
| +} |
| + |
| + |
| // Define our own macros for writing 64-bit constants. This is less fragile |
| // than defining __STDC_CONSTANT_MACROS before including <stdint.h>, and it |
| // works on compilers that don't have it (like MSVC). |
| @@ -164,4 +173,77 @@ inline void USE(T) { } |
| // write V8_2PART_UINT64_C(0x12345678,90123456); |
| #define V8_2PART_UINT64_C(a, b) (((static_cast<uint64_t>(a) << 32) + 0x##b##u)) |
| + |
| +// Compute the 0-relative offset of some absolute value x of type T. |
| +// This allows conversion of Addresses and integral types into |
| +// 0-relative int offsets. |
| +template <typename T> |
| +inline intptr_t OffsetFrom(T x) { |
| + return x - static_cast<T>(0); |
| +} |
| + |
| + |
| +// Compute the absolute value of type T for some 0-relative offset x. |
| +// This allows conversion of 0-relative int offsets into Addresses and |
| +// integral types. |
| +template <typename T> |
| +inline T AddressFrom(intptr_t x) { |
| + return static_cast<T>(static_cast<T>(0) + x); |
| +} |
| + |
| + |
| +// Return the largest multiple of m which is <= x. |
| +template <typename T> |
| +inline T RoundDown(T x, intptr_t m) { |
| + ASSERT(IsPowerOf2(m)); |
| + return AddressFrom<T>(OffsetFrom(x) & -m); |
| +} |
| + |
| + |
| +// Return the smallest multiple of m which is >= x. |
| +template <typename T> |
| +inline T RoundUp(T x, intptr_t m) { |
| + return RoundDown<T>(static_cast<T>(x + m - 1), m); |
| +} |
| + |
| + |
| +// Increment a pointer until it has the specified alignment. |
| +// This works like RoundUp, but it works correctly on pointer types where |
| +// sizeof(*pointer) might not be 1. |
| +template<class T> |
| +T AlignUp(T pointer, size_t alignment) { |
| + ASSERT(sizeof(pointer) == sizeof(uintptr_t)); |
| + uintptr_t pointer_raw = reinterpret_cast<uintptr_t>(pointer); |
| + return reinterpret_cast<T>(RoundUp(pointer_raw, alignment)); |
| +} |
| + |
| + |
| +template <typename T, typename U> |
| +inline bool IsAligned(T value, U alignment) { |
| + return (value & (alignment - 1)) == 0; |
| +} |
| + |
| + |
| +// Returns the smallest power of two which is >= x. If you pass in a |
| +// number that is already a power of two, it is returned as is. |
| +// Implementation is from "Hacker's Delight" by Henry S. Warren, Jr., |
| +// figure 3-3, page 48, where the function is called clp2. |
| +inline uint32_t RoundUpToPowerOf2(uint32_t x) { |
| + ASSERT(x <= 0x80000000u); |
| + x = x - 1; |
| + x = x | (x >> 1); |
| + x = x | (x >> 2); |
| + x = x | (x >> 4); |
| + x = x | (x >> 8); |
| + x = x | (x >> 16); |
| + return x + 1; |
| +} |
| + |
| + |
| +inline uint32_t RoundDownToPowerOf2(uint32_t x) { |
| + uint32_t rounded_up = RoundUpToPowerOf2(x); |
| + if (rounded_up > x) return rounded_up >> 1; |
| + return rounded_up; |
| +} |
| + |
| #endif // V8_BASE_MACROS_H_ |