Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/hotspot/src/share/vm/gc_implementation/shenandoah/shenandoahHeapRegion.hpp
38920 views
1
/*
2
* Copyright (c) 2013, 2019, Red Hat, Inc. All rights reserved.
3
*
4
* This code is free software; you can redistribute it and/or modify it
5
* under the terms of the GNU General Public License version 2 only, as
6
* published by the Free Software Foundation.
7
*
8
* This code is distributed in the hope that it will be useful, but WITHOUT
9
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
11
* version 2 for more details (a copy is included in the LICENSE file that
12
* accompanied this code).
13
*
14
* You should have received a copy of the GNU General Public License version
15
* 2 along with this work; if not, write to the Free Software Foundation,
16
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
17
*
18
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
19
* or visit www.oracle.com if you need additional information or have any
20
* questions.
21
*
22
*/
23
24
#ifndef SHARE_VM_GC_SHENANDOAH_SHENANDOAHHEAPREGION_HPP
25
#define SHARE_VM_GC_SHENANDOAH_SHENANDOAHHEAPREGION_HPP
26
27
#include "gc_implementation/shenandoah/shenandoahAllocRequest.hpp"
28
#include "gc_implementation/shenandoah/shenandoahAsserts.hpp"
29
#include "gc_implementation/shenandoah/shenandoahHeap.hpp"
30
#include "gc_implementation/shenandoah/shenandoahPacer.hpp"
31
#include "gc_implementation/shenandoah/shenandoahPadding.hpp"
32
33
class VMStructs;
34
class ShenandoahHeapRegionStateConstant;
35
36
class ShenandoahHeapRegion {
37
friend class VMStructs;
38
friend class ShenandoahHeapRegionStateConstant;
39
private:
40
/*
41
Region state is described by a state machine. Transitions are guarded by
42
heap lock, which allows changing the state of several regions atomically.
43
Region states can be logically aggregated in groups.
44
45
"Empty":
46
.................................................................
47
. .
48
. .
49
. Uncommitted <------- Committed <------------------------\
50
. | | . |
51
. \---------v-----------/ . |
52
. | . |
53
.........................|....................................... |
54
| |
55
"Active": | |
56
.........................|....................................... |
57
. | . |
58
. /-----------------^-------------------\ . |
59
. | | . |
60
. v v "Humongous": . |
61
. Regular ---\-----\ ..................O................ . |
62
. | ^ | | . | . . |
63
. | | | | . *---------\ . . |
64
. v | | | . v v . . |
65
. Pinned Cset | . HStart <--> H/Start H/Cont . . |
66
. ^ / | | . Pinned v | . . |
67
. | / | | . *<--------/ . . |
68
. | v | | . | . . |
69
. CsetPinned | | ..................O................ . |
70
. | | | . |
71
. \-----\---v-------------------/ . |
72
. | . |
73
.........................|....................................... |
74
| |
75
"Trash": | |
76
.........................|....................................... |
77
. | . |
78
. v . |
79
. Trash ---------------------------------------/
80
. .
81
. .
82
.................................................................
83
84
Transition from "Empty" to "Active" is first allocation. It can go from {Uncommitted, Committed}
85
to {Regular, "Humongous"}. The allocation may happen in Regular regions too, but not in Humongous.
86
87
Transition from "Active" to "Trash" is reclamation. It can go from CSet during the normal cycle,
88
and from {Regular, "Humongous"} for immediate reclamation. The existence of Trash state allows
89
quick reclamation without actual cleaning up.
90
91
Transition from "Trash" to "Empty" is recycling. It cleans up the regions and corresponding metadata.
92
Can be done asynchronously and in bulk.
93
94
Note how internal transitions disallow logic bugs:
95
a) No region can go Empty, unless properly reclaimed/recycled;
96
b) No region can go Uncommitted, unless reclaimed/recycled first;
97
c) Only Regular regions can go to CSet;
98
d) Pinned cannot go Trash, thus it could never be reclaimed until unpinned;
99
e) Pinned cannot go CSet, thus it never moves;
100
f) Humongous cannot be used for regular allocations;
101
g) Humongous cannot go CSet, thus it never moves;
102
h) Humongous start can go pinned, and thus can be protected from moves (humongous continuations should
103
follow associated humongous starts, not pinnable/movable by themselves);
104
i) Empty cannot go Trash, avoiding useless work;
105
j) ...
106
*/
107
108
enum RegionState {
109
_empty_uncommitted, // region is empty and has memory uncommitted
110
_empty_committed, // region is empty and has memory committed
111
_regular, // region is for regular allocations
112
_humongous_start, // region is the humongous start
113
_humongous_cont, // region is the humongous continuation
114
_pinned_humongous_start, // region is both humongous start and pinned
115
_cset, // region is in collection set
116
_pinned, // region is pinned
117
_pinned_cset, // region is pinned and in cset (evac failure path)
118
_trash, // region contains only trash
119
_REGION_STATES_NUM // last
120
};
121
122
static const char* region_state_to_string(RegionState s) {
123
switch (s) {
124
case _empty_uncommitted: return "Empty Uncommitted";
125
case _empty_committed: return "Empty Committed";
126
case _regular: return "Regular";
127
case _humongous_start: return "Humongous Start";
128
case _humongous_cont: return "Humongous Continuation";
129
case _pinned_humongous_start: return "Humongous Start, Pinned";
130
case _cset: return "Collection Set";
131
case _pinned: return "Pinned";
132
case _pinned_cset: return "Collection Set, Pinned";
133
case _trash: return "Trash";
134
default:
135
ShouldNotReachHere();
136
return "";
137
}
138
}
139
140
// This method protects from accidental changes in enum order:
141
int region_state_to_ordinal(RegionState s) const {
142
switch (s) {
143
case _empty_uncommitted: return 0;
144
case _empty_committed: return 1;
145
case _regular: return 2;
146
case _humongous_start: return 3;
147
case _humongous_cont: return 4;
148
case _cset: return 5;
149
case _pinned: return 6;
150
case _trash: return 7;
151
case _pinned_cset: return 8;
152
case _pinned_humongous_start: return 9;
153
default:
154
ShouldNotReachHere();
155
return -1;
156
}
157
}
158
159
void report_illegal_transition(const char* method);
160
161
public:
162
static const int region_states_num() {
163
return _REGION_STATES_NUM;
164
}
165
166
// Allowed transitions from the outside code:
167
void make_regular_allocation();
168
void make_regular_bypass();
169
void make_humongous_start();
170
void make_humongous_cont();
171
void make_humongous_start_bypass();
172
void make_humongous_cont_bypass();
173
void make_pinned();
174
void make_unpinned();
175
void make_cset();
176
void make_trash();
177
void make_trash_immediate();
178
void make_empty();
179
void make_uncommitted();
180
void make_committed_bypass();
181
182
// Individual states:
183
bool is_empty_uncommitted() const { return _state == _empty_uncommitted; }
184
bool is_empty_committed() const { return _state == _empty_committed; }
185
bool is_regular() const { return _state == _regular; }
186
bool is_humongous_continuation() const { return _state == _humongous_cont; }
187
188
// Participation in logical groups:
189
bool is_empty() const { return is_empty_committed() || is_empty_uncommitted(); }
190
bool is_active() const { return !is_empty() && !is_trash(); }
191
bool is_trash() const { return _state == _trash; }
192
bool is_humongous_start() const { return _state == _humongous_start || _state == _pinned_humongous_start; }
193
bool is_humongous() const { return is_humongous_start() || is_humongous_continuation(); }
194
bool is_committed() const { return !is_empty_uncommitted(); }
195
bool is_cset() const { return _state == _cset || _state == _pinned_cset; }
196
bool is_pinned() const { return _state == _pinned || _state == _pinned_cset || _state == _pinned_humongous_start; }
197
198
// Macro-properties:
199
bool is_alloc_allowed() const { return is_empty() || is_regular() || _state == _pinned; }
200
bool is_stw_move_allowed() const { return is_regular() || _state == _cset || (ShenandoahHumongousMoves && _state == _humongous_start); }
201
202
RegionState state() const { return _state; }
203
int state_ordinal() const { return region_state_to_ordinal(_state); }
204
205
void record_pin();
206
void record_unpin();
207
size_t pin_count() const;
208
209
private:
210
static size_t RegionCount;
211
static size_t RegionSizeBytes;
212
static size_t RegionSizeWords;
213
static size_t RegionSizeBytesShift;
214
static size_t RegionSizeWordsShift;
215
static size_t RegionSizeBytesMask;
216
static size_t RegionSizeWordsMask;
217
static size_t HumongousThresholdBytes;
218
static size_t HumongousThresholdWords;
219
static size_t MaxTLABSizeBytes;
220
static size_t MaxTLABSizeWords;
221
222
// Never updated fields
223
size_t const _index;
224
HeapWord* const _bottom;
225
HeapWord* const _end;
226
227
// Rarely updated fields
228
HeapWord* _new_top;
229
double _empty_time;
230
231
// Seldom updated fields
232
RegionState _state;
233
234
// Frequently updated fields
235
HeapWord* _top;
236
237
size_t _tlab_allocs;
238
size_t _gclab_allocs;
239
240
volatile jint _live_data;
241
volatile jint _critical_pins;
242
243
HeapWord* volatile _update_watermark;
244
245
public:
246
ShenandoahHeapRegion(HeapWord* start, size_t index, bool committed);
247
248
static const size_t MIN_NUM_REGIONS = 10;
249
250
static void setup_sizes(size_t max_heap_size);
251
252
double empty_time() {
253
return _empty_time;
254
}
255
256
inline static size_t required_regions(size_t bytes) {
257
return (bytes + ShenandoahHeapRegion::region_size_bytes() - 1) >> ShenandoahHeapRegion::region_size_bytes_shift();
258
}
259
260
inline static size_t region_count() {
261
return ShenandoahHeapRegion::RegionCount;
262
}
263
264
inline static size_t region_size_bytes() {
265
return ShenandoahHeapRegion::RegionSizeBytes;
266
}
267
268
inline static size_t region_size_words() {
269
return ShenandoahHeapRegion::RegionSizeWords;
270
}
271
272
inline static size_t region_size_bytes_shift() {
273
return ShenandoahHeapRegion::RegionSizeBytesShift;
274
}
275
276
inline static size_t region_size_words_shift() {
277
return ShenandoahHeapRegion::RegionSizeWordsShift;
278
}
279
280
inline static size_t region_size_bytes_mask() {
281
return ShenandoahHeapRegion::RegionSizeBytesMask;
282
}
283
284
inline static size_t region_size_words_mask() {
285
return ShenandoahHeapRegion::RegionSizeWordsMask;
286
}
287
288
// Convert to jint with sanity checking
289
inline static jint region_size_bytes_jint() {
290
assert (ShenandoahHeapRegion::RegionSizeBytes <= (size_t)max_jint, "sanity");
291
return (jint)ShenandoahHeapRegion::RegionSizeBytes;
292
}
293
294
// Convert to jint with sanity checking
295
inline static jint region_size_words_jint() {
296
assert (ShenandoahHeapRegion::RegionSizeWords <= (size_t)max_jint, "sanity");
297
return (jint)ShenandoahHeapRegion::RegionSizeWords;
298
}
299
300
// Convert to jint with sanity checking
301
inline static jint region_size_bytes_shift_jint() {
302
assert (ShenandoahHeapRegion::RegionSizeBytesShift <= (size_t)max_jint, "sanity");
303
return (jint)ShenandoahHeapRegion::RegionSizeBytesShift;
304
}
305
306
// Convert to jint with sanity checking
307
inline static jint region_size_words_shift_jint() {
308
assert (ShenandoahHeapRegion::RegionSizeWordsShift <= (size_t)max_jint, "sanity");
309
return (jint)ShenandoahHeapRegion::RegionSizeWordsShift;
310
}
311
312
inline static size_t humongous_threshold_bytes() {
313
return ShenandoahHeapRegion::HumongousThresholdBytes;
314
}
315
316
inline static size_t humongous_threshold_words() {
317
return ShenandoahHeapRegion::HumongousThresholdWords;
318
}
319
320
inline static size_t max_tlab_size_bytes() {
321
return ShenandoahHeapRegion::MaxTLABSizeBytes;
322
}
323
324
inline static size_t max_tlab_size_words() {
325
return ShenandoahHeapRegion::MaxTLABSizeWords;
326
}
327
328
inline size_t index() const {
329
return _index;
330
}
331
332
// Allocation (return NULL if full)
333
inline HeapWord* allocate(size_t word_size, ShenandoahAllocRequest::Type type);
334
335
inline void clear_live_data();
336
void set_live_data(size_t s);
337
338
// Increase live data for newly allocated region
339
inline void increase_live_data_alloc_words(size_t s);
340
341
// Increase live data for region scanned with GC
342
inline void increase_live_data_gc_words(size_t s);
343
344
inline bool has_live() const;
345
inline size_t get_live_data_bytes() const;
346
inline size_t get_live_data_words() const;
347
348
inline size_t garbage() const;
349
350
void print_on(outputStream* st) const;
351
352
void recycle();
353
354
HeapWord* block_start(const void* p) const;
355
size_t block_size(const HeapWord* p) const;
356
bool block_is_obj(const HeapWord* p) const { return p < top(); }
357
358
// Find humongous start region that this region belongs to
359
ShenandoahHeapRegion* humongous_start_region() const;
360
361
HeapWord* top() const { return _top; }
362
void set_top(HeapWord* v) { _top = v; }
363
364
HeapWord* new_top() const { return _new_top; }
365
void set_new_top(HeapWord* v) { _new_top = v; }
366
367
HeapWord* bottom() const { return _bottom; }
368
HeapWord* end() const { return _end; }
369
370
size_t capacity() const { return byte_size(bottom(), end()); }
371
size_t used() const { return byte_size(bottom(), top()); }
372
size_t free() const { return byte_size(top(), end()); }
373
374
inline void adjust_alloc_metadata(ShenandoahAllocRequest::Type type, size_t);
375
void reset_alloc_metadata();
376
size_t get_shared_allocs() const;
377
size_t get_tlab_allocs() const;
378
size_t get_gclab_allocs() const;
379
380
inline HeapWord* get_update_watermark() const;
381
inline void set_update_watermark(HeapWord* w);
382
inline void set_update_watermark_at_safepoint(HeapWord* w);
383
384
private:
385
void do_commit();
386
void do_uncommit();
387
388
inline void internal_increase_live_data(size_t s);
389
390
void set_state(RegionState to);
391
};
392
393
#endif // SHARE_VM_GC_SHENANDOAH_SHENANDOAHHEAPREGION_HPP
394
395