- assembler_x86.cpp
Jvm中很多内置的例程,以及为java method生成的例程,使用了一下这些指令,这段就是generate_call_stub 这个方法的一小段,用来生成c语言到java过渡的一个例程,保存c执行的现场,准备进入java世界的上下文
// call Java function
__ BIND(parameters_done);
__ movptr(rbx, method); // get Method*
__ movptr(c_rarg1, entry_point); // get entry_point
__ mov(r13, rsp); // set sender sp
BLOCK_COMMENT("call Java function");
__ call(c_rarg1);
那么问题来了 call movptr这些到底是什么,在哪里实现,例如x86的,那么可以参考assembler_x86.cpp,例如call指令的实现
void Assembler::call(Register dst) {
int encode = prefix_and_encode(dst->encoding()); //跟汇编指令有些关系,不用来关系,微妙的问题
emit_int8((unsigned char)0xFF);
emit_int8((unsigned char)(0xD0 | encode));
}
emit_intxxx函数
以下列出assembler.hpp中几个emit_intxxx,类似的还有emit_xxx,直接调用code_section()返回值对应的方法,此处可以推断出,code_section()返回的就代表了,我们写入机器码的code所在内存的一个抽象
void emit_int8( int8_t x) { code_section()->emit_int8( x); }
void emit_int16( int16_t x) { code_section()->emit_int16( x); }
void emit_int32( int32_t x) { code_section()->emit_int32( x); }
void emit_int64( int64_t x) { code_section()->emit_int64( x); }
执行完__ call(c_rarg1),也就在code_section代表的代码,写入了call指令表示的机器码 , 同理mov等等都是类似实现,当然不同体系结构下,实现不一样,经过generate_call_stub此方法,就是在jvm管理端的一块内存区域写入了一段可执行的机器码,而这段机器码所做的事情就是帮我们从c程序进入java的执行流的一个桥梁,非常类似kernel进程切换所干的事情 ,最后这个call让我们一脚踏入了java领域,而每一个java的方法,jvm也使用同样的机制生成了一个例程,通过call到这个例程的入口地址