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 ShenandoahTerminationTimings;
  35 class outputStream;
  36 
  37 class ShenandoahPhaseTimings : public CHeapObj<mtGC> {
  38 public:
  39   enum Phase {
  40     total_pause_gross,
  41     total_pause,
  42 
  43     init_mark_gross,
  44     init_mark,
  45     accumulate_stats,
  46     make_parsable,
  47     clear_liveness,
  48 
  49     // Per-thread timer block, should have "roots" counters in consistent order
  50     scan_roots,
  51     scan_thread_roots,
  52     scan_code_roots,
  53     scan_string_table_roots,
  54     scan_universe_roots,
  55     scan_jni_roots,
  56     scan_jni_weak_roots,
  57     scan_synchronizer_roots,
  58     scan_flat_profiler_roots,
  59     scan_management_roots,
  60     scan_system_dictionary_roots,
  61     scan_cldg_roots,
  62     scan_jvmti_roots,
  63     scan_string_dedup_table_roots,
  64     scan_string_dedup_queue_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_table_roots,
  87     update_string_dedup_queue_roots,
  88     update_finish_queues,
  89 
  90     finish_queues,
  91     termination,
  92     weakrefs,
  93     weakrefs_process,
  94     weakrefs_termination,
  95     purge,
  96     purge_class_unload,
  97     purge_par,
  98     purge_par_codecache,
  99     purge_par_symbstring,
 100     purge_par_classes,
 101     purge_par_sync,
 102     purge_cldg,
 103     purge_string_dedup,
 104     complete_liveness,
 105     prepare_evac,
 106     recycle_regions,
 107 
 108     // Per-thread timer block, should have "roots" counters in consistent order
 109     init_evac,
 110     evac_thread_roots,
 111     evac_code_roots,
 112     evac_string_table_roots,
 113     evac_universe_roots,
 114     evac_jni_roots,
 115     evac_jni_weak_roots,
 116     evac_synchronizer_roots,
 117     evac_flat_profiler_roots,
 118     evac_management_roots,
 119     evac_system_dictionary_roots,
 120     evac_cldg_roots,
 121     evac_jvmti_roots,
 122     evac_string_dedup_table_roots,
 123     evac_string_dedup_queue_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_table_roots,
 151     final_update_refs_string_dedup_queue_roots,
 152     final_update_refs_finish_queues,
 153 
 154     final_update_refs_recycle,
 155 
 156     degen_gc_gross,
 157     degen_gc,
 158 
 159     init_traversal_gc_gross,
 160     init_traversal_gc,
 161     traversal_gc_prepare,
 162     traversal_gc_accumulate_stats,
 163     traversal_gc_make_parsable,
 164     traversal_gc_resize_tlabs,
 165 
 166     // Per-thread timer block, should have "roots" counters in consistent order
 167     init_traversal_gc_work,
 168     init_traversal_gc_thread_roots,
 169     init_traversal_gc_code_roots,
 170     init_traversal_gc_string_table_roots,
 171     init_traversal_gc_universe_roots,
 172     init_traversal_gc_jni_roots,
 173     init_traversal_gc_jni_weak_roots,
 174     init_traversal_gc_synchronizer_roots,
 175     init_traversal_gc_flat_profiler_roots,
 176     init_traversal_gc_management_roots,
 177     init_traversal_gc_system_dict_roots,
 178     init_traversal_gc_cldg_roots,
 179     init_traversal_gc_jvmti_roots,
 180     init_traversal_gc_string_dedup_table_roots,
 181     init_traversal_gc_string_dedup_queue_roots,
 182     init_traversal_gc_finish_queues,
 183 
 184     final_traversal_gc_gross,
 185     final_traversal_gc,
 186 
 187     // Per-thread timer block, should have "roots" counters in consistent order
 188     final_traversal_gc_work,
 189     final_traversal_gc_thread_roots,
 190     final_traversal_gc_code_roots,
 191     final_traversal_gc_string_table_roots,
 192     final_traversal_gc_universe_roots,
 193     final_traversal_gc_jni_roots,
 194     final_traversal_gc_jni_weak_roots,
 195     final_traversal_gc_synchronizer_roots,
 196     final_traversal_gc_flat_profiler_roots,
 197     final_traversal_gc_management_roots,
 198     final_traversal_gc_system_dict_roots,
 199     final_traversal_gc_cldg_roots,
 200     final_traversal_gc_jvmti_roots,
 201     final_traversal_gc_string_dedup_table_roots,
 202     final_traversal_gc_string_dedup_queue_roots,
 203     final_traversal_gc_finish_queues,
 204     final_traversal_gc_termination,
 205 
 206     // Per-thread timer block, should have "roots" counters in consistent order
 207     final_traversal_update_roots,
 208     final_traversal_update_thread_roots,
 209     final_traversal_update_code_roots,
 210     final_traversal_update_string_table_roots,
 211     final_traversal_update_universe_roots,
 212     final_traversal_update_jni_roots,
 213     final_traversal_update_jni_weak_roots,
 214     final_traversal_update_synchronizer_roots,
 215     final_traversal_update_flat_profiler_roots,
 216     final_traversal_update_management_roots,
 217     final_traversal_update_system_dict_roots,
 218     final_traversal_update_cldg_roots,
 219     final_traversal_update_jvmti_roots,
 220     final_traversal_update_string_dedup_table_roots,
 221     final_traversal_update_string_dedup_queue_roots,
 222     final_traversal_update_finish_queues,
 223 
 224     traversal_gc_cleanup,
 225 
 226     full_gc_gross,
 227     full_gc,
 228     full_gc_heapdumps,
 229     full_gc_prepare,
 230 
 231     // Per-thread timer block, should have "roots" counters in consistent order
 232     full_gc_roots,
 233     full_gc_thread_roots,
 234     full_gc_code_roots,
 235     full_gc_string_table_roots,
 236     full_gc_universe_roots,
 237     full_gc_jni_roots,
 238     full_gc_jni_weak_roots,
 239     full_gc_synchronizer_roots,
 240     full_gc_flat_profiler_roots,
 241     full_gc_management_roots,
 242     full_gc_system_dictionary_roots,
 243     full_gc_cldg_roots,
 244     full_gc_jvmti_roots,
 245     full_gc_string_dedup_table_roots,
 246     full_gc_string_dedup_queue_roots,
 247     full_gc_finish_queues,
 248 
 249     full_gc_mark,
 250     full_gc_mark_finish_queues,
 251     full_gc_mark_termination,
 252     full_gc_weakrefs,
 253     full_gc_weakrefs_process,
 254     full_gc_weakrefs_termination,
 255     full_gc_purge,
 256     full_gc_purge_class_unload,
 257     full_gc_purge_par,
 258     full_gc_purge_par_codecache,
 259     full_gc_purge_par_symbstring,
 260     full_gc_purge_par_classes,
 261     full_gc_purge_par_sync,
 262     full_gc_purge_cldg,
 263     full_gc_purge_string_dedup,
 264     full_gc_calculate_addresses,
 265     full_gc_calculate_addresses_regular,
 266     full_gc_calculate_addresses_humong,
 267     full_gc_adjust_pointers,
 268     full_gc_copy_objects,
 269     full_gc_copy_objects_regular,
 270     full_gc_copy_objects_humong,
 271     full_gc_copy_objects_reset_next,
 272     full_gc_copy_objects_reset_complete,
 273     full_gc_copy_objects_rebuild,
 274     full_gc_resize_tlabs,
 275 
 276     // Longer concurrent phases at the end
 277     conc_mark,
 278     conc_termination,
 279     conc_preclean,
 280     conc_evac,
 281     conc_update_refs,
 282     conc_cleanup,
 283     conc_cleanup_recycle,
 284     conc_cleanup_reset_bitmaps,
 285     conc_traversal,
 286     conc_traversal_termination,
 287 
 288     conc_uncommit,
 289 
 290     // Unclassified
 291     pause_other,
 292     conc_other,
 293 
 294     _num_phases
 295   };
 296 
 297 
 298   // These are the subphases of GC phases (scan_roots, update_roots,
 299   // init_evac, final_update_refs_roots and full_gc_roots).
 300   // Make sure they are following this order.
 301   enum GCParPhases {
 302     ThreadRoots,
 303     CodeCacheRoots,
 304     StringTableRoots,
 305     UniverseRoots,
 306     JNIRoots,
 307     JNIWeakRoots,
 308     ObjectSynchronizerRoots,
 309     FlatProfilerRoots,
 310     ManagementRoots,
 311     SystemDictionaryRoots,
 312     CLDGRoots,
 313     JVMTIRoots,
 314     StringDedupTableRoots,
 315     StringDedupQueueRoots,
 316     FinishQueues,
 317     GCParPhasesSentinel
 318   };
 319 
 320 private:
 321   struct TimingData {
 322     HdrSeq _secs;
 323     double _start;
 324   };
 325 
 326 private:
 327   TimingData _timing_data[_num_phases];
 328   const char* _phase_names[_num_phases];
 329 
 330   ShenandoahWorkerTimings*      _worker_times;
 331   ShenandoahTerminationTimings* _termination_times;
 332 
 333   ShenandoahCollectorPolicy* _policy;
 334 
 335 public:
 336   ShenandoahPhaseTimings();
 337 
 338   ShenandoahWorkerTimings* const worker_times() const { return _worker_times; }
 339   ShenandoahTerminationTimings* const termination_times() const { return _termination_times; }
 340 
 341   // record phase start
 342   void record_phase_start(Phase phase);
 343   // record phase end and return elapsed time in seconds for the phase
 344   void record_phase_end(Phase phase);
 345   // record an elapsed time in microseconds for the phase
 346   void record_phase_time(Phase phase, jint time_us);
 347 
 348   void record_workers_start(Phase phase);
 349   void record_workers_end(Phase phase);
 350 
 351   void print_on(outputStream* out) const;
 352 
 353 private:
 354   void init_phase_names();
 355   void print_summary_sd(outputStream* out, const char* str, const HdrSeq* seq) const;
 356 };
 357 
 358 class ShenandoahWorkerTimings : public CHeapObj<mtGC> {
 359 private:
 360   uint _max_gc_threads;
 361   WorkerDataArray<double>* _gc_par_phases[ShenandoahPhaseTimings::GCParPhasesSentinel];
 362 
 363 public:
 364   ShenandoahWorkerTimings(uint max_gc_threads);
 365 
 366   // record the time a phase took in seconds
 367   void record_time_secs(ShenandoahPhaseTimings::GCParPhases phase, uint worker_i, double secs);
 368 
 369   double average(uint i) const;
 370   void reset(uint i);
 371   void print() const;
 372 };
 373 
 374 class ShenandoahWorkerTimingsTracker : public StackObj {
 375   double _start_time;
 376   ShenandoahPhaseTimings::GCParPhases _phase;
 377   ShenandoahWorkerTimings* _worker_times;
 378   uint _worker_id;
 379 public:
 380   ShenandoahWorkerTimingsTracker(ShenandoahWorkerTimings* worker_times, ShenandoahPhaseTimings::GCParPhases phase, uint worker_id);
 381   ~ShenandoahWorkerTimingsTracker();
 382 };
 383 
 384 class ShenandoahTerminationTimings : public CHeapObj<mtGC> {
 385 private:
 386   WorkerDataArray<double>* _gc_termination_phase;
 387 public:
 388   ShenandoahTerminationTimings(uint max_gc_threads);
 389 
 390   // record the time a phase took in seconds
 391   void record_time_secs(uint worker_i, double secs);
 392 
 393   double average() const { return _gc_termination_phase->average(); }
 394   void reset() { _gc_termination_phase->reset(); }
 395 
 396   void print() const;
 397 };
 398 
 399 class ShenandoahTerminationTimingsTracker : public StackObj {
 400 private:
 401   double _start_time;
 402   uint   _worker_id;
 403 
 404 public:
 405   ShenandoahTerminationTimingsTracker(uint worker_id);
 406   ~ShenandoahTerminationTimingsTracker();
 407 };
 408 
 409 
 410 // Tracking termination time in specific GC phase
 411 class ShenandoahTerminationTracker : public StackObj {
 412 private:
 413   ShenandoahPhaseTimings::Phase _phase;
 414 
 415   static ShenandoahPhaseTimings::Phase currentPhase;
 416 public:
 417   ShenandoahTerminationTracker(ShenandoahPhaseTimings::Phase phase);
 418   ~ShenandoahTerminationTracker();
 419 };
 420 
 421 #endif // SHARE_VM_GC_SHENANDOAH_SHENANDOAHGCPHASETIMEINGS_HPP