--- 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) {}
+
/////////////////////////////////////////////////////////////////////////////////////////
//