Skip to content

Commit 33f2382

Browse files
author
William Kemper
committed
8325807: Shenandoah: Refactor full gc in preparation for generational mode changes
Reviewed-by: shade, ysr, kdnilsen
1 parent 419191c commit 33f2382

File tree

2 files changed

+62
-43
lines changed

2 files changed

+62
-43
lines changed

src/hotspot/share/gc/shenandoah/shenandoahFullGC.cpp

Lines changed: 61 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -235,12 +235,8 @@ void ShenandoahFullGC::do_it(GCCause::Cause gc_cause) {
235235
phase3_update_references();
236236

237237
phase4_compact_objects(worker_slices);
238-
}
239238

240-
{
241-
// Epilogue
242-
_preserved_marks->restore(heap->workers());
243-
_preserved_marks->reclaim();
239+
phase5_epilog();
244240
}
245241

246242
// Resize metaspace
@@ -280,6 +276,8 @@ class ShenandoahPrepareForMarkClosure: public ShenandoahHeapRegionClosure {
280276
_ctx->capture_top_at_mark_start(r);
281277
r->clear_live_data();
282278
}
279+
280+
bool is_thread_safe() { return true; }
283281
};
284282

285283
void ShenandoahFullGC::phase1_mark_heap() {
@@ -289,7 +287,7 @@ void ShenandoahFullGC::phase1_mark_heap() {
289287
ShenandoahHeap* heap = ShenandoahHeap::heap();
290288

291289
ShenandoahPrepareForMarkClosure cl;
292-
heap->heap_region_iterate(&cl);
290+
heap->parallel_heap_region_iterate(&cl);
293291

294292
heap->set_unload_classes(heap->heuristics()->can_unload_classes());
295293

@@ -328,7 +326,7 @@ class ShenandoahPrepareForCompactionObjectClosure : public ObjectClosure {
328326
_from_region = from_region;
329327
}
330328

331-
void finish_region() {
329+
void finish() {
332330
assert(_to_region != nullptr, "should not happen");
333331
_to_region->set_new_top(_compact_point);
334332
}
@@ -348,7 +346,7 @@ class ShenandoahPrepareForCompactionObjectClosure : public ObjectClosure {
348346

349347
size_t obj_size = p->size();
350348
if (_compact_point + obj_size > _to_region->end()) {
351-
finish_region();
349+
finish();
352350

353351
// Object doesn't fit. Pick next empty region and start compacting there.
354352
ShenandoahHeapRegion* new_to_region;
@@ -400,47 +398,61 @@ class ShenandoahPrepareForCompactionTask : public WorkerTask {
400398
return r->is_stw_move_allowed() && !r->is_humongous();
401399
}
402400

403-
void work(uint worker_id) {
404-
ShenandoahParallelWorkerSession worker_session(worker_id);
405-
ShenandoahHeapRegionSet* slice = _worker_slices[worker_id];
406-
ShenandoahHeapRegionSetIterator it(slice);
407-
ShenandoahHeapRegion* from_region = it.next();
408-
// No work?
409-
if (from_region == nullptr) {
410-
return;
411-
}
412-
413-
// Sliding compaction. Walk all regions in the slice, and compact them.
414-
// Remember empty regions and reuse them as needed.
415-
ResourceMark rm;
401+
void work(uint worker_id) override;
402+
private:
403+
template<typename ClosureType>
404+
void prepare_for_compaction(ClosureType& cl,
405+
GrowableArray<ShenandoahHeapRegion*>& empty_regions,
406+
ShenandoahHeapRegionSetIterator& it,
407+
ShenandoahHeapRegion* from_region);
408+
};
416409

417-
GrowableArray<ShenandoahHeapRegion*> empty_regions((int)_heap->num_regions());
410+
void ShenandoahPrepareForCompactionTask::work(uint worker_id) {
411+
ShenandoahParallelWorkerSession worker_session(worker_id);
412+
ShenandoahHeapRegionSet* slice = _worker_slices[worker_id];
413+
ShenandoahHeapRegionSetIterator it(slice);
414+
ShenandoahHeapRegion* from_region = it.next();
415+
// No work?
416+
if (from_region == nullptr) {
417+
return;
418+
}
418419

419-
ShenandoahPrepareForCompactionObjectClosure cl(_preserved_marks->get(worker_id), empty_regions, from_region);
420+
// Sliding compaction. Walk all regions in the slice, and compact them.
421+
// Remember empty regions and reuse them as needed.
422+
ResourceMark rm;
420423

421-
while (from_region != nullptr) {
422-
assert(is_candidate_region(from_region), "Sanity");
424+
GrowableArray<ShenandoahHeapRegion*> empty_regions((int)_heap->num_regions());
423425

424-
cl.set_from_region(from_region);
425-
if (from_region->has_live()) {
426-
_heap->marked_object_iterate(from_region, &cl);
427-
}
426+
ShenandoahPrepareForCompactionObjectClosure cl(_preserved_marks->get(worker_id), empty_regions, from_region);
427+
prepare_for_compaction(cl, empty_regions, it, from_region);
428+
}
428429

429-
// Compacted the region to somewhere else? From-region is empty then.
430-
if (!cl.is_compact_same_region()) {
431-
empty_regions.append(from_region);
432-
}
433-
from_region = it.next();
430+
template<typename ClosureType>
431+
void ShenandoahPrepareForCompactionTask::prepare_for_compaction(ClosureType& cl,
432+
GrowableArray<ShenandoahHeapRegion*>& empty_regions,
433+
ShenandoahHeapRegionSetIterator& it,
434+
ShenandoahHeapRegion* from_region) {
435+
while (from_region != nullptr) {
436+
assert(is_candidate_region(from_region), "Sanity");
437+
cl.set_from_region(from_region);
438+
if (from_region->has_live()) {
439+
_heap->marked_object_iterate(from_region, &cl);
434440
}
435-
cl.finish_region();
436441

437-
// Mark all remaining regions as empty
438-
for (int pos = cl.empty_regions_pos(); pos < empty_regions.length(); ++pos) {
439-
ShenandoahHeapRegion* r = empty_regions.at(pos);
440-
r->set_new_top(r->bottom());
442+
// Compacted the region to somewhere else? From-region is empty then.
443+
if (!cl.is_compact_same_region()) {
444+
empty_regions.append(from_region);
441445
}
446+
from_region = it.next();
442447
}
443-
};
448+
cl.finish();
449+
450+
// Mark all remaining regions as empty
451+
for (int pos = cl.empty_regions_pos(); pos < empty_regions.length(); ++pos) {
452+
ShenandoahHeapRegion* r = empty_regions.at(pos);
453+
r->set_new_top(r->bottom());
454+
}
455+
}
444456

445457
void ShenandoahFullGC::calculate_target_humongous_objects() {
446458
ShenandoahHeap* heap = ShenandoahHeap::heap();
@@ -948,7 +960,7 @@ void ShenandoahFullGC::compact_humongous_objects() {
948960
//
949961
// This code is serial, because doing the in-slice parallel sliding is tricky. In most cases,
950962
// humongous regions are already compacted, and do not require further moves, which alleviates
951-
// sliding costs. We may consider doing this in parallel in future.
963+
// sliding costs. We may consider doing this in parallel in the future.
952964

953965
ShenandoahHeap* heap = ShenandoahHeap::heap();
954966

@@ -1054,6 +1066,11 @@ void ShenandoahFullGC::phase4_compact_objects(ShenandoahHeapRegionSet** worker_s
10541066
ShenandoahGCPhase phase(ShenandoahPhaseTimings::full_gc_copy_objects_humong);
10551067
compact_humongous_objects();
10561068
}
1069+
}
1070+
1071+
void ShenandoahFullGC::phase5_epilog() {
1072+
GCTraceTime(Info, gc, phases) time("Phase 5: Full GC epilog", _gc_timer);
1073+
ShenandoahHeap* heap = ShenandoahHeap::heap();
10571074

10581075
// Reset complete bitmap. We're about to reset the complete-top-at-mark-start pointer
10591076
// and must ensure the bitmap is in sync.
@@ -1066,14 +1083,15 @@ void ShenandoahFullGC::phase4_compact_objects(ShenandoahHeapRegionSet** worker_s
10661083
// Bring regions in proper states after the collection, and set heap properties.
10671084
{
10681085
ShenandoahGCPhase phase(ShenandoahPhaseTimings::full_gc_copy_objects_rebuild);
1069-
10701086
ShenandoahPostCompactClosure post_compact;
10711087
heap->heap_region_iterate(&post_compact);
10721088
heap->set_used(post_compact.get_live());
10731089

10741090
heap->collection_set()->clear();
10751091
heap->free_set()->rebuild();
1092+
heap->clear_cancelled_gc();
10761093
}
10771094

1078-
heap->clear_cancelled_gc();
1095+
_preserved_marks->restore(heap->workers());
1096+
_preserved_marks->reclaim();
10791097
}

src/hotspot/share/gc/shenandoah/shenandoahFullGC.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ class ShenandoahFullGC : public ShenandoahGC {
8181
void phase2_calculate_target_addresses(ShenandoahHeapRegionSet** worker_slices);
8282
void phase3_update_references();
8383
void phase4_compact_objects(ShenandoahHeapRegionSet** worker_slices);
84+
void phase5_epilog();
8485

8586
void distribute_slices(ShenandoahHeapRegionSet** worker_slices);
8687
void calculate_target_humongous_objects();

0 commit comments

Comments
 (0)