1 /*
2 * Copyright (c) 2013, 2019, Red Hat, Inc. 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 #ifndef SHARE_GC_SHENANDOAH_SHENANDOAHHEAPREGION_HPP
26 #define SHARE_GC_SHENANDOAH_SHENANDOAHHEAPREGION_HPP
27
28 #include "gc/shared/gc_globals.hpp"
29 #include "gc/shared/spaceDecorator.hpp"
30 #include "gc/shenandoah/shenandoahAllocRequest.hpp"
31 #include "gc/shenandoah/shenandoahAsserts.hpp"
32 #include "gc/shenandoah/shenandoahHeap.hpp"
33 #include "gc/shenandoah/shenandoahPacer.hpp"
34 #include "gc/shenandoah/shenandoahPadding.hpp"
35 #include "utilities/sizes.hpp"
36
37 class VMStructs;
38 class ShenandoahHeapRegionStateConstant;
39
40 class ShenandoahHeapRegion {
41 friend class VMStructs;
42 friend class ShenandoahHeapRegionStateConstant;
43 private:
44 /*
45 Region state is described by a state machine. Transitions are guarded by
46 heap lock, which allows changing the state of several regions atomically.
47 Region states can be logically aggregated in groups.
48
49 "Empty":
50 .................................................................
51 . .
52 . .
53 . Uncommitted <------- Committed <------------------------\
106 h) Humongous start can go pinned, and thus can be protected from moves (humongous continuations should
107 follow associated humongous starts, not pinnable/movable by themselves);
108 i) Empty cannot go Trash, avoiding useless work;
109 j) ...
110 */
111
112 enum RegionState {
113 _empty_uncommitted, // region is empty and has memory uncommitted
114 _empty_committed, // region is empty and has memory committed
115 _regular, // region is for regular allocations
116 _humongous_start, // region is the humongous start
117 _humongous_cont, // region is the humongous continuation
118 _pinned_humongous_start, // region is both humongous start and pinned
119 _cset, // region is in collection set
120 _pinned, // region is pinned
121 _pinned_cset, // region is pinned and in cset (evac failure path)
122 _trash, // region contains only trash
123 _REGION_STATES_NUM // last
124 };
125
126 static const char* region_state_to_string(RegionState s) {
127 switch (s) {
128 case _empty_uncommitted: return "Empty Uncommitted";
129 case _empty_committed: return "Empty Committed";
130 case _regular: return "Regular";
131 case _humongous_start: return "Humongous Start";
132 case _humongous_cont: return "Humongous Continuation";
133 case _pinned_humongous_start: return "Humongous Start, Pinned";
134 case _cset: return "Collection Set";
135 case _pinned: return "Pinned";
136 case _pinned_cset: return "Collection Set, Pinned";
137 case _trash: return "Trash";
138 default:
139 ShouldNotReachHere();
140 return "";
141 }
142 }
143
144 // This method protects from accidental changes in enum order:
145 int region_state_to_ordinal(RegionState s) const {
146 switch (s) {
147 case _empty_uncommitted: return 0;
148 case _empty_committed: return 1;
149 case _regular: return 2;
150 case _humongous_start: return 3;
151 case _humongous_cont: return 4;
152 case _cset: return 5;
153 case _pinned: return 6;
154 case _trash: return 7;
155 case _pinned_cset: return 8;
156 case _pinned_humongous_start: return 9;
157 default:
158 ShouldNotReachHere();
159 return -1;
160 }
161 }
162
163 void report_illegal_transition(const char* method);
164
165 public:
166 static const int region_states_num() {
167 return _REGION_STATES_NUM;
168 }
169
170 // Allowed transitions from the outside code:
171 void make_regular_allocation();
172 void make_regular_bypass();
173 void make_humongous_start();
174 void make_humongous_cont();
175 void make_humongous_start_bypass();
176 void make_humongous_cont_bypass();
177 void make_pinned();
178 void make_unpinned();
179 void make_cset();
180 void make_trash();
181 void make_trash_immediate();
182 void make_empty();
183 void make_uncommitted();
184 void make_committed_bypass();
185
186 // Individual states:
187 bool is_empty_uncommitted() const { return _state == _empty_uncommitted; }
188 bool is_empty_committed() const { return _state == _empty_committed; }
189 bool is_regular() const { return _state == _regular; }
190 bool is_humongous_continuation() const { return _state == _humongous_cont; }
191
192 // Participation in logical groups:
193 bool is_empty() const { return is_empty_committed() || is_empty_uncommitted(); }
194 bool is_active() const { return !is_empty() && !is_trash(); }
195 bool is_trash() const { return _state == _trash; }
196 bool is_humongous_start() const { return _state == _humongous_start || _state == _pinned_humongous_start; }
197 bool is_humongous() const { return is_humongous_start() || is_humongous_continuation(); }
198 bool is_committed() const { return !is_empty_uncommitted(); }
199 bool is_cset() const { return _state == _cset || _state == _pinned_cset; }
200 bool is_pinned() const { return _state == _pinned || _state == _pinned_cset || _state == _pinned_humongous_start; }
201
202 // Macro-properties:
203 bool is_alloc_allowed() const { return is_empty() || is_regular() || _state == _pinned; }
204 bool is_stw_move_allowed() const { return is_regular() || _state == _cset || (ShenandoahHumongousMoves && _state == _humongous_start); }
205
206 RegionState state() const { return _state; }
207 int state_ordinal() const { return region_state_to_ordinal(_state); }
208
209 void record_pin();
210 void record_unpin();
211 size_t pin_count() const;
212
213 private:
214 static size_t RegionCount;
215 static size_t RegionSizeBytes;
216 static size_t RegionSizeWords;
217 static size_t RegionSizeBytesShift;
218 static size_t RegionSizeWordsShift;
219 static size_t RegionSizeBytesMask;
220 static size_t RegionSizeWordsMask;
221 static size_t HumongousThresholdBytes;
222 static size_t HumongousThresholdWords;
223 static size_t MaxTLABSizeBytes;
224 static size_t MaxTLABSizeWords;
225
226 // Never updated fields
227 size_t const _index;
228 HeapWord* const _bottom;
229 HeapWord* const _end;
230
231 // Rarely updated fields
232 HeapWord* _new_top;
233 double _empty_time;
234
235 // Seldom updated fields
236 RegionState _state;
237
238 // Frequently updated fields
239 HeapWord* _top;
240
241 size_t _tlab_allocs;
242 size_t _gclab_allocs;
243
244 volatile size_t _live_data;
245 volatile size_t _critical_pins;
246
247 HeapWord* volatile _update_watermark;
248
249 public:
250 ShenandoahHeapRegion(HeapWord* start, size_t index, bool committed);
251
252 static const size_t MIN_NUM_REGIONS = 10;
253
254 // Return adjusted max heap size
255 static size_t setup_sizes(size_t max_heap_size);
256
257 double empty_time() {
258 return _empty_time;
259 }
260
261 inline static size_t required_regions(size_t bytes) {
262 return (bytes + ShenandoahHeapRegion::region_size_bytes() - 1) >> ShenandoahHeapRegion::region_size_bytes_shift();
263 }
264
265 inline static size_t region_count() {
266 return ShenandoahHeapRegion::RegionCount;
267 }
268
269 inline static size_t region_size_bytes() {
270 return ShenandoahHeapRegion::RegionSizeBytes;
271 }
272
273 inline static size_t region_size_words() {
274 return ShenandoahHeapRegion::RegionSizeWords;
275 }
276
277 inline static size_t region_size_bytes_shift() {
278 return ShenandoahHeapRegion::RegionSizeBytesShift;
279 }
280
281 inline static size_t region_size_words_shift() {
282 return ShenandoahHeapRegion::RegionSizeWordsShift;
283 }
284
297 }
298
299 // Convert to jint with sanity checking
300 inline static jint region_size_words_jint() {
301 assert (ShenandoahHeapRegion::RegionSizeWords <= (size_t)max_jint, "sanity");
302 return (jint)ShenandoahHeapRegion::RegionSizeWords;
303 }
304
305 // Convert to jint with sanity checking
306 inline static jint region_size_bytes_shift_jint() {
307 assert (ShenandoahHeapRegion::RegionSizeBytesShift <= (size_t)max_jint, "sanity");
308 return (jint)ShenandoahHeapRegion::RegionSizeBytesShift;
309 }
310
311 // Convert to jint with sanity checking
312 inline static jint region_size_words_shift_jint() {
313 assert (ShenandoahHeapRegion::RegionSizeWordsShift <= (size_t)max_jint, "sanity");
314 return (jint)ShenandoahHeapRegion::RegionSizeWordsShift;
315 }
316
317 inline static size_t humongous_threshold_bytes() {
318 return ShenandoahHeapRegion::HumongousThresholdBytes;
319 }
320
321 inline static size_t humongous_threshold_words() {
322 return ShenandoahHeapRegion::HumongousThresholdWords;
323 }
324
325 inline static size_t max_tlab_size_bytes() {
326 return ShenandoahHeapRegion::MaxTLABSizeBytes;
327 }
328
329 inline static size_t max_tlab_size_words() {
330 return ShenandoahHeapRegion::MaxTLABSizeWords;
331 }
332
333 inline size_t index() const {
334 return _index;
335 }
336
337 // Allocation (return null if full)
338 inline HeapWord* allocate(size_t word_size, ShenandoahAllocRequest::Type type);
339
340 inline void clear_live_data();
341 void set_live_data(size_t s);
342
343 // Increase live data for newly allocated region
344 inline void increase_live_data_alloc_words(size_t s);
345
346 // Increase live data for region scanned with GC
347 inline void increase_live_data_gc_words(size_t s);
348
349 inline bool has_live() const;
350 inline size_t get_live_data_bytes() const;
351 inline size_t get_live_data_words() const;
352
353 inline size_t garbage() const;
354
355 void print_on(outputStream* st) const;
356
357 void recycle();
358
359 void oop_iterate(OopIterateClosure* cl);
360
361 HeapWord* block_start(const void* p) const;
362 size_t block_size(const HeapWord* p) const;
363 bool block_is_obj(const HeapWord* p) const { return p < top(); }
364
365 // Find humongous start region that this region belongs to
366 ShenandoahHeapRegion* humongous_start_region() const;
367
368 HeapWord* top() const { return _top; }
369 void set_top(HeapWord* v) { _top = v; }
370
371 HeapWord* new_top() const { return _new_top; }
372 void set_new_top(HeapWord* v) { _new_top = v; }
373
374 HeapWord* bottom() const { return _bottom; }
375 HeapWord* end() const { return _end; }
376
377 size_t capacity() const { return byte_size(bottom(), end()); }
378 size_t used() const { return byte_size(bottom(), top()); }
379 size_t free() const { return byte_size(top(), end()); }
380
381 inline void adjust_alloc_metadata(ShenandoahAllocRequest::Type type, size_t);
382 void reset_alloc_metadata();
383 size_t get_shared_allocs() const;
384 size_t get_tlab_allocs() const;
385 size_t get_gclab_allocs() const;
386
387 inline HeapWord* get_update_watermark() const;
388 inline void set_update_watermark(HeapWord* w);
389 inline void set_update_watermark_at_safepoint(HeapWord* w);
390
391 private:
392 void do_commit();
393 void do_uncommit();
394
395 void oop_iterate_objects(OopIterateClosure* cl);
396 void oop_iterate_humongous(OopIterateClosure* cl);
397
398 inline void internal_increase_live_data(size_t s);
399
400 void set_state(RegionState to);
401 };
402
403 #endif // SHARE_GC_SHENANDOAH_SHENANDOAHHEAPREGION_HPP
|
1 /*
2 * Copyright (c) 2013, 2019, Red Hat, Inc. All rights reserved.
3 * Copyright Amazon.com Inc. or its affiliates. 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_GC_SHENANDOAH_SHENANDOAHHEAPREGION_HPP
27 #define SHARE_GC_SHENANDOAH_SHENANDOAHHEAPREGION_HPP
28
29 #include "gc/shared/gc_globals.hpp"
30 #include "gc/shared/spaceDecorator.hpp"
31 #include "gc/shenandoah/shenandoahAffiliation.hpp"
32 #include "gc/shenandoah/shenandoahAgeCensus.hpp"
33 #include "gc/shenandoah/shenandoahAllocRequest.hpp"
34 #include "gc/shenandoah/shenandoahAsserts.hpp"
35 #include "gc/shenandoah/shenandoahHeap.hpp"
36 #include "gc/shenandoah/shenandoahPadding.hpp"
37 #include "utilities/sizes.hpp"
38
39 class VMStructs;
40 class ShenandoahHeapRegionStateConstant;
41
42 class ShenandoahHeapRegion {
43 friend class VMStructs;
44 friend class ShenandoahHeapRegionStateConstant;
45 private:
46 /*
47 Region state is described by a state machine. Transitions are guarded by
48 heap lock, which allows changing the state of several regions atomically.
49 Region states can be logically aggregated in groups.
50
51 "Empty":
52 .................................................................
53 . .
54 . .
55 . Uncommitted <------- Committed <------------------------\
108 h) Humongous start can go pinned, and thus can be protected from moves (humongous continuations should
109 follow associated humongous starts, not pinnable/movable by themselves);
110 i) Empty cannot go Trash, avoiding useless work;
111 j) ...
112 */
113
114 enum RegionState {
115 _empty_uncommitted, // region is empty and has memory uncommitted
116 _empty_committed, // region is empty and has memory committed
117 _regular, // region is for regular allocations
118 _humongous_start, // region is the humongous start
119 _humongous_cont, // region is the humongous continuation
120 _pinned_humongous_start, // region is both humongous start and pinned
121 _cset, // region is in collection set
122 _pinned, // region is pinned
123 _pinned_cset, // region is pinned and in cset (evac failure path)
124 _trash, // region contains only trash
125 _REGION_STATES_NUM // last
126 };
127
128 public:
129 static const char* region_state_to_string(RegionState s) {
130 switch (s) {
131 case _empty_uncommitted: return "Empty Uncommitted";
132 case _empty_committed: return "Empty Committed";
133 case _regular: return "Regular";
134 case _humongous_start: return "Humongous Start";
135 case _humongous_cont: return "Humongous Continuation";
136 case _pinned_humongous_start: return "Humongous Start, Pinned";
137 case _cset: return "Collection Set";
138 case _pinned: return "Pinned";
139 case _pinned_cset: return "Collection Set, Pinned";
140 case _trash: return "Trash";
141 default:
142 ShouldNotReachHere();
143 return "";
144 }
145 }
146
147 private:
148 // This method protects from accidental changes in enum order:
149 int region_state_to_ordinal(RegionState s) const {
150 switch (s) {
151 case _empty_uncommitted: return 0;
152 case _empty_committed: return 1;
153 case _regular: return 2;
154 case _humongous_start: return 3;
155 case _humongous_cont: return 4;
156 case _cset: return 5;
157 case _pinned: return 6;
158 case _trash: return 7;
159 case _pinned_cset: return 8;
160 case _pinned_humongous_start: return 9;
161 default:
162 ShouldNotReachHere();
163 return -1;
164 }
165 }
166
167 void report_illegal_transition(const char* method);
168 void recycle_internal();
169
170 public:
171 static int region_states_num() {
172 return _REGION_STATES_NUM;
173 }
174
175 // Allowed transitions from the outside code:
176 void make_regular_allocation(ShenandoahAffiliation affiliation);
177 void make_affiliated_maybe();
178 void make_regular_bypass();
179 void make_humongous_start();
180 void make_humongous_cont();
181 void make_humongous_start_bypass(ShenandoahAffiliation affiliation);
182 void make_humongous_cont_bypass(ShenandoahAffiliation affiliation);
183 void make_pinned();
184 void make_unpinned();
185 void make_cset();
186 void make_trash();
187 void make_trash_immediate();
188 void make_empty();
189 void make_uncommitted();
190 void make_committed_bypass();
191
192 // Primitive state predicates
193 bool is_empty_uncommitted() const { return state() == _empty_uncommitted; }
194 bool is_empty_committed() const { return state() == _empty_committed; }
195 bool is_regular() const { return state() == _regular; }
196 bool is_humongous_continuation() const { return state() == _humongous_cont; }
197 bool is_regular_pinned() const { return state() == _pinned; }
198 bool is_trash() const { return state() == _trash; }
199
200 // Derived state predicates (boolean combinations of individual states)
201 bool static is_empty_state(RegionState state) { return state == _empty_committed || state == _empty_uncommitted; }
202 bool static is_humongous_start_state(RegionState state) { return state == _humongous_start || state == _pinned_humongous_start; }
203 bool is_empty() const { return is_empty_state(this->state()); }
204 bool is_active() const { auto cur_state = state(); return !is_empty_state(cur_state) && cur_state != _trash; }
205 bool is_humongous_start() const { return is_humongous_start_state(state()); }
206 bool is_humongous() const { auto cur_state = state(); return is_humongous_start_state(cur_state) || cur_state == _humongous_cont; }
207 bool is_committed() const { return !is_empty_uncommitted(); }
208 bool is_cset() const { auto cur_state = state(); return cur_state == _cset || cur_state == _pinned_cset; }
209 bool is_pinned() const { auto cur_state = state(); return cur_state == _pinned || cur_state == _pinned_cset || cur_state == _pinned_humongous_start; }
210
211 inline bool is_young() const;
212 inline bool is_old() const;
213 inline bool is_affiliated() const;
214
215 // Macro-properties:
216 bool is_alloc_allowed() const { auto cur_state = state(); return is_empty_state(cur_state) || cur_state == _regular || cur_state == _pinned; }
217 bool is_stw_move_allowed() const { auto cur_state = state(); return cur_state == _regular || cur_state == _cset || (ShenandoahHumongousMoves && cur_state == _humongous_start); }
218
219 RegionState state() const { return Atomic::load(&_state); }
220 int state_ordinal() const { return region_state_to_ordinal(state()); }
221
222 void record_pin();
223 void record_unpin();
224 size_t pin_count() const;
225
226 private:
227 static size_t RegionCount;
228 static size_t RegionSizeBytes;
229 static size_t RegionSizeWords;
230 static size_t RegionSizeBytesShift;
231 static size_t RegionSizeWordsShift;
232 static size_t RegionSizeBytesMask;
233 static size_t RegionSizeWordsMask;
234 static size_t MaxTLABSizeBytes;
235 static size_t MaxTLABSizeWords;
236
237 // Never updated fields
238 size_t const _index;
239 HeapWord* const _bottom;
240 HeapWord* const _end;
241
242 // Rarely updated fields
243 HeapWord* _new_top;
244 double _empty_time;
245
246 HeapWord* _top_before_promoted;
247
248 // Seldom updated fields
249 volatile RegionState _state;
250 HeapWord* _coalesce_and_fill_boundary; // for old regions not selected as collection set candidates.
251
252 // Frequently updated fields
253 HeapWord* _top;
254
255 size_t _tlab_allocs;
256 size_t _gclab_allocs;
257 size_t _plab_allocs;
258
259 volatile size_t _live_data;
260 volatile size_t _critical_pins;
261
262 HeapWord* volatile _update_watermark;
263
264 uint _age;
265 CENSUS_NOISE(uint _youth;) // tracks epochs of retrograde ageing (rejuvenation)
266
267 ShenandoahSharedFlag _recycling; // Used to indicate that the region is being recycled; see try_recycle*().
268
269 bool _needs_bitmap_reset;
270
271 public:
272 ShenandoahHeapRegion(HeapWord* start, size_t index, bool committed);
273
274 static const size_t MIN_NUM_REGIONS = 10;
275
276 // Return adjusted max heap size
277 static size_t setup_sizes(size_t max_heap_size);
278
279 double empty_time() {
280 return _empty_time;
281 }
282
283 inline static size_t required_regions(size_t bytes) {
284 return (bytes + ShenandoahHeapRegion::region_size_bytes() - 1) >> ShenandoahHeapRegion::region_size_bytes_shift();
285 }
286
287 inline static bool requires_humongous(size_t words) {
288 return words > ShenandoahHeapRegion::RegionSizeWords;
289 }
290
291 inline static size_t region_count() {
292 return ShenandoahHeapRegion::RegionCount;
293 }
294
295 inline static size_t region_size_bytes() {
296 return ShenandoahHeapRegion::RegionSizeBytes;
297 }
298
299 inline static size_t region_size_words() {
300 return ShenandoahHeapRegion::RegionSizeWords;
301 }
302
303 inline static size_t region_size_bytes_shift() {
304 return ShenandoahHeapRegion::RegionSizeBytesShift;
305 }
306
307 inline static size_t region_size_words_shift() {
308 return ShenandoahHeapRegion::RegionSizeWordsShift;
309 }
310
323 }
324
325 // Convert to jint with sanity checking
326 inline static jint region_size_words_jint() {
327 assert (ShenandoahHeapRegion::RegionSizeWords <= (size_t)max_jint, "sanity");
328 return (jint)ShenandoahHeapRegion::RegionSizeWords;
329 }
330
331 // Convert to jint with sanity checking
332 inline static jint region_size_bytes_shift_jint() {
333 assert (ShenandoahHeapRegion::RegionSizeBytesShift <= (size_t)max_jint, "sanity");
334 return (jint)ShenandoahHeapRegion::RegionSizeBytesShift;
335 }
336
337 // Convert to jint with sanity checking
338 inline static jint region_size_words_shift_jint() {
339 assert (ShenandoahHeapRegion::RegionSizeWordsShift <= (size_t)max_jint, "sanity");
340 return (jint)ShenandoahHeapRegion::RegionSizeWordsShift;
341 }
342
343 inline static size_t max_tlab_size_bytes() {
344 return ShenandoahHeapRegion::MaxTLABSizeBytes;
345 }
346
347 inline static size_t max_tlab_size_words() {
348 return ShenandoahHeapRegion::MaxTLABSizeWords;
349 }
350
351 inline size_t index() const {
352 return _index;
353 }
354
355 inline void save_top_before_promote();
356 inline HeapWord* get_top_before_promote() const { return _top_before_promoted; }
357 inline void restore_top_before_promote();
358 inline size_t garbage_before_padded_for_promote() const;
359
360 // If next available memory is not aligned on address that is multiple of alignment, fill the empty space
361 // so that returned object is aligned on an address that is a multiple of alignment_in_bytes. Requested
362 // size is in words. It is assumed that this->is_old(). A pad object is allocated, filled, and registered
363 // if necessary to assure the new allocation is properly aligned. Return nullptr if memory is not available.
364 inline HeapWord* allocate_aligned(size_t word_size, ShenandoahAllocRequest &req, size_t alignment_in_bytes);
365
366 // Allocation (return nullptr if full)
367 inline HeapWord* allocate(size_t word_size, const ShenandoahAllocRequest& req);
368
369 inline void clear_live_data();
370 void set_live_data(size_t s);
371
372 // Increase live data for newly allocated region
373 inline void increase_live_data_alloc_words(size_t s);
374
375 // Increase live data for region scanned with GC
376 inline void increase_live_data_gc_words(size_t s);
377
378 inline bool has_live() const;
379 inline size_t get_live_data_bytes() const;
380 inline size_t get_live_data_words() const;
381
382 inline size_t garbage() const;
383
384 void print_on(outputStream* st) const;
385
386 void try_recycle_under_lock();
387
388 void try_recycle();
389
390 inline void begin_preemptible_coalesce_and_fill() {
391 _coalesce_and_fill_boundary = _bottom;
392 }
393
394 inline void end_preemptible_coalesce_and_fill() {
395 _coalesce_and_fill_boundary = _end;
396 }
397
398 inline void suspend_coalesce_and_fill(HeapWord* next_focus) {
399 _coalesce_and_fill_boundary = next_focus;
400 }
401
402 inline HeapWord* resume_coalesce_and_fill() {
403 return _coalesce_and_fill_boundary;
404 }
405
406 // Coalesce contiguous spans of garbage objects by filling header and registering start locations with remembered set.
407 // This is used by old-gen GC following concurrent marking to make old-gen HeapRegions parsable. Old regions must be
408 // parsable because the mark bitmap is not reliable during the concurrent old mark.
409 // Return true iff region is completely coalesced and filled. Returns false if cancelled before task is complete.
410 bool oop_coalesce_and_fill(bool cancellable);
411
412 // Invoke closure on every reference contained within the humongous object that spans this humongous
413 // region if the reference is contained within a DIRTY card and the reference is no more than words following
414 // start within the humongous object.
415 void oop_iterate_humongous_slice_dirty(OopIterateClosure* cl, HeapWord* start, size_t words, bool write_table) const;
416
417 // Invoke closure on every reference contained within the humongous object starting from start and
418 // ending at start + words.
419 void oop_iterate_humongous_slice_all(OopIterateClosure* cl, HeapWord* start, size_t words) const;
420
421 HeapWord* block_start(const void* p) const;
422 size_t block_size(const HeapWord* p) const;
423 bool block_is_obj(const HeapWord* p) const { return p < top(); }
424
425 // Find humongous start region that this region belongs to
426 ShenandoahHeapRegion* humongous_start_region() const;
427
428 HeapWord* top() const { return _top; }
429 void set_top(HeapWord* v) { _top = v; }
430
431 HeapWord* new_top() const { return _new_top; }
432 void set_new_top(HeapWord* v) { _new_top = v; }
433
434 HeapWord* bottom() const { return _bottom; }
435 HeapWord* end() const { return _end; }
436
437 size_t capacity() const { return byte_size(bottom(), end()); }
438 size_t used() const { return byte_size(bottom(), top()); }
439 size_t used_before_promote() const { return byte_size(bottom(), get_top_before_promote()); }
440 size_t free() const { return byte_size(top(), end()); }
441
442 // Does this region contain this address?
443 bool contains(HeapWord* p) const {
444 return (bottom() <= p) && (p < top());
445 }
446
447 inline void adjust_alloc_metadata(ShenandoahAllocRequest::Type type, size_t);
448 void reset_alloc_metadata();
449 size_t get_shared_allocs() const;
450 size_t get_tlab_allocs() const;
451 size_t get_gclab_allocs() const;
452 size_t get_plab_allocs() const;
453
454 inline HeapWord* get_update_watermark() const;
455 inline void set_update_watermark(HeapWord* w);
456 inline void set_update_watermark_at_safepoint(HeapWord* w);
457
458 inline ShenandoahAffiliation affiliation() const;
459 inline const char* affiliation_name() const;
460
461 void set_affiliation(ShenandoahAffiliation new_affiliation);
462
463 // Region ageing and rejuvenation
464 uint age() const { return _age; }
465 CENSUS_NOISE(uint youth() const { return _youth; })
466
467 void increment_age() {
468 const uint max_age = markWord::max_age;
469 assert(_age <= max_age, "Error");
470 if (_age++ >= max_age) {
471 _age = max_age; // clamp
472 }
473 }
474
475 void reset_age() {
476 CENSUS_NOISE(_youth += _age;)
477 _age = 0;
478 }
479
480 CENSUS_NOISE(void clear_youth() { _youth = 0; })
481
482 inline bool need_bitmap_reset() const {
483 return _needs_bitmap_reset;
484 }
485
486 inline void set_needs_bitmap_reset() {
487 _needs_bitmap_reset = true;
488 }
489
490 inline void unset_needs_bitmap_reset() {
491 _needs_bitmap_reset = false;
492 }
493
494 private:
495 void decrement_humongous_waste() const;
496 void do_commit();
497 void do_uncommit();
498
499 inline void internal_increase_live_data(size_t s);
500
501 void set_state(RegionState to);
502 };
503
504 #endif // SHARE_GC_SHENANDOAH_SHENANDOAHHEAPREGION_HPP
|