< prev index next >

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

Print this page

        

*** 1065,1075 **** 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 --- 1065,1076 ---- 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
*** 1503,1527 **** 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(); --- 1504,1532 ---- 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_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();
*** 1608,1621 **** } } }; 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(); --- 1613,1631 ---- } } }; 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); ! } } } void ShenandoahHeap::op_reset() { reset_mark_bitmap();
*** 1988,2035 **** // 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(); ShenandoahPhaseTimings::Phase timing_phase = full_gc ? ShenandoahPhaseTimings::full_gc_purge_par : ShenandoahPhaseTimings::purge_par; // Cleanup weak roots ShenandoahGCPhase phase(timing_phase); ! if (has_forwarded_objects()) { ! ShenandoahForwardedIsAliveClosure is_alive; ! ShenandoahUpdateRefsClosure keep_alive; ! ShenandoahParallelWeakRootsCleaningTask<ShenandoahForwardedIsAliveClosure, ShenandoahUpdateRefsClosure> ! cleaning_task(&is_alive, &keep_alive, num_workers); ! _workers->run_task(&cleaning_task); ! } else { ! ShenandoahIsAliveClosure is_alive; #ifdef ASSERT ShenandoahAssertNotForwardedClosure verify_cl; ShenandoahParallelWeakRootsCleaningTask<ShenandoahIsAliveClosure, ShenandoahAssertNotForwardedClosure> cleaning_task(&is_alive, &verify_cl, num_workers); #else ShenandoahParallelWeakRootsCleaningTask<ShenandoahIsAliveClosure, DoNothingClosure> cleaning_task(&is_alive, &do_nothing_cl, num_workers); #endif ! _workers->run_task(&cleaning_task); ! } } 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) { set_gc_state_mask(HAS_FORWARDED, cond); } --- 1998,2039 ---- // 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(); ShenandoahPhaseTimings::Phase timing_phase = full_gc ? ShenandoahPhaseTimings::full_gc_purge_par : ShenandoahPhaseTimings::purge_par; // Cleanup weak roots ShenandoahGCPhase phase(timing_phase); ! ShenandoahIsAliveClosure is_alive; #ifdef ASSERT ShenandoahAssertNotForwardedClosure verify_cl; ShenandoahParallelWeakRootsCleaningTask<ShenandoahIsAliveClosure, ShenandoahAssertNotForwardedClosure> cleaning_task(&is_alive, &verify_cl, num_workers); #else ShenandoahParallelWeakRootsCleaningTask<ShenandoahIsAliveClosure, DoNothingClosure> cleaning_task(&is_alive, &do_nothing_cl, num_workers); #endif ! _workers->run_task(&cleaning_task); } 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) { set_gc_state_mask(HAS_FORWARDED, cond); }
*** 2088,2102 **** 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) { ShenandoahHeapLocker locker(lock()); heap_region_containing(o)->make_pinned(); --- 2092,2110 ---- 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) { ShenandoahHeapLocker locker(lock()); heap_region_containing(o)->make_pinned();
*** 2110,2119 **** --- 2118,2142 ---- GCTimer* ShenandoahHeap::gc_timer() const { return _gc_timer; } + 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()) {
*** 2225,2234 **** --- 2248,2259 ---- } 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 final_work(ShenandoahPhaseTimings::final_update_refs_finish_work); // Finish updating references where we left off.
*** 2242,2252 **** 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 { --- 2267,2277 ---- 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 >