1 2 /* 3 * Copyright (c) 2017, Red Hat, Inc. and/or its affiliates. 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_VM_GC_SHENANDOAH_SHENANDOAHPHASETIMEINGS_HPP 26 #define SHARE_VM_GC_SHENANDOAH_SHENANDOAHPHASETIMEINGS_HPP 27 28 #include "gc/shared/workerDataArray.hpp" 29 #include "memory/allocation.hpp" 30 #include "utilities/numberSeq.hpp" 31 32 class ShenandoahCollectorPolicy; 33 class ShenandoahWorkerTimings; 34 class outputStream; 35 36 class ShenandoahPhaseTimings : public CHeapObj<mtGC> { 37 public: 38 enum Phase { 39 total_pause_gross, 40 total_pause, 41 42 init_mark_gross, 43 init_mark, 44 accumulate_stats, 45 make_parsable, 46 clear_liveness, 47 48 // Per-thread timer block, should have "roots" counters in consistent order 49 scan_roots, 50 scan_thread_roots, 51 scan_code_roots, 52 scan_string_table_roots, 53 scan_universe_roots, 54 scan_jni_roots, 55 scan_jni_weak_roots, 56 scan_synchronizer_roots, 57 scan_flat_profiler_roots, 58 scan_management_roots, 59 scan_system_dictionary_roots, 60 scan_cldg_roots, 61 scan_jvmti_roots, 62 scan_string_dedup_roots, 63 scan_finish_queues, 64 65 resize_tlabs, 66 67 final_mark_gross, 68 final_mark, 69 70 // Per-thread timer block, should have "roots" counters in consistent order 71 update_roots, 72 update_thread_roots, 73 update_code_roots, 74 update_string_table_roots, 75 update_universe_roots, 76 update_jni_roots, 77 update_jni_weak_roots, 78 update_synchronizer_roots, 79 update_flat_profiler_roots, 80 update_management_roots, 81 update_system_dictionary_roots, 82 update_cldg_roots, 83 update_jvmti_roots, 84 update_string_dedup_roots, 85 update_finish_queues, 86 87 finish_queues, 88 weakrefs, 89 weakrefs_process, 90 weakrefs_enqueue, 91 purge, 92 purge_class_unload, 93 purge_par, 94 purge_par_codecache, 95 purge_par_symbstring, 96 purge_par_rmt, 97 purge_par_classes, 98 purge_par_sync, 99 purge_par_string_dedup, 100 purge_cldg, 101 prepare_evac, 102 recycle_regions, 103 104 // Per-thread timer block, should have "roots" counters in consistent order 105 init_evac, 106 evac_thread_roots, 107 evac_code_roots, 108 evac_string_table_roots, 109 evac_universe_roots, 110 evac_jni_roots, 111 evac_jni_weak_roots, 112 evac_synchronizer_roots, 113 evac_flat_profiler_roots, 114 evac_management_roots, 115 evac_system_dictionary_roots, 116 evac_cldg_roots, 117 evac_jvmti_roots, 118 evac_string_dedup_roots, 119 evac_finish_queues, 120 121 final_evac_gross, 122 final_evac, 123 124 init_update_refs_gross, 125 init_update_refs, 126 127 final_update_refs_gross, 128 final_update_refs, 129 final_update_refs_finish_work, 130 131 // Per-thread timer block, should have "roots" counters in consistent order 132 final_update_refs_roots, 133 final_update_refs_thread_roots, 134 final_update_refs_code_roots, 135 final_update_refs_string_table_roots, 136 final_update_refs_universe_roots, 137 final_update_refs_jni_roots, 138 final_update_refs_jni_weak_roots, 139 final_update_refs_synchronizer_roots, 140 final_update_refs_flat_profiler_roots, 141 final_update_refs_management_roots, 142 final_update_refs_system_dict_roots, 143 final_update_refs_cldg_roots, 144 final_update_refs_jvmti_roots, 145 final_update_refs_string_dedup_roots, 146 final_update_refs_finish_queues, 147 148 final_update_refs_recycle, 149 150 init_partial_gc_gross, 151 init_partial_gc, 152 partial_gc_prepare, 153 154 // Per-thread timer block, should have "roots" counters in consistent order 155 init_partial_gc_work, 156 init_partial_gc_thread_roots, 157 init_partial_gc_code_roots, 158 init_partial_gc_string_table_roots, 159 init_partial_gc_universe_roots, 160 init_partial_gc_jni_roots, 161 init_partial_gc_jni_weak_roots, 162 init_partial_gc_synchronizer_roots, 163 init_partial_gc_flat_profiler_roots, 164 init_partial_gc_management_roots, 165 init_partial_gc_system_dict_roots, 166 init_partial_gc_cldg_roots, 167 init_partial_gc_jvmti_roots, 168 init_partial_gc_string_dedup_roots, 169 init_partial_gc_finish_queues, 170 171 final_partial_gc_gross, 172 final_partial_gc, 173 174 // Per-thread timer block, should have "roots" counters in consistent order 175 final_partial_gc_work, 176 final_partial_gc_thread_roots, 177 final_partial_gc_code_roots, 178 final_partial_gc_string_table_roots, 179 final_partial_gc_universe_roots, 180 final_partial_gc_jni_roots, 181 final_partial_gc_jni_weak_roots, 182 final_partial_gc_synchronizer_roots, 183 final_partial_gc_flat_profiler_roots, 184 final_partial_gc_management_roots, 185 final_partial_gc_system_dict_roots, 186 final_partial_gc_cldg_roots, 187 final_partial_gc_jvmti_roots, 188 final_partial_gc_string_dedup_roots, 189 final_partial_gc_finish_queues, 190 191 partial_gc_cleanup, 192 193 degen_gc_gross, 194 degen_gc, 195 196 init_traversal_gc_gross, 197 init_traversal_gc, 198 traversal_gc_prepare, 199 200 // Per-thread timer block, should have "roots" counters in consistent order 201 init_traversal_gc_work, 202 init_traversal_gc_thread_roots, 203 init_traversal_gc_code_roots, 204 init_traversal_gc_string_table_roots, 205 init_traversal_gc_universe_roots, 206 init_traversal_gc_jni_roots, 207 init_traversal_gc_jni_weak_roots, 208 init_traversal_gc_synchronizer_roots, 209 init_traversal_gc_flat_profiler_roots, 210 init_traversal_gc_management_roots, 211 init_traversal_gc_system_dict_roots, 212 init_traversal_gc_cldg_roots, 213 init_traversal_gc_jvmti_roots, 214 init_traversal_gc_string_dedup_roots, 215 init_traversal_gc_finish_queues, 216 217 final_traversal_gc_gross, 218 final_traversal_gc, 219 220 // Per-thread timer block, should have "roots" counters in consistent order 221 final_traversal_gc_work, 222 final_traversal_gc_thread_roots, 223 final_traversal_gc_code_roots, 224 final_traversal_gc_string_table_roots, 225 final_traversal_gc_universe_roots, 226 final_traversal_gc_jni_roots, 227 final_traversal_gc_jni_weak_roots, 228 final_traversal_gc_synchronizer_roots, 229 final_traversal_gc_flat_profiler_roots, 230 final_traversal_gc_management_roots, 231 final_traversal_gc_system_dict_roots, 232 final_traversal_gc_cldg_roots, 233 final_traversal_gc_jvmti_roots, 234 final_traversal_gc_string_dedup_roots, 235 final_traversal_gc_finish_queues, 236 237 // Per-thread timer block, should have "roots" counters in consistent order 238 final_traversal_update_roots, 239 final_traversal_update_thread_roots, 240 final_traversal_update_code_roots, 241 final_traversal_update_string_table_roots, 242 final_traversal_update_universe_roots, 243 final_traversal_update_jni_roots, 244 final_traversal_update_jni_weak_roots, 245 final_traversal_update_synchronizer_roots, 246 final_traversal_update_flat_profiler_roots, 247 final_traversal_update_management_roots, 248 final_traversal_update_system_dict_roots, 249 final_traversal_update_cldg_roots, 250 final_traversal_update_jvmti_roots, 251 final_traversal_update_string_dedup_roots, 252 final_traversal_update_finish_queues, 253 254 traversal_gc_cleanup, 255 256 full_gc_gross, 257 full_gc, 258 full_gc_heapdumps, 259 full_gc_prepare, 260 261 // Per-thread timer block, should have "roots" counters in consistent order 262 full_gc_roots, 263 full_gc_thread_roots, 264 full_gc_code_roots, 265 full_gc_string_table_roots, 266 full_gc_universe_roots, 267 full_gc_jni_roots, 268 full_gc_jni_weak_roots, 269 full_gc_synchronizer_roots, 270 full_gc_flat_profiler_roots, 271 full_gc_management_roots, 272 full_gc_system_dictionary_roots, 273 full_gc_cldg_roots, 274 full_gc_jvmti_roots, 275 full_gc_string_dedup_roots, 276 full_gc_finish_queues, 277 278 full_gc_mark, 279 full_gc_mark_finish_queues, 280 full_gc_weakrefs, 281 full_gc_weakrefs_process, 282 full_gc_weakrefs_enqueue, 283 full_gc_purge, 284 full_gc_purge_class_unload, 285 full_gc_purge_par, 286 full_gc_purge_par_codecache, 287 full_gc_purge_par_symbstring, 288 full_gc_purge_par_rmt, 289 full_gc_purge_par_classes, 290 full_gc_purge_par_sync, 291 full_gc_purge_cldg, 292 full_gc_purge_par_string_dedup, 293 full_gc_calculate_addresses, 294 full_gc_calculate_addresses_regular, 295 full_gc_calculate_addresses_humong, 296 full_gc_adjust_pointers, 297 full_gc_copy_objects, 298 full_gc_copy_objects_regular, 299 full_gc_copy_objects_humong, 300 full_gc_update_str_dedup_table, 301 full_gc_resize_tlabs, 302 303 // Longer concurrent phases at the end 304 conc_mark, 305 conc_preclean, 306 conc_evac, 307 conc_update_refs, 308 conc_cleanup, 309 conc_cleanup_recycle, 310 conc_cleanup_reset_bitmaps, 311 conc_partial, 312 conc_traversal, 313 314 // Unclassified 315 pause_other, 316 conc_other, 317 318 _num_phases 319 }; 320 321 322 // These are the subphases of GC phases (scan_roots, update_roots, 323 // init_evac, final_update_refs_roots, partial_gc_work and full_gc_roots). 324 // Make sure they are following this order. 325 enum GCParPhases { 326 ThreadRoots, 327 CodeCacheRoots, 328 StringTableRoots, 329 UniverseRoots, 330 JNIRoots, 331 JNIWeakRoots, 332 ObjectSynchronizerRoots, 333 FlatProfilerRoots, 334 ManagementRoots, 335 SystemDictionaryRoots, 336 CLDGRoots, 337 JVMTIRoots, 338 StringDedupRoots, 339 FinishQueues, 340 GCParPhasesSentinel 341 }; 342 343 private: 344 struct TimingData { 345 HdrSeq _secs; 346 double _start; 347 }; 348 349 private: 350 TimingData _timing_data[_num_phases]; 351 const char* _phase_names[_num_phases]; 352 353 ShenandoahWorkerTimings* _worker_times; 354 ShenandoahCollectorPolicy* _policy; 355 356 public: 357 ShenandoahPhaseTimings(); 358 359 ShenandoahWorkerTimings* worker_times() const { return _worker_times; } 360 361 // record phase start 362 void record_phase_start(Phase phase); 363 // record phase end and return elapsed time in seconds for the phase 364 void record_phase_end(Phase phase); 365 // record an elapsed time in seconds for the phase 366 void record_phase_time(Phase phase, jint time_us); 367 368 void record_workers_start(Phase phase); 369 void record_workers_end(Phase phase); 370 371 void print_on(outputStream* out) const; 372 373 private: 374 void init_phase_names(); 375 void print_summary_sd(outputStream* out, const char* str, const HdrSeq* seq) const; 376 }; 377 378 class ShenandoahWorkerTimings : public CHeapObj<mtGC> { 379 private: 380 uint _max_gc_threads; 381 WorkerDataArray<double>* _gc_par_phases[ShenandoahPhaseTimings::GCParPhasesSentinel]; 382 383 public: 384 ShenandoahWorkerTimings(uint max_gc_threads); 385 386 // record the time a phase took in seconds 387 void record_time_secs(ShenandoahPhaseTimings::GCParPhases phase, uint worker_i, double secs); 388 389 double average(uint i); 390 void reset(uint i); 391 void print(); 392 }; 393 394 class ShenandoahWorkerTimingsTracker : public StackObj { 395 double _start_time; 396 ShenandoahPhaseTimings::GCParPhases _phase; 397 ShenandoahWorkerTimings* _worker_times; 398 uint _worker_id; 399 public: 400 ShenandoahWorkerTimingsTracker(ShenandoahWorkerTimings* worker_times, ShenandoahPhaseTimings::GCParPhases phase, uint worker_id); 401 ~ShenandoahWorkerTimingsTracker(); 402 }; 403 404 #endif // SHARE_VM_GC_SHENANDOAH_SHENANDOAHGCPHASETIMEINGS_HPP