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