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