8224881: Shenandoah: trashing "Collection Set, Pinned" region during Degenerated GC
Reviewed-by: rkennke, zgu
--- a/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp Thu Jun 13 13:04:33 2019 -0400
+++ b/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp Thu Jun 13 19:37:49 2019 +0200
@@ -1694,7 +1694,28 @@
// it would be a simple check, which is supposed to be fast. This is also
// safe to do even without degeneration, as CSet iterator is at beginning
// in preparation for evacuation anyway.
- collection_set()->clear_current_index();
+ //
+ // Before doing that, we need to make sure we never had any cset-pinned
+ // regions. This may happen if allocation failure happened when evacuating
+ // the about-to-be-pinned object, oom-evac protocol left the object in
+ // the collection set, and then the pin reached the cset region. If we continue
+ // the cycle here, we would trash the cset and alive objects in it. To avoid
+ // it, we fail degeneration right away and slide into Full GC to recover.
+
+ {
+ collection_set()->clear_current_index();
+
+ ShenandoahHeapRegion* r;
+ while ((r = collection_set()->next()) != NULL) {
+ if (r->is_pinned()) {
+ cancel_gc(GCCause::_shenandoah_upgrade_to_full_gc);
+ op_degenerated_fail();
+ return;
+ }
+ }
+
+ collection_set()->clear_current_index();
+ }
op_stw_evac();
if (cancelled_gc()) {