提交 b95aca5c 编写于 作者: T tonyp

6752248: G1: introduce parallel heap verification

Summary: Introduce parallel heap verification in G1.
Reviewed-by: jcoomes, apetrusenko
上级 5b826922
...@@ -1789,6 +1789,20 @@ G1CollectedHeap::heap_region_par_iterate_chunked(HeapRegionClosure* cl, ...@@ -1789,6 +1789,20 @@ G1CollectedHeap::heap_region_par_iterate_chunked(HeapRegionClosure* cl,
} }
} }
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 #ifdef ASSERT
// This checks whether all regions in the heap have the correct claim // 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 // value. I also piggy-backed on this a check to ensure that the
...@@ -2031,10 +2045,12 @@ public: ...@@ -2031,10 +2045,12 @@ public:
class VerifyRegionClosure: public HeapRegionClosure { class VerifyRegionClosure: public HeapRegionClosure {
public: public:
bool _allow_dirty; bool _allow_dirty;
VerifyRegionClosure(bool allow_dirty) bool _par;
: _allow_dirty(allow_dirty) {} VerifyRegionClosure(bool allow_dirty, bool par = false)
: _allow_dirty(allow_dirty), _par(par) {}
bool doHeapRegion(HeapRegion* r) { 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->isHumongous()) {
if (r->startsHumongous()) { if (r->startsHumongous()) {
// Verify the single H object. // Verify the single H object.
...@@ -2082,6 +2098,25 @@ public: ...@@ -2082,6 +2098,25 @@ public:
} }
}; };
// 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) { void G1CollectedHeap::verify(bool allow_dirty, bool silent) {
if (SafepointSynchronize::is_at_safepoint() || ! UseTLAB) { if (SafepointSynchronize::is_at_safepoint() || ! UseTLAB) {
if (!silent) { gclog_or_tty->print("roots "); } if (!silent) { gclog_or_tty->print("roots "); }
...@@ -2092,8 +2127,27 @@ void G1CollectedHeap::verify(bool allow_dirty, bool silent) { ...@@ -2092,8 +2127,27 @@ void G1CollectedHeap::verify(bool allow_dirty, bool silent) {
&rootsCl); &rootsCl);
rem_set()->invalidate(perm_gen()->used_region(), false); rem_set()->invalidate(perm_gen()->used_region(), false);
if (!silent) { gclog_or_tty->print("heapRegions "); } if (!silent) { gclog_or_tty->print("heapRegions "); }
VerifyRegionClosure blk(allow_dirty); if (GCParallelVerificationEnabled && ParallelGCThreads > 1) {
_hrs->iterate(&blk); 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 "); if (!silent) gclog_or_tty->print("remset ");
rem_set()->verify(); rem_set()->verify();
guarantee(!rootsCl.failures(), "should not have had failures"); guarantee(!rootsCl.failures(), "should not have had failures");
......
...@@ -890,6 +890,9 @@ public: ...@@ -890,6 +890,9 @@ public:
int worker, int worker,
jint claim_value); jint claim_value);
// It resets all the region claim values to the default.
void reset_heap_region_claim_values();
#ifdef ASSERT #ifdef ASSERT
bool check_heap_region_claim_values(jint claim_value); bool check_heap_region_claim_values(jint claim_value);
#endif // ASSERT #endif // ASSERT
......
...@@ -317,7 +317,8 @@ class HeapRegion: public G1OffsetTableContigSpace { ...@@ -317,7 +317,8 @@ class HeapRegion: public G1OffsetTableContigSpace {
InitialClaimValue = 0, InitialClaimValue = 0,
FinalCountClaimValue = 1, FinalCountClaimValue = 1,
NoteEndClaimValue = 2, NoteEndClaimValue = 2,
ScrubRemSetClaimValue = 3 ScrubRemSetClaimValue = 3,
ParVerifyClaimValue = 4
}; };
// Concurrent refinement requires contiguous heap regions (in which TLABs // Concurrent refinement requires contiguous heap regions (in which TLABs
......
...@@ -1825,6 +1825,9 @@ class CommandLineFlags { ...@@ -1825,6 +1825,9 @@ class CommandLineFlags {
diagnostic(bool, VerifyDuringGC, false, \ diagnostic(bool, VerifyDuringGC, false, \
"Verify memory system during GC (between phases)") \ "Verify memory system during GC (between phases)") \
\ \
diagnostic(bool, GCParallelVerificationEnabled, true, \
"Enable parallel memory system verification") \
\
diagnostic(bool, VerifyRememberedSets, false, \ diagnostic(bool, VerifyRememberedSets, false, \
"Verify GC remembered sets") \ "Verify GC remembered sets") \
\ \
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册