< prev index next >

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

Print this page




 115 
 116     double worker_known_time =
 117         _gc_par_phases[ExtRootScan]->get(i) +
 118         _gc_par_phases[SATBFiltering]->get(i) +
 119         _gc_par_phases[UpdateRS]->get(i) +
 120         _gc_par_phases[ScanRS]->get(i) +
 121         _gc_par_phases[CodeRoots]->get(i) +
 122         _gc_par_phases[ObjCopy]->get(i) +
 123         _gc_par_phases[Termination]->get(i);
 124 
 125     record_time_secs(Other, i, worker_time - worker_known_time);
 126   }
 127 
 128   for (int i = 0; i < GCParPhasesSentinel; i++) {
 129     if (_gc_par_phases[i] != NULL) {
 130       _gc_par_phases[i]->verify(_active_gc_threads);
 131     }
 132   }
 133 }
 134 
 135 double G1GCPhaseTimes::info_line(const char* str, double value) {
 136   log_info(gc, phases)("%s%s: %.1lfms", Indents[1], str, value);
 137   return value;
 138 }
 139 
 140 void G1GCPhaseTimes::debug_line(const char* str, double value) {
 141   log_debug(gc, phases)("%s%s: %.1lfms", Indents[2], str, value);
 142 }
 143 
 144 void G1GCPhaseTimes::trace_line(const char* str, double value) {
 145   log_trace(gc, phases)("%s%s: %.1lfms", Indents[3], str, value);
 146 }
 147 
 148 void G1GCPhaseTimes::trace_line(const char* str, size_t value) {
 149   log_trace(gc, phases)("%s%s: " SIZE_FORMAT, Indents[3], str, value);
 150 }
 151 
 152 void G1GCPhaseTimes::trace_phase_tasks(const char* indent, G1GCPhaseTimes::GCParPhases phase_id) {
 153   LogHandle(gc, phases, task) log;
 154   if (!log.is_trace()) {
 155     return;
 156   }
 157   ResourceMark rm;
 158   outputStream* out = log.trace_stream();
 159   out->print("%s%-25s", indent, "");
 160   for (uint i = 0; i < _active_gc_threads; ++i) {
 161     out->print(" %4.1lf", get_time_ms(phase_id, i));
 162   }
 163   out->cr();
 164 }
 165 
 166 void G1GCPhaseTimes::trace_phase_counts(const char* indent, G1GCPhaseTimes::GCParPhases phase_id) {
 167   LogHandle(gc, phases, task) log;
 168   if (!log.is_trace()) {
 169     return;
 170   }
 171   ResourceMark rm;
 172   outputStream* out = log.trace_stream();
 173   out->print("%s%-25s", indent, "");
 174   for (uint i = 0; i < _active_gc_threads; ++i) {
 175     out->print("  " SIZE_FORMAT, get_thread_work_item(phase_id, i));
 176   }
 177   out->cr();
 178 }
 179 
 180 void G1GCPhaseTimes::debug_phase(G1GCPhaseTimes::GCParPhases phase_id) {
 181   WorkerDataArray<double>* phase = _gc_par_phases[phase_id];
 182   log_debug(gc, phases)("%s%-25s Min: %4.1lf, Avg: %4.1lf, Max: %4.1lf, Diff: %4.1lf, Sum: %4.1lf",
 183       Indents[2], phase->title(),
 184       min_time_ms(phase_id), average_time_ms(phase_id), max_time_ms(phase_id),
 185       max_time_ms(phase_id) - min_time_ms(phase_id), sum_time_ms(phase_id));
 186   trace_phase_tasks(Indents[2], phase_id);
 187   if (phase->thread_work_items() != NULL) {
 188     log_debug(gc, phases)("%s%-25s Min: " SIZE_FORMAT ", Avg: %4.1lf, Max: " SIZE_FORMAT ", Diff: " SIZE_FORMAT ", Sum: " SIZE_FORMAT,
 189         Indents[3], phase->thread_work_items()->title(),
 190         min_thread_work_items(phase_id), average_thread_work_items(phase_id), max_thread_work_items(phase_id),
 191         max_thread_work_items(phase_id) - min_thread_work_items(phase_id), sum_thread_work_items(phase_id));
 192     trace_phase_counts(Indents[3], phase_id);
 193   }
 194 }
 195 
 196 void G1GCPhaseTimes::trace_phase(G1GCPhaseTimes::GCParPhases phase_id) {
 197   WorkerDataArray<double>* phase = _gc_par_phases[phase_id];
 198   log_trace(gc, phases)("%s%-25s Min: %4.1lf, Avg: %4.1lf, Max: %4.1lf, Diff: %4.1lf, Sum: %4.1lf",
 199       Indents[3], phase->title(),
 200       min_time_ms(phase_id), average_time_ms(phase_id), max_time_ms(phase_id),
 201       max_time_ms(phase_id) - min_time_ms(phase_id), sum_time_ms(phase_id));
 202   trace_phase_tasks(Indents[3], phase_id);
 203   if (phase->thread_work_items() != NULL) {
 204     log_trace(gc, phases)("%s%-25s Min: " SIZE_FORMAT ", Avg: %4.1lf, Max: " SIZE_FORMAT ", Diff: " SIZE_FORMAT ", Sum: " SIZE_FORMAT,
 205         Indents[4], phase->thread_work_items()->title(),
 206         min_thread_work_items(phase_id), average_thread_work_items(phase_id), max_thread_work_items(phase_id),
 207         max_thread_work_items(phase_id) - min_thread_work_items(phase_id), sum_thread_work_items(phase_id));
 208     trace_phase_counts(Indents[4], phase_id);
 209   }
 210 }
 211 
 212 void G1GCPhaseTimes::trace_phase_no_sum(G1GCPhaseTimes::GCParPhases phase_id) {
 213   WorkerDataArray<double>* phase = _gc_par_phases[phase_id];
 214   log_trace(gc, phases)("%s%-25s Min: %4.1lf, Avg: %4.1lf, Max: %4.1lf, Diff: %4.1lf",
 215       Indents[3], phase->title(),
 216       min_time_ms(phase_id), average_time_ms(phase_id), max_time_ms(phase_id),
 217       max_time_ms(phase_id) - min_time_ms(phase_id));
 218   trace_phase_tasks(Indents[3], phase_id);
 219   assert(phase->thread_work_items() == NULL, "work_items not implemented for no_sum.");
 220 }
 221 
 222 // record the time a phase took in seconds
 223 void G1GCPhaseTimes::record_time_secs(GCParPhases phase, uint worker_i, double secs) {
 224   _gc_par_phases[phase]->set(worker_i, secs);
 225 }
 226 
 227 // add a number of seconds to a phase
 228 void G1GCPhaseTimes::add_time_secs(GCParPhases phase, uint worker_i, double secs) {
 229   _gc_par_phases[phase]->add(worker_i, secs);
 230 }
 231 
 232 void G1GCPhaseTimes::record_thread_work_item(GCParPhases phase, uint worker_i, size_t count) {
 233   _gc_par_phases[phase]->set_thread_work_item(worker_i, count);
 234 }
 235 
 236 // return the average time for a phase in milliseconds
 237 double G1GCPhaseTimes::average_time_ms(GCParPhases phase) {
 238   return _gc_par_phases[phase]->average(_active_gc_threads) * 1000.0;
 239 }
 240 
 241 double G1GCPhaseTimes::get_time_ms(GCParPhases phase, uint worker_i) {
 242   return _gc_par_phases[phase]->get(worker_i) * 1000.0;

 243 }
 244 
 245 double G1GCPhaseTimes::sum_time_ms(GCParPhases phase) {
 246   return _gc_par_phases[phase]->sum(_active_gc_threads) * 1000.0;






 247 }
 248 
 249 double G1GCPhaseTimes::min_time_ms(GCParPhases phase) {
 250   return _gc_par_phases[phase]->minimum(_active_gc_threads) * 1000.0;
 251 }

 252 
 253 double G1GCPhaseTimes::max_time_ms(GCParPhases phase) {
 254   return _gc_par_phases[phase]->maximum(_active_gc_threads) * 1000.0;




 255 }
 256 
 257 size_t G1GCPhaseTimes::get_thread_work_item(GCParPhases phase, uint worker_i) {
 258   assert(_gc_par_phases[phase]->thread_work_items() != NULL, "No sub count");
 259   return _gc_par_phases[phase]->thread_work_items()->get(worker_i);



 260 }
 261 
 262 size_t G1GCPhaseTimes::sum_thread_work_items(GCParPhases phase) {
 263   assert(_gc_par_phases[phase]->thread_work_items() != NULL, "No sub count");
 264   return _gc_par_phases[phase]->thread_work_items()->sum(_active_gc_threads);



 265 }
 266 
 267 double G1GCPhaseTimes::average_thread_work_items(GCParPhases phase) {
 268   assert(_gc_par_phases[phase]->thread_work_items() != NULL, "No sub count");
 269   return _gc_par_phases[phase]->thread_work_items()->average(_active_gc_threads);
 270 }
 271 
 272 size_t G1GCPhaseTimes::min_thread_work_items(GCParPhases phase) {
 273   assert(_gc_par_phases[phase]->thread_work_items() != NULL, "No sub count");
 274   return _gc_par_phases[phase]->thread_work_items()->minimum(_active_gc_threads);
 275 }
 276 
 277 size_t G1GCPhaseTimes::max_thread_work_items(GCParPhases phase) {
 278   assert(_gc_par_phases[phase]->thread_work_items() != NULL, "No sub count");
 279   return _gc_par_phases[phase]->thread_work_items()->maximum(_active_gc_threads);
 280 }











 281 
 282 void G1GCPhaseTimes::print() {
 283   note_gc_end();
 284 
 285   double accounted_time_ms = _external_accounted_time_ms;
 286   if (_root_region_scan_wait_time_ms > 0.0) {
 287     accounted_time_ms += info_line("Root Region Scan Waiting", _root_region_scan_wait_time_ms);
 288   }
 289 
 290   accounted_time_ms += info_line("Evacuate Collection Set", _cur_collection_par_time_ms);
 291   trace_phase_no_sum(GCWorkerStart);
 292   debug_phase(ExtRootScan);
 293   for (int i = ThreadRoots; i <= SATBFiltering; i++) {
 294     trace_phase((GCParPhases) i);
 295   }
 296   debug_phase(UpdateRS);
 297   if (ConcurrentG1Refine::hot_card_cache_enabled()) {
 298     trace_phase(ScanHCC);
 299   }
 300   debug_phase(ScanRS);
 301   debug_phase(CodeRoots);
 302   debug_phase(ObjCopy);
 303   debug_phase(Termination);
 304   debug_phase(Other);
 305   debug_phase(GCWorkerTotal);
 306   trace_phase_no_sum(GCWorkerEnd);
 307 
 308   accounted_time_ms += info_line("Code Roots", _cur_collection_code_root_fixup_time_ms + _cur_strong_code_root_purge_time_ms);
 309   debug_line("Code Roots Fixup", _cur_collection_code_root_fixup_time_ms);
 310   debug_line("Code Roots Purge", _cur_strong_code_root_purge_time_ms);
 311 
 312   if (G1StringDedup::is_enabled()) {
 313     accounted_time_ms += info_line("String Dedup Fixup", _cur_string_dedup_fixup_time_ms);
 314     debug_phase(StringDedupQueueFixup);
 315     debug_phase(StringDedupTableFixup);
 316   }
 317   accounted_time_ms += info_line("Clear Card Table", _cur_clear_ct_time_ms);
 318   accounted_time_ms += info_line("Expand Heap After Collection", _cur_expand_heap_time_ms);
 319 
 320   double free_cset_time = _recorded_young_free_cset_time_ms + _recorded_non_young_free_cset_time_ms;
 321   accounted_time_ms += info_line("Free Collection Set", free_cset_time);
 322   debug_line("Young Free Collection Set", _recorded_young_free_cset_time_ms);
 323   debug_line("Non-Young Free Collection Set", _recorded_non_young_free_cset_time_ms);
 324 
 325   info_line("Other", _gc_pause_time_ms - accounted_time_ms);
 326   if (_cur_verify_before_time_ms > 0.0) {
 327     debug_line("Verify Before", _cur_verify_before_time_ms);
 328   }
 329   if (G1CollectedHeap::heap()->evacuation_failed()) {
 330     double evac_fail_handling = _cur_evac_fail_recalc_used + _cur_evac_fail_remove_self_forwards +
 331       _cur_evac_fail_restore_remsets;
 332     debug_line("Evacuation Failure", evac_fail_handling);
 333     trace_line("Recalculate Used", _cur_evac_fail_recalc_used);
 334     trace_line("Remove Self Forwards",_cur_evac_fail_remove_self_forwards);
 335     trace_line("Restore RemSet", _cur_evac_fail_restore_remsets);
 336   }
 337   debug_line("Choose CSet", (_recorded_young_cset_choice_time_ms + _recorded_non_young_cset_choice_time_ms));
 338   debug_line("Ref Proc", _cur_ref_proc_time_ms);
 339   debug_line("Ref Enq", _cur_ref_enq_time_ms);
 340   debug_line("Redirty Cards", _recorded_redirty_logged_cards_time_ms);
 341   trace_phase(RedirtyCards);
 342   if (G1EagerReclaimHumongousObjects) {
 343     debug_line("Humongous Register", _cur_fast_reclaim_humongous_register_time_ms);
 344     trace_line("Humongous Total", _cur_fast_reclaim_humongous_total);
 345     trace_line("Humongous Candidate", _cur_fast_reclaim_humongous_candidates);
 346     debug_line("Humongous Reclaim", _cur_fast_reclaim_humongous_time_ms);
 347     trace_line("Humongous Reclaimed", _cur_fast_reclaim_humongous_reclaimed);
 348   }
 349   if (_cur_verify_after_time_ms > 0.0) {
 350     debug_line("Verify After", _cur_verify_after_time_ms);
 351   }
 352 }
 353 
 354 G1GCParPhaseTimesTracker::G1GCParPhaseTimesTracker(G1GCPhaseTimes* phase_times, G1GCPhaseTimes::GCParPhases phase, uint worker_id) :
 355     _phase_times(phase_times), _phase(phase), _worker_id(worker_id) {
 356   if (_phase_times != NULL) {
 357     _start_time = os::elapsedTime();
 358   }
 359 }
 360 
 361 G1GCParPhaseTimesTracker::~G1GCParPhaseTimesTracker() {
 362   if (_phase_times != NULL) {
 363     _phase_times->record_time_secs(_phase, _worker_id, os::elapsedTime() - _start_time);
 364   }
 365 }
 366 


 115 
 116     double worker_known_time =
 117         _gc_par_phases[ExtRootScan]->get(i) +
 118         _gc_par_phases[SATBFiltering]->get(i) +
 119         _gc_par_phases[UpdateRS]->get(i) +
 120         _gc_par_phases[ScanRS]->get(i) +
 121         _gc_par_phases[CodeRoots]->get(i) +
 122         _gc_par_phases[ObjCopy]->get(i) +
 123         _gc_par_phases[Termination]->get(i);
 124 
 125     record_time_secs(Other, i, worker_time - worker_known_time);
 126   }
 127 
 128   for (int i = 0; i < GCParPhasesSentinel; i++) {
 129     if (_gc_par_phases[i] != NULL) {
 130       _gc_par_phases[i]->verify(_active_gc_threads);
 131     }
 132   }
 133 }
 134 























































































 135 // record the time a phase took in seconds
 136 void G1GCPhaseTimes::record_time_secs(GCParPhases phase, uint worker_i, double secs) {
 137   _gc_par_phases[phase]->set(worker_i, secs);
 138 }
 139 
 140 // add a number of seconds to a phase
 141 void G1GCPhaseTimes::add_time_secs(GCParPhases phase, uint worker_i, double secs) {
 142   _gc_par_phases[phase]->add(worker_i, secs);
 143 }
 144 
 145 void G1GCPhaseTimes::record_thread_work_item(GCParPhases phase, uint worker_i, size_t count) {
 146   _gc_par_phases[phase]->set_thread_work_item(worker_i, count);
 147 }
 148 
 149 // return the average time for a phase in milliseconds
 150 double G1GCPhaseTimes::average_time_ms(GCParPhases phase) {
 151   return _gc_par_phases[phase]->average(_active_gc_threads) * 1000.0;
 152 }
 153 
 154 size_t G1GCPhaseTimes::sum_thread_work_items(GCParPhases phase) {
 155   assert(_gc_par_phases[phase]->thread_work_items() != NULL, "No sub count");
 156   return _gc_par_phases[phase]->thread_work_items()->sum(_active_gc_threads);
 157 }
 158 
 159 template <class T>
 160 void G1GCPhaseTimes::details(T* phase, const char* indent) {
 161   LogHandle(gc, phases, task) log;
 162   if (log.is_level(LogLevel::Trace)) {
 163     outputStream* trace_out = log.trace_stream();
 164     trace_out->print("%s", indent);
 165     phase->print_details_on(trace_out, _active_gc_threads);
 166   }
 167 }
 168 
 169 void G1GCPhaseTimes::log_phase(WorkerDataArray<double>* phase, uint indent, outputStream* out, bool print_sum) {
 170   out->print("%s", Indents[indent]);
 171   phase->print_summary_on(out, _active_gc_threads, print_sum);
 172   details(phase, Indents[indent]);
 173 
 174   WorkerDataArray<size_t>* work_items = phase->thread_work_items();
 175   if (work_items != NULL) {
 176     out->print("%s", Indents[indent + 1]);
 177     work_items->print_summary_on(out, _active_gc_threads, true);
 178     details(work_items, Indents[indent + 1]);
 179   }
 180 }
 181 
 182 void G1GCPhaseTimes::debug_phase(WorkerDataArray<double>* phase) {
 183   LogHandle(gc, phases) log;
 184   if (log.is_level(LogLevel::Debug)) {
 185     ResourceMark rm;
 186     log_phase(phase, 2, log.debug_stream(), true);
 187   }
 188 }
 189 
 190 void G1GCPhaseTimes::trace_phase(WorkerDataArray<double>* phase, bool print_sum) {
 191   LogHandle(gc, phases) log;
 192   if (log.is_level(LogLevel::Trace)) {
 193     ResourceMark rm;
 194     log_phase(phase, 3, log.trace_stream(), print_sum);
 195   }
 196 }
 197 
 198 #define PHASE_DOUBLE_FORMAT "%s%s: %.1lfms"
 199 #define PHASE_SIZE_FORMAT "%s%s: " SIZE_FORMAT


 200 
 201 #define info_line(str, value) \
 202   log_info(gc, phases)(PHASE_DOUBLE_FORMAT, Indents[1], str, value);


 203 
 204 #define debug_line(str, value) \
 205   log_debug(gc, phases)(PHASE_DOUBLE_FORMAT, Indents[2], str, value);
 206 
 207 #define trace_line(str, value) \
 208   log_trace(gc, phases)(PHASE_DOUBLE_FORMAT, Indents[3], str, value);
 209 
 210 #define trace_line_sz(str, value) \
 211   log_trace(gc, phases)(PHASE_SIZE_FORMAT, Indents[3], str, value);
 212 
 213 #define trace_line_ms(str, value) \
 214   log_trace(gc, phases)(PHASE_SIZE_FORMAT, Indents[3], str, value);
 215 
 216 #define info_line_and_account(str, value) \
 217   info_line(str, value);                  \
 218   accounted_time_ms += value;
 219 
 220 void G1GCPhaseTimes::print() {
 221   note_gc_end();
 222 
 223   double accounted_time_ms = _external_accounted_time_ms;
 224   if (_root_region_scan_wait_time_ms > 0.0) {
 225     info_line_and_account("Root Region Scan Waiting", _root_region_scan_wait_time_ms);
 226   }
 227 
 228   info_line_and_account("Evacuate Collection Set", _cur_collection_par_time_ms);
 229   trace_phase(_gc_par_phases[GCWorkerStart], false);
 230   debug_phase(_gc_par_phases[ExtRootScan]);
 231   for (int i = ThreadRoots; i <= SATBFiltering; i++) {
 232     trace_phase(_gc_par_phases[i]);
 233   }
 234   debug_phase(_gc_par_phases[UpdateRS]);
 235   if (ConcurrentG1Refine::hot_card_cache_enabled()) {
 236     trace_phase(_gc_par_phases[ScanHCC]);
 237   }
 238   debug_phase(_gc_par_phases[ScanRS]);
 239   debug_phase(_gc_par_phases[CodeRoots]);
 240   debug_phase(_gc_par_phases[ObjCopy]);
 241   debug_phase(_gc_par_phases[Termination]);
 242   debug_phase(_gc_par_phases[Other]);
 243   debug_phase(_gc_par_phases[GCWorkerTotal]);
 244   trace_phase(_gc_par_phases[GCWorkerEnd], false);
 245 
 246   info_line_and_account("Code Roots", _cur_collection_code_root_fixup_time_ms + _cur_strong_code_root_purge_time_ms);
 247   debug_line("Code Roots Fixup", _cur_collection_code_root_fixup_time_ms);
 248   debug_line("Code Roots Purge", _cur_strong_code_root_purge_time_ms);
 249 
 250   if (G1StringDedup::is_enabled()) {
 251     info_line_and_account("String Dedup Fixup", _cur_string_dedup_fixup_time_ms);
 252     debug_phase(_gc_par_phases[StringDedupQueueFixup]);
 253     debug_phase(_gc_par_phases[StringDedupTableFixup]);
 254   }
 255   info_line_and_account("Clear Card Table", _cur_clear_ct_time_ms);
 256   info_line_and_account("Expand Heap After Collection", _cur_expand_heap_time_ms);
 257 
 258   double free_cset_time = _recorded_young_free_cset_time_ms + _recorded_non_young_free_cset_time_ms;
 259   info_line_and_account("Free Collection Set", free_cset_time);
 260   debug_line("Young Free Collection Set", _recorded_young_free_cset_time_ms);
 261   debug_line("Non-Young Free Collection Set", _recorded_non_young_free_cset_time_ms);
 262 
 263   info_line("Other", _gc_pause_time_ms - accounted_time_ms);
 264   if (_cur_verify_before_time_ms > 0.0) {
 265     debug_line("Verify Before", _cur_verify_before_time_ms);
 266   }
 267   if (G1CollectedHeap::heap()->evacuation_failed()) {
 268     double evac_fail_handling = _cur_evac_fail_recalc_used + _cur_evac_fail_remove_self_forwards +
 269       _cur_evac_fail_restore_remsets;
 270     debug_line("Evacuation Failure", evac_fail_handling);
 271     trace_line("Recalculate Used", _cur_evac_fail_recalc_used);
 272     trace_line("Remove Self Forwards",_cur_evac_fail_remove_self_forwards);
 273     trace_line("Restore RemSet", _cur_evac_fail_restore_remsets);
 274   }
 275   debug_line("Choose CSet", (_recorded_young_cset_choice_time_ms + _recorded_non_young_cset_choice_time_ms));
 276   debug_line("Ref Proc", _cur_ref_proc_time_ms);
 277   debug_line("Ref Enq", _cur_ref_enq_time_ms);
 278   debug_line("Redirty Cards", _recorded_redirty_logged_cards_time_ms);
 279   trace_phase(_gc_par_phases[RedirtyCards]);
 280   if (G1EagerReclaimHumongousObjects) {
 281     debug_line("Humongous Register", _cur_fast_reclaim_humongous_register_time_ms);
 282     trace_line_sz("Humongous Total", _cur_fast_reclaim_humongous_total);
 283     trace_line_sz("Humongous Candidate", _cur_fast_reclaim_humongous_candidates);
 284     debug_line("Humongous Reclaim", _cur_fast_reclaim_humongous_time_ms);
 285     trace_line_sz("Humongous Reclaimed", _cur_fast_reclaim_humongous_reclaimed);
 286   }
 287   if (_cur_verify_after_time_ms > 0.0) {
 288     debug_line("Verify After", _cur_verify_after_time_ms);
 289   }
 290 }
 291 
 292 G1GCParPhaseTimesTracker::G1GCParPhaseTimesTracker(G1GCPhaseTimes* phase_times, G1GCPhaseTimes::GCParPhases phase, uint worker_id) :
 293     _phase_times(phase_times), _phase(phase), _worker_id(worker_id) {
 294   if (_phase_times != NULL) {
 295     _start_time = os::elapsedTime();
 296   }
 297 }
 298 
 299 G1GCParPhaseTimesTracker::~G1GCParPhaseTimesTracker() {
 300   if (_phase_times != NULL) {
 301     _phase_times->record_time_secs(_phase, _worker_id, os::elapsedTime() - _start_time);
 302   }
 303 }
 304 
< prev index next >