1/*
2 * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25#ifndef SHARE_GC_G1_G1GCPHASETIMES_HPP
26#define SHARE_GC_G1_G1GCPHASETIMES_HPP
27
28#include "gc/shared/referenceProcessorPhaseTimes.hpp"
29#include "gc/shared/weakProcessorPhaseTimes.hpp"
30#include "jfr/jfrEvents.hpp"
31#include "logging/logLevel.hpp"
32#include "memory/allocation.hpp"
33#include "utilities/macros.hpp"
34
35class LineBuffer;
36class G1ParScanThreadState;
37class STWGCTimer;
38
39template <class T> class WorkerDataArray;
40
41class G1GCPhaseTimes : public CHeapObj<mtGC> {
42 uint _max_gc_threads;
43 jlong _gc_start_counter;
44 double _gc_pause_time_ms;
45
46 public:
47 enum GCParPhases {
48 GCWorkerStart,
49 ExtRootScan,
50 ThreadRoots,
51 UniverseRoots,
52 JNIRoots,
53 ObjectSynchronizerRoots,
54 ManagementRoots,
55 SystemDictionaryRoots,
56 CLDGRoots,
57 JVMTIRoots,
58 AOT_ONLY(AOTCodeRoots COMMA)
59 JVMCI_ONLY(JVMCIRoots COMMA)
60 CMRefRoots,
61 WaitForStrongCLD,
62 WeakCLDRoots,
63 UpdateRS,
64 ScanHCC,
65 ScanRS,
66 OptScanRS,
67 CodeRoots,
68 OptCodeRoots,
69 ObjCopy,
70 OptObjCopy,
71 Termination,
72 OptTermination,
73 Other,
74 GCWorkerTotal,
75 GCWorkerEnd,
76 StringDedupQueueFixup,
77 StringDedupTableFixup,
78 RedirtyCards,
79 YoungFreeCSet,
80 NonYoungFreeCSet,
81 GCParPhasesSentinel
82 };
83
84 static const GCParPhases ExtRootScanSubPhasesFirst = ThreadRoots;
85 static const GCParPhases ExtRootScanSubPhasesLast = WeakCLDRoots;
86
87 enum GCScanRSWorkItems {
88 ScanRSScannedCards,
89 ScanRSClaimedCards,
90 ScanRSSkippedCards,
91 ScanRSScannedOptRefs,
92 ScanRSUsedMemory
93 };
94
95 enum GCUpdateRSWorkItems {
96 UpdateRSProcessedBuffers,
97 UpdateRSScannedCards,
98 UpdateRSSkippedCards
99 };
100
101 enum GCObjCopyWorkItems {
102 ObjCopyLABWaste,
103 ObjCopyLABUndoWaste
104 };
105
106 private:
107 // Markers for grouping the phases in the GCPhases enum above
108 static const int GCMainParPhasesLast = GCWorkerEnd;
109
110 WorkerDataArray<double>* _gc_par_phases[GCParPhasesSentinel];
111
112 WorkerDataArray<size_t>* _update_rs_processed_buffers;
113 WorkerDataArray<size_t>* _update_rs_scanned_cards;
114 WorkerDataArray<size_t>* _update_rs_skipped_cards;
115
116 WorkerDataArray<size_t>* _scan_rs_scanned_cards;
117 WorkerDataArray<size_t>* _scan_rs_claimed_cards;
118 WorkerDataArray<size_t>* _scan_rs_skipped_cards;
119
120 WorkerDataArray<size_t>* _opt_scan_rs_scanned_cards;
121 WorkerDataArray<size_t>* _opt_scan_rs_claimed_cards;
122 WorkerDataArray<size_t>* _opt_scan_rs_skipped_cards;
123 WorkerDataArray<size_t>* _opt_scan_rs_scanned_opt_refs;
124 WorkerDataArray<size_t>* _opt_scan_rs_used_memory;
125
126 WorkerDataArray<size_t>* _obj_copy_lab_waste;
127 WorkerDataArray<size_t>* _obj_copy_lab_undo_waste;
128
129 WorkerDataArray<size_t>* _opt_obj_copy_lab_waste;
130 WorkerDataArray<size_t>* _opt_obj_copy_lab_undo_waste;
131
132 WorkerDataArray<size_t>* _termination_attempts;
133
134 WorkerDataArray<size_t>* _opt_termination_attempts;
135
136 WorkerDataArray<size_t>* _redirtied_cards;
137
138 double _cur_collection_initial_evac_time_ms;
139 double _cur_optional_evac_ms;
140 double _cur_collection_code_root_fixup_time_ms;
141 double _cur_strong_code_root_purge_time_ms;
142
143 double _cur_evac_fail_recalc_used;
144 double _cur_evac_fail_remove_self_forwards;
145
146 double _cur_string_deduplication_time_ms;
147
148 double _cur_prepare_tlab_time_ms;
149 double _cur_resize_tlab_time_ms;
150
151 double _cur_derived_pointer_table_update_time_ms;
152
153 double _cur_clear_ct_time_ms;
154 double _cur_expand_heap_time_ms;
155 double _cur_ref_proc_time_ms;
156
157 double _cur_collection_start_sec;
158 double _root_region_scan_wait_time_ms;
159
160 double _external_accounted_time_ms;
161
162 double _recorded_clear_claimed_marks_time_ms;
163
164 double _recorded_young_cset_choice_time_ms;
165 double _recorded_non_young_cset_choice_time_ms;
166
167 double _recorded_redirty_logged_cards_time_ms;
168
169 double _recorded_preserve_cm_referents_time_ms;
170
171 double _recorded_merge_pss_time_ms;
172
173 double _recorded_start_new_cset_time_ms;
174
175 double _recorded_total_free_cset_time_ms;
176
177 double _recorded_serial_free_cset_time_ms;
178
179 double _cur_region_register_time;
180
181 double _cur_fast_reclaim_humongous_time_ms;
182 size_t _cur_fast_reclaim_humongous_total;
183 size_t _cur_fast_reclaim_humongous_candidates;
184 size_t _cur_fast_reclaim_humongous_reclaimed;
185
186 double _cur_verify_before_time_ms;
187 double _cur_verify_after_time_ms;
188
189 ReferenceProcessorPhaseTimes _ref_phase_times;
190 WeakProcessorPhaseTimes _weak_phase_times;
191
192 double worker_time(GCParPhases phase, uint worker);
193 void note_gc_end();
194 void reset();
195
196 template <class T>
197 void details(T* phase, const char* indent) const;
198
199 void log_phase(WorkerDataArray<double>* phase, uint indent, outputStream* out, bool print_sum) const;
200 void debug_phase(WorkerDataArray<double>* phase, uint extra_indent = 0) const;
201 void trace_phase(WorkerDataArray<double>* phase, bool print_sum = true) const;
202
203 void info_time(const char* name, double value) const;
204 void debug_time(const char* name, double value) const;
205 // This will print logs for both 'gc+phases' and 'gc+phases+ref'.
206 void debug_time_for_reference(const char* name, double value) const;
207 void trace_time(const char* name, double value) const;
208 void trace_count(const char* name, size_t value) const;
209
210 double print_pre_evacuate_collection_set() const;
211 double print_evacuate_collection_set() const;
212 double print_evacuate_optional_collection_set() const;
213 double print_post_evacuate_collection_set() const;
214 void print_other(double accounted_ms) const;
215
216 public:
217 G1GCPhaseTimes(STWGCTimer* gc_timer, uint max_gc_threads);
218 void note_gc_start();
219 void print();
220 static const char* phase_name(GCParPhases phase);
221
222 // record the time a phase took in seconds
223 void record_time_secs(GCParPhases phase, uint worker_i, double secs);
224
225 // add a number of seconds to a phase
226 void add_time_secs(GCParPhases phase, uint worker_i, double secs);
227
228 void record_or_add_time_secs(GCParPhases phase, uint worker_i, double secs);
229
230 double get_time_secs(GCParPhases phase, uint worker_i);
231
232 void record_thread_work_item(GCParPhases phase, uint worker_i, size_t count, uint index = 0);
233
234 void record_or_add_thread_work_item(GCParPhases phase, uint worker_i, size_t count, uint index = 0);
235
236 size_t get_thread_work_item(GCParPhases phase, uint worker_i, uint index = 0);
237
238 // return the average time for a phase in milliseconds
239 double average_time_ms(GCParPhases phase);
240
241 size_t sum_thread_work_items(GCParPhases phase, uint index = 0);
242
243 public:
244
245 void record_prepare_tlab_time_ms(double ms) {
246 _cur_prepare_tlab_time_ms = ms;
247 }
248
249 void record_resize_tlab_time_ms(double ms) {
250 _cur_resize_tlab_time_ms = ms;
251 }
252
253 void record_derived_pointer_table_update_time(double ms) {
254 _cur_derived_pointer_table_update_time_ms = ms;
255 }
256
257 void record_clear_ct_time(double ms) {
258 _cur_clear_ct_time_ms = ms;
259 }
260
261 void record_expand_heap_time(double ms) {
262 _cur_expand_heap_time_ms = ms;
263 }
264
265 void record_initial_evac_time(double ms) {
266 _cur_collection_initial_evac_time_ms = ms;
267 }
268
269 void record_or_add_optional_evac_time(double ms) {
270 _cur_optional_evac_ms += ms;
271 }
272
273 void record_or_add_code_root_fixup_time(double ms) {
274 _cur_collection_code_root_fixup_time_ms += ms;
275 }
276
277 void record_strong_code_root_purge_time(double ms) {
278 _cur_strong_code_root_purge_time_ms = ms;
279 }
280
281 void record_evac_fail_recalc_used_time(double ms) {
282 _cur_evac_fail_recalc_used = ms;
283 }
284
285 void record_evac_fail_remove_self_forwards(double ms) {
286 _cur_evac_fail_remove_self_forwards = ms;
287 }
288
289 void record_string_deduplication_time(double ms) {
290 _cur_string_deduplication_time_ms = ms;
291 }
292
293 void record_ref_proc_time(double ms) {
294 _cur_ref_proc_time_ms = ms;
295 }
296
297 void record_root_region_scan_wait_time(double time_ms) {
298 _root_region_scan_wait_time_ms = time_ms;
299 }
300
301 void record_total_free_cset_time_ms(double time_ms) {
302 _recorded_total_free_cset_time_ms = time_ms;
303 }
304
305 void record_serial_free_cset_time_ms(double time_ms) {
306 _recorded_serial_free_cset_time_ms = time_ms;
307 }
308
309 void record_register_regions(double time_ms, size_t total, size_t candidates) {
310 _cur_region_register_time = time_ms;
311 _cur_fast_reclaim_humongous_total = total;
312 _cur_fast_reclaim_humongous_candidates = candidates;
313 }
314
315 void record_fast_reclaim_humongous_time_ms(double value, size_t reclaimed) {
316 _cur_fast_reclaim_humongous_time_ms = value;
317 _cur_fast_reclaim_humongous_reclaimed = reclaimed;
318 }
319
320 void record_young_cset_choice_time_ms(double time_ms) {
321 _recorded_young_cset_choice_time_ms = time_ms;
322 }
323
324 void record_non_young_cset_choice_time_ms(double time_ms) {
325 _recorded_non_young_cset_choice_time_ms = time_ms;
326 }
327
328 void record_redirty_logged_cards_time_ms(double time_ms) {
329 _recorded_redirty_logged_cards_time_ms = time_ms;
330 }
331
332 void record_preserve_cm_referents_time_ms(double time_ms) {
333 _recorded_preserve_cm_referents_time_ms = time_ms;
334 }
335
336 void record_merge_pss_time_ms(double time_ms) {
337 _recorded_merge_pss_time_ms = time_ms;
338 }
339
340 void record_start_new_cset_time_ms(double time_ms) {
341 _recorded_start_new_cset_time_ms = time_ms;
342 }
343
344 void record_cur_collection_start_sec(double time_ms) {
345 _cur_collection_start_sec = time_ms;
346 }
347
348 void record_verify_before_time_ms(double time_ms) {
349 _cur_verify_before_time_ms = time_ms;
350 }
351
352 void record_verify_after_time_ms(double time_ms) {
353 _cur_verify_after_time_ms = time_ms;
354 }
355
356 void inc_external_accounted_time_ms(double time_ms) {
357 _external_accounted_time_ms += time_ms;
358 }
359
360 void record_clear_claimed_marks_time_ms(double recorded_clear_claimed_marks_time_ms) {
361 _recorded_clear_claimed_marks_time_ms = recorded_clear_claimed_marks_time_ms;
362 }
363
364 double cur_collection_start_sec() {
365 return _cur_collection_start_sec;
366 }
367
368 double cur_collection_par_time_ms() {
369 return _cur_collection_initial_evac_time_ms;
370 }
371
372 double cur_clear_ct_time_ms() {
373 return _cur_clear_ct_time_ms;
374 }
375
376 double cur_expand_heap_time_ms() {
377 return _cur_expand_heap_time_ms;
378 }
379
380 double root_region_scan_wait_time_ms() {
381 return _root_region_scan_wait_time_ms;
382 }
383
384 double young_cset_choice_time_ms() {
385 return _recorded_young_cset_choice_time_ms;
386 }
387
388 double total_free_cset_time_ms() {
389 return _recorded_total_free_cset_time_ms;
390 }
391
392 double non_young_cset_choice_time_ms() {
393 return _recorded_non_young_cset_choice_time_ms;
394 }
395
396 double fast_reclaim_humongous_time_ms() {
397 return _cur_fast_reclaim_humongous_time_ms;
398 }
399
400 ReferenceProcessorPhaseTimes* ref_phase_times() { return &_ref_phase_times; }
401
402 WeakProcessorPhaseTimes* weak_phase_times() { return &_weak_phase_times; }
403};
404
405class G1EvacPhaseWithTrimTimeTracker : public StackObj {
406 G1ParScanThreadState* _pss;
407 Ticks _start;
408
409 Tickspan& _total_time;
410 Tickspan& _trim_time;
411
412 bool _stopped;
413public:
414 G1EvacPhaseWithTrimTimeTracker(G1ParScanThreadState* pss, Tickspan& total_time, Tickspan& trim_time);
415 ~G1EvacPhaseWithTrimTimeTracker();
416
417 void stop();
418};
419
420class G1GCParPhaseTimesTracker : public CHeapObj<mtGC> {
421protected:
422 Ticks _start_time;
423 G1GCPhaseTimes::GCParPhases _phase;
424 G1GCPhaseTimes* _phase_times;
425 uint _worker_id;
426 EventGCPhaseParallel _event;
427public:
428 G1GCParPhaseTimesTracker(G1GCPhaseTimes* phase_times, G1GCPhaseTimes::GCParPhases phase, uint worker_id);
429 virtual ~G1GCParPhaseTimesTracker();
430};
431
432class G1EvacPhaseTimesTracker : public G1GCParPhaseTimesTracker {
433 Tickspan _total_time;
434 Tickspan _trim_time;
435
436 G1EvacPhaseWithTrimTimeTracker _trim_tracker;
437public:
438 G1EvacPhaseTimesTracker(G1GCPhaseTimes* phase_times, G1ParScanThreadState* pss, G1GCPhaseTimes::GCParPhases phase, uint worker_id);
439 virtual ~G1EvacPhaseTimesTracker();
440};
441
442#endif // SHARE_GC_G1_G1GCPHASETIMES_HPP
443