1 | /* |
2 | * Copyright (c) 2017, 2019, Red Hat, Inc. All rights reserved. |
3 | * |
4 | * This code is free software; you can redistribute it and/or modify it |
5 | * under the terms of the GNU General Public License version 2 only, as |
6 | * published by the Free Software Foundation. |
7 | * |
8 | * This code is distributed in the hope that it will be useful, but WITHOUT |
9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
10 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
11 | * version 2 for more details (a copy is included in the LICENSE file that |
12 | * accompanied this code). |
13 | * |
14 | * You should have received a copy of the GNU General Public License version |
15 | * 2 along with this work; if not, write to the Free Software Foundation, |
16 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
17 | * |
18 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
19 | * or visit www.oracle.com if you need additional information or have any |
20 | * questions. |
21 | * |
22 | */ |
23 | |
24 | #ifndef SHARE_GC_SHENANDOAH_SHENANDOAHPHASETIMINGS_HPP |
25 | #define SHARE_GC_SHENANDOAH_SHENANDOAHPHASETIMINGS_HPP |
26 | |
27 | #include "gc/shenandoah/shenandoahNumberSeq.hpp" |
28 | #include "gc/shared/workerDataArray.hpp" |
29 | #include "memory/allocation.hpp" |
30 | |
31 | class ShenandoahCollectorPolicy; |
32 | class ShenandoahWorkerTimings; |
33 | class ShenandoahTerminationTimings; |
34 | class outputStream; |
35 | |
36 | #define SHENANDOAH_GC_PHASE_DO(f) \ |
37 | f(total_pause_gross, "Total Pauses (G)") \ |
38 | f(total_pause, "Total Pauses (N)") \ |
39 | f(init_mark_gross, "Pause Init Mark (G)") \ |
40 | f(init_mark, "Pause Init Mark (N)") \ |
41 | f(make_parsable, " Make Parsable") \ |
42 | f(clear_liveness, " Clear Liveness") \ |
43 | \ |
44 | /* Per-thread timer block, should have "roots" counters in consistent order */ \ |
45 | f(scan_roots, " Scan Roots") \ |
46 | f(scan_thread_roots, " S: Thread Roots") \ |
47 | f(scan_code_roots, " S: Code Cache Roots") \ |
48 | f(scan_universe_roots, " S: Universe Roots") \ |
49 | f(scan_jni_roots, " S: JNI Roots") \ |
50 | f(scan_jvmti_weak_roots, " S: JVMTI Weak Roots") \ |
51 | f(scan_jfr_weak_roots, " S: JFR Weak Roots") \ |
52 | f(scan_jni_weak_roots, " S: JNI Weak Roots") \ |
53 | f(scan_stringtable_roots, " S: String Table Roots") \ |
54 | f(scan_resolved_method_table_roots, " S: Resolved Table Roots") \ |
55 | f(scan_vm_weak_roots, " S: VM Weak Roots") \ |
56 | f(scan_synchronizer_roots, " S: Synchronizer Roots") \ |
57 | f(scan_management_roots, " S: Management Roots") \ |
58 | f(scan_system_dictionary_roots, " S: System Dict Roots") \ |
59 | f(scan_cldg_roots, " S: CLDG Roots") \ |
60 | f(scan_jvmti_roots, " S: JVMTI Roots") \ |
61 | f(scan_string_dedup_table_roots, " S: Dedup Table Roots") \ |
62 | f(scan_string_dedup_queue_roots, " S: Dedup Queue Roots") \ |
63 | f(scan_finish_queues, " S: Finish Queues" ) \ |
64 | \ |
65 | f(resize_tlabs, " Resize TLABs") \ |
66 | \ |
67 | f(final_mark_gross, "Pause Final Mark (G)") \ |
68 | f(final_mark, "Pause Final Mark (N)") \ |
69 | \ |
70 | /* Per-thread timer block, should have "roots" counters in consistent order */ \ |
71 | f(update_roots, " Update Roots") \ |
72 | f(update_thread_roots, " U: Thread Roots") \ |
73 | f(update_code_roots, " U: Code Cache Roots") \ |
74 | f(update_universe_roots, " U: Universe Roots") \ |
75 | f(update_jni_roots, " U: JNI Roots") \ |
76 | f(update_jvmti_weak_roots, " U: JVMTI Weak Roots") \ |
77 | f(update_jfr_weak_roots, " U: JFR Weak Roots") \ |
78 | f(update_jni_weak_roots, " U: JNI Weak Roots") \ |
79 | f(update_stringtable_roots, " U: String Table Roots") \ |
80 | f(update_resolved_method_table_roots, " U: Resolved Table Roots") \ |
81 | f(update_vm_weak_roots, " U: VM Weak Roots") \ |
82 | f(update_synchronizer_roots, " U: Synchronizer Roots") \ |
83 | f(update_management_roots, " U: Management Roots") \ |
84 | f(update_system_dictionary_roots, " U: System Dict Roots") \ |
85 | f(update_cldg_roots, " U: CLDG Roots") \ |
86 | f(update_jvmti_roots, " U: JVMTI Roots") \ |
87 | f(update_string_dedup_table_roots, " U: Dedup Table Roots") \ |
88 | f(update_string_dedup_queue_roots, " U: Dedup Queue Roots") \ |
89 | f(update_finish_queues, " U: Finish Queues") \ |
90 | \ |
91 | f(finish_queues, " Finish Queues") \ |
92 | f(termination, " Termination") \ |
93 | f(weakrefs, " Weak References") \ |
94 | f(weakrefs_process, " Process") \ |
95 | f(weakrefs_termination, " Termination") \ |
96 | f(purge, " System Purge") \ |
97 | f(purge_class_unload, " Unload Classes") \ |
98 | f(purge_par, " Parallel Cleanup") \ |
99 | f(purge_cldg, " CLDG") \ |
100 | f(complete_liveness, " Complete Liveness") \ |
101 | f(prepare_evac, " Prepare Evacuation") \ |
102 | f(recycle_regions, " Recycle regions") \ |
103 | \ |
104 | /* Per-thread timer block, should have "roots" counters in consistent order */ \ |
105 | f(init_evac, " Initial Evacuation") \ |
106 | f(evac_thread_roots, " E: Thread Roots") \ |
107 | f(evac_code_roots, " E: Code Cache Roots") \ |
108 | f(evac_universe_roots, " E: Universe Roots") \ |
109 | f(evac_jni_roots, " E: JNI Roots") \ |
110 | f(evac_jvmti_weak_roots, " E: JVMTI Weak Roots") \ |
111 | f(evac_jfr_weak_roots, " E: JFR Weak Roots") \ |
112 | f(evac_jni_weak_roots, " E: JNI Weak Roots") \ |
113 | f(evac_stringtable_roots, " E: String Table Roots") \ |
114 | f(evac_resolved_method_table_roots, " E: Resolved Table Roots") \ |
115 | f(evac_vm_weak_roots, " E: VM Weak Roots") \ |
116 | f(evac_synchronizer_roots, " E: Synchronizer Roots") \ |
117 | f(evac_management_roots, " E: Management Roots") \ |
118 | f(evac_system_dictionary_roots, " E: System Dict Roots") \ |
119 | f(evac_cldg_roots, " E: CLDG Roots") \ |
120 | f(evac_jvmti_roots, " E: JVMTI Roots") \ |
121 | f(evac_string_dedup_table_roots, " E: String Dedup Table Roots") \ |
122 | f(evac_string_dedup_queue_roots, " E: String Dedup Queue Roots") \ |
123 | f(evac_finish_queues, " E: Finish Queues") \ |
124 | \ |
125 | f(final_evac_gross, "Pause Final Evac (G)") \ |
126 | f(final_evac, "Pause Final Evac (N)") \ |
127 | \ |
128 | f(init_update_refs_gross, "Pause Init Update Refs (G)") \ |
129 | f(init_update_refs, "Pause Init Update Refs (N)") \ |
130 | \ |
131 | f(final_update_refs_gross, "Pause Final Update Refs (G)") \ |
132 | f(final_update_refs, "Pause Final Update Refs (N)") \ |
133 | f(final_update_refs_finish_work, " Finish Work") \ |
134 | \ |
135 | /* Per-thread timer block, should have "roots" counters in consistent order */ \ |
136 | f(final_update_refs_roots, " Update Roots") \ |
137 | f(final_update_refs_thread_roots, " UR: Thread Roots") \ |
138 | f(final_update_refs_code_roots, " UR: Code Cache Roots") \ |
139 | f(final_update_refs_universe_roots, " UR: Universe Roots") \ |
140 | f(final_update_refs_jni_roots, " UR: JNI Roots") \ |
141 | f(final_update_jvmti_weak_roots, " UR: JVMTI Weak Roots") \ |
142 | f(final_update_jfr_weak_roots, " UR: JFR Weak Roots") \ |
143 | f(final_update_jni_weak_roots, " UR: JNI Weak Roots") \ |
144 | f(final_update_stringtable_roots, " UR: String Table Roots") \ |
145 | f(final_update_resolved_method_table_roots, " UR: Resolved Table Roots") \ |
146 | f(final_update_vm_weak_roots, " UR: VM Weak Roots") \ |
147 | f(final_update_refs_synchronizer_roots, " UR: Synchronizer Roots") \ |
148 | f(final_update_refs_management_roots, " UR: Management Roots") \ |
149 | f(final_update_refs_system_dict_roots, " UR: System Dict Roots") \ |
150 | f(final_update_refs_cldg_roots, " UR: CLDG Roots") \ |
151 | f(final_update_refs_jvmti_roots, " UR: JVMTI Roots") \ |
152 | f(final_update_refs_string_dedup_table_roots, " UR: Dedup Table Roots") \ |
153 | f(final_update_refs_string_dedup_queue_roots, " UR: Dedup Queue Roots") \ |
154 | f(final_update_refs_finish_queues, " UR: Finish Queues") \ |
155 | \ |
156 | f(final_update_refs_recycle, " Recycle") \ |
157 | \ |
158 | f(degen_gc_gross, "Pause Degenerated GC (G)") \ |
159 | f(degen_gc, "Pause Degenerated GC (N)") \ |
160 | \ |
161 | /* Per-thread timer block, should have "roots" counters in consistent order */ \ |
162 | f(degen_gc_update_roots, " Degen Update Roots") \ |
163 | f(degen_gc_update_thread_roots, " DU: Thread Roots") \ |
164 | f(degen_gc_update_code_roots, " DU: Code Cache Roots") \ |
165 | f(degen_gc_update_universe_roots, " DU: Universe Roots") \ |
166 | f(degen_gc_update_jni_roots, " DU: JNI Roots") \ |
167 | f(degen_gc_update_jvmti_weak_roots, " DU: JVMTI Weak Roots") \ |
168 | f(degen_gc_update_jfr_weak_roots, " DU: JFR Weak Roots") \ |
169 | f(degen_gc_update_jni_weak_roots, " DU: JNI Weak Roots") \ |
170 | f(degen_gc_update_stringtable_roots, " DU: String Table Roots") \ |
171 | f(degen_gc_update_resolved_method_table_roots, " DU: Resolved Table Roots") \ |
172 | f(degen_gc_update_vm_weak_roots, " DU: VM Weak Roots") \ |
173 | f(degen_gc_update_synchronizer_roots, " DU: Synchronizer Roots") \ |
174 | f(degen_gc_update_management_roots, " DU: Management Roots") \ |
175 | f(degen_gc_update_system_dict_roots, " DU: System Dict Roots") \ |
176 | f(degen_gc_update_cldg_roots, " DU: CLDG Roots") \ |
177 | f(degen_gc_update_jvmti_roots, " DU: JVMTI Roots") \ |
178 | f(degen_gc_update_string_dedup_table_roots, " DU: Dedup Table Roots") \ |
179 | f(degen_gc_update_string_dedup_queue_roots, " DU: Dedup Queue Roots") \ |
180 | f(degen_gc_update_finish_queues, " DU: Finish Queues") \ |
181 | \ |
182 | f(init_traversal_gc_gross, "Pause Init Traversal (G)") \ |
183 | f(init_traversal_gc, "Pause Init Traversal (N)") \ |
184 | f(traversal_gc_prepare, " Prepare") \ |
185 | f(traversal_gc_make_parsable, " Make Parsable") \ |
186 | f(traversal_gc_resize_tlabs, " Resize TLABs") \ |
187 | \ |
188 | /* Per-thread timer block, should have "roots" counters in consistent order */ \ |
189 | f(init_traversal_gc_work, " Work") \ |
190 | f(init_traversal_gc_thread_roots, " TI: Thread Roots") \ |
191 | f(init_traversal_gc_code_roots, " TI: Code Cache Roots") \ |
192 | f(init_traversal_gc_universe_roots, " TI: Universe Roots") \ |
193 | f(init_traversal_gc_jni_roots, " TI: JNI Roots") \ |
194 | f(init_traversal_gc_jvmti_weak_roots, " TI: JVMTI Weak Roots") \ |
195 | f(init_traversal_gc_jfr_weak_roots, " TI: JFR Weak Roots") \ |
196 | f(init_traversal_gc_jni_weak_roots, " TI: JNI Weak Roots") \ |
197 | f(init_traversal_gc_stringtable_roots, " TI: String Table Roots") \ |
198 | f(init_traversal_gc_resolved_method_table_roots, " TI: Resolved Table Roots") \ |
199 | f(init_traversal_gc_vm_weak_roots, " TI: VM Weak Roots") \ |
200 | f(init_traversal_gc_synchronizer_roots, " TI: Synchronizer Roots") \ |
201 | f(init_traversal_gc_management_roots, " TI: Management Roots") \ |
202 | f(init_traversal_gc_system_dict_roots, " TI: System Dict Roots") \ |
203 | f(init_traversal_gc_cldg_roots, " TI: CLDG Roots") \ |
204 | f(init_traversal_gc_jvmti_roots, " TI: JVMTI Roots") \ |
205 | f(init_traversal_gc_string_dedup_table_roots, " TI: Dedup Table Roots") \ |
206 | f(init_traversal_gc_string_dedup_queue_roots, " TI: Dedup Queue Roots") \ |
207 | f(init_traversal_gc_finish_queues, " TI: Finish Queues") \ |
208 | \ |
209 | f(final_traversal_gc_gross, "Pause Final Traversal (G)") \ |
210 | f(final_traversal_gc, "Pause Final Traversal (N)") \ |
211 | \ |
212 | /* Per-thread timer block, should have "roots" counters in consistent order */ \ |
213 | f(final_traversal_gc_work, " Work") \ |
214 | f(final_traversal_gc_thread_roots, " TF: Thread Roots") \ |
215 | f(final_traversal_gc_code_roots, " TF: Code Cache Roots") \ |
216 | f(final_traversal_gc_universe_roots, " TF: Universe Roots") \ |
217 | f(final_traversal_gc_jni_roots, " TF: JNI Roots") \ |
218 | f(final_traversal_gc_jvmti_weak_roots, " TF: JVMTI Weak Roots") \ |
219 | f(final_traversal_gc_jfr_weak_roots, " TF: JFR Weak Roots") \ |
220 | f(final_traversal_gc_jni_weak_roots, " TF: JNI Weak Roots") \ |
221 | f(final_traversal_gc_stringtable_roots, " TF: String Table Roots") \ |
222 | f(final_traversal_gc_resolved_method_table_roots, " TF: Resolved Table Roots") \ |
223 | f(final_traversal_gc_vm_weak_roots, " TF: VM Weak Roots") \ |
224 | f(final_traversal_gc_synchronizer_roots, " TF: Synchronizer Roots") \ |
225 | f(final_traversal_gc_management_roots, " TF: Management Roots") \ |
226 | f(final_traversal_gc_system_dict_roots, " TF: System Dict Roots") \ |
227 | f(final_traversal_gc_cldg_roots, " TF: CLDG Roots") \ |
228 | f(final_traversal_gc_jvmti_roots, " TF: JVMTI Roots") \ |
229 | f(final_traversal_gc_string_dedup_table_roots, " TF: Dedup Table Roots") \ |
230 | f(final_traversal_gc_string_dedup_queue_roots, " TF: Dedup Queue Roots") \ |
231 | f(final_traversal_gc_finish_queues, " TF: Finish Queues") \ |
232 | f(final_traversal_gc_termination, " TF: Termination") \ |
233 | \ |
234 | /* Per-thread timer block, should have "roots" counters in consistent order */ \ |
235 | f(final_traversal_update_roots, " Update Roots") \ |
236 | f(final_traversal_update_thread_roots, " TU: Thread Roots") \ |
237 | f(final_traversal_update_code_roots, " TU: Code Cache Roots") \ |
238 | f(final_traversal_update_universe_roots, " TU: Universe Roots") \ |
239 | f(final_traversal_update_jni_roots, " TU: JNI Roots") \ |
240 | f(final_traversal_update_jvmti_weak_roots, " TU: JVMTI Weak Roots") \ |
241 | f(final_traversal_update_jfr_weak_roots, " TU: JFR Weak Roots") \ |
242 | f(final_traversal_update_jni_weak_roots, " TU: JNI Weak Roots") \ |
243 | f(final_traversal_update_stringtable_roots, " TU: String Table Roots") \ |
244 | f(final_traversal_update_resolved_method_table_roots, " TU: Resolved Table Roots") \ |
245 | f(final_traversal_update_vm_weak_roots, " TU: VM Weak Roots") \ |
246 | f(final_traversal_update_synchronizer_roots, " TU: Synchronizer Roots") \ |
247 | f(final_traversal_update_management_roots, " TU: Management Roots") \ |
248 | f(final_traversal_update_system_dict_roots, " TU: System Dict Roots") \ |
249 | f(final_traversal_update_cldg_roots, " TU: CLDG Roots") \ |
250 | f(final_traversal_update_jvmti_roots, " TU: JVMTI Roots") \ |
251 | f(final_traversal_update_string_dedup_table_roots, " TU: Dedup Table Roots") \ |
252 | f(final_traversal_update_string_dedup_queue_roots, " TU: Dedup Queue Roots") \ |
253 | f(final_traversal_update_finish_queues, " TU: Finish Queues") \ |
254 | \ |
255 | f(traversal_gc_cleanup, " Cleanup") \ |
256 | \ |
257 | f(full_gc_gross, "Pause Full GC (G)") \ |
258 | f(full_gc, "Pause Full GC (N)") \ |
259 | f(full_gc_heapdumps, " Heap Dumps") \ |
260 | f(full_gc_prepare, " Prepare") \ |
261 | \ |
262 | /* Per-thread timer block, should have "roots" counters in consistent order */ \ |
263 | f(full_gc_roots, " Roots") \ |
264 | f(full_gc_thread_roots, " F: Thread Roots") \ |
265 | f(full_gc_code_roots, " F: Code Cache Roots") \ |
266 | f(full_gc_universe_roots, " F: Universe Roots") \ |
267 | f(full_gc_jni_roots, " F: JNI Roots") \ |
268 | f(full_gc_jvmti_weak_roots, " F: JVMTI Weak Roots") \ |
269 | f(full_gc_jfr_weak_roots, " F: JFR Weak Roots") \ |
270 | f(full_gc_jni_weak_roots, " F: JNI Weak Roots") \ |
271 | f(full_gc_stringtable_roots, " F: String Table Roots") \ |
272 | f(full_gc_resolved_method_table_roots, " F: Resolved Table Roots") \ |
273 | f(full_gc_vm_weak_roots, " F: VM Weak Roots") \ |
274 | f(full_gc_synchronizer_roots, " F: Synchronizer Roots") \ |
275 | f(full_gc_management_roots, " F: Management Roots") \ |
276 | f(full_gc_system_dictionary_roots, " F: System Dict Roots") \ |
277 | f(full_gc_cldg_roots, " F: CLDG Roots") \ |
278 | f(full_gc_jvmti_roots, " F: JVMTI Roots") \ |
279 | f(full_gc_string_dedup_table_roots, " F: Dedup Table Roots") \ |
280 | f(full_gc_string_dedup_queue_roots, " F: Dedup Queue Roots") \ |
281 | f(full_gc_finish_queues, " F: Finish Queues") \ |
282 | \ |
283 | f(full_gc_mark, " Mark") \ |
284 | f(full_gc_mark_finish_queues, " Finish Queues") \ |
285 | f(full_gc_mark_termination, " Termination") \ |
286 | f(full_gc_weakrefs, " Weak References") \ |
287 | f(full_gc_weakrefs_process, " Process") \ |
288 | f(full_gc_weakrefs_termination, " Termination") \ |
289 | f(full_gc_purge, " System Purge") \ |
290 | f(full_gc_purge_class_unload, " Unload Classes") \ |
291 | f(full_gc_purge_par, " Parallel Cleanup") \ |
292 | f(full_gc_purge_cldg, " CLDG") \ |
293 | f(full_gc_calculate_addresses, " Calculate Addresses") \ |
294 | f(full_gc_calculate_addresses_regular, " Regular Objects") \ |
295 | f(full_gc_calculate_addresses_humong, " Humongous Objects") \ |
296 | f(full_gc_adjust_pointers, " Adjust Pointers") \ |
297 | f(full_gc_copy_objects, " Copy Objects") \ |
298 | f(full_gc_copy_objects_regular, " Regular Objects") \ |
299 | f(full_gc_copy_objects_humong, " Humongous Objects") \ |
300 | f(full_gc_copy_objects_reset_complete, " Reset Complete Bitmap") \ |
301 | f(full_gc_copy_objects_rebuild, " Rebuild Region Sets") \ |
302 | f(full_gc_resize_tlabs, " Resize TLABs") \ |
303 | \ |
304 | /* Longer concurrent phases at the end */ \ |
305 | f(conc_reset, "Concurrent Reset") \ |
306 | f(conc_mark, "Concurrent Marking") \ |
307 | f(conc_termination, " Termination") \ |
308 | f(conc_preclean, "Concurrent Precleaning") \ |
309 | f(conc_evac, "Concurrent Evacuation") \ |
310 | f(conc_update_refs, "Concurrent Update Refs") \ |
311 | f(conc_cleanup, "Concurrent Cleanup") \ |
312 | f(conc_traversal, "Concurrent Traversal") \ |
313 | f(conc_traversal_termination, " Termination") \ |
314 | \ |
315 | f(conc_uncommit, "Concurrent Uncommit") \ |
316 | \ |
317 | /* Unclassified */ \ |
318 | f(pause_other, "Pause Other") \ |
319 | f(conc_other, "Concurrent Other") \ |
320 | // end |
321 | |
322 | #define SHENANDOAH_GC_PAR_PHASE_DO(f) \ |
323 | f(ThreadRoots, "Thread Roots (ms):") \ |
324 | f(CodeCacheRoots, "CodeCache Roots (ms):") \ |
325 | f(UniverseRoots, "Universe Roots (ms):") \ |
326 | f(JNIRoots, "JNI Handles Roots (ms):") \ |
327 | f(JVMTIWeakRoots, "JVMTI Weak Roots (ms):") \ |
328 | f(JFRWeakRoots, "JFR Weak Roots (ms):") \ |
329 | f(JNIWeakRoots, "JNI Weak Roots (ms):") \ |
330 | f(StringTableRoots, "StringTable Roots(ms):") \ |
331 | f(ResolvedMethodTableRoots, "Resolved Table Roots(ms):") \ |
332 | f(VMWeakRoots, "VM Weak Roots(ms)") \ |
333 | f(ObjectSynchronizerRoots, "ObjectSynchronizer Roots (ms):") \ |
334 | f(ManagementRoots, "Management Roots (ms):") \ |
335 | f(SystemDictionaryRoots, "SystemDictionary Roots (ms):") \ |
336 | f(CLDGRoots, "CLDG Roots (ms):") \ |
337 | f(JVMTIRoots, "JVMTI Roots (ms):") \ |
338 | f(StringDedupTableRoots, "String Dedup Table Roots (ms):") \ |
339 | f(StringDedupQueueRoots, "String Dedup Queue Roots (ms):") \ |
340 | f(FinishQueues, "Finish Queues (ms):") \ |
341 | // end |
342 | |
343 | class ShenandoahPhaseTimings : public CHeapObj<mtGC> { |
344 | public: |
345 | #define GC_PHASE_DECLARE_ENUM(type, title) type, |
346 | |
347 | enum Phase { |
348 | SHENANDOAH_GC_PHASE_DO(GC_PHASE_DECLARE_ENUM) |
349 | _num_phases |
350 | }; |
351 | |
352 | // These are the subphases of GC phases (scan_roots, update_roots, |
353 | // init_evac, final_update_refs_roots and full_gc_roots). |
354 | // Make sure they are following this order. |
355 | enum GCParPhases { |
356 | SHENANDOAH_GC_PAR_PHASE_DO(GC_PHASE_DECLARE_ENUM) |
357 | GCParPhasesSentinel |
358 | }; |
359 | |
360 | #undef GC_PHASE_DECLARE_ENUM |
361 | |
362 | private: |
363 | struct TimingData { |
364 | HdrSeq _secs; |
365 | double _start; |
366 | }; |
367 | |
368 | private: |
369 | TimingData _timing_data[_num_phases]; |
370 | static const char* _phase_names[_num_phases]; |
371 | |
372 | ShenandoahWorkerTimings* _worker_times; |
373 | ShenandoahTerminationTimings* _termination_times; |
374 | |
375 | ShenandoahCollectorPolicy* _policy; |
376 | |
377 | public: |
378 | ShenandoahPhaseTimings(); |
379 | |
380 | ShenandoahWorkerTimings* const worker_times() const { return _worker_times; } |
381 | ShenandoahTerminationTimings* const termination_times() const { return _termination_times; } |
382 | |
383 | // record phase start |
384 | void record_phase_start(Phase phase); |
385 | // record phase end and return elapsed time in seconds for the phase |
386 | void record_phase_end(Phase phase); |
387 | // record an elapsed time for the phase |
388 | void record_phase_time(Phase phase, double time); |
389 | |
390 | void record_workers_start(Phase phase); |
391 | void record_workers_end(Phase phase); |
392 | |
393 | static const char* phase_name(Phase phase) { |
394 | assert(phase >= 0 && phase < _num_phases, "Out of bound" ); |
395 | return _phase_names[phase]; |
396 | } |
397 | |
398 | void print_on(outputStream* out) const; |
399 | |
400 | private: |
401 | void init_phase_names(); |
402 | void print_summary_sd(outputStream* out, const char* str, const HdrSeq* seq) const; |
403 | }; |
404 | |
405 | class ShenandoahWorkerTimings : public CHeapObj<mtGC> { |
406 | private: |
407 | uint _max_gc_threads; |
408 | WorkerDataArray<double>* _gc_par_phases[ShenandoahPhaseTimings::GCParPhasesSentinel]; |
409 | |
410 | public: |
411 | ShenandoahWorkerTimings(uint max_gc_threads); |
412 | |
413 | // record the time a phase took in seconds |
414 | void record_time_secs(ShenandoahPhaseTimings::GCParPhases phase, uint worker_i, double secs); |
415 | |
416 | double average(uint i) const; |
417 | void reset(uint i); |
418 | void print() const; |
419 | }; |
420 | |
421 | class ShenandoahTerminationTimings : public CHeapObj<mtGC> { |
422 | private: |
423 | WorkerDataArray<double>* _gc_termination_phase; |
424 | public: |
425 | ShenandoahTerminationTimings(uint max_gc_threads); |
426 | |
427 | // record the time a phase took in seconds |
428 | void record_time_secs(uint worker_i, double secs); |
429 | |
430 | double average() const; |
431 | void reset(); |
432 | |
433 | void print() const; |
434 | }; |
435 | |
436 | #endif // SHARE_GC_SHENANDOAH_SHENANDOAHPHASETIMINGS_HPP |
437 | |