diff a/src/hotspot/share/gc/shenandoah/shenandoahPhaseTimings.cpp b/src/hotspot/share/gc/shenandoah/shenandoahPhaseTimings.cpp
--- a/src/hotspot/share/gc/shenandoah/shenandoahPhaseTimings.cpp
+++ b/src/hotspot/share/gc/shenandoah/shenandoahPhaseTimings.cpp
@@ -1,7 +1,8 @@
 /*
  * Copyright (c) 2017, 2021, Red Hat, Inc. All rights reserved.
+ * Copyright Amazon.com Inc. or its affiliates. All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 only, as
  * published by the Free Software Foundation.
@@ -95,10 +96,11 @@
 
 bool ShenandoahPhaseTimings::is_worker_phase(Phase phase) {
   assert(phase >= 0 && phase < _num_phases, "Out of bounds");
   switch (phase) {
     case init_evac:
+    case init_scan_rset:
     case finish_mark:
     case purge_weak_par:
     case full_gc_mark:
     case full_gc_update_roots:
     case full_gc_adjust_roots:
@@ -106,19 +108,22 @@
     case degen_gc_mark:
     case degen_gc_update_roots:
     case full_gc_weakrefs:
     case full_gc_purge_class_unload:
     case full_gc_purge_weak_par:
+    case degen_gc_coalesce_and_fill:
     case degen_gc_weakrefs:
     case degen_gc_purge_class_unload:
     case degen_gc_purge_weak_par:
     case heap_iteration_roots:
+    case conc_mark:
     case conc_mark_roots:
     case conc_thread_roots:
     case conc_weak_roots_work:
     case conc_weak_refs:
     case conc_strong_roots:
+    case conc_coalesce_and_fill:
       return true;
     default:
       return false;
   }
 }
@@ -135,21 +140,25 @@
     default:
       return false;
   }
 }
 
-void ShenandoahPhaseTimings::set_cycle_data(Phase phase, double time) {
+void ShenandoahPhaseTimings::set_cycle_data(Phase phase, double time, bool should_aggregate) {
+  const double cycle_data = _cycle_data[phase];
+  if (should_aggregate) {
+    _cycle_data[phase] = (cycle_data == uninitialized()) ? time :  (cycle_data + time);
+  } else {
 #ifdef ASSERT
-  double d = _cycle_data[phase];
-  assert(d == uninitialized(), "Should not be set yet: %s, current value: %lf", phase_name(phase), d);
+    assert(cycle_data == uninitialized(), "Should not be set yet: %s, current value: %lf", phase_name(phase), cycle_data);
 #endif
-  _cycle_data[phase] = time;
+    _cycle_data[phase] = time;
+  }
 }
 
-void ShenandoahPhaseTimings::record_phase_time(Phase phase, double time) {
+void ShenandoahPhaseTimings::record_phase_time(Phase phase, double time, bool should_aggregate) {
   if (!_policy->is_at_shutdown()) {
-    set_cycle_data(phase, time);
+    set_cycle_data(phase, time, should_aggregate);
   }
 }
 
 void ShenandoahPhaseTimings::record_workers_start(Phase phase) {
   assert(is_worker_phase(phase), "Phase should accept worker phase times: %s", phase_name(phase));
@@ -306,24 +315,23 @@
     }
   }
 }
 
 ShenandoahWorkerTimingsTracker::ShenandoahWorkerTimingsTracker(ShenandoahPhaseTimings::Phase phase,
-        ShenandoahPhaseTimings::ParPhase par_phase, uint worker_id) :
+        ShenandoahPhaseTimings::ParPhase par_phase, uint worker_id, bool cumulative) :
         _timings(ShenandoahHeap::heap()->phase_timings()),
         _phase(phase), _par_phase(par_phase), _worker_id(worker_id) {
 
-  assert(_timings->worker_data(_phase, _par_phase)->get(_worker_id) == ShenandoahWorkerData::uninitialized(),
+  assert(_timings->worker_data(_phase, _par_phase)->get(_worker_id) == ShenandoahWorkerData::uninitialized() || cumulative,
          "Should not be set yet: %s", ShenandoahPhaseTimings::phase_name(_timings->worker_par_phase(_phase, _par_phase)));
   _start_time = os::elapsedTime();
 }
 
 ShenandoahWorkerTimingsTracker::~ShenandoahWorkerTimingsTracker() {
-  _timings->worker_data(_phase, _par_phase)->set(_worker_id, os::elapsedTime() - _start_time);
+  _timings->worker_data(_phase, _par_phase)->set_or_add(_worker_id, os::elapsedTime() - _start_time);
 
   if (ShenandoahPhaseTimings::is_root_work_phase(_phase)) {
     ShenandoahPhaseTimings::Phase root_phase = _phase;
     ShenandoahPhaseTimings::Phase cur_phase = _timings->worker_par_phase(root_phase, _par_phase);
     _event.commit(GCId::current(), _worker_id, ShenandoahPhaseTimings::phase_name(cur_phase));
   }
 }
-
