# HG changeset patch # User jmasa # Date 1203087670 28800 # Node ID 73e96e5c30dff8695e1686da349e71550d7ec3eb # Parent f21b879b4c721193eb7cd05e1e1dc4e8e932a0fb 6624765: Guarantee failure "Unexpected dirty card found" Summary: In verification take into account partial coverage of a region by a card and expansion of the card table. Reviewed-by: ysr, apetrusenko diff -r f21b879b4c72 -r 73e96e5c30df src/share/vm/gc_implementation/parNew/parNewGeneration.cpp --- a/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp Tue Feb 12 16:07:46 2008 -0800 +++ b/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp Fri Feb 15 07:01:10 2008 -0800 @@ -785,6 +785,9 @@ swap_spaces(); // Make life simpler for CMS || rescan; see 6483690. from()->set_next_compaction_space(to()); gch->set_incremental_collection_will_fail(); + + // Reset the PromotionFailureALot counters. + NOT_PRODUCT(Universe::heap()->reset_promotion_should_fail();) } // set new iteration safe limit for the survivor spaces from()->set_concurrent_iteration_safe_limit(from()->top()); diff -r f21b879b4c72 -r 73e96e5c30df src/share/vm/memory/cardTableModRefBS.cpp --- a/src/share/vm/memory/cardTableModRefBS.cpp Tue Feb 12 16:07:46 2008 -0800 +++ b/src/share/vm/memory/cardTableModRefBS.cpp Fri Feb 15 07:01:10 2008 -0800 @@ -196,8 +196,8 @@ assert(_whole_heap.contains(new_region), "attempt to cover area not in reserved area"); debug_only(verify_guard();) - int ind = find_covering_region_by_base(new_region.start()); - MemRegion old_region = _covered[ind]; + int const ind = find_covering_region_by_base(new_region.start()); + MemRegion const old_region = _covered[ind]; assert(old_region.start() == new_region.start(), "just checking"); if (new_region.word_size() != old_region.word_size()) { // Commit new or uncommit old pages, if necessary. @@ -205,21 +205,21 @@ // Extend the end of this _commited region // to cover the end of any lower _committed regions. // This forms overlapping regions, but never interior regions. - HeapWord* max_prev_end = largest_prev_committed_end(ind); + HeapWord* const max_prev_end = largest_prev_committed_end(ind); if (max_prev_end > cur_committed.end()) { cur_committed.set_end(max_prev_end); } // Align the end up to a page size (starts are already aligned). - jbyte* new_end = byte_after(new_region.last()); - HeapWord* new_end_aligned = - (HeapWord*)align_size_up((uintptr_t)new_end, _page_size); + jbyte* const new_end = byte_after(new_region.last()); + HeapWord* const new_end_aligned = + (HeapWord*) align_size_up((uintptr_t)new_end, _page_size); assert(new_end_aligned >= (HeapWord*) new_end, "align up, but less"); // The guard page is always committed and should not be committed over. - HeapWord* new_end_for_commit = MIN2(new_end_aligned, _guard_region.start()); + HeapWord* const new_end_for_commit = MIN2(new_end_aligned, _guard_region.start()); if (new_end_for_commit > cur_committed.end()) { // Must commit new pages. - MemRegion new_committed = + MemRegion const new_committed = MemRegion(cur_committed.end(), new_end_for_commit); assert(!new_committed.is_empty(), "Region should not be empty here"); @@ -233,7 +233,7 @@ // the cur_committed region may include the guard region. } else if (new_end_aligned < cur_committed.end()) { // Must uncommit pages. - MemRegion uncommit_region = + MemRegion const uncommit_region = committed_unique_to_self(ind, MemRegion(new_end_aligned, cur_committed.end())); if (!uncommit_region.is_empty()) { @@ -257,7 +257,7 @@ } assert(index_for(new_region.last()) < (int) _guard_index, "The guard card will be overwritten"); - jbyte* end = byte_after(new_region.last()); + jbyte* const end = (jbyte*) new_end_for_commit; // do nothing if we resized downward. if (entry < end) { memset(entry, clean_card, pointer_delta(end, entry, sizeof(jbyte))); diff -r f21b879b4c72 -r 73e96e5c30df src/share/vm/memory/cardTableRS.cpp --- a/src/share/vm/memory/cardTableRS.cpp Tue Feb 12 16:07:46 2008 -0800 +++ b/src/share/vm/memory/cardTableRS.cpp Fri Feb 15 07:01:10 2008 -0800 @@ -556,10 +556,16 @@ } -void CardTableRS::verify_empty(MemRegion mr) { +void CardTableRS::verify_aligned_region_empty(MemRegion mr) { if (!mr.is_empty()) { jbyte* cur_entry = byte_for(mr.start()); jbyte* limit = byte_after(mr.last()); + // The region mr may not start on a card boundary so + // the first card may reflect a write to the space + // just prior to mr. + if (!is_aligned(mr.start())) { + cur_entry++; + } for (;cur_entry < limit; cur_entry++) { guarantee(*cur_entry == CardTableModRefBS::clean_card, "Unexpected dirty card found"); diff -r f21b879b4c72 -r 73e96e5c30df src/share/vm/memory/cardTableRS.hpp --- a/src/share/vm/memory/cardTableRS.hpp Tue Feb 12 16:07:46 2008 -0800 +++ b/src/share/vm/memory/cardTableRS.hpp Fri Feb 15 07:01:10 2008 -0800 @@ -126,7 +126,7 @@ } void verify(); - void verify_empty(MemRegion mr); + void verify_aligned_region_empty(MemRegion mr); void clear(MemRegion mr) { _ct_bs.clear(mr); } void clear_into_younger(Generation* gen, bool clear_perm); diff -r f21b879b4c72 -r 73e96e5c30df src/share/vm/memory/genRemSet.hpp --- a/src/share/vm/memory/genRemSet.hpp Tue Feb 12 16:07:46 2008 -0800 +++ b/src/share/vm/memory/genRemSet.hpp Fri Feb 15 07:01:10 2008 -0800 @@ -91,8 +91,15 @@ virtual void verify() = 0; // Verify that the remembered set has no entries for - // the heap interval denoted by mr. - virtual void verify_empty(MemRegion mr) = 0; + // the heap interval denoted by mr. If there are any + // alignment constraints on the remembered set, only the + // part of the region that is aligned is checked. + // + // alignment boundaries + // +--------+-------+--------+-------+ + // [ region mr ) + // [ part checked ) + virtual void verify_aligned_region_empty(MemRegion mr) = 0; // If appropriate, print some information about the remset on "tty". virtual void print() {} diff -r f21b879b4c72 -r 73e96e5c30df src/share/vm/memory/tenuredGeneration.cpp --- a/src/share/vm/memory/tenuredGeneration.cpp Tue Feb 12 16:07:46 2008 -0800 +++ b/src/share/vm/memory/tenuredGeneration.cpp Fri Feb 15 07:01:10 2008 -0800 @@ -409,10 +409,11 @@ void TenuredGeneration::verify_alloc_buffers_clean() { if (UseParNewGC) { for (uint i = 0; i < ParallelGCThreads; i++) { - _rs->verify_empty(_alloc_buffers[i]->range()); + _rs->verify_aligned_region_empty(_alloc_buffers[i]->range()); } } } + #else // SERIALGC void TenuredGeneration::retire_alloc_buffers_before_full_gc() {} void TenuredGeneration::verify_alloc_buffers_clean() {}