hotspot/src/share/vm/prims/jvmtiImpl.cpp
changeset 7444 be338e543a57
parent 7397 5b173b4ca846
child 7896 08aadd7aa3ee
--- a/hotspot/src/share/vm/prims/jvmtiImpl.cpp	Thu Dec 09 17:53:22 2010 +0300
+++ b/hotspot/src/share/vm/prims/jvmtiImpl.cpp	Thu Dec 09 15:04:26 2010 -0500
@@ -586,7 +586,6 @@
 {
 }
 
-
 vframe *VM_GetOrSetLocal::get_vframe() {
   if (!_thread->has_last_Java_frame()) {
     return NULL;
@@ -609,7 +608,7 @@
   }
   javaVFrame *jvf = (javaVFrame*)vf;
 
-  if (!vf->is_java_frame() || jvf->method()->is_native()) {
+  if (!vf->is_java_frame()) {
     _result = JVMTI_ERROR_OPAQUE_FRAME;
     return NULL;
   }
@@ -740,6 +739,15 @@
   _jvf = get_java_vframe();
   NULL_CHECK(_jvf, false);
 
+  if (_jvf->method()->is_native()) {
+    if (getting_receiver() && !_jvf->method()->is_static()) {
+      return true;
+    } else {
+      _result = JVMTI_ERROR_OPAQUE_FRAME;
+      return false;
+    }
+  }
+
   if (!check_slot_type(_jvf)) {
     return false;
   }
@@ -781,40 +789,46 @@
     HandleMark hm;
 
     switch (_type) {
-    case T_INT:    locals->set_int_at   (_index, _value.i); break;
-    case T_LONG:   locals->set_long_at  (_index, _value.j); break;
-    case T_FLOAT:  locals->set_float_at (_index, _value.f); break;
-    case T_DOUBLE: locals->set_double_at(_index, _value.d); break;
-    case T_OBJECT: {
-      Handle ob_h(JNIHandles::resolve_external_guard(_value.l));
-      locals->set_obj_at (_index, ob_h);
-      break;
-    }
-    default: ShouldNotReachHere();
+      case T_INT:    locals->set_int_at   (_index, _value.i); break;
+      case T_LONG:   locals->set_long_at  (_index, _value.j); break;
+      case T_FLOAT:  locals->set_float_at (_index, _value.f); break;
+      case T_DOUBLE: locals->set_double_at(_index, _value.d); break;
+      case T_OBJECT: {
+        Handle ob_h(JNIHandles::resolve_external_guard(_value.l));
+        locals->set_obj_at (_index, ob_h);
+        break;
+      }
+      default: ShouldNotReachHere();
     }
     _jvf->set_locals(locals);
   } else {
-    StackValueCollection *locals = _jvf->locals();
+    if (_jvf->method()->is_native() && _jvf->is_compiled_frame()) {
+      assert(getting_receiver(), "Can only get here when getting receiver");
+      oop receiver = _jvf->fr().get_native_receiver();
+      _value.l = JNIHandles::make_local(_calling_thread, receiver);
+    } else {
+      StackValueCollection *locals = _jvf->locals();
 
-    if (locals->at(_index)->type() == T_CONFLICT) {
-      memset(&_value, 0, sizeof(_value));
-      _value.l = NULL;
-      return;
-    }
+      if (locals->at(_index)->type() == T_CONFLICT) {
+        memset(&_value, 0, sizeof(_value));
+        _value.l = NULL;
+        return;
+      }
 
-    switch (_type) {
-    case T_INT:    _value.i = locals->int_at   (_index);   break;
-    case T_LONG:   _value.j = locals->long_at  (_index);   break;
-    case T_FLOAT:  _value.f = locals->float_at (_index);   break;
-    case T_DOUBLE: _value.d = locals->double_at(_index);   break;
-    case T_OBJECT: {
-      // Wrap the oop to be returned in a local JNI handle since
-      // oops_do() no longer applies after doit() is finished.
-      oop obj = locals->obj_at(_index)();
-      _value.l = JNIHandles::make_local(_calling_thread, obj);
-      break;
-    }
-    default: ShouldNotReachHere();
+      switch (_type) {
+        case T_INT:    _value.i = locals->int_at   (_index);   break;
+        case T_LONG:   _value.j = locals->long_at  (_index);   break;
+        case T_FLOAT:  _value.f = locals->float_at (_index);   break;
+        case T_DOUBLE: _value.d = locals->double_at(_index);   break;
+        case T_OBJECT: {
+          // Wrap the oop to be returned in a local JNI handle since
+          // oops_do() no longer applies after doit() is finished.
+          oop obj = locals->obj_at(_index)();
+          _value.l = JNIHandles::make_local(_calling_thread, obj);
+          break;
+        }
+        default: ShouldNotReachHere();
+      }
     }
   }
 }
@@ -825,6 +839,10 @@
 }
 
 
+VM_GetReceiver::VM_GetReceiver(
+    JavaThread* thread, JavaThread* caller_thread, jint depth)
+    : VM_GetOrSetLocal(thread, caller_thread, depth, 0) {}
+
 /////////////////////////////////////////////////////////////////////////////////////////
 
 //