< prev index next >

src/hotspot/share/runtime/vmThread.cpp

Print this page

 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 "memory/universe.hpp"
 35 #include "oops/oop.inline.hpp"
 36 #include "oops/verifyOopClosure.hpp"
 37 #include "runtime/atomic.hpp"
 38 #include "runtime/cpuTimeCounters.hpp"
 39 #include "runtime/handles.inline.hpp"
 40 #include "runtime/interfaceSupport.inline.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.hpp"
 46 #include "runtime/safepoint.hpp"
 47 #include "runtime/synchronizer.hpp"
 48 #include "runtime/timerTrace.hpp"
 49 #include "runtime/vmThread.hpp"

 50 #include "runtime/vmOperations.hpp"

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

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

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



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





















































































 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 "memory/universe.hpp"
 35 #include "oops/oop.inline.hpp"
 36 #include "oops/verifyOopClosure.hpp"
 37 #include "runtime/atomic.hpp"
 38 #include "runtime/cpuTimeCounters.hpp"
 39 #include "runtime/handles.inline.hpp"
 40 #include "runtime/interfaceSupport.inline.hpp"
 41 #include "runtime/java.hpp"
 42 #include "runtime/javaThread.inline.hpp"
 43 #include "runtime/jniHandles.hpp"
 44 #include "runtime/mutexLocker.hpp"
 45 #include "runtime/os.hpp"
 46 #include "runtime/perfData.inline.hpp"
 47 #include "runtime/safepoint.hpp"
 48 #include "runtime/synchronizer.hpp"
 49 #include "runtime/timerTrace.hpp"
 50 #include "runtime/vmThread.hpp"
 51 #include "runtime/vmOperation.hpp"
 52 #include "runtime/vmOperations.hpp"
 53 #include "services/management.hpp"
 54 #include "utilities/dtrace.hpp"
 55 #include "utilities/events.hpp"
 56 #include "utilities/vmError.hpp"
 57 
 58 
 59 //------------------------------------------------------------------------------------------------------------------
 60 // Timeout machinery
 61 
 62 void VMOperationTimeoutTask::task() {
 63   assert(AbortVMOnVMOperationTimeout, "only if enabled");
 64   if (is_armed()) {
 65     jlong delay = nanos_to_millis(os::javaTimeNanos() - _arm_time);
 66     if (delay > AbortVMOnVMOperationTimeoutDelay) {
 67       fatal("%s VM operation took too long: " JLONG_FORMAT " ms elapsed since VM-op start (timeout: " INTX_FORMAT " ms)",
 68             _vm_op_name, delay, AbortVMOnVMOperationTimeoutDelay);
 69     }
 70   }
 71 }
 72 
 73 bool VMOperationTimeoutTask::is_armed() {

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

508   public:
509 #ifdef ASSERT
510     SkipGCALot(Thread* t) : _t(t) {
511       _saved = _t->skip_gcalot();
512       _t->set_skip_gcalot(true);
513     }
514 
515     ~SkipGCALot() {
516       assert(_t->skip_gcalot(), "Save-restore protocol invariant");
517       _t->set_skip_gcalot(_saved);
518     }
519 #else
520     SkipGCALot(Thread* t) { }
521     ~SkipGCALot() { }
522 #endif
523 };
524 
525 void VMThread::execute(VM_Operation* op) {
526   Thread* t = Thread::current();
527 
528   PerfTraceTimedEvent p(VMThread::get_perf_timer_for(op), VMThread::get_perf_counter_for(op), \
529                         Thread::current()->profile_vm_ops()); \
530 
531   if (t->is_VM_thread()) {
532     op->set_calling_thread(t);
533     ((VMThread*)t)->inner_execute(op);
534     return;
535   }
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 }
560 
561 #define DECLARE_COUNTER(name) \
562 PerfTickCounters* _perf_##name##_timer = nullptr; \
563 PerfCounter*      _perf_##name##_count = nullptr;
564 
565 VM_OPS_DO(DECLARE_COUNTER)
566 
567 #undef DECLARE_COUNTER
568 
569 #define SWITCH_TIMER(name) \
570 case VM_Operation::VMOp_##name: return _perf_##name##_timer;
571 
572 PerfTickCounters* VMThread::get_perf_timer_for(VM_Operation *op) {
573   switch(op->type()) {
574     VM_OPS_DO(SWITCH_TIMER)
575     default: ShouldNotReachHere();
576   }
577 }
578 
579 #undef SWITCH_TIMER
580 
581 #define SWITCH_COUNT(name) \
582 case VM_Operation::VMOp_##name: return _perf_##name##_count;
583 
584 PerfCounter* VMThread::get_perf_counter_for(VM_Operation *op) {
585   switch(op->type()) {
586     VM_OPS_DO(SWITCH_COUNT)
587     default: ShouldNotReachHere();
588   }
589 }
590 
591 #undef SWITCH_COUNT
592 
593 #define INIT_COUNTER(name) \
594     NEWPERFTICKCOUNTERS(_perf_##name##_timer, SUN_RT, #name "_time"); \
595     NEWPERFEVENTCOUNTER(_perf_##name##_count, SUN_RT, #name "_count"); \
596 
597 void VMThread::init_counters() {
598   if (ProfileVMOps && UsePerfData) {
599     EXCEPTION_MARK;
600 
601     VM_OPS_DO(INIT_COUNTER)
602 
603     if (HAS_PENDING_EXCEPTION) {
604       vm_exit_during_initialization("jvm_perf_init failed unexpectedly");
605     }
606   }
607 }
608 
609 #undef INIT_COUNTER
610 
611 static jlong total_count() {
612   jlong total = 0;
613 #define ACC_COUNT(name) total += _perf_##name##_count->get_value();
614   VM_OPS_DO(ACC_COUNT)
615 #undef ACC_COUNT
616   return total;
617 }
618 
619 static jlong total_elapsed_time_in_ms() {
620   jlong total_elapsed_ticks = 0;
621 #define ACC_COUNT(name) total_elapsed_ticks += _perf_##name##_timer->elapsed_counter_value();
622   VM_OPS_DO(ACC_COUNT)
623 #undef ACC_COUNT
624   return Management::ticks_to_ms(total_elapsed_ticks);
625 }
626 
627 #define PRINT_COUNTER(name) {\
628   jlong count = _perf_##name##_count->get_value(); \
629   if (count > 0) { \
630     st->print_cr("  %-40s = %4ldms (%5ld events)", #name, _perf_##name##_timer->elapsed_counter_value_ms(), count); \
631   }}
632 
633 void VMThread::print_counters_on(outputStream* st) {
634   if (ProfileVMOps && UsePerfData) {
635     st->print_cr("VMOperation: Total: %ld events (elapsed %ldms) for thread \"main\":",
636                  total_count(), total_elapsed_time_in_ms());
637     VM_OPS_DO(PRINT_COUNTER)
638   } else {
639     st->print_cr("  VMOperations:  no info (%s is disabled)", (UsePerfData ? "ProfileVMCalls" : "UsePerfData"));
640   }
641 }
642 
643 #undef PRINT_COUNTER
< prev index next >