void doit() { ResourceMark rmark; // _thread != Thread::current() RegisterMap rm(_thread, false); // There can be a race condition between a VM_Operation reaching a safepoint // and the target thread exiting from Java execution. // We must recheck the last Java frame still exists. if (!_thread->is_exiting() && _thread->has_last_Java_frame()) { javaVFrame* vf = _thread->last_java_vframe(&rm); assert(vf != NULL, "must have last java frame"); Method* method = vf->method(); _method_id = method->jmethod_id(); _bci = vf->bci(); } else { // Clear current location as the target thread has no Java frames anymore. _method_id = (jmethodID)NULL; _bci = 0; } }
jvmtiError JvmtiEnvBase::get_frame_location(JavaThread *java_thread, jint depth, 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); if (vf == NULL) { return JVMTI_ERROR_NO_MORE_FRAMES; } // vframeFor should return a java frame. If it doesn't // it means we've got an internal error and we return the // error in product mode. In debug mode we will instead // attempt to cast the vframe to a javaVFrame and will // cause an assertion/crash to allow further diagnosis. #ifdef PRODUCT if (!vf->is_java_frame()) { return JVMTI_ERROR_INTERNAL; } #endif HandleMark hm(current_thread); javaVFrame *jvf = javaVFrame::cast(vf); Method* method = jvf->method(); if (method->is_native()) { *location_ptr = -1; } else { *location_ptr = jvf->bci(); } *method_ptr = method->jmethod_id(); return JVMTI_ERROR_NONE; }