comparison src/share/vm/gc_implementation/shared/gcTimer.cpp @ 13400:86e6d691f2e1

8028128: Add a type safe alternative for working with counter based data Reviewed-by: dholmes, egahlin
author mgronlun
date Sat, 23 Nov 2013 12:25:13 +0100
parents f2110083203d
children
comparison
equal deleted inserted replaced
13399:260ac69dc096 13400:86e6d691f2e1
23 */ 23 */
24 24
25 #include "precompiled.hpp" 25 #include "precompiled.hpp"
26 #include "gc_implementation/shared/gcTimer.hpp" 26 #include "gc_implementation/shared/gcTimer.hpp"
27 #include "utilities/growableArray.hpp" 27 #include "utilities/growableArray.hpp"
28 28 #include "utilities/ticks.inline.hpp"
29 void GCTimer::register_gc_start(jlong time) { 29
30 // the "time" parameter for most functions
31 // has a default value set by Ticks::now()
32
33 void GCTimer::register_gc_start(const Ticks& time) {
30 _time_partitions.clear(); 34 _time_partitions.clear();
31 _gc_start = time; 35 _gc_start = time;
32 } 36 }
33 37
34 void GCTimer::register_gc_end(jlong time) { 38 void GCTimer::register_gc_end(const Ticks& time) {
35 assert(!_time_partitions.has_active_phases(), 39 assert(!_time_partitions.has_active_phases(),
36 "We should have ended all started phases, before ending the GC"); 40 "We should have ended all started phases, before ending the GC");
37 41
38 _gc_end = time; 42 _gc_end = time;
39 } 43 }
40 44
41 void GCTimer::register_gc_pause_start(const char* name, jlong time) { 45 void GCTimer::register_gc_pause_start(const char* name, const Ticks& time) {
42 _time_partitions.report_gc_phase_start(name, time); 46 _time_partitions.report_gc_phase_start(name, time);
43 } 47 }
44 48
45 void GCTimer::register_gc_pause_end(jlong time) { 49 void GCTimer::register_gc_pause_end(const Ticks& time) {
46 _time_partitions.report_gc_phase_end(time); 50 _time_partitions.report_gc_phase_end(time);
47 } 51 }
48 52
49 void GCTimer::register_gc_phase_start(const char* name, jlong time) { 53 void GCTimer::register_gc_phase_start(const char* name, const Ticks& time) {
50 _time_partitions.report_gc_phase_start(name, time); 54 _time_partitions.report_gc_phase_start(name, time);
51 } 55 }
52 56
53 void GCTimer::register_gc_phase_end(jlong time) { 57 void GCTimer::register_gc_phase_end(const Ticks& time) {
54 _time_partitions.report_gc_phase_end(time); 58 _time_partitions.report_gc_phase_end(time);
55 } 59 }
56 60
57 61 void STWGCTimer::register_gc_start(const Ticks& time) {
58 void STWGCTimer::register_gc_start(jlong time) {
59 GCTimer::register_gc_start(time); 62 GCTimer::register_gc_start(time);
60 register_gc_pause_start("GC Pause", time); 63 register_gc_pause_start("GC Pause", time);
61 } 64 }
62 65
63 void STWGCTimer::register_gc_end(jlong time) { 66 void STWGCTimer::register_gc_end(const Ticks& time) {
64 register_gc_pause_end(time); 67 register_gc_pause_end(time);
65 GCTimer::register_gc_end(time); 68 GCTimer::register_gc_end(time);
66 } 69 }
67 70
68 void ConcurrentGCTimer::register_gc_pause_start(const char* name, jlong time) { 71 void ConcurrentGCTimer::register_gc_pause_start(const char* name) {
69 GCTimer::register_gc_pause_start(name, time); 72 GCTimer::register_gc_pause_start(name);
70 } 73 }
71 74
72 void ConcurrentGCTimer::register_gc_pause_end(jlong time) { 75 void ConcurrentGCTimer::register_gc_pause_end() {
73 GCTimer::register_gc_pause_end(time); 76 GCTimer::register_gc_pause_end();
74 } 77 }
75 78
76 void PhasesStack::clear() { 79 void PhasesStack::clear() {
77 _next_phase_level = 0; 80 _next_phase_level = 0;
78 } 81 }
109 } 112 }
110 113
111 void TimePartitions::clear() { 114 void TimePartitions::clear() {
112 _phases->clear(); 115 _phases->clear();
113 _active_phases.clear(); 116 _active_phases.clear();
114 _sum_of_pauses = 0; 117 _sum_of_pauses = Tickspan();
115 _longest_pause = 0; 118 _longest_pause = Tickspan();
116 } 119 }
117 120
118 void TimePartitions::report_gc_phase_start(const char* name, jlong time) { 121 void TimePartitions::report_gc_phase_start(const char* name, const Ticks& time) {
119 assert(_phases->length() <= 1000, "Too many recored phases?"); 122 assert(_phases->length() <= 1000, "Too many recored phases?");
120 123
121 int level = _active_phases.count(); 124 int level = _active_phases.count();
122 125
123 PausePhase phase; 126 PausePhase phase;
131 } 134 }
132 135
133 void TimePartitions::update_statistics(GCPhase* phase) { 136 void TimePartitions::update_statistics(GCPhase* phase) {
134 // FIXME: This should only be done for pause phases 137 // FIXME: This should only be done for pause phases
135 if (phase->level() == 0) { 138 if (phase->level() == 0) {
136 jlong pause = phase->end() - phase->start(); 139 const Tickspan pause = phase->end() - phase->start();
137 _sum_of_pauses += pause; 140 _sum_of_pauses += pause;
138 _longest_pause = MAX2(pause, _longest_pause); 141 _longest_pause = MAX2(pause, _longest_pause);
139 } 142 }
140 } 143 }
141 144
142 void TimePartitions::report_gc_phase_end(jlong time) { 145 void TimePartitions::report_gc_phase_end(const Ticks& time) {
143 int phase_index = _active_phases.pop(); 146 int phase_index = _active_phases.pop();
144 GCPhase* phase = _phases->adr_at(phase_index); 147 GCPhase* phase = _phases->adr_at(phase_index);
145 phase->set_end(time); 148 phase->set_end(time);
146 update_statistics(phase); 149 update_statistics(phase);
147 } 150 }
153 GCPhase* TimePartitions::phase_at(int index) const { 156 GCPhase* TimePartitions::phase_at(int index) const {
154 assert(index >= 0, "Out of bounds"); 157 assert(index >= 0, "Out of bounds");
155 assert(index < _phases->length(), "Out of bounds"); 158 assert(index < _phases->length(), "Out of bounds");
156 159
157 return _phases->adr_at(index); 160 return _phases->adr_at(index);
158 }
159
160 jlong TimePartitions::sum_of_pauses() {
161 return _sum_of_pauses;
162 }
163
164 jlong TimePartitions::longest_pause() {
165 return _longest_pause;
166 } 161 }
167 162
168 bool TimePartitions::has_active_phases() { 163 bool TimePartitions::has_active_phases() {
169 return _active_phases.count() > 0; 164 return _active_phases.count() > 0;
170 } 165 }
192 many_sub_pause_phases(); 187 many_sub_pause_phases();
193 many_sub_pause_phases2(); 188 many_sub_pause_phases2();
194 max_nested_pause_phases(); 189 max_nested_pause_phases();
195 } 190 }
196 191
197 static void validate_pause_phase(GCPhase* phase, int level, const char* name, jlong start, jlong end) { 192 static void validate_pause_phase(GCPhase* phase, int level, const char* name, const Ticks& start, const Ticks& end) {
198 assert(phase->level() == level, "Incorrect level"); 193 assert(phase->level() == level, "Incorrect level");
199 assert(strcmp(phase->name(), name) == 0, "Incorrect name"); 194 assert(strcmp(phase->name(), name) == 0, "Incorrect name");
200 assert(phase->start() == start, "Incorrect start"); 195 assert(phase->start() == start, "Incorrect start");
201 assert(phase->end() == end, "Incorrect end"); 196 assert(phase->end() == end, "Incorrect end");
202 } 197 }
207 time_partitions.report_gc_phase_end(8); 202 time_partitions.report_gc_phase_end(8);
208 203
209 TimePartitionPhasesIterator iter(&time_partitions); 204 TimePartitionPhasesIterator iter(&time_partitions);
210 205
211 validate_pause_phase(iter.next(), 0, "PausePhase", 2, 8); 206 validate_pause_phase(iter.next(), 0, "PausePhase", 2, 8);
212 assert(time_partitions.sum_of_pauses() == 8-2, "Incorrect"); 207 assert(time_partitions.sum_of_pauses() == Ticks(8) - Ticks(2), "Incorrect");
213 assert(time_partitions.longest_pause() == 8-2, "Incorrect"); 208 assert(time_partitions.longest_pause() == Ticks(8) - Ticks(2), "Incorrect");
214 209
215 assert(!iter.has_next(), "Too many elements"); 210 assert(!iter.has_next(), "Too many elements");
216 } 211 }
217 212
218 static void two_pauses() { 213 static void two_pauses() {
225 TimePartitionPhasesIterator iter(&time_partitions); 220 TimePartitionPhasesIterator iter(&time_partitions);
226 221
227 validate_pause_phase(iter.next(), 0, "PausePhase1", 2, 3); 222 validate_pause_phase(iter.next(), 0, "PausePhase1", 2, 3);
228 validate_pause_phase(iter.next(), 0, "PausePhase2", 4, 6); 223 validate_pause_phase(iter.next(), 0, "PausePhase2", 4, 6);
229 224
230 assert(time_partitions.sum_of_pauses() == 3, "Incorrect"); 225 assert(time_partitions.sum_of_pauses() == Ticks(3) - Ticks(0), "Incorrect");
231 assert(time_partitions.longest_pause() == 2, "Incorrect"); 226 assert(time_partitions.longest_pause() == Ticks(2) - Ticks(0), "Incorrect");
232 227
233 assert(!iter.has_next(), "Too many elements"); 228 assert(!iter.has_next(), "Too many elements");
234 } 229 }
235 230
236 static void one_sub_pause_phase() { 231 static void one_sub_pause_phase() {
243 TimePartitionPhasesIterator iter(&time_partitions); 238 TimePartitionPhasesIterator iter(&time_partitions);
244 239
245 validate_pause_phase(iter.next(), 0, "PausePhase", 2, 5); 240 validate_pause_phase(iter.next(), 0, "PausePhase", 2, 5);
246 validate_pause_phase(iter.next(), 1, "SubPhase", 3, 4); 241 validate_pause_phase(iter.next(), 1, "SubPhase", 3, 4);
247 242
248 assert(time_partitions.sum_of_pauses() == 3, "Incorrect"); 243 assert(time_partitions.sum_of_pauses() == Ticks(3) - Ticks(0), "Incorrect");
249 assert(time_partitions.longest_pause() == 3, "Incorrect"); 244 assert(time_partitions.longest_pause() == Ticks(3) - Ticks(0), "Incorrect");
250 245
251 assert(!iter.has_next(), "Too many elements"); 246 assert(!iter.has_next(), "Too many elements");
252 } 247 }
253 248
254 static void max_nested_pause_phases() { 249 static void max_nested_pause_phases() {
267 validate_pause_phase(iter.next(), 0, "PausePhase", 2, 9); 262 validate_pause_phase(iter.next(), 0, "PausePhase", 2, 9);
268 validate_pause_phase(iter.next(), 1, "SubPhase1", 3, 8); 263 validate_pause_phase(iter.next(), 1, "SubPhase1", 3, 8);
269 validate_pause_phase(iter.next(), 2, "SubPhase2", 4, 7); 264 validate_pause_phase(iter.next(), 2, "SubPhase2", 4, 7);
270 validate_pause_phase(iter.next(), 3, "SubPhase3", 5, 6); 265 validate_pause_phase(iter.next(), 3, "SubPhase3", 5, 6);
271 266
272 assert(time_partitions.sum_of_pauses() == 7, "Incorrect"); 267 assert(time_partitions.sum_of_pauses() == Ticks(7) - Ticks(0), "Incorrect");
273 assert(time_partitions.longest_pause() == 7, "Incorrect"); 268 assert(time_partitions.longest_pause() == Ticks(7) - Ticks(0), "Incorrect");
274 269
275 assert(!iter.has_next(), "Too many elements"); 270 assert(!iter.has_next(), "Too many elements");
276 } 271 }
277 272
278 static void many_sub_pause_phases() { 273 static void many_sub_pause_phases() {
296 validate_pause_phase(iter.next(), 1, "SubPhase1", 3, 4); 291 validate_pause_phase(iter.next(), 1, "SubPhase1", 3, 4);
297 validate_pause_phase(iter.next(), 1, "SubPhase2", 5, 6); 292 validate_pause_phase(iter.next(), 1, "SubPhase2", 5, 6);
298 validate_pause_phase(iter.next(), 1, "SubPhase3", 7, 8); 293 validate_pause_phase(iter.next(), 1, "SubPhase3", 7, 8);
299 validate_pause_phase(iter.next(), 1, "SubPhase4", 9, 10); 294 validate_pause_phase(iter.next(), 1, "SubPhase4", 9, 10);
300 295
301 assert(time_partitions.sum_of_pauses() == 9, "Incorrect"); 296 assert(time_partitions.sum_of_pauses() == Ticks(9) - Ticks(0), "Incorrect");
302 assert(time_partitions.longest_pause() == 9, "Incorrect"); 297 assert(time_partitions.longest_pause() == Ticks(9) - Ticks(0), "Incorrect");
303 298
304 assert(!iter.has_next(), "Too many elements"); 299 assert(!iter.has_next(), "Too many elements");
305 } 300 }
306 301
307 static void many_sub_pause_phases2() { 302 static void many_sub_pause_phases2() {
334 validate_pause_phase(iter.next(), 1, "SubPhase2", 9, 14); 329 validate_pause_phase(iter.next(), 1, "SubPhase2", 9, 14);
335 validate_pause_phase(iter.next(), 2, "SubPhase21", 10, 11); 330 validate_pause_phase(iter.next(), 2, "SubPhase21", 10, 11);
336 validate_pause_phase(iter.next(), 2, "SubPhase22", 12, 13); 331 validate_pause_phase(iter.next(), 2, "SubPhase22", 12, 13);
337 validate_pause_phase(iter.next(), 1, "SubPhase3", 15, 16); 332 validate_pause_phase(iter.next(), 1, "SubPhase3", 15, 16);
338 333
339 assert(time_partitions.sum_of_pauses() == 15, "Incorrect"); 334 assert(time_partitions.sum_of_pauses() == Ticks(15) - Ticks(0), "Incorrect");
340 assert(time_partitions.longest_pause() == 15, "Incorrect"); 335 assert(time_partitions.longest_pause() == Ticks(15) - Ticks(0), "Incorrect");
341 336
342 assert(!iter.has_next(), "Too many elements"); 337 assert(!iter.has_next(), "Too many elements");
343 } 338 }
344 }; 339 };
345 340