From c16eb89ce0d59f2ff83b6db0bee3e384ec8d5efe Mon Sep 17 00:00:00 2001 From: "Y. Srinivas Ramakrishna" Date: Thu, 8 Dec 2022 21:54:16 +0000 Subject: [PATCH] 8298138: Shenandoah: HdrSeq asserts "sub-bucket index (512) overflow for value ( 1.00)" Reviewed-by: rkennke, shade --- .../gc/shenandoah/shenandoahNumberSeq.cpp | 4 +- .../gc/shenandoah/shenandoahNumberSeq.hpp | 2 +- .../shenandoah/test_shenandoahNumberSeq.cpp | 74 +++++++++++++++++++ 3 files changed, 77 insertions(+), 3 deletions(-) create mode 100644 test/hotspot/gtest/gc/shenandoah/test_shenandoahNumberSeq.cpp diff --git a/src/hotspot/share/gc/shenandoah/shenandoahNumberSeq.cpp b/src/hotspot/share/gc/shenandoah/shenandoahNumberSeq.cpp index 33d5df425b3..c0fc3aca5a7 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahNumberSeq.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahNumberSeq.cpp @@ -56,7 +56,7 @@ void HdrSeq::add(double val) { int mag; if (v > 0) { mag = 0; - while (v > 1) { + while (v >= 1) { mag++; v /= 10; } @@ -71,7 +71,7 @@ void HdrSeq::add(double val) { int bucket = -MagMinimum + mag; int sub_bucket = (int) (v * ValBuckets); - // Defensively saturate for product bits: + // Defensively saturate for product bits if (bucket < 0) { assert (false, "bucket index (%d) underflow for value (%8.2f)", bucket, val); bucket = 0; diff --git a/src/hotspot/share/gc/shenandoah/shenandoahNumberSeq.hpp b/src/hotspot/share/gc/shenandoah/shenandoahNumberSeq.hpp index 9f9cb2ecaaf..42f91f6a9b8 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahNumberSeq.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahNumberSeq.hpp @@ -55,7 +55,7 @@ public: // Binary magnitude sequence stores the power-of-two histogram. // It has very low memory requirements, and is thread-safe. When accuracy // is not needed, it is preferred over HdrSeq. -class BinaryMagnitudeSeq { +class BinaryMagnitudeSeq : public CHeapObj { private: size_t _sum; size_t* _mags; diff --git a/test/hotspot/gtest/gc/shenandoah/test_shenandoahNumberSeq.cpp b/test/hotspot/gtest/gc/shenandoah/test_shenandoahNumberSeq.cpp new file mode 100644 index 00000000000..eddc11daca1 --- /dev/null +++ b/test/hotspot/gtest/gc/shenandoah/test_shenandoahNumberSeq.cpp @@ -0,0 +1,74 @@ +/* + * Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. + * Copyright (c) 2022, 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +#include "precompiled.hpp" +#include "gc/shenandoah/shenandoahNumberSeq.hpp" +#include +#include "unittest.hpp" +#include "utilities/ostream.hpp" + +class ShenandoahNumberSeqTest: public ::testing::Test { + protected: + HdrSeq seq; +}; + +class BasicShenandoahNumberSeqTest: public ShenandoahNumberSeqTest { + protected: + const double err = 0.5; + BasicShenandoahNumberSeqTest() { + seq.add(0); + seq.add(1); + seq.add(10); + for (int i = 0; i < 7; i++) { + seq.add(100); + } + std::cout << " p0 = " << seq.percentile(0); + std::cout << " p10 = " << seq.percentile(10); + std::cout << " p20 = " << seq.percentile(20); + std::cout << " p30 = " << seq.percentile(30); + std::cout << " p50 = " << seq.percentile(50); + std::cout << " p80 = " << seq.percentile(80); + std::cout << " p90 = " << seq.percentile(90); + std::cout << " p100 = " << seq.percentile(100); + } +}; + +TEST_VM_F(BasicShenandoahNumberSeqTest, maximum_test) { + EXPECT_EQ(seq.maximum(), 100); +} + +TEST_VM_F(BasicShenandoahNumberSeqTest, minimum_test) { + EXPECT_EQ(0, seq.percentile(0)); +} + +TEST_VM_F(BasicShenandoahNumberSeqTest, percentile_test) { + EXPECT_NEAR(0, seq.percentile(10), err); + EXPECT_NEAR(1, seq.percentile(20), err); + EXPECT_NEAR(10, seq.percentile(30), err); + EXPECT_NEAR(100, seq.percentile(40), err); + EXPECT_NEAR(100, seq.percentile(50), err); + EXPECT_NEAR(100, seq.percentile(75), err); + EXPECT_NEAR(100, seq.percentile(90), err); + EXPECT_NEAR(100, seq.percentile(100), err); +}