1 /* 2 * Copyright (c) 2017, 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/referenceProcessorStats.hpp" 29 #include "gc/shared/workerDataArray.inline.hpp" 30 #include "memory/referenceType.hpp" 31 #include "utilities/ticks.hpp" 32 33 class DiscoveredList; 34 class GCTimer; 35 36 class ReferenceProcessorPhaseTimes : public CHeapObj<mtGC> { 37 public: 38 // Detailed phases that has parallel work. 39 enum RefProcParPhases { 40 SoftRefPhase1, 41 SoftRefPhase2, 42 SoftRefPhase3, 43 WeakRefPhase2, 44 WeakRefPhase3, 45 FinalRefPhase2, 46 FinalRefPhase3, 47 PhantomRefPhase2, 48 PhantomRefPhase3, 49 RefEnqueue, 50 RefParPhaseMax 51 }; 52 53 // Sub-phases that are used when processing each j.l.Reference types. 54 // Only SoftReference has RefPhase1. 55 enum RefProcPhaseNumbers { 56 RefPhase1, 57 RefPhase2, 58 RefPhase3, 59 RefPhaseMax 60 }; 61 62 private: 63 static const int number_of_subclasses_of_ref = REF_PHANTOM - REF_OTHER; // 5 - 1 = 4 64 65 // Records per thread information of each phase. 66 WorkerDataArray<double>* _worker_time_sec[RefParPhaseMax]; 67 // Records elapsed time of each phase. 68 double _par_phase_time_ms[RefParPhaseMax]; 69 70 // Total spent time for references. 71 // e.g. _ref_proc_time_ms[0] = _par_phase_time_ms[SoftRefPhase1] + 72 // _par_phase_time_ms[SoftRefPhase2] + 73 // _par_phase_time_ms[SoftRefPhase3] + extra time. 74 double _ref_proc_time_ms[number_of_subclasses_of_ref]; 75 76 double _total_time_ms; 77 78 size_t _ref_cleared[number_of_subclasses_of_ref]; 79 size_t _ref_discovered[number_of_subclasses_of_ref]; 80 size_t _ref_enqueued[number_of_subclasses_of_ref]; 81 double _balance_queues_time_ms[number_of_subclasses_of_ref]; 82 83 bool _processing_is_mt; 84 85 // Currently processing reference type. 86 ReferenceType _processing_ref_type; 87 88 GCTimer* _gc_timer; 89 90 double par_phase_time_ms(RefProcParPhases phase) const; 91 double ref_proc_time_ms(ReferenceType ref_type) const; 92 93 double total_time_ms() const { return _total_time_ms; } 94 95 size_t ref_cleared(ReferenceType ref_type) const; 96 size_t ref_enqueued(ReferenceType ref_type) const; 97 98 double balance_queues_time_ms(ReferenceType ref_type) const; 99 100 void print_reference(ReferenceType ref_type, uint base_indent) const; 101 void print_phase(RefProcParPhases phase, uint indent) const; 102 103 public: 104 ReferenceProcessorPhaseTimes(GCTimer* gc_timer, uint max_gc_threads); 105 ~ReferenceProcessorPhaseTimes(); 106 107 static double uninitialized() { return -1.0; } 108 109 WorkerDataArray<double>* worker_time_sec(RefProcParPhases phase) const; 110 void set_par_phase_time_ms(RefProcParPhases phase, double par_phase_time_ms); 111 112 void set_ref_proc_time_ms(ReferenceType ref_type, double ref_proc_time_ms); 113 114 void set_total_time_ms(double total_time_ms) { _total_time_ms = total_time_ms; } 115 116 void set_ref_cleared(ReferenceType ref_type, size_t count); 117 size_t ref_discovered(ReferenceType ref_type) const; 118 void set_ref_discovered(ReferenceType ref_type, size_t count); 119 void set_ref_enqueued(ReferenceType ref_type, size_t count); 120 121 void set_balance_queues_time_ms(ReferenceType ref_type, double time_ms); 122 123 void set_processing_is_mt(bool processing_is_mt) { _processing_is_mt = processing_is_mt; } 124 125 ReferenceType processing_ref_type() const { return _processing_ref_type; } 126 void set_processing_ref_type(ReferenceType processing_ref_type) { _processing_ref_type = processing_ref_type; } 127 128 // Returns RefProcParPhases calculated from phase_number and _processing_ref_type. 129 RefProcParPhases par_phase(RefProcPhaseNumbers phase_number) const; 130 131 GCTimer* gc_timer() const { return _gc_timer; } 132 133 // Reset all fields. If not reset at next cycle, an assertion will fail. 134 void reset(); 135 136 void print_enqueue_phase(uint base_indent = 0, bool print_total = true) const; 137 void print_all_references(uint base_indent = 0, bool print_total = true) const; 138 }; 139 140 // Updates working time of each worker thread. 141 class RefProcWorkerTimeTracker : public StackObj { 142 protected: 143 WorkerDataArray<double>* _worker_time; 144 double _start_time; 145 uint _worker_id; 146 147 public: 148 RefProcWorkerTimeTracker(ReferenceProcessorPhaseTimes::RefProcPhaseNumbers number, 149 ReferenceProcessorPhaseTimes* phase_times, 150 uint worker_id); 151 RefProcWorkerTimeTracker(ReferenceProcessorPhaseTimes::RefProcParPhases phase, 152 ReferenceProcessorPhaseTimes* phase_times, 153 uint worker_id); 154 ~RefProcWorkerTimeTracker(); 155 }; 156 157 class RefProcPhaseTimeBaseTracker : public StackObj { 158 protected: 159 const char* _title; 160 ReferenceProcessorPhaseTimes* _phase_times; 161 Ticks _start_ticks; 162 Ticks _end_ticks; 163 164 Ticks end_ticks(); 165 double elapsed_time(); 166 ReferenceProcessorPhaseTimes* phase_times() const { return _phase_times; } 167 // Print phase elapsed time with each worker information if MT processed. 168 void print_phase(ReferenceProcessorPhaseTimes::RefProcParPhases phase, uint indent); 169 170 public: 171 RefProcPhaseTimeBaseTracker(const char* title, 172 ReferenceProcessorPhaseTimes* phase_times); 173 ~RefProcPhaseTimeBaseTracker(); 174 }; 175 176 // Updates queue balance time at ReferenceProcessorPhaseTimes and 177 // save it into GCTimer. 178 class RefProcBalanceQueuesTimeTracker : public RefProcPhaseTimeBaseTracker { 179 public: 180 RefProcBalanceQueuesTimeTracker(ReferenceProcessorPhaseTimes* phase_times); 181 ~RefProcBalanceQueuesTimeTracker(); 182 }; 183 184 // Updates phase time at ReferenceProcessorPhaseTimes and save it into GCTimer. 185 class RefProcParPhaseTimeTracker : public RefProcPhaseTimeBaseTracker { 186 ReferenceProcessorPhaseTimes::RefProcPhaseNumbers _phase_number; 187 188 public: 189 RefProcParPhaseTimeTracker(ReferenceProcessorPhaseTimes::RefProcPhaseNumbers phase_number, 190 ReferenceProcessorPhaseTimes* phase_times); 191 ~RefProcParPhaseTimeTracker(); 192 }; 193 194 // Updates phase time related information. 195 // - Each phase processing time, cleared/discovered reference counts and stats for each working threads if MT processed. 196 class RefProcPhaseTimesTracker : public RefProcPhaseTimeBaseTracker { 197 ReferenceProcessor* _rp; 198 199 public: 200 RefProcPhaseTimesTracker(ReferenceType ref_type, 201 ReferenceProcessorPhaseTimes* phase_times, 202 ReferenceProcessor* rp); 203 ~RefProcPhaseTimesTracker(); 204 }; 205 206 // Updates enqueue time related information. 207 // - Enqueueing time, enqueued reference count and stats for each working thread if MT processed. 208 class RefProcEnqueueTimeTracker : public RefProcPhaseTimeBaseTracker { 209 public: 210 RefProcEnqueueTimeTracker(ReferenceProcessorPhaseTimes* phase_times, 211 ReferenceProcessorStats& stats); 212 ~RefProcEnqueueTimeTracker(); 213 }; 214 215 #endif // SHARE_VM_GC_SHARED_REFERENCEPROCESSORPHASETIMES_HPP