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 WaitForStrongCLD, 61 WeakCLDRoots, 62 MergeER, 63 MergeRS, 64 OptMergeRS, 65 MergeLB, 66 MergeHCC, 67 ScanHR, 68 OptScanHR, 69 CodeRoots, 70 OptCodeRoots, 71 ObjCopy, 72 OptObjCopy, 73 Termination, 74 OptTermination, 75 Other, 76 GCWorkerTotal, 77 GCWorkerEnd, 78 StringDedupQueueFixup, 79 StringDedupTableFixup, 80 RedirtyCards, 81 YoungFreeCSet, 82 NonYoungFreeCSet, 83 GCParPhasesSentinel 84 }; 85 86 static const GCParPhases ExtRootScanSubPhasesFirst = ThreadRoots; 87 static const GCParPhases ExtRootScanSubPhasesLast = WeakCLDRoots; 88 89 enum GCMergeRSWorkTimes { 90 MergeRSMergedSparse, 91 MergeRSMergedFine, 92 MergeRSMergedCoarse 93 }; 94 95 enum GCScanHRWorkItems { 96 ScanHRScannedCards, 97 ScanHRScannedBlocks, 98 ScanHRClaimedChunks, 99 ScanHRScannedOptRefs, 100 ScanHRUsedMemory 101 }; 102 103 enum GCMergeHCCWorkItems { 104 MergeHCCDirtyCards, 105 MergeHCCSkippedCards 106 }; 107 108 enum GCMergeLBWorkItems { 109 MergeLBDirtyCards, 110 MergeLBSkippedCards 111 }; 112 113 enum GCObjCopyWorkItems { 114 ObjCopyLABWaste, 115 ObjCopyLABUndoWaste 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>* _obj_copy_lab_waste; 149 WorkerDataArray<size_t>* _obj_copy_lab_undo_waste; 150 151 WorkerDataArray<size_t>* _opt_obj_copy_lab_waste; 152 WorkerDataArray<size_t>* _opt_obj_copy_lab_undo_waste; 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_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 _cur_region_register_time; 210 211 double _cur_fast_reclaim_humongous_time_ms; 212 size_t _cur_fast_reclaim_humongous_total; 213 size_t _cur_fast_reclaim_humongous_candidates; 214 size_t _cur_fast_reclaim_humongous_reclaimed; 215 216 double _cur_verify_before_time_ms; 217 double _cur_verify_after_time_ms; 218 219 ReferenceProcessorPhaseTimes _ref_phase_times; 220 WeakProcessorPhaseTimes _weak_phase_times; 221 222 double worker_time(GCParPhases phase, uint worker); 223 void note_gc_end(); 224 void reset(); 225 226 template <class T> 227 void details(T* phase, const char* indent) const; 228 229 void log_phase(WorkerDataArray<double>* phase, uint indent, outputStream* out, bool print_sum) 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_i, double secs); 255 256 // add a number of seconds to a phase 257 void add_time_secs(GCParPhases phase, uint worker_i, double secs); 258 259 void record_or_add_time_secs(GCParPhases phase, uint worker_i, double secs); 260 261 double get_time_secs(GCParPhases phase, uint worker_i); 262 263 void record_thread_work_item(GCParPhases phase, uint worker_i, size_t count, uint index = 0); 264 265 void record_or_add_thread_work_item(GCParPhases phase, uint worker_i, size_t count, uint index = 0); 266 267 size_t get_thread_work_item(GCParPhases phase, uint worker_i, 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 public: 275 276 void record_prepare_tlab_time_ms(double ms) { 277 _cur_prepare_tlab_time_ms = ms; 278 } 279 280 void record_resize_tlab_time_ms(double ms) { 281 _cur_resize_tlab_time_ms = ms; 282 } 283 284 void record_derived_pointer_table_update_time(double ms) { 285 _cur_derived_pointer_table_update_time_ms = ms; 286 } 287 288 void record_clear_ct_time(double ms) { 289 _cur_clear_ct_time_ms = ms; 290 } 291 292 void record_expand_heap_time(double ms) { 293 _cur_expand_heap_time_ms = ms; 294 } 295 296 void record_initial_evac_time(double ms) { 297 _cur_collection_initial_evac_time_ms = ms; 298 } 299 300 void record_or_add_optional_evac_time(double ms) { 301 _cur_optional_evac_ms += ms; 302 } 303 304 void record_or_add_code_root_fixup_time(double ms) { 305 _cur_collection_code_root_fixup_time_ms += ms; 306 } 307 308 void record_strong_code_root_purge_time(double ms) { 309 _cur_strong_code_root_purge_time_ms = ms; 310 } 311 312 void record_merge_heap_roots_time(double ms) { 313 _cur_merge_heap_roots_time_ms += ms; 314 } 315 316 void record_or_add_optional_merge_heap_roots_time(double ms) { 317 _cur_optional_merge_heap_roots_time_ms += ms; 318 } 319 320 void record_prepare_merge_heap_roots_time(double ms) { 321 _cur_prepare_merge_heap_roots_time_ms += ms; 322 } 323 324 void record_or_add_optional_prepare_merge_heap_roots_time(double ms) { 325 _cur_optional_prepare_merge_heap_roots_time_ms += ms; 326 } 327 328 void record_evac_fail_recalc_used_time(double ms) { 329 _cur_evac_fail_recalc_used = ms; 330 } 331 332 void record_evac_fail_remove_self_forwards(double ms) { 333 _cur_evac_fail_remove_self_forwards = ms; 334 } 335 336 void record_string_deduplication_time(double ms) { 337 _cur_string_deduplication_time_ms = ms; 338 } 339 340 void record_ref_proc_time(double ms) { 341 _cur_ref_proc_time_ms = ms; 342 } 343 344 void record_root_region_scan_wait_time(double time_ms) { 345 _root_region_scan_wait_time_ms = time_ms; 346 } 347 348 void record_total_free_cset_time_ms(double time_ms) { 349 _recorded_total_free_cset_time_ms = time_ms; 350 } 351 352 void record_serial_free_cset_time_ms(double time_ms) { 353 _recorded_serial_free_cset_time_ms = time_ms; 354 } 355 356 void record_register_regions(double time_ms, size_t total, size_t candidates) { 357 _cur_region_register_time = time_ms; 358 _cur_fast_reclaim_humongous_total = total; 359 _cur_fast_reclaim_humongous_candidates = candidates; 360 } 361 362 void record_fast_reclaim_humongous_time_ms(double value, size_t reclaimed) { 363 _cur_fast_reclaim_humongous_time_ms = value; 364 _cur_fast_reclaim_humongous_reclaimed = reclaimed; 365 } 366 367 void record_young_cset_choice_time_ms(double time_ms) { 368 _recorded_young_cset_choice_time_ms = time_ms; 369 } 370 371 void record_non_young_cset_choice_time_ms(double time_ms) { 372 _recorded_non_young_cset_choice_time_ms = time_ms; 373 } 374 375 void record_redirty_logged_cards_time_ms(double time_ms) { 376 _recorded_redirty_logged_cards_time_ms = time_ms; 377 } 378 379 void record_preserve_cm_referents_time_ms(double time_ms) { 380 _recorded_preserve_cm_referents_time_ms = time_ms; 381 } 382 383 void record_merge_pss_time_ms(double time_ms) { 384 _recorded_merge_pss_time_ms = time_ms; 385 } 386 387 void record_start_new_cset_time_ms(double time_ms) { 388 _recorded_start_new_cset_time_ms = time_ms; 389 } 390 391 void record_cur_collection_start_sec(double time_ms) { 392 _cur_collection_start_sec = time_ms; 393 } 394 395 void record_verify_before_time_ms(double time_ms) { 396 _cur_verify_before_time_ms = time_ms; 397 } 398 399 void record_verify_after_time_ms(double time_ms) { 400 _cur_verify_after_time_ms = time_ms; 401 } 402 403 void inc_external_accounted_time_ms(double time_ms) { 404 _external_accounted_time_ms += time_ms; 405 } 406 407 void record_prepare_heap_roots_time_ms(double recorded_prepare_heap_roots_time_ms) { 408 _recorded_prepare_heap_roots_time_ms = recorded_prepare_heap_roots_time_ms; 409 } 410 411 void record_clear_claimed_marks_time_ms(double recorded_clear_claimed_marks_time_ms) { 412 _recorded_clear_claimed_marks_time_ms = recorded_clear_claimed_marks_time_ms; 413 } 414 415 double cur_collection_start_sec() { 416 return _cur_collection_start_sec; 417 } 418 419 double cur_collection_par_time_ms() { 420 return _cur_collection_initial_evac_time_ms; 421 } 422 423 double cur_clear_ct_time_ms() { 424 return _cur_clear_ct_time_ms; 425 } 426 427 double cur_expand_heap_time_ms() { 428 return _cur_expand_heap_time_ms; 429 } 430 431 double root_region_scan_wait_time_ms() { 432 return _root_region_scan_wait_time_ms; 433 } 434 435 double young_cset_choice_time_ms() { 436 return _recorded_young_cset_choice_time_ms; 437 } 438 439 double total_free_cset_time_ms() { 440 return _recorded_total_free_cset_time_ms; 441 } 442 443 double non_young_cset_choice_time_ms() { 444 return _recorded_non_young_cset_choice_time_ms; 445 } 446 447 double fast_reclaim_humongous_time_ms() { 448 return _cur_fast_reclaim_humongous_time_ms; 449 } 450 451 size_t fast_reclaim_humongous_candidates() const { 452 return _cur_fast_reclaim_humongous_candidates; 453 } 454 455 ReferenceProcessorPhaseTimes* ref_phase_times() { return &_ref_phase_times; } 456 457 WeakProcessorPhaseTimes* weak_phase_times() { return &_weak_phase_times; } 458 }; 459 460 class G1EvacPhaseWithTrimTimeTracker : public StackObj { 461 G1ParScanThreadState* _pss; 462 Ticks _start; 463 464 Tickspan& _total_time; 465 Tickspan& _trim_time; 466 467 bool _stopped; 468 public: 469 G1EvacPhaseWithTrimTimeTracker(G1ParScanThreadState* pss, Tickspan& total_time, Tickspan& trim_time); 470 ~G1EvacPhaseWithTrimTimeTracker(); 471 472 void stop(); 473 }; 474 475 class G1GCParPhaseTimesTracker : public CHeapObj<mtGC> { 476 protected: 477 Ticks _start_time; 478 G1GCPhaseTimes::GCParPhases _phase; 479 G1GCPhaseTimes* _phase_times; 480 uint _worker_id; 481 EventGCPhaseParallel _event; 482 bool _must_record; 483 484 public: 485 G1GCParPhaseTimesTracker(G1GCPhaseTimes* phase_times, G1GCPhaseTimes::GCParPhases phase, uint worker_id, bool must_record = true); 486 virtual ~G1GCParPhaseTimesTracker(); 487 }; 488 489 class G1EvacPhaseTimesTracker : public G1GCParPhaseTimesTracker { 490 Tickspan _total_time; 491 Tickspan _trim_time; 492 493 G1EvacPhaseWithTrimTimeTracker _trim_tracker; 494 public: 495 G1EvacPhaseTimesTracker(G1GCPhaseTimes* phase_times, G1ParScanThreadState* pss, G1GCPhaseTimes::GCParPhases phase, uint worker_id); 496 virtual ~G1EvacPhaseTimesTracker(); 497 }; 498 499 #endif // SHARE_GC_G1_G1GCPHASETIMES_HPP