< prev index next >

src/hotspot/share/runtime/vmThread.cpp

Print this page

 20  * or visit www.oracle.com if you need additional information or have any
 21  * questions.
 22  *
 23  */
 24 
 25 #include "compiler/compileBroker.hpp"
 26 #include "gc/shared/collectedHeap.hpp"
 27 #include "jfr/jfrEvents.hpp"
 28 #include "jfr/support/jfrThreadId.hpp"
 29 #include "logging/log.hpp"
 30 #include "logging/logStream.hpp"
 31 #include "logging/logConfiguration.hpp"
 32 #include "memory/resourceArea.hpp"
 33 #include "memory/universe.hpp"
 34 #include "oops/oop.inline.hpp"
 35 #include "oops/verifyOopClosure.hpp"
 36 #include "runtime/atomic.hpp"
 37 #include "runtime/cpuTimeCounters.hpp"
 38 #include "runtime/handles.inline.hpp"
 39 #include "runtime/interfaceSupport.inline.hpp"

 40 #include "runtime/javaThread.inline.hpp"
 41 #include "runtime/jniHandles.hpp"
 42 #include "runtime/mutexLocker.hpp"
 43 #include "runtime/os.hpp"
 44 #include "runtime/perfData.hpp"
 45 #include "runtime/safepoint.hpp"
 46 #include "runtime/synchronizer.hpp"
 47 #include "runtime/timerTrace.hpp"
 48 #include "runtime/vmThread.hpp"

 49 #include "runtime/vmOperations.hpp"

 50 #include "utilities/dtrace.hpp"
 51 #include "utilities/events.hpp"
 52 #include "utilities/vmError.hpp"
 53 
 54 
 55 //------------------------------------------------------------------------------------------------------------------
 56 // Timeout machinery
 57 
 58 void VMOperationTimeoutTask::task() {
 59   assert(AbortVMOnVMOperationTimeout, "only if enabled");
 60   if (is_armed()) {
 61     jlong delay = nanos_to_millis(os::javaTimeNanos() - _arm_time);
 62     if (delay > AbortVMOnVMOperationTimeoutDelay) {
 63       fatal("%s VM operation took too long: " JLONG_FORMAT " ms elapsed since VM-op start (timeout: %zd ms)",
 64             _vm_op_name, delay, AbortVMOnVMOperationTimeoutDelay);
 65     }
 66   }
 67 }
 68 
 69 bool VMOperationTimeoutTask::is_armed() {

256     }
257   }
258 }
259 
260 static void post_vm_operation_event(EventExecuteVMOperation* event, VM_Operation* op) {
261   assert(event != nullptr, "invariant");
262   assert(op != nullptr, "invariant");
263   const bool evaluate_at_safepoint = op->evaluate_at_safepoint();
264   event->set_operation(op->type());
265   event->set_safepoint(evaluate_at_safepoint);
266   event->set_blocking(true);
267   event->set_caller(JFR_THREAD_ID(op->calling_thread()));
268   event->set_safepointId(evaluate_at_safepoint ? SafepointSynchronize::safepoint_id() : 0);
269   event->commit();
270 }
271 
272 void VMThread::evaluate_operation(VM_Operation* op) {
273   ResourceMark rm;
274 
275   {
276     PerfTraceTime vm_op_timer(perf_accumulated_vm_operation_time());
277     HOTSPOT_VMOPS_BEGIN(
278                      (char *) op->name(), strlen(op->name()),
279                      op->evaluate_at_safepoint() ? 0 : 1);
280 
281     EventExecuteVMOperation event;
282     op->evaluate();
283     if (event.should_commit()) {
284       post_vm_operation_event(&event, op);
285     }
286 
287     HOTSPOT_VMOPS_END(
288                      (char *) op->name(), strlen(op->name()),
289                      op->evaluate_at_safepoint() ? 0 : 1);
290   }
291 
292   if (UsePerfData && os::is_thread_cpu_time_supported()) {
293     assert(Thread::current() == this, "Must be called from VM thread");
294     // Update vm_thread_cpu_time after each VM operation.
295     ThreadTotalCPUTimeClosure tttc(CPUTimeGroups::CPUTimeType::vm);
296     tttc.do_thread(this);

504   public:
505 #ifdef ASSERT
506     SkipGCALot(Thread* t) : _t(t) {
507       _saved = _t->skip_gcalot();
508       _t->set_skip_gcalot(true);
509     }
510 
511     ~SkipGCALot() {
512       assert(_t->skip_gcalot(), "Save-restore protocol invariant");
513       _t->set_skip_gcalot(_saved);
514     }
515 #else
516     SkipGCALot(Thread* t) { }
517     ~SkipGCALot() { }
518 #endif
519 };
520 
521 void VMThread::execute(VM_Operation* op) {
522   Thread* t = Thread::current();
523 



524   if (t->is_VM_thread()) {
525     op->set_calling_thread(t);
526     ((VMThread*)t)->inner_execute(op);
527     return;
528   }
529 
530   // The current thread must not belong to the SuspendibleThreadSet, because an
531   // on-the-fly safepoint can be waiting for the current thread, and the
532   // current thread will be blocked in wait_until_executed, resulting in
533   // deadlock.
534   assert(!t->is_suspendible_thread(), "precondition");
535   assert(!t->is_indirectly_suspendible_thread(), "precondition");
536 
537   // Avoid re-entrant attempts to gc-a-lot
538   SkipGCALot sgcalot(t);
539 
540   // JavaThread or WatcherThread
541   if (t->is_Java_thread()) {
542     JavaThread::cast(t)->check_for_valid_safepoint_state();
543   }
544 
545   // New request from Java thread, evaluate prologue
546   if (!op->doit_prologue()) {
547     return;   // op was cancelled
548   }
549 
550   op->set_calling_thread(t);
551 
552   wait_until_executed(op);
553 
554   op->doit_epilogue();
555 }
556 
557 void VMThread::verify() {
558   oops_do(&VerifyOopClosure::verify_oop, nullptr);
559 }





















































































 20  * or visit www.oracle.com if you need additional information or have any
 21  * questions.
 22  *
 23  */
 24 
 25 #include "compiler/compileBroker.hpp"
 26 #include "gc/shared/collectedHeap.hpp"
 27 #include "jfr/jfrEvents.hpp"
 28 #include "jfr/support/jfrThreadId.hpp"
 29 #include "logging/log.hpp"
 30 #include "logging/logStream.hpp"
 31 #include "logging/logConfiguration.hpp"
 32 #include "memory/resourceArea.hpp"
 33 #include "memory/universe.hpp"
 34 #include "oops/oop.inline.hpp"
 35 #include "oops/verifyOopClosure.hpp"
 36 #include "runtime/atomic.hpp"
 37 #include "runtime/cpuTimeCounters.hpp"
 38 #include "runtime/handles.inline.hpp"
 39 #include "runtime/interfaceSupport.inline.hpp"
 40 #include "runtime/java.hpp"
 41 #include "runtime/javaThread.inline.hpp"
 42 #include "runtime/jniHandles.hpp"
 43 #include "runtime/mutexLocker.hpp"
 44 #include "runtime/os.hpp"
 45 #include "runtime/perfData.inline.hpp"
 46 #include "runtime/safepoint.hpp"
 47 #include "runtime/synchronizer.hpp"
 48 #include "runtime/timerTrace.hpp"
 49 #include "runtime/vmThread.hpp"
 50 #include "runtime/vmOperation.hpp"
 51 #include "runtime/vmOperations.hpp"
 52 #include "services/management.hpp"
 53 #include "utilities/dtrace.hpp"
 54 #include "utilities/events.hpp"
 55 #include "utilities/vmError.hpp"
 56 
 57 
 58 //------------------------------------------------------------------------------------------------------------------
 59 // Timeout machinery
 60 
 61 void VMOperationTimeoutTask::task() {
 62   assert(AbortVMOnVMOperationTimeout, "only if enabled");
 63   if (is_armed()) {
 64     jlong delay = nanos_to_millis(os::javaTimeNanos() - _arm_time);
 65     if (delay > AbortVMOnVMOperationTimeoutDelay) {
 66       fatal("%s VM operation took too long: " JLONG_FORMAT " ms elapsed since VM-op start (timeout: %zd ms)",
 67             _vm_op_name, delay, AbortVMOnVMOperationTimeoutDelay);
 68     }
 69   }
 70 }
 71 
 72 bool VMOperationTimeoutTask::is_armed() {

259     }
260   }
261 }
262 
263 static void post_vm_operation_event(EventExecuteVMOperation* event, VM_Operation* op) {
264   assert(event != nullptr, "invariant");
265   assert(op != nullptr, "invariant");
266   const bool evaluate_at_safepoint = op->evaluate_at_safepoint();
267   event->set_operation(op->type());
268   event->set_safepoint(evaluate_at_safepoint);
269   event->set_blocking(true);
270   event->set_caller(JFR_THREAD_ID(op->calling_thread()));
271   event->set_safepointId(evaluate_at_safepoint ? SafepointSynchronize::safepoint_id() : 0);
272   event->commit();
273 }
274 
275 void VMThread::evaluate_operation(VM_Operation* op) {
276   ResourceMark rm;
277 
278   {
279     PerfTraceElapsedTime vm_op_timer(perf_accumulated_vm_operation_time());
280     HOTSPOT_VMOPS_BEGIN(
281                      (char *) op->name(), strlen(op->name()),
282                      op->evaluate_at_safepoint() ? 0 : 1);
283 
284     EventExecuteVMOperation event;
285     op->evaluate();
286     if (event.should_commit()) {
287       post_vm_operation_event(&event, op);
288     }
289 
290     HOTSPOT_VMOPS_END(
291                      (char *) op->name(), strlen(op->name()),
292                      op->evaluate_at_safepoint() ? 0 : 1);
293   }
294 
295   if (UsePerfData && os::is_thread_cpu_time_supported()) {
296     assert(Thread::current() == this, "Must be called from VM thread");
297     // Update vm_thread_cpu_time after each VM operation.
298     ThreadTotalCPUTimeClosure tttc(CPUTimeGroups::CPUTimeType::vm);
299     tttc.do_thread(this);

507   public:
508 #ifdef ASSERT
509     SkipGCALot(Thread* t) : _t(t) {
510       _saved = _t->skip_gcalot();
511       _t->set_skip_gcalot(true);
512     }
513 
514     ~SkipGCALot() {
515       assert(_t->skip_gcalot(), "Save-restore protocol invariant");
516       _t->set_skip_gcalot(_saved);
517     }
518 #else
519     SkipGCALot(Thread* t) { }
520     ~SkipGCALot() { }
521 #endif
522 };
523 
524 void VMThread::execute(VM_Operation* op) {
525   Thread* t = Thread::current();
526 
527   PerfTraceTimedEvent p(VMThread::get_perf_timer_for(op), VMThread::get_perf_counter_for(op), \
528                         Thread::current()->profile_vm_ops()); \
529 
530   if (t->is_VM_thread()) {
531     op->set_calling_thread(t);
532     ((VMThread*)t)->inner_execute(op);
533     return;
534   }
535 
536   // The current thread must not belong to the SuspendibleThreadSet, because an
537   // on-the-fly safepoint can be waiting for the current thread, and the
538   // current thread will be blocked in wait_until_executed, resulting in
539   // deadlock.
540   assert(!t->is_suspendible_thread(), "precondition");
541   assert(!t->is_indirectly_suspendible_thread(), "precondition");
542 
543   // Avoid re-entrant attempts to gc-a-lot
544   SkipGCALot sgcalot(t);
545 
546   // JavaThread or WatcherThread
547   if (t->is_Java_thread()) {
548     JavaThread::cast(t)->check_for_valid_safepoint_state();
549   }
550 
551   // New request from Java thread, evaluate prologue
552   if (!op->doit_prologue()) {
553     return;   // op was cancelled
554   }
555 
556   op->set_calling_thread(t);
557 
558   wait_until_executed(op);
559 
560   op->doit_epilogue();
561 }
562 
563 void VMThread::verify() {
564   oops_do(&VerifyOopClosure::verify_oop, nullptr);
565 }
566 
567 #define DECLARE_COUNTER(name) \
568 PerfTickCounters* _perf_##name##_timer = nullptr; \
569 PerfCounter*      _perf_##name##_count = nullptr;
570 
571 VM_OPS_DO(DECLARE_COUNTER)
572 
573 #undef DECLARE_COUNTER
574 
575 #define SWITCH_TIMER(name) \
576 case VM_Operation::VMOp_##name: return _perf_##name##_timer;
577 
578 PerfTickCounters* VMThread::get_perf_timer_for(VM_Operation *op) {
579   switch(op->type()) {
580     VM_OPS_DO(SWITCH_TIMER)
581     default: ShouldNotReachHere();
582   }
583 }
584 
585 #undef SWITCH_TIMER
586 
587 #define SWITCH_COUNT(name) \
588 case VM_Operation::VMOp_##name: return _perf_##name##_count;
589 
590 PerfCounter* VMThread::get_perf_counter_for(VM_Operation *op) {
591   switch(op->type()) {
592     VM_OPS_DO(SWITCH_COUNT)
593     default: ShouldNotReachHere();
594   }
595 }
596 
597 #undef SWITCH_COUNT
598 
599 #define INIT_COUNTER(name) \
600     NEWPERFTICKCOUNTERS(_perf_##name##_timer, SUN_RT, #name "_time"); \
601     NEWPERFEVENTCOUNTER(_perf_##name##_count, SUN_RT, #name "_count"); \
602 
603 void VMThread::init_counters() {
604   if (ProfileVMOps && UsePerfData) {
605     EXCEPTION_MARK;
606 
607     VM_OPS_DO(INIT_COUNTER)
608 
609     if (HAS_PENDING_EXCEPTION) {
610       vm_exit_during_initialization("jvm_perf_init failed unexpectedly");
611     }
612   }
613 }
614 
615 #undef INIT_COUNTER
616 
617 static jlong total_count() {
618   jlong total = 0;
619 #define ACC_COUNT(name) total += _perf_##name##_count->get_value();
620   VM_OPS_DO(ACC_COUNT)
621 #undef ACC_COUNT
622   return total;
623 }
624 
625 static jlong total_elapsed_time_in_ms() {
626   jlong total_elapsed_ticks = 0;
627 #define ACC_COUNT(name) total_elapsed_ticks += _perf_##name##_timer->elapsed_counter_value();
628   VM_OPS_DO(ACC_COUNT)
629 #undef ACC_COUNT
630   return Management::ticks_to_ms(total_elapsed_ticks);
631 }
632 
633 #define PRINT_COUNTER(name) {\
634   jlong count = _perf_##name##_count->get_value(); \
635   if (count > 0) { \
636     st->print_cr("  %-40s = " JLONG_FORMAT_W(6) "us (" JLONG_FORMAT_W(5) " events)", #name, _perf_##name##_timer->elapsed_counter_value_us(), count); \
637   }}
638 
639 void VMThread::print_counters_on(outputStream* st) {
640   if (ProfileVMOps && UsePerfData) {
641     st->print_cr("VMOperation: Total: " JLONG_FORMAT " events (elapsed " JLONG_FORMAT "ms) for thread \"main\":",
642                  total_count(), total_elapsed_time_in_ms());
643     VM_OPS_DO(PRINT_COUNTER)
644   } else {
645     st->print_cr("  VMOperations:  no info (%s is disabled)", (UsePerfData ? "ProfileVMCalls" : "UsePerfData"));
646   }
647 }
648 
649 #undef PRINT_COUNTER
< prev index next >