comparison src/share/vm/runtime/safepoint.cpp @ 1291:4b0f2f4918ed

6933402: RFE: Improve PrintSafepointStatistics output to track cleanup time Summary: Improve the usability of safepoint statistics data. See bug evaluation for more details. Reviewed-by: ysr, dholmes
author xlu
date Wed, 10 Mar 2010 21:42:26 -0800
parents 528d98fe1037
children 0f6600cee529
comparison
equal deleted inserted replaced
1290:c8a467bf56ad 1291:4b0f2f4918ed
28 // -------------------------------------------------------------------------------------------------- 28 // --------------------------------------------------------------------------------------------------
29 // Implementation of Safepoint begin/end 29 // Implementation of Safepoint begin/end
30 30
31 SafepointSynchronize::SynchronizeState volatile SafepointSynchronize::_state = SafepointSynchronize::_not_synchronized; 31 SafepointSynchronize::SynchronizeState volatile SafepointSynchronize::_state = SafepointSynchronize::_not_synchronized;
32 volatile int SafepointSynchronize::_waiting_to_block = 0; 32 volatile int SafepointSynchronize::_waiting_to_block = 0;
33 jlong SafepointSynchronize::_last_safepoint = 0;
34 volatile int SafepointSynchronize::_safepoint_counter = 0; 33 volatile int SafepointSynchronize::_safepoint_counter = 0;
34 long SafepointSynchronize::_end_of_last_safepoint = 0;
35 static volatile int PageArmed = 0 ; // safepoint polling page is RO|RW vs PROT_NONE 35 static volatile int PageArmed = 0 ; // safepoint polling page is RO|RW vs PROT_NONE
36 static volatile int TryingToBlock = 0 ; // proximate value -- for advisory use only 36 static volatile int TryingToBlock = 0 ; // proximate value -- for advisory use only
37 static bool timeout_error_printed = false; 37 static bool timeout_error_printed = false;
38 38
39 // Roll all threads forward to a safepoint and suspend them all 39 // Roll all threads forward to a safepoint and suspend them all
40 void SafepointSynchronize::begin() { 40 void SafepointSynchronize::begin() {
41 41
42 Thread* myThread = Thread::current(); 42 Thread* myThread = Thread::current();
43 assert(myThread->is_VM_thread(), "Only VM thread may execute a safepoint"); 43 assert(myThread->is_VM_thread(), "Only VM thread may execute a safepoint");
44 44
45 _last_safepoint = os::javaTimeNanos(); 45 if (PrintSafepointStatistics || PrintSafepointStatisticsTimeout > 0) {
46 _safepoint_begin_time = os::javaTimeNanos();
47 _ts_of_current_safepoint = tty->time_stamp().seconds();
48 }
46 49
47 #ifndef SERIALGC 50 #ifndef SERIALGC
48 if (UseConcMarkSweepGC) { 51 if (UseConcMarkSweepGC) {
49 // In the future we should investigate whether CMS can use the 52 // In the future we should investigate whether CMS can use the
50 // more-general mechanism below. DLD (01/05). 53 // more-general mechanism below. DLD (01/05).
318 update_statistics_on_sync_end(os::javaTimeNanos()); 321 update_statistics_on_sync_end(os::javaTimeNanos());
319 } 322 }
320 323
321 // Call stuff that needs to be run when a safepoint is just about to be completed 324 // Call stuff that needs to be run when a safepoint is just about to be completed
322 do_cleanup_tasks(); 325 do_cleanup_tasks();
326
327 if (PrintSafepointStatistics) {
328 // Record how much time spend on the above cleanup tasks
329 update_statistics_on_cleanup_end(os::javaTimeNanos());
330 }
323 } 331 }
324 } 332 }
325 333
326 // Wake up all threads, so they are ready to resume execution after the safepoint 334 // Wake up all threads, so they are ready to resume execution after the safepoint
327 // operation has been carried out 335 // operation has been carried out
409 ConcurrentMarkSweepThread::desynchronize(false); 417 ConcurrentMarkSweepThread::desynchronize(false);
410 } else if (UseG1GC) { 418 } else if (UseG1GC) {
411 ConcurrentGCThread::safepoint_desynchronize(); 419 ConcurrentGCThread::safepoint_desynchronize();
412 } 420 }
413 #endif // SERIALGC 421 #endif // SERIALGC
422 // record this time so VMThread can keep track how much time has elasped
423 // since last safepoint.
424 _end_of_last_safepoint = os::javaTimeMillis();
414 } 425 }
415 426
416 bool SafepointSynchronize::is_cleanup_needed() { 427 bool SafepointSynchronize::is_cleanup_needed() {
417 // Need a safepoint if some inline cache buffers is non-empty 428 // Need a safepoint if some inline cache buffers is non-empty
418 if (!InlineCacheBuffer::is_empty()) return true; 429 if (!InlineCacheBuffer::is_empty()) return true;
443 } 454 }
444 } 455 }
445 456
446 // Various cleaning tasks that should be done periodically at safepoints 457 // Various cleaning tasks that should be done periodically at safepoints
447 void SafepointSynchronize::do_cleanup_tasks() { 458 void SafepointSynchronize::do_cleanup_tasks() {
448 jlong cleanup_time; 459 {
449 460 TraceTime t1("deflating idle monitors", TraceSafepoint);
450 // Update fat-monitor pool, since this is a safepoint. 461 ObjectSynchronizer::deflate_idle_monitors();
451 if (TraceSafepoint) { 462 }
452 cleanup_time = os::javaTimeNanos(); 463
453 } 464 {
454 465 TraceTime t2("updating inline caches", TraceSafepoint);
455 ObjectSynchronizer::deflate_idle_monitors(); 466 InlineCacheBuffer::update_inline_caches();
456 InlineCacheBuffer::update_inline_caches(); 467 }
468
457 if(UseCounterDecay && CounterDecay::is_decay_needed()) { 469 if(UseCounterDecay && CounterDecay::is_decay_needed()) {
470 TraceTime t3("decaying counter", TraceSafepoint);
458 CounterDecay::decay(); 471 CounterDecay::decay();
459 } 472 }
473
474 TraceTime t4("sweeping nmethods", TraceSafepoint);
460 NMethodSweeper::sweep(); 475 NMethodSweeper::sweep();
461
462 if (TraceSafepoint) {
463 tty->print_cr("do_cleanup_tasks takes "INT64_FORMAT_W(6) "ms",
464 (os::javaTimeNanos() - cleanup_time) / MICROUNITS);
465 }
466 } 476 }
467 477
468 478
469 bool SafepointSynchronize::safepoint_safe(JavaThread *thread, JavaThreadState state) { 479 bool SafepointSynchronize::safepoint_safe(JavaThread *thread, JavaThreadState state) {
470 switch(state) { 480 switch(state) {
977 987
978 // 988 //
979 // Statistics & Instrumentations 989 // Statistics & Instrumentations
980 // 990 //
981 SafepointSynchronize::SafepointStats* SafepointSynchronize::_safepoint_stats = NULL; 991 SafepointSynchronize::SafepointStats* SafepointSynchronize::_safepoint_stats = NULL;
992 jlong SafepointSynchronize::_safepoint_begin_time = 0;
982 int SafepointSynchronize::_cur_stat_index = 0; 993 int SafepointSynchronize::_cur_stat_index = 0;
983 julong SafepointSynchronize::_safepoint_reasons[VM_Operation::VMOp_Terminating]; 994 julong SafepointSynchronize::_safepoint_reasons[VM_Operation::VMOp_Terminating];
984 julong SafepointSynchronize::_coalesced_vmop_count = 0; 995 julong SafepointSynchronize::_coalesced_vmop_count = 0;
985 jlong SafepointSynchronize::_max_sync_time = 0; 996 jlong SafepointSynchronize::_max_sync_time = 0;
986 997 jlong SafepointSynchronize::_max_vmop_time = 0;
987 // last_safepoint_start_time records the start time of last safepoint. 998 float SafepointSynchronize::_ts_of_current_safepoint = 0.0f;
988 static jlong last_safepoint_start_time = 0; 999
989 static jlong sync_end_time = 0; 1000 static jlong cleanup_end_time = 0;
990 static bool need_to_track_page_armed_status = false; 1001 static bool need_to_track_page_armed_status = false;
991 static bool init_done = false; 1002 static bool init_done = false;
1003
1004 // Helper method to print the header.
1005 static void print_header() {
1006 tty->print(" vmop "
1007 "[threads: total initially_running wait_to_block] ");
1008 tty->print("[time: spin block sync cleanup vmop] ");
1009
1010 // no page armed status printed out if it is always armed.
1011 if (need_to_track_page_armed_status) {
1012 tty->print("page_armed ");
1013 }
1014
1015 tty->print_cr("page_trap_count");
1016 }
992 1017
993 void SafepointSynchronize::deferred_initialize_stat() { 1018 void SafepointSynchronize::deferred_initialize_stat() {
994 if (init_done) return; 1019 if (init_done) return;
995 1020
996 if (PrintSafepointStatisticsCount <= 0) { 1021 if (PrintSafepointStatisticsCount <= 0) {
1014 "not enough memory for safepoint instrumentation data"); 1039 "not enough memory for safepoint instrumentation data");
1015 1040
1016 if (UseCompilerSafepoints && DeferPollingPageLoopCount >= 0) { 1041 if (UseCompilerSafepoints && DeferPollingPageLoopCount >= 0) {
1017 need_to_track_page_armed_status = true; 1042 need_to_track_page_armed_status = true;
1018 } 1043 }
1019
1020 tty->print(" vmop_name "
1021 "[threads: total initially_running wait_to_block] ");
1022 tty->print("[time: spin block sync] "
1023 "[vmop_time time_elapsed] ");
1024
1025 // no page armed status printed out if it is always armed.
1026 if (need_to_track_page_armed_status) {
1027 tty->print("page_armed ");
1028 }
1029
1030 tty->print_cr("page_trap_count");
1031
1032 init_done = true; 1044 init_done = true;
1033 } 1045 }
1034 1046
1035 void SafepointSynchronize::begin_statistics(int nof_threads, int nof_running) { 1047 void SafepointSynchronize::begin_statistics(int nof_threads, int nof_running) {
1036 assert(init_done, "safepoint statistics array hasn't been initialized"); 1048 assert(init_done, "safepoint statistics array hasn't been initialized");
1037 SafepointStats *spstat = &_safepoint_stats[_cur_stat_index]; 1049 SafepointStats *spstat = &_safepoint_stats[_cur_stat_index];
1050
1051 spstat->_time_stamp = _ts_of_current_safepoint;
1038 1052
1039 VM_Operation *op = VMThread::vm_operation(); 1053 VM_Operation *op = VMThread::vm_operation();
1040 spstat->_vmop_type = (op != NULL ? op->type() : -1); 1054 spstat->_vmop_type = (op != NULL ? op->type() : -1);
1041 if (op != NULL) { 1055 if (op != NULL) {
1042 _safepoint_reasons[spstat->_vmop_type]++; 1056 _safepoint_reasons[spstat->_vmop_type]++;
1052 if (nof_running != 0) { 1066 if (nof_running != 0) {
1053 spstat->_time_to_spin = os::javaTimeNanos(); 1067 spstat->_time_to_spin = os::javaTimeNanos();
1054 } else { 1068 } else {
1055 spstat->_time_to_spin = 0; 1069 spstat->_time_to_spin = 0;
1056 } 1070 }
1057
1058 if (last_safepoint_start_time == 0) {
1059 spstat->_time_elapsed_since_last_safepoint = 0;
1060 } else {
1061 spstat->_time_elapsed_since_last_safepoint = _last_safepoint -
1062 last_safepoint_start_time;
1063 }
1064 last_safepoint_start_time = _last_safepoint;
1065 } 1071 }
1066 1072
1067 void SafepointSynchronize::update_statistics_on_spin_end() { 1073 void SafepointSynchronize::update_statistics_on_spin_end() {
1068 SafepointStats *spstat = &_safepoint_stats[_cur_stat_index]; 1074 SafepointStats *spstat = &_safepoint_stats[_cur_stat_index];
1069 1075
1095 } 1101 }
1096 1102
1097 // Records the end time of sync which will be used to calculate the total 1103 // Records the end time of sync which will be used to calculate the total
1098 // vm operation time. Again, the real time spending in syncing will be deducted 1104 // vm operation time. Again, the real time spending in syncing will be deducted
1099 // from the start of the sync time later when end_statistics is called. 1105 // from the start of the sync time later when end_statistics is called.
1100 spstat->_time_to_sync = end_time - _last_safepoint; 1106 spstat->_time_to_sync = end_time - _safepoint_begin_time;
1101 if (spstat->_time_to_sync > _max_sync_time) { 1107 if (spstat->_time_to_sync > _max_sync_time) {
1102 _max_sync_time = spstat->_time_to_sync; 1108 _max_sync_time = spstat->_time_to_sync;
1103 } 1109 }
1104 sync_end_time = end_time; 1110
1111 spstat->_time_to_do_cleanups = end_time;
1112 }
1113
1114 void SafepointSynchronize::update_statistics_on_cleanup_end(jlong end_time) {
1115 SafepointStats *spstat = &_safepoint_stats[_cur_stat_index];
1116
1117 // Record how long spent in cleanup tasks.
1118 spstat->_time_to_do_cleanups = end_time - spstat->_time_to_do_cleanups;
1119
1120 cleanup_end_time = end_time;
1105 } 1121 }
1106 1122
1107 void SafepointSynchronize::end_statistics(jlong vmop_end_time) { 1123 void SafepointSynchronize::end_statistics(jlong vmop_end_time) {
1108 SafepointStats *spstat = &_safepoint_stats[_cur_stat_index]; 1124 SafepointStats *spstat = &_safepoint_stats[_cur_stat_index];
1109 1125
1110 // Update the vm operation time. 1126 // Update the vm operation time.
1111 spstat->_time_to_exec_vmop = vmop_end_time - sync_end_time; 1127 spstat->_time_to_exec_vmop = vmop_end_time - cleanup_end_time;
1128 if (spstat->_time_to_exec_vmop > _max_vmop_time) {
1129 _max_vmop_time = spstat->_time_to_exec_vmop;
1130 }
1112 // Only the sync time longer than the specified 1131 // Only the sync time longer than the specified
1113 // PrintSafepointStatisticsTimeout will be printed out right away. 1132 // PrintSafepointStatisticsTimeout will be printed out right away.
1114 // By default, it is -1 meaning all samples will be put into the list. 1133 // By default, it is -1 meaning all samples will be put into the list.
1115 if ( PrintSafepointStatisticsTimeout > 0) { 1134 if ( PrintSafepointStatisticsTimeout > 0) {
1116 if (spstat->_time_to_sync > PrintSafepointStatisticsTimeout * MICROUNITS) { 1135 if (spstat->_time_to_sync > PrintSafepointStatisticsTimeout * MICROUNITS) {
1117 print_statistics(); 1136 print_statistics();
1118 } 1137 }
1119 } else { 1138 } else {
1120 // The safepoint statistics will be printed out when the _safepoin_stats 1139 // The safepoint statistics will be printed out when the _safepoin_stats
1121 // array fills up. 1140 // array fills up.
1122 if (_cur_stat_index != PrintSafepointStatisticsCount - 1) { 1141 if (_cur_stat_index == PrintSafepointStatisticsCount - 1) {
1123 _cur_stat_index ++;
1124 } else {
1125 print_statistics(); 1142 print_statistics();
1126 _cur_stat_index = 0; 1143 _cur_stat_index = 0;
1127 tty->print_cr(""); 1144 } else {
1145 _cur_stat_index++;
1128 } 1146 }
1129 } 1147 }
1130 } 1148 }
1131 1149
1132 void SafepointSynchronize::print_statistics() { 1150 void SafepointSynchronize::print_statistics() {
1133 int index;
1134 SafepointStats* sstats = _safepoint_stats; 1151 SafepointStats* sstats = _safepoint_stats;
1135 1152
1136 for (index = 0; index <= _cur_stat_index; index++) { 1153 for (int index = 0; index <= _cur_stat_index; index++) {
1154 if (index % 30 == 0) {
1155 print_header();
1156 }
1137 sstats = &_safepoint_stats[index]; 1157 sstats = &_safepoint_stats[index];
1138 tty->print("%-28s [" 1158 tty->print("%.3f: ", sstats->_time_stamp);
1159 tty->print("%-26s ["
1139 INT32_FORMAT_W(8)INT32_FORMAT_W(11)INT32_FORMAT_W(15) 1160 INT32_FORMAT_W(8)INT32_FORMAT_W(11)INT32_FORMAT_W(15)
1140 "] ", 1161 " ] ",
1141 sstats->_vmop_type == -1 ? "no vm operation" : 1162 sstats->_vmop_type == -1 ? "no vm operation" :
1142 VM_Operation::name(sstats->_vmop_type), 1163 VM_Operation::name(sstats->_vmop_type),
1143 sstats->_nof_total_threads, 1164 sstats->_nof_total_threads,
1144 sstats->_nof_initial_running_threads, 1165 sstats->_nof_initial_running_threads,
1145 sstats->_nof_threads_wait_to_block); 1166 sstats->_nof_threads_wait_to_block);
1146 // "/ MICROUNITS " is to convert the unit from nanos to millis. 1167 // "/ MICROUNITS " is to convert the unit from nanos to millis.
1147 tty->print(" [" 1168 tty->print(" ["
1148 INT64_FORMAT_W(6)INT64_FORMAT_W(6)INT64_FORMAT_W(6) 1169 INT64_FORMAT_W(6)INT64_FORMAT_W(6)
1149 "] " 1170 INT64_FORMAT_W(6)INT64_FORMAT_W(6)
1150 "["INT64_FORMAT_W(6)INT64_FORMAT_W(9) "] ", 1171 INT64_FORMAT_W(6)" ] ",
1151 sstats->_time_to_spin / MICROUNITS, 1172 sstats->_time_to_spin / MICROUNITS,
1152 sstats->_time_to_wait_to_block / MICROUNITS, 1173 sstats->_time_to_wait_to_block / MICROUNITS,
1153 sstats->_time_to_sync / MICROUNITS, 1174 sstats->_time_to_sync / MICROUNITS,
1154 sstats->_time_to_exec_vmop / MICROUNITS, 1175 sstats->_time_to_do_cleanups / MICROUNITS,
1155 sstats->_time_elapsed_since_last_safepoint / MICROUNITS); 1176 sstats->_time_to_exec_vmop / MICROUNITS);
1156 1177
1157 if (need_to_track_page_armed_status) { 1178 if (need_to_track_page_armed_status) {
1158 tty->print(INT32_FORMAT" ", sstats->_page_armed); 1179 tty->print(INT32_FORMAT" ", sstats->_page_armed);
1159 } 1180 }
1160 tty->print_cr(INT32_FORMAT" ", sstats->_nof_threads_hit_page_trap); 1181 tty->print_cr(INT32_FORMAT" ", sstats->_nof_threads_hit_page_trap);
1172 // During VM exit, end_statistics may not get called and in that 1193 // During VM exit, end_statistics may not get called and in that
1173 // case, if the sync time is less than PrintSafepointStatisticsTimeout, 1194 // case, if the sync time is less than PrintSafepointStatisticsTimeout,
1174 // don't print it out. 1195 // don't print it out.
1175 // Approximate the vm op time. 1196 // Approximate the vm op time.
1176 _safepoint_stats[_cur_stat_index]._time_to_exec_vmop = 1197 _safepoint_stats[_cur_stat_index]._time_to_exec_vmop =
1177 os::javaTimeNanos() - sync_end_time; 1198 os::javaTimeNanos() - cleanup_end_time;
1178 1199
1179 if ( PrintSafepointStatisticsTimeout < 0 || 1200 if ( PrintSafepointStatisticsTimeout < 0 ||
1180 spstat->_time_to_sync > PrintSafepointStatisticsTimeout * MICROUNITS) { 1201 spstat->_time_to_sync > PrintSafepointStatisticsTimeout * MICROUNITS) {
1181 print_statistics(); 1202 print_statistics();
1182 } 1203 }
1201 1222
1202 tty->print_cr(UINT64_FORMAT_W(5)" VM operations coalesced during safepoint", 1223 tty->print_cr(UINT64_FORMAT_W(5)" VM operations coalesced during safepoint",
1203 _coalesced_vmop_count); 1224 _coalesced_vmop_count);
1204 tty->print_cr("Maximum sync time "INT64_FORMAT_W(5)" ms", 1225 tty->print_cr("Maximum sync time "INT64_FORMAT_W(5)" ms",
1205 _max_sync_time / MICROUNITS); 1226 _max_sync_time / MICROUNITS);
1227 tty->print_cr("Maximum vm operation time (except for Exit VM operation) "
1228 INT64_FORMAT_W(5)" ms",
1229 _max_vmop_time / MICROUNITS);
1206 } 1230 }
1207 1231
1208 // ------------------------------------------------------------------------------------------------ 1232 // ------------------------------------------------------------------------------------------------
1209 // Non-product code 1233 // Non-product code
1210 1234