< prev index next >

src/hotspot/share/prims/jvmtiEnvBase.cpp

Print this page
rev 47819 : imported patch 10.07.open.rebase_20171110.dcubed

*** 42,51 **** --- 42,52 ---- #include "runtime/jfieldIDWorkaround.hpp" #include "runtime/objectMonitor.hpp" #include "runtime/objectMonitor.inline.hpp" #include "runtime/signature.hpp" #include "runtime/thread.inline.hpp" + #include "runtime/threadSMR.hpp" #include "runtime/vframe.hpp" #include "runtime/vframe_hp.hpp" #include "runtime/vmThread.hpp" #include "runtime/vm_operations.hpp"
*** 485,526 **** } memcpy(&_event_callbacks, callbacks, byte_cnt); } } - // Called from JVMTI entry points which perform stack walking. If the - // associated JavaThread is the current thread, then wait_for_suspend - // is not used. Otherwise, it determines if we should wait for the - // "other" thread to complete external suspension. (NOTE: in future - // releases the suspension mechanism should be reimplemented so this - // is not necessary.) - // - bool - JvmtiEnvBase::is_thread_fully_suspended(JavaThread* thr, bool wait_for_suspend, uint32_t *bits) { - // "other" threads require special handling - if (thr != JavaThread::current()) { - if (wait_for_suspend) { - // We are allowed to wait for the external suspend to complete - // so give the other thread a chance to get suspended. - if (!thr->wait_for_ext_suspend_completion(SuspendRetryCount, - SuspendRetryDelay, bits)) { - // didn't make it so let the caller know - return false; - } - } - // We aren't allowed to wait for the external suspend to complete - // so if the other thread isn't externally suspended we need to - // let the caller know. - else if (!thr->is_ext_suspend_completed_with_lock(bits)) { - return false; - } - } - return true; - } - - // In the fullness of time, all users of the method should instead // directly use allocate, besides being cleaner and faster, this will // mean much better out of memory handling unsigned char * JvmtiEnvBase::jvmtiMalloc(jlong size) { --- 486,496 ----
*** 558,580 **** jthreadGroup * JvmtiEnvBase::new_jthreadGroupArray(int length, Handle *handles) { return (jthreadGroup *) new_jobjectArray(length,handles); } - - JavaThread * - JvmtiEnvBase::get_JavaThread(jthread jni_thread) { - oop t = JNIHandles::resolve_external_guard(jni_thread); - if (t == NULL || !t->is_a(SystemDictionary::Thread_klass())) { - return NULL; - } - // The following returns NULL if the thread has not yet run or is in - // process of exiting - return java_lang_Thread::thread(t); - } - - // return the vframe on the specified thread and depth, NULL if no such frame vframe* JvmtiEnvBase::vframeFor(JavaThread* java_thread, jint depth) { if (!java_thread->has_last_Java_frame()) { return NULL; --- 528,537 ----
*** 668,678 **** JvmtiEnvBase::get_current_contended_monitor(JavaThread *calling_thread, JavaThread *java_thread, jobject *monitor_ptr) { #ifdef ASSERT uint32_t debug_bits = 0; #endif assert((SafepointSynchronize::is_at_safepoint() || ! is_thread_fully_suspended(java_thread, false, &debug_bits)), "at safepoint or target thread is suspended"); oop obj = NULL; ObjectMonitor *mon = java_thread->current_waiting_monitor(); if (mon == NULL) { // thread is not doing an Object.wait() call --- 625,635 ---- JvmtiEnvBase::get_current_contended_monitor(JavaThread *calling_thread, JavaThread *java_thread, jobject *monitor_ptr) { #ifdef ASSERT uint32_t debug_bits = 0; #endif assert((SafepointSynchronize::is_at_safepoint() || ! java_thread->is_thread_fully_suspended(false, &debug_bits)), "at safepoint or target thread is suspended"); oop obj = NULL; ObjectMonitor *mon = java_thread->current_waiting_monitor(); if (mon == NULL) { // thread is not doing an Object.wait() call
*** 707,717 **** jvmtiError err = JVMTI_ERROR_NONE; #ifdef ASSERT uint32_t debug_bits = 0; #endif assert((SafepointSynchronize::is_at_safepoint() || ! is_thread_fully_suspended(java_thread, false, &debug_bits)), "at safepoint or target thread is suspended"); if (java_thread->has_last_Java_frame()) { ResourceMark rm; HandleMark hm; --- 664,674 ---- jvmtiError err = JVMTI_ERROR_NONE; #ifdef ASSERT uint32_t debug_bits = 0; #endif assert((SafepointSynchronize::is_at_safepoint() || ! java_thread->is_thread_fully_suspended(false, &debug_bits)), "at safepoint or target thread is suspended"); if (java_thread->has_last_Java_frame()) { ResourceMark rm; HandleMark hm;
*** 829,839 **** jvmtiFrameInfo* frame_buffer, jint* count_ptr) { #ifdef ASSERT uint32_t debug_bits = 0; #endif assert((SafepointSynchronize::is_at_safepoint() || ! is_thread_fully_suspended(java_thread, false, &debug_bits)), "at safepoint or target thread is suspended"); int count = 0; if (java_thread->has_last_Java_frame()) { RegisterMap reg_map(java_thread); Thread* current_thread = Thread::current(); --- 786,796 ---- jvmtiFrameInfo* frame_buffer, jint* count_ptr) { #ifdef ASSERT uint32_t debug_bits = 0; #endif assert((SafepointSynchronize::is_at_safepoint() || ! java_thread->is_thread_fully_suspended(false, &debug_bits)), "at safepoint or target thread is suspended"); int count = 0; if (java_thread->has_last_Java_frame()) { RegisterMap reg_map(java_thread); Thread* current_thread = Thread::current();
*** 912,922 **** jmethodID* method_ptr, jlocation* location_ptr) { #ifdef ASSERT uint32_t debug_bits = 0; #endif assert((SafepointSynchronize::is_at_safepoint() || ! is_thread_fully_suspended(java_thread, false, &debug_bits)), "at safepoint or target thread is suspended"); Thread* current_thread = Thread::current(); ResourceMark rm(current_thread); vframe *vf = vframeFor(java_thread, depth); --- 869,879 ---- jmethodID* method_ptr, jlocation* location_ptr) { #ifdef ASSERT uint32_t debug_bits = 0; #endif assert((SafepointSynchronize::is_at_safepoint() || ! java_thread->is_thread_fully_suspended(false, &debug_bits)), "at safepoint or target thread is suspended"); Thread* current_thread = Thread::current(); ResourceMark rm(current_thread); vframe *vf = vframeFor(java_thread, depth);
*** 974,984 **** 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 (SafepointSynchronize::is_at_safepoint()) { BiasedLocking::revoke_at_safepoint(hobj); } else { BiasedLocking::revoke_and_rebias(hobj, false, calling_thread); } --- 931,941 ---- 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_and_rebias(hobj, false, calling_thread); }
*** 1006,1029 **** owner = (address)mon->owner(); } } if (owner != NULL) { // This monitor is owned so we have to find the owning JavaThread. ! // Since owning_thread_from_monitor_owner() grabs a lock, GC can ! // move our object at this point. However, our owner value is safe ! // since it is either the Lock word on a stack or a JavaThread *. ! owning_thread = Threads::owning_thread_from_monitor_owner(owner, !at_safepoint); // 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 && !JvmtiEnv::is_thread_fully_suspended(owning_thread, 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; --- 963,986 ---- 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;
*** 1031,1041 **** HandleMark hm; Handle th(current_thread, owning_thread->threadObj()); ret.owner = (jthread)jni_reference(calling_thread, th); } // implied else: no owner ! } 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. --- 988,998 ---- 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.
*** 1082,1098 **** 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; 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( ! nWant, (address)mon, !at_safepoint); if (wantList->length() < nWant) { // robustness: the pending list has gotten smaller nWant = wantList->length(); } for (int i = 0; i < nWant; i++) { --- 1039,1057 ---- 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++) {
*** 1099,1109 **** 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 & ! !JvmtiEnv::is_thread_fully_suspended(pending_thread, 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]); --- 1058,1068 ---- 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]);
*** 1137,1147 **** ret.notify_waiters[j++] = (jthread)jni_reference(calling_thread, th); } waiter = mon->next_waiter(waiter); } } ! } // Adjust count. nWant and nWait count values may be less than original. ret.waiter_count = nWant + nWait; ret.notify_waiter_count = nWait; } else { --- 1096,1106 ---- ret.notify_waiters[j++] = (jthread)jni_reference(calling_thread, th); } waiter = mon->next_waiter(waiter); } } ! } // ThreadsListHandle is destroyed here. // Adjust count. nWant and nWait count values may be less than original. ret.waiter_count = nWant + nWait; ret.notify_waiter_count = nWait; } else {
*** 1289,1317 **** void VM_GetThreadListStackTraces::doit() { assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint"); ResourceMark rm; for (int i = 0; i < _thread_count; ++i) { jthread jt = _thread_list[i]; ! oop thread_oop = JNIHandles::resolve_external_guard(jt); ! if (thread_oop == NULL || !thread_oop->is_a(SystemDictionary::Thread_klass())) { ! set_result(JVMTI_ERROR_INVALID_THREAD); return; } ! fill_frames(jt, java_lang_Thread::thread(thread_oop), thread_oop); } allocate_and_fill_stacks(_thread_count); } void VM_GetAllStackTraces::doit() { assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint"); ResourceMark rm; _final_thread_count = 0; ! for (JavaThread *jt = Threads::first(); jt != NULL; jt = jt->next()) { oop thread_oop = jt->threadObj(); if (thread_oop != NULL && !jt->is_exiting() && java_lang_Thread::is_alive(thread_oop) && !jt->is_hidden_from_external_view()) { --- 1248,1285 ---- void VM_GetThreadListStackTraces::doit() { assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint"); ResourceMark rm; + ThreadsListHandle tlh; for (int i = 0; i < _thread_count; ++i) { jthread jt = _thread_list[i]; ! JavaThread* java_thread = NULL; ! oop thread_oop = NULL; ! jvmtiError err = JvmtiExport::cv_external_thread_to_JavaThread(tlh.list(), jt, &java_thread, &thread_oop); ! if (err != JVMTI_ERROR_NONE) { ! // We got an error code so we don't have a JavaThread *, but ! // only return an error from here if we didn't get a valid ! // thread_oop. ! if (thread_oop == NULL) { ! set_result(err); return; } ! // We have a valid thread_oop. } + fill_frames(jt, java_thread, thread_oop); + } allocate_and_fill_stacks(_thread_count); } void VM_GetAllStackTraces::doit() { assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint"); ResourceMark rm; _final_thread_count = 0; ! for (JavaThreadIteratorWithHandle jtiwh; JavaThread *jt = jtiwh.next(); ) { oop thread_oop = jt->threadObj(); if (thread_oop != NULL && !jt->is_exiting() && java_lang_Thread::is_alive(thread_oop) && !jt->is_hidden_from_external_view()) {
*** 1402,1414 **** if (state == NULL) { return JVMTI_ERROR_THREAD_NOT_ALIVE; } // Check if java_thread is fully suspended ! if (!is_thread_fully_suspended(java_thread, ! true /* wait for suspend completion */, ! &debug_bits)) { return JVMTI_ERROR_THREAD_NOT_SUSPENDED; } // Check to see if a ForceEarlyReturn was already in progress if (state->is_earlyret_pending()) { --- 1370,1380 ---- if (state == NULL) { return JVMTI_ERROR_THREAD_NOT_ALIVE; } // Check if java_thread is fully suspended ! if (!java_thread->is_thread_fully_suspended(true /* wait for suspend completion */, &debug_bits)) { return JVMTI_ERROR_THREAD_NOT_SUSPENDED; } // Check to see if a ForceEarlyReturn was already in progress if (state->is_earlyret_pending()) {
*** 1519,1523 **** --- 1485,1565 ---- *modules_ptr = array; *module_count_ptr = len; return JVMTI_ERROR_NONE; } + void + VM_UpdateForPopTopFrame::doit() { + JavaThread* jt = _state->get_thread(); + ThreadsListHandle tlh; + if (jt != NULL && tlh.includes(jt) && !jt->is_exiting() && jt->threadObj() != NULL) { + _state->update_for_pop_top_frame(); + } else { + _result = JVMTI_ERROR_THREAD_NOT_ALIVE; + } + } + + void + VM_SetFramePop::doit() { + JavaThread* jt = _state->get_thread(); + ThreadsListHandle tlh; + if (jt != NULL && tlh.includes(jt) && !jt->is_exiting() && jt->threadObj() != NULL) { + int frame_number = _state->count_frames() - _depth; + _state->env_thread_state((JvmtiEnvBase*)_env)->set_frame_pop(frame_number); + } else { + _result = JVMTI_ERROR_THREAD_NOT_ALIVE; + } + } + + void + VM_GetOwnedMonitorInfo::doit() { + _result = JVMTI_ERROR_THREAD_NOT_ALIVE; + ThreadsListHandle tlh; + if (_java_thread != NULL && tlh.includes(_java_thread) + && !_java_thread->is_exiting() && _java_thread->threadObj() != NULL) { + _result = ((JvmtiEnvBase *)_env)->get_owned_monitors(_calling_thread, _java_thread, + _owned_monitors_list); + } + } + + void + VM_GetCurrentContendedMonitor::doit() { + _result = JVMTI_ERROR_THREAD_NOT_ALIVE; + ThreadsListHandle tlh; + if (_java_thread != NULL && tlh.includes(_java_thread) + && !_java_thread->is_exiting() && _java_thread->threadObj() != NULL) { + _result = ((JvmtiEnvBase *)_env)->get_current_contended_monitor(_calling_thread,_java_thread,_owned_monitor_ptr); + } + } + + void + VM_GetStackTrace::doit() { + _result = JVMTI_ERROR_THREAD_NOT_ALIVE; + ThreadsListHandle tlh; + if (_java_thread != NULL && tlh.includes(_java_thread) + && !_java_thread->is_exiting() && _java_thread->threadObj() != NULL) { + _result = ((JvmtiEnvBase *)_env)->get_stack_trace(_java_thread, + _start_depth, _max_count, + _frame_buffer, _count_ptr); + } + } + + void + VM_GetFrameCount::doit() { + _result = JVMTI_ERROR_THREAD_NOT_ALIVE; + JavaThread* jt = _state->get_thread(); + ThreadsListHandle tlh; + if (jt != NULL && tlh.includes(jt) && !jt->is_exiting() && jt->threadObj() != NULL) { + _result = ((JvmtiEnvBase*)_env)->get_frame_count(_state, _count_ptr); + } + } + + void + VM_GetFrameLocation::doit() { + _result = JVMTI_ERROR_THREAD_NOT_ALIVE; + ThreadsListHandle tlh; + if (_java_thread != NULL && tlh.includes(_java_thread) + && !_java_thread->is_exiting() && _java_thread->threadObj() != NULL) { + _result = ((JvmtiEnvBase*)_env)->get_frame_location(_java_thread, _depth, + _method_ptr, _location_ptr); + } + }
< prev index next >