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     degen_gc_gross,
 151     degen_gc,
 152 
 153     init_traversal_gc_gross,
 154     init_traversal_gc,
 155     traversal_gc_prepare,
 156 
 157     // Per-thread timer block, should have "roots" counters in consistent order
 158     init_traversal_gc_work,
 159     init_traversal_gc_thread_roots,
 160     init_traversal_gc_code_roots,
 161     init_traversal_gc_string_table_roots,
 162     init_traversal_gc_universe_roots,
 163     init_traversal_gc_jni_roots,
 164     init_traversal_gc_jni_weak_roots,
 165     init_traversal_gc_synchronizer_roots,
 166     init_traversal_gc_flat_profiler_roots,
 167     init_traversal_gc_management_roots,
 168     init_traversal_gc_system_dict_roots,
 169     init_traversal_gc_cldg_roots,
 170     init_traversal_gc_jvmti_roots,
 171     init_traversal_gc_string_dedup_roots,
 172     init_traversal_gc_finish_queues,
 173 
 174     final_traversal_gc_gross,
 175     final_traversal_gc,
 176 
 177     // Per-thread timer block, should have "roots" counters in consistent order
 178     final_traversal_gc_work,
 179     final_traversal_gc_thread_roots,
 180     final_traversal_gc_code_roots,
 181     final_traversal_gc_string_table_roots,
 182     final_traversal_gc_universe_roots,
 183     final_traversal_gc_jni_roots,
 184     final_traversal_gc_jni_weak_roots,
 185     final_traversal_gc_synchronizer_roots,
 186     final_traversal_gc_flat_profiler_roots,
 187     final_traversal_gc_management_roots,
 188     final_traversal_gc_system_dict_roots,
 189     final_traversal_gc_cldg_roots,
 190     final_traversal_gc_jvmti_roots,
 191     final_traversal_gc_string_dedup_roots,
 192     final_traversal_gc_finish_queues,
 193 
 194     // Per-thread timer block, should have "roots" counters in consistent order
 195     final_traversal_update_roots,
 196     final_traversal_update_thread_roots,
 197     final_traversal_update_code_roots,
 198     final_traversal_update_string_table_roots,
 199     final_traversal_update_universe_roots,
 200     final_traversal_update_jni_roots,
 201     final_traversal_update_jni_weak_roots,
 202     final_traversal_update_synchronizer_roots,
 203     final_traversal_update_flat_profiler_roots,
 204     final_traversal_update_management_roots,
 205     final_traversal_update_system_dict_roots,
 206     final_traversal_update_cldg_roots,
 207     final_traversal_update_jvmti_roots,
 208     final_traversal_update_string_dedup_roots,
 209     final_traversal_update_finish_queues,
 210 
 211     traversal_gc_cleanup,
 212 
 213     full_gc_gross,
 214     full_gc,
 215     full_gc_heapdumps,
 216     full_gc_prepare,
 217 
 218     // Per-thread timer block, should have "roots" counters in consistent order
 219     full_gc_roots,
 220     full_gc_thread_roots,
 221     full_gc_code_roots,
 222     full_gc_string_table_roots,
 223     full_gc_universe_roots,
 224     full_gc_jni_roots,
 225     full_gc_jni_weak_roots,
 226     full_gc_synchronizer_roots,
 227     full_gc_flat_profiler_roots,
 228     full_gc_management_roots,
 229     full_gc_system_dictionary_roots,
 230     full_gc_cldg_roots,
 231     full_gc_jvmti_roots,
 232     full_gc_string_dedup_roots,
 233     full_gc_finish_queues,
 234 
 235     full_gc_mark,
 236     full_gc_mark_finish_queues,
 237     full_gc_weakrefs,
 238     full_gc_weakrefs_process,
 239     full_gc_weakrefs_enqueue,
 240     full_gc_purge,
 241     full_gc_purge_class_unload,
 242     full_gc_purge_par,
 243     full_gc_purge_par_codecache,
 244     full_gc_purge_par_symbstring,
 245     full_gc_purge_par_rmt,
 246     full_gc_purge_par_classes,
 247     full_gc_purge_par_sync,
 248     full_gc_purge_cldg,
 249     full_gc_purge_par_string_dedup,
 250     full_gc_calculate_addresses,
 251     full_gc_calculate_addresses_regular,
 252     full_gc_calculate_addresses_humong,
 253     full_gc_adjust_pointers,
 254     full_gc_copy_objects,
 255     full_gc_copy_objects_regular,
 256     full_gc_copy_objects_humong,
 257     full_gc_update_str_dedup_table,
 258     full_gc_resize_tlabs,
 259 
 260     // Longer concurrent phases at the end
 261     conc_mark,
 262     conc_preclean,
 263     conc_evac,
 264     conc_update_refs,
 265     conc_cleanup,
 266     conc_cleanup_recycle,
 267     conc_cleanup_reset_bitmaps,
 268     conc_traversal,
 269 
 270     // Unclassified
 271     pause_other,
 272     conc_other,
 273 
 274     _num_phases
 275   };
 276 
 277 
 278   // These are the subphases of GC phases (scan_roots, update_roots,
 279   // init_evac, final_update_refs_roots and full_gc_roots).
 280   // Make sure they are following this order.
 281   enum GCParPhases {
 282     ThreadRoots,
 283     CodeCacheRoots,
 284     StringTableRoots,
 285     UniverseRoots,
 286     JNIRoots,
 287     JNIWeakRoots,
 288     ObjectSynchronizerRoots,
 289     FlatProfilerRoots,
 290     ManagementRoots,
 291     SystemDictionaryRoots,
 292     CLDGRoots,
 293     JVMTIRoots,
 294     StringDedupRoots,
 295     FinishQueues,
 296     GCParPhasesSentinel
 297   };
 298 
 299 private:
 300   struct TimingData {
 301     HdrSeq _secs;
 302     double _start;
 303   };
 304 
 305 private:
 306   TimingData _timing_data[_num_phases];
 307   const char* _phase_names[_num_phases];
 308 
 309   ShenandoahWorkerTimings* _worker_times;
 310   ShenandoahCollectorPolicy* _policy;
 311 
 312 public:
 313   ShenandoahPhaseTimings();
 314 
 315   ShenandoahWorkerTimings* worker_times() const { return _worker_times; }
 316 
 317   // record phase start
 318   void record_phase_start(Phase phase);
 319   // record phase end and return elapsed time in seconds for the phase
 320   void record_phase_end(Phase phase);
 321   // record an elapsed time in seconds for the phase
 322   void record_phase_time(Phase phase, jint time_us);
 323 
 324   void record_workers_start(Phase phase);
 325   void record_workers_end(Phase phase);
 326 
 327   void print_on(outputStream* out) const;
 328 
 329 private:
 330   void init_phase_names();
 331   void print_summary_sd(outputStream* out, const char* str, const HdrSeq* seq) const;
 332 };
 333 
 334 class ShenandoahWorkerTimings : public CHeapObj<mtGC> {
 335 private:
 336   uint _max_gc_threads;
 337   WorkerDataArray<double>* _gc_par_phases[ShenandoahPhaseTimings::GCParPhasesSentinel];
 338 
 339 public:
 340   ShenandoahWorkerTimings(uint max_gc_threads);
 341 
 342   // record the time a phase took in seconds
 343   void record_time_secs(ShenandoahPhaseTimings::GCParPhases phase, uint worker_i, double secs);
 344 
 345   double average(uint i);
 346   void reset(uint i);
 347   void print();
 348 };
 349 
 350 class ShenandoahWorkerTimingsTracker : public StackObj {
 351   double _start_time;
 352   ShenandoahPhaseTimings::GCParPhases _phase;
 353   ShenandoahWorkerTimings* _worker_times;
 354   uint _worker_id;
 355 public:
 356   ShenandoahWorkerTimingsTracker(ShenandoahWorkerTimings* worker_times, ShenandoahPhaseTimings::GCParPhases phase, uint worker_id);
 357   ~ShenandoahWorkerTimingsTracker();
 358 };
 359 
 360 #endif // SHARE_VM_GC_SHENANDOAH_SHENANDOAHGCPHASETIMEINGS_HPP