1 /*
  2  * Copyright (c) 2017, 2019, Red Hat, Inc. All rights reserved.
  3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  4  *
  5  * This code is free software; you can redistribute it and/or modify it
  6  * under the terms of the GNU General Public License version 2 only, as
  7  * published by the Free Software Foundation.
  8  *
  9  * This code is distributed in the hope that it will be useful, but WITHOUT
 10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 12  * version 2 for more details (a copy is included in the LICENSE file that
 13  * accompanied this code).
 14  *
 15  * You should have received a copy of the GNU General Public License version
 16  * 2 along with this work; if not, write to the Free Software Foundation,
 17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 18  *
 19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 20  * or visit www.oracle.com if you need additional information or have any
 21  * questions.
 22  *
 23  */
 24 
 25 #ifndef SHARE_GC_SHENANDOAH_SHENANDOAHPHASETIMINGS_HPP
 26 #define SHARE_GC_SHENANDOAH_SHENANDOAHPHASETIMINGS_HPP
 27 
 28 #include "gc/shenandoah/shenandoahNumberSeq.hpp"
 29 #include "gc/shared/workerDataArray.hpp"
 30 #include "memory/allocation.hpp"
 31 
 32 class ShenandoahCollectorPolicy;
 33 class ShenandoahWorkerTimings;
 34 class ShenandoahTerminationTimings;
 35 class outputStream;
 36 
 37 #define SHENANDOAH_GC_PHASE_DO(f)                                                       \
 38   f(total_pause_gross,                              "Total Pauses (G)")                 \
 39   f(total_pause,                                    "Total Pauses (N)")                 \
 40   f(init_mark_gross,                                "Pause Init Mark (G)")              \
 41   f(init_mark,                                      "Pause Init Mark (N)")              \
 42   f(make_parsable,                                  "  Make Parsable")                  \
 43   f(clear_liveness,                                 "  Clear Liveness")                 \
 44                                                                                         \
 45   /* Per-thread timer block, should have "roots" counters in consistent order */        \
 46   f(scan_roots,                                     "  Scan Roots")                     \
 47   f(scan_thread_roots,                              "    S: Thread Roots")              \
 48   f(scan_code_roots,                                "    S: Code Cache Roots")          \
 49   f(scan_universe_roots,                            "    S: Universe Roots")            \
 50   f(scan_jni_roots,                                 "    S: JNI Roots")                 \
 51   f(scan_jvmti_weak_roots,                          "    S: JVMTI Weak Roots")          \
 52   f(scan_jfr_weak_roots,                            "    S: JFR Weak Roots")            \
 53   f(scan_jni_weak_roots,                            "    S: JNI Weak Roots")            \
 54   f(scan_stringtable_roots,                         "    S: String Table Roots")        \
 55   f(scan_resolved_method_table_roots,               "    S: Resolved Table Roots")      \
 56   f(scan_vm_global_roots,                           "    S: VM Global Roots")           \
 57   f(scan_vm_weak_roots,                             "    S: VM Weak Roots")             \
 58   f(scan_synchronizer_roots,                        "    S: Synchronizer Roots")        \
 59   f(scan_management_roots,                          "    S: Management Roots")          \
 60   f(scan_system_dictionary_roots,                   "    S: System Dict Roots")         \
 61   f(scan_cldg_roots,                                "    S: CLDG Roots")                \
 62   f(scan_jvmti_roots,                               "    S: JVMTI Roots")               \
 63   f(scan_string_dedup_table_roots,                  "    S: Dedup Table Roots")         \
 64   f(scan_string_dedup_queue_roots,                  "    S: Dedup Queue Roots")         \
 65   f(scan_finish_queues,                             "    S: Finish Queues" )            \
 66                                                                                         \
 67   f(resize_tlabs,                                   "  Resize TLABs")                   \
 68                                                                                         \
 69   f(final_mark_gross,                               "Pause Final Mark (G)")             \
 70   f(final_mark,                                     "Pause Final Mark (N)")             \
 71                                                                                         \
 72   /* Per-thread timer block, should have "roots" counters in consistent order */        \
 73   f(update_roots,                                   "  Update Roots")                   \
 74   f(update_thread_roots,                            "    U: Thread Roots")              \
 75   f(update_code_roots,                              "    U: Code Cache Roots")          \
 76   f(update_universe_roots,                          "    U: Universe Roots")            \
 77   f(update_jni_roots,                               "    U: JNI Roots")                 \
 78   f(update_jvmti_weak_roots,                        "    U: JVMTI Weak Roots")          \
 79   f(update_jfr_weak_roots,                          "    U: JFR Weak Roots")            \
 80   f(update_jni_weak_roots,                          "    U: JNI Weak Roots")            \
 81   f(update_stringtable_roots,                       "    U: String Table Roots")        \
 82   f(update_resolved_method_table_roots,             "    U: Resolved Table Roots")      \
 83   f(update_vm_global_roots,                         "    U: VM Global Roots")           \
 84   f(update_vm_weak_roots,                           "    U: VM Weak Roots")             \
 85   f(update_synchronizer_roots,                      "    U: Synchronizer Roots")        \
 86   f(update_management_roots,                        "    U: Management Roots")          \
 87   f(update_system_dictionary_roots,                 "    U: System Dict Roots")         \
 88   f(update_cldg_roots,                              "    U: CLDG Roots")                \
 89   f(update_jvmti_roots,                             "    U: JVMTI Roots")               \
 90   f(update_string_dedup_table_roots,                "    U: Dedup Table Roots")         \
 91   f(update_string_dedup_queue_roots,                "    U: Dedup Queue Roots")         \
 92   f(update_finish_queues,                           "    U: Finish Queues")             \
 93                                                                                         \
 94   f(finish_queues,                                  "  Finish Queues")                  \
 95   f(termination,                                    "    Termination")                  \
 96   f(weakrefs,                                       "  Weak References")                \
 97   f(weakrefs_process,                               "    Process")                      \
 98   f(weakrefs_termination,                           "      Termination")                \
 99   f(purge,                                          "  System Purge")                   \
