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