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