Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/hotspot/share/memory/metaspace/counters.hpp
40957 views
1
/*
2
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
3
* Copyright (c) 2020 SAP SE. All rights reserved.
4
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5
*
6
* This code is free software; you can redistribute it and/or modify it
7
* under the terms of the GNU General Public License version 2 only, as
8
* published by the Free Software Foundation.
9
*
10
* This code is distributed in the hope that it will be useful, but WITHOUT
11
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13
* version 2 for more details (a copy is included in the LICENSE file that
14
* accompanied this code).
15
*
16
* You should have received a copy of the GNU General Public License version
17
* 2 along with this work; if not, write to the Free Software Foundation,
18
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19
*
20
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21
* or visit www.oracle.com if you need additional information or have any
22
* questions.
23
*
24
*/
25
26
#ifndef SHARE_MEMORY_METASPACE_COUNTERS_HPP
27
#define SHARE_MEMORY_METASPACE_COUNTERS_HPP
28
29
#include "metaprogramming/isSigned.hpp"
30
#include "runtime/atomic.hpp"
31
#include "utilities/debug.hpp"
32
#include "utilities/globalDefinitions.hpp"
33
34
namespace metaspace {
35
36
// We seem to be counting a lot of things which makes it worthwhile to
37
// make helper classes for all that boilerplate coding.
38
39
// AbstractCounter counts something and asserts overflow and underflow.
40
template <class T>
41
class AbstractCounter {
42
43
T _c;
44
45
// Only allow unsigned values for now
46
STATIC_ASSERT(IsSigned<T>::value == false);
47
48
public:
49
50
AbstractCounter() : _c(0) {}
51
52
T get() const { return _c; }
53
54
void increment() { increment_by(1); }
55
void decrement() { decrement_by(1); }
56
57
void increment_by(T v) {
58
#ifdef ASSERT
59
T old = _c;
60
assert(old + v >= old,
61
"overflow (" UINT64_FORMAT "+" UINT64_FORMAT ")", (uint64_t)old, (uint64_t)v);
62
#endif
63
_c += v;
64
}
65
66
void decrement_by(T v) {
67
assert(_c >= v,
68
"underflow (" UINT64_FORMAT "-" UINT64_FORMAT ")",
69
(uint64_t)_c, (uint64_t)v);
70
_c -= v;
71
}
72
73
void reset() { _c = 0; }
74
75
#ifdef ASSERT
76
void check(T expected) const {
77
assert(_c == expected, "Counter mismatch: %d, expected: %d.",
78
(int)_c, (int)expected);
79
}
80
#endif
81
82
};
83
84
// Atomic variant of AbstractCounter.
85
template <class T>
86
class AbstractAtomicCounter {
87
88
volatile T _c;
89
90
// Only allow unsigned values for now
91
STATIC_ASSERT(IsSigned<T>::value == false);
92
93
public:
94
95
AbstractAtomicCounter() : _c(0) {}
96
97
T get() const { return _c; }
98
99
void increment() {
100
Atomic::inc(&_c);
101
}
102
103
void decrement() {
104
Atomic::dec(&_c);
105
}
106
107
void increment_by(T v) {
108
Atomic::add(&_c, v);
109
}
110
111
void decrement_by(T v) {
112
Atomic::sub(&_c, v);
113
}
114
115
#ifdef ASSERT
116
void check(T expected) const {
117
assert(_c == expected, "Counter mismatch: %d, expected: %d.",
118
(int)_c, (int)expected);
119
}
120
#endif
121
122
};
123
124
typedef AbstractCounter<size_t> SizeCounter;
125
typedef AbstractCounter<unsigned> IntCounter;
126
127
typedef AbstractAtomicCounter<size_t> SizeAtomicCounter;
128
129
// We often count memory ranges (blocks, chunks etc).
130
// Make a helper class for that.
131
template <class T_num, class T_size>
132
class AbstractMemoryRangeCounter {
133
134
AbstractCounter<T_num> _count;
135
AbstractCounter<T_size> _total_size;
136
137
public:
138
139
void add(T_size s) {
140
if(s > 0) {
141
_count.increment();
142
_total_size.increment_by(s);
143
}
144
}
145
146
void sub(T_size s) {
147
if(s > 0) {
148
_count.decrement();
149
_total_size.decrement_by(s);
150
}
151
}
152
153
T_num count() const { return _count.get(); }
154
T_size total_size() const { return _total_size.get(); }
155
156
#ifdef ASSERT
157
void check(T_num expected_count, T_size expected_size) const {
158
_count.check(expected_count);
159
_total_size.check(expected_size);
160
}
161
void check(const AbstractMemoryRangeCounter<T_num, T_size>& other) const {
162
check(other.count(), other.total_size());
163
}
164
#endif
165
166
};
167
168
typedef AbstractMemoryRangeCounter<unsigned, size_t> MemRangeCounter;
169
170
} // namespace metaspace
171
172
#endif // SHARE_MEMORY_METASPACE_COUNTERS_HPP
173
174
175