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