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 "memory/allocation.hpp" 29 #include "utilities/numberSeq.hpp" 30 #include "gc_implementation/shenandoah/shenandoahWorkerDataArray.hpp" 31 #include "gc_implementation/shenandoah/shenandoahWorkerDataArray.inline.hpp" 32 33 class ShenandoahCollectorPolicy; 34 class ShenandoahWorkerTimings; 35 class ShenandoahTerminationTimings; 36 class outputStream; 37 38 class ShenandoahPhaseTimings : public CHeapObj<mtGC> { 39 public: 40 enum Phase { 41 total_pause_gross, 42 total_pause, 43 44 init_mark_gross, 45 init_mark, 46 accumulate_stats, 47 make_parsable, 48 clear_liveness, 49 50 // Per-thread timer block, should have "roots" counters in consistent order 51 scan_roots, 52 scan_thread_roots, 53 scan_code_roots, 54 scan_string_table_roots, 55 scan_universe_roots, 56 scan_jni_roots, 57 scan_jni_weak_roots, 58 scan_synchronizer_roots, 59 scan_flat_profiler_roots, 60 scan_management_roots, 61 scan_system_dictionary_roots, 62 scan_cldg_roots, 63 scan_jvmti_roots, 64 scan_string_dedup_roots, 65 scan_finish_queues, 66 67 resize_tlabs, 68 69 final_mark_gross, 70 final_mark, 71 72 // Per-thread timer block, should have "roots" counters in consistent order 73 update_roots, 74 update_thread_roots, 75 update_code_roots, 76 update_string_table_roots, 77 update_universe_roots, 78 update_jni_roots, 79 update_jni_weak_roots, 80 update_synchronizer_roots, 81 update_flat_profiler_roots, 82 update_management_roots, 83 update_system_dictionary_roots, 84 update_cldg_roots, 85 update_jvmti_roots, 86 update_string_dedup_roots, 87 update_finish_queues, 88 89 finish_queues, 90 termination, 91 weakrefs, 92 weakrefs_process, 93 weakrefs_termination, 94 weakrefs_enqueue, 95 purge, 96 purge_class_unload, 97 purge_par, 98 purge_par_codecache, 99 purge_par_symbstring, 100 purge_par_rmt, 101 purge_par_classes, 102 purge_par_sync, 103 purge_par_string_dedup, 104 purge_cldg, 105 prepare_evac, 106 complete_liveness, 107 recycle_regions, 108 109 // Per-thread timer block, should have "roots" counters in consistent order 110 init_evac, 111 evac_thread_roots, 112 evac_code_roots, 113 evac_string_table_roots, 114 evac_universe_roots, 115 evac_jni_roots, 116 evac_jni_weak_roots, 117 evac_synchronizer_roots, 118 evac_flat_profiler_roots, 119 evac_management_roots, 120 evac_system_dictionary_roots, 121 evac_cldg_roots, 122 evac_jvmti_roots, 123 evac_string_dedup_roots, 124 evac_finish_queues, 125 126 final_evac_gross, 127 final_evac, 128 129 init_update_refs_gross, 130 init_update_refs, 131 132 final_update_refs_gross, 133 final_update_refs, 134 final_update_refs_finish_work, 135 136 // Per-thread timer block, should have "roots" counters in consistent order 137 final_update_refs_roots, 138 final_update_refs_thread_roots, 139 final_update_refs_code_roots, 140 final_update_refs_string_table_roots, 141 final_update_refs_universe_roots, 142 final_update_refs_jni_roots, 143 final_update_refs_jni_weak_roots, 144 final_update_refs_synchronizer_roots, 145 final_update_refs_flat_profiler_roots, 146 final_update_refs_management_roots, 147 final_update_refs_system_dict_roots, 148 final_update_refs_cldg_roots, 149 final_update_refs_jvmti_roots, 150 final_update_refs_string_dedup_roots, 151 final_update_refs_finish_queues, 152 153 final_update_refs_recycle, 154 155 degen_gc_gross, 156 degen_gc, 157 158 full_gc_gross, 159 full_gc, 160 full_gc_heapdumps, 161 full_gc_prepare, 162 163 // Per-thread timer block, should have "roots" counters in consistent order 164 full_gc_roots, 165 full_gc_thread_roots, 166 full_gc_code_roots, 167 full_gc_string_table_roots, 168 full_gc_universe_roots, 169 full_gc_jni_roots, 170 full_gc_jni_weak_roots, 171 full_gc_synchronizer_roots, 172 full_gc_flat_profiler_roots, 173 full_gc_management_roots, 174 full_gc_system_dictionary_roots, 175 full_gc_cldg_roots, 176 full_gc_jvmti_roots, 177 full_gc_string_dedup_roots, 178 full_gc_finish_queues, 179 180 full_gc_mark, 181 full_gc_mark_finish_queues, 182 full_gc_mark_termination, 183 full_gc_weakrefs, 184 full_gc_weakrefs_process, 185 full_gc_weakrefs_termination, 186 full_gc_weakrefs_enqueue, 187 full_gc_purge, 188 full_gc_purge_class_unload, 189 full_gc_purge_par, 190 full_gc_purge_par_codecache, 191 full_gc_purge_par_symbstring, 192 full_gc_purge_par_rmt, 193 full_gc_purge_par_classes, 194 full_gc_purge_par_sync, 195 full_gc_purge_cldg, 196 full_gc_purge_par_string_dedup, 197 full_gc_calculate_addresses, 198 full_gc_calculate_addresses_regular, 199 full_gc_calculate_addresses_humong, 200 full_gc_adjust_pointers, 201 full_gc_copy_objects, 202 full_gc_copy_objects_regular, 203 full_gc_copy_objects_humong, 204 full_gc_copy_objects_reset_next, 205 full_gc_copy_objects_reset_complete, 206 full_gc_copy_objects_rebuild, 207 full_gc_update_str_dedup_table, 208 full_gc_resize_tlabs, 209 210 // Longer concurrent phases at the end 211 conc_mark, 212 conc_termination, 213 conc_preclean, 214 conc_evac, 215 conc_update_refs, 216 conc_cleanup, 217 conc_cleanup_recycle, 218 conc_cleanup_reset_bitmaps, 219 220 conc_uncommit, 221 222 // Unclassified 223 pause_other, 224 conc_other, 225 226 _num_phases 227 }; 228 229 230 // These are the subphases of GC phases (scan_roots, update_roots, 231 // init_evac, final_update_refs_roots, and full_gc_roots). 232 // Make sure they are following this order. 233 enum GCParPhases { 234 ThreadRoots, 235 CodeCacheRoots, 236 StringTableRoots, 237 UniverseRoots, 238 JNIRoots, 239 JNIWeakRoots, 240 ObjectSynchronizerRoots, 241 FlatProfilerRoots, 242 ManagementRoots, 243 SystemDictionaryRoots, 244 CLDGRoots, 245 JVMTIRoots, 246 StringDedupRoots, 247 FinishQueues, 248 GCParPhasesSentinel 249 }; 250 251 private: 252 struct TimingData { 253 HdrSeq _secs; 254 double _start; 255 }; 256 257 private: 258 TimingData _timing_data[_num_phases]; 259 const char* _phase_names[_num_phases]; 260 261 ShenandoahWorkerTimings* _worker_times; 262 ShenandoahTerminationTimings* _termination_times; 263 264 ShenandoahCollectorPolicy* _policy; 265 266 public: 267 ShenandoahPhaseTimings(); 268 269 ShenandoahWorkerTimings* const worker_times() const { return _worker_times; } 270 ShenandoahTerminationTimings* const termination_times() const { return _termination_times; } 271 272 // record phase start 273 void record_phase_start(Phase phase); 274 // record phase end and return elapsed time in seconds for the phase 275 void record_phase_end(Phase phase); 276 // record an elapsed time in microseconds for the phase 277 void record_phase_time(Phase phase, jint time_us); 278 279 void record_workers_start(Phase phase); 280 void record_workers_end(Phase phase); 281 282 void print_on(outputStream* out) const; 283 284 private: 285 void init_phase_names(); 286 void print_summary_sd(outputStream* out, const char* str, const HdrSeq* seq) const; 287 }; 288 289 class ShenandoahWorkerTimings : public CHeapObj<mtGC> { 290 private: 291 uint _max_gc_threads; 292 ShenandoahWorkerDataArray<double>* _gc_par_phases[ShenandoahPhaseTimings::GCParPhasesSentinel]; 293 294 public: 295 ShenandoahWorkerTimings(uint max_gc_threads); 296 297 // record the time a phase took in seconds 298 void record_time_secs(ShenandoahPhaseTimings::GCParPhases phase, uint worker_i, double secs); 299 300 double average(uint i); 301 void reset(uint i); 302 void print(); 303 }; 304 305 class ShenandoahWorkerTimingsTracker : public StackObj { 306 double _start_time; 307 ShenandoahPhaseTimings::GCParPhases _phase; 308 ShenandoahWorkerTimings* _worker_times; 309 uint _worker_id; 310 public: 311 ShenandoahWorkerTimingsTracker(ShenandoahWorkerTimings* worker_times, ShenandoahPhaseTimings::GCParPhases phase, uint worker_id); 312 ~ShenandoahWorkerTimingsTracker(); 313 }; 314 315 class ShenandoahTerminationTimings : public CHeapObj<mtGC> { 316 private: 317 ShenandoahWorkerDataArray<double>* _gc_termination_phase; 318 public: 319 ShenandoahTerminationTimings(uint max_gc_threads); 320 321 // record the time a phase took in seconds 322 void record_time_secs(uint worker_i, double secs); 323 324 double average() const { return _gc_termination_phase->average(); } 325 void reset() { _gc_termination_phase->reset(); } 326 327 void print() const; 328 }; 329 330 class ShenandoahTerminationTimingsTracker : public StackObj { 331 private: 332 double _start_time; 333 uint _worker_id; 334 335 public: 336 ShenandoahTerminationTimingsTracker(uint worker_id); 337 ~ShenandoahTerminationTimingsTracker(); 338 }; 339 340 341 // Tracking termination time in specific GC phase 342 class ShenandoahTerminationTracker : public StackObj { 343 private: 344 ShenandoahPhaseTimings::Phase _phase; 345 346 static ShenandoahPhaseTimings::Phase currentPhase; 347 public: 348 ShenandoahTerminationTracker(ShenandoahPhaseTimings::Phase phase); 349 ~ShenandoahTerminationTracker(); 350 }; 351 352 #endif // SHARE_VM_GC_SHENANDOAH_SHENANDOAHGCPHASETIMEINGS_HPP