--- old/src/hotspot/share/prims/jvmtiEnvBase.cpp 2020-06-19 10:37:10.528556210 +0900 +++ new/src/hotspot/share/prims/jvmtiEnvBase.cpp 2020-06-19 10:37:10.449553884 +0900 @@ -937,11 +937,12 @@ jvmtiError JvmtiEnvBase::get_object_monitor_usage(JavaThread* calling_thread, jobject object, jvmtiMonitorUsage* info_ptr) { - HandleMark hm; - Handle hobj; + assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint"); + Thread* current_thread = VMThread::vm_thread(); + assert(current_thread == Thread::current(), "must be"); - Thread* current_thread = Thread::current(); - bool at_safepoint = SafepointSynchronize::is_at_safepoint(); + HandleMark hm(current_thread); + Handle hobj; // Check arguments { @@ -952,6 +953,7 @@ hobj = Handle(current_thread, mirror); } + ThreadsListHandle tlh(current_thread); JavaThread *owning_thread = NULL; ObjectMonitor *mon = NULL; jvmtiMonitorUsage ret = { @@ -962,11 +964,7 @@ // first derive the object's owner and entry_count (if any) { // Revoke any biases before querying the mark word - if (at_safepoint) { - BiasedLocking::revoke_at_safepoint(hobj); - } else { - BiasedLocking::revoke(hobj, calling_thread); - } + BiasedLocking::revoke_at_safepoint(hobj); address owner = NULL; { @@ -994,39 +992,19 @@ } if (owner != NULL) { - // Use current thread since function can be called from a - // JavaThread or the VMThread. - ThreadsListHandle tlh; // This monitor is owned so we have to find the owning JavaThread. owning_thread = Threads::owning_thread_from_monitor_owner(tlh.list(), owner); - // Cannot assume (owning_thread != NULL) here because this function - // may not have been called at a safepoint and the owning_thread - // might not be suspended. - if (owning_thread != NULL) { - // The monitor's owner either has to be the current thread, at safepoint - // or it has to be suspended. Any of these conditions will prevent both - // contending and waiting threads from modifying the state of - // the monitor. - if (!at_safepoint && !owning_thread->is_thread_fully_suspended(true, &debug_bits)) { - // Don't worry! This return of JVMTI_ERROR_THREAD_NOT_SUSPENDED - // will not make it back to the JVM/TI agent. The error code will - // get intercepted in JvmtiEnv::GetObjectMonitorUsage() which - // will retry the call via a VM_GetObjectMonitorUsage VM op. - return JVMTI_ERROR_THREAD_NOT_SUSPENDED; - } - HandleMark hm; - Handle th(current_thread, owning_thread->threadObj()); - ret.owner = (jthread)jni_reference(calling_thread, th); - } - // implied else: no owner - } // ThreadsListHandle is destroyed here. + assert(owning_thread != NULL, "owning JavaThread must not be NULL"); + Handle th(current_thread, owning_thread->threadObj()); + ret.owner = (jthread)jni_reference(calling_thread, th); + } if (owning_thread != NULL) { // monitor is owned // The recursions field of a monitor does not reflect recursions // as lightweight locks before inflating the monitor are not included. // We have to count the number of recursive monitor entries the hard way. // We pass a handle to survive any GCs along the way. - ResourceMark rm; + ResourceMark rm(current_thread); ret.entry_count = count_locked_objects(owning_thread, hobj); } // implied else: entry_count == 0 @@ -1069,13 +1047,9 @@ if (ret.waiter_count > 0) { // we have contending and/or waiting threads - HandleMark hm; - // Use current thread since function can be called from a - // JavaThread or the VMThread. - ThreadsListHandle tlh; if (nWant > 0) { // we have contending threads - ResourceMark rm; + ResourceMark rm(current_thread); // get_pending_threads returns only java thread so we do not need to // check for non java threads. GrowableArray* wantList = Threads::get_pending_threads(tlh.list(), nWant, (address)mon); @@ -1085,21 +1059,6 @@ } for (int i = 0; i < nWant; i++) { JavaThread *pending_thread = wantList->at(i); - // If the monitor has no owner, then a non-suspended contending - // thread could potentially change the state of the monitor by - // entering it. The JVM/TI spec doesn't allow this. - if (owning_thread == NULL && !at_safepoint && - !pending_thread->is_thread_fully_suspended(true, &debug_bits)) { - if (ret.owner != NULL) { - destroy_jni_reference(calling_thread, ret.owner); - } - for (int j = 0; j < i; j++) { - destroy_jni_reference(calling_thread, ret.waiters[j]); - } - deallocate((unsigned char*)ret.waiters); - deallocate((unsigned char*)ret.notify_waiters); - return JVMTI_ERROR_THREAD_NOT_SUSPENDED; - } Handle th(current_thread, pending_thread->threadObj()); ret.waiters[i] = (jthread)jni_reference(calling_thread, th); }