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