src/share/vm/gc_implementation/g1/g1GCPhaseTimes.cpp

Sat, 06 Oct 2012 01:17:44 -0700

author
johnc
date
Sat, 06 Oct 2012 01:17:44 -0700
changeset 4173
8a5ea0a9ccc4
parent 4097
5baec2e69518
child 4475
7df93f7c14a5
permissions
-rw-r--r--

7127708: G1: change task num types from int to uint in concurrent mark
Summary: Change the type of various task num fields, parameters etc to unsigned and rename them to be more consistent with the other collectors. Code changes were also reviewed by Vitaly Davidovich.
Reviewed-by: johnc
Contributed-by: Kaushik Srenevasan <kaushik@twitter.com>

brutisso@3923 1 /*
brutisso@3923 2 * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
brutisso@3923 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
brutisso@3923 4 *
brutisso@3923 5 * This code is free software; you can redistribute it and/or modify it
brutisso@3923 6 * under the terms of the GNU General Public License version 2 only, as
brutisso@3923 7 * published by the Free Software Foundation.
brutisso@3923 8 *
brutisso@3923 9 * This code is distributed in the hope that it will be useful, but WITHOUT
brutisso@3923 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
brutisso@3923 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
brutisso@3923 12 * version 2 for more details (a copy is included in the LICENSE file that
brutisso@3923 13 * accompanied this code).
brutisso@3923 14 *
brutisso@3923 15 * You should have received a copy of the GNU General Public License version
brutisso@3923 16 * 2 along with this work; if not, write to the Free Software Foundation,
brutisso@3923 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
brutisso@3923 18 *
brutisso@3923 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
brutisso@3923 20 * or visit www.oracle.com if you need additional information or have any
brutisso@3923 21 * questions.
brutisso@3923 22 *
brutisso@3923 23 */
brutisso@3923 24
brutisso@3923 25
brutisso@3923 26 #include "precompiled.hpp"
brutisso@3923 27 #include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
brutisso@3923 28 #include "gc_implementation/g1/g1GCPhaseTimes.hpp"
brutisso@3923 29 #include "gc_implementation/g1/g1Log.hpp"
brutisso@3923 30
brutisso@3923 31 // Helper class for avoiding interleaved logging
brutisso@3923 32 class LineBuffer: public StackObj {
brutisso@3923 33
brutisso@3923 34 private:
brutisso@3923 35 static const int BUFFER_LEN = 1024;
brutisso@3923 36 static const int INDENT_CHARS = 3;
brutisso@3923 37 char _buffer[BUFFER_LEN];
brutisso@3923 38 int _indent_level;
brutisso@3923 39 int _cur;
brutisso@3923 40
brutisso@3923 41 void vappend(const char* format, va_list ap) {
brutisso@3923 42 int res = vsnprintf(&_buffer[_cur], BUFFER_LEN - _cur, format, ap);
brutisso@3923 43 if (res != -1) {
brutisso@3923 44 _cur += res;
brutisso@3923 45 } else {
brutisso@3923 46 DEBUG_ONLY(warning("buffer too small in LineBuffer");)
brutisso@3923 47 _buffer[BUFFER_LEN -1] = 0;
brutisso@3923 48 _cur = BUFFER_LEN; // vsnprintf above should not add to _buffer if we are called again
brutisso@3923 49 }
brutisso@3923 50 }
brutisso@3923 51
brutisso@3923 52 public:
brutisso@3923 53 explicit LineBuffer(int indent_level): _indent_level(indent_level), _cur(0) {
brutisso@3923 54 for (; (_cur < BUFFER_LEN && _cur < (_indent_level * INDENT_CHARS)); _cur++) {
brutisso@3923 55 _buffer[_cur] = ' ';
brutisso@3923 56 }
brutisso@3923 57 }
brutisso@3923 58
brutisso@3923 59 #ifndef PRODUCT
brutisso@3923 60 ~LineBuffer() {
brutisso@3923 61 assert(_cur == _indent_level * INDENT_CHARS, "pending data in buffer - append_and_print_cr() not called?");
brutisso@3923 62 }
brutisso@3923 63 #endif
brutisso@3923 64
brutisso@3923 65 void append(const char* format, ...) {
brutisso@3923 66 va_list ap;
brutisso@3923 67 va_start(ap, format);
brutisso@3923 68 vappend(format, ap);
brutisso@3923 69 va_end(ap);
brutisso@3923 70 }
brutisso@3923 71
brutisso@3923 72 void append_and_print_cr(const char* format, ...) {
brutisso@3923 73 va_list ap;
brutisso@3923 74 va_start(ap, format);
brutisso@3923 75 vappend(format, ap);
brutisso@3923 76 va_end(ap);
brutisso@3923 77 gclog_or_tty->print_cr("%s", _buffer);
brutisso@3923 78 _cur = _indent_level * INDENT_CHARS;
brutisso@3923 79 }
brutisso@3923 80 };
brutisso@3923 81
brutisso@4015 82 template <class T>
brutisso@4015 83 void WorkerDataArray<T>::print(int level, const char* title) {
brutisso@4015 84 if (_length == 1) {
brutisso@4015 85 // No need for min, max, average and sum for only one worker
brutisso@4015 86 LineBuffer buf(level);
brutisso@4015 87 buf.append("[%s: ", title);
brutisso@4015 88 buf.append(_print_format, _data[0]);
brutisso@4015 89 buf.append_and_print_cr("]");
brutisso@4015 90 return;
brutisso@4015 91 }
brutisso@4015 92
brutisso@4015 93 T min = _data[0];
brutisso@4015 94 T max = _data[0];
brutisso@4015 95 T sum = 0;
brutisso@4015 96
brutisso@4015 97 LineBuffer buf(level);
brutisso@4015 98 buf.append("[%s:", title);
brutisso@4015 99 for (uint i = 0; i < _length; ++i) {
brutisso@4015 100 T val = _data[i];
brutisso@4015 101 min = MIN2(val, min);
brutisso@4015 102 max = MAX2(val, max);
brutisso@4015 103 sum += val;
brutisso@4015 104 if (G1Log::finest()) {
brutisso@4015 105 buf.append(" ");
brutisso@4015 106 buf.append(_print_format, val);
brutisso@4015 107 }
brutisso@4015 108 }
brutisso@4015 109
brutisso@4015 110 if (G1Log::finest()) {
brutisso@4015 111 buf.append_and_print_cr("");
brutisso@4015 112 }
brutisso@4015 113
brutisso@4015 114 double avg = (double)sum / (double)_length;
brutisso@4015 115 buf.append(" Min: ");
brutisso@4015 116 buf.append(_print_format, min);
brutisso@4015 117 buf.append(", Avg: ");
brutisso@4015 118 buf.append("%.1lf", avg); // Always print average as a double
brutisso@4015 119 buf.append(", Max: ");
brutisso@4015 120 buf.append(_print_format, max);
brutisso@4015 121 buf.append(", Diff: ");
brutisso@4015 122 buf.append(_print_format, max - min);
brutisso@4015 123 if (_print_sum) {
brutisso@4015 124 // for things like the start and end times the sum is not
brutisso@4015 125 // that relevant
brutisso@4015 126 buf.append(", Sum: ");
brutisso@4015 127 buf.append(_print_format, sum);
brutisso@4015 128 }
brutisso@4015 129 buf.append_and_print_cr("]");
brutisso@4015 130 }
brutisso@4015 131
jmasa@4097 132 #ifndef PRODUCT
brutisso@4015 133
brutisso@4015 134 template <class T>
brutisso@4015 135 void WorkerDataArray<T>::reset() {
brutisso@4015 136 for (uint i = 0; i < _length; i++) {
brutisso@4015 137 _data[i] = (T)-1;
brutisso@4015 138 }
brutisso@4015 139 }
brutisso@4015 140
brutisso@4015 141 template <class T>
brutisso@4015 142 void WorkerDataArray<T>::verify() {
brutisso@4015 143 for (uint i = 0; i < _length; i++) {
brutisso@4015 144 assert(_data[i] >= (T)0, err_msg("Invalid data for worker %d", i));
brutisso@4015 145 }
brutisso@4015 146 }
brutisso@4015 147
brutisso@4015 148 #endif
brutisso@4015 149
brutisso@3923 150 G1GCPhaseTimes::G1GCPhaseTimes(uint max_gc_threads) :
brutisso@3923 151 _max_gc_threads(max_gc_threads),
brutisso@3923 152 _min_clear_cc_time_ms(-1.0),
brutisso@3923 153 _max_clear_cc_time_ms(-1.0),
brutisso@3923 154 _cur_clear_cc_time_ms(0.0),
brutisso@3923 155 _cum_clear_cc_time_ms(0.0),
brutisso@4015 156 _num_cc_clears(0L),
brutisso@4015 157 _last_gc_worker_start_times_ms(_max_gc_threads, "%.1lf", false),
brutisso@4015 158 _last_ext_root_scan_times_ms(_max_gc_threads, "%.1lf"),
brutisso@4015 159 _last_satb_filtering_times_ms(_max_gc_threads, "%.1lf"),
brutisso@4015 160 _last_update_rs_times_ms(_max_gc_threads, "%.1lf"),
brutisso@4015 161 _last_update_rs_processed_buffers(_max_gc_threads, "%d"),
brutisso@4015 162 _last_scan_rs_times_ms(_max_gc_threads, "%.1lf"),
brutisso@4015 163 _last_obj_copy_times_ms(_max_gc_threads, "%.1lf"),
brutisso@4015 164 _last_termination_times_ms(_max_gc_threads, "%.1lf"),
brutisso@4015 165 _last_termination_attempts(_max_gc_threads, SIZE_FORMAT),
brutisso@4015 166 _last_gc_worker_end_times_ms(_max_gc_threads, "%.1lf", false),
brutisso@4015 167 _last_gc_worker_times_ms(_max_gc_threads, "%.1lf"),
brutisso@4015 168 _last_gc_worker_other_times_ms(_max_gc_threads, "%.1lf")
brutisso@3923 169 {
brutisso@3923 170 assert(max_gc_threads > 0, "Must have some GC threads");
brutisso@3923 171 }
brutisso@3923 172
brutisso@4015 173 void G1GCPhaseTimes::note_gc_start(uint active_gc_threads) {
brutisso@3923 174 assert(active_gc_threads > 0, "The number of threads must be > 0");
brutisso@3923 175 assert(active_gc_threads <= _max_gc_threads, "The number of active threads must be <= the max nubmer of threads");
brutisso@3923 176 _active_gc_threads = active_gc_threads;
brutisso@3923 177
brutisso@4015 178 _last_gc_worker_start_times_ms.reset();
brutisso@4015 179 _last_ext_root_scan_times_ms.reset();
brutisso@4015 180 _last_satb_filtering_times_ms.reset();
brutisso@4015 181 _last_update_rs_times_ms.reset();
brutisso@4015 182 _last_update_rs_processed_buffers.reset();
brutisso@4015 183 _last_scan_rs_times_ms.reset();
brutisso@4015 184 _last_obj_copy_times_ms.reset();
brutisso@4015 185 _last_termination_times_ms.reset();
brutisso@4015 186 _last_termination_attempts.reset();
brutisso@4015 187 _last_gc_worker_end_times_ms.reset();
brutisso@4015 188 _last_gc_worker_times_ms.reset();
brutisso@4015 189 _last_gc_worker_other_times_ms.reset();
brutisso@3923 190 }
brutisso@3923 191
brutisso@4015 192 void G1GCPhaseTimes::note_gc_end() {
brutisso@4015 193 _last_gc_worker_start_times_ms.verify();
brutisso@4015 194 _last_ext_root_scan_times_ms.verify();
brutisso@4015 195 _last_satb_filtering_times_ms.verify();
brutisso@4015 196 _last_update_rs_times_ms.verify();
brutisso@4015 197 _last_update_rs_processed_buffers.verify();
brutisso@4015 198 _last_scan_rs_times_ms.verify();
brutisso@4015 199 _last_obj_copy_times_ms.verify();
brutisso@4015 200 _last_termination_times_ms.verify();
brutisso@4015 201 _last_termination_attempts.verify();
brutisso@4015 202 _last_gc_worker_end_times_ms.verify();
brutisso@3923 203
brutisso@3923 204 for (uint i = 0; i < _active_gc_threads; i++) {
brutisso@4015 205 double worker_time = _last_gc_worker_end_times_ms.get(i) - _last_gc_worker_start_times_ms.get(i);
brutisso@4015 206 _last_gc_worker_times_ms.set(i, worker_time);
brutisso@3923 207
brutisso@4015 208 double worker_known_time = _last_ext_root_scan_times_ms.get(i) +
brutisso@4015 209 _last_satb_filtering_times_ms.get(i) +
brutisso@4015 210 _last_update_rs_times_ms.get(i) +
brutisso@4015 211 _last_scan_rs_times_ms.get(i) +
brutisso@4015 212 _last_obj_copy_times_ms.get(i) +
brutisso@4015 213 _last_termination_times_ms.get(i);
brutisso@3923 214
brutisso@4015 215 double worker_other_time = worker_time - worker_known_time;
brutisso@4015 216 _last_gc_worker_other_times_ms.set(i, worker_other_time);
brutisso@3923 217 }
brutisso@3923 218
brutisso@4015 219 _last_gc_worker_times_ms.verify();
brutisso@4015 220 _last_gc_worker_other_times_ms.verify();
brutisso@3923 221 }
brutisso@3923 222
brutisso@3923 223 void G1GCPhaseTimes::print_stats(int level, const char* str, double value) {
brutisso@3923 224 LineBuffer(level).append_and_print_cr("[%s: %.1lf ms]", str, value);
brutisso@3923 225 }
brutisso@3923 226
brutisso@3923 227 void G1GCPhaseTimes::print_stats(int level, const char* str, double value, int workers) {
brutisso@3923 228 LineBuffer(level).append_and_print_cr("[%s: %.1lf ms, GC Workers: %d]", str, value, workers);
brutisso@3923 229 }
brutisso@3923 230
brutisso@3923 231 double G1GCPhaseTimes::accounted_time_ms() {
brutisso@3923 232 // Subtract the root region scanning wait time. It's initialized to
brutisso@3923 233 // zero at the start of the pause.
brutisso@3923 234 double misc_time_ms = _root_region_scan_wait_time_ms;
brutisso@3923 235
brutisso@3923 236 misc_time_ms += _cur_collection_par_time_ms;
brutisso@3923 237
brutisso@3923 238 // Now subtract the time taken to fix up roots in generated code
brutisso@3923 239 misc_time_ms += _cur_collection_code_root_fixup_time_ms;
brutisso@3923 240
brutisso@3923 241 // Subtract the time taken to clean the card table from the
brutisso@3923 242 // current value of "other time"
brutisso@3923 243 misc_time_ms += _cur_clear_ct_time_ms;
brutisso@3923 244
brutisso@3923 245 return misc_time_ms;
brutisso@3923 246 }
brutisso@3923 247
brutisso@4015 248 void G1GCPhaseTimes::print(double pause_time_sec) {
brutisso@3923 249 if (_root_region_scan_wait_time_ms > 0.0) {
brutisso@3923 250 print_stats(1, "Root Region Scan Waiting", _root_region_scan_wait_time_ms);
brutisso@3923 251 }
brutisso@3923 252 if (G1CollectedHeap::use_parallel_gc_threads()) {
brutisso@3923 253 print_stats(1, "Parallel Time", _cur_collection_par_time_ms, _active_gc_threads);
brutisso@4015 254 _last_gc_worker_start_times_ms.print(2, "GC Worker Start (ms)");
brutisso@4015 255 _last_ext_root_scan_times_ms.print(2, "Ext Root Scanning (ms)");
brutisso@4015 256 if (_last_satb_filtering_times_ms.sum() > 0.0) {
brutisso@4015 257 _last_satb_filtering_times_ms.print(2, "SATB Filtering (ms)");
brutisso@3923 258 }
brutisso@4015 259 _last_update_rs_times_ms.print(2, "Update RS (ms)");
brutisso@4015 260 _last_update_rs_processed_buffers.print(3, "Processed Buffers");
brutisso@4015 261 _last_scan_rs_times_ms.print(2, "Scan RS (ms)");
brutisso@4015 262 _last_obj_copy_times_ms.print(2, "Object Copy (ms)");
brutisso@4015 263 _last_termination_times_ms.print(2, "Termination (ms)");
brutisso@3923 264 if (G1Log::finest()) {
brutisso@4015 265 _last_termination_attempts.print(3, "Termination Attempts");
brutisso@3923 266 }
brutisso@4015 267 _last_gc_worker_other_times_ms.print(2, "GC Worker Other (ms)");
brutisso@4015 268 _last_gc_worker_times_ms.print(2, "GC Worker Total (ms)");
brutisso@4015 269 _last_gc_worker_end_times_ms.print(2, "GC Worker End (ms)");
brutisso@4015 270 } else {
brutisso@4015 271 _last_ext_root_scan_times_ms.print(1, "Ext Root Scanning (ms)");
brutisso@4015 272 if (_last_satb_filtering_times_ms.sum() > 0.0) {
brutisso@4015 273 _last_satb_filtering_times_ms.print(1, "SATB Filtering (ms)");
brutisso@3923 274 }
brutisso@4015 275 _last_update_rs_times_ms.print(1, "Update RS (ms)");
brutisso@4015 276 _last_update_rs_processed_buffers.print(2, "Processed Buffers");
brutisso@4015 277 _last_scan_rs_times_ms.print(1, "Scan RS (ms)");
brutisso@4015 278 _last_obj_copy_times_ms.print(1, "Object Copy (ms)");
brutisso@3923 279 }
brutisso@3923 280 print_stats(1, "Code Root Fixup", _cur_collection_code_root_fixup_time_ms);
brutisso@3923 281 print_stats(1, "Clear CT", _cur_clear_ct_time_ms);
brutisso@3923 282 if (Verbose && G1Log::finest()) {
brutisso@3923 283 print_stats(1, "Cur Clear CC", _cur_clear_cc_time_ms);
brutisso@3923 284 print_stats(1, "Cum Clear CC", _cum_clear_cc_time_ms);
brutisso@3923 285 print_stats(1, "Min Clear CC", _min_clear_cc_time_ms);
brutisso@3923 286 print_stats(1, "Max Clear CC", _max_clear_cc_time_ms);
brutisso@3923 287 if (_num_cc_clears > 0) {
brutisso@3923 288 print_stats(1, "Avg Clear CC", _cum_clear_cc_time_ms / ((double)_num_cc_clears));
brutisso@3923 289 }
brutisso@3923 290 }
brutisso@4015 291 double misc_time_ms = pause_time_sec * MILLIUNITS - accounted_time_ms();
brutisso@3923 292 print_stats(1, "Other", misc_time_ms);
brutisso@4015 293 if (_cur_verify_before_time_ms > 0.0) {
brutisso@4015 294 print_stats(2, "Verify Before", _cur_verify_before_time_ms);
brutisso@4015 295 }
brutisso@3923 296 print_stats(2, "Choose CSet",
brutisso@3923 297 (_recorded_young_cset_choice_time_ms +
brutisso@3923 298 _recorded_non_young_cset_choice_time_ms));
brutisso@3923 299 print_stats(2, "Ref Proc", _cur_ref_proc_time_ms);
brutisso@3923 300 print_stats(2, "Ref Enq", _cur_ref_enq_time_ms);
brutisso@3923 301 print_stats(2, "Free CSet",
brutisso@3923 302 (_recorded_young_free_cset_time_ms +
brutisso@3923 303 _recorded_non_young_free_cset_time_ms));
brutisso@4015 304 if (_cur_verify_after_time_ms > 0.0) {
brutisso@4015 305 print_stats(2, "Verify After", _cur_verify_after_time_ms);
brutisso@4015 306 }
brutisso@3923 307 }
brutisso@3923 308
brutisso@3923 309 void G1GCPhaseTimes::record_cc_clear_time_ms(double ms) {
brutisso@3923 310 if (!(Verbose && G1Log::finest())) {
brutisso@3923 311 return;
brutisso@3923 312 }
brutisso@3923 313
brutisso@3923 314 if (_min_clear_cc_time_ms < 0.0 || ms <= _min_clear_cc_time_ms) {
brutisso@3923 315 _min_clear_cc_time_ms = ms;
brutisso@3923 316 }
brutisso@3923 317 if (_max_clear_cc_time_ms < 0.0 || ms >= _max_clear_cc_time_ms) {
brutisso@3923 318 _max_clear_cc_time_ms = ms;
brutisso@3923 319 }
brutisso@3923 320 _cur_clear_cc_time_ms = ms;
brutisso@3923 321 _cum_clear_cc_time_ms += ms;
brutisso@3923 322 _num_cc_clears++;
brutisso@3923 323 }

mercurial