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