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