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 #if INCLUDE_AOT 59 AOTCodeRoots, 60 #endif 61 CMRefRoots, 62 WaitForStrongCLD, 63 WeakCLDRoots, 64 SATBFiltering, 65 UpdateRS, 66 ScanHCC, 67 ScanRS, 68 OptScanRS, 69 CodeRoots, 70 ObjCopy, 71 OptObjCopy, 72 Termination, 73 Other, 74 GCWorkerTotal, 75 GCWorkerEnd, 76 StringDedupQueueFixup, 77 StringDedupTableFixup, 78 RedirtyCards, 79 YoungFreeCSet, 80 NonYoungFreeCSet, 81 GCParPhasesSentinel 82 }; 83 84 enum GCScanRSWorkItems { 85 ScanRSScannedCards, 86 ScanRSClaimedCards, 87 ScanRSSkippedCards 88 }; 89 90 enum GCUpdateRSWorkItems { 91 UpdateRSProcessedBuffers, 92 UpdateRSScannedCards, 93 UpdateRSSkippedCards 94 }; 95 96 enum GCObjCopyWorkItems { 97 ObjCopyLABWaste, 98 ObjCopyLABUndoWaste 99 }; 100 101 enum GCOptCSetWorkItems { 102 OptCSetScannedCards, 103 OptCSetClaimedCards, 104 OptCSetSkippedCards, 105 OptCSetUsedMemory 106 }; 107 108 private: 109 // Markers for grouping the phases in the GCPhases enum above 110 static const int GCMainParPhasesLast = GCWorkerEnd; 111 112 WorkerDataArray<double>* _gc_par_phases[GCParPhasesSentinel]; 113 114 WorkerDataArray<size_t>* _update_rs_processed_buffers; 115 WorkerDataArray<size_t>* _update_rs_scanned_cards; 116 WorkerDataArray<size_t>* _update_rs_skipped_cards; 117 118 WorkerDataArray<size_t>* _scan_rs_scanned_cards; 119 WorkerDataArray<size_t>* _scan_rs_claimed_cards; 120 WorkerDataArray<size_t>* _scan_rs_skipped_cards; 121 122 WorkerDataArray<size_t>* _obj_copy_lab_waste; 123 WorkerDataArray<size_t>* _obj_copy_lab_undo_waste; 124 125 WorkerDataArray<size_t>* _opt_cset_scanned_cards; 126 WorkerDataArray<size_t>* _opt_cset_claimed_cards; 127 WorkerDataArray<size_t>* _opt_cset_skipped_cards; 128 WorkerDataArray<size_t>* _opt_cset_used_memory; 129 130 WorkerDataArray<size_t>* _termination_attempts; 131 132 WorkerDataArray<size_t>* _redirtied_cards; 133 134 double _cur_collection_par_time_ms; 135 double _cur_optional_evac_ms; 136 double _cur_collection_code_root_fixup_time_ms; 137 double _cur_strong_code_root_purge_time_ms; 138 139 double _cur_evac_fail_recalc_used; 140 double _cur_evac_fail_remove_self_forwards; 141 142 double _cur_string_deduplication_time_ms; 143 144 double _cur_prepare_tlab_time_ms; 145 double _cur_resize_tlab_time_ms; 146 147 double _cur_derived_pointer_table_update_time_ms; 148 149 double _cur_clear_ct_time_ms; 150 double _cur_expand_heap_time_ms; 151 double _cur_ref_proc_time_ms; 152 153 double _cur_collection_start_sec; 154 double _root_region_scan_wait_time_ms; 155 156 double _external_accounted_time_ms; 157 158 double _recorded_clear_claimed_marks_time_ms; 159 160 double _recorded_young_cset_choice_time_ms; 161 double _recorded_non_young_cset_choice_time_ms; 162 163 double _recorded_redirty_logged_cards_time_ms; 164 165 double _recorded_preserve_cm_referents_time_ms; 166 167 double _recorded_merge_pss_time_ms; 168 169 double _recorded_start_new_cset_time_ms; 170 171 double _recorded_total_free_cset_time_ms; 172 173 double _recorded_serial_free_cset_time_ms; 174 175 double _cur_fast_reclaim_humongous_time_ms; 176 double _cur_fast_reclaim_humongous_register_time_ms; 177 size_t _cur_fast_reclaim_humongous_total; 178 size_t _cur_fast_reclaim_humongous_candidates; 179 size_t _cur_fast_reclaim_humongous_reclaimed; 180 181 double _cur_verify_before_time_ms; 182 double _cur_verify_after_time_ms; 183 184 ReferenceProcessorPhaseTimes _ref_phase_times; 185 WeakProcessorPhaseTimes _weak_phase_times; 186 187 double worker_time(GCParPhases phase, uint worker); 188 void note_gc_end(); 189 void reset(); 190 191 template <class T> 192 void details(T* phase, const char* indent) const; 193 194 void log_phase(WorkerDataArray<double>* phase, uint indent, outputStream* out, bool print_sum) const; 195 void debug_phase(WorkerDataArray<double>* phase, uint extra_indent = 0) const; 196 void trace_phase(WorkerDataArray<double>* phase, bool print_sum = true) const; 197 198 void info_time(const char* name, double value) const; 199 void debug_time(const char* name, double value) const; 200 // This will print logs for both 'gc+phases' and 'gc+phases+ref'. 201 void debug_time_for_reference(const char* name, double value) const; 202 void trace_time(const char* name, double value) const; 203 void trace_count(const char* name, size_t value) const; 204 205 double print_pre_evacuate_collection_set() const; 206 double print_evacuate_collection_set() const; 207 double print_evacuate_optional_collection_set() const; 208 double print_post_evacuate_collection_set() const; 209 void print_other(double accounted_ms) const; 210 211 public: 212 G1GCPhaseTimes(STWGCTimer* gc_timer, uint max_gc_threads); 213 void note_gc_start(); 214 void print(); 215 static const char* phase_name(GCParPhases phase); 216 217 // record the time a phase took in seconds 218 void record_time_secs(GCParPhases phase, uint worker_i, double secs); 219 220 // add a number of seconds to a phase 221 void add_time_secs(GCParPhases phase, uint worker_i, double secs); 222 223 void record_or_add_time_secs(GCParPhases phase, uint worker_i, double secs); 224 225 void record_thread_work_item(GCParPhases phase, uint worker_i, size_t count, uint index = 0); 226 227 void record_or_add_thread_work_item(GCParPhases phase, uint worker_i, size_t count, uint index = 0); 228 229 // return the average time for a phase in milliseconds 230 double average_time_ms(GCParPhases phase); 231 232 size_t sum_thread_work_items(GCParPhases phase, uint index = 0); 233 234 public: 235 236 void record_prepare_tlab_time_ms(double ms) { 237 _cur_prepare_tlab_time_ms = ms; 238 } 239 240 void record_resize_tlab_time_ms(double ms) { 241 _cur_resize_tlab_time_ms = ms; 242 } 243 244 void record_derived_pointer_table_update_time(double ms) { 245 _cur_derived_pointer_table_update_time_ms = ms; 246 } 247 248 void record_clear_ct_time(double ms) { 249 _cur_clear_ct_time_ms = ms; 250 } 251 252 void record_expand_heap_time(double ms) { 253 _cur_expand_heap_time_ms = ms; 254 } 255 256 void record_par_time(double ms) { 257 _cur_collection_par_time_ms = ms; 258 } 259 260 void record_optional_evacuation(double ms) { 261 _cur_optional_evac_ms = ms; 262 } 263 264 void record_code_root_fixup_time(double ms) { 265 _cur_collection_code_root_fixup_time_ms = ms; 266 } 267 268 void record_strong_code_root_purge_time(double ms) { 269 _cur_strong_code_root_purge_time_ms = ms; 270 } 271 272 void record_evac_fail_recalc_used_time(double ms) { 273 _cur_evac_fail_recalc_used = ms; 274 } 275 276 void record_evac_fail_remove_self_forwards(double ms) { 277 _cur_evac_fail_remove_self_forwards = ms; 278 } 279 280 void record_string_deduplication_time(double ms) { 281 _cur_string_deduplication_time_ms = ms; 282 } 283 284 void record_ref_proc_time(double ms) { 285 _cur_ref_proc_time_ms = ms; 286 } 287 288 void record_root_region_scan_wait_time(double time_ms) { 289 _root_region_scan_wait_time_ms = time_ms; 290 } 291 292 void record_total_free_cset_time_ms(double time_ms) { 293 _recorded_total_free_cset_time_ms = time_ms; 294 } 295 296 void record_serial_free_cset_time_ms(double time_ms) { 297 _recorded_serial_free_cset_time_ms = time_ms; 298 } 299 300 void record_fast_reclaim_humongous_stats(double time_ms, size_t total, size_t candidates) { 301 _cur_fast_reclaim_humongous_register_time_ms = time_ms; 302 _cur_fast_reclaim_humongous_total = total; 303 _cur_fast_reclaim_humongous_candidates = candidates; 304 } 305 306 void record_fast_reclaim_humongous_time_ms(double value, size_t reclaimed) { 307 _cur_fast_reclaim_humongous_time_ms = value; 308 _cur_fast_reclaim_humongous_reclaimed = reclaimed; 309 } 310 311 void record_young_cset_choice_time_ms(double time_ms) { 312 _recorded_young_cset_choice_time_ms = time_ms; 313 } 314 315 void record_non_young_cset_choice_time_ms(double time_ms) { 316 _recorded_non_young_cset_choice_time_ms = time_ms; 317 } 318 319 void record_redirty_logged_cards_time_ms(double time_ms) { 320 _recorded_redirty_logged_cards_time_ms = time_ms; 321 } 322 323 void record_preserve_cm_referents_time_ms(double time_ms) { 324 _recorded_preserve_cm_referents_time_ms = time_ms; 325 } 326 327 void record_merge_pss_time_ms(double time_ms) { 328 _recorded_merge_pss_time_ms = time_ms; 329 } 330 331 void record_start_new_cset_time_ms(double time_ms) { 332 _recorded_start_new_cset_time_ms = time_ms; 333 } 334 335 void record_cur_collection_start_sec(double time_ms) { 336 _cur_collection_start_sec = time_ms; 337 } 338 339 void record_verify_before_time_ms(double time_ms) { 340 _cur_verify_before_time_ms = time_ms; 341 } 342 343 void record_verify_after_time_ms(double time_ms) { 344 _cur_verify_after_time_ms = time_ms; 345 } 346 347 void inc_external_accounted_time_ms(double time_ms) { 348 _external_accounted_time_ms += time_ms; 349 } 350 351 void record_clear_claimed_marks_time_ms(double recorded_clear_claimed_marks_time_ms) { 352 _recorded_clear_claimed_marks_time_ms = recorded_clear_claimed_marks_time_ms; 353 } 354 355 double cur_collection_start_sec() { 356 return _cur_collection_start_sec; 357 } 358 359 double cur_collection_par_time_ms() { 360 return _cur_collection_par_time_ms; 361 } 362 363 double cur_clear_ct_time_ms() { 364 return _cur_clear_ct_time_ms; 365 } 366 367 double cur_expand_heap_time_ms() { 368 return _cur_expand_heap_time_ms; 369 } 370 371 double root_region_scan_wait_time_ms() { 372 return _root_region_scan_wait_time_ms; 373 } 374 375 double young_cset_choice_time_ms() { 376 return _recorded_young_cset_choice_time_ms; 377 } 378 379 double total_free_cset_time_ms() { 380 return _recorded_total_free_cset_time_ms; 381 } 382 383 double non_young_cset_choice_time_ms() { 384 return _recorded_non_young_cset_choice_time_ms; 385 } 386 387 double fast_reclaim_humongous_time_ms() { 388 return _cur_fast_reclaim_humongous_time_ms; 389 } 390 391 ReferenceProcessorPhaseTimes* ref_phase_times() { return &_ref_phase_times; } 392 393 WeakProcessorPhaseTimes* weak_phase_times() { return &_weak_phase_times; } 394 }; 395 396 class G1EvacPhaseWithTrimTimeTracker : public StackObj { 397 G1ParScanThreadState* _pss; 398 Ticks _start; 399 400 Tickspan& _total_time; 401 Tickspan& _trim_time; 402 403 bool _stopped; 404 public: 405 G1EvacPhaseWithTrimTimeTracker(G1ParScanThreadState* pss, Tickspan& total_time, Tickspan& trim_time); 406 ~G1EvacPhaseWithTrimTimeTracker(); 407 408 void stop(); 409 }; 410 411 class G1GCParPhaseTimesTracker : public CHeapObj<mtGC> { 412 protected: 413 Ticks _start_time; 414 G1GCPhaseTimes::GCParPhases _phase; 415 G1GCPhaseTimes* _phase_times; 416 uint _worker_id; 417 EventGCPhaseParallel _event; 418 public: 419 G1GCParPhaseTimesTracker(G1GCPhaseTimes* phase_times, G1GCPhaseTimes::GCParPhases phase, uint worker_id); 420 virtual ~G1GCParPhaseTimesTracker(); 421 }; 422 423 class G1EvacPhaseTimesTracker : public G1GCParPhaseTimesTracker { 424 Tickspan _total_time; 425 Tickspan _trim_time; 426 427 G1EvacPhaseWithTrimTimeTracker _trim_tracker; 428 public: 429 G1EvacPhaseTimesTracker(G1GCPhaseTimes* phase_times, G1ParScanThreadState* pss, G1GCPhaseTimes::GCParPhases phase, uint worker_id); 430 virtual ~G1EvacPhaseTimesTracker(); 431 }; 432 433 #endif // SHARE_GC_G1_G1GCPHASETIMES_HPP