22 *
23 */
24
25 #ifndef SHARE_VM_GC_SHARED_GCTIMER_HPP
26 #define SHARE_VM_GC_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.
84 static const int PHASE_LEVELS = 5;
85
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);
115 void report_gc_phase_end(const Ticks& time);
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());
145 void register_gc_phase_start(const char* name, const Ticks& time);
146 void register_gc_phase_end(const Ticks& time);
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:
|
22 *
23 */
24
25 #ifndef SHARE_VM_GC_SHARED_GCTIMER_HPP
26 #define SHARE_VM_GC_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 };
43
44 class GCPhase {
45 public:
46 enum PhaseType {
47 PausePhaseType = 0,
48 ConcurrentPhaseType = 1
49 };
50
51 private:
52 const char* _name;
53 int _level;
54 Ticks _start;
55 Ticks _end;
56 PhaseType _type;
57
58 public:
59 void set_name(const char* name) { _name = name; }
60 const char* name() const { return _name; }
61
62 int level() const { return _level; }
63 void set_level(int level) { _level = level; }
64
65 const Ticks start() const { return _start; }
66 void set_start(const Ticks& time) { _start = time; }
67
68 const Ticks end() const { return _end; }
69 void set_end(const Ticks& time) { _end = time; }
70
71 PhaseType type() const { return _type; }
72 void set_type(PhaseType type) { _type = type; }
73
74 void accept(PhaseVisitor* visitor) {
75 visitor->visit(this);
76 }
77 };
78
79 class PhasesStack {
80 public:
81 // Set to 5, since Reference processing needs it.
82 static const int PHASE_LEVELS = 5;
83
84 private:
85 int _phase_indices[PHASE_LEVELS];
86 int _next_phase_level;
87
88 public:
89 PhasesStack() { clear(); }
90 void clear();
91
92 void push(int phase_index);
93 int pop();
94 int count() const;
95 };
96
97 class TimePartitions {
98 static const int INITIAL_CAPACITY = 10;
99
100 GrowableArray<GCPhase>* _phases;
101 PhasesStack _active_phases;
102
103 Tickspan _sum_of_pauses;
104 Tickspan _longest_pause;
105
106 public:
107 TimePartitions();
108 ~TimePartitions();
109 void clear();
110
111 void report_gc_phase_start(const char* name, const Ticks& time, GCPhase::PhaseType type=GCPhase::PausePhaseType);
112 void report_gc_phase_end(const Ticks& time, GCPhase::PhaseType type=GCPhase::PausePhaseType);
113
114 int num_phases() const;
115 GCPhase* phase_at(int index) const;
116
117 const Tickspan sum_of_pauses() const { return _sum_of_pauses; }
118 const Tickspan longest_pause() const { return _longest_pause; }
119
120 bool has_active_phases();
121
122 private:
123 void update_statistics(GCPhase* phase);
124 };
125
126 class PhasesIterator {
127 public:
128 virtual bool has_next() = 0;
129 virtual GCPhase* next() = 0;
130 };
131
132 class GCTimer : public ResourceObj {
133 NOT_PRODUCT(friend class GCTimerTest;)
134 protected:
135 Ticks _gc_start;
136 Ticks _gc_end;
137 TimePartitions _time_partitions;
138
139 public:
140 virtual void register_gc_start(const Ticks& time = Ticks::now());
141 virtual void register_gc_end(const Ticks& time = Ticks::now());
143 void register_gc_phase_start(const char* name, const Ticks& time);
144 void register_gc_phase_end(const Ticks& time);
145
146 const Ticks gc_start() const { return _gc_start; }
147 const Ticks gc_end() const { return _gc_end; }
148
149 TimePartitions* time_partitions() { return &_time_partitions; }
150
151 protected:
152 void register_gc_pause_start(const char* name, const Ticks& time = Ticks::now());
153 void register_gc_pause_end(const Ticks& time = Ticks::now());
154 };
155
156 class STWGCTimer : public GCTimer {
157 public:
158 virtual void register_gc_start(const Ticks& time = Ticks::now());
159 virtual void register_gc_end(const Ticks& time = Ticks::now());
160 };
161
162 class ConcurrentGCTimer : public GCTimer {
163 // ConcurrentGCTimer can't be used if there is an overlap between a pause phase and a concurrent phase.
164 // _is_concurrent_phase_active is used to find above case.
165 bool _is_concurrent_phase_active;
166
167 public:
168 ConcurrentGCTimer(): GCTimer(), _is_concurrent_phase_active(false) {};
169
170 void register_gc_pause_start(const char* name);
171 void register_gc_pause_end();
172
173 void register_gc_concurrent_start(const char* name, const Ticks& time = Ticks::now());
174 void register_gc_concurrent_end(const Ticks& time = Ticks::now());
175 };
176
177 class TimePartitionPhasesIterator {
178 TimePartitions* _time_partitions;
179 int _next;
180
181 public:
182 TimePartitionPhasesIterator(TimePartitions* time_partitions) : _time_partitions(time_partitions), _next(0) { }
183
184 virtual bool has_next();
185 virtual GCPhase* next();
186 };
187
188
189 /////////////// Unit tests ///////////////
190
191 #ifndef PRODUCT
192
193 class GCTimerAllTest {
194 public:
|