Path: blob/master/src/hotspot/share/memory/metaspace/counters.hpp
40957 views
/*1* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.2* Copyright (c) 2020 SAP SE. 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 it6* under the terms of the GNU General Public License version 2 only, as7* published by the Free Software Foundation.8*9* This code is distributed in the hope that it will be useful, but WITHOUT10* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or11* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License12* version 2 for more details (a copy is included in the LICENSE file that13* accompanied this code).14*15* You should have received a copy of the GNU General Public License version16* 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 USA20* or visit www.oracle.com if you need additional information or have any21* questions.22*23*/2425#ifndef SHARE_MEMORY_METASPACE_COUNTERS_HPP26#define SHARE_MEMORY_METASPACE_COUNTERS_HPP2728#include "metaprogramming/isSigned.hpp"29#include "runtime/atomic.hpp"30#include "utilities/debug.hpp"31#include "utilities/globalDefinitions.hpp"3233namespace metaspace {3435// We seem to be counting a lot of things which makes it worthwhile to36// make helper classes for all that boilerplate coding.3738// AbstractCounter counts something and asserts overflow and underflow.39template <class T>40class AbstractCounter {4142T _c;4344// Only allow unsigned values for now45STATIC_ASSERT(IsSigned<T>::value == false);4647public:4849AbstractCounter() : _c(0) {}5051T get() const { return _c; }5253void increment() { increment_by(1); }54void decrement() { decrement_by(1); }5556void increment_by(T v) {57#ifdef ASSERT58T old = _c;59assert(old + v >= old,60"overflow (" UINT64_FORMAT "+" UINT64_FORMAT ")", (uint64_t)old, (uint64_t)v);61#endif62_c += v;63}6465void decrement_by(T v) {66assert(_c >= v,67"underflow (" UINT64_FORMAT "-" UINT64_FORMAT ")",68(uint64_t)_c, (uint64_t)v);69_c -= v;70}7172void reset() { _c = 0; }7374#ifdef ASSERT75void check(T expected) const {76assert(_c == expected, "Counter mismatch: %d, expected: %d.",77(int)_c, (int)expected);78}79#endif8081};8283// Atomic variant of AbstractCounter.84template <class T>85class AbstractAtomicCounter {8687volatile T _c;8889// Only allow unsigned values for now90STATIC_ASSERT(IsSigned<T>::value == false);9192public:9394AbstractAtomicCounter() : _c(0) {}9596T get() const { return _c; }9798void increment() {99Atomic::inc(&_c);100}101102void decrement() {103Atomic::dec(&_c);104}105106void increment_by(T v) {107Atomic::add(&_c, v);108}109110void decrement_by(T v) {111Atomic::sub(&_c, v);112}113114#ifdef ASSERT115void check(T expected) const {116assert(_c == expected, "Counter mismatch: %d, expected: %d.",117(int)_c, (int)expected);118}119#endif120121};122123typedef AbstractCounter<size_t> SizeCounter;124typedef AbstractCounter<unsigned> IntCounter;125126typedef AbstractAtomicCounter<size_t> SizeAtomicCounter;127128// We often count memory ranges (blocks, chunks etc).129// Make a helper class for that.130template <class T_num, class T_size>131class AbstractMemoryRangeCounter {132133AbstractCounter<T_num> _count;134AbstractCounter<T_size> _total_size;135136public:137138void add(T_size s) {139if(s > 0) {140_count.increment();141_total_size.increment_by(s);142}143}144145void sub(T_size s) {146if(s > 0) {147_count.decrement();148_total_size.decrement_by(s);149}150}151152T_num count() const { return _count.get(); }153T_size total_size() const { return _total_size.get(); }154155#ifdef ASSERT156void check(T_num expected_count, T_size expected_size) const {157_count.check(expected_count);158_total_size.check(expected_size);159}160void check(const AbstractMemoryRangeCounter<T_num, T_size>& other) const {161check(other.count(), other.total_size());162}163#endif164165};166167typedef AbstractMemoryRangeCounter<unsigned, size_t> MemRangeCounter;168169} // namespace metaspace170171#endif // SHARE_MEMORY_METASPACE_COUNTERS_HPP172173174175