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