< prev index next >

src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp

Print this page

        

*** 36,46 **** #include "gc/shenandoah/shenandoahBarrierSet.hpp" #include "gc/shenandoah/shenandoahClosures.inline.hpp" #include "gc/shenandoah/shenandoahCollectionSet.hpp" #include "gc/shenandoah/shenandoahCollectorPolicy.hpp" #include "gc/shenandoah/shenandoahConcurrentMark.inline.hpp" - #include "gc/shenandoah/shenandoahConcurrentRoots.hpp" #include "gc/shenandoah/shenandoahControlThread.hpp" #include "gc/shenandoah/shenandoahFreeSet.hpp" #include "gc/shenandoah/shenandoahPhaseTimings.hpp" #include "gc/shenandoah/shenandoahHeap.inline.hpp" #include "gc/shenandoah/shenandoahHeapRegion.hpp" --- 36,45 ----
*** 1066,1089 **** _rp->roots_do(worker_id, &cl); } }; void ShenandoahHeap::evacuate_and_update_roots() { ! #if COMPILER2_OR_JVMCI DerivedPointerTable::clear(); #endif assert(ShenandoahSafepoint::is_at_shenandoah_safepoint(), "Only iterate roots while world is stopped"); { ! // Include concurrent roots if current cycle can not process those roots concurrently ! ShenandoahRootEvacuator rp(workers()->active_workers(), ! ShenandoahPhaseTimings::init_evac, ! !ShenandoahConcurrentRoots::should_do_concurrent_roots()); ShenandoahEvacuateUpdateRootsTask roots_task(&rp); workers()->run_task(&roots_task); } ! #if COMPILER2_OR_JVMCI DerivedPointerTable::update_pointers(); #endif } // Returns size in bytes --- 1065,1086 ---- _rp->roots_do(worker_id, &cl); } }; void ShenandoahHeap::evacuate_and_update_roots() { ! #if defined(COMPILER2) || INCLUDE_JVMCI DerivedPointerTable::clear(); #endif assert(ShenandoahSafepoint::is_at_shenandoah_safepoint(), "Only iterate roots while world is stopped"); + { ! ShenandoahRootEvacuator rp(workers()->active_workers(), ShenandoahPhaseTimings::init_evac); ShenandoahEvacuateUpdateRootsTask roots_task(&rp); workers()->run_task(&roots_task); } ! #if defined(COMPILER2) || INCLUDE_JVMCI DerivedPointerTable::update_pointers(); #endif } // Returns size in bytes
*** 1277,1295 **** // Reset bitmap _aux_bit_map.clear(); Stack<oop,mtGC> oop_stack; ! // First, we process GC roots according to current GC cycle. This populates the work stack with initial objects. ! ShenandoahHeapIterationRootScanner rp; ObjectIterateScanRootClosure oops(&_aux_bit_map, &oop_stack); ! ! if (unload_classes()) { ! rp.strong_roots_do(&oops); ! } else { ! rp.roots_do(&oops); ! } // Work through the oop stack to traverse heap. while (! oop_stack.is_empty()) { oop obj = oop_stack.pop(); assert(oopDesc::is_oop(obj), "must be a valid oop"); --- 1274,1287 ---- // Reset bitmap _aux_bit_map.clear(); Stack<oop,mtGC> oop_stack; ! // First, we process all GC roots. This populates the work stack with initial objects. ! ShenandoahAllRootScanner rp(1, ShenandoahPhaseTimings::_num_phases); ObjectIterateScanRootClosure oops(&_aux_bit_map, &oop_stack); ! rp.roots_do(0, &oops); // Work through the oop stack to traverse heap. while (! oop_stack.is_empty()) { oop obj = oop_stack.pop(); assert(oopDesc::is_oop(obj), "must be a valid oop");
*** 1518,1532 **** if (ShenandoahPacing) { pacer()->setup_for_evac(); } if (ShenandoahVerify) { ! if (ShenandoahConcurrentRoots::should_do_concurrent_roots()) { ! verifier()->verify_roots_no_forwarded_except(ShenandoahRootVerifier::JNIHandleRoots); ! } else { ! verifier()->verify_roots_no_forwarded(); ! } verifier()->verify_during_evacuation(); } } else { if (ShenandoahVerify) { verifier()->verify_after_concmark(); --- 1510,1520 ---- if (ShenandoahPacing) { pacer()->setup_for_evac(); } if (ShenandoahVerify) { ! verifier()->verify_roots_no_forwarded(); verifier()->verify_during_evacuation(); } } else { if (ShenandoahVerify) { verifier()->verify_after_concmark();
*** 1583,1616 **** void ShenandoahHeap::op_cleanup() { free_set()->recycle_trash(); } - class ShenandoahConcurrentRootsEvacUpdateTask : public AbstractGangTask { - private: - ShenandoahJNIHandleRoots<true /*concurrent*/> _jni_roots; - - public: - ShenandoahConcurrentRootsEvacUpdateTask() : - AbstractGangTask("Shenandoah Evacuate/Update Concurrent Roots Task") { - } - - void work(uint worker_id) { - ShenandoahEvacOOMScope oom; - ShenandoahEvacuateUpdateRootsClosure cl; - _jni_roots.oops_do<ShenandoahEvacuateUpdateRootsClosure>(&cl); - } - }; - - void ShenandoahHeap::op_roots() { - if (is_evacuation_in_progress() && - ShenandoahConcurrentRoots::should_do_concurrent_roots()) { - ShenandoahConcurrentRootsEvacUpdateTask task; - workers()->run_task(&task); - } - } - void ShenandoahHeap::op_reset() { reset_mark_bitmap(); } void ShenandoahHeap::op_preclean() { --- 1571,1580 ----
*** 1638,1649 **** ShenandoahGCPhase phase(ShenandoahPhaseTimings::full_gc_resize_tlabs); resize_all_tlabs(); } metrics.snap_after(); ! if (metrics.is_good_progress()) { _progress_last_gc.set(); } else { // Nothing to do. Tell the allocation path that we have failed to make // progress, and it can finally fail. _progress_last_gc.unset(); --- 1602,1614 ---- ShenandoahGCPhase phase(ShenandoahPhaseTimings::full_gc_resize_tlabs); resize_all_tlabs(); } metrics.snap_after(); + metrics.print(); ! if (metrics.is_good_progress("Full GC")) { _progress_last_gc.set(); } else { // Nothing to do. Tell the allocation path that we have failed to make // progress, and it can finally fail. _progress_last_gc.unset();
*** 1728,1759 **** // collection set un-evacuated. Restart evacuation from the beginning to // capture all objects. For all the objects that are already evacuated, // it would be a simple check, which is supposed to be fast. This is also // safe to do even without degeneration, as CSet iterator is at beginning // in preparation for evacuation anyway. ! // ! // Before doing that, we need to make sure we never had any cset-pinned ! // regions. This may happen if allocation failure happened when evacuating ! // the about-to-be-pinned object, oom-evac protocol left the object in ! // the collection set, and then the pin reached the cset region. If we continue ! // the cycle here, we would trash the cset and alive objects in it. To avoid ! // it, we fail degeneration right away and slide into Full GC to recover. ! ! { ! collection_set()->clear_current_index(); ! ! ShenandoahHeapRegion* r; ! while ((r = collection_set()->next()) != NULL) { ! if (r->is_pinned()) { ! cancel_gc(GCCause::_shenandoah_upgrade_to_full_gc); ! op_degenerated_fail(); ! return; ! } ! } ! ! collection_set()->clear_current_index(); ! } op_stw_evac(); if (cancelled_gc()) { op_degenerated_fail(); return; --- 1693,1703 ---- // collection set un-evacuated. Restart evacuation from the beginning to // capture all objects. For all the objects that are already evacuated, // it would be a simple check, which is supposed to be fast. This is also // safe to do even without degeneration, as CSet iterator is at beginning // in preparation for evacuation anyway. ! collection_set()->clear_current_index(); op_stw_evac(); if (cancelled_gc()) { op_degenerated_fail(); return;
*** 1793,1806 **** if (VerifyAfterGC) { Universe::verify(); } metrics.snap_after(); // Check for futility and fail. There is no reason to do several back-to-back Degenerated cycles, // because that probably means the heap is overloaded and/or fragmented. ! if (!metrics.is_good_progress()) { _progress_last_gc.unset(); cancel_gc(GCCause::_shenandoah_upgrade_to_full_gc); op_degenerated_futile(); } else { _progress_last_gc.set(); --- 1737,1751 ---- if (VerifyAfterGC) { Universe::verify(); } metrics.snap_after(); + metrics.print(); // Check for futility and fail. There is no reason to do several back-to-back Degenerated cycles, // because that probably means the heap is overloaded and/or fragmented. ! if (!metrics.is_good_progress("Degenerated GC")) { _progress_last_gc.unset(); cancel_gc(GCCause::_shenandoah_upgrade_to_full_gc); op_degenerated_futile(); } else { _progress_last_gc.set();
*** 2207,2228 **** concurrent_mark()->update_roots(ShenandoahPhaseTimings::degen_gc_update_roots); } else { concurrent_mark()->update_thread_roots(ShenandoahPhaseTimings::final_update_refs_roots); } - // Has to be done before cset is clear - if (ShenandoahVerify) { - verifier()->verify_roots_in_to_space(); - } - ShenandoahGCPhase final_update_refs(ShenandoahPhaseTimings::final_update_refs_recycle); trash_cset_regions(); set_has_forwarded_objects(false); set_update_refs_in_progress(false); if (ShenandoahVerify) { verifier()->verify_after_updaterefs(); } if (VerifyAfterGC) { Universe::verify(); --- 2152,2169 ---- concurrent_mark()->update_roots(ShenandoahPhaseTimings::degen_gc_update_roots); } else { concurrent_mark()->update_thread_roots(ShenandoahPhaseTimings::final_update_refs_roots); } ShenandoahGCPhase final_update_refs(ShenandoahPhaseTimings::final_update_refs_recycle); trash_cset_regions(); set_has_forwarded_objects(false); set_update_refs_in_progress(false); if (ShenandoahVerify) { + verifier()->verify_roots_no_forwarded(); verifier()->verify_after_updaterefs(); } if (VerifyAfterGC) { Universe::verify();
*** 2588,2613 **** "concurrent reference update"); try_inject_alloc_failure(); op_updaterefs(); } - - void ShenandoahHeap::entry_roots() { - ShenandoahGCPhase phase(ShenandoahPhaseTimings::conc_roots); - - static const char* msg = "Concurrent roots processing"; - GCTraceTime(Info, gc) time(msg, NULL, GCCause::_no_gc, true); - EventMark em("%s", msg); - - ShenandoahWorkerScope scope(workers(), - ShenandoahWorkerPolicy::calc_workers_for_conc_root_processing(), - "concurrent root processing"); - - try_inject_alloc_failure(); - op_roots(); - } - void ShenandoahHeap::entry_cleanup() { ShenandoahGCPhase phase(ShenandoahPhaseTimings::conc_cleanup); static const char* msg = "Concurrent cleanup"; GCTraceTime(Info, gc) time(msg, NULL, GCCause::_no_gc, true); --- 2529,2538 ----
< prev index next >