src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp
Print this page
rev 3985 : 7132678: G1: verify that the marking bitmaps have no marks for objects over TAMS
Summary: Verify that parts of the marking bitmaps that should not have marks do not have marks, i.e., the parts of the bitmap that cover [TAMS:top) areas for each heap region.
Reviewed-by:
*** 1,7 ****
/*
! * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
--- 1,7 ----
/*
! * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*** 782,791 ****
--- 782,792 ----
// If we have continues humongous regions (hr != NULL), then the
// end of the last one should match new_end and its top should
// match new_top.
assert(hr == NULL ||
(hr->end() == new_end && hr->top() == new_top), "sanity");
+ check_bitmaps("Humongous Region Allocation", first_hr);
assert(first_hr->used() == word_size * HeapWordSize, "invariant");
_summary_bytes_used += first_hr->used();
_humongous_set.add(first_hr);
*** 1332,1341 ****
--- 1333,1343 ----
size_t g1h_prev_used = used();
assert(used() == recalculate_used(), "Should be equal");
verify_before_gc();
+ check_bitmaps("Full GC Start");
pre_full_gc_dump();
COMPILER2_PRESENT(DerivedPointerTable::clear());
// Disable discovery and empty the discovered lists
*** 1343,1354 ****
ref_processor_cm()->disable_discovery();
ref_processor_cm()->abandon_partial_discovery();
ref_processor_cm()->verify_no_references_recorded();
// Abandon current iterations of concurrent marking and concurrent
! // refinement, if any are in progress. We have to do this before
! // wait_until_scan_finished() below.
concurrent_mark()->abort();
// Make sure we'll choose a new allocation region afterwards.
release_mutator_alloc_region();
abandon_gc_alloc_regions();
--- 1345,1355 ----
ref_processor_cm()->disable_discovery();
ref_processor_cm()->abandon_partial_discovery();
ref_processor_cm()->verify_no_references_recorded();
// Abandon current iterations of concurrent marking and concurrent
! // refinement, if any are in progress.
concurrent_mark()->abort();
// Make sure we'll choose a new allocation region afterwards.
release_mutator_alloc_region();
abandon_gc_alloc_regions();
*** 1387,1396 ****
--- 1388,1405 ----
{
HandleMark hm; // Discard invalid handles created during gc
G1MarkSweep::invoke_at_safepoint(ref_processor_stw(), do_clear_all_soft_refs);
}
+ // Clear the previous marking bitmap, if needed for bitmap verification.
+ // Note we cannot do this when we clear the next marking bitmap in
+ // ConcurrentMark::abort() above since VerifyDuringGC verifies the
+ // objects marked during a full GC against the previous bitmap.
+ if (G1VerifyPrevBitmap) {
+ ((CMBitMap*) concurrent_mark()->prevMarkBitMap())->clearAll();
+ }
+
assert(free_regions() == 0, "we should not have added any free regions");
rebuild_region_sets(false /* free_list_only */);
// Enqueue any discovered reference objects that have
// not been removed from the discovered lists.
*** 1400,1409 ****
--- 1409,1420 ----
MemoryService::track_memory_usage();
verify_after_gc();
+ check_bitmaps("Full GC End");
+
assert(!ref_processor_stw()->discovery_enabled(), "Postcondition");
ref_processor_stw()->verify_no_references_recorded();
// Delete metaspaces for unloaded class loaders and clean up loader_data graph
ClassLoaderDataGraph::purge();
*** 3773,3782 ****
--- 3784,3794 ----
gc_prologue(false);
increment_total_collections(false /* full gc */);
increment_gc_time_stamp();
verify_before_gc();
+ check_bitmaps("GC Start");
COMPILER2_PRESENT(DerivedPointerTable::clear());
// Please see comment in g1CollectedHeap.hpp and
// G1CollectedHeap::ref_processing_init() to see how
*** 4017,4026 ****
--- 4029,4039 ----
// is_gc_active() check to decided which top to use when
// scanning cards (see CR 7039627).
increment_gc_time_stamp();
verify_after_gc();
+ check_bitmaps("GC End");
assert(!ref_processor_stw()->discovery_enabled(), "Postcondition");
ref_processor_stw()->verify_no_references_recorded();
// CM reference discovery will be re-enabled if necessary.
*** 5739,5748 ****
--- 5752,5765 ----
bool par) {
assert(!hr->isHumongous(), "this is only for non-humongous regions");
assert(!hr->is_empty(), "the region should not be empty");
assert(free_list != NULL, "pre-condition");
+ if (G1VerifyPrevBitmap) {
+ MemRegion mr(hr->bottom(), hr->end());
+ concurrent_mark()->clearRangePrevBitmap(mr);
+ }
*pre_used += hr->used();
hr->hr_clear(par, true /* clear_space */);
free_list->add_as_head(hr);
}
*** 5877,5887 ****
}
void G1CollectedHeap::verify_dirty_young_regions() {
verify_dirty_young_list(_young_list->first_region());
}
! #endif
void G1CollectedHeap::cleanUpCardTable() {
CardTableModRefBS* ct_bs = (CardTableModRefBS*) (barrier_set());
double start = os::elapsedTime();
--- 5894,5986 ----
}
void G1CollectedHeap::verify_dirty_young_regions() {
verify_dirty_young_list(_young_list->first_region());
}
!
! bool G1CollectedHeap::verify_bitmap(const char* bitmap_name, CMBitMapRO* bitmap,
! HeapWord* tams, HeapWord* end) {
! guarantee(tams <= end,
! err_msg("tams: "PTR_FORMAT" end: "PTR_FORMAT, tams, end));
! HeapWord* result = bitmap->getNextMarkedWordAddress(tams, end);
! guarantee(result <= end,
! err_msg("result: "PTR_FORMAT" end: "PTR_FORMAT, result, end));
! if (result < end) {
! gclog_or_tty->cr();
! gclog_or_tty->print_cr("## wrong marked address on %s bitmap: "PTR_FORMAT,
! bitmap_name, result);
! gclog_or_tty->print_cr("## %s tams: "PTR_FORMAT" end: "PTR_FORMAT,
! bitmap_name, tams, end);
! return false;
! }
! return true;
! }
!
! bool G1CollectedHeap::verify_bitmaps(const char* caller, HeapRegion* hr) {
! CMBitMapRO* prev_bitmap = concurrent_mark()->prevMarkBitMap();
! CMBitMapRO* next_bitmap = (CMBitMapRO*) concurrent_mark()->nextMarkBitMap();
!
! HeapWord* bottom = hr->bottom();
! HeapWord* ptams = hr->prev_top_at_mark_start();
! HeapWord* ntams = hr->next_top_at_mark_start();
! HeapWord* end = hr->end();
!
! bool res_p = true;
! if (G1VerifyPrevBitmap) {
! res_p = verify_bitmap("prev", prev_bitmap, ptams, end);
! }
!
! bool res_n = true;
! if (mark_in_progress() || !_cmThread->in_progress()) {
! res_n = verify_bitmap("next", next_bitmap, ntams, end);
! }
! if (!res_p || !res_n) {
! gclog_or_tty->print_cr("#### Bitmap verification failed for "HR_FORMAT,
! HR_FORMAT_PARAMS(hr));
! gclog_or_tty->print_cr("#### Caller: %s", caller);
! return false;
! }
! return true;
! }
!
! void G1CollectedHeap::check_bitmaps(const char* caller, HeapRegion* hr) {
! if (!G1VerifyBitmaps) return;
!
! guarantee(verify_bitmaps(caller, hr), "bitmap verification");
! }
!
! class G1VerifyBitmapClosure : public HeapRegionClosure {
! private:
! const char* _caller;
! G1CollectedHeap* _g1h;
! bool _failures;
!
! public:
! G1VerifyBitmapClosure(const char* caller, G1CollectedHeap* g1h) :
! _caller(caller), _g1h(g1h), _failures(false) { }
!
! bool failures() { return _failures; }
!
! virtual bool doHeapRegion(HeapRegion* hr) {
! if (hr->continuesHumongous()) return false;
!
! bool result = _g1h->verify_bitmaps(_caller, hr);
! if (!result) {
! _failures = true;
! }
! return false;
! }
! };
!
! void G1CollectedHeap::check_bitmaps(const char* caller) {
! if (!G1VerifyBitmaps) return;
!
! G1VerifyBitmapClosure cl(caller, this);
! heap_region_iterate(&cl);
! guarantee(!cl.failures(), "bitmap verification");
! }
! #endif // PRODUCT
void G1CollectedHeap::cleanUpCardTable() {
CardTableModRefBS* ct_bs = (CardTableModRefBS*) (barrier_set());
double start = os::elapsedTime();
*** 6259,6268 ****
--- 6358,6368 ----
HeapRegion* new_alloc_region = new_region(word_size,
false /* do_expand */);
if (new_alloc_region != NULL) {
set_region_short_lived_locked(new_alloc_region);
_hr_printer.alloc(new_alloc_region, G1HRPrinter::Eden, young_list_full);
+ check_bitmaps("Mutator Region Allocation", new_alloc_region);
return new_alloc_region;
}
}
return NULL;
}
*** 6323,6334 ****
--- 6423,6436 ----
// for survivors too.
new_alloc_region->set_saved_mark();
if (ap == GCAllocForSurvived) {
new_alloc_region->set_survivor();
_hr_printer.alloc(new_alloc_region, G1HRPrinter::Survivor);
+ check_bitmaps("Survivor Region Allocation", new_alloc_region);
} else {
_hr_printer.alloc(new_alloc_region, G1HRPrinter::Old);
+ check_bitmaps("Old Region Allocation", new_alloc_region);
}
bool during_im = g1_policy()->during_initial_mark_pause();
new_alloc_region->note_start_of_copying(during_im);
return new_alloc_region;
} else {