8152955: Many safepoints of "no vm operation" kind
Reviewed-by: dholmes, rkennke, shade
--- a/hotspot/src/share/vm/runtime/safepoint.cpp Thu May 25 09:38:33 2017 +0200
+++ b/hotspot/src/share/vm/runtime/safepoint.cpp Thu May 25 09:43:43 2017 +0200
@@ -396,9 +396,7 @@
GCLocker::set_jni_lock_count(_current_jni_active_count);
if (log_is_enabled(Debug, safepoint)) {
- VM_Operation *op = VMThread::vm_operation();
- log_debug(safepoint)("Entering safepoint region: %s",
- (op != NULL) ? op->name() : "no vm operation");
+ log_debug(safepoint)("Entering safepoint region: %s", VMThread::vm_safepoint_description());
}
RuntimeService::record_safepoint_synchronized();
@@ -845,10 +843,8 @@
// To debug the long safepoint, specify both DieOnSafepointTimeout &
// ShowMessageBoxOnError.
if (DieOnSafepointTimeout) {
- VM_Operation *op = VMThread::vm_operation();
fatal("Safepoint sync time longer than " INTX_FORMAT "ms detected when executing %s.",
- SafepointTimeoutDelay,
- op != NULL ? op->name() : "no vm operation");
+ SafepointTimeoutDelay, VMThread::vm_safepoint_description());
}
}
--- a/hotspot/src/share/vm/runtime/vmThread.cpp Thu May 25 09:38:33 2017 +0200
+++ b/hotspot/src/share/vm/runtime/vmThread.cpp Thu May 25 09:43:43 2017 +0200
@@ -204,6 +204,7 @@
VM_Operation* VMThread::_cur_vm_operation = NULL;
VMOperationQueue* VMThread::_vm_queue = NULL;
PerfCounter* VMThread::_perf_accumulated_vm_operation_time = NULL;
+const char* VMThread::_no_op_reason = NULL;
void VMThread::create() {
@@ -273,6 +274,7 @@
}
// 4526887 let VM thread exit at Safepoint
+ _no_op_reason = "Halt";
SafepointSynchronize::begin();
if (VerifyBeforeExit) {
@@ -380,6 +382,25 @@
}
}
+bool VMThread::no_op_safepoint_needed(bool check_time) {
+ if (SafepointALot) {
+ _no_op_reason = "SafepointALot";
+ return true;
+ }
+ if (!SafepointSynchronize::is_cleanup_needed()) {
+ return false;
+ }
+ if (check_time) {
+ long interval = SafepointSynchronize::last_non_safepoint_interval();
+ bool max_time_exceeded = GuaranteedSafepointInterval != 0 &&
+ (interval > GuaranteedSafepointInterval);
+ if (!max_time_exceeded) {
+ return false;
+ }
+ }
+ _no_op_reason = "Cleanup";
+ return true;
+}
void VMThread::loop() {
assert(_cur_vm_operation == NULL, "no current one should be executing");
@@ -418,8 +439,7 @@
exit(-1);
}
- if (timedout && (SafepointALot ||
- SafepointSynchronize::is_cleanup_needed())) {
+ if (timedout && VMThread::no_op_safepoint_needed(false)) {
MutexUnlockerEx mul(VMOperationQueue_lock,
Mutex::_no_safepoint_check_flag);
// Force a safepoint since we have not had one for at least
@@ -542,14 +562,10 @@
//
// We want to make sure that we get to a safepoint regularly.
//
- if (SafepointALot || SafepointSynchronize::is_cleanup_needed()) {
- long interval = SafepointSynchronize::last_non_safepoint_interval();
- bool max_time_exceeded = GuaranteedSafepointInterval != 0 && (interval > GuaranteedSafepointInterval);
- if (SafepointALot || max_time_exceeded) {
- HandleMark hm(VMThread::vm_thread());
- SafepointSynchronize::begin();
- SafepointSynchronize::end();
- }
+ if (VMThread::no_op_safepoint_needed(true)) {
+ HandleMark hm(VMThread::vm_thread());
+ SafepointSynchronize::begin();
+ SafepointSynchronize::end();
}
}
}
--- a/hotspot/src/share/vm/runtime/vmThread.hpp Thu May 25 09:38:33 2017 +0200
+++ b/hotspot/src/share/vm/runtime/vmThread.hpp Thu May 25 09:43:43 2017 +0200
@@ -99,7 +99,12 @@
static Monitor * _terminate_lock;
static PerfCounter* _perf_accumulated_vm_operation_time;
+ static const char* _no_op_reason;
+
+ static bool no_op_safepoint_needed(bool check_time);
+
void evaluate_operation(VM_Operation* op);
+
public:
// Constructor
VMThread();
@@ -126,7 +131,10 @@
static void execute(VM_Operation* op);
// Returns the current vm operation if any.
- static VM_Operation* vm_operation() { return _cur_vm_operation; }
+ static VM_Operation* vm_operation() { return _cur_vm_operation; }
+
+ // Returns the current vm operation name or set reason
+ static const char* vm_safepoint_description() { return _cur_vm_operation != NULL ? _cur_vm_operation->name() : _no_op_reason; };
// Returns the single instance of VMThread.
static VMThread* vm_thread() { return _vm_thread; }