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_SIMPLE_PHASE_DEF(f, final_mark_flush_satb_roots, " Flush SATB and Roots") \
74 SHENANDOAH_WORKER_PHASE_DEF(f, finish_mark, " Finish Mark", \
75 " FM: ") \
76 SHENANDOAH_SIMPLE_PHASE_DEF(f, final_mark_propagate_gc_state, " Propagate GC State") \
77 SHENANDOAH_WORKER_PHASE_DEF(f, purge, " System Purge", \
78 " CU: ") \
79 SHENANDOAH_WORKER_PHASE_DEF(f, purge_weak_par, " Weak Roots", \
80 " WR: ") \
81 SHENANDOAH_SIMPLE_PHASE_DEF(f, final_update_region_states, " Update Region States") \
82 SHENANDOAH_SIMPLE_PHASE_DEF(f, final_manage_labs, " Manage GC/TLABs") \
83 SHENANDOAH_SIMPLE_PHASE_DEF(f, choose_cset, " Choose Collection Set") \
84 SHENANDOAH_SIMPLE_PHASE_DEF(f, final_rebuild_freeset, " Rebuild Free Set") \
85 SHENANDOAH_WORKER_PHASE_DEF(f, conc_thread_roots, "Concurrent Thread Roots", \
86 " CTR: ") \
87 SHENANDOAH_WORKER_PHASE_DEF(f, conc_weak_refs, "Concurrent Weak References", \
88 " CWRF: ") \
89 SHENANDOAH_WORKER_PHASE_DEF(f, conc_weak_roots, "Concurrent Weak Roots", \
90 " CWR: ") \
91 SHENANDOAH_SIMPLE_PHASE_DEF(f, conc_weak_roots_rendezvous, " Rendezvous") \
92 SHENANDOAH_SIMPLE_PHASE_DEF(f, conc_cleanup_early, "Concurrent Cleanup, Early") \
93 SHENANDOAH_SIMPLE_PHASE_DEF(f, conc_class_unload, "Concurrent Class Unloading") \
94 SHENANDOAH_SIMPLE_PHASE_DEF(f, conc_class_unload_unlink, " Unlink Stale") \
95 SHENANDOAH_SIMPLE_PHASE_DEF(f, conc_class_unload_unlink_sd, " System Dictionary") \
96 SHENANDOAH_SIMPLE_PHASE_DEF(f, conc_class_unload_unlink_weak_klass, " Weak Class Links") \
97 SHENANDOAH_SIMPLE_PHASE_DEF(f, conc_class_unload_unlink_code_roots, " Code Roots") \
98 SHENANDOAH_SIMPLE_PHASE_DEF(f, conc_class_unload_rendezvous, " Rendezvous") \
99 SHENANDOAH_SIMPLE_PHASE_DEF(f, conc_class_unload_purge, " Purge Unlinked") \
100 SHENANDOAH_SIMPLE_PHASE_DEF(f, conc_class_unload_purge_coderoots, " Code Roots") \
101 SHENANDOAH_SIMPLE_PHASE_DEF(f, conc_class_unload_purge_cldg, " CLDG") \
102 SHENANDOAH_SIMPLE_PHASE_DEF(f, conc_class_unload_purge_ec, " Exception Caches") \
103 SHENANDOAH_WORKER_PHASE_DEF(f, conc_strong_roots, "Concurrent Strong Roots", \
104 " CSR: ") \
105 SHENANDOAH_WORKER_PHASE_DEF(f, conc_evac, "Concurrent Evacuation", \
106 " CE: ") \
107 SHENANDOAH_SIMPLE_PHASE_DEF(f, conc_update_card_table, "Concurrent Update Cards") \
108 SHENANDOAH_SIMPLE_PHASE_DEF(f, conc_final_roots, "Concurrent Final Roots") \
109 SHENANDOAH_WORKER_PHASE_DEF(f, promote_in_place, " Promote Regions", \
110 " PIP: ") \
111 SHENANDOAH_SIMPLE_PHASE_DEF(f, final_verify_gross, "Pause Final Verify (G)") \
112 SHENANDOAH_SIMPLE_PHASE_DEF(f, final_verify, "Pause Final Verify (N)") \
113 SHENANDOAH_SIMPLE_PHASE_DEF(f, init_update_refs_gross, "Pause Init Update Refs (G)") \
114 SHENANDOAH_SIMPLE_PHASE_DEF(f, init_update_refs, "Pause Init Update Refs (N)") \
115 SHENANDOAH_SIMPLE_PHASE_DEF(f, init_update_refs_verify, " Verify") \
116 SHENANDOAH_SIMPLE_PHASE_DEF(f, conc_update_refs_prepare, "Concurrent Update Refs Prepare") \
117 SHENANDOAH_WORKER_PHASE_DEF(f, conc_update_refs, "Concurrent Update Refs", \
118 " CUR: ") \
119 SHENANDOAH_SIMPLE_PHASE_DEF(f, conc_update_thread_roots, "Concurrent Update Thread Roots") \
120 SHENANDOAH_SIMPLE_PHASE_DEF(f, final_update_refs_gross, "Pause Final Update Refs (G)") \
121 SHENANDOAH_SIMPLE_PHASE_DEF(f, final_update_refs, "Pause Final Update Refs (N)") \
122 SHENANDOAH_SIMPLE_PHASE_DEF(f, final_update_refs_verify, " Verify") \
123 SHENANDOAH_SIMPLE_PHASE_DEF(f, final_update_refs_update_region_states, " Update Region States") \
124 SHENANDOAH_SIMPLE_PHASE_DEF(f, final_update_refs_transfer_satb, " Transfer Old From SATB") \
125 SHENANDOAH_SIMPLE_PHASE_DEF(f, final_update_refs_trash_cset, " Trash Collection Set") \
126 SHENANDOAH_SIMPLE_PHASE_DEF(f, final_update_refs_rebuild_freeset, " Rebuild Free Set") \
127 SHENANDOAH_SIMPLE_PHASE_DEF(f, final_update_refs_propagate_gc_state, " Propagate GC State") \
128 SHENANDOAH_SIMPLE_PHASE_DEF(f, conc_cleanup_complete, "Concurrent Cleanup, Complete") \
129 SHENANDOAH_WORKER_PHASE_DEF(f, conc_coalesce_and_fill, "Concurrent Coalesce and Fill", \
130 " CC&F: ") \
131 \
132 SHENANDOAH_SIMPLE_PHASE_DEF(f, degen_gc_gross, "Pause Degenerated GC (G)") \
133 SHENANDOAH_SIMPLE_PHASE_DEF(f, degen_gc, "Pause Degenerated GC (N)") \
134 SHENANDOAH_SIMPLE_PHASE_DEF(f, degen_gc_un_self_forward, " Un-Self-Forward") \
135 SHENANDOAH_WORKER_PHASE_DEF(f, degen_gc_mark, " Mark", \
136 " DM: ") \
137 SHENANDOAH_SIMPLE_PHASE_DEF(f, degen_gc_purge, " System Purge") \
138 SHENANDOAH_WORKER_PHASE_DEF(f, degen_gc_weakrefs, " Weak References", \
139 " WRP: ") \
140 SHENANDOAH_WORKER_PHASE_DEF(f, degen_gc_purge_class_unload, " Unload Classes", \
141 " DCU: ") \
142 SHENANDOAH_WORKER_PHASE_DEF(f, degen_gc_purge_weak_par, " Weak Roots", \
143 " DWR: ") \
144 SHENANDOAH_SIMPLE_PHASE_DEF(f, degen_gc_purge_cldg, " CLDG") \
145 SHENANDOAH_SIMPLE_PHASE_DEF(f, degen_gc_final_update_region_states, " Update Region States") \
146 SHENANDOAH_SIMPLE_PHASE_DEF(f, degen_gc_final_manage_labs, " Manage GC/TLABs") \
147 SHENANDOAH_SIMPLE_PHASE_DEF(f, degen_gc_choose_cset, " Choose Collection Set") \
148 SHENANDOAH_SIMPLE_PHASE_DEF(f, degen_gc_final_rebuild_freeset, " Rebuild Free Set") \
149 SHENANDOAH_WORKER_PHASE_DEF(f, degen_gc_evac, " Evacuation", \
150 " DE: ") \
151 SHENANDOAH_SIMPLE_PHASE_DEF(f, degen_gc_init_update_refs_manage_gclabs, " Manage GCLABs") \
152 SHENANDOAH_WORKER_PHASE_DEF(f, degen_gc_update_refs, " Update References", \
153 " DUR: ") \
154 SHENANDOAH_SIMPLE_PHASE_DEF(f, degen_gc_final_update_refs_update_region_states, " Update Region States") \
155 SHENANDOAH_SIMPLE_PHASE_DEF(f, degen_gc_final_update_refs_trash_cset, " Trash Collection Set") \
156 SHENANDOAH_SIMPLE_PHASE_DEF(f, degen_gc_final_update_refs_rebuild_freeset, " Rebuild Free Set") \
157 SHENANDOAH_WORKER_PHASE_DEF(f, degen_gc_update_roots, " Degen Update Roots", \
158 " DU: ") \
159 SHENANDOAH_SIMPLE_PHASE_DEF(f, degen_gc_cleanup_complete, " Cleanup") \
160 SHENANDOAH_SIMPLE_PHASE_DEF(f, degen_gc_promote_regions, " Degen Promote Regions") \
161 SHENANDOAH_WORKER_PHASE_DEF(f, degen_gc_coalesce_and_fill, " Degen Coalesce and Fill", \
162 " DC&F") \
163 SHENANDOAH_SIMPLE_PHASE_DEF(f, degen_gc_propagate_gc_state, " Propagate GC State") \
164 \
165 SHENANDOAH_SIMPLE_PHASE_DEF(f, full_gc_gross, "Pause Full GC (G)") \
166 SHENANDOAH_SIMPLE_PHASE_DEF(f, full_gc, "Pause Full GC (N)") \
167 SHENANDOAH_SIMPLE_PHASE_DEF(f, full_gc_un_self_forward, " Un-Self-Forward") \
168 SHENANDOAH_SIMPLE_PHASE_DEF(f, full_gc_heapdump_pre, " Pre Heap Dump") \
169 SHENANDOAH_SIMPLE_PHASE_DEF(f, full_gc_prepare, " Prepare") \
170 SHENANDOAH_WORKER_PHASE_DEF(f, full_gc_update_roots, " Update Roots", \
171 " FU: ") \
172 SHENANDOAH_WORKER_PHASE_DEF(f, full_gc_mark, " Mark", \
173 " FM: ") \
174 SHENANDOAH_SIMPLE_PHASE_DEF(f, full_gc_purge, " System Purge") \
175 SHENANDOAH_WORKER_PHASE_DEF(f, full_gc_weakrefs, " Weak References", \
176 " WRP: ") \
177 SHENANDOAH_WORKER_PHASE_DEF(f, full_gc_purge_class_unload, " Unload Classes", \
178 " CU: ") \
179 SHENANDOAH_WORKER_PHASE_DEF(f, full_gc_purge_weak_par, " Weak Roots", \
180 " WR: ") \
181 SHENANDOAH_SIMPLE_PHASE_DEF(f, full_gc_purge_cldg, " CLDG") \
182 SHENANDOAH_SIMPLE_PHASE_DEF(f, full_gc_calculate_addresses, " Calculate Addresses") \
183 SHENANDOAH_SIMPLE_PHASE_DEF(f, full_gc_calculate_addresses_regular, " Regular Objects") \
184 SHENANDOAH_SIMPLE_PHASE_DEF(f, full_gc_calculate_addresses_humong, " Humongous Objects") \
185 SHENANDOAH_SIMPLE_PHASE_DEF(f, full_gc_adjust_pointers, " Adjust Pointers") \
186 SHENANDOAH_WORKER_PHASE_DEF(f, full_gc_adjust_roots, " Adjust Roots", \
187 " FA: ") \
188 SHENANDOAH_SIMPLE_PHASE_DEF(f, full_gc_copy_objects, " Copy Objects") \
189 SHENANDOAH_SIMPLE_PHASE_DEF(f, full_gc_copy_objects_regular, " Regular Objects") \
190 SHENANDOAH_SIMPLE_PHASE_DEF(f, full_gc_copy_objects_humong, " Humongous Objects") \
191 SHENANDOAH_SIMPLE_PHASE_DEF(f, full_gc_recompute_generation_usage, " Recompute generation usage") \
192 SHENANDOAH_SIMPLE_PHASE_DEF(f, full_gc_copy_objects_reset_complete, " Reset Complete Bitmap") \
193 SHENANDOAH_SIMPLE_PHASE_DEF(f, full_gc_copy_objects_rebuild, " Rebuild Region Sets") \
194 SHENANDOAH_SIMPLE_PHASE_DEF(f, full_gc_reconstruct_remembered_set, " Reconstruct Remembered Set") \
195 SHENANDOAH_SIMPLE_PHASE_DEF(f, full_gc_heapdump_post, " Post Heap Dump") \
196 SHENANDOAH_SIMPLE_PHASE_DEF(f, full_gc_propagate_gc_state, " Propagate GC State") \
197 \
198 SHENANDOAH_SIMPLE_PHASE_DEF(f, conc_reset_after_collect, "Concurrent Reset After Collect") \
199 \
200 SHENANDOAH_WORKER_PHASE_DEF(f, heap_iteration_roots, "Heap Iteration", \
201 " HI: ") \
202 // END
203
204 typedef WorkerDataArray<double> ShenandoahWorkerData;
205
206 class ShenandoahPhaseTimings : public CHeapObj<mtGC> {
207 friend class ShenandoahGCPhase;
208 friend class ShenandoahWorkerTimingsTracker;
209 public:
210 #define SHENANDOAH_PHASE_DECLARE_ENUM(name, desc, has_worker_phase) name,
211
212 enum Phase {
213 SHENANDOAH_PHASE_DO(SHENANDOAH_PHASE_DECLARE_ENUM)
214 _num_phases,
215 _invalid_phase = _num_phases
216 };
217
218 enum WorkerPhase {
219 SHENANDOAH_WORKER_PHASE_DO(,, SHENANDOAH_PHASE_DECLARE_ENUM)
220 _num_par_phases
221 };
222
223 #undef SHENANDOAH_PHASE_DECLARE_ENUM
224
225 private:
226 uint _max_workers;
227 double _cycle_data[_num_phases];
228 HdrSeq _global_data[_num_phases];
229 static const char* _desc[_num_phases];
230 static bool _has_worker_phase[_num_phases];
231
232 ShenandoahWorkerData* _worker_data[_num_phases];
233 ShenandoahCollectorPolicy* _policy;
234
235 static bool is_root_work_phase(Phase phase);
236
237 ShenandoahWorkerData* worker_data(Phase phase, WorkerPhase par_phase);
238 static Phase compute_phase_slot(Phase phase, WorkerPhase worker_phase);
239
240 void set_cycle_data(Phase phase, double time, bool should_aggregate = false);
241 static double uninitialized() { return -1; }
242
243 public:
244 ShenandoahPhaseTimings(uint max_workers);
245
246 void record_phase_time(Phase phase, double time, bool should_aggregate = false);
247
248 void record_workers_start(Phase phase);
249 void record_workers_end(Phase phase);
250
251 void flush_par_workers_to_cycle();
252 void flush_cycle_to_global();
253
254 static const char* phase_desc(Phase phase) {
255 assert(phase >= 0 && phase < _num_phases, "Out of bounds: %d", phase);
256 return _desc[phase];
257 }
258
259 static bool has_worker_phases(Phase phase) {
260 assert(phase >= 0 && phase < _num_phases, "Out of bounds: %d", phase);
261 return _has_worker_phase[phase];
262 }
263
264 void print_cycle_on(outputStream* out) const;
265 void print_global_on(outputStream* out) const;
266 };
267
268 class ShenandoahWorkerTimingsTracker : public StackObj {
269 private:
270 ShenandoahPhaseTimings* const _timings;
271 ShenandoahPhaseTimings::Phase const _phase;
272 ShenandoahPhaseTimings::WorkerPhase const _worker_phase;
273 uint const _worker_id;
274
275 double _start_time;
276 EventGCPhaseParallel _event;
277 public:
278 ShenandoahWorkerTimingsTracker(ShenandoahPhaseTimings::Phase phase,
279 ShenandoahPhaseTimings::WorkerPhase worker_phase,
280 uint worker_id,
281 bool cumulative = false);
282 ~ShenandoahWorkerTimingsTracker();
283 };
284
285 #endif // SHARE_GC_SHENANDOAH_SHENANDOAHPHASETIMINGS_HPP