1 /*
2  * Copyright (c) 2017, 2018, 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_VM_GC_SHARED_REFERENCEPROCESSORPHASETIMES_HPP
26 #define SHARE_VM_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 
35 class DiscoveredList;
36 class GCTimer;
37 class LogStream;
38 
39 class 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 
total_time_ms() const67   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 
uninitialized()78   static double uninitialized() { return -1.0; }
79 public:
80   ReferenceProcessorPhaseTimes(GCTimer* gc_timer, uint max_gc_threads);
81   ~ReferenceProcessorPhaseTimes();
82 
phase2_worker_time_sec() const83   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 
set_total_time_ms(double total_time_ms)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 
set_processing_is_mt(bool processing_is_mt)96   void set_processing_is_mt(bool processing_is_mt) { _processing_is_mt = processing_is_mt; }
97 
gc_timer() const98   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 
106 class RefProcWorkerTimeTracker : public CHeapObj<mtGC> {
107 protected:
108   WorkerDataArray<double>* _worker_time;
109   double                   _start_time;
110   uint                     _worker_id;
111 public:
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.
117 class RefProcSubPhasesWorkerTimeTracker : public RefProcWorkerTimeTracker {
118 public:
119   RefProcSubPhasesWorkerTimeTracker(ReferenceProcessor::RefProcSubPhases phase,
120                                     ReferenceProcessorPhaseTimes* phase_times,
121                                     uint worker_id);
122   ~RefProcSubPhasesWorkerTimeTracker();
123 };
124 
125 class RefProcPhaseTimeBaseTracker : public StackObj {
126 protected:
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();
phase_times() const135   ReferenceProcessorPhaseTimes* phase_times() const { return _phase_times; }
136 
137 public:
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.
146 class RefProcBalanceQueuesTimeTracker : public RefProcPhaseTimeBaseTracker {
147 public:
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.
154 class RefProcPhaseTimeTracker : public RefProcPhaseTimeBaseTracker {
155 public:
156   RefProcPhaseTimeTracker(ReferenceProcessor::RefProcPhases phase_number,
157                           ReferenceProcessorPhaseTimes* phase_times);
158   ~RefProcPhaseTimeTracker();
159 };
160 
161 // Highest level time tracker.
162 class RefProcTotalPhaseTimesTracker : public RefProcPhaseTimeBaseTracker {
163   ReferenceProcessor* _rp;
164 public:
165   RefProcTotalPhaseTimesTracker(ReferenceProcessor::RefProcPhases phase_number,
166                                 ReferenceProcessorPhaseTimes* phase_times,
167                                 ReferenceProcessor* rp);
168   ~RefProcTotalPhaseTimesTracker();
169 };
170 
171 #endif // SHARE_VM_GC_SHARED_REFERENCEPROCESSORPHASETIMES_HPP
172