From 44e045f0f89e79a3d24bb0c1d84c320c1603b1d0 Mon Sep 17 00:00:00 2001 From: duke Date: Thu, 22 Jun 2023 15:59:48 +0000 Subject: [PATCH] Backport 92167505b217c0e6074f58f8479be97bc4c776b3 --- .../share/gc/parallel/spaceCounters.cpp | 28 +++--- .../share/gc/parallel/spaceCounters.hpp | 17 ++-- .../share/gc/serial/cSpaceCounters.cpp | 32 ++++--- .../share/gc/serial/cSpaceCounters.hpp | 17 ++-- test/hotspot/jtreg/gc/TestSpaceCounters.java | 95 +++++++++++++++++++ 5 files changed, 146 insertions(+), 43 deletions(-) create mode 100644 test/hotspot/jtreg/gc/TestSpaceCounters.java diff --git a/src/hotspot/share/gc/parallel/spaceCounters.cpp b/src/hotspot/share/gc/parallel/spaceCounters.cpp index 08e1d13b17c..588c743d865 100644 --- a/src/hotspot/share/gc/parallel/spaceCounters.cpp +++ b/src/hotspot/share/gc/parallel/spaceCounters.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2023, 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 @@ -33,9 +33,9 @@ #include "utilities/macros.hpp" SpaceCounters::SpaceCounters(const char* name, int ordinal, size_t max_size, - MutableSpace* m, GenerationCounters* gc) : - _object_space(m) { - + MutableSpace* m, GenerationCounters* gc) + : _last_used_in_bytes(0), _object_space(m) +{ if (UsePerfData) { EXCEPTION_MARK; ResourceMark rm; @@ -55,13 +55,14 @@ SpaceCounters::SpaceCounters(const char* name, int ordinal, size_t max_size, cname = PerfDataManager::counter_name(_name_space, "capacity"); _capacity = PerfDataManager::create_variable(SUN_GC, cname, - PerfData::U_Bytes, - _object_space->capacity_in_bytes(), CHECK); + PerfData::U_Bytes, + _object_space->capacity_in_bytes(), + CHECK); cname = PerfDataManager::counter_name(_name_space, "used"); _used = PerfDataManager::create_variable(SUN_GC, cname, PerfData::U_Bytes, - new MutableSpaceUsedHelper(_object_space), - CHECK); + new UsedHelper(this), + CHECK); cname = PerfDataManager::counter_name(_name_space, "initCapacity"); PerfDataManager::create_constant(SUN_GC, cname, PerfData::U_Bytes, @@ -73,23 +74,22 @@ SpaceCounters::~SpaceCounters() { FREE_C_HEAP_ARRAY(char, _name_space); } -static volatile size_t last_used_in_bytes = 0; - void SpaceCounters::update_used() { size_t new_used = _object_space->used_in_bytes(); - Atomic::store(&last_used_in_bytes, new_used); + Atomic::store(&_last_used_in_bytes, new_used); _used->set_value(new_used); } -jlong MutableSpaceUsedHelper::take_sample() { +jlong SpaceCounters::UsedHelper::take_sample() { // Sampling may occur during GC, possibly while GC is updating the space. // The space can be in an inconsistent state during such an update. We // don't want to block sampling for the duration of a GC. Instead, skip // sampling in that case, using the last recorded value. assert(!Heap_lock->owned_by_self(), "precondition"); if (Heap_lock->try_lock()) { - Atomic::store(&last_used_in_bytes, _m->used_in_bytes()); + size_t new_used = _counters->_object_space->used_in_bytes(); + Atomic::store(&_counters->_last_used_in_bytes, new_used); Heap_lock->unlock(); } - return Atomic::load(&last_used_in_bytes); + return Atomic::load(&_counters->_last_used_in_bytes); } diff --git a/src/hotspot/share/gc/parallel/spaceCounters.hpp b/src/hotspot/share/gc/parallel/spaceCounters.hpp index d86762f6fca..3d0c1ff7b50 100644 --- a/src/hotspot/share/gc/parallel/spaceCounters.hpp +++ b/src/hotspot/share/gc/parallel/spaceCounters.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2023, 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 @@ -39,6 +39,7 @@ class SpaceCounters: public CHeapObj { private: PerfVariable* _capacity; PerfVariable* _used; + volatile size_t _last_used_in_bytes; // Constant PerfData types don't need to retain a reference. // However, it's a good idea to document them here. @@ -47,6 +48,8 @@ class SpaceCounters: public CHeapObj { MutableSpace* _object_space; char* _name_space; + class UsedHelper; + public: SpaceCounters(const char* name, int ordinal, size_t max_size, @@ -68,14 +71,14 @@ class SpaceCounters: public CHeapObj { const char* name_space() const { return _name_space; } }; -class MutableSpaceUsedHelper: public PerfLongSampleHelper { - private: - MutableSpace* _m; +class SpaceCounters::UsedHelper: public PerfLongSampleHelper { + private: + SpaceCounters* _counters; - public: - MutableSpaceUsedHelper(MutableSpace* m) : _m(m) { } + public: + UsedHelper(SpaceCounters* counters) : _counters(counters) { } - jlong take_sample() override; + jlong take_sample() override; }; #endif // SHARE_GC_PARALLEL_SPACECOUNTERS_HPP diff --git a/src/hotspot/share/gc/serial/cSpaceCounters.cpp b/src/hotspot/share/gc/serial/cSpaceCounters.cpp index 4bb6ecc7d62..6a9b5124578 100644 --- a/src/hotspot/share/gc/serial/cSpaceCounters.cpp +++ b/src/hotspot/share/gc/serial/cSpaceCounters.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2023, 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 @@ -28,9 +28,9 @@ #include "memory/resourceArea.hpp" CSpaceCounters::CSpaceCounters(const char* name, int ordinal, size_t max_size, - ContiguousSpace* s, GenerationCounters* gc) : - _space(s) { - + ContiguousSpace* s, GenerationCounters* gc) + : _last_used_in_bytes(0), _space(s) +{ if (UsePerfData) { EXCEPTION_MARK; ResourceMark rm; @@ -45,18 +45,21 @@ CSpaceCounters::CSpaceCounters(const char* name, int ordinal, size_t max_size, PerfDataManager::create_string_constant(SUN_GC, cname, name, CHECK); cname = PerfDataManager::counter_name(_name_space, "maxCapacity"); - _max_capacity = PerfDataManager::create_variable(SUN_GC, cname, PerfData::U_Bytes, - (jlong)max_size, CHECK); + _max_capacity = PerfDataManager::create_variable(SUN_GC, cname, + PerfData::U_Bytes, + (jlong)max_size, + CHECK); cname = PerfDataManager::counter_name(_name_space, "capacity"); _capacity = PerfDataManager::create_variable(SUN_GC, cname, PerfData::U_Bytes, - _space->capacity(), CHECK); + _space->capacity(), + CHECK); cname = PerfDataManager::counter_name(_name_space, "used"); _used = PerfDataManager::create_variable(SUN_GC, cname, PerfData::U_Bytes, - new ContiguousSpaceUsedHelper(_space), - CHECK); + new UsedHelper(this), + CHECK); cname = PerfDataManager::counter_name(_name_space, "initCapacity"); PerfDataManager::create_constant(SUN_GC, cname, PerfData::U_Bytes, @@ -72,11 +75,9 @@ void CSpaceCounters::update_capacity() { _capacity->set_value(_space->capacity()); } -static volatile size_t last_used_in_bytes = 0; - void CSpaceCounters::update_used() { size_t new_used = _space->used(); - Atomic::store(&last_used_in_bytes, new_used); + Atomic::store(&_last_used_in_bytes, new_used); _used->set_value(new_used); } @@ -85,15 +86,16 @@ void CSpaceCounters::update_all() { update_capacity(); } -jlong ContiguousSpaceUsedHelper::take_sample(){ +jlong CSpaceCounters::UsedHelper::take_sample(){ // Sampling may occur during GC, possibly while GC is updating the space. // The space can be in an inconsistent state during such an update. We // don't want to block sampling for the duration of a GC. Instead, skip // sampling in that case, using the last recorded value. assert(!Heap_lock->owned_by_self(), "precondition"); if (Heap_lock->try_lock()) { - Atomic::store(&last_used_in_bytes, _space->used()); + size_t new_used = _counters->_space->used(); + Atomic::store(&_counters->_last_used_in_bytes, new_used); Heap_lock->unlock(); } - return Atomic::load(&last_used_in_bytes); + return Atomic::load(&_counters->_last_used_in_bytes); } diff --git a/src/hotspot/share/gc/serial/cSpaceCounters.hpp b/src/hotspot/share/gc/serial/cSpaceCounters.hpp index fa3ee42140c..334f649382b 100644 --- a/src/hotspot/share/gc/serial/cSpaceCounters.hpp +++ b/src/hotspot/share/gc/serial/cSpaceCounters.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2023, 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 @@ -39,6 +39,7 @@ class CSpaceCounters: public CHeapObj { PerfVariable* _capacity; PerfVariable* _used; PerfVariable* _max_capacity; + volatile size_t _last_used_in_bytes; // Constant PerfData types don't need to retain a reference. // However, it's a good idea to document them here. @@ -47,6 +48,8 @@ class CSpaceCounters: public CHeapObj { ContiguousSpace* _space; char* _name_space; + class UsedHelper; + public: CSpaceCounters(const char* name, int ordinal, size_t max_size, @@ -61,14 +64,14 @@ class CSpaceCounters: public CHeapObj { const char* name_space() const { return _name_space; } }; -class ContiguousSpaceUsedHelper : public PerfLongSampleHelper { - private: - ContiguousSpace* _space; +class CSpaceCounters::UsedHelper : public PerfLongSampleHelper { + private: + CSpaceCounters* _counters; - public: - ContiguousSpaceUsedHelper(ContiguousSpace* space) : _space(space) { } + public: + UsedHelper(CSpaceCounters* counters) : _counters(counters) { } - jlong take_sample() override; + jlong take_sample() override; }; #endif // SHARE_GC_SERIAL_CSPACECOUNTERS_HPP diff --git a/test/hotspot/jtreg/gc/TestSpaceCounters.java b/test/hotspot/jtreg/gc/TestSpaceCounters.java new file mode 100644 index 00000000000..8fb1b2fdfe9 --- /dev/null +++ b/test/hotspot/jtreg/gc/TestSpaceCounters.java @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2023, 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. + */ + +package gc; + +/** + * @test id=Serial + * @requires vm.gc.Serial + * @summary Verify the expected space counters exist. + * @modules java.base/jdk.internal.misc + * @modules java.management/sun.management + * @modules jdk.internal.jvmstat/sun.jvmstat.monitor + * @library /test/lib / + * @run main/othervm -XX:+UseSerialGC -XX:+UsePerfData gc.TestSpaceCounters + */ + +/** + * @test id=Parallel + * @requires vm.gc.Parallel + * @summary Verify the expected space counters exist. + * @modules java.base/jdk.internal.misc + * @modules java.management/sun.management + * @modules jdk.internal.jvmstat/sun.jvmstat.monitor + * @library /test/lib / + * @run main/othervm -XX:+UseParallelGC -XX:+UsePerfData gc.TestSpaceCounters + */ + +import gc.testlibrary.Helpers; +import gc.testlibrary.PerfCounter; +import gc.testlibrary.PerfCounters; +import sun.jvmstat.monitor.MonitorException; + +public class TestSpaceCounters { + private static final String GENERATION_NAMESPACE = "sun.gc.generation."; + + // Each space has these counters. + private static final String[] COUNTER_NAMES = { + "maxCapacity", "capacity", "used", "initCapacity" }; + + private static String counterName(String name, int generation, int space) { + return GENERATION_NAMESPACE + generation + ".space." + space + "." + name; + } + + private static PerfCounter counter(String name, int generation, int space) { + String cname = counterName(name, generation, space); + try { + return PerfCounters.findByName(cname); + } catch (MonitorException e) { + throw new RuntimeException(e.toString()); + } + } + + private static long value(String name, int generation, int space) { + PerfCounter pc = counter(name, generation, space); + return pc.longValue(); + } + + private static void checkCounters(int generation, int space) { + for (int i = 0; i < COUNTER_NAMES.length; ++i) { + value(COUNTER_NAMES[i], generation, space); + } + } + + private static final int YOUNG_GENERATION = 0; + private static final int OLD_GENERATION = 1; + + public static void main(String[] args) { + // Young Generation has 3 spaces - eden, and two survivor spaces. + checkCounters(YOUNG_GENERATION, 0); + checkCounters(YOUNG_GENERATION, 1); + checkCounters(YOUNG_GENERATION, 2); + // Old Generation has 1 space. + checkCounters(OLD_GENERATION, 0); + } +}