1 2 /* 3 * Copyright (c) 2017, 2018, Red Hat, Inc. All rights reserved. 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_VM_GC_SHENANDOAH_SHENANDOAHPHASETIMEINGS_HPP 26 #define SHARE_VM_GC_SHENANDOAH_SHENANDOAHPHASETIMEINGS_HPP 27 28 #include "memory/allocation.hpp" 29 #include "gc_implementation/shenandoah/shenandoahNumberSeq.hpp" 30 #include "gc_implementation/shenandoah/shenandoahWorkerDataArray.hpp" 31 #include "gc_implementation/shenandoah/shenandoahWorkerDataArray.inline.hpp" 32 33 class ShenandoahCollectorPolicy; 34 class outputStream; 35 36 #define SHENANDOAH_PAR_PHASE_DO(CNT_PREFIX, DESC_PREFIX, f) \ 37 f(CNT_PREFIX ## TotalWork, DESC_PREFIX "<total>") \ 38 f(CNT_PREFIX ## ThreadRoots, DESC_PREFIX "Thread Roots") \ 39 f(CNT_PREFIX ## CodeCacheRoots, DESC_PREFIX "Code Cache Roots") \ 40 f(CNT_PREFIX ## UniverseRoots, DESC_PREFIX "Universe Roots") \ 41 f(CNT_PREFIX ## JNIRoots, DESC_PREFIX "JNI Handles Roots") \ 42 f(CNT_PREFIX ## JVMTIWeakRoots, DESC_PREFIX "JVMTI Weak Roots") \ 43 f(CNT_PREFIX ## JFRWeakRoots, DESC_PREFIX "JFR Weak Roots") \ 44 f(CNT_PREFIX ## JNIWeakRoots, DESC_PREFIX "JNI Weak Roots") \ 45 f(CNT_PREFIX ## StringTableRoots, DESC_PREFIX "String Table Roots") \ 46 f(CNT_PREFIX ## ResolvedMethodTableRoots, DESC_PREFIX "Resolved Table Roots") \ 47 f(CNT_PREFIX ## VMGlobalRoots, DESC_PREFIX "VM Global Roots") \ 48 f(CNT_PREFIX ## VMWeakRoots, DESC_PREFIX "VM Weak Roots") \ 49 f(CNT_PREFIX ## ObjectSynchronizerRoots, DESC_PREFIX "Synchronizer Roots") \ 50 f(CNT_PREFIX ## FlatProfilerRoots, DESC_PREFIX "Flat Profiler Roots") \ 51 f(CNT_PREFIX ## ManagementRoots, DESC_PREFIX "Management Roots") \ 52 f(CNT_PREFIX ## SystemDictionaryRoots, DESC_PREFIX "System Dict Roots") \ 53 f(CNT_PREFIX ## CLDGRoots, DESC_PREFIX "CLDG Roots") \ 54 f(CNT_PREFIX ## JVMTIRoots, DESC_PREFIX "JVMTI Roots") \ 55 f(CNT_PREFIX ## StringDedupTableRoots, DESC_PREFIX "Dedup Table Roots") \ 56 f(CNT_PREFIX ## StringDedupQueueRoots, DESC_PREFIX "Dedup Queue Roots") \ 57 f(CNT_PREFIX ## StringDedupThreadRoots, DESC_PREFIX "Dedup Thread Roots") \ 58 f(CNT_PREFIX ## FinishQueues, DESC_PREFIX "Finish Queues") \ 59 // end 60 61 #define SHENANDOAH_PHASE_DO(f) \ 62 f(conc_reset, "Concurrent Reset") \ 63 \ 64 f(init_mark_gross, "Pause Init Mark (G)") \ 65 f(init_mark, "Pause Init Mark (N)") \ 66 f(accumulate_stats, " Accumulate Stats") \ 67 f(make_parsable, " Make Parsable") \ 68 f(init_update_region_states, " Update Region States") \ 69 f(scan_roots, " Scan Roots") \ 70 SHENANDOAH_PAR_PHASE_DO(scan_, " S: ", f) \ 71 f(resize_tlabs, " Resize TLABs") \ 72 \ 73 f(conc_mark, "Concurrent Marking") \ 74 f(conc_preclean, "Concurrent Precleaning") \ 75 \ 76 f(final_mark_gross, "Pause Final Mark (G)") \ 77 f(final_mark, "Pause Final Mark (N)") \ 78 f(update_roots, " Update Roots") \ 79 SHENANDOAH_PAR_PHASE_DO(update_, " U: ", f) \ 80 f(finish_queues, " Finish Queues") \ 81 f(weakrefs, " Weak References") \ 82 f(weakrefs_process, " Process") \ 83 f(weakrefs_enqueue, " Enqueue") \ 84 f(weak_roots, " Weak Roots") \ 85 SHENANDOAH_PAR_PHASE_DO(weak_roots_, " WR: ", f) \ 86 f(purge, " System Purge") \ 87 f(purge_class_unload, " Unload Classes") \ 88 f(purge_par, " Parallel Cleanup") \ 89 f(purge_metadata, " Deallocate Metadata") \ 90 f(purge_cldg, " CLDG") \ 91 f(purge_string_dedup, " String Dedup") \ 92 f(final_update_region_states, " Update Region States") \ 93 f(retire_tlabs, " Retire TLABs") \ 94 f(choose_cset, " Choose Collection Set") \ 95 f(final_rebuild_freeset, " Rebuild Free Set") \ 96 f(init_evac, " Initial Evacuation") \ 97 SHENANDOAH_PAR_PHASE_DO(evac_, " E: ", f) \ 98 \ 99 f(conc_cleanup_early, "Concurrent Cleanup") \ 100 f(conc_evac, "Concurrent Evacuation") \ 101 \ 102 f(init_update_refs_gross, "Pause Init Update Refs (G)") \ 103 f(init_update_refs, "Pause Init Update Refs (N)") \ 104 f(init_update_refs_retire_gclabs, " Retire GCLABs") \ 105 f(init_update_refs_prepare, " Prepare") \ 106 \ 107 f(conc_update_refs, "Concurrent Update Refs") \ 108 \ 109 f(final_update_refs_gross, "Pause Final Update Refs (G)") \ 110 f(final_update_refs, "Pause Final Update Refs (N)") \ 111 f(final_update_refs_finish_work, " Finish Work") \ 112 f(final_update_refs_roots, " Update Roots") \ 113 SHENANDOAH_PAR_PHASE_DO(final_update_, " UR: ", f) \ 114 f(final_update_refs_update_region_states, " Update Region States") \ 115 f(final_update_refs_trash_cset, " Trash Collection Set") \ 116 f(final_update_refs_rebuild_freeset, " Rebuild Free Set") \ 117 \ 118 f(conc_cleanup_complete, "Concurrent Cleanup") \ 119 \ 120 f(degen_gc_gross, "Pause Degenerated GC (G)") \ 121 f(degen_gc, "Pause Degenerated GC (N)") \ 122 f(degen_gc_update_roots, " Degen Update Roots") \ 123 SHENANDOAH_PAR_PHASE_DO(degen_gc_update_, " DU: ", f) \ 124 \ 125 f(full_gc_gross, "Pause Full GC (G)") \ 126 f(full_gc, "Pause Full GC (N)") \ 127 f(full_gc_heapdump_pre, " Pre Heap Dump") \ 128 f(full_gc_prepare, " Prepare") \ 129 f(full_gc_update_roots, " Update Roots") \ 130 SHENANDOAH_PAR_PHASE_DO(full_gc_update_roots_, " FU: ", f) \ 131 f(full_gc_scan_roots, " Scan Roots") \ 132 SHENANDOAH_PAR_PHASE_DO(full_gc_scan_roots_, " FS: ", f) \ 133 f(full_gc_mark, " Mark") \ 134 f(full_gc_mark_finish_queues, " Finish Queues") \ 135 f(full_gc_weakrefs, " Weak References") \ 136 f(full_gc_weakrefs_process, " Process") \ 137 f(full_gc_weakrefs_enqueue, " Enqueue") \ 138 f(full_gc_weak_roots, " Weak Roots") \ 139 SHENANDOAH_PAR_PHASE_DO(full_gc_weak_roots_, " WR: ", f) \ 140 f(full_gc_purge, " System Purge") \ 141 f(full_gc_purge_class_unload, " Unload Classes") \ 142 f(full_gc_purge_par, " Parallel Cleanup") \ 143 f(full_gc_purge_metadata, " Deallocate Metadata") \ 144 f(full_gc_purge_cldg, " CLDG") \ 145 f(full_gc_purge_string_dedup, " String Dedup") \ 146 f(full_gc_calculate_addresses, " Calculate Addresses") \ 147 f(full_gc_calculate_addresses_regular, " Regular Objects") \ 148 f(full_gc_calculate_addresses_humong, " Humongous Objects") \ 149 f(full_gc_adjust_pointers, " Adjust Pointers") \ 150 f(full_gc_adjust_roots, " Adjust Roots") \ 151 SHENANDOAH_PAR_PHASE_DO(full_gc_adjust_roots_, " FA: ", f) \ 152 f(full_gc_copy_objects, " Copy Objects") \ 153 f(full_gc_copy_objects_regular, " Regular Objects") \ 154 f(full_gc_copy_objects_humong, " Humongous Objects") \ 155 f(full_gc_copy_objects_reset_complete, " Reset Complete Bitmap") \ 156 f(full_gc_copy_objects_rebuild, " Rebuild Region Sets") \ 157 f(full_gc_resize_tlabs, " Resize TLABs") \ 158 f(full_gc_heapdump_post, " Post Heap Dump") \ 159 \ 160 /* Longer concurrent phases at the end */ \ 161 \ 162 f(conc_uncommit, "Concurrent Uncommit") \ 163 f(pacing, "Pacing") \ 164 \ 165 f(heap_iteration_roots, "Heap Iteration") \ 166 SHENANDOAH_PAR_PHASE_DO(heap_iteration_roots_, " HI: ", f) \ 167 f(verifier_roots, "Verifier") \ 168 SHENANDOAH_PAR_PHASE_DO(verifier_roots_, " V: ", f) \ 169 // end 170 171 typedef ShenandoahWorkerDataArray<double> ShenandoahWorkerData; 172 173 class ShenandoahPhaseTimings : public CHeapObj<mtGC> { 174 friend class ShenandoahGCPhase; 175 friend class ShenandoahWorkerTimingsTracker; 176 public: 177 #define SHENANDOAH_PHASE_DECLARE_ENUM(type, title) type, 178 enum Phase { 179 SHENANDOAH_PHASE_DO(SHENANDOAH_PHASE_DECLARE_ENUM) 180 _num_phases, 181 _invalid_phase = _num_phases 182 }; 183 184 enum ParPhase { 185 SHENANDOAH_PAR_PHASE_DO(,, SHENANDOAH_PHASE_DECLARE_ENUM) 186 _num_par_phases 187 }; 188 189 #undef SHENANDOAH_PHASE_DECLARE_ENUM 190 191 private: 192 uint _max_workers; 193 double _cycle_data[_num_phases]; 194 HdrSeq _global_data[_num_phases]; 195 static const char* _phase_names[_num_phases]; 196 197 ShenandoahWorkerData* _worker_data[_num_phases]; 198 ShenandoahCollectorPolicy* _policy; 199 200 static bool is_worker_phase(Phase phase); 201 static bool is_root_work_phase(Phase phase); 202 203 ShenandoahWorkerData* worker_data(Phase phase, ParPhase par_phase); 204 Phase worker_par_phase(Phase phase, ParPhase par_phase); 205 206 void set_cycle_data(Phase phase, double time); 207 static double uninitialized() { return -1; } 208 209 public: 210 ShenandoahPhaseTimings(uint max_workers); 211 212 void record_phase_time(Phase phase, double time); 213 214 void record_workers_start(Phase phase); 215 void record_workers_end(Phase phase); 216 217 void flush_par_workers_to_cycle(); 218 void flush_cycle_to_global(); 219 220 static const char* phase_name(Phase phase) { 221 assert(phase >= 0 && phase < _num_phases, "Out of bound"); 222 return _phase_names[phase]; 223 } 224 225 void print_cycle_on(outputStream* out) const; 226 void print_global_on(outputStream* out) const; 227 }; 228 229 class ShenandoahWorkerTimingsTracker : public StackObj { 230 private: 231 ShenandoahPhaseTimings* const _timings; 232 ShenandoahPhaseTimings::Phase const _phase; 233 ShenandoahPhaseTimings::ParPhase const _par_phase; 234 uint const _worker_id; 235 236 double _start_time; 237 public: 238 ShenandoahWorkerTimingsTracker(ShenandoahPhaseTimings::Phase phase, ShenandoahPhaseTimings::ParPhase par_phase, uint worker_id); 239 ~ShenandoahWorkerTimingsTracker(); 240 }; 241 242 #endif // SHARE_VM_GC_SHENANDOAH_SHENANDOAHGCPHASETIMEINGS_HPP