HotSpot的SharedRuntime::generate_native_wrapper(...)方法用于生成以编译方式调用JNI方法时的wrapper,该wrapper主要用于完成从编译执行的java方法(不妨称为caller)向jni方法(不妨称为callee,且设它是个static方法)传递参数的过程。
具体来说,caller调用callee传出的参数,前6个在寄存器中,多余的在栈上,遇到java对象/数组作为参数,传递的是该对象的oop;而callee作为static jni方法,其第一个参数是env,第二个参数是mirror的handle,第三个参数开始才是caller调出时给出的参数,遇到java对象/数组参数,需要将它们转换为handle后才能作为jni方法的参数。wrapper的作用就是完成env、mirror handle的填写,以及oop到handle的转换。
以下代码就是生成填充第二个参数mirror handle的汇编的代码
if (method->is_static() && !is_critical_native) { __ set_oop_constant(JNIHandles::make_local(Klass::cast(method->method_holder())->java_mirror()), O1); // Now handlize the static class mirror in O1. It's known not-null. __ st_ptr(O1, SP, klass_offset + STACK_BIAS); map->set_oop(VMRegImpl::stack2reg(klass_slot_offset)); __ add(SP, klass_offset + STACK_BIAS, O1); }
我的问题是,JNIHandles::make_local(...)返还的明明已经是mirror的handle了,因此存储到SP+klass_offset位置的也是mirror的handle,而不是mirror oop。但从后面的代码看,SP+klass_offset位置存放的应该是oop而不是handle。这中间到底哪里出了问题,怎么也没想明白!!!