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     JVMCI_ONLY(JVMCIRoots COMMA)
  60     CMRefRoots,
  61     WaitForStrongCLD,
  62     WeakCLDRoots,
  63     UpdateRS,
  64     ScanHCC,
  65     ScanRS,
  66     OptScanRS,
  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     GCParPhasesSentinel
  82   };
  83 
  84   static const GCParPhases ExtRootScanSubPhasesFirst = ThreadRoots;
  85   static const GCParPhases ExtRootScanSubPhasesLast = WeakCLDRoots;
  86 
  87   enum GCScanRSWorkItems {
  88     ScanRSScannedCards,
  89     ScanRSClaimedCards,
  90     ScanRSSkippedCards,
  91     ScanRSScannedOptRefs,
  92     ScanRSUsedMemory
  93   };
  94 
  95   enum GCUpdateRSWorkItems {
  96     UpdateRSProcessedBuffers,
  97     UpdateRSScannedCards,
  98     UpdateRSSkippedCards
  99   };
 100 
 101   enum GCObjCopyWorkItems {
 102     ObjCopyLABWaste,
 103     ObjCopyLABUndoWaste
 104   };
 105 
 106  private:
 107   // Markers for grouping the phases in the GCPhases enum above
 108   static const int GCMainParPhasesLast = GCWorkerEnd;
 109 
 110   WorkerDataArray<double>* _gc_par_phases[GCParPhasesSentinel];
 111 
 112   WorkerDataArray<size_t>* _update_rs_processed_buffers;
 113   WorkerDataArray<size_t>* _update_rs_scanned_cards;
 114   WorkerDataArray<size_t>* _update_rs_skipped_cards;
 115 
 116   WorkerDataArray<size_t>* _scan_rs_scanned_cards;
 117   WorkerDataArray<size_t>* _scan_rs_claimed_cards;
 118   WorkerDataArray<size_t>* _scan_rs_skipped_cards;
 119 
 120   WorkerDataArray<size_t>* _opt_scan_rs_scanned_cards;
 121   WorkerDataArray<size_t>* _opt_scan_rs_claimed_cards;
 122   WorkerDataArray<size_t>* _opt_scan_rs_skipped_cards;
 123   WorkerDataArray<size_t>* _opt_scan_rs_scanned_opt_refs;
 124   WorkerDataArray<size_t>* _opt_scan_rs_used_memory;
 125 
 126   WorkerDataArray<size_t>* _obj_copy_lab_waste;
 127   WorkerDataArray<size_t>* _obj_copy_lab_undo_waste;
 128 
 129   WorkerDataArray<size_t>* _opt_obj_copy_lab_waste;
 130   WorkerDataArray<size_t>* _opt_obj_copy_lab_undo_waste;
 131 
 132   WorkerDataArray<size_t>* _termination_attempts;
 133 
 134   WorkerDataArray<size_t>* _opt_termination_attempts;
 135 
 136   WorkerDataArray<size_t>* _redirtied_cards;
 137 
 138   double _cur_collection_initial_evac_time_ms;
 139   double _cur_optional_evac_ms;
 140   double _cur_collection_code_root_fixup_time_ms;
 141   double _cur_strong_code_root_purge_time_ms;
 142 
 143   double _cur_evac_fail_recalc_used;
 144   double _cur_evac_fail_remove_self_forwards;
 145 
 146   double _cur_string_deduplication_time_ms;
 147 
 148   double _cur_prepare_tlab_time_ms;
 149   double _cur_resize_tlab_time_ms;
 150 
 151   double _cur_derived_pointer_table_update_time_ms;
 152 
 153   double _cur_clear_ct_time_ms;
 154   double _cur_expand_heap_time_ms;
 155   double _cur_ref_proc_time_ms;
 156 
 157   double _cur_collection_start_sec;
 158   double _root_region_scan_wait_time_ms;
 159 
 160   double _external_accounted_time_ms;
 161 
 162   double _recorded_clear_claimed_marks_time_ms;
 163 
 164   double _recorded_young_cset_choice_time_ms;
 165   double _recorded_non_young_cset_choice_time_ms;
 166 
 167   double _recorded_redirty_logged_cards_time_ms;
 168 
 169   double _recorded_preserve_cm_referents_time_ms;
 170 
 171   double _recorded_merge_pss_time_ms;
 172 
 173   double _recorded_start_new_cset_time_ms;
 174 
 175   double _recorded_total_free_cset_time_ms;
 176 
 177   double _recorded_serial_free_cset_time_ms;
 178 
 179   double _cur_region_register_time;
 180 
 181   double _cur_fast_reclaim_humongous_time_ms;
 182   size_t _cur_fast_reclaim_humongous_total;
 183   size_t _cur_fast_reclaim_humongous_candidates;
 184   size_t _cur_fast_reclaim_humongous_reclaimed;
 185 
 186   double _cur_verify_before_time_ms;
 187   double _cur_verify_after_time_ms;
 188 
 189   ReferenceProcessorPhaseTimes _ref_phase_times;
 190   WeakProcessorPhaseTimes _weak_phase_times;
 191 
 192   double worker_time(GCParPhases phase, uint worker);
 193   void note_gc_end();
 194   void reset();
 195 
 196   template <class T>
 197   void details(T* phase, const char* indent) const;
 198 
 199   void log_phase(WorkerDataArray<double>* phase, uint indent, outputStream* out, bool print_sum) const;
 200   void debug_phase(WorkerDataArray<double>* phase, uint extra_indent = 0) const;
 201   void trace_phase(WorkerDataArray<double>* phase, bool print_sum = true) const;
 202 
 203   void info_time(const char* name, double value) const;
 204   void debug_time(const char* name, double value) const;
 205   // This will print logs for both 'gc+phases' and 'gc+phases+ref'.
 206   void debug_time_for_reference(const char* name, double value) const;
 207   void trace_time(const char* name, double value) const;
 208   void trace_count(const char* name, size_t value) const;
 209 
 210   double print_pre_evacuate_collection_set() const;
 211   double print_evacuate_collection_set() const;
 212   double print_evacuate_optional_collection_set() const;
 213   double print_post_evacuate_collection_set() const;
 214   void print_other(double accounted_ms) const;
 215 
 216  public:
 217   G1GCPhaseTimes(STWGCTimer* gc_timer, uint max_gc_threads);
 218   void note_gc_start();
 219   void print();
 220   static const char* phase_name(GCParPhases phase);
 221 
 222   // record the time a phase took in seconds
 223   void record_time_secs(GCParPhases phase, uint worker_i, double secs);
 224 
 225   // add a number of seconds to a phase
 226   void add_time_secs(GCParPhases phase, uint worker_i, double secs);
 227 
 228   void record_or_add_time_secs(GCParPhases phase, uint worker_i, double secs);
 229 
 230   double get_time_secs(GCParPhases phase, uint worker_i);
 231 
 232   void record_thread_work_item(GCParPhases phase, uint worker_i, size_t count, uint index = 0);
 233 
 234   void record_or_add_thread_work_item(GCParPhases phase, uint worker_i, size_t count, uint index = 0);
 235 
 236   size_t get_thread_work_item(GCParPhases phase, uint worker_i, uint index = 0);
 237 
 238   // return the average time for a phase in milliseconds
 239   double average_time_ms(GCParPhases phase);
 240 
 241   size_t sum_thread_work_items(GCParPhases phase, uint index = 0);
 242 
 243  public:
 244 
 245   void record_prepare_tlab_time_ms(double ms) {
 246     _cur_prepare_tlab_time_ms = ms;
 247   }
 248 
 249   void record_resize_tlab_time_ms(double ms) {
 250     _cur_resize_tlab_time_ms = ms;
 251   }
 252 
 253   void record_derived_pointer_table_update_time(double ms) {
 254     _cur_derived_pointer_table_update_time_ms = ms;
 255   }
 256 
 257   void record_clear_ct_time(double ms) {
 258     _cur_clear_ct_time_ms = ms;
 259   }
 260 
 261   void record_expand_heap_time(double ms) {
 262     _cur_expand_heap_time_ms = ms;
 263   }
 264 
 265   void record_initial_evac_time(double ms) {
 266     _cur_collection_initial_evac_time_ms = ms;
 267   }
 268 
 269   void record_or_add_optional_evac_time(double ms) {
 270     _cur_optional_evac_ms += ms;
 271   }
 272 
 273   void record_or_add_code_root_fixup_time(double ms) {
 274     _cur_collection_code_root_fixup_time_ms += ms;
 275   }
 276 
 277   void record_strong_code_root_purge_time(double ms) {
 278     _cur_strong_code_root_purge_time_ms = ms;
 279   }
 280 
 281   void record_evac_fail_recalc_used_time(double ms) {
 282     _cur_evac_fail_recalc_used = ms;
 283   }
 284 
 285   void record_evac_fail_remove_self_forwards(double ms) {
 286     _cur_evac_fail_remove_self_forwards = ms;
 287   }
 288 
 289   void record_string_deduplication_time(double ms) {
 290     _cur_string_deduplication_time_ms = ms;
 291   }
 292 
 293   void record_ref_proc_time(double ms) {
 294     _cur_ref_proc_time_ms = ms;
 295   }
 296 
 297   void record_root_region_scan_wait_time(double time_ms) {
 298     _root_region_scan_wait_time_ms = time_ms;
 299   }
 300 
 301   void record_total_free_cset_time_ms(double time_ms) {
 302     _recorded_total_free_cset_time_ms = time_ms;
 303   }
 304 
 305   void record_serial_free_cset_time_ms(double time_ms) {
 306     _recorded_serial_free_cset_time_ms = time_ms;
 307   }
 308 
 309   void record_register_regions(double time_ms, size_t total, size_t candidates) {
 310     _cur_region_register_time = time_ms;
 311     _cur_fast_reclaim_humongous_total = total;
 312     _cur_fast_reclaim_humongous_candidates = candidates;
 313   }
 314 
 315   void record_fast_reclaim_humongous_time_ms(double value, size_t reclaimed) {
 316     _cur_fast_reclaim_humongous_time_ms = value;
 317     _cur_fast_reclaim_humongous_reclaimed = reclaimed;
 318   }
 319 
 320   void record_young_cset_choice_time_ms(double time_ms) {
 321     _recorded_young_cset_choice_time_ms = time_ms;
 322   }
 323 
 324   void record_non_young_cset_choice_time_ms(double time_ms) {
 325     _recorded_non_young_cset_choice_time_ms = time_ms;
 326   }
 327 
 328   void record_redirty_logged_cards_time_ms(double time_ms) {
 329     _recorded_redirty_logged_cards_time_ms = time_ms;
 330   }
 331 
 332   void record_preserve_cm_referents_time_ms(double time_ms) {
 333     _recorded_preserve_cm_referents_time_ms = time_ms;
 334   }
 335 
 336   void record_merge_pss_time_ms(double time_ms) {
 337     _recorded_merge_pss_time_ms = time_ms;
 338   }
 339 
 340   void record_start_new_cset_time_ms(double time_ms) {
 341     _recorded_start_new_cset_time_ms = time_ms;
 342   }
 343 
 344   void record_cur_collection_start_sec(double time_ms) {
 345     _cur_collection_start_sec = time_ms;
 346   }
 347 
 348   void record_verify_before_time_ms(double time_ms) {
 349     _cur_verify_before_time_ms = time_ms;
 350   }
 351 
 352   void record_verify_after_time_ms(double time_ms) {
 353     _cur_verify_after_time_ms = time_ms;
 354   }
 355 
 356   void inc_external_accounted_time_ms(double time_ms) {
 357     _external_accounted_time_ms += time_ms;
 358   }
 359 
 360   void record_clear_claimed_marks_time_ms(double recorded_clear_claimed_marks_time_ms) {
 361     _recorded_clear_claimed_marks_time_ms = recorded_clear_claimed_marks_time_ms;
 362   }
 363 
 364   double cur_collection_start_sec() {
 365     return _cur_collection_start_sec;
 366   }
 367 
 368   double cur_collection_par_time_ms() {
 369     return _cur_collection_initial_evac_time_ms;
 370   }
 371 
 372   double cur_clear_ct_time_ms() {
 373     return _cur_clear_ct_time_ms;
 374   }
 375 
 376   double cur_expand_heap_time_ms() {
 377     return _cur_expand_heap_time_ms;
 378   }
 379 
 380   double root_region_scan_wait_time_ms() {
 381     return _root_region_scan_wait_time_ms;
 382   }
 383 
 384   double young_cset_choice_time_ms() {
 385     return _recorded_young_cset_choice_time_ms;
 386   }
 387 
 388   double total_free_cset_time_ms() {
 389     return _recorded_total_free_cset_time_ms;
 390   }
 391 
 392   double non_young_cset_choice_time_ms() {
 393     return _recorded_non_young_cset_choice_time_ms;
 394   }
 395 
 396   double fast_reclaim_humongous_time_ms() {
 397     return _cur_fast_reclaim_humongous_time_ms;
 398   }
 399 
 400   ReferenceProcessorPhaseTimes* ref_phase_times() { return &_ref_phase_times; }
 401 
 402   WeakProcessorPhaseTimes* weak_phase_times() { return &_weak_phase_times; }
 403 };
 404 
 405 class G1EvacPhaseWithTrimTimeTracker : public StackObj {
 406   G1ParScanThreadState* _pss;
 407   Ticks _start;
 408 
 409   Tickspan& _total_time;
 410   Tickspan& _trim_time;
 411 
 412   bool _stopped;
 413 public:
 414   G1EvacPhaseWithTrimTimeTracker(G1ParScanThreadState* pss, Tickspan& total_time, Tickspan& trim_time);
 415   ~G1EvacPhaseWithTrimTimeTracker();
 416 
 417   void stop();
 418 };
 419 
 420 class G1GCParPhaseTimesTracker : public CHeapObj<mtGC> {
 421 protected:
 422   Ticks _start_time;
 423   G1GCPhaseTimes::GCParPhases _phase;
 424   G1GCPhaseTimes* _phase_times;
 425   uint _worker_id;
 426   EventGCPhaseParallel _event;
 427 public:
 428   G1GCParPhaseTimesTracker(G1GCPhaseTimes* phase_times, G1GCPhaseTimes::GCParPhases phase, uint worker_id);
 429   virtual ~G1GCParPhaseTimesTracker();
 430 };
 431 
 432 class G1EvacPhaseTimesTracker : public G1GCParPhaseTimesTracker {
 433   Tickspan _total_time;
 434   Tickspan _trim_time;
 435 
 436   G1EvacPhaseWithTrimTimeTracker _trim_tracker;
 437 public:
 438   G1EvacPhaseTimesTracker(G1GCPhaseTimes* phase_times, G1ParScanThreadState* pss, G1GCPhaseTimes::GCParPhases phase, uint worker_id);
 439   virtual ~G1EvacPhaseTimesTracker();
 440 };
 441 
 442 #endif // SHARE_GC_G1_G1GCPHASETIMES_HPP