< prev index next >

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

Print this page
rev 55336 : 8225550: Shenandoah: Prevent SH::object_iterate() call's side-effects
rev 55337 : 8225573: Shenandoah: Enhance ShenandoahVerifier to ensure roots to-space invariant
rev 55339 : 8225582: Shenandoah: Enable concurrent evacuation of JNIHandles and CLDG roots

*** 36,45 **** --- 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"
*** 947,957 **** {} void work(uint worker_id) { if (_concurrent) { ShenandoahConcurrentWorkerSession worker_session(worker_id); ! ShenandoahSuspendibleThreadSetJoiner stsj(ShenandoahSuspendibleWorkers); ShenandoahEvacOOMScope oom_evac_scope; do_work(); } else { ShenandoahParallelWorkerSession worker_session(worker_id); ShenandoahEvacOOMScope oom_evac_scope; --- 948,958 ---- {} void work(uint worker_id) { if (_concurrent) { ShenandoahConcurrentWorkerSession worker_session(worker_id); ! ShenandoahSuspendibleThreadSetJoiner stsj; ShenandoahEvacOOMScope oom_evac_scope; do_work(); } else { ShenandoahParallelWorkerSession worker_session(worker_id); ShenandoahEvacOOMScope oom_evac_scope;
*** 1069,1081 **** 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"); - { ! ShenandoahRootEvacuator rp(workers()->active_workers(), ShenandoahPhaseTimings::init_evac); ShenandoahEvacuateUpdateRootsTask roots_task(&rp); workers()->run_task(&roots_task); } #if COMPILER2_OR_JVMCI --- 1070,1084 ---- 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 ! 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); } #if COMPILER2_OR_JVMCI
*** 1515,1525 **** --- 1518,1533 ---- if (ShenandoahPacing) { pacer()->setup_for_evac(); } if (ShenandoahVerify) { + 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 { if (ShenandoahVerify) { verifier()->verify_after_concmark();
*** 1576,1585 **** --- 1584,1621 ---- void ShenandoahHeap::op_cleanup() { free_set()->recycle_trash(); } + class ShenandoahConcurrentRootsEvacUpdateTask : public AbstractGangTask { + private: + SuspendibleThreadSetJoiner _sts_joiner; + ShenandoahJNIHandleRoots<true /*concurrent*/> _jni_roots; + ShenandoahClassLoaderDataRoots<true /* concurrent */> _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<ShenandoahEvacuateUpdateRootsClosure>(&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(); } void ShenandoahHeap::op_preclean() {
*** 1849,1859 **** bool ShenandoahHeap::try_cancel_gc() { while (true) { jbyte prev = _cancelled_gc.cmpxchg(CANCELLED, CANCELLABLE); if (prev == CANCELLABLE) return true; else if (prev == CANCELLED) return false; - assert(ShenandoahSuspendibleWorkers, "should not get here when not using suspendible workers"); assert(prev == NOT_CANCELLED, "must be NOT_CANCELLED"); { // We need to provide a safepoint here, otherwise we might // spin forever if a SP is pending. ThreadBlockInVM sp(JavaThread::current()); --- 1885,1894 ----
*** 2063,2073 **** } void work(uint worker_id) { if (_concurrent) { ShenandoahConcurrentWorkerSession worker_session(worker_id); ! ShenandoahSuspendibleThreadSetJoiner stsj(ShenandoahSuspendibleWorkers); do_work(); } else { ShenandoahParallelWorkerSession worker_session(worker_id); do_work(); } --- 2098,2108 ---- } void work(uint worker_id) { if (_concurrent) { ShenandoahConcurrentWorkerSession worker_session(worker_id); ! ShenandoahSuspendibleThreadSetJoiner stsj; do_work(); } else { ShenandoahParallelWorkerSession worker_session(worker_id); do_work(); }
*** 2263,2281 **** } return true; } void ShenandoahHeap::safepoint_synchronize_begin() { - if (ShenandoahSuspendibleWorkers || UseStringDeduplication) { SuspendibleThreadSet::synchronize(); - } } void ShenandoahHeap::safepoint_synchronize_end() { - if (ShenandoahSuspendibleWorkers || UseStringDeduplication) { SuspendibleThreadSet::desynchronize(); - } } void ShenandoahHeap::vmop_entry_init_mark() { TraceCollectorStats tcs(monitoring_support()->stw_collection_counters()); ShenandoahGCPhase total(ShenandoahPhaseTimings::total_pause_gross); --- 2298,2312 ----
*** 2536,2545 **** --- 2567,2592 ---- "concurrent reference update"); 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); static const char* msg = "Concurrent cleanup"; GCTraceTime(Info, gc) time(msg, NULL, GCCause::_no_gc, true);
< prev index next >