1/*
2 * Copyright (c) 2017, 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_SHARED_REFERENCEPROCESSORPHASETIMES_HPP
26#define SHARE_GC_SHARED_REFERENCEPROCESSORPHASETIMES_HPP
27
28#include "gc/shared/referenceProcessor.hpp"
29#include "gc/shared/referenceProcessorStats.hpp"
30#include "gc/shared/workerDataArray.hpp"
31#include "memory/allocation.hpp"
32#include "memory/referenceType.hpp"
33#include "utilities/ticks.hpp"
34
35class DiscoveredList;
36class GCTimer;
37class LogStream;
38
39class ReferenceProcessorPhaseTimes : public CHeapObj<mtGC> {
40 static const int number_of_subclasses_of_ref = REF_PHANTOM - REF_OTHER; // 5 - 1 = 4
41
42 // Records per thread time information of each sub phase.
43 WorkerDataArray<double>* _sub_phases_worker_time_sec[ReferenceProcessor::RefSubPhaseMax];
44 // Total time of each sub phase.
45 double _sub_phases_total_time_ms[ReferenceProcessor::RefSubPhaseMax];
46
47 // Records total elapsed time for each phase.
48 double _phases_time_ms[ReferenceProcessor::RefPhaseMax];
49 // Records total queue balancing for each phase.
50 double _balance_queues_time_ms[ReferenceProcessor::RefPhaseMax];
51
52 WorkerDataArray<double>* _phase2_worker_time_sec;
53
54 // Total spent time for reference processing.
55 double _total_time_ms;
56
57 size_t _ref_cleared[number_of_subclasses_of_ref];
58 size_t _ref_discovered[number_of_subclasses_of_ref];
59
60 bool _processing_is_mt;
61
62 GCTimer* _gc_timer;
63
64 double phase_time_ms(ReferenceProcessor::RefProcPhases phase) const;
65 double sub_phase_total_time_ms(ReferenceProcessor::RefProcSubPhases sub_phase) const;
66
67 double total_time_ms() const { return _total_time_ms; }
68
69 double balance_queues_time_ms(ReferenceProcessor::RefProcPhases phase) const;
70
71 void print_reference(ReferenceType ref_type, uint base_indent) const;
72
73 void print_phase(ReferenceProcessor::RefProcPhases phase, uint indent) const;
74 void print_balance_time(LogStream* ls, ReferenceProcessor::RefProcPhases phase, uint indent) const;
75 void print_sub_phase(LogStream* ls, ReferenceProcessor::RefProcSubPhases sub_phase, uint indent) const;
76 void print_worker_time(LogStream* ls, WorkerDataArray<double>* worker_time, const char* ser_title, uint indent) const;
77
78 static double uninitialized() { return -1.0; }
79public:
80 ReferenceProcessorPhaseTimes(GCTimer* gc_timer, uint max_gc_threads);
81 ~ReferenceProcessorPhaseTimes();
82
83 WorkerDataArray<double>* phase2_worker_time_sec() const { return _phase2_worker_time_sec; }
84 WorkerDataArray<double>* sub_phase_worker_time_sec(ReferenceProcessor::RefProcSubPhases phase) const;
85 void set_phase_time_ms(ReferenceProcessor::RefProcPhases phase, double par_phase_time_ms);
86
87 void set_sub_phase_total_phase_time_ms(ReferenceProcessor::RefProcSubPhases sub_phase, double ref_proc_time_ms);
88
89 void set_total_time_ms(double total_time_ms) { _total_time_ms = total_time_ms; }
90
91 void add_ref_cleared(ReferenceType ref_type, size_t count);
92 void set_ref_discovered(ReferenceType ref_type, size_t count);
93
94 void set_balance_queues_time_ms(ReferenceProcessor::RefProcPhases phase, double time_ms);
95
96 void set_processing_is_mt(bool processing_is_mt) { _processing_is_mt = processing_is_mt; }
97
98 GCTimer* gc_timer() const { return _gc_timer; }
99
100 // Reset all fields. If not reset at next cycle, an assertion will fail.
101 void reset();
102
103 void print_all_references(uint base_indent = 0, bool print_total = true) const;
104};
105
106class RefProcWorkerTimeTracker : public CHeapObj<mtGC> {
107protected:
108 WorkerDataArray<double>* _worker_time;
109 double _start_time;
110 uint _worker_id;
111public:
112 RefProcWorkerTimeTracker(WorkerDataArray<double>* worker_time, uint worker_id);
113 virtual ~RefProcWorkerTimeTracker();
114};
115
116// Updates working time of each worker thread for a given sub phase.
117class RefProcSubPhasesWorkerTimeTracker : public RefProcWorkerTimeTracker {
118public:
119 RefProcSubPhasesWorkerTimeTracker(ReferenceProcessor::RefProcSubPhases phase,
120 ReferenceProcessorPhaseTimes* phase_times,
121 uint worker_id);
122 ~RefProcSubPhasesWorkerTimeTracker();
123};
124
125class RefProcPhaseTimeBaseTracker : public StackObj {
126protected:
127 ReferenceProcessorPhaseTimes* _phase_times;
128 Ticks _start_ticks;
129 Ticks _end_ticks;
130
131 ReferenceProcessor::RefProcPhases _phase_number;
132
133 Ticks end_ticks();
134 double elapsed_time();
135 ReferenceProcessorPhaseTimes* phase_times() const { return _phase_times; }
136
137public:
138 RefProcPhaseTimeBaseTracker(const char* title,
139 ReferenceProcessor::RefProcPhases _phase_number,
140 ReferenceProcessorPhaseTimes* phase_times);
141 ~RefProcPhaseTimeBaseTracker();
142};
143
144// Updates queue balance time at ReferenceProcessorPhaseTimes and
145// save it into GCTimer.
146class RefProcBalanceQueuesTimeTracker : public RefProcPhaseTimeBaseTracker {
147public:
148 RefProcBalanceQueuesTimeTracker(ReferenceProcessor::RefProcPhases phase_number,
149 ReferenceProcessorPhaseTimes* phase_times);
150 ~RefProcBalanceQueuesTimeTracker();
151};
152
153// Updates phase time at ReferenceProcessorPhaseTimes and save it into GCTimer.
154class RefProcPhaseTimeTracker : public RefProcPhaseTimeBaseTracker {
155public:
156 RefProcPhaseTimeTracker(ReferenceProcessor::RefProcPhases phase_number,
157 ReferenceProcessorPhaseTimes* phase_times);
158 ~RefProcPhaseTimeTracker();
159};
160
161// Highest level time tracker.
162class RefProcTotalPhaseTimesTracker : public RefProcPhaseTimeBaseTracker {
163 ReferenceProcessor* _rp;
164public:
165 RefProcTotalPhaseTimesTracker(ReferenceProcessor::RefProcPhases phase_number,
166 ReferenceProcessorPhaseTimes* phase_times,
167 ReferenceProcessor* rp);
168 ~RefProcTotalPhaseTimesTracker();
169};
170
171#endif // SHARE_GC_SHARED_REFERENCEPROCESSORPHASETIMES_HPP
172