8152955: Many safepoints of "no vm operation" kind

Reviewed-by: dholmes, rkennke, shade
This commit is contained in:
Robbin Ehn 2017-05-25 09:43:43 +02:00
parent ad4bc13f9f
commit 3ca4b6b01b
3 changed files with 37 additions and 17 deletions

View File

@ -396,9 +396,7 @@ void SafepointSynchronize::begin() {
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 @@ void SafepointSynchronize::print_safepoint_timeout(SafepointTimeoutReason reason
// 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());
}
}

View File

@ -204,6 +204,7 @@ VMThread* VMThread::_vm_thread = NULL;
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 @@ void VMThread::run() {
}
// 4526887 let VM thread exit at Safepoint
_no_op_reason = "Halt";
SafepointSynchronize::begin();
if (VerifyBeforeExit) {
@ -380,6 +382,25 @@ void VMThread::evaluate_operation(VM_Operation* op) {
}
}
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 @@ void VMThread::loop() {
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 @@ void VMThread::loop() {
//
// 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();
}
}
}

View File

@ -99,7 +99,12 @@ class VMThread: public NamedThread {
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 @@ class VMThread: public NamedThread {
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; }