Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/hotspot/share/gc/g1/g1CommittedRegionMap.cpp
40961 views
1
/*
2
* Copyright (c) 2020, Oracle and/or its affiliates. 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 it
6
* under the terms of the GNU General Public License version 2 only, as
7
* published by the Free Software Foundation.
8
*
9
* This code is distributed in the hope that it will be useful, but WITHOUT
10
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12
* version 2 for more details (a copy is included in the LICENSE file that
13
* accompanied this code).
14
*
15
* You should have received a copy of the GNU General Public License version
16
* 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 USA
20
* or visit www.oracle.com if you need additional information or have any
21
* questions.
22
*
23
*/
24
25
#include "precompiled.hpp"
26
#include "gc/g1/g1CommittedRegionMap.inline.hpp"
27
#include "logging/log.hpp"
28
#include "memory/universe.hpp"
29
#include "runtime/mutexLocker.hpp"
30
#include "runtime/safepoint.hpp"
31
#include "utilities/debug.hpp"
32
33
HeapRegionRange::HeapRegionRange(uint start, uint end) :
34
_start(start),
35
_end(end) {
36
assert(start <= end, "Invariant");
37
}
38
39
G1CommittedRegionMap::G1CommittedRegionMap() :
40
_active(mtGC),
41
_inactive(mtGC),
42
_num_active(0),
43
_num_inactive(0) { }
44
45
void G1CommittedRegionMap::initialize(uint num_regions) {
46
_active.initialize(num_regions);
47
_inactive.initialize(num_regions);
48
}
49
50
uint G1CommittedRegionMap::num_active() const {
51
return _num_active;
52
}
53
54
uint G1CommittedRegionMap::num_inactive() const {
55
return _num_inactive;
56
}
57
58
uint G1CommittedRegionMap::max_length() const {
59
return (uint) _active.size();
60
}
61
62
void G1CommittedRegionMap::activate(uint start, uint end) {
63
verify_active_count(start, end, 0);
64
verify_inactive_count(start, end, 0);
65
66
log_debug(gc, heap, region)("Activate regions [%u, %u)", start, end);
67
68
active_set_range(start, end);
69
}
70
71
void G1CommittedRegionMap::reactivate(uint start, uint end) {
72
verify_active_count(start, end, 0);
73
verify_inactive_count(start, end, (end - start));
74
75
log_debug(gc, heap, region)("Reactivate regions [%u, %u)", start, end);
76
77
active_set_range(start, end);
78
inactive_clear_range(start, end);
79
}
80
81
void G1CommittedRegionMap::deactivate(uint start, uint end) {
82
verify_active_count(start, end, (end - start));
83
verify_inactive_count(start, end, 0);
84
85
log_debug(gc, heap, region)("Deactivate regions [%u, %u)", start, end);
86
87
active_clear_range(start, end);
88
inactive_set_range(start, end);
89
}
90
91
void G1CommittedRegionMap::uncommit(uint start, uint end) {
92
verify_active_count(start, end, 0);
93
verify_inactive_count(start, end, (end-start));
94
95
log_debug(gc, heap, region)("Uncommit regions [%u, %u)", start, end);
96
97
inactive_clear_range(start, end);
98
}
99
100
HeapRegionRange G1CommittedRegionMap::next_active_range(uint offset) const {
101
// Find first active index from offset.
102
uint start = (uint) _active.get_next_one_offset(offset);
103
if (start == max_length()) {
104
// Early out when no active regions are found.
105
return HeapRegionRange(max_length(), max_length());
106
}
107
108
uint end = (uint) _active.get_next_zero_offset(start);
109
verify_active_range(start, end);
110
111
return HeapRegionRange(start, end);
112
}
113
114
HeapRegionRange G1CommittedRegionMap::next_committable_range(uint offset) const {
115
// We should only call this function when there are no inactive regions.
116
verify_no_inactive_regons();
117
118
// Find first free region from offset.
119
uint start = (uint) _active.get_next_zero_offset(offset);
120
if (start == max_length()) {
121
// Early out when no free regions are found.
122
return HeapRegionRange(max_length(), max_length());
123
}
124
125
uint end = (uint) _active.get_next_one_offset(start);
126
verify_free_range(start, end);
127
128
return HeapRegionRange(start, end);
129
}
130
131
HeapRegionRange G1CommittedRegionMap::next_inactive_range(uint offset) const {
132
// Find first inactive region from offset.
133
uint start = (uint) _inactive.get_next_one_offset(offset);
134
135
if (start == max_length()) {
136
// Early when no inactive regions are found.
137
return HeapRegionRange(max_length(), max_length());
138
}
139
140
uint end = (uint) _inactive.get_next_zero_offset(start);
141
verify_inactive_range(start, end);
142
143
return HeapRegionRange(start, end);
144
}
145
146
void G1CommittedRegionMap::active_set_range(uint start, uint end) {
147
guarantee_mt_safety_active();
148
149
_active.par_set_range(start, end, BitMap::unknown_range);
150
_num_active += (end - start);
151
}
152
153
void G1CommittedRegionMap::active_clear_range(uint start, uint end) {
154
guarantee_mt_safety_active();
155
156
_active.par_clear_range(start, end, BitMap::unknown_range);
157
_num_active -= (end - start);
158
}
159
160
void G1CommittedRegionMap::inactive_set_range(uint start, uint end) {
161
guarantee_mt_safety_inactive();
162
163
_inactive.par_set_range(start, end, BitMap::unknown_range);
164
_num_inactive += (end - start);
165
}
166
167
void G1CommittedRegionMap::inactive_clear_range(uint start, uint end) {
168
guarantee_mt_safety_inactive();
169
170
_inactive.par_clear_range(start, end, BitMap::unknown_range);
171
_num_inactive -= (end - start);
172
}
173
174
void G1CommittedRegionMap::guarantee_mt_safety_active() const {
175
// G1CommittedRegionMap _active-map MT safety protocol:
176
// (a) If we're at a safepoint, the caller must either be the VM thread or
177
// hold the FreeList_lock.
178
// (b) If we're not at a safepoint, the caller must hold the Heap_lock.
179
// Protocol only applies after initialization is complete.
180
181
if (!Universe::is_fully_initialized()) {
182
return;
183
}
184
185
if (SafepointSynchronize::is_at_safepoint()) {
186
guarantee(Thread::current()->is_VM_thread() ||
187
FreeList_lock->owned_by_self(),
188
"G1CommittedRegionMap _active-map MT safety protocol at a safepoint");
189
} else {
190
guarantee(Heap_lock->owned_by_self(),
191
"G1CommittedRegionMap _active-map MT safety protocol outside a safepoint");
192
}
193
}
194
195
void G1CommittedRegionMap::guarantee_mt_safety_inactive() const {
196
// G1CommittedRegionMap _inactive-map MT safety protocol:
197
// (a) If we're at a safepoint, the caller must either be the VM thread or
198
// hold the FreeList_lock.
199
// (b) If we're not at a safepoint, the caller must hold the Uncommit_lock.
200
// Protocol only applies after initialization is complete.
201
202
if (!Universe::is_fully_initialized()) {
203
return;
204
}
205
206
if (SafepointSynchronize::is_at_safepoint()) {
207
guarantee(Thread::current()->is_VM_thread() ||
208
FreeList_lock->owned_by_self(),
209
"G1CommittedRegionMap MT safety protocol at a safepoint");
210
} else {
211
guarantee(Uncommit_lock->owned_by_self(),
212
"G1CommittedRegionMap MT safety protocol outside a safepoint");
213
}
214
}
215
216
#ifdef ASSERT
217
void G1CommittedRegionMap::verify_active_range(uint start, uint end) const {
218
assert(active(start), "First region (%u) is not active", start);
219
assert(active(end - 1), "Last region (%u) is not active", end - 1);
220
assert(end == _active.size() || !active(end), "Region (%u) is active but not included in range", end);
221
}
222
223
void G1CommittedRegionMap::verify_inactive_range(uint start, uint end) const {
224
assert(inactive(start), "First region (%u) is not inactive", start);
225
assert(inactive(end - 1), "Last region (%u) in range is not inactive", end - 1);
226
assert(end == _inactive.size() || !inactive(end), "Region (%u) is inactive but not included in range", end);
227
}
228
229
void G1CommittedRegionMap::verify_free_range(uint start, uint end) const {
230
assert(!active(start), "First region (%u) is active", start);
231
assert(!active(end - 1), "Last region (%u) in range is active", end - 1);
232
}
233
234
void G1CommittedRegionMap::verify_no_inactive_regons() const {
235
BitMap::idx_t first_inactive = _inactive.get_next_one_offset(0);
236
assert(first_inactive == _inactive.size(), "Should be no inactive regions, but was at index: " SIZE_FORMAT, first_inactive);
237
}
238
239
void G1CommittedRegionMap::verify_active_count(uint start, uint end, uint expected) const {
240
uint found = (uint) _active.count_one_bits(start, end);
241
assert(found == expected, "Unexpected number of active regions, found: %u, expected: %u", found, expected);
242
}
243
244
void G1CommittedRegionMap::verify_inactive_count(uint start, uint end, uint expected) const {
245
uint found = (uint) _inactive.count_one_bits(start, end);
246
assert(found == expected, "Unexpected number of inactive regions, found: %u, expected: %u", found, expected);
247
}
248
249
#endif //ASSERT
250
251