# HG changeset patch # User zgu # Date 1597762531 14400 # Tue Aug 18 10:55:31 2020 -0400 # Node ID 79a449333955e282064516d81e8b5110e4f5f8f0 # Parent 01c5097cf1cd64d95f19ce7bd93ef16f86a8afe1 8251910: Shenandoah: assert(external_guard || result != __null) failed: Invalid JNI handle diff --git a/src/hotspot/share/gc/shenandoah/shenandoahControlThread.cpp b/src/hotspot/share/gc/shenandoah/shenandoahControlThread.cpp --- a/src/hotspot/share/gc/shenandoah/shenandoahControlThread.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahControlThread.cpp @@ -424,6 +424,12 @@ // Update references freed up collection set, kick the cleanup to reclaim the space. heap->entry_cleanup_complete(); + } else { + // Concurrent weak/strong root flags are unset concurrently. We depend on updateref GC safepoints + // to ensure the changes are visible to all mutators before gc cycle is completed. + // In case of no evacuation, updateref GC safepoints are skipped. Therefore, we will need + // to perform thread handshake to ensure their consistences. + heap->entry_rendezvous_roots(); } // Cycle is complete diff --git a/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp b/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp --- a/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp @@ -1821,8 +1821,7 @@ // Perform handshake to flush out dead oops { ShenandoahTimingsTracker t(ShenandoahPhaseTimings::conc_weak_roots_rendezvous); - ShenandoahRendezvousClosure cl; - Handshake::execute(&cl); + rendezvous_threads(); } } } @@ -1842,6 +1841,15 @@ set_concurrent_strong_root_in_progress(false); } +void ShenandoahHeap::op_rendezvous_roots() { + rendezvous_threads(); +} + +void ShenandoahHeap::rendezvous_threads() { + ShenandoahRendezvousClosure cl; + Handshake::execute(&cl); +} + class ShenandoahResetUpdateRegionStateClosure : public ShenandoahHeapRegionClosure { private: ShenandoahMarkingContext* const _ctx; @@ -2900,6 +2908,16 @@ op_cleanup_early(); } +void ShenandoahHeap::entry_rendezvous_roots() { + static const char* msg = "Rendezvous roots"; + ShenandoahConcurrentPhase gc_phase(msg, ShenandoahPhaseTimings::conc_rendezvous_roots); + EventMark em("%s", msg); + + // This phase does not use workers, no need for setup + try_inject_alloc_failure(); + op_rendezvous_roots(); +} + void ShenandoahHeap::entry_cleanup_complete() { static const char* msg = "Concurrent cleanup"; ShenandoahConcurrentPhase gc_phase(msg, ShenandoahPhaseTimings::conc_cleanup_complete, true /* log_heap_usage */); diff --git a/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp b/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp --- a/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp @@ -386,6 +386,7 @@ void entry_class_unloading(); void entry_strong_roots(); void entry_cleanup_early(); + void entry_rendezvous_roots(); void entry_evac(); void entry_updaterefs(); void entry_cleanup_complete(); @@ -409,12 +410,15 @@ void op_class_unloading(); void op_strong_roots(); void op_cleanup_early(); + void op_rendezvous_roots(); void op_conc_evac(); void op_stw_evac(); void op_updaterefs(); void op_cleanup_complete(); void op_uncommit(double shrink_before); + void rendezvous_threads(); + // Messages for GC trace events, they have to be immortal for // passing around the logging/tracing systems const char* init_mark_event_message() const; diff --git a/src/hotspot/share/gc/shenandoah/shenandoahPhaseTimings.hpp b/src/hotspot/share/gc/shenandoah/shenandoahPhaseTimings.hpp --- a/src/hotspot/share/gc/shenandoah/shenandoahPhaseTimings.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahPhaseTimings.hpp @@ -99,6 +99,7 @@ f(conc_class_unload_purge_cldg, " CLDG") \ f(conc_class_unload_purge_ec, " Exception Caches") \ f(conc_strong_roots, "Concurrent Strong Roots") \ + f(conc_rendezvous_roots, "Rendezvous") \ SHENANDOAH_PAR_PHASE_DO(conc_strong_roots_, " CSR: ", f) \ f(conc_evac, "Concurrent Evacuation") \ \