6752248: G1: introduce parallel heap verification
authortonyp
Mon, 06 Oct 2008 13:16:35 -0400
changeset 1422 9af8f4023912
parent 1421 a7ef1a3b2644
child 1423 1233b1e85dfd
6752248: G1: introduce parallel heap verification Summary: Introduce parallel heap verification in G1. Reviewed-by: jcoomes, apetrusenko
hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp
hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp
hotspot/src/share/vm/gc_implementation/g1/heapRegion.hpp
hotspot/src/share/vm/runtime/globals.hpp
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp	Thu Oct 02 12:01:08 2008 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp	Mon Oct 06 13:16:35 2008 -0400
@@ -1789,6 +1789,20 @@
   }
 }
 
+class ResetClaimValuesClosure: public HeapRegionClosure {
+public:
+  bool doHeapRegion(HeapRegion* r) {
+    r->set_claim_value(HeapRegion::InitialClaimValue);
+    return false;
+  }
+};
+
+void
+G1CollectedHeap::reset_heap_region_claim_values() {
+  ResetClaimValuesClosure blk;
+  heap_region_iterate(&blk);
+}
+
 #ifdef ASSERT
 // This checks whether all regions in the heap have the correct claim
 // value. I also piggy-backed on this a check to ensure that the
@@ -2031,10 +2045,12 @@
 class VerifyRegionClosure: public HeapRegionClosure {
 public:
   bool _allow_dirty;
-  VerifyRegionClosure(bool allow_dirty)
-    : _allow_dirty(allow_dirty) {}
+  bool _par;
+  VerifyRegionClosure(bool allow_dirty, bool par = false)
+    : _allow_dirty(allow_dirty), _par(par) {}
   bool doHeapRegion(HeapRegion* r) {
-    guarantee(r->claim_value() == 0, "Should be unclaimed at verify points.");
+    guarantee(_par || r->claim_value() == HeapRegion::InitialClaimValue,
+              "Should be unclaimed at verify points.");
     if (r->isHumongous()) {
       if (r->startsHumongous()) {
         // Verify the single H object.
@@ -2082,6 +2098,25 @@
   }
 };
 
+// This is the task used for parallel heap verification.
+
+class G1ParVerifyTask: public AbstractGangTask {
+private:
+  G1CollectedHeap* _g1h;
+  bool _allow_dirty;
+
+public:
+  G1ParVerifyTask(G1CollectedHeap* g1h, bool allow_dirty) :
+    AbstractGangTask("Parallel verify task"),
+    _g1h(g1h), _allow_dirty(allow_dirty) { }
+
+  void work(int worker_i) {
+    VerifyRegionClosure blk(_allow_dirty, true);
+    _g1h->heap_region_par_iterate_chunked(&blk, worker_i,
+                                          HeapRegion::ParVerifyClaimValue);
+  }
+};
+
 void G1CollectedHeap::verify(bool allow_dirty, bool silent) {
   if (SafepointSynchronize::is_at_safepoint() || ! UseTLAB) {
     if (!silent) { gclog_or_tty->print("roots "); }
@@ -2092,8 +2127,27 @@
                          &rootsCl);
     rem_set()->invalidate(perm_gen()->used_region(), false);
     if (!silent) { gclog_or_tty->print("heapRegions "); }
-    VerifyRegionClosure blk(allow_dirty);
-    _hrs->iterate(&blk);
+    if (GCParallelVerificationEnabled && ParallelGCThreads > 1) {
+      assert(check_heap_region_claim_values(HeapRegion::InitialClaimValue),
+             "sanity check");
+
+      G1ParVerifyTask task(this, allow_dirty);
+      int n_workers = workers()->total_workers();
+      set_par_threads(n_workers);
+      workers()->run_task(&task);
+      set_par_threads(0);
+
+      assert(check_heap_region_claim_values(HeapRegion::ParVerifyClaimValue),
+             "sanity check");
+
+      reset_heap_region_claim_values();
+
+      assert(check_heap_region_claim_values(HeapRegion::InitialClaimValue),
+             "sanity check");
+    } else {
+      VerifyRegionClosure blk(allow_dirty);
+      _hrs->iterate(&blk);
+    }
     if (!silent) gclog_or_tty->print("remset ");
     rem_set()->verify();
     guarantee(!rootsCl.failures(), "should not have had failures");
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp	Thu Oct 02 12:01:08 2008 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp	Mon Oct 06 13:16:35 2008 -0400
@@ -890,6 +890,9 @@
                                        int worker,
                                        jint claim_value);
 
+  // It resets all the region claim values to the default.
+  void reset_heap_region_claim_values();
+
 #ifdef ASSERT
   bool check_heap_region_claim_values(jint claim_value);
 #endif // ASSERT
--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegion.hpp	Thu Oct 02 12:01:08 2008 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegion.hpp	Mon Oct 06 13:16:35 2008 -0400
@@ -317,7 +317,8 @@
     InitialClaimValue     = 0,
     FinalCountClaimValue  = 1,
     NoteEndClaimValue     = 2,
-    ScrubRemSetClaimValue = 3
+    ScrubRemSetClaimValue = 3,
+    ParVerifyClaimValue   = 4
   };
 
   // Concurrent refinement requires contiguous heap regions (in which TLABs
--- a/hotspot/src/share/vm/runtime/globals.hpp	Thu Oct 02 12:01:08 2008 -0700
+++ b/hotspot/src/share/vm/runtime/globals.hpp	Mon Oct 06 13:16:35 2008 -0400
@@ -1825,6 +1825,9 @@
   diagnostic(bool, VerifyDuringGC, false,                                   \
           "Verify memory system during GC (between phases)")                \
                                                                             \
+  diagnostic(bool, GCParallelVerificationEnabled, true,                     \
+          "Enable parallel memory system verification")                     \
+                                                                            \
   diagnostic(bool, VerifyRememberedSets, false,                             \
           "Verify GC remembered sets")                                      \
                                                                             \