1 /*
   2  * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   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_GC_G1_G1GCPHASETIMES_HPP
  26 #define SHARE_GC_G1_G1GCPHASETIMES_HPP
  27 
  28 #include "gc/shared/referenceProcessorPhaseTimes.hpp"
  29 #include "gc/shared/weakProcessorPhaseTimes.hpp"
  30 #include "jfr/jfrEvents.hpp"
  31 #include "logging/logLevel.hpp"
  32 #include "memory/allocation.hpp"
  33 #include "utilities/macros.hpp"
  34 
  35 class LineBuffer;
  36 class G1ParScanThreadState;
  37 class STWGCTimer;
  38 
  39 template <class T> class WorkerDataArray;
  40 
  41 class G1GCPhaseTimes : public CHeapObj<mtGC> {
  42   uint _max_gc_threads;
  43   jlong _gc_start_counter;
  44   double _gc_pause_time_ms;
  45 
  46  public:
  47   enum GCParPhases {
  48     GCWorkerStart,
  49     ExtRootScan,
  50     ThreadRoots,
  51     UniverseRoots,
  52     JNIRoots,
  53     ObjectSynchronizerRoots,
  54     ManagementRoots,
  55     SystemDictionaryRoots,
  56     CLDGRoots,
  57     JVMTIRoots,
  58     AOT_ONLY(AOTCodeRoots COMMA)
  59     CMRefRoots,
  60     MergeER,
  61     MergeRS,
  62     OptMergeRS,
  63     MergeLB,
  64     MergeHCC,
  65     ScanHR,
  66     OptScanHR,
  67     CodeRoots,
  68     OptCodeRoots,
  69     ObjCopy,
  70     OptObjCopy,
  71     Termination,
  72     OptTermination,
  73     Other,
  74     GCWorkerTotal,
  75     GCWorkerEnd,
  76     StringDedupQueueFixup,
  77     StringDedupTableFixup,
  78     RedirtyCards,
  79     YoungFreeCSet,
  80     NonYoungFreeCSet,
  81     MergePSS,
  82     GCParPhasesSentinel
  83   };
  84 
  85   static const GCParPhases ExtRootScanSubPhasesFirst = ThreadRoots;
  86   static const GCParPhases ExtRootScanSubPhasesLast = CMRefRoots;
  87 
  88   enum GCMergeRSWorkTimes {
  89     MergeRSMergedSparse,
  90     MergeRSMergedFine,
  91     MergeRSMergedCoarse
  92   };
  93 
  94   enum GCScanHRWorkItems {
  95     ScanHRScannedCards,
  96     ScanHRScannedBlocks,
  97     ScanHRClaimedChunks,
  98     ScanHRScannedOptRefs,
  99     ScanHRUsedMemory
 100   };
 101 
 102   enum GCMergeHCCWorkItems {
 103     MergeHCCDirtyCards,
 104     MergeHCCSkippedCards
 105   };
 106 
 107   enum GCMergeLBWorkItems {
 108     MergeLBDirtyCards,
 109     MergeLBSkippedCards
 110   };
 111 
 112   enum GCMergePSSWorkItems {
 113     MergePSSCopiedBytes,
 114     MergePSSLABWasteBytes,
 115     MergePSSLABUndoWasteBytes
 116   };
 117 
 118  private:
 119   // Markers for grouping the phases in the GCPhases enum above
 120   static const int GCMainParPhasesLast = GCWorkerEnd;
 121 
 122   WorkerDataArray<double>* _gc_par_phases[GCParPhasesSentinel];
 123 
 124   WorkerDataArray<size_t>* _merge_rs_merged_sparse;
 125   WorkerDataArray<size_t>* _merge_rs_merged_fine;
 126   WorkerDataArray<size_t>* _merge_rs_merged_coarse;
 127 
 128   WorkerDataArray<size_t>* _merge_hcc_dirty_cards;
 129   WorkerDataArray<size_t>* _merge_hcc_skipped_cards;
 130 
 131   WorkerDataArray<size_t>* _merge_lb_dirty_cards;
 132   WorkerDataArray<size_t>* _merge_lb_skipped_cards;
 133 
 134   WorkerDataArray<size_t>* _scan_hr_scanned_cards;
 135   WorkerDataArray<size_t>* _scan_hr_scanned_blocks;
 136   WorkerDataArray<size_t>* _scan_hr_claimed_chunks;
 137 
 138   WorkerDataArray<size_t>* _opt_merge_rs_merged_sparse;
 139   WorkerDataArray<size_t>* _opt_merge_rs_merged_fine;
 140   WorkerDataArray<size_t>* _opt_merge_rs_merged_coarse;
 141 
 142   WorkerDataArray<size_t>* _opt_scan_hr_scanned_cards;
 143   WorkerDataArray<size_t>* _opt_scan_hr_scanned_blocks;
 144   WorkerDataArray<size_t>* _opt_scan_hr_claimed_chunks;
 145   WorkerDataArray<size_t>* _opt_scan_hr_scanned_opt_refs;
 146   WorkerDataArray<size_t>* _opt_scan_hr_used_memory;
 147 
 148   WorkerDataArray<size_t>* _merge_pss_copied_bytes;
 149   WorkerDataArray<size_t>* _merge_pss_lab_waste_bytes;
 150   WorkerDataArray<size_t>* _merge_pss_lab_undo_waste_bytes;
 151 
 152   WorkerDataArray<size_t>* _termination_attempts;
 153 
 154   WorkerDataArray<size_t>* _opt_termination_attempts;
 155 
 156   WorkerDataArray<size_t>* _redirtied_cards;
 157 
 158   double _cur_collection_initial_evac_time_ms;
 159   double _cur_optional_evac_time_ms;
 160   double _cur_collection_code_root_fixup_time_ms;
 161   double _cur_strong_code_root_purge_time_ms;
 162 
 163   double _cur_evac_fail_recalc_used;
 164   double _cur_evac_fail_remove_self_forwards;
 165 
 166   double _cur_string_deduplication_time_ms;
 167 
 168   double _cur_merge_heap_roots_time_ms;
 169   double _cur_optional_merge_heap_roots_time_ms;
 170 
 171   double _cur_prepare_merge_heap_roots_time_ms;
 172   double _cur_optional_prepare_merge_heap_roots_time_ms;
 173 
 174   double _cur_prepare_tlab_time_ms;
 175   double _cur_resize_tlab_time_ms;
 176 
 177   double _cur_derived_pointer_table_update_time_ms;
 178 
 179   double _cur_clear_ct_time_ms;
 180   double _cur_expand_heap_time_ms;
 181   double _cur_ref_proc_time_ms;
 182 
 183   double _cur_collection_start_sec;
 184   double _root_region_scan_wait_time_ms;
 185 
 186   double _external_accounted_time_ms;
 187 
 188   double _recorded_prepare_heap_roots_time_ms;
 189 
 190   double _recorded_clear_claimed_marks_time_ms;
 191 
 192   double _recorded_young_cset_choice_time_ms;
 193   double _recorded_non_young_cset_choice_time_ms;
 194 
 195   double _recorded_redirty_logged_cards_time_ms;
 196 
 197   double _recorded_preserve_cm_referents_time_ms;
 198 
 199   double _recorded_merge_pss_time_ms;
 200 
 201   double _recorded_start_new_cset_time_ms;
 202 
 203   double _recorded_total_free_cset_time_ms;
 204 
 205   double _recorded_serial_free_cset_time_ms;
 206 
 207   double _cur_region_register_time;
 208 
 209   double _cur_fast_reclaim_humongous_time_ms;
 210   size_t _cur_fast_reclaim_humongous_total;
 211   size_t _cur_fast_reclaim_humongous_candidates;
 212   size_t _cur_fast_reclaim_humongous_reclaimed;
 213 
 214   double _cur_verify_before_time_ms;
 215   double _cur_verify_after_time_ms;
 216 
 217   ReferenceProcessorPhaseTimes _ref_phase_times;
 218   WeakProcessorPhaseTimes _weak_phase_times;
 219 
 220   double worker_time(GCParPhases phase, uint worker);
 221   void note_gc_end();
 222   void reset();
 223 
 224   template <class T>
 225   void details(T* phase, const char* indent) const;
 226 
 227   void log_work_items(WorkerDataArray<double>* phase, uint indent, outputStream* out) const;
 228   void log_phase(WorkerDataArray<double>* phase, uint indent, outputStream* out, bool print_sum) const;
 229   void debug_serial_phase(WorkerDataArray<double>* phase, uint extra_indent = 0) const;
 230   void debug_phase(WorkerDataArray<double>* phase, uint extra_indent = 0) const;
 231   void trace_phase(WorkerDataArray<double>* phase, bool print_sum = true) const;
 232 
 233   void info_time(const char* name, double value) const;
 234   void debug_time(const char* name, double value) const;
 235   // This will print logs for both 'gc+phases' and 'gc+phases+ref'.
 236   void debug_time_for_reference(const char* name, double value) const;
 237   void trace_time(const char* name, double value) const;
 238   void trace_count(const char* name, size_t value) const;
 239 
 240   double print_pre_evacuate_collection_set() const;
 241   double print_merge_heap_roots_time() const;
 242   double print_evacuate_initial_collection_set() const;
 243   double print_evacuate_optional_collection_set() const;
 244   double print_post_evacuate_collection_set() const;
 245   void print_other(double accounted_ms) const;
 246 
 247  public:
 248   G1GCPhaseTimes(STWGCTimer* gc_timer, uint max_gc_threads);
 249   void note_gc_start();
 250   void print();
 251   static const char* phase_name(GCParPhases phase);
 252 
 253   // record the time a phase took in seconds
 254   void record_time_secs(GCParPhases phase, uint worker_id, double secs);
 255 
 256   // add a number of seconds to a phase
 257   void add_time_secs(GCParPhases phase, uint worker_id, double secs);
 258 
 259   void record_or_add_time_secs(GCParPhases phase, uint worker_id, double secs);
 260 
 261   double get_time_secs(GCParPhases phase, uint worker_id);
 262 
 263   void record_thread_work_item(GCParPhases phase, uint worker_id, size_t count, uint index = 0);
 264 
 265   void record_or_add_thread_work_item(GCParPhases phase, uint worker_id, size_t count, uint index = 0);
 266 
 267   size_t get_thread_work_item(GCParPhases phase, uint worker_id, uint index = 0);
 268 
 269   // return the average time for a phase in milliseconds
 270   double average_time_ms(GCParPhases phase);
 271 
 272   size_t sum_thread_work_items(GCParPhases phase, uint index = 0);
 273 
 274   void record_prepare_tlab_time_ms(double ms) {
 275     _cur_prepare_tlab_time_ms = ms;
 276   }
 277 
 278   void record_resize_tlab_time_ms(double ms) {
 279     _cur_resize_tlab_time_ms = ms;
 280   }
 281 
 282   void record_derived_pointer_table_update_time(double ms) {
 283     _cur_derived_pointer_table_update_time_ms = ms;
 284   }
 285 
 286   void record_clear_ct_time(double ms) {
 287     _cur_clear_ct_time_ms = ms;
 288   }
 289 
 290   void record_expand_heap_time(double ms) {
 291     _cur_expand_heap_time_ms = ms;
 292   }
 293 
 294   void record_initial_evac_time(double ms) {
 295     _cur_collection_initial_evac_time_ms = ms;
 296   }
 297 
 298   void record_or_add_optional_evac_time(double ms) {
 299     _cur_optional_evac_time_ms += ms;
 300   }
 301 
 302   void record_or_add_code_root_fixup_time(double ms) {
 303     _cur_collection_code_root_fixup_time_ms += ms;
 304   }
 305 
 306   void record_strong_code_root_purge_time(double ms) {
 307     _cur_strong_code_root_purge_time_ms = ms;
 308   }
 309 
 310   void record_merge_heap_roots_time(double ms) {
 311     _cur_merge_heap_roots_time_ms += ms;
 312   }
 313 
 314   void record_or_add_optional_merge_heap_roots_time(double ms) {
 315     _cur_optional_merge_heap_roots_time_ms += ms;
 316   }
 317 
 318   void record_prepare_merge_heap_roots_time(double ms) {
 319     _cur_prepare_merge_heap_roots_time_ms += ms;
 320   }
 321 
 322   void record_or_add_optional_prepare_merge_heap_roots_time(double ms) {
 323     _cur_optional_prepare_merge_heap_roots_time_ms += ms;
 324   }
 325 
 326   void record_evac_fail_recalc_used_time(double ms) {
 327     _cur_evac_fail_recalc_used = ms;
 328   }
 329 
 330   void record_evac_fail_remove_self_forwards(double ms) {
 331     _cur_evac_fail_remove_self_forwards = ms;
 332   }
 333 
 334   void record_string_deduplication_time(double ms) {
 335     _cur_string_deduplication_time_ms = ms;
 336   }
 337 
 338   void record_ref_proc_time(double ms) {
 339     _cur_ref_proc_time_ms = ms;
 340   }
 341 
 342   void record_root_region_scan_wait_time(double time_ms) {
 343     _root_region_scan_wait_time_ms = time_ms;
 344   }
 345 
 346   void record_total_free_cset_time_ms(double time_ms) {
 347     _recorded_total_free_cset_time_ms = time_ms;
 348   }
 349 
 350   void record_serial_free_cset_time_ms(double time_ms) {
 351     _recorded_serial_free_cset_time_ms = time_ms;
 352   }
 353 
 354   void record_register_regions(double time_ms, size_t total, size_t candidates) {
 355     _cur_region_register_time = time_ms;
 356     _cur_fast_reclaim_humongous_total = total;
 357     _cur_fast_reclaim_humongous_candidates = candidates;
 358   }
 359 
 360   void record_fast_reclaim_humongous_time_ms(double value, size_t reclaimed) {
 361     _cur_fast_reclaim_humongous_time_ms = value;
 362     _cur_fast_reclaim_humongous_reclaimed = reclaimed;
 363   }
 364 
 365   void record_young_cset_choice_time_ms(double time_ms) {
 366     _recorded_young_cset_choice_time_ms = time_ms;
 367   }
 368 
 369   void record_non_young_cset_choice_time_ms(double time_ms) {
 370     _recorded_non_young_cset_choice_time_ms = time_ms;
 371   }
 372 
 373   void record_redirty_logged_cards_time_ms(double time_ms) {
 374     _recorded_redirty_logged_cards_time_ms = time_ms;
 375   }
 376 
 377   void record_preserve_cm_referents_time_ms(double time_ms) {
 378     _recorded_preserve_cm_referents_time_ms = time_ms;
 379   }
 380 
 381   void record_start_new_cset_time_ms(double time_ms) {
 382     _recorded_start_new_cset_time_ms = time_ms;
 383   }
 384 
 385   void record_cur_collection_start_sec(double time_ms) {
 386     _cur_collection_start_sec = time_ms;
 387   }
 388 
 389   void record_verify_before_time_ms(double time_ms) {
 390     _cur_verify_before_time_ms = time_ms;
 391   }
 392 
 393   void record_verify_after_time_ms(double time_ms) {
 394     _cur_verify_after_time_ms = time_ms;
 395   }
 396 
 397   void inc_external_accounted_time_ms(double time_ms) {
 398     _external_accounted_time_ms += time_ms;
 399   }
 400 
 401   void record_prepare_heap_roots_time_ms(double recorded_prepare_heap_roots_time_ms) {
 402     _recorded_prepare_heap_roots_time_ms = recorded_prepare_heap_roots_time_ms;
 403   }
 404 
 405   void record_clear_claimed_marks_time_ms(double recorded_clear_claimed_marks_time_ms) {
 406     _recorded_clear_claimed_marks_time_ms = recorded_clear_claimed_marks_time_ms;
 407   }
 408 
 409   double cur_collection_start_sec() {
 410     return _cur_collection_start_sec;
 411   }
 412 
 413   double cur_collection_par_time_ms() {
 414     return _cur_collection_initial_evac_time_ms + _cur_optional_evac_time_ms;
 415   }
 416 
 417   double cur_clear_ct_time_ms() {
 418     return _cur_clear_ct_time_ms;
 419   }
 420 
 421   double cur_expand_heap_time_ms() {
 422     return _cur_expand_heap_time_ms;
 423   }
 424 
 425   double root_region_scan_wait_time_ms() {
 426     return _root_region_scan_wait_time_ms;
 427   }
 428 
 429   double young_cset_choice_time_ms() {
 430     return _recorded_young_cset_choice_time_ms;
 431   }
 432 
 433   double total_free_cset_time_ms() {
 434     return _recorded_total_free_cset_time_ms;
 435   }
 436 
 437   double non_young_cset_choice_time_ms() {
 438     return _recorded_non_young_cset_choice_time_ms;
 439   }
 440 
 441   double fast_reclaim_humongous_time_ms() {
 442     return _cur_fast_reclaim_humongous_time_ms;
 443   }
 444 
 445   size_t fast_reclaim_humongous_candidates() const {
 446     return _cur_fast_reclaim_humongous_candidates;
 447   }
 448 
 449   ReferenceProcessorPhaseTimes* ref_phase_times() { return &_ref_phase_times; }
 450 
 451   WeakProcessorPhaseTimes* weak_phase_times() { return &_weak_phase_times; }
 452 };
 453 
 454 class G1EvacPhaseWithTrimTimeTracker : public StackObj {
 455   G1ParScanThreadState* _pss;
 456   Ticks _start;
 457 
 458   Tickspan& _total_time;
 459   Tickspan& _trim_time;
 460 
 461   bool _stopped;
 462 public:
 463   G1EvacPhaseWithTrimTimeTracker(G1ParScanThreadState* pss, Tickspan& total_time, Tickspan& trim_time);
 464   ~G1EvacPhaseWithTrimTimeTracker();
 465 
 466   void stop();
 467 };
 468 
 469 class G1GCParPhaseTimesTracker : public CHeapObj<mtGC> {
 470 protected:
 471   Ticks _start_time;
 472   G1GCPhaseTimes::GCParPhases _phase;
 473   G1GCPhaseTimes* _phase_times;
 474   uint _worker_id;
 475   EventGCPhaseParallel _event;
 476   bool _must_record;
 477 
 478 public:
 479   G1GCParPhaseTimesTracker(G1GCPhaseTimes* phase_times, G1GCPhaseTimes::GCParPhases phase, uint worker_id, bool must_record = true);
 480   virtual ~G1GCParPhaseTimesTracker();
 481 };
 482 
 483 class G1EvacPhaseTimesTracker : public G1GCParPhaseTimesTracker {
 484   Tickspan _total_time;
 485   Tickspan _trim_time;
 486 
 487   G1EvacPhaseWithTrimTimeTracker _trim_tracker;
 488 public:
 489   G1EvacPhaseTimesTracker(G1GCPhaseTimes* phase_times, G1ParScanThreadState* pss, G1GCPhaseTimes::GCParPhases phase, uint worker_id);
 490   virtual ~G1EvacPhaseTimesTracker();
 491 };
 492 
 493 #endif // SHARE_GC_G1_G1GCPHASETIMES_HPP