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_IMPLEMENTATION_SHARED_GCTIMER_HPP 26 #define SHARE_VM_GC_IMPLEMENTATION_SHARED_GCTIMER_HPP 27 28 #include "memory/allocation.hpp" 29 #include "prims/jni_md.h" 30 #include "utilities/macros.hpp" 31 32 class ConcurrentPhase; 33 class GCPhase; 34 class PausePhase; 35 36 template <class E> class GrowableArray; 37 38 class PhaseVisitor { 39 public: 40 virtual void visit(GCPhase* phase) = 0; 41 virtual void visit(PausePhase* phase) { visit((GCPhase*)phase); } 42 virtual void visit(ConcurrentPhase* phase) { visit((GCPhase*)phase); } 43 }; 44 45 class GCPhase { 46 const char* _name; 47 int _level; 48 jlong _start; 49 jlong _end; 50 51 public: 52 void set_name(const char* name) { _name = name; } 53 const char* name() { return _name; } 54 55 int level() { return _level; } 56 void set_level(int level) { _level = level; } 57 58 jlong start() { return _start; } 59 void set_start(jlong time) { _start = time; } 60 61 jlong end() { return _end; } 62 void set_end(jlong time) { _end = time; } 63 64 virtual void accept(PhaseVisitor* visitor) = 0; 65 }; 66 67 class PausePhase : public GCPhase { 68 public: 69 void accept(PhaseVisitor* visitor) { 70 visitor->visit(this); 71 } 72 }; 73 74 class ConcurrentPhase : public GCPhase { 75 void accept(PhaseVisitor* visitor) { 76 visitor->visit(this); 77 } 78 }; 79 80 class PhasesStack { 81 public: 82 // FIXME: Temporary set to 5 (used to be 4), since Reference processing needs it. 85 private: 86 int _phase_indices[PHASE_LEVELS]; 87 int _next_phase_level; 88 89 public: 90 PhasesStack() { clear(); } 91 void clear(); 92 93 void push(int phase_index); 94 int pop(); 95 int count() const; 96 }; 97 98 class TimePartitions { 99 static const int INITIAL_CAPACITY = 10; 100 101 // Currently we only support pause phases. 102 GrowableArray<PausePhase>* _phases; 103 PhasesStack _active_phases; 104 105 jlong _sum_of_pauses; 106 jlong _longest_pause; 107 108 public: 109 TimePartitions(); 110 ~TimePartitions(); 111 void clear(); 112 113 void report_gc_phase_start(const char* name, jlong time); 114 void report_gc_phase_end(jlong time); 115 116 int num_phases() const; 117 GCPhase* phase_at(int index) const; 118 119 jlong sum_of_pauses(); 120 jlong longest_pause(); 121 122 bool has_active_phases(); 123 private: 124 void update_statistics(GCPhase* phase); 125 }; 126 127 class PhasesIterator { 128 public: 129 virtual bool has_next() = 0; 130 virtual GCPhase* next() = 0; 131 }; 132 133 class GCTimer : public ResourceObj { 134 NOT_PRODUCT(friend class GCTimerTest;) 135 protected: 136 jlong _gc_start; 137 jlong _gc_end; 138 TimePartitions _time_partitions; 139 140 public: 141 virtual void register_gc_start(jlong time); 142 virtual void register_gc_end(jlong time); 143 144 void register_gc_phase_start(const char* name, jlong time); 145 void register_gc_phase_end(jlong time); 146 147 jlong gc_start() { return _gc_start; } 148 jlong gc_end() { return _gc_end; } 149 150 TimePartitions* time_partitions() { return &_time_partitions; } 151 152 long longest_pause(); 153 long sum_of_pauses(); 154 155 protected: 156 void register_gc_pause_start(const char* name, jlong time); 157 void register_gc_pause_end(jlong time); 158 }; 159 160 class STWGCTimer : public GCTimer { 161 public: 162 virtual void register_gc_start(jlong time); 163 virtual void register_gc_end(jlong time); 164 }; 165 166 class ConcurrentGCTimer : public GCTimer { 167 public: 168 void register_gc_pause_start(const char* name, jlong time); 169 void register_gc_pause_end(jlong time); 170 }; 171 172 class TimePartitionPhasesIterator { 173 TimePartitions* _time_partitions; 174 int _next; 175 176 public: 177 TimePartitionPhasesIterator(TimePartitions* time_partitions) : _time_partitions(time_partitions), _next(0) { } 178 179 virtual bool has_next(); 180 virtual GCPhase* next(); 181 }; 182 183 184 /////////////// Unit tests /////////////// 185 186 #ifndef PRODUCT 187 188 class GCTimerAllTest { 189 public: | 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_IMPLEMENTATION_SHARED_GCTIMER_HPP 26 #define SHARE_VM_GC_IMPLEMENTATION_SHARED_GCTIMER_HPP 27 28 #include "memory/allocation.hpp" 29 #include "prims/jni_md.h" 30 #include "utilities/macros.hpp" 31 #include "utilities/ticks.hpp" 32 33 class ConcurrentPhase; 34 class GCPhase; 35 class PausePhase; 36 37 template <class E> class GrowableArray; 38 39 class PhaseVisitor { 40 public: 41 virtual void visit(GCPhase* phase) = 0; 42 virtual void visit(PausePhase* phase) { visit((GCPhase*)phase); } 43 virtual void visit(ConcurrentPhase* phase) { visit((GCPhase*)phase); } 44 }; 45 46 class GCPhase { 47 const char* _name; 48 int _level; 49 Ticks _start; 50 Ticks _end; 51 52 public: 53 void set_name(const char* name) { _name = name; } 54 const char* name() const { return _name; } 55 56 int level() const { return _level; } 57 void set_level(int level) { _level = level; } 58 59 const Ticks start() const { return _start; } 60 void set_start(const Ticks& time) { _start = time; } 61 62 const Ticks end() const { return _end; } 63 void set_end(const Ticks& time) { _end = time; } 64 65 virtual void accept(PhaseVisitor* visitor) = 0; 66 }; 67 68 class PausePhase : public GCPhase { 69 public: 70 void accept(PhaseVisitor* visitor) { 71 visitor->visit(this); 72 } 73 }; 74 75 class ConcurrentPhase : public GCPhase { 76 void accept(PhaseVisitor* visitor) { 77 visitor->visit(this); 78 } 79 }; 80 81 class PhasesStack { 82 public: 83 // FIXME: Temporary set to 5 (used to be 4), since Reference processing needs it. 86 private: 87 int _phase_indices[PHASE_LEVELS]; 88 int _next_phase_level; 89 90 public: 91 PhasesStack() { clear(); } 92 void clear(); 93 94 void push(int phase_index); 95 int pop(); 96 int count() const; 97 }; 98 99 class TimePartitions { 100 static const int INITIAL_CAPACITY = 10; 101 102 // Currently we only support pause phases. 103 GrowableArray<PausePhase>* _phases; 104 PhasesStack _active_phases; 105 106 Tickspan _sum_of_pauses; 107 Tickspan _longest_pause; 108 109 public: 110 TimePartitions(); 111 ~TimePartitions(); 112 void clear(); 113 114 void report_gc_phase_start(const char* name, const Ticks& time = Ticks::now()); 115 void report_gc_phase_end(const Ticks& time = Ticks::now()); 116 117 int num_phases() const; 118 GCPhase* phase_at(int index) const; 119 120 const Tickspan sum_of_pauses() const { return _sum_of_pauses; } 121 const Tickspan longest_pause() const { return _longest_pause; } 122 123 bool has_active_phases(); 124 private: 125 void update_statistics(GCPhase* phase); 126 }; 127 128 class PhasesIterator { 129 public: 130 virtual bool has_next() = 0; 131 virtual GCPhase* next() = 0; 132 }; 133 134 class GCTimer : public ResourceObj { 135 NOT_PRODUCT(friend class GCTimerTest;) 136 protected: 137 Ticks _gc_start; 138 Ticks _gc_end; 139 TimePartitions _time_partitions; 140 141 public: 142 virtual void register_gc_start(const Ticks& time = Ticks::now()); 143 virtual void register_gc_end(const Ticks& time = Ticks::now()); 144 145 void register_gc_phase_start(const char* name, const Ticks& time = Ticks::now()); 146 void register_gc_phase_end(const Ticks& time = Ticks::now()); 147 148 const Ticks gc_start() const { return _gc_start; } 149 const Ticks gc_end() const { return _gc_end; } 150 151 TimePartitions* time_partitions() { return &_time_partitions; } 152 153 protected: 154 void register_gc_pause_start(const char* name, const Ticks& time = Ticks::now()); 155 void register_gc_pause_end(const Ticks& time = Ticks::now()); 156 }; 157 158 class STWGCTimer : public GCTimer { 159 public: 160 virtual void register_gc_start(const Ticks& time = Ticks::now()); 161 virtual void register_gc_end(const Ticks& time = Ticks::now()); 162 }; 163 164 class ConcurrentGCTimer : public GCTimer { 165 public: 166 void register_gc_pause_start(const char* name); 167 void register_gc_pause_end(); 168 }; 169 170 class TimePartitionPhasesIterator { 171 TimePartitions* _time_partitions; 172 int _next; 173 174 public: 175 TimePartitionPhasesIterator(TimePartitions* time_partitions) : _time_partitions(time_partitions), _next(0) { } 176 177 virtual bool has_next(); 178 virtual GCPhase* next(); 179 }; 180 181 182 /////////////// Unit tests /////////////// 183 184 #ifndef PRODUCT 185 186 class GCTimerAllTest { 187 public: |