1 /*
2 * Copyright (c) 2017, 2021, Red Hat, Inc. All rights reserved.
3 * Copyright Amazon.com Inc. or its affiliates. All Rights Reserved.
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 *
6 * This code is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License version 2 only, as
8 * published by the Free Software Foundation.
9 *
10 * This code is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * version 2 for more details (a copy is included in the LICENSE file that
14 * accompanied this code).
15 *
16 * You should have received a copy of the GNU General Public License version
17 * 2 along with this work; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19 *
20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21 * or visit www.oracle.com if you need additional information or have any
22 * questions.
23 *
24 */
25
26 #ifndef SHARE_GC_SHENANDOAH_SHENANDOAHPHASETIMINGS_HPP
27 #define SHARE_GC_SHENANDOAH_SHENANDOAHPHASETIMINGS_HPP
28
29 #include "gc/shared/workerDataArray.hpp"
30 #include "gc/shenandoah/shenandoahNumberSeq.hpp"
31 #include "jfr/jfrEvents.hpp"
32 #include "memory/allocation.hpp"
33
34 class ShenandoahCollectorPolicy;
35 class outputStream;
36
37 #define SHENANDOAH_WORKER_PHASE_DO(NAME_PREFIX, DESC_PREFIX, f) \
38 f(NAME_PREFIX ## Work, DESC_PREFIX "Work", false) \
39 f(NAME_PREFIX ## Threads, DESC_PREFIX "Threads", false) \
40 f(NAME_PREFIX ## CodeCache, DESC_PREFIX "Code Cache", false) \
41 f(NAME_PREFIX ## VMStrongs, DESC_PREFIX "VM Strongs", false) \
42 f(NAME_PREFIX ## VMWeaks, DESC_PREFIX "VM Weaks", false) \
43 f(NAME_PREFIX ## Classes, DESC_PREFIX "Classes", false) \
44 // END
45
46 #define SHENANDOAH_SIMPLE_PHASE_DEF(f, NAME, DESC) \
47 f(NAME, DESC, false)
48
49 #define SHENANDOAH_WORKER_PHASE_DEF(f, NAME_PREFIX, MAIN_DESC, DESC_PREFIX) \
50 f(NAME_PREFIX, MAIN_DESC, true) \
51 SHENANDOAH_WORKER_PHASE_DO(NAME_PREFIX, DESC_PREFIX, f)
52
53 #define SHENANDOAH_PHASE_DO(f) \
54 SHENANDOAH_SIMPLE_PHASE_DEF(f, conc_reset, "Concurrent Reset") \
55 SHENANDOAH_SIMPLE_PHASE_DEF(f, init_mark_gross, "Pause Init Mark (G)") \
56 SHENANDOAH_SIMPLE_PHASE_DEF(f, init_mark, "Pause Init Mark (N)") \
57 SHENANDOAH_SIMPLE_PHASE_DEF(f, init_mark_verify, " Verify") \
58 SHENANDOAH_SIMPLE_PHASE_DEF(f, init_manage_tlabs, " Manage TLABs") \
59 SHENANDOAH_SIMPLE_PHASE_DEF(f, init_swap_rset, " Swap Remembered Set") \
60 SHENANDOAH_SIMPLE_PHASE_DEF(f, init_transfer_satb, " Transfer Old From SATB") \
61 SHENANDOAH_SIMPLE_PHASE_DEF(f, init_update_region_states, " Update Region States") \
62 SHENANDOAH_SIMPLE_PHASE_DEF(f, init_propagate_gc_state, " Propagate GC State") \
63 SHENANDOAH_WORKER_PHASE_DEF(f, init_scan_rset, "Concurrent Scan Remembered Set", \
64 " RS: ") \
65 SHENANDOAH_WORKER_PHASE_DEF(f, conc_mark_roots, "Concurrent Mark Roots", \
66 " CMR: ") \
67 SHENANDOAH_WORKER_PHASE_DEF(f, conc_mark, "Concurrent Marking", \
68 " CM: ") \
69 SHENANDOAH_SIMPLE_PHASE_DEF(f, conc_mark_satb_flush, " Flush SATB") \
70 SHENANDOAH_SIMPLE_PHASE_DEF(f, final_mark_gross, "Pause Final Mark (G)") \
71 SHENANDOAH_SIMPLE_PHASE_DEF(f, final_mark, "Pause Final Mark (N)") \
72 SHENANDOAH_SIMPLE_PHASE_DEF(f, final_mark_verify, " Verify") \
73 SHENANDOAH_WORKER_PHASE_DEF(f, finish_mark, " Finish Mark", \
74 " FM: ") \
75 SHENANDOAH_SIMPLE_PHASE_DEF(f, final_mark_propagate_gc_state, " Propagate GC State") \
76 SHENANDOAH_WORKER_PHASE_DEF(f, purge, " System Purge", \
77 " CU: ") \
78 SHENANDOAH_WORKER_PHASE_DEF(f, purge_weak_par, " Weak Roots", \
79 " WR: ") \
80 SHENANDOAH_SIMPLE_PHASE_DEF(f, final_update_region_states, " Update Region States") \
81 SHENANDOAH_SIMPLE_PHASE_DEF(f, final_manage_labs, " Manage GC/TLABs") \
82 SHENANDOAH_SIMPLE_PHASE_DEF(f, choose_cset, " Choose Collection Set") \
83 SHENANDOAH_SIMPLE_PHASE_DEF(f, final_rebuild_freeset, " Rebuild Free Set") \
84 SHENANDOAH_WORKER_PHASE_DEF(f, conc_thread_roots, "Concurrent Thread Roots", \
85 " CTR: ") \
86 SHENANDOAH_WORKER_PHASE_DEF(f, conc_weak_refs, "Concurrent Weak References", \
87 " CWRF: ") \
88 SHENANDOAH_WORKER_PHASE_DEF(f, conc_weak_roots, "Concurrent Weak Roots", \
89 " CWR: ") \
90 SHENANDOAH_SIMPLE_PHASE_DEF(f, conc_weak_roots_rendezvous, " Rendezvous") \
91 SHENANDOAH_SIMPLE_PHASE_DEF(f, conc_cleanup_early, "Concurrent Cleanup, Early") \
92 SHENANDOAH_SIMPLE_PHASE_DEF(f, conc_class_unload, "Concurrent Class Unloading") \
93 SHENANDOAH_SIMPLE_PHASE_DEF(f, conc_class_unload_unlink, " Unlink Stale") \
94 SHENANDOAH_SIMPLE_PHASE_DEF(f, conc_class_unload_unlink_sd, " System Dictionary") \
95 SHENANDOAH_SIMPLE_PHASE_DEF(f, conc_class_unload_unlink_weak_klass, " Weak Class Links") \
96 SHENANDOAH_SIMPLE_PHASE_DEF(f, conc_class_unload_unlink_code_roots, " Code Roots") \
97 SHENANDOAH_SIMPLE_PHASE_DEF(f, conc_class_unload_rendezvous, " Rendezvous") \
98 SHENANDOAH_SIMPLE_PHASE_DEF(f, conc_class_unload_purge, " Purge Unlinked") \
99 SHENANDOAH_SIMPLE_PHASE_DEF(f, conc_class_unload_purge_coderoots, " Code Roots") \
100 SHENANDOAH_SIMPLE_PHASE_DEF(f, conc_class_unload_purge_cldg, " CLDG") \
101 SHENANDOAH_SIMPLE_PHASE_DEF(f, conc_class_unload_purge_ec, " Exception Caches") \
102 SHENANDOAH_WORKER_PHASE_DEF(f, conc_strong_roots, "Concurrent Strong Roots", \
103 " CSR: ") \
104 SHENANDOAH_WORKER_PHASE_DEF(f, conc_evac, "Concurrent Evacuation", \
105 " CE: ") \
106 SHENANDOAH_SIMPLE_PHASE_DEF(f, conc_update_card_table, "Concurrent Update Cards") \
107 SHENANDOAH_SIMPLE_PHASE_DEF(f, conc_final_roots, "Concurrent Final Roots") \
108 SHENANDOAH_WORKER_PHASE_DEF(f, promote_in_place, " Promote Regions", \
109 " PIP: ") \
110 SHENANDOAH_SIMPLE_PHASE_DEF(f, final_verify_gross, "Pause Final Verify (G)") \
111 SHENANDOAH_SIMPLE_PHASE_DEF(f, final_verify, "Pause Final Verify (N)") \
112 SHENANDOAH_SIMPLE_PHASE_DEF(f, init_update_refs_gross, "Pause Init Update Refs (G)") \
113 SHENANDOAH_SIMPLE_PHASE_DEF(f, init_update_refs, "Pause Init Update Refs (N)") \
114 SHENANDOAH_SIMPLE_PHASE_DEF(f, init_update_refs_verify, " Verify") \
115 SHENANDOAH_SIMPLE_PHASE_DEF(f, conc_update_refs_prepare, "Concurrent Update Refs Prepare") \
116 SHENANDOAH_WORKER_PHASE_DEF(f, conc_update_refs, "Concurrent Update Refs", \
117 " CUR: ") \
118 SHENANDOAH_SIMPLE_PHASE_DEF(f, conc_update_thread_roots, "Concurrent Update Thread Roots") \
119 SHENANDOAH_SIMPLE_PHASE_DEF(f, final_update_refs_gross, "Pause Final Update Refs (G)") \
120 SHENANDOAH_SIMPLE_PHASE_DEF(f, final_update_refs, "Pause Final Update Refs (N)") \
121 SHENANDOAH_SIMPLE_PHASE_DEF(f, final_update_refs_verify, " Verify") \
122 SHENANDOAH_SIMPLE_PHASE_DEF(f, final_update_refs_update_region_states, " Update Region States") \
123 SHENANDOAH_SIMPLE_PHASE_DEF(f, final_update_refs_transfer_satb, " Transfer Old From SATB") \
124 SHENANDOAH_SIMPLE_PHASE_DEF(f, final_update_refs_trash_cset, " Trash Collection Set") \
125 SHENANDOAH_SIMPLE_PHASE_DEF(f, final_update_refs_rebuild_freeset, " Rebuild Free Set") \
126 SHENANDOAH_SIMPLE_PHASE_DEF(f, final_update_refs_propagate_gc_state, " Propagate GC State") \
127 SHENANDOAH_SIMPLE_PHASE_DEF(f, conc_cleanup_complete, "Concurrent Cleanup, Complete") \
128 SHENANDOAH_WORKER_PHASE_DEF(f, conc_coalesce_and_fill, "Concurrent Coalesce and Fill", \
129 " CC&F: ") \
130 \
131 SHENANDOAH_SIMPLE_PHASE_DEF(f, degen_gc_gross, "Pause Degenerated GC (G)") \
132 SHENANDOAH_SIMPLE_PHASE_DEF(f, degen_gc, "Pause Degenerated GC (N)") \
133 SHENANDOAH_SIMPLE_PHASE_DEF(f, degen_gc_un_self_forward, " Un-Self-Forward") \
134 SHENANDOAH_WORKER_PHASE_DEF(f, degen_gc_mark, " Mark", \
135 " DM: ") \
136 SHENANDOAH_SIMPLE_PHASE_DEF(f, degen_gc_purge, " System Purge") \
137 SHENANDOAH_WORKER_PHASE_DEF(f, degen_gc_weakrefs, " Weak References", \
138 " WRP: ") \
139 SHENANDOAH_WORKER_PHASE_DEF(f, degen_gc_purge_class_unload, " Unload Classes", \
140 " DCU: ") \
141 SHENANDOAH_WORKER_PHASE_DEF(f, degen_gc_purge_weak_par, " Weak Roots", \
142 " DWR: ") \
143 SHENANDOAH_SIMPLE_PHASE_DEF(f, degen_gc_purge_cldg, " CLDG") \
144 SHENANDOAH_SIMPLE_PHASE_DEF(f, degen_gc_final_update_region_states, " Update Region States") \
145 SHENANDOAH_SIMPLE_PHASE_DEF(f, degen_gc_final_manage_labs, " Manage GC/TLABs") \
146 SHENANDOAH_SIMPLE_PHASE_DEF(f, degen_gc_choose_cset, " Choose Collection Set") \
147 SHENANDOAH_SIMPLE_PHASE_DEF(f, degen_gc_final_rebuild_freeset, " Rebuild Free Set") \
148 SHENANDOAH_WORKER_PHASE_DEF(f, degen_gc_evac, " Evacuation", \
149 " DE: ") \
150 SHENANDOAH_SIMPLE_PHASE_DEF(f, degen_gc_init_update_refs_manage_gclabs, " Manage GCLABs") \
151 SHENANDOAH_WORKER_PHASE_DEF(f, degen_gc_update_refs, " Update References", \
152 " DUR: ") \
153 SHENANDOAH_SIMPLE_PHASE_DEF(f, degen_gc_final_update_refs_update_region_states, " Update Region States") \
154 SHENANDOAH_SIMPLE_PHASE_DEF(f, degen_gc_final_update_refs_trash_cset, " Trash Collection Set") \
155 SHENANDOAH_SIMPLE_PHASE_DEF(f, degen_gc_final_update_refs_rebuild_freeset, " Rebuild Free Set") \
156 SHENANDOAH_WORKER_PHASE_DEF(f, degen_gc_update_roots, " Degen Update Roots", \
157 " DU: ") \
158 SHENANDOAH_SIMPLE_PHASE_DEF(f, degen_gc_cleanup_complete, " Cleanup") \
159 SHENANDOAH_SIMPLE_PHASE_DEF(f, degen_gc_promote_regions, " Degen Promote Regions") \
160 SHENANDOAH_WORKER_PHASE_DEF(f, degen_gc_coalesce_and_fill, " Degen Coalesce and Fill", \
161 " DC&F") \
162 SHENANDOAH_SIMPLE_PHASE_DEF(f, degen_gc_propagate_gc_state, " Propagate GC State") \
163 \
164 SHENANDOAH_SIMPLE_PHASE_DEF(f, full_gc_gross, "Pause Full GC (G)") \
165 SHENANDOAH_SIMPLE_PHASE_DEF(f, full_gc, "Pause Full GC (N)") \
166 SHENANDOAH_SIMPLE_PHASE_DEF(f, full_gc_un_self_forward, " Un-Self-Forward") \
167 SHENANDOAH_SIMPLE_PHASE_DEF(f, full_gc_heapdump_pre, " Pre Heap Dump") \
168 SHENANDOAH_SIMPLE_PHASE_DEF(f, full_gc_prepare, " Prepare") \
169 SHENANDOAH_WORKER_PHASE_DEF(f, full_gc_update_roots, " Update Roots", \
170 " FU: ") \
171 SHENANDOAH_WORKER_PHASE_DEF(f, full_gc_mark, " Mark", \
172 " FM: ") \
173 SHENANDOAH_SIMPLE_PHASE_DEF(f, full_gc_purge, " System Purge") \
174 SHENANDOAH_WORKER_PHASE_DEF(f, full_gc_weakrefs, " Weak References", \
175 " WRP: ") \
176 SHENANDOAH_WORKER_PHASE_DEF(f, full_gc_purge_class_unload, " Unload Classes", \
177 " CU: ") \
178 SHENANDOAH_WORKER_PHASE_DEF(f, full_gc_purge_weak_par, " Weak Roots", \
179 " WR: ") \
180 SHENANDOAH_SIMPLE_PHASE_DEF(f, full_gc_purge_cldg, " CLDG") \
181 SHENANDOAH_SIMPLE_PHASE_DEF(f, full_gc_calculate_addresses, " Calculate Addresses") \
182 SHENANDOAH_SIMPLE_PHASE_DEF(f, full_gc_calculate_addresses_regular, " Regular Objects") \
183 SHENANDOAH_SIMPLE_PHASE_DEF(f, full_gc_calculate_addresses_humong, " Humongous Objects") \
184 SHENANDOAH_SIMPLE_PHASE_DEF(f, full_gc_adjust_pointers, " Adjust Pointers") \
185 SHENANDOAH_WORKER_PHASE_DEF(f, full_gc_adjust_roots, " Adjust Roots", \
186 " FA: ") \
187 SHENANDOAH_SIMPLE_PHASE_DEF(f, full_gc_copy_objects, " Copy Objects") \
188 SHENANDOAH_SIMPLE_PHASE_DEF(f, full_gc_copy_objects_regular, " Regular Objects") \
189 SHENANDOAH_SIMPLE_PHASE_DEF(f, full_gc_copy_objects_humong, " Humongous Objects") \
190 SHENANDOAH_SIMPLE_PHASE_DEF(f, full_gc_recompute_generation_usage, " Recompute generation usage") \
191 SHENANDOAH_SIMPLE_PHASE_DEF(f, full_gc_copy_objects_reset_complete, " Reset Complete Bitmap") \
192 SHENANDOAH_SIMPLE_PHASE_DEF(f, full_gc_copy_objects_rebuild, " Rebuild Region Sets") \
193 SHENANDOAH_SIMPLE_PHASE_DEF(f, full_gc_reconstruct_remembered_set, " Reconstruct Remembered Set") \
194 SHENANDOAH_SIMPLE_PHASE_DEF(f, full_gc_heapdump_post, " Post Heap Dump") \
195 SHENANDOAH_SIMPLE_PHASE_DEF(f, full_gc_propagate_gc_state, " Propagate GC State") \
196 \
197 SHENANDOAH_SIMPLE_PHASE_DEF(f, conc_reset_after_collect, "Concurrent Reset After Collect") \
198 \
199 SHENANDOAH_WORKER_PHASE_DEF(f, heap_iteration_roots, "Heap Iteration", \
200 " HI: ") \
201 // END
202
203 typedef WorkerDataArray<double> ShenandoahWorkerData;
204
205 class ShenandoahPhaseTimings : public CHeapObj<mtGC> {
206 friend class ShenandoahGCPhase;
207 friend class ShenandoahWorkerTimingsTracker;
208 public:
209 #define SHENANDOAH_PHASE_DECLARE_ENUM(name, desc, has_worker_phase) name,
210
211 enum Phase {
212 SHENANDOAH_PHASE_DO(SHENANDOAH_PHASE_DECLARE_ENUM)
213 _num_phases,
214 _invalid_phase = _num_phases
215 };
216
217 enum WorkerPhase {
218 SHENANDOAH_WORKER_PHASE_DO(,, SHENANDOAH_PHASE_DECLARE_ENUM)
219 _num_par_phases
220 };
221
222 #undef SHENANDOAH_PHASE_DECLARE_ENUM
223
224 private:
225 uint _max_workers;
226 double _cycle_data[_num_phases];
227 HdrSeq _global_data[_num_phases];
228 static const char* _desc[_num_phases];
229 static bool _has_worker_phase[_num_phases];
230
231 ShenandoahWorkerData* _worker_data[_num_phases];
232 ShenandoahCollectorPolicy* _policy;
233
234 static bool is_root_work_phase(Phase phase);
235
236 ShenandoahWorkerData* worker_data(Phase phase, WorkerPhase par_phase);
237 static Phase compute_phase_slot(Phase phase, WorkerPhase worker_phase);
238
239 void set_cycle_data(Phase phase, double time, bool should_aggregate = false);
240 static double uninitialized() { return -1; }
241
242 public:
243 ShenandoahPhaseTimings(uint max_workers);
244
245 void record_phase_time(Phase phase, double time, bool should_aggregate = false);
246
247 void record_workers_start(Phase phase);
248 void record_workers_end(Phase phase);
249
250 void flush_par_workers_to_cycle();
251 void flush_cycle_to_global();
252
253 static const char* phase_desc(Phase phase) {
254 assert(phase >= 0 && phase < _num_phases, "Out of bounds: %d", phase);
255 return _desc[phase];
256 }
257
258 static bool has_worker_phases(Phase phase) {
259 assert(phase >= 0 && phase < _num_phases, "Out of bounds: %d", phase);
260 return _has_worker_phase[phase];
261 }
262
263 void print_cycle_on(outputStream* out) const;
264 void print_global_on(outputStream* out) const;
265 };
266
267 class ShenandoahWorkerTimingsTracker : public StackObj {
268 private:
269 ShenandoahPhaseTimings* const _timings;
270 ShenandoahPhaseTimings::Phase const _phase;
271 ShenandoahPhaseTimings::WorkerPhase const _worker_phase;
272 uint const _worker_id;
273
274 double _start_time;
275 EventGCPhaseParallel _event;
276 public:
277 ShenandoahWorkerTimingsTracker(ShenandoahPhaseTimings::Phase phase,
278 ShenandoahPhaseTimings::WorkerPhase worker_phase,
279 uint worker_id,
280 bool cumulative = false);
281 ~ShenandoahWorkerTimingsTracker();
282 };
283
284 #endif // SHARE_GC_SHENANDOAH_SHENANDOAHPHASETIMINGS_HPP