113 public:
114 WorkerDataArray(uint length, const char* title, bool print_sum, int log_level, uint indent_level) :
115 _title(title), _length(0), _print_sum(print_sum), _log_level(log_level), _indent_level(indent_level),
116 _has_new_data(true), _thread_work_items(NULL), _enabled(true) {
117 assert(length > 0, "Must have some workers to store data for");
118 _length = length;
119 _data = NEW_C_HEAP_ARRAY(T, _length, mtGC);
120 }
121
122 ~WorkerDataArray() {
123 FREE_C_HEAP_ARRAY(T, _data);
124 }
125
126 void link_thread_work_items(WorkerDataArray<size_t>* thread_work_items) {
127 _thread_work_items = thread_work_items;
128 }
129
130 WorkerDataArray<size_t>* thread_work_items() { return _thread_work_items; }
131
132 void set(uint worker_i, T value) {
133 assert(worker_i < _length, err_msg("Worker %d is greater than max: %d", worker_i, _length));
134 assert(_data[worker_i] == WorkerDataArray<T>::uninitialized(), err_msg("Overwriting data for worker %d in %s", worker_i, _title));
135 _data[worker_i] = value;
136 _has_new_data = true;
137 }
138
139 void set_thread_work_item(uint worker_i, size_t value) {
140 assert(_thread_work_items != NULL, "No sub count");
141 _thread_work_items->set(worker_i, value);
142 }
143
144 T get(uint worker_i) {
145 assert(worker_i < _length, err_msg("Worker %d is greater than max: %d", worker_i, _length));
146 assert(_data[worker_i] != WorkerDataArray<T>::uninitialized(), err_msg("No data added for worker %d", worker_i));
147 return _data[worker_i];
148 }
149
150 void add(uint worker_i, T value) {
151 assert(worker_i < _length, err_msg("Worker %d is greater than max: %d", worker_i, _length));
152 assert(_data[worker_i] != WorkerDataArray<T>::uninitialized(), err_msg("No data to add to for worker %d", worker_i));
153 _data[worker_i] += value;
154 _has_new_data = true;
155 }
156
157 double average(uint active_threads){
158 calculate_totals(active_threads);
159 return _average;
160 }
161
162 T sum(uint active_threads) {
163 calculate_totals(active_threads);
164 return _sum;
165 }
166
167 T minimum(uint active_threads) {
168 calculate_totals(active_threads);
169 return _min;
170 }
171
172 T maximum(uint active_threads) {
218
219 template <class T>
220 void WorkerDataArray<T>::reset() {
221 for (uint i = 0; i < _length; i++) {
222 _data[i] = WorkerDataArray<T>::uninitialized();
223 }
224 if (_thread_work_items != NULL) {
225 _thread_work_items->reset();
226 }
227 }
228
229 template <class T>
230 void WorkerDataArray<T>::verify(uint active_threads) {
231 if (!_enabled) {
232 return;
233 }
234
235 assert(active_threads <= _length, "Wrong number of active threads");
236 for (uint i = 0; i < active_threads; i++) {
237 assert(_data[i] != WorkerDataArray<T>::uninitialized(),
238 err_msg("Invalid data for worker %u in '%s'", i, _title));
239 }
240 if (_thread_work_items != NULL) {
241 _thread_work_items->verify(active_threads);
242 }
243 }
244
245 #endif
246
247 G1GCPhaseTimes::G1GCPhaseTimes(uint max_gc_threads) :
248 _max_gc_threads(max_gc_threads)
249 {
250 assert(max_gc_threads > 0, "Must have some GC threads");
251
252 _gc_par_phases[GCWorkerStart] = new WorkerDataArray<double>(max_gc_threads, "GC Worker Start (ms)", false, G1Log::LevelFiner, 2);
253 _gc_par_phases[ExtRootScan] = new WorkerDataArray<double>(max_gc_threads, "Ext Root Scanning (ms)", true, G1Log::LevelFiner, 2);
254
255 // Root scanning phases
256 _gc_par_phases[ThreadRoots] = new WorkerDataArray<double>(max_gc_threads, "Thread Roots (ms)", true, G1Log::LevelFinest, 3);
257 _gc_par_phases[StringTableRoots] = new WorkerDataArray<double>(max_gc_threads, "StringTable Roots (ms)", true, G1Log::LevelFinest, 3);
258 _gc_par_phases[UniverseRoots] = new WorkerDataArray<double>(max_gc_threads, "Universe Roots (ms)", true, G1Log::LevelFinest, 3);
462 }
463 buf.print_cr();
464 }
465
466 void print_count_values(LineBuffer& buf, G1GCPhaseTimes::GCParPhases phase_id, WorkerDataArray<size_t>* thread_work_items) {
467 uint active_length = _phase_times->_active_gc_threads;
468 for (uint i = 0; i < active_length; ++i) {
469 buf.append(" " SIZE_FORMAT, _phase_times->get_thread_work_item(phase_id, i));
470 }
471 buf.print_cr();
472 }
473
474 void print_thread_work_items(G1GCPhaseTimes::GCParPhases phase_id, WorkerDataArray<size_t>* thread_work_items) {
475 LineBuffer buf(thread_work_items->_indent_level);
476 buf.append("[%s:", thread_work_items->_title);
477
478 if (G1Log::finest()) {
479 print_count_values(buf, phase_id, thread_work_items);
480 }
481
482 assert(thread_work_items->_print_sum, err_msg("%s does not have print sum true even though it is a count", thread_work_items->_title));
483
484 buf.append_and_print_cr(" Min: " SIZE_FORMAT ", Avg: %.1lf, Max: " SIZE_FORMAT ", Diff: " SIZE_FORMAT ", Sum: " SIZE_FORMAT "]",
485 _phase_times->min_thread_work_items(phase_id), _phase_times->average_thread_work_items(phase_id), _phase_times->max_thread_work_items(phase_id),
486 _phase_times->max_thread_work_items(phase_id) - _phase_times->min_thread_work_items(phase_id), _phase_times->sum_thread_work_items(phase_id));
487 }
488
489 void print_multi_length(G1GCPhaseTimes::GCParPhases phase_id, WorkerDataArray<double>* phase) {
490 LineBuffer buf(phase->_indent_level);
491 buf.append("[%s:", phase->_title);
492
493 if (G1Log::finest()) {
494 print_time_values(buf, phase_id, phase);
495 }
496
497 buf.append(" Min: %.1lf, Avg: %.1lf, Max: %.1lf, Diff: %.1lf",
498 _phase_times->min_time_ms(phase_id), _phase_times->average_time_ms(phase_id), _phase_times->max_time_ms(phase_id),
499 _phase_times->max_time_ms(phase_id) - _phase_times->min_time_ms(phase_id));
500
501 if (phase->_print_sum) {
502 // for things like the start and end times the sum is not
|
113 public:
114 WorkerDataArray(uint length, const char* title, bool print_sum, int log_level, uint indent_level) :
115 _title(title), _length(0), _print_sum(print_sum), _log_level(log_level), _indent_level(indent_level),
116 _has_new_data(true), _thread_work_items(NULL), _enabled(true) {
117 assert(length > 0, "Must have some workers to store data for");
118 _length = length;
119 _data = NEW_C_HEAP_ARRAY(T, _length, mtGC);
120 }
121
122 ~WorkerDataArray() {
123 FREE_C_HEAP_ARRAY(T, _data);
124 }
125
126 void link_thread_work_items(WorkerDataArray<size_t>* thread_work_items) {
127 _thread_work_items = thread_work_items;
128 }
129
130 WorkerDataArray<size_t>* thread_work_items() { return _thread_work_items; }
131
132 void set(uint worker_i, T value) {
133 assert(worker_i < _length, "Worker %d is greater than max: %d", worker_i, _length);
134 assert(_data[worker_i] == WorkerDataArray<T>::uninitialized(), "Overwriting data for worker %d in %s", worker_i, _title);
135 _data[worker_i] = value;
136 _has_new_data = true;
137 }
138
139 void set_thread_work_item(uint worker_i, size_t value) {
140 assert(_thread_work_items != NULL, "No sub count");
141 _thread_work_items->set(worker_i, value);
142 }
143
144 T get(uint worker_i) {
145 assert(worker_i < _length, "Worker %d is greater than max: %d", worker_i, _length);
146 assert(_data[worker_i] != WorkerDataArray<T>::uninitialized(), "No data added for worker %d", worker_i);
147 return _data[worker_i];
148 }
149
150 void add(uint worker_i, T value) {
151 assert(worker_i < _length, "Worker %d is greater than max: %d", worker_i, _length);
152 assert(_data[worker_i] != WorkerDataArray<T>::uninitialized(), "No data to add to for worker %d", worker_i);
153 _data[worker_i] += value;
154 _has_new_data = true;
155 }
156
157 double average(uint active_threads){
158 calculate_totals(active_threads);
159 return _average;
160 }
161
162 T sum(uint active_threads) {
163 calculate_totals(active_threads);
164 return _sum;
165 }
166
167 T minimum(uint active_threads) {
168 calculate_totals(active_threads);
169 return _min;
170 }
171
172 T maximum(uint active_threads) {
218
219 template <class T>
220 void WorkerDataArray<T>::reset() {
221 for (uint i = 0; i < _length; i++) {
222 _data[i] = WorkerDataArray<T>::uninitialized();
223 }
224 if (_thread_work_items != NULL) {
225 _thread_work_items->reset();
226 }
227 }
228
229 template <class T>
230 void WorkerDataArray<T>::verify(uint active_threads) {
231 if (!_enabled) {
232 return;
233 }
234
235 assert(active_threads <= _length, "Wrong number of active threads");
236 for (uint i = 0; i < active_threads; i++) {
237 assert(_data[i] != WorkerDataArray<T>::uninitialized(),
238 "Invalid data for worker %u in '%s'", i, _title);
239 }
240 if (_thread_work_items != NULL) {
241 _thread_work_items->verify(active_threads);
242 }
243 }
244
245 #endif
246
247 G1GCPhaseTimes::G1GCPhaseTimes(uint max_gc_threads) :
248 _max_gc_threads(max_gc_threads)
249 {
250 assert(max_gc_threads > 0, "Must have some GC threads");
251
252 _gc_par_phases[GCWorkerStart] = new WorkerDataArray<double>(max_gc_threads, "GC Worker Start (ms)", false, G1Log::LevelFiner, 2);
253 _gc_par_phases[ExtRootScan] = new WorkerDataArray<double>(max_gc_threads, "Ext Root Scanning (ms)", true, G1Log::LevelFiner, 2);
254
255 // Root scanning phases
256 _gc_par_phases[ThreadRoots] = new WorkerDataArray<double>(max_gc_threads, "Thread Roots (ms)", true, G1Log::LevelFinest, 3);
257 _gc_par_phases[StringTableRoots] = new WorkerDataArray<double>(max_gc_threads, "StringTable Roots (ms)", true, G1Log::LevelFinest, 3);
258 _gc_par_phases[UniverseRoots] = new WorkerDataArray<double>(max_gc_threads, "Universe Roots (ms)", true, G1Log::LevelFinest, 3);
462 }
463 buf.print_cr();
464 }
465
466 void print_count_values(LineBuffer& buf, G1GCPhaseTimes::GCParPhases phase_id, WorkerDataArray<size_t>* thread_work_items) {
467 uint active_length = _phase_times->_active_gc_threads;
468 for (uint i = 0; i < active_length; ++i) {
469 buf.append(" " SIZE_FORMAT, _phase_times->get_thread_work_item(phase_id, i));
470 }
471 buf.print_cr();
472 }
473
474 void print_thread_work_items(G1GCPhaseTimes::GCParPhases phase_id, WorkerDataArray<size_t>* thread_work_items) {
475 LineBuffer buf(thread_work_items->_indent_level);
476 buf.append("[%s:", thread_work_items->_title);
477
478 if (G1Log::finest()) {
479 print_count_values(buf, phase_id, thread_work_items);
480 }
481
482 assert(thread_work_items->_print_sum, "%s does not have print sum true even though it is a count", thread_work_items->_title);
483
484 buf.append_and_print_cr(" Min: " SIZE_FORMAT ", Avg: %.1lf, Max: " SIZE_FORMAT ", Diff: " SIZE_FORMAT ", Sum: " SIZE_FORMAT "]",
485 _phase_times->min_thread_work_items(phase_id), _phase_times->average_thread_work_items(phase_id), _phase_times->max_thread_work_items(phase_id),
486 _phase_times->max_thread_work_items(phase_id) - _phase_times->min_thread_work_items(phase_id), _phase_times->sum_thread_work_items(phase_id));
487 }
488
489 void print_multi_length(G1GCPhaseTimes::GCParPhases phase_id, WorkerDataArray<double>* phase) {
490 LineBuffer buf(phase->_indent_level);
491 buf.append("[%s:", phase->_title);
492
493 if (G1Log::finest()) {
494 print_time_values(buf, phase_id, phase);
495 }
496
497 buf.append(" Min: %.1lf, Avg: %.1lf, Max: %.1lf, Diff: %.1lf",
498 _phase_times->min_time_ms(phase_id), _phase_times->average_time_ms(phase_id), _phase_times->max_time_ms(phase_id),
499 _phase_times->max_time_ms(phase_id) - _phase_times->min_time_ms(phase_id));
500
501 if (phase->_print_sum) {
502 // for things like the start and end times the sum is not
|