hotspot/src/cpu/x86/vm/templateTable_x86_64.cpp
void TemplateTable::invokevirtual_helper(Register index,
Register recv,
Register flags) {
{- -------------------------------------------
(1) (なお, 以下では一時的に rax と rdx を使用する)
---------------------------------------- -}
// Uses temporary registers rax, rdx
{- -------------------------------------------
(1) (assert)
---------------------------------------- -}
assert_different_registers(index, recv, rax, rdx);
{- -------------------------------------------
(1) コード生成:
「呼び出し対象のメソッドに final 修飾子が付いているかどうかを確認.
付いていなければ notFinal ラベルに分岐.」
---------------------------------------- -}
// Test for an invoke of a final method
Label notFinal;
__ movl(rax, flags);
__ andl(rax, (1 << ConstantPoolCacheEntry::vfinalMethod));
__ jcc(Assembler::zero, notFinal);
{- -------------------------------------------
(1) (変数宣言など)
---------------------------------------- -}
const Register method = index; // method must be rbx
assert(method == rbx,
"methodOop must be rbx for interpreter calling convention");
{- -------------------------------------------
(1) (以下は, final 修飾子が付いていた場合のコード生成)
---------------------------------------- -}
{- -------------------------------------------
(1.1) コード生成: (verify)
---------------------------------------- -}
// do the call - the index is actually the method to call
__ verify_oop(method);
{- -------------------------------------------
(1.1) コード生成:
「receiver が NULL でないことを確認する.
NULL の場合は NullPointerException (See: [here](no30592Qc.html) for details)」
---------------------------------------- -}
// It's final, need a null check here!
__ null_check(recv);
{- -------------------------------------------
(1.1) コード生成:
「method data pointer (mdp) の値を更新しておく」
---------------------------------------- -}
// profile this call
__ profile_final_call(rax);
{- -------------------------------------------
(1.1) コード生成:
「実際の呼び出し処理を行う」
---------------------------------------- -}
__ jump_from_interpreted(method, rax);
{- -------------------------------------------
(1) (ここまでが, final 修飾子が付いていた場合)
---------------------------------------- -}
{- -------------------------------------------
(1) (以下は, final 修飾子が付いていなかった場合のコード生成)
---------------------------------------- -}
__ bind(notFinal);
{- -------------------------------------------
(1.1) コード生成:
「receiver の klass フィールドが NULL でないことを確認した後,
クラスオブジェクトを Rrecv にロードする.
NULL の場合は NullPointerException (See: [here](no30592Qc.html) for details)」
---------------------------------------- -}
// get receiver klass
__ null_check(recv, oopDesc::klass_offset_in_bytes());
__ load_klass(rax, recv);
{- -------------------------------------------
(1.1) コード生成: (verify)
---------------------------------------- -}
__ verify_oop(rax);
{- -------------------------------------------
(1.1) コード生成:
「method data pointer (mdp) の値を更新しておく」
---------------------------------------- -}
// profile this call
__ profile_virtual_call(rax, r14, rdx);
{- -------------------------------------------
(1.1) (変数宣言など)
---------------------------------------- -}
// get target methodOop & entry point
const int base = instanceKlass::vtable_start_offset() * wordSize;
{- -------------------------------------------
(1.1) (assert)
---------------------------------------- -}
assert(vtableEntry::size() * wordSize == 8,
"adjust the scaling in the code below");
{- -------------------------------------------
(1.1) コード生成:
「クラスオブジェクトから vtable を取得し,
CPCache から取得しておいた vtable 内の index 番号とつき合わせて methodOop を取得する.
取得した結果は, 引数の method で指定されたレジスタに格納.」
---------------------------------------- -}
__ movptr(method, Address(rax, index,
Address::times_8,
base + vtableEntry::method_offset_in_bytes()));
{- -------------------------------------------
(1.1) コード生成:
「?? (ここのロードは何か意味があるか?? 使われていないような... しかも参照先は interpreter_entry だし...)」
---------------------------------------- -}
__ movptr(rdx, Address(method, methodOopDesc::interpreter_entry_offset()));
{- -------------------------------------------
(1.1) コード生成:
「実際の呼び出し処理を行う」
---------------------------------------- -}
__ jump_from_interpreted(method, rdx);
}
{- -------------------------------------------
(1) (ここまでが, final 修飾子が付いていなかった場合)
---------------------------------------- -}
This document is available under the GNU GENERAL PUBLIC LICENSE Version 2.