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