< prev index next >

src/hotspot/share/runtime/vmThread.cpp

Print this page
rev 52955 : 8181143: Introduce diagnostic flag to abort VM on too long VM operations
Reviewed-by: XXX


  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #include "precompiled.hpp"
  26 #include "compiler/compileBroker.hpp"
  27 #include "gc/shared/collectedHeap.hpp"
  28 #include "jfr/jfrEvents.hpp"
  29 #include "jfr/support/jfrThreadId.hpp"
  30 #include "logging/log.hpp"

  31 #include "logging/logConfiguration.hpp"
  32 #include "memory/resourceArea.hpp"
  33 #include "oops/method.hpp"
  34 #include "oops/oop.inline.hpp"
  35 #include "oops/verifyOopClosure.hpp"
  36 #include "runtime/interfaceSupport.inline.hpp"
  37 #include "runtime/mutexLocker.hpp"
  38 #include "runtime/os.hpp"
  39 #include "runtime/safepoint.hpp"
  40 #include "runtime/thread.inline.hpp"
  41 #include "runtime/vmThread.hpp"
  42 #include "runtime/vmOperations.hpp"
  43 #include "services/runtimeService.hpp"
  44 #include "utilities/dtrace.hpp"
  45 #include "utilities/events.hpp"
  46 #include "utilities/vmError.hpp"
  47 #include "utilities/xmlstream.hpp"
  48 
  49 // Dummy VM operation to act as first element in our circular double-linked list
  50 class VM_None: public VM_Operation {


 180   int high_prio, low_prio;
 181   if (_queue_counter++ < 10) {
 182       high_prio = SafepointPriority;
 183       low_prio  = MediumPriority;
 184   } else {
 185       _queue_counter = 0;
 186       high_prio = MediumPriority;
 187       low_prio  = SafepointPriority;
 188   }
 189 
 190   return queue_remove_front(queue_empty(high_prio) ? low_prio : high_prio);
 191 }
 192 
 193 void VMOperationQueue::oops_do(OopClosure* f) {
 194   for(int i = 0; i < nof_priorities; i++) {
 195     queue_oops_do(i, f);
 196   }
 197   drain_list_oops_do(f);
 198 }
 199 


























 200 
 201 //------------------------------------------------------------------------------------------------------------------
 202 // Implementation of VMThread stuff
 203 
 204 bool                VMThread::_should_terminate   = false;
 205 bool              VMThread::_terminated         = false;
 206 Monitor*          VMThread::_terminate_lock     = NULL;
 207 VMThread*         VMThread::_vm_thread          = NULL;
 208 VM_Operation*     VMThread::_cur_vm_operation   = NULL;
 209 VMOperationQueue* VMThread::_vm_queue           = NULL;
 210 PerfCounter*      VMThread::_perf_accumulated_vm_operation_time = NULL;
 211 const char*       VMThread::_no_op_reason       = NULL;

 212 
 213 
 214 void VMThread::create() {
 215   assert(vm_thread() == NULL, "we can only allocate one VMThread");
 216   _vm_thread = new VMThread();
 217 















 218   // Create VM operation queue
 219   _vm_queue = new VMOperationQueue();
 220   guarantee(_vm_queue != NULL, "just checking");
 221 
 222   _terminate_lock = new Monitor(Mutex::safepoint, "VMThread::_terminate_lock", true,
 223                                 Monitor::_safepoint_check_never);
 224 
 225   if (UsePerfData) {
 226     // jvmstat performance counters
 227     Thread* THREAD = Thread::current();
 228     _perf_accumulated_vm_operation_time =
 229                  PerfDataManager::create_counter(SUN_THREADS, "vmOperationTime",
 230                                                  PerfData::U_Ticks, CHECK);
 231   }
 232 }
 233 
 234 VMThread::VMThread() : NamedThread() {
 235   set_name("VM Thread");
 236 }
 237 


 475 
 476       if (should_terminate()) break;
 477     } // Release mu_queue_lock
 478 
 479     //
 480     // Execute VM operation
 481     //
 482     { HandleMark hm(VMThread::vm_thread());
 483 
 484       EventMark em("Executing VM operation: %s", vm_operation()->name());
 485       assert(_cur_vm_operation != NULL, "we should have found an operation to execute");
 486 
 487       // If we are at a safepoint we will evaluate all the operations that
 488       // follow that also require a safepoint
 489       if (_cur_vm_operation->evaluate_at_safepoint()) {
 490         log_debug(vmthread)("Evaluating safepoint VM operation: %s", _cur_vm_operation->name());
 491 
 492         _vm_queue->set_drain_list(safepoint_ops); // ensure ops can be scanned
 493 
 494         SafepointSynchronize::begin();





 495         evaluate_operation(_cur_vm_operation);
 496         // now process all queued safepoint ops, iteratively draining
 497         // the queue until there are none left
 498         do {
 499           _cur_vm_operation = safepoint_ops;
 500           if (_cur_vm_operation != NULL) {
 501             do {
 502               log_debug(vmthread)("Evaluating coalesced safepoint VM operation: %s", _cur_vm_operation->name());
 503               // evaluate_operation deletes the op object so we have
 504               // to grab the next op now
 505               VM_Operation* next = _cur_vm_operation->next();
 506               _vm_queue->set_drain_list(next);
 507               evaluate_operation(_cur_vm_operation);
 508               _cur_vm_operation = next;
 509               if (log_is_enabled(Debug, safepoint, stats)) {
 510                 SafepointSynchronize::inc_vmop_coalesced_count();
 511               }
 512             } while (_cur_vm_operation != NULL);
 513           }
 514           // There is a chance that a thread enqueued a safepoint op
 515           // since we released the op-queue lock and initiated the safepoint.
 516           // So we drain the queue again if there is anything there, as an
 517           // optimization to try and reduce the number of safepoints.
 518           // As the safepoint synchronizes us with JavaThreads we will see
 519           // any enqueue made by a JavaThread, but the peek will not
 520           // necessarily detect a concurrent enqueue by a GC thread, but
 521           // that simply means the op will wait for the next major cycle of the
 522           // VMThread - just as it would if the GC thread lost the race for
 523           // the lock.
 524           if (_vm_queue->peek_at_safepoint_priority()) {
 525             // must hold lock while draining queue
 526             MutexLockerEx mu_queue(VMOperationQueue_lock,
 527                                      Mutex::_no_safepoint_check_flag);
 528             safepoint_ops = _vm_queue->drain_at_safepoint_priority();
 529           } else {
 530             safepoint_ops = NULL;
 531           }
 532         } while(safepoint_ops != NULL);
 533 
 534         _vm_queue->set_drain_list(NULL);




 535 
 536         // Complete safepoint synchronization
 537         SafepointSynchronize::end();
 538 
 539       } else {  // not a safepoint operation
 540         log_debug(vmthread)("Evaluating non-safepoint VM operation: %s", _cur_vm_operation->name());
 541         if (TraceLongCompiles) {
 542           elapsedTimer t;
 543           t.start();
 544           evaluate_operation(_cur_vm_operation);
 545           t.stop();
 546           double secs = t.seconds();
 547           if (secs * 1e3 > LongCompileThreshold) {
 548             // XXX - _cur_vm_operation should not be accessed after
 549             // the completed count has been incremented; the waiting
 550             // thread may have already freed this memory.
 551             tty->print_cr("vm %s: %3.7f secs]", _cur_vm_operation->name(), secs);
 552           }
 553         } else {
 554           evaluate_operation(_cur_vm_operation);




  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #include "precompiled.hpp"
  26 #include "compiler/compileBroker.hpp"
  27 #include "gc/shared/collectedHeap.hpp"
  28 #include "jfr/jfrEvents.hpp"
  29 #include "jfr/support/jfrThreadId.hpp"
  30 #include "logging/log.hpp"
  31 #include "logging/logStream.hpp"
  32 #include "logging/logConfiguration.hpp"
  33 #include "memory/resourceArea.hpp"
  34 #include "oops/method.hpp"
  35 #include "oops/oop.inline.hpp"
  36 #include "oops/verifyOopClosure.hpp"
  37 #include "runtime/interfaceSupport.inline.hpp"
  38 #include "runtime/mutexLocker.hpp"
  39 #include "runtime/os.hpp"
  40 #include "runtime/safepoint.hpp"
  41 #include "runtime/thread.inline.hpp"
  42 #include "runtime/vmThread.hpp"
  43 #include "runtime/vmOperations.hpp"
  44 #include "services/runtimeService.hpp"
  45 #include "utilities/dtrace.hpp"
  46 #include "utilities/events.hpp"
  47 #include "utilities/vmError.hpp"
  48 #include "utilities/xmlstream.hpp"
  49 
  50 // Dummy VM operation to act as first element in our circular double-linked list
  51 class VM_None: public VM_Operation {


 181   int high_prio, low_prio;
 182   if (_queue_counter++ < 10) {
 183       high_prio = SafepointPriority;
 184       low_prio  = MediumPriority;
 185   } else {
 186       _queue_counter = 0;
 187       high_prio = MediumPriority;
 188       low_prio  = SafepointPriority;
 189   }
 190 
 191   return queue_remove_front(queue_empty(high_prio) ? low_prio : high_prio);
 192 }
 193 
 194 void VMOperationQueue::oops_do(OopClosure* f) {
 195   for(int i = 0; i < nof_priorities; i++) {
 196     queue_oops_do(i, f);
 197   }
 198   drain_list_oops_do(f);
 199 }
 200 
 201 //------------------------------------------------------------------------------------------------------------------
 202 // Timeout machinery
 203 
 204 void VMOperationTimeoutTask::task() {
 205   assert(AbortVMOnVMOperationTimeout, "only if enabled");
 206   if (is_armed()) {
 207     jlong delay = (os::javaTimeMillis() - _arm_time);
 208     if (delay > AbortVMOnVMOperationTimeoutDelay) {
 209       fatal("VM operation took too long: " SIZE_FORMAT " ms (timeout: " SIZE_FORMAT " ms)",
 210             delay, AbortVMOnVMOperationTimeoutDelay);
 211     }
 212   }
 213 }
 214 
 215 bool VMOperationTimeoutTask::is_armed() {
 216   return OrderAccess::load_acquire(&_armed) != 0;
 217 }
 218 
 219 void VMOperationTimeoutTask::arm() {
 220   _arm_time = os::javaTimeMillis();
 221   OrderAccess::release_store_fence(&_armed, 1);
 222 }
 223 
 224 void VMOperationTimeoutTask::disarm() {
 225   OrderAccess::release_store_fence(&_armed, 0);
 226 }
 227 
 228 //------------------------------------------------------------------------------------------------------------------
 229 // Implementation of VMThread stuff
 230 
 231 bool                VMThread::_should_terminate   = false;
 232 bool              VMThread::_terminated         = false;
 233 Monitor*          VMThread::_terminate_lock     = NULL;
 234 VMThread*         VMThread::_vm_thread          = NULL;
 235 VM_Operation*     VMThread::_cur_vm_operation   = NULL;
 236 VMOperationQueue* VMThread::_vm_queue           = NULL;
 237 PerfCounter*      VMThread::_perf_accumulated_vm_operation_time = NULL;
 238 const char*       VMThread::_no_op_reason       = NULL;
 239 VMOperationTimeoutTask* VMThread::_timeout_task = NULL;
 240 
 241 
 242 void VMThread::create() {
 243   assert(vm_thread() == NULL, "we can only allocate one VMThread");
 244   _vm_thread = new VMThread();
 245 
 246   if (AbortVMOnVMOperationTimeout) {
 247     // Make sure we call the timeout task frequently enough, but not too frequent.
 248     // Try to make the interval 10% of the timeout delay, so that we miss the timeout
 249     // by those 10% at max. Periodic task also expects it to fit min/max intervals.
 250     size_t interval = (size_t)AbortVMOnVMOperationTimeoutDelay / 10;
 251     interval = interval / PeriodicTask::interval_gran * PeriodicTask::interval_gran;
 252     interval = MAX2<size_t>(interval, PeriodicTask::min_interval);
 253     interval = MIN2<size_t>(interval, PeriodicTask::max_interval);
 254 
 255     _timeout_task = new VMOperationTimeoutTask(interval);
 256     _timeout_task->enroll();
 257   } else {
 258     assert(_timeout_task == NULL, "sanity");
 259   }
 260 
 261   // Create VM operation queue
 262   _vm_queue = new VMOperationQueue();
 263   guarantee(_vm_queue != NULL, "just checking");
 264 
 265   _terminate_lock = new Monitor(Mutex::safepoint, "VMThread::_terminate_lock", true,
 266                                 Monitor::_safepoint_check_never);
 267 
 268   if (UsePerfData) {
 269     // jvmstat performance counters
 270     Thread* THREAD = Thread::current();
 271     _perf_accumulated_vm_operation_time =
 272                  PerfDataManager::create_counter(SUN_THREADS, "vmOperationTime",
 273                                                  PerfData::U_Ticks, CHECK);
 274   }
 275 }
 276 
 277 VMThread::VMThread() : NamedThread() {
 278   set_name("VM Thread");
 279 }
 280 


 518 
 519       if (should_terminate()) break;
 520     } // Release mu_queue_lock
 521 
 522     //
 523     // Execute VM operation
 524     //
 525     { HandleMark hm(VMThread::vm_thread());
 526 
 527       EventMark em("Executing VM operation: %s", vm_operation()->name());
 528       assert(_cur_vm_operation != NULL, "we should have found an operation to execute");
 529 
 530       // If we are at a safepoint we will evaluate all the operations that
 531       // follow that also require a safepoint
 532       if (_cur_vm_operation->evaluate_at_safepoint()) {
 533         log_debug(vmthread)("Evaluating safepoint VM operation: %s", _cur_vm_operation->name());
 534 
 535         _vm_queue->set_drain_list(safepoint_ops); // ensure ops can be scanned
 536 
 537         SafepointSynchronize::begin();
 538 
 539         if (_timeout_task != NULL) {
 540           _timeout_task->arm();
 541         }
 542 
 543         evaluate_operation(_cur_vm_operation);
 544         // now process all queued safepoint ops, iteratively draining
 545         // the queue until there are none left
 546         do {
 547           _cur_vm_operation = safepoint_ops;
 548           if (_cur_vm_operation != NULL) {
 549             do {
 550               log_debug(vmthread)("Evaluating coalesced safepoint VM operation: %s", _cur_vm_operation->name());
 551               // evaluate_operation deletes the op object so we have
 552               // to grab the next op now
 553               VM_Operation* next = _cur_vm_operation->next();
 554               _vm_queue->set_drain_list(next);
 555               evaluate_operation(_cur_vm_operation);
 556               _cur_vm_operation = next;
 557               if (log_is_enabled(Debug, safepoint, stats)) {
 558                 SafepointSynchronize::inc_vmop_coalesced_count();
 559               }
 560             } while (_cur_vm_operation != NULL);
 561           }
 562           // There is a chance that a thread enqueued a safepoint op
 563           // since we released the op-queue lock and initiated the safepoint.
 564           // So we drain the queue again if there is anything there, as an
 565           // optimization to try and reduce the number of safepoints.
 566           // As the safepoint synchronizes us with JavaThreads we will see
 567           // any enqueue made by a JavaThread, but the peek will not
 568           // necessarily detect a concurrent enqueue by a GC thread, but
 569           // that simply means the op will wait for the next major cycle of the
 570           // VMThread - just as it would if the GC thread lost the race for
 571           // the lock.
 572           if (_vm_queue->peek_at_safepoint_priority()) {
 573             // must hold lock while draining queue
 574             MutexLockerEx mu_queue(VMOperationQueue_lock,
 575                                      Mutex::_no_safepoint_check_flag);
 576             safepoint_ops = _vm_queue->drain_at_safepoint_priority();
 577           } else {
 578             safepoint_ops = NULL;
 579           }
 580         } while(safepoint_ops != NULL);
 581 
 582         _vm_queue->set_drain_list(NULL);
 583 
 584         if (_timeout_task != NULL) {
 585           _timeout_task->disarm();
 586         }
 587 
 588         // Complete safepoint synchronization
 589         SafepointSynchronize::end();
 590 
 591       } else {  // not a safepoint operation
 592         log_debug(vmthread)("Evaluating non-safepoint VM operation: %s", _cur_vm_operation->name());
 593         if (TraceLongCompiles) {
 594           elapsedTimer t;
 595           t.start();
 596           evaluate_operation(_cur_vm_operation);
 597           t.stop();
 598           double secs = t.seconds();
 599           if (secs * 1e3 > LongCompileThreshold) {
 600             // XXX - _cur_vm_operation should not be accessed after
 601             // the completed count has been incremented; the waiting
 602             // thread may have already freed this memory.
 603             tty->print_cr("vm %s: %3.7f secs]", _cur_vm_operation->name(), secs);
 604           }
 605         } else {
 606           evaluate_operation(_cur_vm_operation);


< prev index next >