8251910: Shenandoah: Handshake threads between weak-roots and reset phases

Reviewed-by: rkennke
This commit is contained in:
Zhengyu Gu 2020-08-18 13:34:10 -04:00
parent 9871f3a27a
commit f797e19e3d
4 changed files with 31 additions and 2 deletions

View file

@ -424,6 +424,12 @@ void ShenandoahControlThread::service_concurrent_normal_cycle(GCCause::Cause cau
// Update references freed up collection set, kick the cleanup to reclaim the space. // Update references freed up collection set, kick the cleanup to reclaim the space.
heap->entry_cleanup_complete(); 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 // Cycle is complete

View file

@ -1821,8 +1821,7 @@ void ShenandoahHeap::op_weak_roots() {
// Perform handshake to flush out dead oops // Perform handshake to flush out dead oops
{ {
ShenandoahTimingsTracker t(ShenandoahPhaseTimings::conc_weak_roots_rendezvous); ShenandoahTimingsTracker t(ShenandoahPhaseTimings::conc_weak_roots_rendezvous);
ShenandoahRendezvousClosure cl; rendezvous_threads();
Handshake::execute(&cl);
} }
} }
} }
@ -1842,6 +1841,15 @@ void ShenandoahHeap::op_strong_roots() {
set_concurrent_strong_root_in_progress(false); 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 { class ShenandoahResetUpdateRegionStateClosure : public ShenandoahHeapRegionClosure {
private: private:
ShenandoahMarkingContext* const _ctx; ShenandoahMarkingContext* const _ctx;
@ -2900,6 +2908,16 @@ void ShenandoahHeap::entry_cleanup_early() {
op_cleanup_early(); 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() { void ShenandoahHeap::entry_cleanup_complete() {
static const char* msg = "Concurrent cleanup"; static const char* msg = "Concurrent cleanup";
ShenandoahConcurrentPhase gc_phase(msg, ShenandoahPhaseTimings::conc_cleanup_complete, true /* log_heap_usage */); ShenandoahConcurrentPhase gc_phase(msg, ShenandoahPhaseTimings::conc_cleanup_complete, true /* log_heap_usage */);

View file

@ -386,6 +386,7 @@ public:
void entry_class_unloading(); void entry_class_unloading();
void entry_strong_roots(); void entry_strong_roots();
void entry_cleanup_early(); void entry_cleanup_early();
void entry_rendezvous_roots();
void entry_evac(); void entry_evac();
void entry_updaterefs(); void entry_updaterefs();
void entry_cleanup_complete(); void entry_cleanup_complete();
@ -409,12 +410,15 @@ private:
void op_class_unloading(); void op_class_unloading();
void op_strong_roots(); void op_strong_roots();
void op_cleanup_early(); void op_cleanup_early();
void op_rendezvous_roots();
void op_conc_evac(); void op_conc_evac();
void op_stw_evac(); void op_stw_evac();
void op_updaterefs(); void op_updaterefs();
void op_cleanup_complete(); void op_cleanup_complete();
void op_uncommit(double shrink_before); void op_uncommit(double shrink_before);
void rendezvous_threads();
// Messages for GC trace events, they have to be immortal for // Messages for GC trace events, they have to be immortal for
// passing around the logging/tracing systems // passing around the logging/tracing systems
const char* init_mark_event_message() const; const char* init_mark_event_message() const;

View file

@ -99,6 +99,7 @@ class outputStream;
f(conc_class_unload_purge_cldg, " CLDG") \ f(conc_class_unload_purge_cldg, " CLDG") \
f(conc_class_unload_purge_ec, " Exception Caches") \ f(conc_class_unload_purge_ec, " Exception Caches") \
f(conc_strong_roots, "Concurrent Strong Roots") \ f(conc_strong_roots, "Concurrent Strong Roots") \
f(conc_rendezvous_roots, "Rendezvous") \
SHENANDOAH_PAR_PHASE_DO(conc_strong_roots_, " CSR: ", f) \ SHENANDOAH_PAR_PHASE_DO(conc_strong_roots_, " CSR: ", f) \
f(conc_evac, "Concurrent Evacuation") \ f(conc_evac, "Concurrent Evacuation") \
\ \