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