7039089: G1: changeset for 7037276 broke heap verification, and related cleanups

In G1 heap verification, we no longer scan perm to G1-collected heap refs as part of process_strong_roots() but rather in a separate explicit oop iteration over the perm gen. This preserves the original perm card-marks. Added a new assertion in younger_refs_iterate() to catch a simple subcase where the user may have forgotten a prior save_marks() call, as happened in the case of G1's attempt to iterate perm to G1 refs when verifying the heap before exit. The assert was deliberately weakened for ParNew+CMS and will be fixed for that combination in a future CR. Also made some (non-G1) cleanups related to code and comments obsoleted by the migration of Symbols to the native heap.

Reviewed-by: iveresov, jmasa, tonyp
This commit is contained in:
Y. Srinivas Ramakrishna 2011-04-26 21:17:24 -07:00
parent e3121a5a43
commit d86311b13c
8 changed files with 69 additions and 28 deletions

View file

@ -1963,10 +1963,21 @@ CompactibleFreeListSpace::gc_epilogue() {
// Iteration support, mostly delegated from a CMS generation
void CompactibleFreeListSpace::save_marks() {
// mark the "end" of the used space at the time of this call;
assert(Thread::current()->is_VM_thread(),
"Global variable should only be set when single-threaded");
// Mark the "end" of the used space at the time of this call;
// note, however, that promoted objects from this point
// on are tracked in the _promoInfo below.
set_saved_mark_word(unallocated_block());
#ifdef ASSERT
// Check the sanity of save_marks() etc.
MemRegion ur = used_region();
MemRegion urasm = used_region_at_save_marks();
assert(ur.contains(urasm),
err_msg(" Error at save_marks(): [" PTR_FORMAT "," PTR_FORMAT ")"
" should contain [" PTR_FORMAT "," PTR_FORMAT ")",
ur.start(), ur.end(), urasm.start(), urasm.end()));
#endif
// inform allocator that promotions should be tracked.
assert(_promoInfo.noPromotions(), "_promoInfo inconsistency");
_promoInfo.startTrackingPromotions();

View file

@ -3189,10 +3189,9 @@ bool ConcurrentMarkSweepGeneration::is_too_full() const {
}
void CMSCollector::setup_cms_unloading_and_verification_state() {
const bool should_verify = VerifyBeforeGC || VerifyAfterGC || VerifyDuringGC
const bool should_verify = VerifyBeforeGC || VerifyAfterGC || VerifyDuringGC
|| VerifyBeforeExit;
const int rso = SharedHeap::SO_Symbols | SharedHeap::SO_Strings
| SharedHeap::SO_CodeCache;
const int rso = SharedHeap::SO_Strings | SharedHeap::SO_CodeCache;
if (should_unload_classes()) { // Should unload classes this cycle
remove_root_scanning_option(rso); // Shrink the root set appropriately

View file

@ -2805,17 +2805,26 @@ void G1CollectedHeap::verify(bool allow_dirty,
bool silent,
bool use_prev_marking) {
if (SafepointSynchronize::is_at_safepoint() || ! UseTLAB) {
if (!silent) { gclog_or_tty->print("roots "); }
if (!silent) { gclog_or_tty->print("Roots (excluding permgen) "); }
VerifyRootsClosure rootsCl(use_prev_marking);
CodeBlobToOopClosure blobsCl(&rootsCl, /*do_marking=*/ false);
process_strong_roots(true, // activate StrongRootsScope
false,
SharedHeap::SO_AllClasses,
// We apply the relevant closures to all the oops in the
// system dictionary, the string table and the code cache.
const int so = SharedHeap::SO_AllClasses | SharedHeap::SO_Strings | SharedHeap::SO_CodeCache;
process_strong_roots(true, // activate StrongRootsScope
true, // we set "collecting perm gen" to true,
// so we don't reset the dirty cards in the perm gen.
SharedHeap::ScanningOption(so), // roots scanning options
&rootsCl,
&blobsCl,
&rootsCl);
// Since we used "collecting_perm_gen" == true above, we will not have
// checked the refs from perm into the G1-collected heap. We check those
// references explicitly below. Whether the relevant cards are dirty
// is checked further below in the rem set verification.
if (!silent) { gclog_or_tty->print("Permgen roots "); }
perm_gen()->oop_iterate(&rootsCl);
bool failures = rootsCl.failures();
rem_set()->invalidate(perm_gen()->used_region(), false);
if (!silent) { gclog_or_tty->print("HeapRegionSets "); }
verify_region_sets();
if (!silent) { gclog_or_tty->print("HeapRegions "); }