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