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()); |