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