< 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 >