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到這個例程的入口地址

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