changeset 59210:ca61965cfcf4

8244243: Shenandoah: Cleanup Shenandoah phase timing tracking and JFR event supporting Reviewed-by: shade
author zgu
date Thu, 07 May 2020 17:44:53 -0400
parents 868fe697bad4
children 79158e8fdf2c
files src/hotspot/share/gc/shenandoah/shenandoahCodeRoots.cpp src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.cpp src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp src/hotspot/share/gc/shenandoah/shenandoahMarkCompact.cpp src/hotspot/share/gc/shenandoah/shenandoahUtils.cpp src/hotspot/share/gc/shenandoah/shenandoahUtils.hpp
diffstat 6 files changed, 117 insertions(+), 115 deletions(-) [+]
line wrap: on
line diff
--- a/src/hotspot/share/gc/shenandoah/shenandoahCodeRoots.cpp	Thu May 07 19:18:22 2020 +0100
+++ b/src/hotspot/share/gc/shenandoah/shenandoahCodeRoots.cpp	Thu May 07 17:44:53 2020 -0400
@@ -194,6 +194,7 @@
   ShenandoahDisarmNMethodsTask() :
     AbstractGangTask("ShenandoahDisarmNMethodsTask"),
     _iterator(ShenandoahCodeRoots::table()) {
+    assert(SafepointSynchronize::is_at_safepoint(), "Only at a safepoint");
     MutexLocker mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
     _iterator.nmethods_do_begin();
   }
@@ -204,6 +205,7 @@
   }
 
   virtual void work(uint worker_id) {
+    ShenandoahParallelWorkerSession worker_session(worker_id);
     _iterator.nmethods_do(&_cl);
   }
 };
--- a/src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.cpp	Thu May 07 19:18:22 2020 +0100
+++ b/src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.cpp	Thu May 07 17:44:53 2020 -0400
@@ -351,6 +351,7 @@
     _worker_phase(phase) {}
 
   void work(uint worker_id) {
+    ShenandoahParallelWorkerSession worker_session(worker_id);
     ShenandoahUpdateRefsClosure cl;
     _thread_roots.oops_do(&cl, NULL, worker_id);
   }
@@ -588,6 +589,7 @@
     HandleMark hm;
     assert(ShenandoahSafepoint::is_at_shenandoah_safepoint(), "Must be at a safepoint");
     ShenandoahHeap* heap = ShenandoahHeap::heap();
