OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #ifndef RUNTIME_PLATFORM_UTILS_H_ | 5 #ifndef RUNTIME_PLATFORM_UTILS_H_ |
6 #define RUNTIME_PLATFORM_UTILS_H_ | 6 #define RUNTIME_PLATFORM_UTILS_H_ |
7 | 7 |
8 #include "platform/assert.h" | 8 #include "platform/assert.h" |
9 #include "platform/globals.h" | 9 #include "platform/globals.h" |
10 | 10 |
11 namespace dart { | 11 namespace dart { |
12 | 12 |
13 class Utils { | 13 class Utils { |
14 public: | 14 public: |
15 template<typename T> | 15 template <typename T> |
16 static inline T Minimum(T x, T y) { | 16 static inline T Minimum(T x, T y) { |
17 return x < y ? x : y; | 17 return x < y ? x : y; |
18 } | 18 } |
19 | 19 |
20 template<typename T> | 20 template <typename T> |
21 static inline T Maximum(T x, T y) { | 21 static inline T Maximum(T x, T y) { |
22 return x > y ? x : y; | 22 return x > y ? x : y; |
23 } | 23 } |
24 | 24 |
25 template<typename T> | 25 template <typename T> |
26 static inline T Abs(T x) { | 26 static inline T Abs(T x) { |
27 if (x < 0) return -x; | 27 if (x < 0) return -x; |
28 return x; | 28 return x; |
29 } | 29 } |
30 | 30 |
31 template<typename T> | 31 template <typename T> |
32 static inline bool IsPowerOfTwo(T x) { | 32 static inline bool IsPowerOfTwo(T x) { |
33 return ((x & (x - 1)) == 0) && (x != 0); | 33 return ((x & (x - 1)) == 0) && (x != 0); |
34 } | 34 } |
35 | 35 |
36 template<typename T> | 36 template <typename T> |
37 static inline int ShiftForPowerOfTwo(T x) { | 37 static inline int ShiftForPowerOfTwo(T x) { |
38 ASSERT(IsPowerOfTwo(x)); | 38 ASSERT(IsPowerOfTwo(x)); |
39 int num_shifts = 0; | 39 int num_shifts = 0; |
40 while (x > 1) { | 40 while (x > 1) { |
41 num_shifts++; | 41 num_shifts++; |
42 x = x >> 1; | 42 x = x >> 1; |
43 } | 43 } |
44 return num_shifts; | 44 return num_shifts; |
45 } | 45 } |
46 | 46 |
47 template<typename T> | 47 template <typename T> |
48 static inline bool IsAligned(T x, intptr_t n) { | 48 static inline bool IsAligned(T x, intptr_t n) { |
49 ASSERT(IsPowerOfTwo(n)); | 49 ASSERT(IsPowerOfTwo(n)); |
50 return (x & (n - 1)) == 0; | 50 return (x & (n - 1)) == 0; |
51 } | 51 } |
52 | 52 |
53 template<typename T> | 53 template <typename T> |
54 static inline bool IsAligned(T* x, intptr_t n) { | 54 static inline bool IsAligned(T* x, intptr_t n) { |
55 return IsAligned(reinterpret_cast<uword>(x), n); | 55 return IsAligned(reinterpret_cast<uword>(x), n); |
56 } | 56 } |
57 | 57 |
58 template<typename T> | 58 template <typename T> |
59 static inline T RoundDown(T x, intptr_t n) { | 59 static inline T RoundDown(T x, intptr_t n) { |
60 ASSERT(IsPowerOfTwo(n)); | 60 ASSERT(IsPowerOfTwo(n)); |
61 return (x & -n); | 61 return (x & -n); |
62 } | 62 } |
63 | 63 |
64 template<typename T> | 64 template <typename T> |
65 static inline T* RoundDown(T* x, intptr_t n) { | 65 static inline T* RoundDown(T* x, intptr_t n) { |
66 return reinterpret_cast<T*>(RoundDown(reinterpret_cast<uword>(x), n)); | 66 return reinterpret_cast<T*>(RoundDown(reinterpret_cast<uword>(x), n)); |
67 } | 67 } |
68 | 68 |
69 template<typename T> | 69 template <typename T> |
70 static inline T RoundUp(T x, intptr_t n) { | 70 static inline T RoundUp(T x, intptr_t n) { |
71 return RoundDown(x + n - 1, n); | 71 return RoundDown(x + n - 1, n); |
72 } | 72 } |
73 | 73 |
74 template<typename T> | 74 template <typename T> |
75 static inline T* RoundUp(T* x, intptr_t n) { | 75 static inline T* RoundUp(T* x, intptr_t n) { |
76 return reinterpret_cast<T*>(RoundUp(reinterpret_cast<uword>(x), n)); | 76 return reinterpret_cast<T*>(RoundUp(reinterpret_cast<uword>(x), n)); |
77 } | 77 } |
78 | 78 |
79 static uintptr_t RoundUpToPowerOfTwo(uintptr_t x); | 79 static uintptr_t RoundUpToPowerOfTwo(uintptr_t x); |
80 static int CountOneBits(uint32_t x); | 80 static int CountOneBits(uint32_t x); |
81 | 81 |
82 static int HighestBit(int64_t v); | 82 static int HighestBit(int64_t v); |
83 | 83 |
84 static int BitLength(int64_t value) { | 84 static int BitLength(int64_t value) { |
85 // Flip bits if negative (-1 becomes 0). | 85 // Flip bits if negative (-1 becomes 0). |
86 value ^= value >> (8 * sizeof(value) - 1); | 86 value ^= value >> (8 * sizeof(value) - 1); |
87 return (value == 0) ? 0 : (Utils::HighestBit(value) + 1); | 87 return (value == 0) ? 0 : (Utils::HighestBit(value) + 1); |
88 } | 88 } |
89 | 89 |
90 static int CountLeadingZeros(uword x); | 90 static int CountLeadingZeros(uword x); |
91 static int CountTrailingZeros(uword x); | 91 static int CountTrailingZeros(uword x); |
92 | 92 |
93 // Computes a hash value for the given string. | 93 // Computes a hash value for the given string. |
94 static uint32_t StringHash(const char* data, int length); | 94 static uint32_t StringHash(const char* data, int length); |
95 | 95 |
96 // Computes a hash value for the given word. | 96 // Computes a hash value for the given word. |
97 static uint32_t WordHash(intptr_t key); | 97 static uint32_t WordHash(intptr_t key); |
98 | 98 |
99 // Check whether an N-bit two's-complement representation can hold value. | 99 // Check whether an N-bit two's-complement representation can hold value. |
100 template<typename T> | 100 template <typename T> |
101 static inline bool IsInt(int N, T value) { | 101 static inline bool IsInt(int N, T value) { |
102 ASSERT((0 < N) && | 102 ASSERT((0 < N) && |
103 (static_cast<unsigned int>(N) < (kBitsPerByte * sizeof(value)))); | 103 (static_cast<unsigned int>(N) < (kBitsPerByte * sizeof(value)))); |
104 T limit = static_cast<T>(1) << (N - 1); | 104 T limit = static_cast<T>(1) << (N - 1); |
105 return (-limit <= value) && (value < limit); | 105 return (-limit <= value) && (value < limit); |
106 } | 106 } |
107 | 107 |
108 template<typename T> | 108 template <typename T> |
109 static inline bool IsUint(int N, T value) { | 109 static inline bool IsUint(int N, T value) { |
110 ASSERT((0 < N) && | 110 ASSERT((0 < N) && |
111 (static_cast<unsigned int>(N) < (kBitsPerByte * sizeof(value)))); | 111 (static_cast<unsigned int>(N) < (kBitsPerByte * sizeof(value)))); |
112 T limit = static_cast<T>(1) << N; | 112 T limit = static_cast<T>(1) << N; |
113 return (0 <= value) && (value < limit); | 113 return (0 <= value) && (value < limit); |
114 } | 114 } |
115 | 115 |
116 // Check whether the magnitude of value fits in N bits, i.e., whether an | 116 // Check whether the magnitude of value fits in N bits, i.e., whether an |
117 // (N+1)-bit sign-magnitude representation can hold value. | 117 // (N+1)-bit sign-magnitude representation can hold value. |
118 template<typename T> | 118 template <typename T> |
119 static inline bool IsAbsoluteUint(int N, T value) { | 119 static inline bool IsAbsoluteUint(int N, T value) { |
120 ASSERT((0 < N) && | 120 ASSERT((0 < N) && |
121 (static_cast<unsigned int>(N) < (kBitsPerByte * sizeof(value)))); | 121 (static_cast<unsigned int>(N) < (kBitsPerByte * sizeof(value)))); |
122 if (value < 0) value = -value; | 122 if (value < 0) value = -value; |
123 return IsUint(N, value); | 123 return IsUint(N, value); |
124 } | 124 } |
125 | 125 |
126 static inline int32_t Low16Bits(int32_t value) { | 126 static inline int32_t Low16Bits(int32_t value) { |
127 return static_cast<int32_t>(value & 0xffff); | 127 return static_cast<int32_t>(value & 0xffff); |
128 } | 128 } |
129 | 129 |
130 static inline int32_t High16Bits(int32_t value) { | 130 static inline int32_t High16Bits(int32_t value) { |
131 return static_cast<int32_t>(value >> 16); | 131 return static_cast<int32_t>(value >> 16); |
132 } | 132 } |
133 | 133 |
134 static inline int32_t Low32Bits(int64_t value) { | 134 static inline int32_t Low32Bits(int64_t value) { |
135 return static_cast<int32_t>(value); | 135 return static_cast<int32_t>(value); |
136 } | 136 } |
137 | 137 |
138 static inline int32_t High32Bits(int64_t value) { | 138 static inline int32_t High32Bits(int64_t value) { |
139 return static_cast<int32_t>(value >> 32); | 139 return static_cast<int32_t>(value >> 32); |
140 } | 140 } |
141 | 141 |
142 static inline int64_t LowHighTo64Bits(uint32_t low, int32_t high) { | 142 static inline int64_t LowHighTo64Bits(uint32_t low, int32_t high) { |
143 return (static_cast<int64_t>(high) << 32) | (low & 0x0ffffffffLL); | 143 return (static_cast<int64_t>(high) << 32) | (low & 0x0ffffffffLL); |
144 } | 144 } |
145 | 145 |
146 static bool IsDecimalDigit(char c) { | 146 static bool IsDecimalDigit(char c) { return ('0' <= c) && (c <= '9'); } |
147 return ('0' <= c) && (c <= '9'); | |
148 } | |
149 | 147 |
150 static bool IsHexDigit(char c) { | 148 static bool IsHexDigit(char c) { |
151 return IsDecimalDigit(c) | 149 return IsDecimalDigit(c) || (('A' <= c) && (c <= 'F')) || |
152 || (('A' <= c) && (c <= 'F')) | 150 (('a' <= c) && (c <= 'f')); |
153 || (('a' <= c) && (c <= 'f')); | |
154 } | 151 } |
155 | 152 |
156 static int HexDigitToInt(char c) { | 153 static int HexDigitToInt(char c) { |
157 ASSERT(IsHexDigit(c)); | 154 ASSERT(IsHexDigit(c)); |
158 if (IsDecimalDigit(c)) return c - '0'; | 155 if (IsDecimalDigit(c)) return c - '0'; |
159 if (('A' <= c) && (c <= 'F')) return 10 + (c - 'A'); | 156 if (('A' <= c) && (c <= 'F')) return 10 + (c - 'A'); |
160 return 10 + (c - 'a'); | 157 return 10 + (c - 'a'); |
161 } | 158 } |
162 | 159 |
163 static char IntToHexDigit(int i) { | 160 static char IntToHexDigit(int i) { |
164 ASSERT(0 <= i && i < 16); | 161 ASSERT(0 <= i && i < 16); |
165 if (i < 10) return static_cast<char>('0' + i); | 162 if (i < 10) return static_cast<char>('0' + i); |
166 return static_cast<char>('A' + (i - 10)); | 163 return static_cast<char>('A' + (i - 10)); |
167 } | 164 } |
168 | 165 |
169 // Perform a range check, checking if | 166 // Perform a range check, checking if |
170 // offset + count <= length | 167 // offset + count <= length |
171 // without the risk of integer overflow. | 168 // without the risk of integer overflow. |
172 static inline bool RangeCheck(intptr_t offset, | 169 static inline bool RangeCheck(intptr_t offset, |
173 intptr_t count, | 170 intptr_t count, |
174 intptr_t length) { | 171 intptr_t length) { |
175 return offset >= 0 && | 172 return offset >= 0 && count >= 0 && length >= 0 && |
176 count >= 0 && | |
177 length >= 0 && | |
178 count <= (length - offset); | 173 count <= (length - offset); |
179 } | 174 } |
180 | 175 |
181 static inline bool WillAddOverflow(int64_t a, int64_t b) { | 176 static inline bool WillAddOverflow(int64_t a, int64_t b) { |
182 return ((b > 0) && (a > (kMaxInt64 - b))) || | 177 return ((b > 0) && (a > (kMaxInt64 - b))) || |
183 ((b < 0) && (a < (kMinInt64 - b))); | 178 ((b < 0) && (a < (kMinInt64 - b))); |
184 } | 179 } |
185 | 180 |
186 static inline bool WillSubOverflow(int64_t a, int64_t b) { | 181 static inline bool WillSubOverflow(int64_t a, int64_t b) { |
187 return ((b > 0) && (a < (kMinInt64 + b))) || | 182 return ((b > 0) && (a < (kMinInt64 + b))) || |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
221 #include "platform/utils_linux.h" | 216 #include "platform/utils_linux.h" |
222 #elif defined(TARGET_OS_MACOS) | 217 #elif defined(TARGET_OS_MACOS) |
223 #include "platform/utils_macos.h" | 218 #include "platform/utils_macos.h" |
224 #elif defined(TARGET_OS_WINDOWS) | 219 #elif defined(TARGET_OS_WINDOWS) |
225 #include "platform/utils_win.h" | 220 #include "platform/utils_win.h" |
226 #else | 221 #else |
227 #error Unknown target os. | 222 #error Unknown target os. |
228 #endif | 223 #endif |
229 | 224 |
230 #endif // RUNTIME_PLATFORM_UTILS_H_ | 225 #endif // RUNTIME_PLATFORM_UTILS_H_ |
OLD | NEW |