< prev index next >

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

Print this page

        

*** 1072,1082 **** 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 --- 1072,1083 ---- 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(), ! !ShenandoahConcurrentRoots::should_do_concurrent_class_unloading()); ShenandoahEvacuateUpdateRootsTask roots_task(&rp); workers()->run_task(&roots_task); } #if COMPILER2_OR_JVMCI
*** 1549,1573 **** set_evacuation_in_progress(true); // From here on, we need to update references. set_has_forwarded_objects(true); if (!is_degenerated_gc_in_progress()) { evacuate_and_update_roots(); } if (ShenandoahPacing) { pacer()->setup_for_evac(); } if (ShenandoahVerify) { if (ShenandoahConcurrentRoots::should_do_concurrent_roots()) { ! ShenandoahRootVerifier::RootTypes types = ShenandoahRootVerifier::combine(ShenandoahRootVerifier::JNIHandleRoots, ShenandoahRootVerifier::WeakRoots); types = ShenandoahRootVerifier::combine(types, ShenandoahRootVerifier::CLDGRoots); - verifier()->verify_roots_no_forwarded_except(types); - } else { - verifier()->verify_roots_no_forwarded(); } verifier()->verify_during_evacuation(); } } else { if (ShenandoahVerify) { verifier()->verify_after_concmark(); --- 1550,1579 ---- set_evacuation_in_progress(true); // From here on, we need to update references. set_has_forwarded_objects(true); if (!is_degenerated_gc_in_progress()) { + prepare_concurrent_roots(); + prepare_concurrent_unloading(); evacuate_and_update_roots(); } if (ShenandoahPacing) { pacer()->setup_for_evac(); } if (ShenandoahVerify) { + ShenandoahRootVerifier::RootTypes types = ShenandoahRootVerifier::None; if (ShenandoahConcurrentRoots::should_do_concurrent_roots()) { ! types = ShenandoahRootVerifier::combine(ShenandoahRootVerifier::JNIHandleRoots, ShenandoahRootVerifier::WeakRoots); types = ShenandoahRootVerifier::combine(types, ShenandoahRootVerifier::CLDGRoots); } + + if (ShenandoahConcurrentRoots::should_do_concurrent_class_unloading()) { + types = ShenandoahRootVerifier::combine(types, ShenandoahRootVerifier::CodeRoots); + } + verifier()->verify_roots_no_forwarded_except(types); verifier()->verify_during_evacuation(); } } else { if (ShenandoahVerify) { verifier()->verify_after_concmark();
*** 1659,1673 **** } } }; 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(); } --- 1665,1686 ---- } } }; void ShenandoahHeap::op_roots() { ! if (is_evacuation_in_progress()) { ! if (ShenandoahConcurrentRoots::should_do_concurrent_class_unloading()) { ! _unloader.unload(); ! } ! ! if (ShenandoahConcurrentRoots::should_do_concurrent_roots()) { ! ShenandoahConcurrentRootsEvacUpdateTask task; ! workers()->run_task(&task); ! } } + + set_concurrent_root_in_progress(false); } void ShenandoahHeap::op_reset() { reset_mark_bitmap(); }
*** 1921,1930 **** --- 1934,1952 ---- void ShenandoahHeap::set_evacuation_in_progress(bool in_progress) { assert(ShenandoahSafepoint::is_at_shenandoah_safepoint(), "Only call this at safepoint"); set_gc_state_mask(EVACUATION, in_progress); } + void ShenandoahHeap::set_concurrent_root_in_progress(bool in_progress) { + assert(ShenandoahConcurrentRoots::can_do_concurrent_roots(), "Why set the flag?"); + if (in_progress) { + _concurrent_root_in_progress.set(); + } else { + _concurrent_root_in_progress.unset(); + } + } + void ShenandoahHeap::ref_processing_init() { assert(_max_workers > 0, "Sanity"); _ref_processor = new ReferenceProcessor(&_subject_to_discovery, // is_subject_to_discovery
*** 2029,2042 **** // Resize and verify metaspace MetaspaceGC::compute_new_size(); MetaspaceUtils::verify_metrics(); } ! // Process leftover weak oops: update them, if needed or assert they do not ! // need updating otherwise. ! // Weak processor API requires us to visit the oops, even if we are not doing ! // anything to them. void ShenandoahHeap::stw_process_weak_roots(bool full_gc) { ShenandoahGCPhase root_phase(full_gc ? ShenandoahPhaseTimings::full_gc_purge : ShenandoahPhaseTimings::purge); uint num_workers = _workers->active_workers(); --- 2051,2064 ---- // Resize and verify metaspace MetaspaceGC::compute_new_size(); MetaspaceUtils::verify_metrics(); } ! // Weak roots are either pre-evacuated (final mark) or updated (final updaterefs), ! // so they should not have forwarded oops. ! // However, we do need to "null" dead oops in the roots, if can not be done ! // in concurrent cycles. void ShenandoahHeap::stw_process_weak_roots(bool full_gc) { ShenandoahGCPhase root_phase(full_gc ? ShenandoahPhaseTimings::full_gc_purge : ShenandoahPhaseTimings::purge); uint num_workers = _workers->active_workers();
*** 2074,2084 **** } void ShenandoahHeap::parallel_cleaning(bool full_gc) { assert(SafepointSynchronize::is_at_safepoint(), "Must be at a safepoint"); stw_process_weak_roots(full_gc); ! stw_unload_classes(full_gc); } void ShenandoahHeap::set_has_forwarded_objects(bool cond) { if (is_traversal_mode()) { set_gc_state_mask(HAS_FORWARDED | UPDATEREFS, cond); --- 2096,2108 ---- } void ShenandoahHeap::parallel_cleaning(bool full_gc) { assert(SafepointSynchronize::is_at_safepoint(), "Must be at a safepoint"); stw_process_weak_roots(full_gc); ! if (!ShenandoahConcurrentRoots::should_do_concurrent_class_unloading()) { ! stw_unload_classes(full_gc); ! } } void ShenandoahHeap::set_has_forwarded_objects(bool cond) { if (is_traversal_mode()) { set_gc_state_mask(HAS_FORWARDED | UPDATEREFS, cond);
*** 2142,2156 **** void ShenandoahHeap::set_update_refs_in_progress(bool in_progress) { set_gc_state_mask(UPDATEREFS, in_progress); } void ShenandoahHeap::register_nmethod(nmethod* nm) { ! ShenandoahCodeRoots::add_nmethod(nm); } void ShenandoahHeap::unregister_nmethod(nmethod* nm) { ! ShenandoahCodeRoots::remove_nmethod(nm); } oop ShenandoahHeap::pin_object(JavaThread* thr, oop o) { heap_region_containing(o)->record_pin(); return o; --- 2166,2184 ---- void ShenandoahHeap::set_update_refs_in_progress(bool in_progress) { set_gc_state_mask(UPDATEREFS, in_progress); } void ShenandoahHeap::register_nmethod(nmethod* nm) { ! ShenandoahCodeRoots::register_nmethod(nm); } void ShenandoahHeap::unregister_nmethod(nmethod* nm) { ! ShenandoahCodeRoots::unregister_nmethod(nm); ! } ! ! void ShenandoahHeap::flush_nmethod(nmethod* nm) { ! ShenandoahCodeRoots::flush_nmethod(nm); } oop ShenandoahHeap::pin_object(JavaThread* thr, oop o) { heap_region_containing(o)->record_pin(); return o;
*** 2193,2202 **** --- 2221,2252 ---- GCTimer* ShenandoahHeap::gc_timer() const { return _gc_timer; } + void ShenandoahHeap::prepare_concurrent_roots() { + assert(SafepointSynchronize::is_at_safepoint(), "Must be at a safepoint"); + if (ShenandoahConcurrentRoots::should_do_concurrent_roots()) { + set_concurrent_root_in_progress(true); + } + } + + void ShenandoahHeap::prepare_concurrent_unloading() { + assert(SafepointSynchronize::is_at_safepoint(), "Must be at a safepoint"); + if (ShenandoahConcurrentRoots::should_do_concurrent_class_unloading()) { + ShenandoahCodeRoots::prepare_concurrent_unloading(); + _unloader.prepare(); + } + } + + void ShenandoahHeap::finish_concurrent_unloading() { + assert(SafepointSynchronize::is_at_safepoint(), "Must be at a safepoint"); + if (ShenandoahConcurrentRoots::should_do_concurrent_class_unloading()) { + _unloader.finish(); + } + } + #ifdef ASSERT void ShenandoahHeap::assert_gc_workers(uint nworkers) { assert(nworkers > 0 && nworkers <= max_workers(), "Sanity"); if (ShenandoahSafepoint::is_at_shenandoah_safepoint()) {
*** 2316,2325 **** --- 2366,2377 ---- } void ShenandoahHeap::op_final_updaterefs() { assert(ShenandoahSafepoint::is_at_shenandoah_safepoint(), "must be at safepoint"); + finish_concurrent_unloading(); + // Check if there is left-over work, and finish it if (_update_refs_iterator.has_next()) { ShenandoahGCPhase phase(ShenandoahPhaseTimings::final_update_refs_finish_work); // Finish updating references where we left off.
*** 2333,2343 **** clear_cancelled_gc(); } assert(!cancelled_gc(), "Should have been done right before"); if (ShenandoahVerify && !is_degenerated_gc_in_progress()) { ! verifier()->verify_roots_no_forwarded_except(ShenandoahRootVerifier::ThreadRoots); } if (is_degenerated_gc_in_progress()) { concurrent_mark()->update_roots(ShenandoahPhaseTimings::degen_gc_update_roots); } else { --- 2385,2395 ---- clear_cancelled_gc(); } assert(!cancelled_gc(), "Should have been done right before"); if (ShenandoahVerify && !is_degenerated_gc_in_progress()) { ! verifier()->verify_roots_in_to_space_except(ShenandoahRootVerifier::ThreadRoots); } if (is_degenerated_gc_in_progress()) { concurrent_mark()->update_roots(ShenandoahPhaseTimings::degen_gc_update_roots); } else {
< prev index next >