java JNI 实现原理 (五) JNI方法解释调用
来源:互联网 发布:兼职 大数据 英文 翻译 编辑:程序博客网 时间:2024/04/30 10:08
Hotspot主要有两种解释器,而下面我们主要讨论的是 Template Intepreter也叫asm interprete解释器, 文章下面的介绍基本都是基于template解释器
我们举一个invokespecial的例子,下面是templateTable方法解释invokespecial的代码
void TemplateTable::invokespecial(int byte_no) { transition(vtos, vtos); assert(byte_no == f1_byte, "use this argument"); prepare_invoke(rbx, noreg, byte_no); // do the call __ verify_oop(rbx); __ profile_call(rax); __ jump_from_interpreted(rbx, rax);}
函数prepare_invoke
函数prepare_invoke的层级调用关系
TemplateTable::prepare_invoke
-> TemplateTable::load_invoke_cp_cache_entry
-> TemplateTable::resolve_cache_and_index
在函数中resolve_cache_and_index可以看到
1. 首先先检查constantpoolcache,是否将方法指针保存到到线程的constantpoolcache里,如果有在方法里会使用jcc跳转到Label resolved去,而Lable resolved 在方法第一次运行结束后bind到函数的末尾。
2. 如果cache里没有那么会尝试用interpreterRuntime:resolve_invoke去找到正确的method, 并保存到constant pool cache 里
case Bytecodes::_invokevirtual: case Bytecodes::_invokespecial: case Bytecodes::_invokestatic: case Bytecodes::_invokeinterface: entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_invoke); break;
而函数
interpreterRuntime:resolve_invoke
-->LinkResolver::resolve_invoke
-->LinkResolver::resolve_special_call
-->LinkResolver::linktime_resolve_special_method
-->LinkResolver::resolve_method
不论什么调用方式,最后都会调用LinkResolver::resolve_method 找到真实的调用方法,通过runtime_resolve_special_method把method指针作为methodhandle存放到CallInfo 中传回InterperterRuntime::resolve_invoke中,同时在CallInfo::set_common当设置-Xcomp情况下,决定是否需要编译方法。
我们可以看到方法prepare_invoke,已经找到了methodoop指针并且存放到寄存器rbx中
函数jump_from_interpreted
void InterpreterMacroAssembler::jump_from_interpreted(Register method, Register temp) { prepare_to_jump_from_interpreted(); if (JvmtiExport::can_post_interpreter_events()) { Label run_compiled_code; // JVMTI events, such as single-stepping, are implemented partly by avoiding running // compiled code in threads for which the event is enabled. Check here for // interp_only_mode if these events CAN be enabled. get_thread(temp); // interp_only is an int, on little endian it is sufficient to test the byte only // Is a cmpl faster (ce cmpb(Address(temp, JavaThread::interp_only_mode_offset()), 0); jcc(Assembler::zero, run_compiled_code); jmp(Address(method, methodOopDesc::interpreter_entry_offset())); bind(run_compiled_code); } jmp(Address(method, methodOopDesc::from_interpreted_offset()));}我们看到跳转到了methodoop中的_from_interpreted_entry,也就是在前面的博客里(java JNI (四) 初始化JNI方法)说的generate_native_entry 中
在这篇博客并没有太多的涉及到native方法的调用,而是asm解释器在解释一个方法的时候如何link到所对应method,并且找到处理method的entry。
- java JNI 实现原理 (五) JNI方法解释调用
- java JNI 实现原理 (六) 调用JNI方法
- java JNI 实现原理 (三) JNI中的RegisterNatives方法
- java JNI 实现原理 (四) 初始化JNI方法
- JNI调用Java方法
- JNI调用Java方法
- JNI调用Java方法
- JNI调用Java方法
- JNI调用Java方法
- JNI调用Java方法
- Java JNI 调用C#方法
- java调用dll方法--JNI
- jni - c 调用java方法
- Java JNI实现原理初探
- java JNI 实现原理 (一)
- Java JNI实现原理初探
- JNI实现Java调用C++
- 模仿android_debug_JNITest实现apk 调用framework java JNI中方法
- NSCopying协议和copy方法
- 生产者消费者问题-转自维基百科
- The Ruby On Rials Gudie -- Active Record Associations
- 数据库的备份和恢复
- 内存管理与智能指针
- java JNI 实现原理 (五) JNI方法解释调用
- 开通博客了
- accumulate everyday:grep()函数
- Basic view
- 陌陌,该甩掉你“约炮”的帽子了
- 不是职业规划的职业规划
- 简述java中的final、finally、finalize的差别
- struts2 action 文件下载的配置
- 【转】ArcGIS Engine ITable 与System.DataTable相互转换