Path: blob/master/test/hotspot/gtest/utilities/test_powerOfTwo.cpp
41145 views
/*1* Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223#include "precompiled.hpp"2425#include "utilities/globalDefinitions.hpp"26#include "utilities/powerOfTwo.hpp"27#include <limits>28#include <type_traits>29#include "unittest.hpp"3031struct StaticTestIsPowerOf2Result {32uint64_t _value;33int _status; // 0: success, > 0 indicates which failure case34constexpr StaticTestIsPowerOf2Result(uint64_t value, int status) :35_value(value), _status(status) {}36};3738// Structure copied from test_is_power_of_2 runtime test (below).39template<typename T>40static constexpr StaticTestIsPowerOf2Result static_test_is_power_of_2_aux(T v) {41using Result = StaticTestIsPowerOf2Result;42for ( ; v > 0; v >>= 1) {43if (!is_power_of_2(v)) {44return Result(v, 1);45} else if ((v > 2) && is_power_of_2(T(v - 1))) {46return Result(v, 2);47} else if ((v > 1) && is_power_of_2(T(v + 1))) {48return Result(v, 3);49}50}51return Result(v, 0);52}5354template<typename T>55static void static_test_is_power_of_2() {56constexpr StaticTestIsPowerOf2Result result57= static_test_is_power_of_2_aux(max_power_of_2<T>());5859EXPECT_EQ(0, result._status)60<< "value = " << result._value << ", status = " << result._status;61}6263template <typename T> static void test_is_power_of_2() {64EXPECT_FALSE(is_power_of_2(T(0)));65EXPECT_FALSE(is_power_of_2(~T(0)));6667static_assert(!is_power_of_2(T(0)), "");68static_assert(!is_power_of_2(~T(0)), "");6970// Should be false regardless of whether T is signed or unsigned.71EXPECT_FALSE(is_power_of_2(std::numeric_limits<T>::min()));72static_assert(!is_power_of_2(std::numeric_limits<T>::min()), "");7374// Test true75for (T i = max_power_of_2<T>(); i > 0; i = (i >> 1)) {76EXPECT_TRUE(is_power_of_2(i)) << "value = " << T(i);77}7879// Test one less80for (T i = max_power_of_2<T>(); i > 2; i = (i >> 1)) {81EXPECT_FALSE(is_power_of_2(i - 1)) << "value = " << T(i - 1);82}8384// Test one more85for (T i = max_power_of_2<T>(); i > 1; i = (i >> 1)) {86EXPECT_FALSE(is_power_of_2(i + 1)) << "value = " << T(i + 1);87}8889static_test_is_power_of_2<T>();90}9192TEST(power_of_2, is_power_of_2) {93test_is_power_of_2<int8_t>();94test_is_power_of_2<int16_t>();95test_is_power_of_2<int32_t>();96test_is_power_of_2<int64_t>();97test_is_power_of_2<int8_t>();98test_is_power_of_2<int16_t>();99test_is_power_of_2<int32_t>();100test_is_power_of_2<int64_t>();101102test_is_power_of_2<jint>();103test_is_power_of_2<jlong>();104}105106TEST(power_of_2, exact_log2) {107{108uintptr_t j = 1;109#ifdef _LP64110for (int i = 0; i < 64; i++, j <<= 1) {111#else112for (int i = 0; i < 32; i++, j <<= 1) {113#endif114EXPECT_EQ(i, exact_log2(j));115}116}117{118julong j = 1;119for (int i = 0; i < 64; i++, j <<= 1) {120EXPECT_EQ(i, exact_log2_long(j));121}122}123}124125template <typename T> void round_up_power_of_2() {126EXPECT_EQ(round_up_power_of_2(T(1)), T(1)) << "value = " << T(1);127EXPECT_EQ(round_up_power_of_2(T(2)), T(2)) << "value = " << T(2);128EXPECT_EQ(round_up_power_of_2(T(3)), T(4)) << "value = " << T(3);129EXPECT_EQ(round_up_power_of_2(T(4)), T(4)) << "value = " << T(4);130EXPECT_EQ(round_up_power_of_2(T(5)), T(8)) << "value = " << T(5);131EXPECT_EQ(round_up_power_of_2(T(6)), T(8)) << "value = " << T(6);132EXPECT_EQ(round_up_power_of_2(T(7)), T(8)) << "value = " << T(7);133EXPECT_EQ(round_up_power_of_2(T(8)), T(8)) << "value = " << T(8);134EXPECT_EQ(round_up_power_of_2(T(9)), T(16)) << "value = " << T(9);135EXPECT_EQ(round_up_power_of_2(T(10)), T(16)) << "value = " << T(10);136137T t_max_pow2 = max_power_of_2<T>();138139// round_up(any power of two) should return input140for (T pow2 = T(1); pow2 < t_max_pow2; pow2 *= 2) {141EXPECT_EQ(pow2, round_up_power_of_2(pow2))142<< "value = " << pow2;143}144EXPECT_EQ(round_up_power_of_2(t_max_pow2), t_max_pow2)145<< "value = " << (t_max_pow2);146147// For each pow2 gt 2, round_up(pow2 - 1) should return pow2148for (T pow2 = T(4); pow2 < t_max_pow2; pow2 *= 2) {149EXPECT_EQ(pow2, round_up_power_of_2(pow2 - 1))150<< "value = " << pow2;151}152EXPECT_EQ(round_up_power_of_2(t_max_pow2 - 1), t_max_pow2)153<< "value = " << (t_max_pow2 - 1);154155}156157TEST(power_of_2, round_up_power_of_2) {158round_up_power_of_2<int8_t>();159round_up_power_of_2<int16_t>();160round_up_power_of_2<int32_t>();161round_up_power_of_2<int64_t>();162round_up_power_of_2<uint8_t>();163round_up_power_of_2<uint16_t>();164round_up_power_of_2<uint32_t>();165round_up_power_of_2<uint64_t>();166}167168template <typename T> void round_down_power_of_2() {169EXPECT_EQ(round_down_power_of_2(T(1)), T(1)) << "value = " << T(1);170EXPECT_EQ(round_down_power_of_2(T(2)), T(2)) << "value = " << T(2);171EXPECT_EQ(round_down_power_of_2(T(3)), T(2)) << "value = " << T(3);172EXPECT_EQ(round_down_power_of_2(T(4)), T(4)) << "value = " << T(4);173EXPECT_EQ(round_down_power_of_2(T(5)), T(4)) << "value = " << T(5);174EXPECT_EQ(round_down_power_of_2(T(6)), T(4)) << "value = " << T(6);175EXPECT_EQ(round_down_power_of_2(T(7)), T(4)) << "value = " << T(7);176EXPECT_EQ(round_down_power_of_2(T(8)), T(8)) << "value = " << T(8);177EXPECT_EQ(round_down_power_of_2(T(9)), T(8)) << "value = " << T(9);178EXPECT_EQ(round_down_power_of_2(T(10)), T(8)) << "value = " << T(10);179180T t_max_pow2 = max_power_of_2<T>();181182// For each pow2 >= 2:183// - round_down(pow2) should return pow2184// - round_down(pow2 + 1) should return pow2185// - round_down(pow2 - 1) should return pow2 / 2186for (T pow2 = T(2); pow2 < t_max_pow2; pow2 = pow2 * 2) {187EXPECT_EQ(pow2, round_down_power_of_2(pow2))188<< "value = " << pow2;189EXPECT_EQ(pow2, round_down_power_of_2(pow2 + 1))190<< "value = " << pow2;191EXPECT_EQ(pow2 / 2, round_down_power_of_2(pow2 - 1))192<< "value = " << (pow2 / 2);193}194EXPECT_EQ(round_down_power_of_2(t_max_pow2), t_max_pow2)195<< "value = " << (t_max_pow2);196EXPECT_EQ(round_down_power_of_2(t_max_pow2 + 1), t_max_pow2)197<< "value = " << (t_max_pow2 + 1);198EXPECT_EQ(round_down_power_of_2(t_max_pow2 - 1), t_max_pow2 / 2)199<< "value = " << (t_max_pow2 - 1);200}201202TEST(power_of_2, round_down_power_of_2) {203round_down_power_of_2<int8_t>();204round_down_power_of_2<int16_t>();205round_down_power_of_2<int32_t>();206round_down_power_of_2<int64_t>();207round_down_power_of_2<uint8_t>();208round_down_power_of_2<uint16_t>();209round_down_power_of_2<uint32_t>();210round_down_power_of_2<uint64_t>();211}212213template <typename T> void next_power_of_2() {214EXPECT_EQ(next_power_of_2(T(0)), T(1)) << "value = " << T(0);215EXPECT_EQ(next_power_of_2(T(1)), T(2)) << "value = " << T(1);216EXPECT_EQ(next_power_of_2(T(2)), T(4)) << "value = " << T(2);217EXPECT_EQ(next_power_of_2(T(3)), T(4)) << "value = " << T(3);218EXPECT_EQ(next_power_of_2(T(4)), T(8)) << "value = " << T(4);219EXPECT_EQ(next_power_of_2(T(5)), T(8)) << "value = " << T(5);220EXPECT_EQ(next_power_of_2(T(6)), T(8)) << "value = " << T(6);221EXPECT_EQ(next_power_of_2(T(7)), T(8)) << "value = " << T(7);222EXPECT_EQ(next_power_of_2(T(8)), T(16)) << "value = " << T(8);223EXPECT_EQ(next_power_of_2(T(9)), T(16)) << "value = " << T(9);224EXPECT_EQ(next_power_of_2(T(10)), T(16)) << "value = " << T(10);225226T t_max_pow2 = max_power_of_2<T>();227228// next(pow2 - 1) should return pow2229for (T pow2 = T(1); pow2 < t_max_pow2; pow2 = pow2 * 2) {230EXPECT_EQ(pow2, next_power_of_2(pow2 - 1))231<< "value = " << pow2 - 1;232}233EXPECT_EQ(next_power_of_2(t_max_pow2 - 1), t_max_pow2)234<< "value = " << (t_max_pow2 - 1);235236// next(pow2) should return pow2 * 2237for (T pow2 = T(1); pow2 < t_max_pow2 / 2; pow2 = pow2 * 2) {238EXPECT_EQ(pow2 * 2, next_power_of_2(pow2))239<< "value = " << pow2;240}241}242243TEST(power_of_2, next_power_of_2) {244next_power_of_2<int8_t>();245next_power_of_2<int16_t>();246next_power_of_2<int32_t>();247next_power_of_2<int64_t>();248next_power_of_2<uint8_t>();249next_power_of_2<uint16_t>();250next_power_of_2<uint32_t>();251next_power_of_2<uint64_t>();252}253254TEST(power_of_2, max) {255EXPECT_EQ(max_power_of_2<int8_t>(), 0x40);256EXPECT_EQ(max_power_of_2<int16_t>(), 0x4000);257EXPECT_EQ(max_power_of_2<int32_t>(), 0x40000000);258EXPECT_EQ(max_power_of_2<int64_t>(), CONST64(0x4000000000000000));259EXPECT_EQ(max_power_of_2<uint8_t>(), 0x80u);260EXPECT_EQ(max_power_of_2<uint16_t>(), 0x8000u);261EXPECT_EQ(max_power_of_2<uint32_t>(), 0x80000000u);262EXPECT_EQ(max_power_of_2<uint64_t>(), UCONST64(0x8000000000000000));263}264265template <typename T, ENABLE_IF(std::is_integral<T>::value)>266void check_log2i_variants_for(T dummy) {267int limit = sizeof(T) * BitsPerByte;268if (std::is_signed<T>::value) {269T min = std::numeric_limits<T>::min();270EXPECT_EQ(limit - 1, log2i_graceful(min));271EXPECT_EQ(limit - 1, log2i_graceful((T)-1));272limit--;273}274{275// Test log2i_graceful handles 0 input276EXPECT_EQ(-1, log2i_graceful(T(0)));277}278{279// Test the all-1s bit patterns280T var = 1;281for (int i = 0; i < limit; i++, var = (var << 1) | 1) {282EXPECT_EQ(i, log2i(var));283}284}285{286// Test the powers of 2 and powers + 1287T var = 1;288for (int i = 0; i < limit; i++, var <<= 1) {289EXPECT_EQ(i, log2i(var));290EXPECT_EQ(i, log2i_graceful(var));291EXPECT_EQ(i, log2i_exact(var));292EXPECT_EQ(i, log2i(var | 1));293}294}295}296297TEST(power_of_2, log2i) {298check_log2i_variants_for((uintptr_t)0);299check_log2i_variants_for((intptr_t)0);300check_log2i_variants_for((julong)0);301check_log2i_variants_for((int)0);302check_log2i_variants_for((jint)0);303check_log2i_variants_for((uint)0);304check_log2i_variants_for((jlong)0);305}306307308