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