6624765: Guarantee failure "Unexpected dirty card found"
In verification take into account partial coverage of a region by a card and expansion of the card table. Reviewed-by: ysr, apetrusenko
This commit is contained in:
parent
41895dc06d
commit
38fdc8ab98
hotspot/src/share/vm
gc_implementation/parNew
memory
@ -785,6 +785,9 @@ void ParNewGeneration::collect(bool full,
|
||||
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());
|
||||
|
@ -196,8 +196,8 @@ void CardTableModRefBS::resize_covered_region(MemRegion new_region) {
|
||||
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 @@ void CardTableModRefBS::resize_covered_region(MemRegion new_region) {
|
||||
// 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 @@ void CardTableModRefBS::resize_covered_region(MemRegion new_region) {
|
||||
// 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 @@ void CardTableModRefBS::resize_covered_region(MemRegion new_region) {
|
||||
}
|
||||
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)));
|
||||
|
@ -556,10 +556,16 @@ void CardTableRS::verify() {
|
||||
}
|
||||
|
||||
|
||||
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");
|
||||
|
@ -126,7 +126,7 @@ public:
|
||||
}
|
||||
|
||||
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);
|
||||
|
@ -91,8 +91,15 @@ public:
|
||||
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() {}
|
||||
|
@ -409,10 +409,11 @@ void TenuredGeneration::retire_alloc_buffers_before_full_gc() {
|
||||
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() {}
|
||||
|
Loading…
x
Reference in New Issue
Block a user