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/referenceProcessorStats.hpp" 29 #include "gc/shared/workerDataArray.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 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 void print_reference(ReferenceType ref_type, uint base_indent) const; 100 void print_phase(RefProcParPhases phase, uint indent) const; 101 102 public: 103 ReferenceProcessorPhaseTimes(GCTimer* gc_timer, uint max_gc_threads); 104 ~ReferenceProcessorPhaseTimes(); 105 106 static double uninitialized() { return -1.0; } 107 108 WorkerDataArray<double>* worker_time_sec(RefProcParPhases phase) const; 109 void set_par_phase_time_ms(RefProcParPhases phase, double par_phase_time_ms); 110 111 void set_ref_proc_time_ms(ReferenceType ref_type, double ref_proc_time_ms); 112 113 void set_total_time_ms(double total_time_ms) { _total_time_ms = total_time_ms; } 114 115 void set_ref_cleared(ReferenceType ref_type, size_t count); 116 size_t ref_discovered(ReferenceType ref_type) const; 117 void set_ref_discovered(ReferenceType ref_type, size_t count); 118 void set_ref_enqueued(ReferenceType ref_type, size_t count); 119 120 void set_balance_queues_time_ms(ReferenceType ref_type, double time_ms); 121 122 void set_processing_is_mt(bool processing_is_mt) { _processing_is_mt = processing_is_mt; } 123 124 ReferenceType processing_ref_type() const { return _processing_ref_type; } 125 void set_processing_ref_type(ReferenceType processing_ref_type) { _processing_ref_type = processing_ref_type; } 126 127 // Returns RefProcParPhases calculated from phase_number and _processing_ref_type. 128 RefProcParPhases par_phase(RefProcPhaseNumbers phase_number) const; 129 130 GCTimer* gc_timer() const { return _gc_timer; } 131 132 // Reset all fields. If not reset at next cycle, an assertion will fail. 133 void reset(); 134 135 void print_all_references(uint base_indent = 0, bool print_total = true) const; 136 }; 137 138 // Updates working time of each worker thread. 139 class RefProcWorkerTimeTracker : public StackObj { 140 protected: 141 WorkerDataArray<double>* _worker_time; 142 double _start_time; 143 uint _worker_id; 144 145 public: 146 RefProcWorkerTimeTracker(ReferenceProcessorPhaseTimes::RefProcPhaseNumbers number, 147 ReferenceProcessorPhaseTimes* phase_times, 148 uint worker_id); 149 RefProcWorkerTimeTracker(ReferenceProcessorPhaseTimes::RefProcParPhases phase, 150 ReferenceProcessorPhaseTimes* phase_times, 151 uint worker_id); 152 ~RefProcWorkerTimeTracker(); 153 }; 154 155 class RefProcPhaseTimeBaseTracker : public StackObj { 156 protected: 157 const char* _title; 158 ReferenceProcessorPhaseTimes* _phase_times; 159 Ticks _start_ticks; 160 Ticks _end_ticks; 161 162 Ticks end_ticks(); 163 double elapsed_time(); 164 ReferenceProcessorPhaseTimes* phase_times() const { return _phase_times; } 165 // Print phase elapsed time with each worker information if MT processed. 166 void print_phase(ReferenceProcessorPhaseTimes::RefProcParPhases phase, uint indent); 167 168 public: 169 RefProcPhaseTimeBaseTracker(const char* title, 170 ReferenceProcessorPhaseTimes* phase_times); 171 ~RefProcPhaseTimeBaseTracker(); 172 }; 173 174 // Updates queue balance time at ReferenceProcessorPhaseTimes and 175 // save it into GCTimer. 176 class RefProcBalanceQueuesTimeTracker : public RefProcPhaseTimeBaseTracker { 177 public: 178 RefProcBalanceQueuesTimeTracker(ReferenceProcessorPhaseTimes* phase_times); 179 ~RefProcBalanceQueuesTimeTracker(); 180 }; 181 182 // Updates phase time at ReferenceProcessorPhaseTimes and save it into GCTimer. 183 class RefProcParPhaseTimeTracker : public RefProcPhaseTimeBaseTracker { 184 ReferenceProcessorPhaseTimes::RefProcPhaseNumbers _phase_number; 185 186 public: 187 RefProcParPhaseTimeTracker(ReferenceProcessorPhaseTimes::RefProcPhaseNumbers phase_number, 188 ReferenceProcessorPhaseTimes* phase_times); 189 ~RefProcParPhaseTimeTracker(); 190 }; 191 192 // Updates phase time related information. 193 // - Each phase processing time, cleared/discovered reference counts and stats for each working threads if MT processed. 194 class RefProcPhaseTimesTracker : public RefProcPhaseTimeBaseTracker { 195 ReferenceProcessor* _rp; 196 197 public: 198 RefProcPhaseTimesTracker(ReferenceType ref_type, 199 ReferenceProcessorPhaseTimes* phase_times, 200 ReferenceProcessor* rp); 201 ~RefProcPhaseTimesTracker(); 202 }; 203 204 #endif // SHARE_VM_GC_SHARED_REFERENCEPROCESSORPHASETIMES_HPP