< prev index next >
src/hotspot/share/prims/jvmtiEnvBase.cpp
Print this page
*** 935,974 ****
}
jvmtiError
JvmtiEnvBase::get_object_monitor_usage(JavaThread* calling_thread, jobject object, jvmtiMonitorUsage* info_ptr) {
! HandleMark hm;
! Handle hobj;
! Thread* current_thread = Thread::current();
! bool at_safepoint = SafepointSynchronize::is_at_safepoint();
// Check arguments
{
oop mirror = JNIHandles::resolve_external_guard(object);
NULL_CHECK(mirror, JVMTI_ERROR_INVALID_OBJECT);
NULL_CHECK(info_ptr, JVMTI_ERROR_NULL_POINTER);
hobj = Handle(current_thread, mirror);
}
JavaThread *owning_thread = NULL;
ObjectMonitor *mon = NULL;
jvmtiMonitorUsage ret = {
NULL, 0, 0, NULL, 0, NULL
};
uint32_t debug_bits = 0;
// 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);
- }
address owner = NULL;
{
markWord mark = hobj()->mark();
--- 935,972 ----
}
jvmtiError
JvmtiEnvBase::get_object_monitor_usage(JavaThread* calling_thread, jobject object, jvmtiMonitorUsage* info_ptr) {
! assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
! Thread* current_thread = VMThread::vm_thread();
! assert(current_thread == Thread::current(), "must be");
! HandleMark hm(current_thread);
! Handle hobj;
// Check arguments
{
oop mirror = JNIHandles::resolve_external_guard(object);
NULL_CHECK(mirror, JVMTI_ERROR_INVALID_OBJECT);
NULL_CHECK(info_ptr, JVMTI_ERROR_NULL_POINTER);
hobj = Handle(current_thread, mirror);
}
+ ThreadsListHandle tlh(current_thread);
JavaThread *owning_thread = NULL;
ObjectMonitor *mon = NULL;
jvmtiMonitorUsage ret = {
NULL, 0, 0, NULL, 0, NULL
};
uint32_t debug_bits = 0;
// first derive the object's owner and entry_count (if any)
{
// Revoke any biases before querying the mark word
BiasedLocking::revoke_at_safepoint(hobj);
address owner = NULL;
{
markWord mark = hobj()->mark();
*** 992,1034 ****
owner = (address)mon->owner();
}
}
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.
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;
ret.entry_count = count_locked_objects(owning_thread, hobj);
}
// implied else: entry_count == 0
}
--- 990,1012 ----
owner = (address)mon->owner();
}
}
if (owner != NULL) {
// This monitor is owned so we have to find the owning JavaThread.
owning_thread = Threads::owning_thread_from_monitor_owner(tlh.list(), owner);
! 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(current_thread);
ret.entry_count = count_locked_objects(owning_thread, hobj);
}
// implied else: entry_count == 0
}
*** 1067,1107 ****
memset(ret.waiters, 0, ret.waiter_count * sizeof(jthread *));
memset(ret.notify_waiters, 0, ret.notify_waiter_count * sizeof(jthread *));
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;
// get_pending_threads returns only java thread so we do not need to
// check for non java threads.
GrowableArray<JavaThread*>* wantList = Threads::get_pending_threads(tlh.list(), nWant, (address)mon);
if (wantList->length() < nWant) {
// robustness: the pending list has gotten smaller
nWant = wantList->length();
}
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);
}
}
if (nWait > 0) {
--- 1045,1066 ----
memset(ret.waiters, 0, ret.waiter_count * sizeof(jthread *));
memset(ret.notify_waiters, 0, ret.notify_waiter_count * sizeof(jthread *));
if (ret.waiter_count > 0) {
// we have contending and/or waiting threads
if (nWant > 0) {
// we have contending threads
! ResourceMark rm(current_thread);
// get_pending_threads returns only java thread so we do not need to
// check for non java threads.
GrowableArray<JavaThread*>* wantList = Threads::get_pending_threads(tlh.list(), nWant, (address)mon);
if (wantList->length() < nWant) {
// robustness: the pending list has gotten smaller
nWant = wantList->length();
}
for (int i = 0; i < nWant; i++) {
JavaThread *pending_thread = wantList->at(i);
Handle th(current_thread, pending_thread->threadObj());
ret.waiters[i] = (jthread)jni_reference(calling_thread, th);
}
}
if (nWait > 0) {
< prev index next >