+    ShenandoahParallelWorkerSession worker_session(worker_id);
     ShenandoahCMDrainMarkingStackClosure complete_gc(worker_id, _terminator);
     if (heap->has_forwarded_objects()) {
       ShenandoahForwardedIsAliveClosure is_alive;
@@ -682,7 +684,11 @@
   ReferenceProcessorPhaseTimes pt(_heap->gc_timer(), rp->num_queues());
 
   {
-    ShenandoahGCPhase phase(phase_process);
+    // Note: Don't emit JFR event for this phase, to avoid overflow nesting phase level.
+    // Reference Processor emits 2 levels JFR event, that can get us over the JFR
+    // event nesting level limits, in case of degenerated GC gets upgraded to
+    // full GC.
+    ShenandoahTimingsTracker phase_timing(phase_process);
 
     if (_heap->has_forwarded_objects()) {
       ShenandoahCMKeepAliveUpdateClosure keep_alive(get_queue(serial_worker_id));
--- a/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp	Thu May 07 19:18:22 2020 +0100
+++ b/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp	Thu May 07 17:44:53 2020 -0400
@@ -1343,6 +1343,7 @@
           _heap(ShenandoahHeap::heap()), _blk(blk), _index(0) {}
 
   void work(uint worker_id) {
+    ShenandoahParallelWorkerSession worker_session(worker_id);
     size_t stride = ShenandoahParallelRegionStride;
 
     size_t max = _heap->num_regions();
@@ -1412,12 +1413,12 @@
   set_concurrent_mark_in_progress(true);
   // We need to reset all TLABs because we'd lose marks on all objects allocated in them.
   {
-    ShenandoahGCSubPhase phase(ShenandoahPhaseTimings::make_parsable);
+    ShenandoahGCPhase phase(ShenandoahPhaseTimings::make_parsable);
     make_parsable(true);
   }
 
   {
-    ShenandoahGCSubPhase phase(ShenandoahPhaseTimings::init_update_region_states);
+    ShenandoahGCPhase phase(ShenandoahPhaseTimings::init_update_region_states);
     ShenandoahInitMarkUpdateRegionStateClosure cl;
     parallel_heap_region_iterate(&cl);
   }
@@ -1428,7 +1429,7 @@
   concurrent_mark()->mark_roots(ShenandoahPhaseTimings::scan_roots);
 
   if (UseTLAB) {
-    ShenandoahGCSubPhase phase(ShenandoahPhaseTimings::resize_tlabs);
+    ShenandoahGCPhase phase(ShenandoahPhaseTimings::resize_tlabs);
     resize_tlabs();
   }
 
@@ -1517,7 +1518,7 @@
     }
 
     {
-      ShenandoahGCSubPhase phase(ShenandoahPhaseTimings::final_update_region_states);
+      ShenandoahGCPhase phase(ShenandoahPhaseTimings::final_update_region_states);
       ShenandoahFinalMarkUpdateRegionStateClosure cl;
       parallel_heap_region_iterate(&cl);
 
@@ -1530,19 +1531,19 @@
     // Weaker one: new allocations would happen past update watermark, and so less work would
     // be needed for reference updates (would update the large filler instead).
     {
-      ShenandoahGCSubPhase phase(ShenandoahPhaseTimings::retire_tlabs);
+      ShenandoahGCPhase phase(ShenandoahPhaseTimings::retire_tlabs);
       make_parsable(true);
     }
 
     {
-      ShenandoahGCSubPhase phase(ShenandoahPhaseTimings::choose_cset);
+      ShenandoahGCPhase phase(ShenandoahPhaseTimings::choose_cset);
       ShenandoahHeapLocker locker(lock());
       _collection_set->clear();
       heuristics()->choose_collection_set(_collection_set);
     }
 
     {
-      ShenandoahGCSubPhase phase(ShenandoahPhaseTimings::final_rebuild_freeset);
+      ShenandoahGCPhase phase(ShenandoahPhaseTimings::final_rebuild_freeset);
       ShenandoahHeapLocker locker(lock());
       _free_set->rebuild();
     }
@@ -1555,7 +1556,7 @@
     // If collection set has candidates, start evacuation.
     // Otherwise, bypass the rest of the cycle.
     if (!collection_set()->is_empty()) {
-      ShenandoahGCSubPhase init_evac(ShenandoahPhaseTimings::init_evac);
+      ShenandoahGCPhase init_evac(ShenandoahPhaseTimings::init_evac);
 
       if (ShenandoahVerify) {
         verifier()->verify_before_evacuation();
@@ -1651,6 +1652,7 @@
     _cld_roots(phase) {}
 
   void work(uint worker_id) {
+    ShenandoahConcurrentWorkerSession worker_session(worker_id);
     ShenandoahEvacOOMScope oom;
     {
       // vm_roots and weak_roots are OopStorage backed roots, concurrent iteration
@@ -1789,6 +1791,7 @@
   }
 
   void work(uint worker_id) {
+    ShenandoahConcurrentWorkerSession worker_session(worker_id);
     {
       ShenandoahEvacOOMScope oom;
       // jni_roots and weak_roots are OopStorage backed roots, concurrent iteration
@@ -1892,7 +1895,7 @@
 
   full_gc()->do_it(cause);
   if (UseTLAB) {
-    ShenandoahGCSubPhase phase(ShenandoahPhaseTimings::full_gc_resize_tlabs);
+    ShenandoahGCPhase phase(ShenandoahPhaseTimings::full_gc_resize_tlabs);
     resize_all_tlabs();
   }
 
@@ -2203,9 +2206,9 @@
 
   // Unload classes and purge SystemDictionary.
   {
-    ShenandoahGCSubPhase phase(full_gc ?
-                               ShenandoahPhaseTimings::full_gc_purge_class_unload :
-                               ShenandoahPhaseTimings::purge_class_unload);
+    ShenandoahGCPhase phase(full_gc ?
+                            ShenandoahPhaseTimings::full_gc_purge_class_unload :
+                            ShenandoahPhaseTimings::purge_class_unload);
     bool purged_class = SystemDictionary::do_unloading(gc_timer());
 
     ShenandoahIsAliveSelector is_alive;
@@ -2215,9 +2218,9 @@
   }
 
   {
-    ShenandoahGCSubPhase phase(full_gc ?
-                               ShenandoahPhaseTimings::full_gc_purge_cldg :
-                               ShenandoahPhaseTimings::purge_cldg);
+    ShenandoahGCPhase phase(full_gc ?
+                            ShenandoahPhaseTimings::full_gc_purge_cldg :
+                            ShenandoahPhaseTimings::purge_cldg);
     ClassLoaderDataGraph::purge();
   }
   // Resize and verify metaspace
@@ -2230,14 +2233,14 @@
 // 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) {
-  ShenandoahGCSubPhase root_phase(full_gc ?
-                                  ShenandoahPhaseTimings::full_gc_purge :
-                                  ShenandoahPhaseTimings::purge);
+  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_weak_par :
                                                ShenandoahPhaseTimings::purge_weak_par;
-  ShenandoahGCSubPhase phase(timing_phase);
+  ShenandoahGCPhase phase(timing_phase);
   ShenandoahGCWorkerPhase worker_phase(timing_phase);
 
   // Cleanup weak roots
@@ -2493,7 +2496,7 @@
   set_evacuation_in_progress(false);
 
   {
-    ShenandoahGCSubPhase phase(ShenandoahPhaseTimings::init_update_refs_retire_gclabs);
+    ShenandoahGCPhase phase(ShenandoahPhaseTimings::init_update_refs_retire_gclabs);
     retire_and_reset_gclabs();
   }
 
@@ -2549,7 +2552,7 @@
 
   // Check if there is left-over work, and finish it
   if (_update_refs_iterator.has_next()) {
-    ShenandoahGCSubPhase phase(ShenandoahPhaseTimings::final_update_refs_finish_work);
+    ShenandoahGCPhase phase(ShenandoahPhaseTimings::final_update_refs_finish_work);
 
     // Finish updating references where we left off.
     clear_cancelled_gc();
@@ -2579,7 +2582,7 @@
   }
 
   {
-    ShenandoahGCSubPhase phase(ShenandoahPhaseTimings::final_update_refs_update_region_states);
+    ShenandoahGCPhase phase(ShenandoahPhaseTimings::final_update_refs_update_region_states);
     ShenandoahFinalUpdateRefsUpdateRegionStateClosure cl;
     parallel_heap_region_iterate(&cl);
 
@@ -2587,7 +2590,7 @@
   }
 
   {
-    ShenandoahGCSubPhase phase(ShenandoahPhaseTimings::final_update_refs_trash_cset);
+    ShenandoahGCPhase phase(ShenandoahPhaseTimings::final_update_refs_trash_cset);
     trash_cset_regions();
   }
 
@@ -2603,7 +2606,7 @@
   }
 
   {
-    ShenandoahGCSubPhase phase(ShenandoahPhaseTimings::final_update_refs_rebuild_freeset);
+    ShenandoahGCPhase phase(ShenandoahPhaseTimings::final_update_refs_rebuild_freeset);
     ShenandoahHeapLocker locker(lock());
     _free_set->rebuild();
   }
@@ -2691,7 +2694,7 @@
 
 void ShenandoahHeap::vmop_entry_init_mark() {
   TraceCollectorStats tcs(monitoring_support()->stw_collection_counters());
-  ShenandoahGCPhase phase(ShenandoahPhaseTimings::init_mark_gross);
+  ShenandoahTimingsTracker timing(ShenandoahPhaseTimings::init_mark_gross);
 
   try_inject_alloc_failure();
   VM_ShenandoahInitMark op;
@@ -2700,7 +2703,7 @@
 
 void ShenandoahHeap::vmop_entry_final_mark() {
   TraceCollectorStats tcs(monitoring_support()->stw_collection_counters());
-  ShenandoahGCPhase phase(ShenandoahPhaseTimings::final_mark_gross);
+  ShenandoahTimingsTracker timing(ShenandoahPhaseTimings::final_mark_gross);
 
   try_inject_alloc_failure();
   VM_ShenandoahFinalMarkStartEvac op;
@@ -2709,7 +2712,7 @@
 
 void ShenandoahHeap::vmop_entry_init_updaterefs() {
   TraceCollectorStats tcs(monitoring_support()->stw_collection_counters());
-  ShenandoahGCPhase phase(ShenandoahPhaseTimings::init_update_refs_gross);
+  ShenandoahTimingsTracker timing(ShenandoahPhaseTimings::init_update_refs_gross);
 
   try_inject_alloc_failure();
   VM_ShenandoahInitUpdateRefs op;
@@ -2718,7 +2721,7 @@
 
 void ShenandoahHeap::vmop_entry_final_updaterefs() {
   TraceCollectorStats tcs(monitoring_support()->stw_collection_counters());
-  ShenandoahGCPhase phase(ShenandoahPhaseTimings::final_update_refs_gross);
+  ShenandoahTimingsTracker timing(ShenandoahPhaseTimings::final_update_refs_gross);
 
   try_inject_alloc_failure();
   VM_ShenandoahFinalUpdateRefs op;
@@ -2727,7 +2730,7 @@
 
 void ShenandoahHeap::vmop_entry_full(GCCause::Cause cause) {
   TraceCollectorStats tcs(monitoring_support()->full_stw_collection_counters());
-  ShenandoahGCPhase phase(ShenandoahPhaseTimings::full_gc_gross);
+  ShenandoahTimingsTracker timing(ShenandoahPhaseTimings::full_gc_gross);
 
   try_inject_alloc_failure();
   VM_ShenandoahFullGC op(cause);
@@ -2736,7 +2739,7 @@
 
 void ShenandoahHeap::vmop_degenerated(ShenandoahDegenPoint point) {
   TraceCollectorStats tcs(monitoring_support()->full_stw_collection_counters());
-  ShenandoahGCPhase phase(ShenandoahPhaseTimings::degen_gc_gross);
+  ShenandoahTimingsTracker timing(ShenandoahPhaseTimings::degen_gc_gross);
 
   VM_ShenandoahDegeneratedGC degenerated_gc((int)point);
   VMThread::execute(&degenerated_gc);
@@ -2744,11 +2747,9 @@
 
 void ShenandoahHeap::entry_init_mark() {
   const char* msg = init_mark_event_message();
-  ShenandoahPausePhase gc_phase(msg);
+  ShenandoahPausePhase gc_phase(msg, ShenandoahPhaseTimings::init_mark);
   EventMark em("%s", msg);
 
-  ShenandoahGCPhase phase(ShenandoahPhaseTimings::init_mark);
-
   ShenandoahWorkerScope scope(workers(),
                               ShenandoahWorkerPolicy::calc_workers_for_init_marking(),
                               "init marking");
@@ -2758,11 +2759,9 @@
 
 void ShenandoahHeap::entry_final_mark() {
   const char* msg = final_mark_event_message();
-  ShenandoahPausePhase gc_phase(msg);
+  ShenandoahPausePhase gc_phase(msg, ShenandoahPhaseTimings::final_mark);
   EventMark em("%s", msg);
 
-  ShenandoahGCPhase phase(ShenandoahPhaseTimings::final_mark);
-
   ShenandoahWorkerScope scope(workers(),
                               ShenandoahWorkerPolicy::calc_workers_for_final_marking(),
                               "final marking");
@@ -2772,11 +2771,9 @@
 
 void ShenandoahHeap::entry_init_updaterefs() {
   static const char* msg = "Pause Init Update Refs";
-  ShenandoahPausePhase gc_phase(msg);
+  ShenandoahPausePhase gc_phase(msg, ShenandoahPhaseTimings::init_update_refs);
   EventMark em("%s", msg);
 
-  ShenandoahGCPhase phase(ShenandoahPhaseTimings::init_update_refs);
-
   // No workers used in this phase, no setup required
 
   op_init_updaterefs();
@@ -2784,11 +2781,9 @@
 
 void ShenandoahHeap::entry_final_updaterefs() {
   static const char* msg = "Pause Final Update Refs";
-  ShenandoahPausePhase gc_phase(msg);
+  ShenandoahPausePhase gc_phase(msg, ShenandoahPhaseTimings::final_update_refs);
   EventMark em("%s", msg);
 
-  ShenandoahGCPhase phase(ShenandoahPhaseTimings::final_update_refs);
-
   ShenandoahWorkerScope scope(workers(),
                               ShenandoahWorkerPolicy::calc_workers_for_final_update_ref(),
                               "final reference update");
@@ -2798,11 +2793,9 @@
 
 void ShenandoahHeap::entry_full(GCCause::Cause cause) {
   static const char* msg = "Pause Full";
-  ShenandoahPausePhase gc_phase(msg, true /* log_heap_usage */);
+  ShenandoahPausePhase gc_phase(msg, ShenandoahPhaseTimings::full_gc, true /* log_heap_usage */);
   EventMark em("%s", msg);
 
-  ShenandoahGCPhase phase(ShenandoahPhaseTimings::full_gc);
-
   ShenandoahWorkerScope scope(workers(),
                               ShenandoahWorkerPolicy::calc_workers_for_fullgc(),
                               "full gc");
@@ -2813,11 +2806,9 @@
 void ShenandoahHeap::entry_degenerated(int point) {
   ShenandoahDegenPoint dpoint = (ShenandoahDegenPoint)point;
   const char* msg = degen_event_message(dpoint);
-  ShenandoahPausePhase gc_phase(msg, true /* log_heap_usage */);
+  ShenandoahPausePhase gc_phase(msg, ShenandoahPhaseTimings::degen_gc, true /* log_heap_usage */);
   EventMark em("%s", msg);
 
-  ShenandoahGCPhase phase(ShenandoahPhaseTimings::degen_gc);
-
   ShenandoahWorkerScope scope(workers(),
                               ShenandoahWorkerPolicy::calc_workers_for_stw_degenerated(),
                               "stw degenerated gc");
@@ -2831,11 +2822,9 @@
   TraceCollectorStats tcs(monitoring_support()->concurrent_collection_counters());
 
   const char* msg = conc_mark_event_message();
-  ShenandoahConcurrentPhase gc_phase(msg);
+  ShenandoahConcurrentPhase gc_phase(msg, ShenandoahPhaseTimings::conc_mark);
   EventMark em("%s", msg);
 
-  ShenandoahGCPhase conc_mark_phase(ShenandoahPhaseTimings::conc_mark);
-
   ShenandoahWorkerScope scope(workers(),
                               ShenandoahWorkerPolicy::calc_workers_for_conc_marking(),
                               "concurrent marking");
@@ -2848,11 +2837,9 @@
   TraceCollectorStats tcs(monitoring_support()->concurrent_collection_counters());
 
   static const char* msg = "Concurrent evacuation";
-  ShenandoahConcurrentPhase gc_phase(msg);
+  ShenandoahConcurrentPhase gc_phase(msg, ShenandoahPhaseTimings::conc_evac);
   EventMark em("%s", msg);
 
-  ShenandoahGCPhase conc_evac_phase(ShenandoahPhaseTimings::conc_evac);
-
   ShenandoahWorkerScope scope(workers(),
                               ShenandoahWorkerPolicy::calc_workers_for_conc_evac(),
                               "concurrent evacuation");
@@ -2863,11 +2850,9 @@
 
 void ShenandoahHeap::entry_updaterefs() {
   static const char* msg = "Concurrent update references";
-  ShenandoahConcurrentPhase gc_phase(msg);
+  ShenandoahConcurrentPhase gc_phase(msg, ShenandoahPhaseTimings::conc_update_refs);
   EventMark em("%s", msg);
 
-  ShenandoahGCPhase phase(ShenandoahPhaseTimings::conc_update_refs);
-
   ShenandoahWorkerScope scope(workers(),
                               ShenandoahWorkerPolicy::calc_workers_for_conc_update_ref(),
                               "concurrent reference update");
@@ -2878,10 +2863,9 @@
 
 void ShenandoahHeap::entry_weak_roots() {
   static const char* msg = "Concurrent weak roots";
-  ShenandoahConcurrentPhase gc_phase(msg);
+  ShenandoahConcurrentPhase gc_phase(msg, ShenandoahPhaseTimings::conc_weak_roots);
   EventMark em("%s", msg);
 
-  ShenandoahGCPhase phase(ShenandoahPhaseTimings::conc_weak_roots);
   ShenandoahGCWorkerPhase worker_phase(ShenandoahPhaseTimings::conc_weak_roots);
 
   ShenandoahWorkerScope scope(workers(),
@@ -2894,11 +2878,9 @@
 
 void ShenandoahHeap::entry_class_unloading() {
   static const char* msg = "Concurrent class unloading";
-  ShenandoahConcurrentPhase gc_phase(msg);
+  ShenandoahConcurrentPhase gc_phase(msg, ShenandoahPhaseTimings::conc_class_unloading);
   EventMark em("%s", msg);
 
-  ShenandoahGCPhase phase(ShenandoahPhaseTimings::conc_class_unloading);
-
   ShenandoahWorkerScope scope(workers(),
                               ShenandoahWorkerPolicy::calc_workers_for_conc_root_processing(),
                               "concurrent class unloading");
@@ -2909,10 +2891,9 @@
 
 void ShenandoahHeap::entry_strong_roots() {
   static const char* msg = "Concurrent strong roots";
-  ShenandoahConcurrentPhase gc_phase(msg);
+  ShenandoahConcurrentPhase gc_phase(msg, ShenandoahPhaseTimings::conc_strong_roots);
   EventMark em("%s", msg);
 
-  ShenandoahGCPhase phase(ShenandoahPhaseTimings::conc_strong_roots);
   ShenandoahGCWorkerPhase worker_phase(ShenandoahPhaseTimings::conc_strong_roots);
 
   ShenandoahWorkerScope scope(workers(),
@@ -2925,11 +2906,9 @@
 
 void ShenandoahHeap::entry_cleanup_early() {
   static const char* msg = "Concurrent cleanup";
-  ShenandoahConcurrentPhase gc_phase(msg,  true /* log_heap_usage */);
+  ShenandoahConcurrentPhase gc_phase(msg, ShenandoahPhaseTimings::conc_cleanup_early, true /* log_heap_usage */);
   EventMark em("%s", msg);
 
-  ShenandoahGCSubPhase phase(ShenandoahPhaseTimings::conc_cleanup_early);
-
   // This phase does not use workers, no need for setup
 
   try_inject_alloc_failure();
@@ -2938,11 +2917,9 @@
 
 void ShenandoahHeap::entry_cleanup_complete() {
   static const char* msg = "Concurrent cleanup";
-  ShenandoahConcurrentPhase gc_phase(msg,  true /* log_heap_usage */);
+  ShenandoahConcurrentPhase gc_phase(msg, ShenandoahPhaseTimings::conc_cleanup_complete, true /* log_heap_usage */);
   EventMark em("%s", msg);
 
-  ShenandoahGCSubPhase phase(ShenandoahPhaseTimings::conc_cleanup_complete);
-
   // This phase does not use workers, no need for setup
 
   try_inject_alloc_failure();
@@ -2951,11 +2928,9 @@
 
 void ShenandoahHeap::entry_reset() {
   static const char* msg = "Concurrent reset";
-  ShenandoahConcurrentPhase gc_phase(msg);
+  ShenandoahConcurrentPhase gc_phase(msg, ShenandoahPhaseTimings::conc_reset);
   EventMark em("%s", msg);
 
-  ShenandoahGCSubPhase phase(ShenandoahPhaseTimings::conc_reset);
-
   ShenandoahWorkerScope scope(workers(),
                               ShenandoahWorkerPolicy::calc_workers_for_conc_reset(),
                               "concurrent reset");
@@ -2967,11 +2942,9 @@
 void ShenandoahHeap::entry_preclean() {
   if (ShenandoahPreclean && process_references()) {
     static const char* msg = "Concurrent precleaning";
-    ShenandoahConcurrentPhase gc_phase(msg);
+    ShenandoahConcurrentPhase gc_phase(msg, ShenandoahPhaseTimings::conc_preclean);
     EventMark em("%s", msg);
 
-    ShenandoahGCSubPhase conc_preclean(ShenandoahPhaseTimings::conc_preclean);
-
     ShenandoahWorkerScope scope(workers(),
                                 ShenandoahWorkerPolicy::calc_workers_for_conc_preclean(),
                                 "concurrent preclean",
@@ -2984,11 +2957,9 @@
 
 void ShenandoahHeap::entry_uncommit(double shrink_before) {
   static const char *msg = "Concurrent uncommit";
-  ShenandoahConcurrentPhase gc_phase(msg, true /* log_heap_usage */);
+  ShenandoahConcurrentPhase gc_phase(msg, ShenandoahPhaseTimings::conc_uncommit, true /* log_heap_usage */);
   EventMark em("%s", msg);
 
-  ShenandoahGCSubPhase phase(ShenandoahPhaseTimings::conc_uncommit);
-
   op_uncommit(shrink_before);
 }
 
--- a/src/hotspot/share/gc/shenandoah/shenandoahMarkCompact.cpp	Thu May 07 19:18:22 2020 +0100
+++ b/src/hotspot/share/gc/shenandoah/shenandoahMarkCompact.cpp	Thu May 07 17:44:53 2020 -0400
@@ -348,6 +348,7 @@
   }
 
   void work(uint worker_id) {
+    ShenandoahParallelWorkerSession worker_session(worker_id);
     ShenandoahHeapRegionSet* slice = _worker_slices[worker_id];
     ShenandoahHeapRegionSetIterator it(slice);
     ShenandoahHeapRegion* from_region = it.next();
@@ -727,6 +728,7 @@
   }
 
   void work(uint worker_id) {
+    ShenandoahParallelWorkerSession worker_session(worker_id);
     ShenandoahAdjustPointersObjectClosure obj_cl;
     ShenandoahHeapRegion* r = _regions.next();
     while (r != NULL) {
@@ -749,6 +751,7 @@
     _preserved_marks(preserved_marks) {}
 
   void work(uint worker_id) {
+    ShenandoahParallelWorkerSession worker_session(worker_id);
     ShenandoahAdjustPointersClosure cl;
     _rp->roots_do(worker_id, &cl);
     _preserved_marks->get(worker_id)->adjust_during_full_gc();
@@ -814,6 +817,7 @@
   }
 
   void work(uint worker_id) {
+    ShenandoahParallelWorkerSession worker_session(worker_id);
     ShenandoahHeapRegionSetIterator slice(_worker_slices[worker_id]);
 
     ShenandoahCompactObjectsClosure cl(worker_id);
@@ -960,6 +964,7 @@
   }
 
   void work(uint worker_id) {
+    ShenandoahParallelWorkerSession worker_session(worker_id);
     ShenandoahHeapRegion* region = _regions.next();
     ShenandoahHeap* heap = ShenandoahHeap::heap();
     ShenandoahMarkingContext* const ctx = heap->complete_marking_context();
--- a/src/hotspot/share/gc/shenandoah/shenandoahUtils.cpp	Thu May 07 19:18:22 2020 +0100
+++ b/src/hotspot/share/gc/shenandoah/shenandoahUtils.cpp	Thu May 07 17:44:53 2020 -0400
@@ -35,7 +35,7 @@
 #include "gc/shenandoah/shenandoahUtils.hpp"
 #include "utilities/debug.hpp"
 
-ShenandoahPhaseTimings::Phase ShenandoahGCPhase::_current_phase = ShenandoahPhaseTimings::_invalid_phase;
+ShenandoahPhaseTimings::Phase ShenandoahTimingsTracker::_current_phase = ShenandoahPhaseTimings::_invalid_phase;
 
 ShenandoahGCSession::ShenandoahGCSession(GCCause::Cause cause) :
   _heap(ShenandoahHeap::heap()),
@@ -85,7 +85,8 @@
   );
 }
 
-ShenandoahPausePhase::ShenandoahPausePhase(const char* title, bool log_heap_usage) :
+ShenandoahPausePhase::ShenandoahPausePhase(const char* title, ShenandoahPhaseTimings::Phase phase, bool log_heap_usage) :
+  ShenandoahTimingsTracker(phase),
   _tracer(title, NULL, GCCause::_no_gc, log_heap_usage),
   _timer(ShenandoahHeap::heap()->gc_timer()) {
   _timer->register_gc_pause_start(title);
@@ -95,7 +96,8 @@
   _timer->register_gc_pause_end();
 }
 
-ShenandoahConcurrentPhase::ShenandoahConcurrentPhase(const char* title, bool log_heap_usage) :
+ShenandoahConcurrentPhase::ShenandoahConcurrentPhase(const char* title, ShenandoahPhaseTimings::Phase phase, bool log_heap_usage) :
+  ShenandoahTimingsTracker(phase),
   _tracer(title, NULL, GCCause::_no_gc, log_heap_usage),
   _timer(ShenandoahHeap::heap()->gc_timer()) {
   _timer->register_gc_concurrent_start(title);
@@ -105,7 +107,7 @@
   _timer->register_gc_concurrent_end();
 }
 
-ShenandoahGCPhase::ShenandoahGCPhase(ShenandoahPhaseTimings::Phase phase) :
+ShenandoahTimingsTracker::ShenandoahTimingsTracker(ShenandoahPhaseTimings::Phase phase) :
   _timings(ShenandoahHeap::heap()->phase_timings()), _phase(phase) {
   assert(!Thread::current()->is_Worker_thread() &&
               (Thread::current()->is_VM_thread() ||
@@ -116,22 +118,22 @@
   _start = os::elapsedTime();
 }
 
-ShenandoahGCPhase::~ShenandoahGCPhase() {
+ShenandoahTimingsTracker::~ShenandoahTimingsTracker() {
   _timings->record_phase_time(_phase, os::elapsedTime() - _start);
   _current_phase = _parent_phase;
 }
 
-bool ShenandoahGCPhase::is_current_phase_valid() {
+bool ShenandoahTimingsTracker::is_current_phase_valid() {
   return _current_phase < ShenandoahPhaseTimings::_num_phases;
 }
 
-ShenandoahGCSubPhase::ShenandoahGCSubPhase(ShenandoahPhaseTimings::Phase phase) :
-  ShenandoahGCPhase(phase),
+ShenandoahGCPhase::ShenandoahGCPhase(ShenandoahPhaseTimings::Phase phase) :
+  ShenandoahTimingsTracker(phase),
   _timer(ShenandoahHeap::heap()->gc_timer()) {
   _timer->register_gc_phase_start(ShenandoahPhaseTimings::phase_name(phase), Ticks::now());
 }
 
-ShenandoahGCSubPhase::~ShenandoahGCSubPhase() {
+ShenandoahGCPhase::~ShenandoahGCPhase() {
   _timer->register_gc_phase_end(Ticks::now());
 }
 
--- a/src/hotspot/share/gc/shenandoah/shenandoahUtils.hpp	Thu May 07 19:18:22 2020 +0100
+++ b/src/hotspot/share/gc/shenandoah/shenandoahUtils.hpp	Thu May 07 17:44:53 2020 -0400
@@ -54,27 +54,11 @@
   ~ShenandoahGCSession();
 };
 
-class ShenandoahPausePhase : public StackObj {
-private:
-  GCTraceTimeWrapper<LogLevel::Info, LOG_TAGS(gc)> _tracer;
-  ConcurrentGCTimer* const _timer;
-
-public:
-  ShenandoahPausePhase(const char* title, bool log_heap_usage = false);
-  ~ShenandoahPausePhase();
-};
-
-class ShenandoahConcurrentPhase : public StackObj {
-private:
-  GCTraceTimeWrapper<LogLevel::Info, LOG_TAGS(gc)> _tracer;
-  ConcurrentGCTimer* const _timer;
-
-public:
-  ShenandoahConcurrentPhase(const char* title, bool log_heap_usage = false);
-  ~ShenandoahConcurrentPhase();
-};
-
-class ShenandoahGCPhase : public StackObj {
+/*
+ * ShenandoahGCPhaseTiming tracks Shenandoah specific timing information
+ * of a GC phase
+ */
+class ShenandoahTimingsTracker : public StackObj {
 private:
   static ShenandoahPhaseTimings::Phase  _current_phase;
 
@@ -84,21 +68,53 @@
   double _start;
 
 public:
-  ShenandoahGCPhase(ShenandoahPhaseTimings::Phase phase);
-  ~ShenandoahGCPhase();
+  ShenandoahTimingsTracker(ShenandoahPhaseTimings::Phase phase);
+  ~ShenandoahTimingsTracker();
 
   static ShenandoahPhaseTimings::Phase current_phase() { return _current_phase; }
 
   static bool is_current_phase_valid();
 };
 
-class ShenandoahGCSubPhase: public ShenandoahGCPhase {
+/*
+ * ShenandoahPausePhase tracks a STW pause and emits Shenandoah timing and
+ * a corresponding JFR event
+ */
+class ShenandoahPausePhase : public ShenandoahTimingsTracker {
+private:
+  GCTraceTimeWrapper<LogLevel::Info, LOG_TAGS(gc)> _tracer;
+  ConcurrentGCTimer* const _timer;
+
+public:
+  ShenandoahPausePhase(const char* title, ShenandoahPhaseTimings::Phase phase, bool log_heap_usage = false);
+  ~ShenandoahPausePhase();
+};
+
+/*
+ * ShenandoahConcurrentPhase tracks a concurrent GC phase and emits Shenandoah timing and
+ * a corresponding JFR event
+ */
+class ShenandoahConcurrentPhase : public ShenandoahTimingsTracker {
+private:
+  GCTraceTimeWrapper<LogLevel::Info, LOG_TAGS(gc)> _tracer;
+  ConcurrentGCTimer* const _timer;
+
+public:
+  ShenandoahConcurrentPhase(const char* title, ShenandoahPhaseTimings::Phase phase, bool log_heap_usage = false);
+  ~ShenandoahConcurrentPhase();
+};
+
+/*
+ * ShenandoahGCPhase tracks Shenandoah specific timing information
+ * and emits a corresponding JFR event of a GC phase
+ */
+class ShenandoahGCPhase : public ShenandoahTimingsTracker {
 private:
   ConcurrentGCTimer* const _timer;
 
 public:
-  ShenandoahGCSubPhase(ShenandoahPhaseTimings::Phase phase);
-  ~ShenandoahGCSubPhase();
+  ShenandoahGCPhase(ShenandoahPhaseTimings::Phase phase);
+  ~ShenandoahGCPhase();
 };
 
 class ShenandoahGCWorkerPhase : public StackObj {