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