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