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 {