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 *
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
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, 2020, 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 *
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(ShenandoahRegionAffiliation affiliation);
172 void make_young_maybe();
173 void make_regular_bypass();
174 void make_humongous_start();
175 void make_humongous_cont();
176 void make_humongous_start_bypass(ShenandoahRegionAffiliation affiliation);
177 void make_humongous_cont_bypass(ShenandoahRegionAffiliation affiliation);
178 void make_pinned();
179 void make_unpinned();
180 void make_cset();
181 void make_trash();
182 void make_trash_immediate();
183 void make_empty();
184 void make_uncommitted();
185 void make_committed_bypass();
186
187 // Individual states:
188 bool is_empty_uncommitted() const { return _state == _empty_uncommitted; }
189 bool is_empty_committed() const { return _state == _empty_committed; }
190 bool is_regular() const { return _state == _regular; }
191 bool is_humongous_continuation() const { return _state == _humongous_cont; }
192
193 // Participation in logical groups:
194 bool is_empty() const { return is_empty_committed() || is_empty_uncommitted(); }
195 bool is_active() const { return !is_empty() && !is_trash(); }
196 bool is_trash() const { return _state == _trash; }
197 bool is_humongous_start() const { return _state == _humongous_start || _state == _pinned_humongous_start; }
198 bool is_humongous() const { return is_humongous_start() || is_humongous_continuation(); }
199 bool is_committed() const { return !is_empty_uncommitted(); }
200 bool is_cset() const { return _state == _cset || _state == _pinned_cset; }
201 bool is_pinned() const { return _state == _pinned || _state == _pinned_cset || _state == _pinned_humongous_start; }
202 inline bool is_young() const;
203 inline bool is_old() const;
204
205 // Macro-properties:
206 bool is_alloc_allowed() const { return is_empty() || is_regular() || _state == _pinned; }
207 bool is_stw_move_allowed() const { return is_regular() || _state == _cset || (ShenandoahHumongousMoves && _state == _humongous_start); }
208
209 RegionState state() const { return _state; }
210 int state_ordinal() const { return region_state_to_ordinal(_state); }
211
212 void record_pin();
213 void record_unpin();
214 size_t pin_count() const;
215
216 void clear_young_lab_flags();
217 void set_young_lab_flag();
218 bool has_young_lab_flag();
219
220 private:
221 static size_t RegionCount;
222 static size_t RegionSizeBytes;
223 static size_t RegionSizeWords;
224 static size_t RegionSizeBytesShift;
225 static size_t RegionSizeWordsShift;
226 static size_t RegionSizeBytesMask;
227 static size_t RegionSizeWordsMask;
228 static size_t HumongousThresholdBytes;
229 static size_t HumongousThresholdWords;
230 static size_t MaxTLABSizeBytes;
231 static size_t MaxTLABSizeWords;
232
233 // Never updated fields
234 size_t const _index;
235 HeapWord* const _bottom;
236 HeapWord* const _end;
237
238 // Rarely updated fields
239 HeapWord* _new_top;
240 double _empty_time;
241
242 // Seldom updated fields
243 RegionState _state;
244 HeapWord* _coalesce_and_fill_boundary; // for old regions not selected as collection set candidates.
245
246 // Frequently updated fields
247 HeapWord* _top;
248
249 size_t _tlab_allocs;
250 size_t _gclab_allocs;
251 size_t _plab_allocs;
252
253 bool _has_young_lab;
254
255 volatile size_t _live_data;
256 volatile size_t _critical_pins;
257
258 HeapWord* volatile _update_watermark;
259
260 uint _age;
261
262 public:
263 ShenandoahHeapRegion(HeapWord* start, size_t index, bool committed);
264
265 static const size_t MIN_NUM_REGIONS = 10;
266
267 // Return adjusted max heap size
268 static size_t setup_sizes(size_t max_heap_size);
269
270 double empty_time() {
271 return _empty_time;
272 }
273
274 inline static size_t required_regions(size_t bytes) {
275 return (bytes + ShenandoahHeapRegion::region_size_bytes() - 1) >> ShenandoahHeapRegion::region_size_bytes_shift();
276 }
277
278 inline static size_t region_count() {
279 return ShenandoahHeapRegion::RegionCount;
280 }
281
330 inline static size_t humongous_threshold_bytes() {
331 return ShenandoahHeapRegion::HumongousThresholdBytes;
332 }
333
334 inline static size_t humongous_threshold_words() {
335 return ShenandoahHeapRegion::HumongousThresholdWords;
336 }
337
338 inline static size_t max_tlab_size_bytes() {
339 return ShenandoahHeapRegion::MaxTLABSizeBytes;
340 }
341
342 inline static size_t max_tlab_size_words() {
343 return ShenandoahHeapRegion::MaxTLABSizeWords;
344 }
345
346 inline size_t index() const {
347 return _index;
348 }
349
350 // Allocation (return nullptr if full)
351 inline HeapWord* allocate_aligned(size_t word_size, ShenandoahAllocRequest &req, size_t alignment_in_words);
352
353 // Allocation (return nullptr if full)
354 inline HeapWord* allocate(size_t word_size, ShenandoahAllocRequest req);
355
356 inline void clear_live_data();
357 void set_live_data(size_t s);
358
359 // Increase live data for newly allocated region
360 inline void increase_live_data_alloc_words(size_t s);
361
362 // Increase live data for region scanned with GC
363 inline void increase_live_data_gc_words(size_t s);
364
365 inline bool has_live() const;
366 inline size_t get_live_data_bytes() const;
367 inline size_t get_live_data_words() const;
368
369 inline size_t garbage() const;
370
371 void print_on(outputStream* st) const;
372
373 void recycle();
374
375 inline void begin_preemptible_coalesce_and_fill() {
376 _coalesce_and_fill_boundary = _bottom;
377 }
378
379 inline void end_preemptible_coalesce_and_fill() {
380 _coalesce_and_fill_boundary = _end;
381 }
382
383 inline void suspend_coalesce_and_fill(HeapWord* next_focus) {
384 _coalesce_and_fill_boundary = next_focus;
385 }
386
387 inline HeapWord* resume_coalesce_and_fill() {
388 return _coalesce_and_fill_boundary;
389 }
390
391 // Coalesce contiguous spans of garbage objects by filling header and reregistering start locations with remembered set.
392 // This is used by old-gen GC following concurrent marking to make old-gen HeapRegions parseable. Return true iff
393 // region is completely coalesced and filled. Returns false if cancelled before task is complete.
394 bool oop_fill_and_coalesce();
395
396 // Like oop_fill_and_coalesce(), but without honoring cancellation requests.
397 bool oop_fill_and_coalesce_wo_cancel();
398
399 // During global collections, this service iterates through an old-gen heap region that is not part of collection
400 // set to fill and register ranges of dead memory. Note that live objects were previously registered. Some dead objects
401 // that are subsumed into coalesced ranges of dead memory need to be "unregistered".
402 void global_oop_iterate_and_fill_dead(OopIterateClosure* cl);
403 void oop_iterate_humongous(OopIterateClosure* cl);
404 void oop_iterate_humongous(OopIterateClosure* cl, HeapWord* start, size_t words);
405
406 // Invoke closure on every reference contained within the humongous object that spans this humongous
407 // region if the reference is contained within a DIRTY card and the reference is no more than words following
408 // start within the humongous object.
409 void oop_iterate_humongous_slice(OopIterateClosure* cl, bool dirty_only, HeapWord* start, size_t words, bool write_table);
410
411 HeapWord* block_start(const void* p) const;
412 size_t block_size(const HeapWord* p) const;
413 bool block_is_obj(const HeapWord* p) const { return p < top(); }
414
415 // Find humongous start region that this region belongs to
416 ShenandoahHeapRegion* humongous_start_region() const;
417
418 HeapWord* top() const { return _top; }
419 void set_top(HeapWord* v) { _top = v; }
420
421 HeapWord* new_top() const { return _new_top; }
422 void set_new_top(HeapWord* v) { _new_top = v; }
423
424 HeapWord* bottom() const { return _bottom; }
425 HeapWord* end() const { return _end; }
426
427 size_t capacity() const { return byte_size(bottom(), end()); }
428 size_t used() const { return byte_size(bottom(), top()); }
429 size_t free() const { return byte_size(top(), end()); }
430
431 // Does this region contain this address?
432 bool contains(HeapWord* p) const {
433 return (bottom() <= p) && (p < top());
434 }
435
436 inline void adjust_alloc_metadata(ShenandoahAllocRequest::Type type, size_t);
437 void reset_alloc_metadata();
438 size_t get_shared_allocs() const;
439 size_t get_tlab_allocs() const;
440 size_t get_gclab_allocs() const;
441 size_t get_plab_allocs() const;
442
443 inline HeapWord* get_update_watermark() const;
444 inline void set_update_watermark(HeapWord* w);
445 inline void set_update_watermark_at_safepoint(HeapWord* w);
446
447 inline ShenandoahRegionAffiliation affiliation() const;
448
449 void set_affiliation(ShenandoahRegionAffiliation new_affiliation);
450
451 uint age() { return _age; }
452 void increment_age() { _age++; }
453 void decrement_age() { if (_age-- == 0) { _age = 0; } }
454 void reset_age() { _age = 0; }
455
456 // Sets all remembered set cards to dirty. Returns the number of regions spanned by the associated humongous object.
457 size_t promote_humongous();
458
459 private:
460 void do_commit();
461 void do_uncommit();
462
463 // This is an old-region that was not part of the collection set during a GLOBAL collection. We coalesce the dead
464 // objects, but do not need to register the live objects as they are already registered.
465 void global_oop_iterate_objects_and_fill_dead(OopIterateClosure* cl);
466
467 inline void internal_increase_live_data(size_t s);
468
469 void set_state(RegionState to);
470 };
471
472 #endif // SHARE_GC_SHENANDOAH_SHENANDOAHHEAPREGION_HPP
|