Mercurial > hg > truffle
comparison src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp @ 3317:063382f9b575
7035144: G1: nightly failure: Non-dirty cards in region that should be dirty (failures still exist...)
Summary: We should only undirty cards after we decide that they are not on a young region, not before. The fix also includes improvements to the verify_dirty_region() method which print out which cards were not found dirty.
Reviewed-by: johnc, brutisso
author | tonyp |
---|---|
date | Fri, 29 Apr 2011 14:59:04 -0400 |
parents | 1f4413413144 |
children | 75af3e8de182 |
comparison
equal
deleted
inserted
replaced
3316:cd8e33b2a8ad | 3317:063382f9b575 |
---|---|
4959 }; | 4959 }; |
4960 | 4960 |
4961 | 4961 |
4962 #ifndef PRODUCT | 4962 #ifndef PRODUCT |
4963 class G1VerifyCardTableCleanup: public HeapRegionClosure { | 4963 class G1VerifyCardTableCleanup: public HeapRegionClosure { |
4964 G1CollectedHeap* _g1h; | |
4964 CardTableModRefBS* _ct_bs; | 4965 CardTableModRefBS* _ct_bs; |
4965 public: | 4966 public: |
4966 G1VerifyCardTableCleanup(CardTableModRefBS* ct_bs) | 4967 G1VerifyCardTableCleanup(G1CollectedHeap* g1h, CardTableModRefBS* ct_bs) |
4967 : _ct_bs(ct_bs) { } | 4968 : _g1h(g1h), _ct_bs(ct_bs) { } |
4968 virtual bool doHeapRegion(HeapRegion* r) { | 4969 virtual bool doHeapRegion(HeapRegion* r) { |
4969 MemRegion mr(r->bottom(), r->end()); | |
4970 if (r->is_survivor()) { | 4970 if (r->is_survivor()) { |
4971 _ct_bs->verify_dirty_region(mr); | 4971 _g1h->verify_dirty_region(r); |
4972 } else { | 4972 } else { |
4973 _ct_bs->verify_clean_region(mr); | 4973 _g1h->verify_not_dirty_region(r); |
4974 } | 4974 } |
4975 return false; | 4975 return false; |
4976 } | 4976 } |
4977 }; | 4977 }; |
4978 | 4978 |
4979 void G1CollectedHeap::verify_not_dirty_region(HeapRegion* hr) { | |
4980 // All of the region should be clean. | |
4981 CardTableModRefBS* ct_bs = (CardTableModRefBS*)barrier_set(); | |
4982 MemRegion mr(hr->bottom(), hr->end()); | |
4983 ct_bs->verify_not_dirty_region(mr); | |
4984 } | |
4985 | |
4986 void G1CollectedHeap::verify_dirty_region(HeapRegion* hr) { | |
4987 // We cannot guarantee that [bottom(),end()] is dirty. Threads | |
4988 // dirty allocated blocks as they allocate them. The thread that | |
4989 // retires each region and replaces it with a new one will do a | |
4990 // maximal allocation to fill in [pre_dummy_top(),end()] but will | |
4991 // not dirty that area (one less thing to have to do while holding | |
4992 // a lock). So we can only verify that [bottom(),pre_dummy_top()] | |
4993 // is dirty. | |
4994 CardTableModRefBS* ct_bs = (CardTableModRefBS*) barrier_set(); | |
4995 MemRegion mr(hr->bottom(), hr->pre_dummy_top()); | |
4996 ct_bs->verify_dirty_region(mr); | |
4997 } | |
4998 | |
4979 void G1CollectedHeap::verify_dirty_young_list(HeapRegion* head) { | 4999 void G1CollectedHeap::verify_dirty_young_list(HeapRegion* head) { |
4980 CardTableModRefBS* ct_bs = (CardTableModRefBS*) (barrier_set()); | 5000 CardTableModRefBS* ct_bs = (CardTableModRefBS*) barrier_set(); |
4981 for (HeapRegion* hr = head; hr != NULL; hr = hr->get_next_young_region()) { | 5001 for (HeapRegion* hr = head; hr != NULL; hr = hr->get_next_young_region()) { |
4982 // We cannot guarantee that [bottom(),end()] is dirty. Threads | 5002 verify_dirty_region(hr); |
4983 // dirty allocated blocks as they allocate them. The thread that | |
4984 // retires each region and replaces it with a new one will do a | |
4985 // maximal allocation to fill in [pre_dummy_top(),end()] but will | |
4986 // not dirty that area (one less thing to have to do while holding | |
4987 // a lock). So we can only verify that [bottom(),pre_dummy_top()] | |
4988 // is dirty. Also note that verify_dirty_region() requires | |
4989 // mr.start() and mr.end() to be card aligned and pre_dummy_top() | |
4990 // is not guaranteed to be. | |
4991 MemRegion mr(hr->bottom(), | |
4992 ct_bs->align_to_card_boundary(hr->pre_dummy_top())); | |
4993 ct_bs->verify_dirty_region(mr); | |
4994 } | 5003 } |
4995 } | 5004 } |
4996 | 5005 |
4997 void G1CollectedHeap::verify_dirty_young_regions() { | 5006 void G1CollectedHeap::verify_dirty_young_regions() { |
4998 verify_dirty_young_list(_young_list->first_region()); | 5007 verify_dirty_young_list(_young_list->first_region()); |
5031 | 5040 |
5032 double elapsed = os::elapsedTime() - start; | 5041 double elapsed = os::elapsedTime() - start; |
5033 g1_policy()->record_clear_ct_time( elapsed * 1000.0); | 5042 g1_policy()->record_clear_ct_time( elapsed * 1000.0); |
5034 #ifndef PRODUCT | 5043 #ifndef PRODUCT |
5035 if (G1VerifyCTCleanup || VerifyAfterGC) { | 5044 if (G1VerifyCTCleanup || VerifyAfterGC) { |
5036 G1VerifyCardTableCleanup cleanup_verifier(ct_bs); | 5045 G1VerifyCardTableCleanup cleanup_verifier(this, ct_bs); |
5037 heap_region_iterate(&cleanup_verifier); | 5046 heap_region_iterate(&cleanup_verifier); |
5038 } | 5047 } |
5039 #endif | 5048 #endif |
5040 } | 5049 } |
5041 | 5050 |