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