hotspot/src/share/vm/prims/jvmtiImpl.cpp
void VM_GetOrSetLocal::doit() {
{- -------------------------------------------
(1) (この関数の処理は, _set フィールドの値に応じて 2通りに分岐.
このフィールドの値はコンストラクタ引数で指定され, 局所変数を get するのか set するのかを示す)
---------------------------------------- -}
{- -------------------------------------------
(1) (以下は, 局所変数を set する場合の処理)
---------------------------------------- -}
if (_set) {
// Force deoptimization of frame if compiled because it's
// possible the compiler emitted some locals as constant values,
// meaning they are not mutable.
if (can_be_deoptimized(_jvf)) {
// Schedule deoptimization so that eventually the local
// update will be written to an interpreter frame.
Deoptimization::deoptimize_frame(_jvf->thread(), _jvf->fr().id());
// Now store a new value for the local which will be applied
// once deoptimization occurs. Note however that while this
// write is deferred until deoptimization actually happens
// can vframe created after this point will have its locals
// reflecting this update so as far as anyone can see the
// write has already taken place.
// If we are updating an oop then get the oop from the handle
// since the handle will be long gone by the time the deopt
// happens. The oop stored in the deferred local will be
// gc'd on its own.
if (_type == T_OBJECT) {
_value.l = (jobject) (JNIHandles::resolve_external_guard(_value.l));
}
// Re-read the vframe so we can see that it is deoptimized
// [ Only need because of assert in update_local() ]
_jvf = get_java_vframe();
((compiledVFrame*)_jvf)->update_local(_type, _index, _value);
return;
}
StackValueCollection *locals = _jvf->locals();
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();
}
_jvf->set_locals(locals);
{- -------------------------------------------
(1) (以下は, 局所変数を get する場合の処理)
---------------------------------------- -}
} else {
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;
}
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();
}
}
}
}
This document is available under the GNU GENERAL PUBLIC LICENSE Version 2.