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