src/hotspot/share/runtime/safepoint.cpp
changeset 49169 af8578e25d17
parent 49061 a6b6a428c915
child 49359 59f6547e151f
equal deleted inserted replaced
49168:23348e42fb34 49169:af8578e25d17
    76 SafepointSynchronize::SynchronizeState volatile SafepointSynchronize::_state = SafepointSynchronize::_not_synchronized;
    76 SafepointSynchronize::SynchronizeState volatile SafepointSynchronize::_state = SafepointSynchronize::_not_synchronized;
    77 volatile int  SafepointSynchronize::_waiting_to_block = 0;
    77 volatile int  SafepointSynchronize::_waiting_to_block = 0;
    78 volatile int SafepointSynchronize::_safepoint_counter = 0;
    78 volatile int SafepointSynchronize::_safepoint_counter = 0;
    79 int SafepointSynchronize::_current_jni_active_count = 0;
    79 int SafepointSynchronize::_current_jni_active_count = 0;
    80 long  SafepointSynchronize::_end_of_last_safepoint = 0;
    80 long  SafepointSynchronize::_end_of_last_safepoint = 0;
       
    81 int SafepointSynchronize::_defer_thr_suspend_loop_count = 4000;
       
    82 static const int safepoint_spin_before_yield = 2000;
    81 static volatile int PageArmed = 0 ;        // safepoint polling page is RO|RW vs PROT_NONE
    83 static volatile int PageArmed = 0 ;        // safepoint polling page is RO|RW vs PROT_NONE
    82 static volatile int TryingToBlock = 0 ;    // proximate value -- for advisory use only
    84 static volatile int TryingToBlock = 0 ;    // proximate value -- for advisory use only
    83 static bool timeout_error_printed = false;
    85 static bool timeout_error_printed = false;
    84 
    86 
    85 // Roll all threads forward to a safepoint and suspend them all
    87 // Roll all threads forward to a safepoint and suspend them all
   189 
   191 
   190     if (SafepointMechanism::uses_global_page_poll()) {
   192     if (SafepointMechanism::uses_global_page_poll()) {
   191       // Make interpreter safepoint aware
   193       // Make interpreter safepoint aware
   192       Interpreter::notice_safepoints();
   194       Interpreter::notice_safepoints();
   193 
   195 
   194       if (DeferPollingPageLoopCount < 0) {
   196       // Make polling safepoint aware
   195         // Make polling safepoint aware
   197       guarantee (PageArmed == 0, "invariant") ;
   196         guarantee (PageArmed == 0, "invariant") ;
   198       PageArmed = 1 ;
   197         PageArmed = 1 ;
   199       os::make_polling_page_unreadable();
   198         os::make_polling_page_unreadable();
       
   199       }
       
   200     }
   200     }
   201 
   201 
   202     // Consider using active_processor_count() ... but that call is expensive.
   202     // Consider using active_processor_count() ... but that call is expensive.
   203     int ncpus = os::processor_count() ;
   203     int ncpus = os::processor_count() ;
   204     unsigned int iterations = 0;
   204     unsigned int iterations = 0;
   307           //    Alternately, instead of counting iterations of the outer loop
   307           //    Alternately, instead of counting iterations of the outer loop
   308           //    we could count the # of threads visited in the inner loop, above.
   308           //    we could count the # of threads visited in the inner loop, above.
   309           // 9. On windows consider using the return value from SwitchThreadTo()
   309           // 9. On windows consider using the return value from SwitchThreadTo()
   310           //    to drive subsequent spin/SwitchThreadTo()/Sleep(N) decisions.
   310           //    to drive subsequent spin/SwitchThreadTo()/Sleep(N) decisions.
   311 
   311 
   312           if (SafepointMechanism::uses_global_page_poll() && int(iterations) == DeferPollingPageLoopCount) {
   312           if (int(iterations) == -1) { // overflow - something is wrong.
   313             guarantee (PageArmed == 0, "invariant") ;
   313             // We can only overflow here when we are using global
   314             PageArmed = 1 ;
   314             // polling pages. We keep this guarantee in its original
   315             os::make_polling_page_unreadable();
   315             // form so that searches of the bug database for this
       
   316             // failure mode find the right bugs.
       
   317             guarantee (PageArmed == 0, "invariant");
   316           }
   318           }
   317 
   319 
   318           // Instead of (ncpus > 1) consider either (still_running < (ncpus + EPSILON)) or
   320           // Instead of (ncpus > 1) consider either (still_running < (ncpus + EPSILON)) or
   319           // ((still_running + _waiting_to_block - TryingToBlock)) < ncpus)
   321           // ((still_running + _waiting_to_block - TryingToBlock)) < ncpus)
   320           ++steps ;
   322           ++steps ;
   321           if (ncpus > 1 && steps < SafepointSpinBeforeYield) {
   323           if (ncpus > 1 && steps < safepoint_spin_before_yield) {
   322             SpinPause() ;     // MP-Polite spin
   324             SpinPause() ;     // MP-Polite spin
   323           } else
   325           } else
   324             if (steps < DeferThrSuspendLoopCount) {
   326             if (steps < _defer_thr_suspend_loop_count) {
   325               os::naked_yield() ;
   327               os::naked_yield() ;
   326             } else {
   328             } else {
   327               os::naked_short_sleep(1);
   329               os::naked_short_sleep(1);
   328             }
   330             }
   329 
   331 
  1188 jlong  SafepointSynchronize::_max_sync_time = 0;
  1190 jlong  SafepointSynchronize::_max_sync_time = 0;
  1189 jlong  SafepointSynchronize::_max_vmop_time = 0;
  1191 jlong  SafepointSynchronize::_max_vmop_time = 0;
  1190 float  SafepointSynchronize::_ts_of_current_safepoint = 0.0f;
  1192 float  SafepointSynchronize::_ts_of_current_safepoint = 0.0f;
  1191 
  1193 
  1192 static jlong  cleanup_end_time = 0;
  1194 static jlong  cleanup_end_time = 0;
  1193 static bool   need_to_track_page_armed_status = false;
       
  1194 static bool   init_done = false;
  1195 static bool   init_done = false;
  1195 
  1196 
  1196 // Helper method to print the header.
  1197 // Helper method to print the header.
  1197 static void print_header() {
  1198 static void print_header() {
  1198   // The number of spaces is significant here, and should match the format
  1199   // The number of spaces is significant here, and should match the format
  1199   // specifiers in print_statistics().
  1200   // specifiers in print_statistics().
  1200 
  1201 
  1201   tty->print("          vmop                            "
  1202   tty->print("          vmop                            "
  1202              "[ threads:    total initially_running wait_to_block ]"
  1203              "[ threads:    total initially_running wait_to_block ]"
  1203              "[ time:    spin   block    sync cleanup    vmop ] ");
  1204              "[ time:    spin   block    sync cleanup    vmop ] ");
  1204 
       
  1205   // no page armed status printed out if it is always armed.
       
  1206   if (need_to_track_page_armed_status) {
       
  1207     tty->print("page_armed ");
       
  1208   }
       
  1209 
  1205 
  1210   tty->print_cr("page_trap_count");
  1206   tty->print_cr("page_trap_count");
  1211 }
  1207 }
  1212 
  1208 
  1213 void SafepointSynchronize::deferred_initialize_stat() {
  1209 void SafepointSynchronize::deferred_initialize_stat() {
  1227   _safepoint_stats = (SafepointStats*)os::malloc(stats_array_size
  1223   _safepoint_stats = (SafepointStats*)os::malloc(stats_array_size
  1228                                                  * sizeof(SafepointStats), mtInternal);
  1224                                                  * sizeof(SafepointStats), mtInternal);
  1229   guarantee(_safepoint_stats != NULL,
  1225   guarantee(_safepoint_stats != NULL,
  1230             "not enough memory for safepoint instrumentation data");
  1226             "not enough memory for safepoint instrumentation data");
  1231 
  1227 
  1232   if (DeferPollingPageLoopCount >= 0) {
       
  1233     need_to_track_page_armed_status = true;
       
  1234   }
       
  1235   init_done = true;
  1228   init_done = true;
  1236 }
  1229 }
  1237 
  1230 
  1238 void SafepointSynchronize::begin_statistics(int nof_threads, int nof_running) {
  1231 void SafepointSynchronize::begin_statistics(int nof_threads, int nof_running) {
  1239   assert(init_done, "safepoint statistics array hasn't been initialized");
  1232   assert(init_done, "safepoint statistics array hasn't been initialized");
  1267   jlong cur_time = os::javaTimeNanos();
  1260   jlong cur_time = os::javaTimeNanos();
  1268 
  1261 
  1269   spstat->_nof_threads_wait_to_block = _waiting_to_block;
  1262   spstat->_nof_threads_wait_to_block = _waiting_to_block;
  1270   if (spstat->_nof_initial_running_threads != 0) {
  1263   if (spstat->_nof_initial_running_threads != 0) {
  1271     spstat->_time_to_spin = cur_time - spstat->_time_to_spin;
  1264     spstat->_time_to_spin = cur_time - spstat->_time_to_spin;
  1272   }
       
  1273 
       
  1274   if (need_to_track_page_armed_status) {
       
  1275     spstat->_page_armed = (PageArmed == 1);
       
  1276   }
  1265   }
  1277 
  1266 
  1278   // Records the start time of waiting for to block. Updated when block is done.
  1267   // Records the start time of waiting for to block. Updated when block is done.
  1279   if (_waiting_to_block != 0) {
  1268   if (_waiting_to_block != 0) {
  1280     spstat->_time_to_wait_to_block = cur_time;
  1269     spstat->_time_to_wait_to_block = cur_time;
  1361                (int64_t)(sstats->_time_to_wait_to_block / MICROUNITS),
  1350                (int64_t)(sstats->_time_to_wait_to_block / MICROUNITS),
  1362                (int64_t)(sstats->_time_to_sync / MICROUNITS),
  1351                (int64_t)(sstats->_time_to_sync / MICROUNITS),
  1363                (int64_t)(sstats->_time_to_do_cleanups / MICROUNITS),
  1352                (int64_t)(sstats->_time_to_do_cleanups / MICROUNITS),
  1364                (int64_t)(sstats->_time_to_exec_vmop / MICROUNITS));
  1353                (int64_t)(sstats->_time_to_exec_vmop / MICROUNITS));
  1365 
  1354 
  1366     if (need_to_track_page_armed_status) {
       
  1367       tty->print(INT32_FORMAT_W(10) " ", sstats->_page_armed);
       
  1368     }
       
  1369     tty->print_cr(INT32_FORMAT_W(15) " ", sstats->_nof_threads_hit_page_trap);
  1355     tty->print_cr(INT32_FORMAT_W(15) " ", sstats->_nof_threads_hit_page_trap);
  1370   }
  1356   }
  1371 }
  1357 }
  1372 
  1358 
  1373 // This method will be called when VM exits. It will first call
  1359 // This method will be called when VM exits. It will first call
  1390     print_statistics();
  1376     print_statistics();
  1391   }
  1377   }
  1392   tty->cr();
  1378   tty->cr();
  1393 
  1379 
  1394   // Print out polling page sampling status.
  1380   // Print out polling page sampling status.
  1395   if (!need_to_track_page_armed_status) {
  1381   tty->print_cr("Polling page always armed");
  1396     tty->print_cr("Polling page always armed");
       
  1397   } else {
       
  1398     tty->print_cr("Defer polling page loop count = " INTX_FORMAT "\n",
       
  1399                   DeferPollingPageLoopCount);
       
  1400   }
       
  1401 
  1382 
  1402   for (int index = 0; index < VM_Operation::VMOp_Terminating; index++) {
  1383   for (int index = 0; index < VM_Operation::VMOp_Terminating; index++) {
  1403     if (_safepoint_reasons[index] != 0) {
  1384     if (_safepoint_reasons[index] != 0) {
  1404       tty->print_cr("%-26s" UINT64_FORMAT_W(10), VM_Operation::name(index),
  1385       tty->print_cr("%-26s" UINT64_FORMAT_W(10), VM_Operation::name(index),
  1405                     _safepoint_reasons[index]);
  1386                     _safepoint_reasons[index]);