| // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| // for details. All rights reserved. Use of this source code is governed by a |
| // BSD-style license that can be found in the LICENSE file. |
| |
| #ifndef PLATFORM_UTILS_H_ |
| #define PLATFORM_UTILS_H_ |
| |
| #include "platform/assert.h" |
| #include "platform/globals.h" |
| |
| namespace dart { |
| |
| class Utils { |
| public: |
| template<typename T> |
| static inline T Minimum(T x, T y) { |
| return x < y ? x : y; |
| } |
| |
| template<typename T> |
| static inline T Maximum(T x, T y) { |
| return x > y ? x : y; |
| } |
| |
| template<typename T> |
| static inline T Abs(T x) { |
| if (x < 0) return -x; |
| return x; |
| } |
| |
| template<typename T> |
| static inline bool IsPowerOfTwo(T x) { |
| return (x & (x - 1)) == 0; |
| } |
| |
| template<typename T> |
| static inline int ShiftForPowerOfTwo(T x) { |
| ASSERT(IsPowerOfTwo(x)); |
| int num_shifts = 0; |
| while (x > 1) { |
| num_shifts++; |
| x = x >> 1; |
| } |
| return num_shifts; |
| } |
| |
| template<typename T> |
| static inline bool IsAligned(T x, int n) { |
| ASSERT(IsPowerOfTwo(n)); |
| return (x & (n - 1)) == 0; |
| } |
| |
| template<typename T> |
| static inline bool IsAligned(T* x, int n) { |
| return IsAligned(reinterpret_cast<uword>(x), n); |
| } |
| |
| template<typename T> |
| static inline T RoundDown(T x, int n) { |
| ASSERT(IsPowerOfTwo(n)); |
| return (x & -n); |
| } |
| |
| template<typename T> |
| static inline T* RoundDown(T* x, int n) { |
| return reinterpret_cast<T*>(RoundDown(reinterpret_cast<uword>(x), n)); |
| } |
| |
| template<typename T> |
| static inline T RoundUp(T x, int n) { |
| return RoundDown(x + n - 1, n); |
| } |
| |
| template<typename T> |
| static inline T* RoundUp(T* x, int n) { |
| return reinterpret_cast<T*>(RoundUp(reinterpret_cast<uword>(x), n)); |
| } |
| |
| static uint32_t RoundUpToPowerOfTwo(uint32_t x); |
| static int CountOneBits(uint32_t x); |
| |
| static int HighestBit(int64_t v); |
| |
| static int CountTrailingZeros(uword x); |
| |
| // Computes a hash value for the given string. |
| static uint32_t StringHash(const char* data, int length); |
| |
| // Computes a hash value for the given word. |
| static uint32_t WordHash(word key); |
| |
| // Check whether an N-bit two's-complement representation can hold value. |
| template<typename T> |
| static inline bool IsInt(int N, T value) { |
| ASSERT((0 < N) && |
| (static_cast<unsigned int>(N) < (kBitsPerByte * sizeof(value)))); |
| T limit = static_cast<T>(1) << (N - 1); |
| return (-limit <= value) && (value < limit); |
| } |
| |
| template<typename T> |
| static inline bool IsUint(int N, T value) { |
| ASSERT((0 < N) && |
| (static_cast<unsigned int>(N) < (kBitsPerByte * sizeof(value)))); |
| T limit = static_cast<T>(1) << N; |
| return (0 <= value) && (value < limit); |
| } |
| |
| // Check whether the magnitude of value fits in N bits, i.e., whether an |
| // (N+1)-bit sign-magnitude representation can hold value. |
| template<typename T> |
| static inline bool IsAbsoluteUint(int N, T value) { |
| ASSERT((0 < N) && |
| (static_cast<unsigned int>(N) < (kBitsPerByte * sizeof(value)))); |
| if (value < 0) value = -value; |
| return IsUint(N, value); |
| } |
| |
| static inline int32_t Low16Bits(int32_t value) { |
| return static_cast<int32_t>(value & 0xffff); |
| } |
| |
| static inline int32_t High16Bits(int32_t value) { |
| return static_cast<int32_t>(value >> 16); |
| } |
| |
| static inline int32_t Low32Bits(int64_t value) { |
| return static_cast<int32_t>(value); |
| } |
| |
| static inline int32_t High32Bits(int64_t value) { |
| return static_cast<int32_t>(value >> 32); |
| } |
| |
| static inline int64_t LowHighTo64Bits(uint32_t low, int32_t high) { |
| return (static_cast<int64_t>(high) << 32) | (low & 0x0ffffffffLL); |
| } |
| |
| static bool IsDecimalDigit(char c) { |
| return ('0' <= c) && (c <= '9'); |
| } |
| |
| static bool IsHexDigit(char c) { |
| return IsDecimalDigit(c) |
| || (('A' <= c) && (c <= 'F')) |
| || (('a' <= c) && (c <= 'f')); |
| } |
| |
| static int HexDigitToInt(char c) { |
| ASSERT(IsHexDigit(c)); |
| if (IsDecimalDigit(c)) return c - '0'; |
| if (('A' <= c) && (c <= 'F')) return 10 + (c - 'A'); |
| return 10 + (c - 'a'); |
| } |
| |
| static char IntToHexDigit(int i) { |
| ASSERT(0 <= i && i < 16); |
| if (i < 10) return static_cast<char>('0' + i); |
| return static_cast<char>('A' + (i - 10)); |
| } |
| |
| // Perform a range check, checking if |
| // offset + count <= length |
| // without the risk of integer overflow. |
| static inline bool RangeCheck(intptr_t offset, |
| intptr_t count, |
| intptr_t length) { |
| return offset >= 0 && |
| count >= 0 && |
| length >= 0 && |
| count <= (length - offset); |
| } |
| }; |
| |
| } // namespace dart |
| |
| #if defined(TARGET_OS_ANDROID) |
| #include "platform/utils_android.h" |
| #elif defined(TARGET_OS_LINUX) |
| #include "platform/utils_linux.h" |
| #elif defined(TARGET_OS_MACOS) |
| #include "platform/utils_macos.h" |
| #elif defined(TARGET_OS_WINDOWS) |
| #include "platform/utils_win.h" |
| #else |
| #error Unknown target os. |
| #endif |
| |
| #endif // PLATFORM_UTILS_H_ |