Mercurial > hg > truffle
diff src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp @ 3777:e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
Summary: Remove two unnecessary iterations over the collection set which are supposed to prepare the RSet's of the CSet regions for parallel iterations (we'll make sure this is done incrementally). I'll piggyback on this CR the removal of the G1_REM_SET_LOGGING code.
Reviewed-by: brutisso, johnc
author | tonyp |
---|---|
date | Tue, 21 Jun 2011 15:23:07 -0400 |
parents | c9ca3f51cf41 |
children | 5f6f2615433a |
line wrap: on
line diff
--- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Mon Jun 20 22:03:13 2011 -0400 +++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Tue Jun 21 15:23:07 2011 -0400 @@ -3015,6 +3015,56 @@ SpecializationStats::print(); } +#ifndef PRODUCT +// Helpful for debugging RSet issues. + +class PrintRSetsClosure : public HeapRegionClosure { +private: + const char* _msg; + size_t _occupied_sum; + +public: + bool doHeapRegion(HeapRegion* r) { + HeapRegionRemSet* hrrs = r->rem_set(); + size_t occupied = hrrs->occupied(); + _occupied_sum += occupied; + + gclog_or_tty->print_cr("Printing RSet for region "HR_FORMAT, + HR_FORMAT_PARAMS(r)); + if (occupied == 0) { + gclog_or_tty->print_cr(" RSet is empty"); + } else { + hrrs->print(); + } + gclog_or_tty->print_cr("----------"); + return false; + } + + PrintRSetsClosure(const char* msg) : _msg(msg), _occupied_sum(0) { + gclog_or_tty->cr(); + gclog_or_tty->print_cr("========================================"); + gclog_or_tty->print_cr(msg); + gclog_or_tty->cr(); + } + + ~PrintRSetsClosure() { + gclog_or_tty->print_cr("Occupied Sum: "SIZE_FORMAT, _occupied_sum); + gclog_or_tty->print_cr("========================================"); + gclog_or_tty->cr(); + } +}; + +void G1CollectedHeap::print_cset_rsets() { + PrintRSetsClosure cl("Printing CSet RSets"); + collection_set_iterate(&cl); +} + +void G1CollectedHeap::print_all_rsets() { + PrintRSetsClosure cl("Printing All RSets");; + heap_region_iterate(&cl); +} +#endif // PRODUCT + G1CollectedHeap* G1CollectedHeap::heap() { assert(_sh->kind() == CollectedHeap::G1CollectedHeap, "not a garbage-first heap"); @@ -3148,12 +3198,27 @@ // </NEW PREDICTION> -struct PrepareForRSScanningClosure : public HeapRegionClosure { - bool doHeapRegion(HeapRegion *r) { - r->rem_set()->set_iter_claimed(0); +#ifdef ASSERT +class VerifyCSetClosure: public HeapRegionClosure { +public: + bool doHeapRegion(HeapRegion* hr) { + // Here we check that the CSet region's RSet is ready for parallel + // iteration. The fields that we'll verify are only manipulated + // when the region is part of a CSet and is collected. Afterwards, + // we reset these fields when we clear the region's RSet (when the + // region is freed) so they are ready when the region is + // re-allocated. The only exception to this is if there's an + // evacuation failure and instead of freeing the region we leave + // it in the heap. In that case, we reset these fields during + // evacuation failure handling. + guarantee(hr->rem_set()->verify_ready_for_par_iteration(), "verification"); + + // Here's a good place to add any other checks we'd like to + // perform on CSet regions. return false; } }; +#endif // ASSERT #if TASKQUEUE_STATS void G1CollectedHeap::print_taskqueue_stats_hdr(outputStream* const st) { @@ -3257,11 +3322,6 @@ gc_prologue(false); increment_total_collections(false /* full gc */); -#if G1_REM_SET_LOGGING - gclog_or_tty->print_cr("\nJust chose CS, heap:"); - print(); -#endif - if (VerifyBeforeGC && total_collections() >= VerifyGCStartAt) { HandleMark hm; // Discard invalid handles created during verification gclog_or_tty->print(" VerifyBeforeGC:"); @@ -3347,13 +3407,10 @@ concurrent_mark()->reset_active_task_region_fields_in_cset(); } - // Nothing to do if we were unable to choose a collection set. -#if G1_REM_SET_LOGGING - gclog_or_tty->print_cr("\nAfter pause, heap:"); - print(); -#endif - PrepareForRSScanningClosure prepare_for_rs_scan; - collection_set_iterate(&prepare_for_rs_scan); +#ifdef ASSERT + VerifyCSetClosure cl; + collection_set_iterate(&cl); +#endif // ASSERT setup_surviving_young_words(); @@ -3955,6 +4012,14 @@ assert(cur->in_collection_set(), "bad CS"); RemoveSelfPointerClosure rspc(_g1h, cur, cl); + // In the common case we make sure that this is done when the + // region is freed so that it is "ready-to-go" when it's + // re-allocated. However, when evacuation failure happens, a + // region will remain in the heap and might ultimately be added + // to a CSet in the future. So we have to be careful here and + // make sure the region's RSet is ready for parallel iteration + // whenever this might be required in the future. + cur->rem_set()->reset_for_par_iteration(); cur->reset_bot(); cl->set_region(cur); cur->object_iterate(&rspc); @@ -4474,10 +4539,6 @@ // here the null check is implicit in the cset_fast_test() test if (_g1->in_cset_fast_test(obj)) { -#if G1_REM_SET_LOGGING - gclog_or_tty->print_cr("Loc "PTR_FORMAT" contains pointer "PTR_FORMAT" " - "into CS.", p, (void*) obj); -#endif if (obj->is_forwarded()) { oopDesc::encode_store_heap_oop(p, obj->forwardee()); } else {