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 #include "precompiled.hpp" 26 #include "gc/g1/g1CollectedHeap.inline.hpp" 27 #include "gc/g1/g1GCPhaseTimes.hpp" 28 #include "gc/g1/g1HotCardCache.hpp" 29 #include "gc/g1/g1ParScanThreadState.inline.hpp" 30 #include "gc/g1/g1StringDedup.hpp" 31 #include "gc/shared/gcTimer.hpp" 32 #include "gc/shared/workerDataArray.inline.hpp" 33 #include "memory/resourceArea.hpp" 34 #include "logging/log.hpp" 35 #include "logging/logStream.hpp" 36 #include "runtime/timer.hpp" 37 #include "runtime/os.hpp" 38 #include "utilities/macros.hpp" 39 40 static const char* indent(uint level) { 41 static const char* Indents[] = {"", " ", " ", " ", " ", " "}; 42 assert(level < ARRAY_SIZE(Indents), "Too high indent level %u", level); 43 return Indents[level]; 44 } 45 46 G1GCPhaseTimes::G1GCPhaseTimes(STWGCTimer* gc_timer, uint max_gc_threads) : 47 _max_gc_threads(max_gc_threads), 48 _gc_start_counter(0), 49 _gc_pause_time_ms(0.0), 50 _ref_phase_times(gc_timer, max_gc_threads), 51 _weak_phase_times(max_gc_threads) 52 { 53 assert(max_gc_threads > 0, "Must have some GC threads"); 54 55 _gc_par_phases[GCWorkerStart] = new WorkerDataArray<double>("GC Worker Start (ms):", max_gc_threads); 56 _gc_par_phases[ExtRootScan] = new WorkerDataArray<double>("Ext Root Scanning (ms):", max_gc_threads); 57 58 // Root scanning phases 59 _gc_par_phases[ThreadRoots] = new WorkerDataArray<double>("Thread Roots (ms):", max_gc_threads); 60 _gc_par_phases[UniverseRoots] = new WorkerDataArray<double>("Universe Roots (ms):", max_gc_threads); 61 _gc_par_phases[JNIRoots] = new WorkerDataArray<double>("JNI Handles Roots (ms):", max_gc_threads); 62 _gc_par_phases[ObjectSynchronizerRoots] = new WorkerDataArray<double>("ObjectSynchronizer Roots (ms):", max_gc_threads); 63 _gc_par_phases[ManagementRoots] = new WorkerDataArray<double>("Management Roots (ms):", max_gc_threads); 64 _gc_par_phases[SystemDictionaryRoots] = new WorkerDataArray<double>("SystemDictionary Roots (ms):", max_gc_threads); 65 _gc_par_phases[CLDGRoots] = new WorkerDataArray<double>("CLDG Roots (ms):", max_gc_threads); 66 _gc_par_phases[JVMTIRoots] = new WorkerDataArray<double>("JVMTI Roots (ms):", max_gc_threads); 67 AOT_ONLY(_gc_par_phases[AOTCodeRoots] = new WorkerDataArray<double>("AOT Root Scan (ms):", max_gc_threads);) 68 _gc_par_phases[CMRefRoots] = new WorkerDataArray<double>("CM RefProcessor Roots (ms):", max_gc_threads); 69 70 _gc_par_phases[MergeER] = new WorkerDataArray<double>("Eager Reclaim (ms):", max_gc_threads); 71 72 _gc_par_phases[MergeRS] = new WorkerDataArray<double>("Remembered Sets (ms):", max_gc_threads); 73 _gc_par_phases[MergeRS]->create_thread_work_items("Merged Sparse:", MergeRSMergedSparse); 74 _gc_par_phases[MergeRS]->create_thread_work_items("Merged Fine:", MergeRSMergedFine); 75 _gc_par_phases[MergeRS]->create_thread_work_items("Merged Coarse:", MergeRSMergedCoarse); 76 _gc_par_phases[MergeRS]->create_thread_work_items("Dirty Cards:", MergeRSDirtyCards); 77 78 _gc_par_phases[OptMergeRS] = new WorkerDataArray<double>("Optional Remembered Sets (ms):", max_gc_threads); 79 _gc_par_phases[OptMergeRS]->create_thread_work_items("Merged Sparse:", MergeRSMergedSparse); 80 _gc_par_phases[OptMergeRS]->create_thread_work_items("Merged Fine:", MergeRSMergedFine); 81 _gc_par_phases[OptMergeRS]->create_thread_work_items("Merged Coarse:", MergeRSMergedCoarse); 82 _gc_par_phases[OptMergeRS]->create_thread_work_items("Dirty Cards:", MergeRSDirtyCards); 83 84 _gc_par_phases[MergeLB] = new WorkerDataArray<double>("Log Buffers (ms):", max_gc_threads); 85 if (G1HotCardCache::default_use_cache()) { 86 _gc_par_phases[MergeHCC] = new WorkerDataArray<double>("Hot Card Cache (ms):", max_gc_threads); 87 _gc_par_phases[MergeHCC]->create_thread_work_items("Dirty Cards:", MergeHCCDirtyCards); 88 _gc_par_phases[MergeHCC]->create_thread_work_items("Skipped Cards:", MergeHCCSkippedCards); 89 } else { 90 _gc_par_phases[MergeHCC] = NULL; 91 } 92 _gc_par_phases[ScanHR] = new WorkerDataArray<double>("Scan Heap Roots (ms):", max_gc_threads); 93 _gc_par_phases[OptScanHR] = new WorkerDataArray<double>("Optional Scan Heap Roots (ms):", max_gc_threads); 94 _gc_par_phases[CodeRoots] = new WorkerDataArray<double>("Code Root Scan (ms):", max_gc_threads); 95 _gc_par_phases[OptCodeRoots] = new WorkerDataArray<double>("Optional Code Root Scan (ms):", max_gc_threads); 96 _gc_par_phases[ObjCopy] = new WorkerDataArray<double>("Object Copy (ms):", max_gc_threads); 97 _gc_par_phases[OptObjCopy] = new WorkerDataArray<double>("Optional Object Copy (ms):", max_gc_threads); 98 _gc_par_phases[Termination] = new WorkerDataArray<double>("Termination (ms):", max_gc_threads); 99 _gc_par_phases[OptTermination] = new WorkerDataArray<double>("Optional Termination (ms):", max_gc_threads); 100 _gc_par_phases[GCWorkerTotal] = new WorkerDataArray<double>("GC Worker Total (ms):", max_gc_threads); 101 _gc_par_phases[GCWorkerEnd] = new WorkerDataArray<double>("GC Worker End (ms):", max_gc_threads); 102 _gc_par_phases[Other] = new WorkerDataArray<double>("GC Worker Other (ms):", max_gc_threads); 103 104 _gc_par_phases[ScanHR]->create_thread_work_items("Scanned Cards:", ScanHRScannedCards); 105 _gc_par_phases[ScanHR]->create_thread_work_items("Scanned Blocks:", ScanHRScannedBlocks); 106 _gc_par_phases[ScanHR]->create_thread_work_items("Claimed Chunks:", ScanHRClaimedChunks); 107 108 _gc_par_phases[OptScanHR]->create_thread_work_items("Scanned Cards:", ScanHRScannedCards); 109 _gc_par_phases[OptScanHR]->create_thread_work_items("Scanned Blocks:", ScanHRScannedBlocks); 110 _gc_par_phases[OptScanHR]->create_thread_work_items("Claimed Chunks:", ScanHRClaimedChunks); 111 _gc_par_phases[OptScanHR]->create_thread_work_items("Scanned Refs:", ScanHRScannedOptRefs); 112 _gc_par_phases[OptScanHR]->create_thread_work_items("Used Memory:", ScanHRUsedMemory); 113 114 _gc_par_phases[MergeLB]->create_thread_work_items("Dirty Cards:", MergeLBDirtyCards); 115 _gc_par_phases[MergeLB]->create_thread_work_items("Skipped Cards:", MergeLBSkippedCards); 116 117 _gc_par_phases[MergePSS] = new WorkerDataArray<double>("Merge Per-Thread State", 1 /* length */, true /* is_serial */); 118 119 _gc_par_phases[MergePSS]->create_thread_work_items("Copied Bytes", MergePSSCopiedBytes, max_gc_threads); 120 _gc_par_phases[MergePSS]->create_thread_work_items("LAB Waste", MergePSSLABWasteBytes, max_gc_threads); 121 _gc_par_phases[MergePSS]->create_thread_work_items("LAB Undo Waste", MergePSSLABUndoWasteBytes, max_gc_threads); 122 123 _gc_par_phases[Termination]->create_thread_work_items("Termination Attempts:"); 124 125 _gc_par_phases[OptTermination]->create_thread_work_items("Optional Termination Attempts:"); 126 127 if (UseStringDeduplication) { 128 _gc_par_phases[StringDedupQueueFixup] = new WorkerDataArray<double>("Queue Fixup (ms):", max_gc_threads); 129 _gc_par_phases[StringDedupTableFixup] = new WorkerDataArray<double>("Table Fixup (ms):", max_gc_threads); 130 } else { 131 _gc_par_phases[StringDedupQueueFixup] = NULL; 132 _gc_par_phases[StringDedupTableFixup] = NULL; 133 } 134 135 _gc_par_phases[RedirtyCards] = new WorkerDataArray<double>("Parallel Redirty (ms):", max_gc_threads); 136 _gc_par_phases[RedirtyCards]->create_thread_work_items("Redirtied Cards:"); 137 138 _gc_par_phases[ParFreeCSet] = new WorkerDataArray<double>("Parallel Free Collection Set (ms):", max_gc_threads); 139 _gc_par_phases[YoungFreeCSet] = new WorkerDataArray<double>("Young Free Collection Set (ms):", max_gc_threads); 140 _gc_par_phases[NonYoungFreeCSet] = new WorkerDataArray<double>("Non-Young Free Collection Set (ms):", max_gc_threads); 141 _gc_par_phases[RebuildFreeList] = new WorkerDataArray<double>("Parallel Rebuild Free List (ms):", max_gc_threads); 142 143 reset(); 144 } 145 146 void G1GCPhaseTimes::reset() { 147 _cur_collection_initial_evac_time_ms = 0.0; 148 _cur_optional_evac_time_ms = 0.0; 149 _cur_collection_code_root_fixup_time_ms = 0.0; 150 _cur_strong_code_root_purge_time_ms = 0.0; 151 _cur_merge_heap_roots_time_ms = 0.0; 152 _cur_optional_merge_heap_roots_time_ms = 0.0; 153 _cur_prepare_merge_heap_roots_time_ms = 0.0; 154 _cur_optional_prepare_merge_heap_roots_time_ms = 0.0; 155 _cur_evac_fail_recalc_used = 0.0; 156 _cur_evac_fail_remove_self_forwards = 0.0; 157 _cur_string_deduplication_time_ms = 0.0; 158 _cur_prepare_tlab_time_ms = 0.0; 159 _cur_resize_tlab_time_ms = 0.0; 160 _cur_concatenate_dirty_card_logs_time_ms = 0.0; 161 _cur_derived_pointer_table_update_time_ms = 0.0; 162 _cur_clear_ct_time_ms = 0.0; 163 _cur_expand_heap_time_ms = 0.0; 164 _cur_ref_proc_time_ms = 0.0; 165 _cur_collection_start_sec = 0.0; 166 _root_region_scan_wait_time_ms = 0.0; 167 _external_accounted_time_ms = 0.0; 168 _recorded_prepare_heap_roots_time_ms = 0.0; 169 _recorded_clear_claimed_marks_time_ms = 0.0; 170 _recorded_young_cset_choice_time_ms = 0.0; 171 _recorded_non_young_cset_choice_time_ms = 0.0; 172 _recorded_redirty_logged_cards_time_ms = 0.0; 173 _recorded_preserve_cm_referents_time_ms = 0.0; 174 _recorded_start_new_cset_time_ms = 0.0; 175 _recorded_total_free_cset_time_ms = 0.0; 176 _recorded_serial_free_cset_time_ms = 0.0; 177 _recorded_total_rebuild_freelist_time_ms = 0.0; 178 _recorded_serial_rebuild_freelist_time_ms = 0.0; 179 _cur_fast_reclaim_humongous_time_ms = 0.0; 180 _cur_region_register_time = 0.0; 181 _cur_fast_reclaim_humongous_total = 0; 182 _cur_fast_reclaim_humongous_candidates = 0; 183 _cur_fast_reclaim_humongous_reclaimed = 0; 184 _cur_verify_before_time_ms = 0.0; 185 _cur_verify_after_time_ms = 0.0; 186 187 for (int i = 0; i < GCParPhasesSentinel; i++) { 188 if (_gc_par_phases[i] != NULL) { 189 _gc_par_phases[i]->reset(); 190 } 191 } 192 193 _ref_phase_times.reset(); 194 _weak_phase_times.reset(); 195 } 196 197 void G1GCPhaseTimes::note_gc_start() { 198 _gc_start_counter = os::elapsed_counter(); 199 reset(); 200 } 201 202 #define ASSERT_PHASE_UNINITIALIZED(phase) \ 203 assert(_gc_par_phases[phase] == NULL || _gc_par_phases[phase]->get(i) == uninitialized, "Phase " #phase " reported for thread that was not started"); 204 205 double G1GCPhaseTimes::worker_time(GCParPhases phase, uint worker) { 206 if (_gc_par_phases[phase] == NULL) { 207 return 0.0; 208 } 209 double value = _gc_par_phases[phase]->get(worker); 210 if (value != WorkerDataArray<double>::uninitialized()) { 211 return value; 212 } 213 return 0.0; 214 } 215 216 void G1GCPhaseTimes::note_gc_end() { 217 _gc_pause_time_ms = TimeHelper::counter_to_millis(os::elapsed_counter() - _gc_start_counter); 218 219 double uninitialized = WorkerDataArray<double>::uninitialized(); 220 221 for (uint i = 0; i < _max_gc_threads; i++) { 222 double worker_start = _gc_par_phases[GCWorkerStart]->get(i); 223 if (worker_start != uninitialized) { 224 assert(_gc_par_phases[GCWorkerEnd]->get(i) != uninitialized, "Worker started but not ended."); 225 double total_worker_time = _gc_par_phases[GCWorkerEnd]->get(i) - _gc_par_phases[GCWorkerStart]->get(i); 226 record_time_secs(GCWorkerTotal, i , total_worker_time); 227 228 double worker_known_time = worker_time(ExtRootScan, i) + 229 worker_time(ScanHR, i) + 230 worker_time(CodeRoots, i) + 231 worker_time(ObjCopy, i) + 232 worker_time(Termination, i); 233 234 record_time_secs(Other, i, total_worker_time - worker_known_time); 235 } else { 236 // Make sure all slots are uninitialized since this thread did not seem to have been started 237 ASSERT_PHASE_UNINITIALIZED(GCWorkerEnd); 238 ASSERT_PHASE_UNINITIALIZED(ExtRootScan); 239 ASSERT_PHASE_UNINITIALIZED(MergeER); 240 ASSERT_PHASE_UNINITIALIZED(MergeRS); 241 ASSERT_PHASE_UNINITIALIZED(OptMergeRS); 242 ASSERT_PHASE_UNINITIALIZED(MergeHCC); 243 ASSERT_PHASE_UNINITIALIZED(MergeLB); 244 ASSERT_PHASE_UNINITIALIZED(ScanHR); 245 ASSERT_PHASE_UNINITIALIZED(CodeRoots); 246 ASSERT_PHASE_UNINITIALIZED(OptCodeRoots); 247 ASSERT_PHASE_UNINITIALIZED(ObjCopy); 248 ASSERT_PHASE_UNINITIALIZED(OptObjCopy); 249 ASSERT_PHASE_UNINITIALIZED(Termination); 250 } 251 } 252 } 253 254 #undef ASSERT_PHASE_UNINITIALIZED 255 256 // record the time a phase took in seconds 257 void G1GCPhaseTimes::record_time_secs(GCParPhases phase, uint worker_id, double secs) { 258 _gc_par_phases[phase]->set(worker_id, secs); 259 } 260 261 // add a number of seconds to a phase 262 void G1GCPhaseTimes::add_time_secs(GCParPhases phase, uint worker_id, double secs) { 263 _gc_par_phases[phase]->add(worker_id, secs); 264 } 265 266 void G1GCPhaseTimes::record_or_add_time_secs(GCParPhases phase, uint worker_id, double secs) { 267 if (_gc_par_phases[phase]->get(worker_id) == _gc_par_phases[phase]->uninitialized()) { 268 record_time_secs(phase, worker_id, secs); 269 } else { 270 add_time_secs(phase, worker_id, secs); 271 } 272 } 273 274 double G1GCPhaseTimes::get_time_secs(GCParPhases phase, uint worker_id) { 275 return _gc_par_phases[phase]->get(worker_id); 276 } 277 278 void G1GCPhaseTimes::record_thread_work_item(GCParPhases phase, uint worker_id, size_t count, uint index) { 279 _gc_par_phases[phase]->set_thread_work_item(worker_id, count, index); 280 } 281 282 void G1GCPhaseTimes::record_or_add_thread_work_item(GCParPhases phase, uint worker_id, size_t count, uint index) { 283 _gc_par_phases[phase]->set_or_add_thread_work_item(worker_id, count, index); 284 } 285 286 size_t G1GCPhaseTimes::get_thread_work_item(GCParPhases phase, uint worker_id, uint index) { 287 return _gc_par_phases[phase]->get_thread_work_item(worker_id, index); 288 } 289 290 // return the average time for a phase in milliseconds 291 double G1GCPhaseTimes::average_time_ms(GCParPhases phase) { 292 if (_gc_par_phases[phase] == NULL) { 293 return 0.0; 294 } 295 return _gc_par_phases[phase]->average() * 1000.0; 296 } 297 298 size_t G1GCPhaseTimes::sum_thread_work_items(GCParPhases phase, uint index) { 299 if (_gc_par_phases[phase] == NULL) { 300 return 0; 301 } 302 assert(_gc_par_phases[phase]->thread_work_items(index) != NULL, "No sub count"); 303 return _gc_par_phases[phase]->thread_work_items(index)->sum(); 304 } 305 306 template <class T> 307 void G1GCPhaseTimes::details(T* phase, const char* indent_str) const { 308 LogTarget(Trace, gc, phases, task) lt; 309 if (lt.is_enabled()) { 310 LogStream ls(lt); 311 ls.print("%s", indent_str); 312 phase->print_details_on(&ls); 313 } 314 } 315 316 void G1GCPhaseTimes::log_phase(WorkerDataArray<double>* phase, uint indent_level, outputStream* out, bool print_sum) const { 317 out->print("%s", indent(indent_level)); 318 phase->print_summary_on(out, print_sum); 319 details(phase, indent(indent_level)); 320 321 for (uint i = 0; i < phase->MaxThreadWorkItems; i++) { 322 WorkerDataArray<size_t>* work_items = phase->thread_work_items(i); 323 if (work_items != NULL) { 324 out->print("%s", indent(indent_level + 1)); 325 work_items->print_summary_on(out, true); 326 details(work_items, indent(indent_level + 1)); 327 } 328 } 329 } 330 331 void G1GCPhaseTimes::debug_phase(WorkerDataArray<double>* phase, uint extra_indent) const { 332 LogTarget(Debug, gc, phases) lt; 333 if (lt.is_enabled()) { 334 ResourceMark rm; 335 LogStream ls(lt); 336 log_phase(phase, 2 + extra_indent, &ls, true); 337 } 338 } 339 340 void G1GCPhaseTimes::trace_phase(WorkerDataArray<double>* phase, bool print_sum, uint extra_indent) const { 341 LogTarget(Trace, gc, phases) lt; 342 if (lt.is_enabled()) { 343 LogStream ls(lt); 344 log_phase(phase, 3 + extra_indent, &ls, print_sum); 345 } 346 } 347 348 #define TIME_FORMAT "%.1lfms" 349 350 void G1GCPhaseTimes::info_time(const char* name, double value) const { 351 log_info(gc, phases)("%s%s: " TIME_FORMAT, indent(1), name, value); 352 } 353 354 void G1GCPhaseTimes::debug_time(const char* name, double value) const { 355 log_debug(gc, phases)("%s%s: " TIME_FORMAT, indent(2), name, value); 356 } 357 358 void G1GCPhaseTimes::debug_time_for_reference(const char* name, double value) const { 359 LogTarget(Debug, gc, phases) lt; 360 LogTarget(Debug, gc, phases, ref) lt2; 361 362 if (lt.is_enabled()) { 363 LogStream ls(lt); 364 ls.print_cr("%s%s: " TIME_FORMAT, indent(2), name, value); 365 } else if (lt2.is_enabled()) { 366 LogStream ls(lt2); 367 ls.print_cr("%s%s: " TIME_FORMAT, indent(2), name, value); 368 } 369 } 370 371 void G1GCPhaseTimes::trace_time(const char* name, double value) const { 372 log_trace(gc, phases)("%s%s: " TIME_FORMAT, indent(3), name, value); 373 } 374 375 void G1GCPhaseTimes::trace_count(const char* name, size_t value) const { 376 log_trace(gc, phases)("%s%s: " SIZE_FORMAT, indent(3), name, value); 377 } 378 379 double G1GCPhaseTimes::print_pre_evacuate_collection_set() const { 380 const double sum_ms = _root_region_scan_wait_time_ms + 381 _cur_prepare_tlab_time_ms + 382 _cur_concatenate_dirty_card_logs_time_ms + 383 _recorded_young_cset_choice_time_ms + 384 _recorded_non_young_cset_choice_time_ms + 385 _cur_region_register_time + 386 _recorded_prepare_heap_roots_time_ms + 387 _recorded_clear_claimed_marks_time_ms; 388 389 info_time("Pre Evacuate Collection Set", sum_ms); 390 391 if (_root_region_scan_wait_time_ms > 0.0) { 392 debug_time("Root Region Scan Waiting", _root_region_scan_wait_time_ms); 393 } 394 debug_time("Prepare TLABs", _cur_prepare_tlab_time_ms); 395 debug_time("Concatenate Dirty Card Logs", _cur_concatenate_dirty_card_logs_time_ms); 396 debug_time("Choose Collection Set", (_recorded_young_cset_choice_time_ms + _recorded_non_young_cset_choice_time_ms)); 397 debug_time("Region Register", _cur_region_register_time); 398 if (G1EagerReclaimHumongousObjects) { 399 trace_count("Humongous Total", _cur_fast_reclaim_humongous_total); 400 trace_count("Humongous Candidate", _cur_fast_reclaim_humongous_candidates); 401 } 402 403 debug_time("Prepare Heap Roots", _recorded_prepare_heap_roots_time_ms); 404 if (_recorded_clear_claimed_marks_time_ms > 0.0) { 405 debug_time("Clear Claimed Marks", _recorded_clear_claimed_marks_time_ms); 406 } 407 return sum_ms; 408 } 409 410 double G1GCPhaseTimes::print_evacuate_optional_collection_set() const { 411 const double sum_ms = _cur_optional_evac_time_ms + _cur_optional_merge_heap_roots_time_ms; 412 if (sum_ms > 0) { 413 info_time("Merge Optional Heap Roots", _cur_optional_merge_heap_roots_time_ms); 414 415 debug_time("Prepare Optional Merge Heap Roots", _cur_optional_prepare_merge_heap_roots_time_ms); 416 debug_phase(_gc_par_phases[OptMergeRS]); 417 418 info_time("Evacuate Optional Collection Set", _cur_optional_evac_time_ms); 419 debug_phase(_gc_par_phases[OptScanHR]); 420 debug_phase(_gc_par_phases[OptObjCopy]); 421 debug_phase(_gc_par_phases[OptCodeRoots]); 422 debug_phase(_gc_par_phases[OptTermination]); 423 } 424 return sum_ms; 425 } 426 427 double G1GCPhaseTimes::print_evacuate_initial_collection_set() const { 428 info_time("Merge Heap Roots", _cur_merge_heap_roots_time_ms); 429 430 debug_time("Prepare Merge Heap Roots", _cur_prepare_merge_heap_roots_time_ms); 431 debug_phase(_gc_par_phases[MergeER]); 432 debug_phase(_gc_par_phases[MergeRS]); 433 if (G1HotCardCache::default_use_cache()) { 434 debug_phase(_gc_par_phases[MergeHCC]); 435 } 436 debug_phase(_gc_par_phases[MergeLB]); 437 438 info_time("Evacuate Collection Set", _cur_collection_initial_evac_time_ms); 439 440 trace_phase(_gc_par_phases[GCWorkerStart], false); 441 debug_phase(_gc_par_phases[ExtRootScan]); 442 for (int i = ExtRootScanSubPhasesFirst; i <= ExtRootScanSubPhasesLast; i++) { 443 trace_phase(_gc_par_phases[i]); 444 } 445 debug_phase(_gc_par_phases[ScanHR]); 446 debug_phase(_gc_par_phases[CodeRoots]); 447 debug_phase(_gc_par_phases[ObjCopy]); 448 debug_phase(_gc_par_phases[Termination]); 449 debug_phase(_gc_par_phases[Other]); 450 debug_phase(_gc_par_phases[GCWorkerTotal]); 451 trace_phase(_gc_par_phases[GCWorkerEnd], false); 452 453 return _cur_collection_initial_evac_time_ms + _cur_merge_heap_roots_time_ms; 454 } 455 456 double G1GCPhaseTimes::print_post_evacuate_collection_set() const { 457 const double evac_fail_handling = _cur_evac_fail_recalc_used + 458 _cur_evac_fail_remove_self_forwards; 459 assert(_gc_par_phases[MergePSS]->get(0) != WorkerDataArray<double>::uninitialized(), "must be set"); 460 const double merge_pss = _gc_par_phases[MergePSS]->get(0) * MILLIUNITS; 461 const double sum_ms = evac_fail_handling + 462 _cur_collection_code_root_fixup_time_ms + 463 _recorded_preserve_cm_referents_time_ms + 464 _cur_ref_proc_time_ms + 465 (_weak_phase_times.total_time_sec() * MILLIUNITS) + 466 _cur_clear_ct_time_ms + 467 merge_pss + 468 _cur_strong_code_root_purge_time_ms + 469 _recorded_redirty_logged_cards_time_ms + 470 _recorded_total_free_cset_time_ms + 471 _recorded_total_rebuild_freelist_time_ms + 472 _cur_fast_reclaim_humongous_time_ms + 473 _cur_expand_heap_time_ms + 474 _cur_string_deduplication_time_ms; 475 476 info_time("Post Evacuate Collection Set", sum_ms); 477 478 debug_time("Code Roots Fixup", _cur_collection_code_root_fixup_time_ms); 479 480 debug_time("Clear Card Table", _cur_clear_ct_time_ms); 481 482 debug_time_for_reference("Reference Processing", _cur_ref_proc_time_ms); 483 _ref_phase_times.print_all_references(2, false); 484 _weak_phase_times.log_print(2); 485 486 if (G1StringDedup::is_enabled()) { 487 debug_time("String Deduplication", _cur_string_deduplication_time_ms); 488 debug_phase(_gc_par_phases[StringDedupQueueFixup], 1); 489 debug_phase(_gc_par_phases[StringDedupTableFixup], 1); 490 } 491 492 if (G1CollectedHeap::heap()->evacuation_failed()) { 493 debug_time("Evacuation Failure", evac_fail_handling); 494 trace_time("Recalculate Used", _cur_evac_fail_recalc_used); 495 trace_time("Remove Self Forwards",_cur_evac_fail_remove_self_forwards); 496 } 497 498 debug_phase(_gc_par_phases[MergePSS], 0); 499 debug_time("Code Roots Purge", _cur_strong_code_root_purge_time_ms); 500 501 debug_time("Redirty Cards", _recorded_redirty_logged_cards_time_ms); 502 trace_phase(_gc_par_phases[RedirtyCards]); 503 #if COMPILER2_OR_JVMCI 504 debug_time("DerivedPointerTable Update", _cur_derived_pointer_table_update_time_ms); 505 #endif 506 507 debug_time("Free Collection Set", _recorded_total_free_cset_time_ms); 508 trace_time("Serial Free Collection Set", _recorded_serial_free_cset_time_ms); 509 trace_phase(_gc_par_phases[ParFreeCSet]); 510 trace_phase(_gc_par_phases[YoungFreeCSet], true, 1); 511 trace_phase(_gc_par_phases[NonYoungFreeCSet], true, 1); 512 513 debug_time("Rebuild Free List", _recorded_total_rebuild_freelist_time_ms); 514 trace_time("Serial Rebuild Free List ", _recorded_serial_rebuild_freelist_time_ms); 515 trace_phase(_gc_par_phases[RebuildFreeList]); 516 517 if (G1EagerReclaimHumongousObjects) { 518 debug_time("Humongous Reclaim", _cur_fast_reclaim_humongous_time_ms); 519 trace_count("Humongous Reclaimed", _cur_fast_reclaim_humongous_reclaimed); 520 } 521 debug_time("Start New Collection Set", _recorded_start_new_cset_time_ms); 522 if (UseTLAB && ResizeTLAB) { 523 debug_time("Resize TLABs", _cur_resize_tlab_time_ms); 524 } 525 debug_time("Expand Heap After Collection", _cur_expand_heap_time_ms); 526 527 528 return sum_ms; 529 } 530 531 void G1GCPhaseTimes::print_other(double accounted_ms) const { 532 info_time("Other", _gc_pause_time_ms - accounted_ms); 533 } 534 535 void G1GCPhaseTimes::print() { 536 note_gc_end(); 537 538 if (_cur_verify_before_time_ms > 0.0) { 539 debug_time("Verify Before", _cur_verify_before_time_ms); 540 } 541 542 double accounted_ms = 0.0; 543 accounted_ms += print_pre_evacuate_collection_set(); 544 accounted_ms += print_evacuate_initial_collection_set(); 545 accounted_ms += print_evacuate_optional_collection_set(); 546 accounted_ms += print_post_evacuate_collection_set(); 547 print_other(accounted_ms); 548 549 if (_cur_verify_after_time_ms > 0.0) { 550 debug_time("Verify After", _cur_verify_after_time_ms); 551 } 552 } 553 554 const char* G1GCPhaseTimes::phase_name(GCParPhases phase) { 555 static const char* names[] = { 556 "GCWorkerStart", 557 "ExtRootScan", 558 "ThreadRoots", 559 "UniverseRoots", 560 "JNIRoots", 561 "ObjectSynchronizerRoots", 562 "ManagementRoots", 563 "SystemDictionaryRoots", 564 "CLDGRoots", 565 "JVMTIRoots", 566 AOT_ONLY("AOTCodeRoots" COMMA) 567 "CMRefRoots", 568 "MergeER", 569 "MergeRS", 570 "OptMergeRS", 571 "MergeLB", 572 "MergeHCC", 573 "ScanHR", 574 "OptScanHR", 575 "CodeRoots", 576 "OptCodeRoots", 577 "ObjCopy", 578 "OptObjCopy", 579 "Termination", 580 "OptTermination", 581 "Other", 582 "GCWorkerTotal", 583 "GCWorkerEnd", 584 "StringDedupQueueFixup", 585 "StringDedupTableFixup", 586 "RedirtyCards", 587 "ParFreeCSet", 588 "YoungFreeCSet", 589 "NonYoungFreeCSet", 590 "RebuildFreeList", 591 "MergePSS" 592 //GCParPhasesSentinel only used to tell end of enum 593 }; 594 595 STATIC_ASSERT(ARRAY_SIZE(names) == G1GCPhaseTimes::GCParPhasesSentinel); // GCParPhases enum and corresponding string array should have the same "length", this tries to assert it 596 597 return names[phase]; 598 } 599 600 G1EvacPhaseWithTrimTimeTracker::G1EvacPhaseWithTrimTimeTracker(G1ParScanThreadState* pss, Tickspan& total_time, Tickspan& trim_time) : 601 _pss(pss), 602 _start(Ticks::now()), 603 _total_time(total_time), 604 _trim_time(trim_time), 605 _stopped(false) { 606 607 assert(_pss->trim_ticks().value() == 0, "Possibly remaining trim ticks left over from previous use"); 608 } 609 610 G1EvacPhaseWithTrimTimeTracker::~G1EvacPhaseWithTrimTimeTracker() { 611 if (!_stopped) { 612 stop(); 613 } 614 } 615 616 void G1EvacPhaseWithTrimTimeTracker::stop() { 617 assert(!_stopped, "Should only be called once"); 618 _total_time += (Ticks::now() - _start) - _pss->trim_ticks(); 619 _trim_time += _pss->trim_ticks(); 620 _pss->reset_trim_ticks(); 621 _stopped = true; 622 } 623 624 G1GCParPhaseTimesTracker::G1GCParPhaseTimesTracker(G1GCPhaseTimes* phase_times, G1GCPhaseTimes::GCParPhases phase, uint worker_id, bool must_record) : 625 _start_time(), _phase(phase), _phase_times(phase_times), _worker_id(worker_id), _event(), _must_record(must_record) { 626 if (_phase_times != NULL) { 627 _start_time = Ticks::now(); 628 } 629 } 630 631 G1GCParPhaseTimesTracker::~G1GCParPhaseTimesTracker() { 632 if (_phase_times != NULL) { 633 if (_must_record) { 634 _phase_times->record_time_secs(_phase, _worker_id, (Ticks::now() - _start_time).seconds()); 635 } else { 636 _phase_times->record_or_add_time_secs(_phase, _worker_id, (Ticks::now() - _start_time).seconds()); 637 } 638 _event.commit(GCId::current(), _worker_id, G1GCPhaseTimes::phase_name(_phase)); 639 } 640 } 641 642 G1EvacPhaseTimesTracker::G1EvacPhaseTimesTracker(G1GCPhaseTimes* phase_times, 643 G1ParScanThreadState* pss, 644 G1GCPhaseTimes::GCParPhases phase, 645 uint worker_id) : 646 G1GCParPhaseTimesTracker(phase_times, phase, worker_id), 647 _total_time(), 648 _trim_time(), 649 _trim_tracker(pss, _total_time, _trim_time) { 650 } 651 652 G1EvacPhaseTimesTracker::~G1EvacPhaseTimesTracker() { 653 if (_phase_times != NULL) { 654 // Explicitly stop the trim tracker since it's not yet destructed. 655 _trim_tracker.stop(); 656 // Exclude trim time by increasing the start time. 657 _start_time += _trim_time; 658 _phase_times->record_or_add_time_secs(G1GCPhaseTimes::ObjCopy, _worker_id, _trim_time.seconds()); 659 } 660 } 661