Jvm超级武器机器码如何生成

  1. 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到这个例程的入口地址

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章