Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/test/hotspot/gtest/utilities/test_powerOfTwo.cpp
41145 views
1
/*
2
* Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
*
5
* This code is free software; you can redistribute it and/or modify it
6
* under the terms of the GNU General Public License version 2 only, as
7
* published by the Free Software Foundation.
8
*
9
* This code is distributed in the hope that it will be useful, but WITHOUT
10
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12
* version 2 for more details (a copy is included in the LICENSE file that
13
* accompanied this code).
14
*
15
* You should have received a copy of the GNU General Public License version
16
* 2 along with this work; if not, write to the Free Software Foundation,
17
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18
*
19
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20
* or visit www.oracle.com if you need additional information or have any
21
* questions.
22
*/
23
24
#include "precompiled.hpp"
25
26
#include "utilities/globalDefinitions.hpp"
27
#include "utilities/powerOfTwo.hpp"
28
#include <limits>
29
#include <type_traits>
30
#include "unittest.hpp"
31
32
struct StaticTestIsPowerOf2Result {
33
uint64_t _value;
34
int _status; // 0: success, > 0 indicates which failure case
35
constexpr StaticTestIsPowerOf2Result(uint64_t value, int status) :
36
_value(value), _status(status) {}
37
};
38
39
// Structure copied from test_is_power_of_2 runtime test (below).
40
template<typename T>
41
static constexpr StaticTestIsPowerOf2Result static_test_is_power_of_2_aux(T v) {
42
using Result = StaticTestIsPowerOf2Result;
43
for ( ; v > 0; v >>= 1) {
44
if (!is_power_of_2(v)) {
45
return Result(v, 1);
46
} else if ((v > 2) && is_power_of_2(T(v - 1))) {
47
return Result(v, 2);
48
} else if ((v > 1) && is_power_of_2(T(v + 1))) {
49
return Result(v, 3);
50
}
51
}
52
return Result(v, 0);
53
}
54
55
template<typename T>
56
static void static_test_is_power_of_2() {
57
constexpr StaticTestIsPowerOf2Result result
58
= static_test_is_power_of_2_aux(max_power_of_2<T>());
59
60
EXPECT_EQ(0, result._status)
61
<< "value = " << result._value << ", status = " << result._status;
62
}
63
64
template <typename T> static void test_is_power_of_2() {
65
EXPECT_FALSE(is_power_of_2(T(0)));
66
EXPECT_FALSE(is_power_of_2(~T(0)));
67
68
static_assert(!is_power_of_2(T(0)), "");
69
static_assert(!is_power_of_2(~T(0)), "");
70
71
// Should be false regardless of whether T is signed or unsigned.
72
EXPECT_FALSE(is_power_of_2(std::numeric_limits<T>::min()));
73
static_assert(!is_power_of_2(std::numeric_limits<T>::min()), "");
74
75
// Test true
76
for (T i = max_power_of_2<T>(); i > 0; i = (i >> 1)) {
77
EXPECT_TRUE(is_power_of_2(i)) << "value = " << T(i);
78
}
79
80
// Test one less
81
for (T i = max_power_of_2<T>(); i > 2; i = (i >> 1)) {
82
EXPECT_FALSE(is_power_of_2(i - 1)) << "value = " << T(i - 1);
83
}
84
85
// Test one more
86
for (T i = max_power_of_2<T>(); i > 1; i = (i >> 1)) {
87
EXPECT_FALSE(is_power_of_2(i + 1)) << "value = " << T(i + 1);
88
}
89
90
static_test_is_power_of_2<T>();
91
}
92
93
TEST(power_of_2, is_power_of_2) {
94
test_is_power_of_2<int8_t>();
95
test_is_power_of_2<int16_t>();
96
test_is_power_of_2<int32_t>();
97
test_is_power_of_2<int64_t>();
98
test_is_power_of_2<int8_t>();
99
test_is_power_of_2<int16_t>();
100
test_is_power_of_2<int32_t>();
101
test_is_power_of_2<int64_t>();
102
103
test_is_power_of_2<jint>();
104
test_is_power_of_2<jlong>();
105
}
106
107
TEST(power_of_2, exact_log2) {
108
{
109
uintptr_t j = 1;
110
#ifdef _LP64
111
for (int i = 0; i < 64; i++, j <<= 1) {
112
#else
113
for (int i = 0; i < 32; i++, j <<= 1) {
114
#endif
115
EXPECT_EQ(i, exact_log2(j));
116
}
117
}
118
{
119
julong j = 1;
120
for (int i = 0; i < 64; i++, j <<= 1) {
121
EXPECT_EQ(i, exact_log2_long(j));
122
}
123
}
124
}
125
126
template <typename T> void round_up_power_of_2() {
127
EXPECT_EQ(round_up_power_of_2(T(1)), T(1)) << "value = " << T(1);
128
EXPECT_EQ(round_up_power_of_2(T(2)), T(2)) << "value = " << T(2);
129
EXPECT_EQ(round_up_power_of_2(T(3)), T(4)) << "value = " << T(3);
130
EXPECT_EQ(round_up_power_of_2(T(4)), T(4)) << "value = " << T(4);
131
EXPECT_EQ(round_up_power_of_2(T(5)), T(8)) << "value = " << T(5);
132
EXPECT_EQ(round_up_power_of_2(T(6)), T(8)) << "value = " << T(6);
133
EXPECT_EQ(round_up_power_of_2(T(7)), T(8)) << "value = " << T(7);
134
EXPECT_EQ(round_up_power_of_2(T(8)), T(8)) << "value = " << T(8);
135
EXPECT_EQ(round_up_power_of_2(T(9)), T(16)) << "value = " << T(9);
136
EXPECT_EQ(round_up_power_of_2(T(10)), T(16)) << "value = " << T(10);
137
138
T t_max_pow2 = max_power_of_2<T>();
139
140
// round_up(any power of two) should return input
141
for (T pow2 = T(1); pow2 < t_max_pow2; pow2 *= 2) {
142
EXPECT_EQ(pow2, round_up_power_of_2(pow2))
143
<< "value = " << pow2;
144
}
145
EXPECT_EQ(round_up_power_of_2(t_max_pow2), t_max_pow2)
146
<< "value = " << (t_max_pow2);
147
148
// For each pow2 gt 2, round_up(pow2 - 1) should return pow2
149
for (T pow2 = T(4); pow2 < t_max_pow2; pow2 *= 2) {
150
EXPECT_EQ(pow2, round_up_power_of_2(pow2 - 1))
151
<< "value = " << pow2;
152
}
153
EXPECT_EQ(round_up_power_of_2(t_max_pow2 - 1), t_max_pow2)
154
<< "value = " << (t_max_pow2 - 1);
155
156
}
157
158
TEST(power_of_2, round_up_power_of_2) {
159
round_up_power_of_2<int8_t>();
160
round_up_power_of_2<int16_t>();
161
round_up_power_of_2<int32_t>();
162
round_up_power_of_2<int64_t>();
163
round_up_power_of_2<uint8_t>();
164
round_up_power_of_2<uint16_t>();
165
round_up_power_of_2<uint32_t>();
166
round_up_power_of_2<uint64_t>();
167
}
168
169
template <typename T> void round_down_power_of_2() {
170
EXPECT_EQ(round_down_power_of_2(T(1)), T(1)) << "value = " << T(1);
171
EXPECT_EQ(round_down_power_of_2(T(2)), T(2)) << "value = " << T(2);
172
EXPECT_EQ(round_down_power_of_2(T(3)), T(2)) << "value = " << T(3);
173
EXPECT_EQ(round_down_power_of_2(T(4)), T(4)) << "value = " << T(4);
174
EXPECT_EQ(round_down_power_of_2(T(5)), T(4)) << "value = " << T(5);
175
EXPECT_EQ(round_down_power_of_2(T(6)), T(4)) << "value = " << T(6);
176
EXPECT_EQ(round_down_power_of_2(T(7)), T(4)) << "value = " << T(7);
177
EXPECT_EQ(round_down_power_of_2(T(8)), T(8)) << "value = " << T(8);
178
EXPECT_EQ(round_down_power_of_2(T(9)), T(8)) << "value = " << T(9);
179
EXPECT_EQ(round_down_power_of_2(T(10)), T(8)) << "value = " << T(10);
180
181
T t_max_pow2 = max_power_of_2<T>();
182
183
// For each pow2 >= 2:
184
// - round_down(pow2) should return pow2
185
// - round_down(pow2 + 1) should return pow2
186
// - round_down(pow2 - 1) should return pow2 / 2
187
for (T pow2 = T(2); pow2 < t_max_pow2; pow2 = pow2 * 2) {
188
EXPECT_EQ(pow2, round_down_power_of_2(pow2))
189
<< "value = " << pow2;
190
EXPECT_EQ(pow2, round_down_power_of_2(pow2 + 1))
191
<< "value = " << pow2;
192
EXPECT_EQ(pow2 / 2, round_down_power_of_2(pow2 - 1))
193
<< "value = " << (pow2 / 2);
194
}
195
EXPECT_EQ(round_down_power_of_2(t_max_pow2), t_max_pow2)
196
<< "value = " << (t_max_pow2);
197
EXPECT_EQ(round_down_power_of_2(t_max_pow2 + 1), t_max_pow2)
198
<< "value = " << (t_max_pow2 + 1);
199
EXPECT_EQ(round_down_power_of_2(t_max_pow2 - 1), t_max_pow2 / 2)
200
<< "value = " << (t_max_pow2 - 1);
201
}
202
203
TEST(power_of_2, round_down_power_of_2) {
204
round_down_power_of_2<int8_t>();
205
round_down_power_of_2<int16_t>();
206
round_down_power_of_2<int32_t>();
207
round_down_power_of_2<int64_t>();
208
round_down_power_of_2<uint8_t>();
209
round_down_power_of_2<uint16_t>();
210
round_down_power_of_2<uint32_t>();
211
round_down_power_of_2<uint64_t>();
212
}
213
214
template <typename T> void next_power_of_2() {
215
EXPECT_EQ(next_power_of_2(T(0)), T(1)) << "value = " << T(0);
216
EXPECT_EQ(next_power_of_2(T(1)), T(2)) << "value = " << T(1);
217
EXPECT_EQ(next_power_of_2(T(2)), T(4)) << "value = " << T(2);
218
EXPECT_EQ(next_power_of_2(T(3)), T(4)) << "value = " << T(3);
219
EXPECT_EQ(next_power_of_2(T(4)), T(8)) << "value = " << T(4);
220
EXPECT_EQ(next_power_of_2(T(5)), T(8)) << "value = " << T(5);
221
EXPECT_EQ(next_power_of_2(T(6)), T(8)) << "value = " << T(6);
222
EXPECT_EQ(next_power_of_2(T(7)), T(8)) << "value = " << T(7);
223
EXPECT_EQ(next_power_of_2(T(8)), T(16)) << "value = " << T(8);
224
EXPECT_EQ(next_power_of_2(T(9)), T(16)) << "value = " << T(9);
225
EXPECT_EQ(next_power_of_2(T(10)), T(16)) << "value = " << T(10);
226
227
T t_max_pow2 = max_power_of_2<T>();
228
229
// next(pow2 - 1) should return pow2
230
for (T pow2 = T(1); pow2 < t_max_pow2; pow2 = pow2 * 2) {
231
EXPECT_EQ(pow2, next_power_of_2(pow2 - 1))
232
<< "value = " << pow2 - 1;
233
}
234
EXPECT_EQ(next_power_of_2(t_max_pow2 - 1), t_max_pow2)
235
<< "value = " << (t_max_pow2 - 1);
236
237
// next(pow2) should return pow2 * 2
238
for (T pow2 = T(1); pow2 < t_max_pow2 / 2; pow2 = pow2 * 2) {
239
EXPECT_EQ(pow2 * 2, next_power_of_2(pow2))
240
<< "value = " << pow2;
241
}
242
}
243
244
TEST(power_of_2, next_power_of_2) {
245
next_power_of_2<int8_t>();
246
next_power_of_2<int16_t>();
247
next_power_of_2<int32_t>();
248
next_power_of_2<int64_t>();
249
next_power_of_2<uint8_t>();
250
next_power_of_2<uint16_t>();
251
next_power_of_2<uint32_t>();
252
next_power_of_2<uint64_t>();
253
}
254
255
TEST(power_of_2, max) {
256
EXPECT_EQ(max_power_of_2<int8_t>(), 0x40);
257
EXPECT_EQ(max_power_of_2<int16_t>(), 0x4000);
258
EXPECT_EQ(max_power_of_2<int32_t>(), 0x40000000);
259
EXPECT_EQ(max_power_of_2<int64_t>(), CONST64(0x4000000000000000));
260
EXPECT_EQ(max_power_of_2<uint8_t>(), 0x80u);
261
EXPECT_EQ(max_power_of_2<uint16_t>(), 0x8000u);
262
EXPECT_EQ(max_power_of_2<uint32_t>(), 0x80000000u);
263
EXPECT_EQ(max_power_of_2<uint64_t>(), UCONST64(0x8000000000000000));
264
}
265
266
template <typename T, ENABLE_IF(std::is_integral<T>::value)>
267
void check_log2i_variants_for(T dummy) {
268
int limit = sizeof(T) * BitsPerByte;
269
if (std::is_signed<T>::value) {
270
T min = std::numeric_limits<T>::min();
271
EXPECT_EQ(limit - 1, log2i_graceful(min));
272
EXPECT_EQ(limit - 1, log2i_graceful((T)-1));
273
limit--;
274
}
275
{
276
// Test log2i_graceful handles 0 input
277
EXPECT_EQ(-1, log2i_graceful(T(0)));
278
}
279
{
280
// Test the all-1s bit patterns
281
T var = 1;
282
for (int i = 0; i < limit; i++, var = (var << 1) | 1) {
283
EXPECT_EQ(i, log2i(var));
284
}
285
}
286
{
287
// Test the powers of 2 and powers + 1
288
T var = 1;
289
for (int i = 0; i < limit; i++, var <<= 1) {
290
EXPECT_EQ(i, log2i(var));
291
EXPECT_EQ(i, log2i_graceful(var));
292
EXPECT_EQ(i, log2i_exact(var));
293
EXPECT_EQ(i, log2i(var | 1));
294
}
295
}
296
}
297
298
TEST(power_of_2, log2i) {
299
check_log2i_variants_for((uintptr_t)0);
300
check_log2i_variants_for((intptr_t)0);
301
check_log2i_variants_for((julong)0);
302
check_log2i_variants_for((int)0);
303
check_log2i_variants_for((jint)0);
304
check_log2i_variants_for((uint)0);
305
check_log2i_variants_for((jlong)0);
306
}
307
308