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;
   }
 }
Пример #2
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;
}