changeset 55885:2c47220ce9bb

8224881: Shenandoah: trashing "Collection Set, Pinned" region during Degenerated GC Reviewed-by: rkennke, zgu
author shade
date Thu, 13 Jun 2019 19:37:49 +0200
parents 31d026474e77
children 2f4e214781a1
files src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp
diffstat 1 files changed, 22 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- 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()) {