100   f(purge_class_unload,                             "    Unload Classes")               \
101   f(purge_par,                                      "    Parallel Cleanup")             \
102   f(purge_cldg,                                     "    CLDG")                         \
103   f(complete_liveness,                              "  Complete Liveness")              \
104   f(retire_tlabs,                                   "  Retire TLABs")                   \
105   f(sync_pinned,                                    "  Sync Pinned")                    \
106   f(trash_cset,                                     "  Trash CSet")                     \
107   f(prepare_evac,                                   "  Prepare Evacuation")             \
108                                                                                         \
109   /* Per-thread timer block, should have "roots" counters in consistent order */        \
110   f(init_evac,                                      "  Initial Evacuation")             \
111   f(evac_thread_roots,                              "    E: Thread Roots")              \
112   f(evac_code_roots,                                "    E: Code Cache Roots")          \
113   f(evac_universe_roots,                            "    E: Universe Roots")            \
114   f(evac_jni_roots,                                 "    E: JNI Roots")                 \
115   f(evac_jvmti_weak_roots,                          "    E: JVMTI Weak Roots")          \
116   f(evac_jfr_weak_roots,                            "    E: JFR Weak Roots")            \
117   f(evac_jni_weak_roots,                            "    E: JNI Weak Roots")            \
118   f(evac_stringtable_roots,                         "    E: String Table Roots")        \
119   f(evac_resolved_method_table_roots,               "    E: Resolved Table Roots")      \
120   f(evac_vm_global_roots,                           "    E: VM Global Roots")           \
121   f(evac_vm_weak_roots,                             "    E: VM Weak Roots")             \
122   f(evac_synchronizer_roots,                        "    E: Synchronizer Roots")        \
123   f(evac_management_roots,                          "    E: Management Roots")          \
124   f(evac_system_dictionary_roots,                   "    E: System Dict Roots")         \
125   f(evac_cldg_roots,                                "    E: CLDG Roots")                \
126   f(evac_jvmti_roots,                               "    E: JVMTI Roots")               \
127   f(evac_string_dedup_table_roots,                  "    E: String Dedup Table Roots")  \
128   f(evac_string_dedup_queue_roots,                  "    E: String Dedup Queue Roots")  \
129   f(evac_finish_queues,                             "    E: Finish Queues")             \
130                                                                                         \
131   f(final_evac_gross,                               "Pause Final Evac (G)")             \
132   f(final_evac,                                     "Pause Final Evac (N)")             \
133   f(final_evac_retire_gclabs,                       "  Retire GCLABs")                  \
134                                                                                         \
135   f(init_update_refs_gross,                         "Pause Init  Update Refs (G)")      \
136   f(init_update_refs,                               "Pause Init  Update Refs (N)")      \
137   f(init_update_refs_retire_gclabs,                 "  Retire GCLABs")                  \
138   f(init_update_refs_prepare,                       "  Prepare")                        \
139                                                                                         \
140   f(final_update_refs_gross,                         "Pause Final Update Refs (G)")     \
141   f(final_update_refs,                               "Pause Final Update Refs (N)")     \
142   f(final_update_refs_finish_work,                   "  Finish Work")                   \
143                                                                                         \
144   /* Per-thread timer block, should have "roots" counters in consistent order */        \
145   f(final_update_refs_roots,                         "  Update Roots")                  \
146   f(final_update_refs_thread_roots,                  "    UR: Thread Roots")            \
147   f(final_update_refs_code_roots,                    "    UR: Code Cache Roots")        \
148   f(final_update_refs_universe_roots,                "    UR: Universe Roots")          \
149   f(final_update_refs_jni_roots,                     "    UR: JNI Roots")               \
150   f(final_update_jvmti_weak_roots,                   "    UR: JVMTI Weak Roots")        \
151   f(final_update_jfr_weak_roots,                     "    UR: JFR Weak Roots")          \
152   f(final_update_jni_weak_roots,                     "    UR: JNI Weak Roots")          \
153   f(final_update_stringtable_roots,                  "    UR: String Table Roots")      \
154   f(final_update_resolved_method_table_roots,        "    UR: Resolved Table Roots")    \
155   f(final_update_vm_global_roots,                    "    UR: VM Global Roots")         \
156   f(final_update_vm_weak_roots,                      "    UR: VM Weak Roots")           \
157   f(final_update_refs_synchronizer_roots,            "    UR: Synchronizer Roots")      \
158   f(final_update_refs_management_roots,              "    UR: Management Roots")        \
159   f(final_update_refs_system_dict_roots,             "    UR: System Dict Roots")       \
160   f(final_update_refs_cldg_roots,                    "    UR: CLDG Roots")              \
161   f(final_update_refs_jvmti_roots,                   "    UR: JVMTI Roots")             \
162   f(final_update_refs_string_dedup_table_roots,      "    UR: Dedup Table Roots")       \
163   f(final_update_refs_string_dedup_queue_roots,      "    UR: Dedup Queue Roots")       \
164   f(final_update_refs_finish_queues,                 "    UR: Finish Queues")           \
165                                                                                         \
166   f(final_update_refs_sync_pinned,                   "  Sync Pinned")                   \
167   f(final_update_refs_trash_cset,                    "  Trash CSet")                    \
168                                                                                         \
169   f(degen_gc_gross,                                  "Pause Degenerated GC (G)")        \
170   f(degen_gc,                                        "Pause Degenerated GC (N)")        \
171                                                                                         \
172   /* Per-thread timer block, should have "roots" counters in consistent order */        \
173   f(degen_gc_update_roots,                           "  Degen Update Roots")            \
174   f(degen_gc_update_thread_roots,                    "    DU: Thread Roots")            \
175   f(degen_gc_update_code_roots,                      "    DU: Code Cache Roots")        \
176   f(degen_gc_update_universe_roots,                  "    DU: Universe Roots")          \
177   f(degen_gc_update_jni_roots,                       "    DU: JNI Roots")               \
178   f(degen_gc_update_jvmti_weak_roots,                "    DU: JVMTI Weak Roots")        \
179   f(degen_gc_update_jfr_weak_roots,                  "    DU: JFR Weak Roots")          \
180   f(degen_gc_update_jni_weak_roots,                  "    DU: JNI Weak Roots")          \
181   f(degen_gc_update_stringtable_roots,               "    DU: String Table Roots")      \
182   f(degen_gc_update_resolved_method_table_roots,     "    DU: Resolved Table Roots")    \
183   f(degen_gc_update_vm_global_roots,                 "    DU: VM Global Roots")         \
184   f(degen_gc_update_vm_weak_roots,                   "    DU: VM Weak Roots")           \
185   f(degen_gc_update_synchronizer_roots,              "    DU: Synchronizer Roots")      \
186   f(degen_gc_update_management_roots,                "    DU: Management Roots")        \
187   f(degen_gc_update_system_dict_roots,               "    DU: System Dict Roots")       \
188   f(degen_gc_update_cldg_roots,                      "    DU: CLDG Roots")              \
189   f(degen_gc_update_jvmti_roots,                     "    DU: JVMTI Roots")             \
190   f(degen_gc_update_string_dedup_table_roots,        "    DU: Dedup Table Roots")       \
191   f(degen_gc_update_string_dedup_queue_roots,        "    DU: Dedup Queue Roots")       \
192   f(degen_gc_update_finish_queues,                   "    DU: Finish Queues")           \
193                                                                                         \
194   f(init_traversal_gc_gross,                         "Pause Init Traversal (G)")        \
195   f(init_traversal_gc,                               "Pause Init Traversal (N)")        \
196   f(traversal_gc_prepare,                            "  Prepare")                       \
197   f(traversal_gc_make_parsable,                      "    Make Parsable")               \
198   f(traversal_gc_resize_tlabs,                       "    Resize TLABs")                \
199   f(traversal_gc_prepare_sync_pinned,                "    Sync Pinned")                 \
200                                                                                         \
201   /* Per-thread timer block, should have "roots" counters in consistent order */        \
202   f(init_traversal_gc_work,                          "  Work")                          \
203   f(init_traversal_gc_thread_roots,                  "    TI: Thread Roots")            \
204   f(init_traversal_gc_code_roots,                    "    TI: Code Cache Roots")        \
205   f(init_traversal_gc_universe_roots,                "    TI: Universe Roots")          \
206   f(init_traversal_gc_jni_roots,                     "    TI: JNI Roots")               \
207   f(init_traversal_gc_jvmti_weak_roots,              "    TI: JVMTI Weak Roots")        \
208   f(init_traversal_gc_jfr_weak_roots,                "    TI: JFR Weak Roots")          \
209   f(init_traversal_gc_jni_weak_roots,                "    TI: JNI Weak Roots")          \
210   f(init_traversal_gc_stringtable_roots,             "    TI: String Table Roots")      \
211   f(init_traversal_gc_resolved_method_table_roots,   "    TI: Resolved Table Roots")    \
212   f(init_traversal_gc_vm_global_roots,               "    TI: VM Global Roots")         \
213   f(init_traversal_gc_vm_weak_roots,                 "    TI: VM Weak Roots")           \
214   f(init_traversal_gc_synchronizer_roots,            "    TI: Synchronizer Roots")      \
215   f(init_traversal_gc_management_roots,              "    TI: Management Roots")        \
216   f(init_traversal_gc_system_dict_roots,             "    TI: System Dict Roots")       \
217   f(init_traversal_gc_cldg_roots,                    "    TI: CLDG Roots")              \
218   f(init_traversal_gc_jvmti_roots,                   "    TI: JVMTI Roots")             \
219   f(init_traversal_gc_string_dedup_table_roots,      "    TI: Dedup Table Roots")       \
220   f(init_traversal_gc_string_dedup_queue_roots,      "    TI: Dedup Queue Roots")       \
221   f(init_traversal_gc_finish_queues,                 "    TI: Finish Queues")           \
222                                                                                         \
223   f(final_traversal_gc_gross,                        "Pause Final Traversal (G)")       \
224   f(final_traversal_gc,                              "Pause Final Traversal (N)")       \
225                                                                                         \
226   /* Per-thread timer block, should have "roots" counters in consistent order */        \
227   f(final_traversal_gc_work,                         "  Work")                          \
228   f(final_traversal_gc_thread_roots,                 "    TF: Thread Roots")            \
229   f(final_traversal_gc_code_roots,                   "    TF: Code Cache Roots")        \
230   f(final_traversal_gc_universe_roots,               "    TF: Universe Roots")          \
231   f(final_traversal_gc_jni_roots,                    "    TF: JNI Roots")               \
232   f(final_traversal_gc_jvmti_weak_roots,             "    TF: JVMTI Weak Roots")        \
233   f(final_traversal_gc_jfr_weak_roots,               "    TF: JFR Weak Roots")          \
234   f(final_traversal_gc_jni_weak_roots,               "    TF: JNI Weak Roots")          \
235   f(final_traversal_gc_stringtable_roots,            "    TF: String Table Roots")      \
236   f(final_traversal_gc_resolved_method_table_roots,  "    TF: Resolved Table Roots")    \
237   f(final_traversal_gc_vm_global_roots,              "    TF: VM Global Roots")         \
238   f(final_traversal_gc_vm_weak_roots,                "    TF: VM Weak Roots")           \
239   f(final_traversal_gc_synchronizer_roots,           "    TF: Synchronizer Roots")      \
240   f(final_traversal_gc_management_roots,             "    TF: Management Roots")        \
241   f(final_traversal_gc_system_dict_roots,            "    TF: System Dict Roots")       \
242   f(final_traversal_gc_cldg_roots,                   "    TF: CLDG Roots")              \
243   f(final_traversal_gc_jvmti_roots,                  "    TF: JVMTI Roots")             \
244   f(final_traversal_gc_string_dedup_table_roots,     "    TF: Dedup Table Roots")       \
245   f(final_traversal_gc_string_dedup_queue_roots,     "    TF: Dedup Queue Roots")       \
246   f(final_traversal_gc_finish_queues,                "    TF: Finish Queues")           \
247   f(final_traversal_gc_termination,                  "    TF:   Termination")           \
248                                                                                         \
249   /* Per-thread timer block, should have "roots" counters in consistent order */        \
250   f(final_traversal_update_roots,                       "  Update Roots")               \
251   f(final_traversal_update_thread_roots,                "    TU: Thread Roots")         \
252   f(final_traversal_update_code_roots,                  "    TU: Code Cache Roots")     \
253   f(final_traversal_update_universe_roots,              "    TU: Universe Roots")       \
254   f(final_traversal_update_jni_roots,                   "    TU: JNI Roots")            \
255   f(final_traversal_update_jvmti_weak_roots,            "    TU: JVMTI Weak Roots")     \
256   f(final_traversal_update_jfr_weak_roots,              "    TU: JFR Weak Roots")       \
257   f(final_traversal_update_jni_weak_roots,              "    TU: JNI Weak Roots")       \
258   f(final_traversal_update_stringtable_roots,           "    TU: String Table Roots")   \
259   f(final_traversal_update_resolved_method_table_roots, "    TU: Resolved Table Roots") \
260   f(final_traversal_update_vm_global_roots,             "    TU: VM Global Roots")      \
261   f(final_traversal_update_vm_weak_roots,               "    TU: VM Weak Roots")        \
262   f(final_traversal_update_synchronizer_roots,          "    TU: Synchronizer Roots")   \
263   f(final_traversal_update_management_roots,            "    TU: Management Roots")     \
264   f(final_traversal_update_system_dict_roots,           "    TU: System Dict Roots")    \
265   f(final_traversal_update_cldg_roots,                  "    TU: CLDG Roots")           \
266   f(final_traversal_update_jvmti_roots,                 "    TU: JVMTI Roots")          \
267   f(final_traversal_update_string_dedup_table_roots,    "    TU: Dedup Table Roots")    \
268   f(final_traversal_update_string_dedup_queue_roots,    "    TU: Dedup Queue Roots")    \
269   f(final_traversal_update_finish_queues,               "    TU: Finish Queues")        \
270                                                                                         \
271   f(traversal_gc_sync_pinned,                        "  Sync Pinned")                   \
272   f(traversal_gc_cleanup,                            "  Cleanup")                       \
273                                                                                         \
274   f(full_gc_gross,                                   "Pause Full GC (G)")               \
275   f(full_gc,                                         "Pause Full GC (N)")               \
276   f(full_gc_heapdumps,                               "  Heap Dumps")                    \
277   f(full_gc_prepare,                                 "  Prepare")                       \
278                                                                                         \
279   /* Per-thread timer block, should have "roots" counters in consistent order */        \
280   f(full_gc_roots,                                   "  Roots")                         \
281   f(full_gc_thread_roots,                            "    F: Thread Roots")             \
282   f(full_gc_code_roots,                              "    F: Code Cache Roots")         \
283   f(full_gc_universe_roots,                          "    F: Universe Roots")           \
284   f(full_gc_jni_roots,                               "    F: JNI Roots")                \
285   f(full_gc_jvmti_weak_roots,                        "    F: JVMTI Weak Roots")         \
286   f(full_gc_jfr_weak_roots,                          "    F: JFR Weak Roots")           \
287   f(full_gc_jni_weak_roots,                          "    F: JNI Weak Roots")           \
288   f(full_gc_stringtable_roots,                       "    F: String Table Roots")       \
289   f(full_gc_resolved_method_table_roots,             "    F: Resolved Table Roots")     \
290   f(full_gc_vm_global_roots,                         "    F: VM Global Roots")          \
291   f(full_gc_vm_weak_roots,                           "    F: VM Weak Roots")            \
292   f(full_gc_synchronizer_roots,                      "    F: Synchronizer Roots")       \
293   f(full_gc_management_roots,                        "    F: Management Roots")         \
294   f(full_gc_system_dictionary_roots,                 "    F: System Dict Roots")        \
295   f(full_gc_cldg_roots,                              "    F: CLDG Roots")               \
296   f(full_gc_jvmti_roots,                             "    F: JVMTI Roots")              \
297   f(full_gc_string_dedup_table_roots,                "    F: Dedup Table Roots")        \
298   f(full_gc_string_dedup_queue_roots,                "    F: Dedup Queue Roots")        \
299   f(full_gc_finish_queues,                           "    F: Finish Queues")            \
300                                                                                         \
301   f(full_gc_mark,                                    "  Mark")                          \
302   f(full_gc_mark_finish_queues,                      "    Finish Queues")               \
303   f(full_gc_mark_termination,                        "      Termination")               \
304   f(full_gc_weakrefs,                                "    Weak References")             \
305   f(full_gc_weakrefs_process,                        "      Process")                   \
306   f(full_gc_weakrefs_termination,                    "        Termination")             \
307   f(full_gc_purge,                                   "    System Purge")                \
308   f(full_gc_purge_class_unload,                      "      Unload Classes")            \
309   f(full_gc_purge_par,                               "    Parallel Cleanup")            \
310   f(full_gc_purge_cldg,                              "    CLDG")                        \
311   f(full_gc_calculate_addresses,                     "  Calculate Addresses")           \
312   f(full_gc_calculate_addresses_regular,             "    Regular Objects")             \
313   f(full_gc_calculate_addresses_humong,              "    Humongous Objects")           \
314   f(full_gc_adjust_pointers,                         "  Adjust Pointers")               \
315   f(full_gc_copy_objects,                            "  Copy Objects")                  \
316   f(full_gc_copy_objects_regular,                    "    Regular Objects")             \
317   f(full_gc_copy_objects_humong,                     "    Humongous Objects")           \
318   f(full_gc_copy_objects_reset_complete,             "    Reset Complete Bitmap")       \
319   f(full_gc_copy_objects_rebuild,                    "    Rebuild Region Sets")         \
320   f(full_gc_resize_tlabs,                            "  Resize TLABs")                  \
321                                                                                         \
322   /* Longer concurrent phases at the end */                                             \
323   f(conc_reset,                                      "Concurrent Reset")                \
324   f(conc_mark,                                       "Concurrent Marking")              \
325   f(conc_termination,                                "  Termination")                   \
326   f(conc_preclean,                                   "Concurrent Precleaning")          \
327   f(conc_roots,                                      "Concurrent Roots")                \
328   f(conc_evac,                                       "Concurrent Evacuation")           \
329   f(conc_update_refs,                                "Concurrent Update Refs")          \
330   f(conc_cleanup,                                    "Concurrent Cleanup")              \
331   f(conc_traversal,                                  "Concurrent Traversal")            \
332   f(conc_traversal_termination,                      "  Termination")                   \
333                                                                                         \
334   f(conc_uncommit,                                   "Concurrent Uncommit")             \
335                                                                                         \
336   /* Unclassified */                                                                    \
337   f(pause_other,                                     "Pause Other")                     \
338   f(conc_other,                                      "Concurrent Other")                \
339   // end
340 
341 #define SHENANDOAH_GC_PAR_PHASE_DO(f)                           \
342   f(ThreadRoots,              "Thread Roots (ms):")              \
343   f(CodeCacheRoots,           "CodeCache Roots (ms):")           \
344   f(UniverseRoots,            "Universe Roots (ms):")            \
345   f(JNIRoots,                 "JNI Handles Roots (ms):")         \
346   f(JVMTIWeakRoots,           "JVMTI Weak Roots (ms):")          \
347   f(JFRWeakRoots,             "JFR Weak Roots (ms):")            \
348   f(TSANWeakRoots,            "TSAN Weak Roots (ms):")           \
349   f(JNIWeakRoots,             "JNI Weak Roots (ms):")            \
350   f(StringTableRoots,         "StringTable Roots(ms):")          \
351   f(ResolvedMethodTableRoots, "Resolved Table Roots(ms):")       \
352   f(VMGlobalRoots,            "VM Global Roots(ms)")             \
353   f(VMWeakRoots,              "VM Weak Roots(ms)")               \
354   f(ObjectSynchronizerRoots,  "ObjectSynchronizer Roots (ms):")  \
355   f(ManagementRoots,          "Management Roots (ms):")          \
356   f(SystemDictionaryRoots,    "SystemDictionary Roots (ms):")    \
357   f(CLDGRoots,                "CLDG Roots (ms):")                \
358   f(JVMTIRoots,               "JVMTI Roots (ms):")               \
359   f(StringDedupTableRoots,    "String Dedup Table Roots (ms):")  \
360   f(StringDedupQueueRoots,    "String Dedup Queue Roots (ms):")  \
361   f(FinishQueues,             "Finish Queues (ms):")             \
362   // end
363 
364 class ShenandoahPhaseTimings : public CHeapObj<mtGC> {
365 public:
366 #define GC_PHASE_DECLARE_ENUM(type, title)   type,
367 
368   enum Phase {
369     SHENANDOAH_GC_PHASE_DO(GC_PHASE_DECLARE_ENUM)
370     _num_phases
371   };
372 
373   // These are the subphases of GC phases (scan_roots, update_roots,
374   // init_evac, final_update_refs_roots and full_gc_roots).
375   // Make sure they are following this order.
376   enum GCParPhases {
377     SHENANDOAH_GC_PAR_PHASE_DO(GC_PHASE_DECLARE_ENUM)
378     GCParPhasesSentinel
379   };
380 
381 #undef GC_PHASE_DECLARE_ENUM
382 
383 private:
384   struct TimingData {
385     HdrSeq _secs;
386     double _start;
387   };
388 
389 private:
390   TimingData          _timing_data[_num_phases];
391   static const char*  _phase_names[_num_phases];
392 
393   ShenandoahWorkerTimings*      _worker_times;
394   ShenandoahTerminationTimings* _termination_times;
395 
396   ShenandoahCollectorPolicy* _policy;
397 
398 public:
399   ShenandoahPhaseTimings();
400 
401   ShenandoahWorkerTimings* const worker_times() const { return _worker_times; }
402   ShenandoahTerminationTimings* const termination_times() const { return _termination_times; }
403 
404   // record phase start
405   void record_phase_start(Phase phase);
406   // record phase end and return elapsed time in seconds for the phase
407   void record_phase_end(Phase phase);
408   // record an elapsed time for the phase
409   void record_phase_time(Phase phase, double time);
410 
411   void record_workers_start(Phase phase);
412   void record_workers_end(Phase phase);
413 
414   static const char* phase_name(Phase phase) {
415     assert(phase >= 0 && phase < _num_phases, "Out of bound");
416     return _phase_names[phase];
417   }
418 
419   void print_on(outputStream* out) const;
420 
421 private:
422   void init_phase_names();
423   void print_summary_sd(outputStream* out, const char* str, const HdrSeq* seq) const;
424 };
425 
426 class ShenandoahWorkerTimings : public CHeapObj<mtGC> {
427 private:
428   uint _max_gc_threads;
429   WorkerDataArray<double>* _gc_par_phases[ShenandoahPhaseTimings::GCParPhasesSentinel];
430 
431 public:
432   ShenandoahWorkerTimings(uint max_gc_threads);
433 
434   // record the time a phase took in seconds
435   void record_time_secs(ShenandoahPhaseTimings::GCParPhases phase, uint worker_i, double secs);
436 
437   double average(uint i) const;
438   void reset(uint i);
439   void print() const;
440 };
441 
442 class ShenandoahTerminationTimings : public CHeapObj<mtGC> {
443 private:
444   WorkerDataArray<double>* _gc_termination_phase;
445 public:
446   ShenandoahTerminationTimings(uint max_gc_threads);
447 
448   // record the time a phase took in seconds
449   void record_time_secs(uint worker_i, double secs);
450 
451   double average() const;
452   void reset();
453 
454   void print() const;
455 };
456 
457 #endif // SHARE_GC_SHENANDOAH_SHENANDOAHPHASETIMINGS_HPP