< 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   // Avoid re-entrant attempts to gc-a-lot
531   SkipGCALot sgcalot(t);
532 
533   // JavaThread or WatcherThread
534   if (t->is_Java_thread()) {
535     JavaThread::cast(t)->check_for_valid_safepoint_state();
536   }
537 
538   // New request from Java thread, evaluate prologue
539   if (!op->doit_prologue()) {
540     return;   // op was cancelled
541   }
542 
543   op->set_calling_thread(t);
544 
545   wait_until_executed(op);
546 
547   op->doit_epilogue();
548 }
549 
550 void VMThread::verify() {
551   oops_do(&VerifyOopClosure::verify_oop, nullptr);
552 }





















































































 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   // Avoid re-entrant attempts to gc-a-lot
537   SkipGCALot sgcalot(t);
538 
539   // JavaThread or WatcherThread
540   if (t->is_Java_thread()) {
541     JavaThread::cast(t)->check_for_valid_safepoint_state();
542   }
543 
544   // New request from Java thread, evaluate prologue
545   if (!op->doit_prologue()) {
546     return;   // op was cancelled
547   }
548 
549   op->set_calling_thread(t);
550 
551   wait_until_executed(op);
552 
553   op->doit_epilogue();
554 }
555 
556 void VMThread::verify() {
557   oops_do(&VerifyOopClosure::verify_oop, nullptr);
558 }
559 
560 #define DECLARE_COUNTER(name) \
561 PerfTickCounters* _perf_##name##_timer = nullptr; \
562 PerfCounter*      _perf_##name##_count = nullptr;
563 
564 VM_OPS_DO(DECLARE_COUNTER)
565 
566 #undef DECLARE_COUNTER
567 
568 #define SWITCH_TIMER(name) \
569 case VM_Operation::VMOp_##name: return _perf_##name##_timer;
570 
571 PerfTickCounters* VMThread::get_perf_timer_for(VM_Operation *op) {
572   switch(op->type()) {
573     VM_OPS_DO(SWITCH_TIMER)
574     default: ShouldNotReachHere();
575   }
576 }
577 
578 #undef SWITCH_TIMER
579 
580 #define SWITCH_COUNT(name) \
581 case VM_Operation::VMOp_##name: return _perf_##name##_count;
582 
583 PerfCounter* VMThread::get_perf_counter_for(VM_Operation *op) {
584   switch(op->type()) {
585     VM_OPS_DO(SWITCH_COUNT)
586     default: ShouldNotReachHere();
587   }
588 }
589 
590 #undef SWITCH_COUNT
591 
592 #define INIT_COUNTER(name) \
593     NEWPERFTICKCOUNTERS(_perf_##name##_timer, SUN_RT, #name "_time"); \
594     NEWPERFEVENTCOUNTER(_perf_##name##_count, SUN_RT, #name "_count"); \
595 
596 void VMThread::init_counters() {
597   if (ProfileVMOps && UsePerfData) {
598     EXCEPTION_MARK;
599 
600     VM_OPS_DO(INIT_COUNTER)
601 
602     if (HAS_PENDING_EXCEPTION) {
603       vm_exit_during_initialization("jvm_perf_init failed unexpectedly");
604     }
605   }
606 }
607 
608 #undef INIT_COUNTER
609 
610 static jlong total_count() {
611   jlong total = 0;
612 #define ACC_COUNT(name) total += _perf_##name##_count->get_value();
613   VM_OPS_DO(ACC_COUNT)
614 #undef ACC_COUNT
615   return total;
616 }
617 
618 static jlong total_elapsed_time_in_ms() {
619   jlong total_elapsed_ticks = 0;
620 #define ACC_COUNT(name) total_elapsed_ticks += _perf_##name##_timer->elapsed_counter_value();
621   VM_OPS_DO(ACC_COUNT)
622 #undef ACC_COUNT
623   return Management::ticks_to_ms(total_elapsed_ticks);
624 }
625 
626 #define PRINT_COUNTER(name) {\
627   jlong count = _perf_##name##_count->get_value(); \
628   if (count > 0) { \
629     st->print_cr("  %-40s = " JLONG_FORMAT_W(6) "us (" JLONG_FORMAT_W(5) " events)", #name, _perf_##name##_timer->elapsed_counter_value_us(), count); \
630   }}
631 
632 void VMThread::print_counters_on(outputStream* st) {
633   if (ProfileVMOps && UsePerfData) {
634     st->print_cr("VMOperation: Total: " JLONG_FORMAT " events (elapsed " JLONG_FORMAT "ms) for thread \"main\":",
635                  total_count(), total_elapsed_time_in_ms());
636     VM_OPS_DO(PRINT_COUNTER)
637   } else {
638     st->print_cr("  VMOperations:  no info (%s is disabled)", (UsePerfData ? "ProfileVMCalls" : "UsePerfData"));
639   }
640 }
641 
642 #undef PRINT_COUNTER
< prev index next >