8240829: Use a fast O(1) algorithm for exact_log2

Reviewed-by: jrose, redestad
This commit is contained in:
Andrew Haley 2020-03-11 12:38:57 +00:00
parent 661c073594
commit 0992e17b97
2 changed files with 28 additions and 5 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -41,14 +41,18 @@ bool is_power_of_2(T x) {
// Log2 of a power of 2
inline int exact_log2(intptr_t x) {
assert(is_power_of_2(x), "x must be a power of 2: " INTPTR_FORMAT, x);
return log2_intptr(x);
assert(is_power_of_2((uintptr_t)x), "x must be a power of 2: " INTPTR_FORMAT, x);
const int bits = sizeof x * BitsPerByte;
return bits - count_leading_zeros(x) - 1;
}
// Log2 of a power of 2
inline int exact_log2_long(jlong x) {
assert(is_power_of_2(x), "x must be a power of 2: " JLONG_FORMAT, x);
return log2_long(x);
assert(is_power_of_2((julong)x), "x must be a power of 2: " JLONG_FORMAT, x);
const int bits = sizeof x * BitsPerByte;
return bits - count_leading_zeros(x) - 1;
}
// Round down to the closest power of two greater to or equal to the given

View File

@ -70,6 +70,25 @@ TEST(power_of_2, is_power_of_2) {
test_is_power_of_2<jlong>();
}
TEST(power_of_2, exact_log2) {
{
uintptr_t j = 1;
#ifdef _LP64
for (int i = 0; i < 64; i++, j <<= 1) {
#else
for (int i = 0; i < 32; i++, j <<= 1) {
#endif
EXPECT_EQ(i, exact_log2(j));
}
}
{
julong j = 1;
for (int i = 0; i < 64; i++, j <<= 1) {
EXPECT_EQ(i, exact_log2_long(j));
}
}
}
template <typename T> void round_up_power_of_2() {
EXPECT_EQ(round_up_power_of_2(T(1)), T(1)) << "value = " << T(1);
EXPECT_EQ(round_up_power_of_2(T(2)), T(2)) << "value = " << T(2);