# HG changeset patch # User tonyp # Date 1223313395 14400 # Node ID cc68c8e9b309577bbbd3c17c9aaa1d697a83980d # Parent ee21eaa8ffe19cf9964371640bfeb1163a40d71d 6752248: G1: introduce parallel heap verification Summary: Introduce parallel heap verification in G1. Reviewed-by: jcoomes, apetrusenko diff -r ee21eaa8ffe1 -r cc68c8e9b309 src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp --- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Thu Oct 02 12:01:08 2008 -0700 +++ b/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"); diff -r ee21eaa8ffe1 -r cc68c8e9b309 src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp --- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp Thu Oct 02 12:01:08 2008 -0700 +++ b/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 diff -r ee21eaa8ffe1 -r cc68c8e9b309 src/share/vm/gc_implementation/g1/heapRegion.hpp --- a/src/share/vm/gc_implementation/g1/heapRegion.hpp Thu Oct 02 12:01:08 2008 -0700 +++ b/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 diff -r ee21eaa8ffe1 -r cc68c8e9b309 src/share/vm/runtime/globals.hpp --- a/src/share/vm/runtime/globals.hpp Thu Oct 02 12:01:08 2008 -0700 +++ b/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") \ \