src/share/vm/gc/g1/g1MarkSweep.cpp

Print this page

        

*** 67,193 **** if (G1CollectedHeap::heap()->collector_policy()->should_clear_all_soft_refs()) { assert(clear_all_softrefs, "Policy should have been checked earler"); } #endif // hook up weak ref data so it can be used during Mark-Sweep - assert(GenMarkSweep::ref_processor() == NULL, "no stomping"); assert(rp != NULL, "should be non-NULL"); assert(rp == G1CollectedHeap::heap()->ref_processor_stw(), "Precondition"); ! GenMarkSweep::set_ref_processor(rp); rp->setup_policy(clear_all_softrefs); // When collecting the permanent generation Method*s may be moving, // so we either have to flush all bcp data or convert it into bci. CodeCache::gc_prologue(); bool marked_for_unloading = false; ! allocate_stacks(); // We should save the marks of the currently locked biased monitors. // The marking doesn't preserve the marks of biased objects. BiasedLocking::preserve_marks(); ! mark_sweep_phase1(marked_for_unloading, clear_all_softrefs); ! mark_sweep_phase2(); #if defined(COMPILER2) || INCLUDE_JVMCI // Don't add any more derived pointers during phase3 DerivedPointerTable::set_active(false); #endif ! mark_sweep_phase3(); ! mark_sweep_phase4(); ! GenMarkSweep::restore_marks(); BiasedLocking::restore_marks(); ! GenMarkSweep::deallocate_stacks(); CodeCache::gc_epilogue(); JvmtiExport::gc_epilogue(); // refs processing: clean slate ! GenMarkSweep::set_ref_processor(NULL); } ! void G1MarkSweep::allocate_stacks() { ! GenMarkSweep::_preserved_count_max = 0; ! GenMarkSweep::_preserved_marks = NULL; ! GenMarkSweep::_preserved_count = 0; } ! void G1MarkSweep::mark_sweep_phase1(bool& marked_for_unloading, bool clear_all_softrefs) { // Recursively traverse all live objects and mark them GCTraceTime(Info, gc, phases) tm("Phase 1: Mark live objects", gc_timer()); G1CollectedHeap* g1h = G1CollectedHeap::heap(); // Need cleared claim bits for the roots processing ClassLoaderDataGraph::clear_claimed_marks(); ! MarkingCodeBlobClosure follow_code_closure(&GenMarkSweep::follow_root_closure, !CodeBlobToOopClosure::FixRelocations); { G1RootProcessor root_processor(g1h, 1); if (ClassUnloading) { ! root_processor.process_strong_roots(&GenMarkSweep::follow_root_closure, ! &GenMarkSweep::follow_cld_closure, &follow_code_closure); } else { root_processor.process_all_roots_no_string_table( ! &GenMarkSweep::follow_root_closure, ! &GenMarkSweep::follow_cld_closure, &follow_code_closure); } } { GCTraceTime(Debug, gc, phases) trace("Reference Processing", gc_timer()); // Process reference objects found during marking ! ReferenceProcessor* rp = GenMarkSweep::ref_processor(); assert(rp == g1h->ref_processor_stw(), "Sanity"); rp->setup_policy(clear_all_softrefs); const ReferenceProcessorStats& stats = ! rp->process_discovered_references(&GenMarkSweep::is_alive, ! &GenMarkSweep::keep_alive, ! &GenMarkSweep::follow_stack_closure, NULL, gc_timer()); gc_tracer()->report_gc_reference_stats(stats); } // This is the point where the entire marking should have completed. ! assert(GenMarkSweep::_marking_stack.is_empty(), "Marking should have completed"); if (ClassUnloading) { GCTraceTime(Debug, gc, phases) trace("Class Unloading", gc_timer()); // Unload classes and purge the SystemDictionary. ! bool purged_class = SystemDictionary::do_unloading(&GenMarkSweep::is_alive); // Unload nmethods. ! CodeCache::do_unloading(&GenMarkSweep::is_alive, purged_class); // Prune dead klasses from subklass/sibling/implementor lists. ! Klass::clean_weak_klass_links(&GenMarkSweep::is_alive); } { GCTraceTime(Debug, gc, phases) trace("Scrub String and Symbol Tables", gc_timer()); // Delete entries for dead interned string and clean up unreferenced symbols in symbol table. ! g1h->unlink_string_and_symbol_table(&GenMarkSweep::is_alive); } if (G1StringDedup::is_enabled()) { GCTraceTime(Debug, gc, phases) trace("String Deduplication Unlink", gc_timer()); ! G1StringDedup::unlink(&GenMarkSweep::is_alive); } if (VerifyDuringGC) { HandleMark hm; // handle scope #if defined(COMPILER2) || INCLUDE_JVMCI --- 67,193 ---- if (G1CollectedHeap::heap()->collector_policy()->should_clear_all_soft_refs()) { assert(clear_all_softrefs, "Policy should have been checked earler"); } #endif // hook up weak ref data so it can be used during Mark-Sweep assert(rp != NULL, "should be non-NULL"); assert(rp == G1CollectedHeap::heap()->ref_processor_stw(), "Precondition"); ! GenMarkSweep gms; ! gms.set_ref_processor(rp); rp->setup_policy(clear_all_softrefs); // When collecting the permanent generation Method*s may be moving, // so we either have to flush all bcp data or convert it into bci. CodeCache::gc_prologue(); bool marked_for_unloading = false; ! allocate_stacks(&gms); // We should save the marks of the currently locked biased monitors. // The marking doesn't preserve the marks of biased objects. BiasedLocking::preserve_marks(); ! mark_sweep_phase1(&gms, marked_for_unloading, clear_all_softrefs); ! mark_sweep_phase2(&gms); #if defined(COMPILER2) || INCLUDE_JVMCI // Don't add any more derived pointers during phase3 DerivedPointerTable::set_active(false); #endif ! mark_sweep_phase3(&gms); ! mark_sweep_phase4(&gms); ! gms.restore_marks(); BiasedLocking::restore_marks(); ! gms.deallocate_stacks(); CodeCache::gc_epilogue(); JvmtiExport::gc_epilogue(); // refs processing: clean slate ! gms.set_ref_processor(NULL); } ! void G1MarkSweep::allocate_stacks(GenMarkSweep* gms) { ! gms->_preserved_count_max = 0; ! gms->_preserved_marks = NULL; ! gms->_preserved_count = 0; } ! void G1MarkSweep::mark_sweep_phase1(GenMarkSweep* gms, bool& marked_for_unloading, bool clear_all_softrefs) { // Recursively traverse all live objects and mark them GCTraceTime(Info, gc, phases) tm("Phase 1: Mark live objects", gc_timer()); G1CollectedHeap* g1h = G1CollectedHeap::heap(); // Need cleared claim bits for the roots processing ClassLoaderDataGraph::clear_claimed_marks(); ! MarkingCodeBlobClosure follow_code_closure(&gms->follow_root_closure, !CodeBlobToOopClosure::FixRelocations); { G1RootProcessor root_processor(g1h, 1); if (ClassUnloading) { ! root_processor.process_strong_roots(&gms->follow_root_closure, ! &gms->follow_cld_closure, &follow_code_closure); } else { root_processor.process_all_roots_no_string_table( ! &gms->follow_root_closure, ! &gms->follow_cld_closure, &follow_code_closure); } } { GCTraceTime(Debug, gc, phases) trace("Reference Processing", gc_timer()); // Process reference objects found during marking ! ReferenceProcessor* rp = gms->ref_processor(); assert(rp == g1h->ref_processor_stw(), "Sanity"); rp->setup_policy(clear_all_softrefs); const ReferenceProcessorStats& stats = ! rp->process_discovered_references(&gms->is_alive, ! &gms->keep_alive, ! &gms->follow_stack_closure, NULL, gc_timer()); gc_tracer()->report_gc_reference_stats(stats); } // This is the point where the entire marking should have completed. ! assert(gms->_marking_stack.is_empty(), "Marking should have completed"); if (ClassUnloading) { GCTraceTime(Debug, gc, phases) trace("Class Unloading", gc_timer()); // Unload classes and purge the SystemDictionary. ! bool purged_class = SystemDictionary::do_unloading(&gms->is_alive); // Unload nmethods. ! CodeCache::do_unloading(&gms->is_alive, purged_class); // Prune dead klasses from subklass/sibling/implementor lists. ! Klass::clean_weak_klass_links(&gms->is_alive); } { GCTraceTime(Debug, gc, phases) trace("Scrub String and Symbol Tables", gc_timer()); // Delete entries for dead interned string and clean up unreferenced symbols in symbol table. ! g1h->unlink_string_and_symbol_table(&gms->is_alive); } if (G1StringDedup::is_enabled()) { GCTraceTime(Debug, gc, phases) trace("String Deduplication Unlink", gc_timer()); ! G1StringDedup::unlink(&gms->is_alive); } if (VerifyDuringGC) { HandleMark hm; // handle scope #if defined(COMPILER2) || INCLUDE_JVMCI
*** 206,220 **** // objects. GCTraceTime(Info, gc, verify)("During GC (full)"); g1h->verify(VerifyOption_G1UseMarkWord); } ! gc_tracer()->report_object_count_after_gc(&GenMarkSweep::is_alive); } ! void G1MarkSweep::mark_sweep_phase2() { // Now all live objects are marked, compute the new object addresses. // It is not required that we traverse spaces in the same order in // phase2, phase3 and phase4, but the ValidateMarkSweep live oops // tracking expects us to do so. See comment under phase4. --- 206,220 ---- // objects. GCTraceTime(Info, gc, verify)("During GC (full)"); g1h->verify(VerifyOption_G1UseMarkWord); } ! gc_tracer()->report_object_count_after_gc(&gms->is_alive); } ! void G1MarkSweep::mark_sweep_phase2(GenMarkSweep* /* gms */) { // Now all live objects are marked, compute the new object addresses. // It is not required that we traverse spaces in the same order in // phase2, phase3 and phase4, but the ValidateMarkSweep live oops // tracking expects us to do so. See comment under phase4.
*** 223,280 **** prepare_compaction(); } class G1AdjustPointersClosure: public HeapRegionClosure { public: bool doHeapRegion(HeapRegion* r) { if (r->is_humongous()) { if (r->is_starts_humongous()) { // We must adjust the pointers on the single H object. oop obj = oop(r->bottom()); // point all the oops to the new location ! MarkSweep::adjust_pointers(obj); } } else if (!r->is_pinned()) { // This really ought to be "as_CompactibleSpace"... ! r->adjust_pointers(); } return false; } }; ! void G1MarkSweep::mark_sweep_phase3() { G1CollectedHeap* g1h = G1CollectedHeap::heap(); // Adjust the pointers to reflect the new locations GCTraceTime(Info, gc, phases) tm("Phase 3: Adjust pointers", gc_timer()); // Need cleared claim bits for the roots processing ClassLoaderDataGraph::clear_claimed_marks(); ! CodeBlobToOopClosure adjust_code_closure(&GenMarkSweep::adjust_pointer_closure, CodeBlobToOopClosure::FixRelocations); { G1RootProcessor root_processor(g1h, 1); ! root_processor.process_all_roots(&GenMarkSweep::adjust_pointer_closure, ! &GenMarkSweep::adjust_cld_closure, &adjust_code_closure); } ! assert(GenMarkSweep::ref_processor() == g1h->ref_processor_stw(), "Sanity"); ! g1h->ref_processor_stw()->weak_oops_do(&GenMarkSweep::adjust_pointer_closure); // Now adjust pointers in remaining weak roots. (All of which should // have been cleared if they pointed to non-surviving objects.) ! JNIHandles::weak_oops_do(&GenMarkSweep::adjust_pointer_closure); if (G1StringDedup::is_enabled()) { ! G1StringDedup::oops_do(&GenMarkSweep::adjust_pointer_closure); } ! GenMarkSweep::adjust_marks(); ! G1AdjustPointersClosure blk; g1h->heap_region_iterate(&blk); } class G1SpaceCompactClosure: public HeapRegionClosure { public: --- 223,282 ---- prepare_compaction(); } class G1AdjustPointersClosure: public HeapRegionClosure { + MarkSweep* _ms; public: + G1AdjustPointersClosure(MarkSweep* ms) : _ms(ms) {} bool doHeapRegion(HeapRegion* r) { if (r->is_humongous()) { if (r->is_starts_humongous()) { // We must adjust the pointers on the single H object. oop obj = oop(r->bottom()); // point all the oops to the new location ! _ms->adjust_pointers(obj); } } else if (!r->is_pinned()) { // This really ought to be "as_CompactibleSpace"... ! r->adjust_pointers(_ms); } return false; } }; ! void G1MarkSweep::mark_sweep_phase3(GenMarkSweep* gms) { G1CollectedHeap* g1h = G1CollectedHeap::heap(); // Adjust the pointers to reflect the new locations GCTraceTime(Info, gc, phases) tm("Phase 3: Adjust pointers", gc_timer()); // Need cleared claim bits for the roots processing ClassLoaderDataGraph::clear_claimed_marks(); ! CodeBlobToOopClosure adjust_code_closure(&gms->adjust_pointer_closure, CodeBlobToOopClosure::FixRelocations); { G1RootProcessor root_processor(g1h, 1); ! root_processor.process_all_roots(&gms->adjust_pointer_closure, ! &gms->adjust_cld_closure, &adjust_code_closure); } ! assert(gms->ref_processor() == g1h->ref_processor_stw(), "Sanity"); ! g1h->ref_processor_stw()->weak_oops_do(&gms->adjust_pointer_closure); // Now adjust pointers in remaining weak roots. (All of which should // have been cleared if they pointed to non-surviving objects.) ! JNIHandles::weak_oops_do(&gms->adjust_pointer_closure); if (G1StringDedup::is_enabled()) { ! G1StringDedup::oops_do(&gms->adjust_pointer_closure); } ! gms->adjust_marks(); ! G1AdjustPointersClosure blk(gms); g1h->heap_region_iterate(&blk); } class G1SpaceCompactClosure: public HeapRegionClosure { public:
*** 296,306 **** } return false; } }; ! void G1MarkSweep::mark_sweep_phase4() { // All pointers are now adjusted, move objects accordingly // The ValidateMarkSweep live oops tracking expects us to traverse spaces // in the same order in phase2, phase3 and phase4. We don't quite do that // here (code and comment not fixed for perm removal), so we tell the validate code --- 298,308 ---- } return false; } }; ! void G1MarkSweep::mark_sweep_phase4(GenMarkSweep* /* gms */) { // All pointers are now adjusted, move objects accordingly // The ValidateMarkSweep live oops tracking expects us to traverse spaces // in the same order in phase2, phase3 and phase4. We don't quite do that // here (code and comment not fixed for perm removal), so we tell the validate code