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
--- a/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp Tue Feb 12 16:07:46 2008 -0800
+++ b/hotspot/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());
--- a/hotspot/src/share/vm/memory/cardTableModRefBS.cpp Tue Feb 12 16:07:46 2008 -0800
+++ b/hotspot/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)));
--- a/hotspot/src/share/vm/memory/cardTableRS.cpp Tue Feb 12 16:07:46 2008 -0800
+++ b/hotspot/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");
--- a/hotspot/src/share/vm/memory/cardTableRS.hpp Tue Feb 12 16:07:46 2008 -0800
+++ b/hotspot/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);
--- a/hotspot/src/share/vm/memory/genRemSet.hpp Tue Feb 12 16:07:46 2008 -0800
+++ b/hotspot/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() {}
--- a/hotspot/src/share/vm/memory/tenuredGeneration.cpp Tue Feb 12 16:07:46 2008 -0800
+++ b/hotspot/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() {}