--- old/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp 2019-06-15 08:29:42.246029018 -0400 +++ new/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp 2019-06-15 08:29:41.904028866 -0400 @@ -38,6 +38,7 @@ #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" @@ -1071,9 +1072,11 @@ DerivedPointerTable::clear(); #endif assert(ShenandoahSafepoint::is_at_shenandoah_safepoint(), "Only iterate roots while world is stopped"); - { - ShenandoahRootEvacuator rp(workers()->active_workers(), ShenandoahPhaseTimings::init_evac); + // Include concurrent roots if current cycle can not process those roots concurrently + bool include_concurrent_roots = !ShenandoahConcurrentRoots::should_do_concurrent_roots(); + + ShenandoahRootEvacuator rp(workers()->active_workers(), ShenandoahPhaseTimings::init_evac, include_concurrent_roots); ShenandoahEvacuateUpdateRootsTask roots_task(&rp); workers()->run_task(&roots_task); } @@ -1517,7 +1520,12 @@ } if (ShenandoahVerify) { - verifier()->verify_roots_no_forwarded(); + if (ShenandoahConcurrentRoots::should_do_concurrent_roots()) { + ShenandoahRootVerifier::RootTypes types = ShenandoahRootVerifier::combine(ShenandoahRootVerifier::JNIHandleRoots, ShenandoahRootVerifier::CLDGRoots); + verifier()->verify_roots_no_forwarded_except(types); + } else { + verifier()->verify_roots_no_forwarded(); + } verifier()->verify_during_evacuation(); } } else { @@ -1578,6 +1586,34 @@ free_set()->recycle_trash(); } +class ShenandoahConcurrentRootsEvacUpdateTask : public AbstractGangTask { +private: + SuspendibleThreadSetJoiner _sts_joiner; + ShenandoahJNIHandleRoots _jni_roots; + ShenandoahClassLoaderDataRoots _cld_roots; +public: + ShenandoahConcurrentRootsEvacUpdateTask() : + AbstractGangTask("Shenandoah Evacuate/Update Concurrent Roots Task") { + } + + void work(uint worker_id) { + ShenandoahEvacOOMScope oom; + ShenandoahEvacuateUpdateRootsClosure cl; + CLDToOopClosure clds(&cl, ClassLoaderData::_claim_strong); + + _jni_roots.oops_do(&cl); + _cld_roots.cld_do(&clds); + } +}; + +void ShenandoahHeap::op_concurrent_roots() { + if (is_evacuation_in_progress() && + ShenandoahConcurrentRoots::should_do_concurrent_roots()) { + ShenandoahConcurrentRootsEvacUpdateTask task; + workers()->run_task(&task); + } +} + void ShenandoahHeap::op_reset() { reset_mark_bitmap(); } @@ -2554,6 +2590,22 @@ try_inject_alloc_failure(); op_updaterefs(); } + +void ShenandoahHeap::entry_concurrent_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_concurrent_roots(); +} + void ShenandoahHeap::entry_cleanup() { ShenandoahGCPhase phase(ShenandoahPhaseTimings::conc_cleanup);