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