hotspot/src/cpu/sparc/vm/interp_masm_sparc.cpp
// Load compiled (i2c) or interpreter entry when calling from interpreted and
// do the call. Centralized so that all interpreter calls will do the same actions.
// If jvmti single stepping is on for a thread we must not call compiled code.
void InterpreterMacroAssembler::call_from_interpreter(Register target, Register scratch, Register Rret) {
{- -------------------------------------------
(1)
---------------------------------------- -}
// Assume we want to go compiled if available
{- -------------------------------------------
(1) コード生成:
「呼び出し対象の methodOop から, from_interpreted フィールドの値を取り出す
(これが呼び出し対象のエントリポイント)」
---------------------------------------- -}
ld_ptr(G5_method, in_bytes(methodOopDesc::from_interpreted_offset()), target);
{- -------------------------------------------
(1) コード生成: (ただし, JvmtiExport::can_post_interpreter_events() が false であれば
interp_only_mode のチェックは不要なので生成しない)
「(JVMTI の状況によっては, 実行がインタープリタのみに制限されることがある. See: [here](no3059eFS.html) for details)
カレントスレッドの interp_only_mode フィールドの値を確認する.
もし true であれば, インタープリタ実行用のエントリポイントを使わないといけないため,
呼び出し対象の methodOop から interpreter_entry フィールドの値を取り出す
(これがインタープリタ実行用のエントリポイント.
JIT 対象になったとしてもこちらのエントリポイントは変更されない. See: ...#TODO)」
---------------------------------------- -}
if (JvmtiExport::can_post_interpreter_events()) {
// JVMTI events, such as single-stepping, are implemented partly by avoiding running
// compiled code in threads for which the event is enabled. Check here for
// interp_only_mode if these events CAN be enabled.
verify_thread();
Label skip_compiled_code;
const Address interp_only(G2_thread, JavaThread::interp_only_mode_offset());
ld(interp_only, scratch);
tst(scratch);
br(Assembler::notZero, true, Assembler::pn, skip_compiled_code);
delayed()->ld_ptr(G5_method, in_bytes(methodOopDesc::interpreter_entry_offset()), target);
bind(skip_compiled_code);
}
{- -------------------------------------------
(1) (i2c アダプターは methodOop が G5_method レジスタに入っていると想定している(正しい??), とのこと)
---------------------------------------- -}
// the i2c_adapters need methodOop in G5_method (right? %%%)
{- -------------------------------------------
(1) (以下で実際に呼び出しを行う)
---------------------------------------- -}
// do the call
{- -------------------------------------------
(1) (デバッグ用の処理) (#ifdef ASSERT 時にのみ実行)
コード生成: (デバッグ用の処理)
---------------------------------------- -}
#ifdef ASSERT
{
Label ok;
br_notnull(target, false, Assembler::pt, ok);
delayed()->nop();
stop("null entry point");
bind(ok);
}
#endif // ASSERT
{- -------------------------------------------
(1) コード生成:
「あらかじめ取得しておいた return entry のアドレス(Rret)を O7 にセット.
(ただし, frame::pc_return_offset 分だけ調整は行う).」
---------------------------------------- -}
// Adjust Rret first so Llast_SP can be same as Rret
add(Rret, -frame::pc_return_offset, O7);
{- -------------------------------------------
(1) コード生成:
「Gargs レジスタに最終引数のアドレスを設定」
(呼び出される側がこの値が入っていることを想定しているため)
---------------------------------------- -}
add(Lesp, BytesPerWord, Gargs); // setup parameter pointer
{- -------------------------------------------
(1) コード生成:
「SP の値を Llast_SP レジスタに保存しつつ, 飛び先にジャンプ」
---------------------------------------- -}
// Record SP so we can remove any stack space allocated by adapter transition
jmp(target, 0);
delayed()->mov(SP, Llast_SP);
}
This document is available under the GNU GENERAL PUBLIC LICENSE Version 2.