JavaCalls::call为hotspot调用java方法的实现之一。其调用os::os_exception_wrapper(call_helper, result, &method, args, THREAD);这个还是比较好看懂,通过传入call_helper函数指针,在call_helper上面封装了异常的处理,典型的回调函数用法。call_helper的实现里面的具体调用java函数的方法相对难看明白,下面进行进一步分析。
....
//函数的具体调用
{ JavaCallWrapper link(method, receiver, result, CHECK);
{ HandleMark hm(thread); // HandleMark used by HandleMarkCleaner
StubRoutines::call_stub()(
(address)&link,
// (intptr_t*)&(result->_value), // see NOTE above (compiler problem)
result_val_address, // see NOTE above (compiler problem)
result_type,
method(),
entry_point,
args->parameters(),
args->size_of_parameters(),
CHECK
);
result = link.result(); // circumvent MS C++ 5.0 compiler bug (result is clobbered across call)
// Preserve oop return value across possible gc points
if (oop_result_flag) {
thread->set_vm_result((oop) result->get_jobject());
}
}
上面代码中StubRoutines::call_stub()返回的是一个函数指针,在执行上面的call_stub()时,会先将参数先压入堆栈。
这个函数指针指向什么地方呢,这是和机器类型有关的,以X86-32为例,看stubGenerator_x86_32.cpp里面
StubGenerator::generate_call_stub。返回的是__pc()的值,这个值其实是内存的的一个动态生态的机器码的一个位置。
address generate_call_stub(address& return_address) {
StubCodeMark mark(this, "StubRoutines", "call_stub");
address start = __ pc(); //注意,这是返回的指针值,下面还继续生成机器码,也就是说在上面的javaCall
//会调用下面产生的机器码,这些才是真正调用java方法的内容。
bool sse_save = false;
const Address rsp_after_call(rbp, -4 * wordSize); // same as in generate_catch_exception()!
const int locals_count_in_bytes (4*wordSize);
const Address mxcsr_save (rbp, -4 * wordSize);
const Address saved_rbx (rbp, -3 * wordSize);
const Address saved_rsi (rbp, -2 * wordSize);
const Address saved_rdi (rbp, -1 * wordSize);
const Address result (rbp, 3 * wordSize);
const Address result_type (rbp, 4 * wordSize);
const Address method (rbp, 5 * wordSize);
const Address entry_point (rbp, 6 * wordSize);
const Address parameters (rbp, 7 * wordSize);
const Address parameter_size(rbp, 8 * wordSize);
const Address thread (rbp, 9 * wordSize); // same as in generate_catch_exception()!
sse_save = UseSSE > 0;
//上面为对调用压入的堆栈进行的处理,将具体的值赋给寄存器
//下面就是残端代码,主要是产生机器码,用类似汇编语言的格式产生
// stub code
__ enter();
__ movl(rcx, parameter_size); // parameter counter
__ shll(rcx, Interpreter::logStackElementSize()); // convert parameter count to bytes
__ addl(rcx, locals_count_in_bytes); // reserve space for register saves
__ subl(rsp, rcx);
__ andl(rsp, -(StackAlignmentInBytes)); // Align stack
.....
采用类的方法,模拟汇编语言产生机器码还是很体现了大牛们的水平。
汇编调用java方法的具体代码
// call Java function
__ BIND(parameters_done);
__ movl(rbx, method); // get methodOop
__ movl(rax, entry_point); // get entry_point
__ movl(rsi, rsp); // set sender sp
BLOCK_COMMENT("call Java function");
__ call(rax);
上面就将cpu控制转向了entry_point,这正是java方法的入口。
这个entry_point从何而来,从method->from_interpreted_entry(),从methodOopDesc::link_method中获取address entry = Interpreter::entry_for_method(h_method),也就是说如果不用jit的,直接调用解析器的入口,由解释器再进行操作。
分享到:
相关推荐
CALL代码生成器是一款专为程序员和开发者设计的实用工具,主要用于自动生成特定的CALL代码,以提高编程效率和代码质量。在编程过程中,CALL代码通常指的是调用其他函数或子程序的指令,它在各种编程语言中都有所应用...
在IT行业中,"call代码测试"通常指的是对游戏或应用程序中的呼叫(Call)功能进行的测试过程,确保这些功能能够正确、稳定地运行。这里提到的"call代码测试.rar"可能是一个包含专门用于测试此类功能的工具的压缩包。...
在JavaCalls::call_helper()函数中,我们可以看到call_stub的具体实现。这个函数接收四个参数:result(用于存放调用结果的JavaValue指针)、methodHandle(指向要调用的方法的句柄)、JavaCallArguments(包含调用...
GPU显卡的Compute Capability需>=5.3,否则会提示error: (-217:Gpu API call) invalid device function in function 'make_policy' 编译本接口所用的工具及环境: Cmake-3.17.5 VS2019 opencv-4.2.0 opencv-contrib...
云函数 调用失败 Error: errCode: -404011 cloud function execution error | errMsg: cloud.callFunction:fail requestID , cloud function service error code -504001, error message Unkown function;...
技能Call代码生成器 技能Call代码生成器
主要功能: 远程进程CALL代码注入测试 特点:带有try异常保护的远程CALL注入执行, 即使CALL参数错误或读写空指针,目标程序不会因产生错误而崩溃。 从而带给了程序员在测试CALL代码时的便利。 *****************...
android开发,打印调用栈 ,callstack.cpp,android开发,打印调用栈,android开发,打印调用栈
【代码注入器(外挂Call测试的)】是一种在软件测试中用于模拟特定行为或功能的工具,尤其在游戏外挂测试中应用广泛。代码注入技术允许开发者将自定义的代码片段插入到运行中的进程,以此来操控或扩展程序的行为,以...
* 解释:这个响应代码表示call正在被重新路由到另外一个目的地,caller需要等待新的响应。 182 Queued * 说明:callee当前是不可获得的,但是对方不想直接拒绝呼叫,而是选择放在呼叫队列中。 * 解释:这个响应...
根据给定的信息,本文将对“VC代码注入和CALL”的知识点进行详细解析,重点在于代码注入的基本原理、实现过程以及CALL指令在其中的作用。 ### 一、代码注入基础概念 代码注入是一种技术手段,通常用于将一段代码...
【汇编代码注入工具call工具】是一种用于在目标进程中注入汇编代码的实用程序,它允许程序员或安全研究员实现远程函数调用。汇编代码注入是计算机编程中的一个技术,通常用于调试、性能优化或者安全渗透测试。在这个...
4. 中间代码结构:调用`call id(E1...En)`的中间代码会包含每个实参的计算结果(ValACT或VarACT,取决于参数类型),以及偏移量和大小信息。例如,`(ValACT ,t1 ,Offset1 ,1)`表示将值`t1`作为值参数传递,偏移量为`...
郁金香代码注入器,又称为郁金香CALL,是一种技术工具,主要用于软件开发和逆向工程中的代码注入测试。代码注入是计算机编程中的一个高级技术,它允许程序在运行时将新的指令或代码注入到另一个正在运行的进程。这种...
python call:随着软件工程变得越来越复杂,面向对象编程(OOP)成为了构建可维护、可扩展应用程序的标准方式。在Python中,`__call__`方法提供了一种使类实例表现得像函数或方法一样的机制。这不仅使得代码更加简洁...
"代码注入器 CALL"很可能是指一个特定的工具或技术,它利用了编程语言中的`CALL`指令来实现代码注入。`CALL`在汇编语言中是一个关键的指令,用于调用子程序或函数,它会将控制权转移给指定的地址,并在完成执行后...
- 通过callstack上的方法右键选择“Edit Source Lookup”。 - 添加Android源代码工程到Source Lookup中。 - 直接在源代码中设置断点进行调试。 5. **Android源代码Native代码调试** - **关键步骤**:确保已...
CALL调用示例分析-远程代码注入器 CodeInEX_dong代码注入 CodeInEX_dong代码注入
Keil 中的报警错误 WARNING L15: MULTIPLE CALL TO SEGMENT Keil 中的报警错误 WARNING L15: MULTIPLE CALL TO SEGMENT 是一个常见的报警错误,今天我们来详细讲解这个问题。 在 Keil 中,当编译器检测到多个调用...