hotspot/src/cpu/sparc/vm/stubGenerator_sparc.cpp
//----------------------------------------------------------------------------------------------------
// Continuation point for runtime calls returning with a pending exception
// The pending exception check happened in the runtime or native call stub
// The pending exception in Thread is converted into a Java-level exception
//
// Contract with Java-level exception handler: O0 = exception
// O1 = throwing pc
address generate_forward_exception() {
{- -------------------------------------------
(1) (以下, StubCodeMark によるスタブ生成を行う) (See: StubCodeMark)
---------------------------------------- -}
StubCodeMark mark(this, "StubRoutines", "forward_exception");
{- -------------------------------------------
(1) (ここからが生成するコードの始まり)
---------------------------------------- -}
address start = __ pc();
{- -------------------------------------------
(1) (このスタブに入ってきた時点では, O7 に
Java コードへのリターンアドレス(インタープリタ or JIT 生成コード)が入っている.
例外処理ルーチンからのリターンアドレスなので, つまり例外送出が起こった PC が O7 に入っている.)
---------------------------------------- -}
// Upon entry, O7 has the return address returning into Java
// (interpreted or compiled) code; i.e. the return address
// becomes the throwing pc.
{- -------------------------------------------
(1) (変数宣言など)
---------------------------------------- -}
const Register& handler_reg = Gtemp;
Address exception_addr(G2_thread, Thread::pending_exception_offset());
{- -------------------------------------------
(1) (デバッグ用の処理) (#ifdef ASSERT 時にのみ実行)
コード生成: (デバッグ用の処理)
---------------------------------------- -}
#ifdef ASSERT
// make sure that this code is only executed if there is a pending exception
{ Label L;
__ ld_ptr(exception_addr, Gtemp);
__ br_notnull(Gtemp, false, Assembler::pt, L);
__ delayed()->nop();
__ stop("StubRoutines::forward exception: no pending exception (1)");
__ bind(L);
}
#endif
{- -------------------------------------------
(1) コード生成:
「カレントスレッドの pending_exception フィールドから exception オブジェクトを取得し, Oexception レジスタに入れておく.
(これは, SharedRuntime::exception_handler_for_return_address() の引数として使う)」
---------------------------------------- -}
// compute exception handler into handler_reg
__ get_thread();
__ ld_ptr(exception_addr, Oexception);
{- -------------------------------------------
(1) コード生成: (verify)
---------------------------------------- -}
__ verify_oop(Oexception);
{- -------------------------------------------
(1) コード生成:
「SharedRuntime::exception_handler_for_return_address() を呼んで, 対応する例外ハンドラのアドレスを取得する.
(呼び出しの前後では save/restore も行っている)」
(なお, SharedRuntime::exception_handler_for_return_address() は,
例外発生時の PC が Lscratch に入っていると想定している模様)
---------------------------------------- -}
__ save_frame(0); // compensates for compiler weakness
__ add(O7->after_save(), frame::pc_return_offset, Lscratch); // save the issuing PC
BLOCK_COMMENT("call exception_handler_for_return_address");
__ call_VM_leaf(L7_thread_cache, CAST_FROM_FN_PTR(address, SharedRuntime::exception_handler_for_return_address), G2_thread, Lscratch);
__ mov(O0, handler_reg);
__ restore(); // compensates for compiler weakness
{- -------------------------------------------
(1) コード生成:
「カレントスレッドの pending_exception フィールドから exception オブジェクトを取得し, Oexception レジスタに入れておく.
また, 例外発生時の PC を Oissuing_pc に入れておく.」
---------------------------------------- -}
__ ld_ptr(exception_addr, Oexception);
__ add(O7, frame::pc_return_offset, Oissuing_pc); // save the issuing PC
{- -------------------------------------------
(1) (デバッグ用の処理) (#ifdef ASSERT 時にのみ実行)
コード生成: (デバッグ用の処理)
---------------------------------------- -}
#ifdef ASSERT
// make sure exception is set
{ Label L;
__ br_notnull(Oexception, false, Assembler::pt, L);
__ delayed()->nop();
__ stop("StubRoutines::forward exception: no pending exception (2)");
__ bind(L);
}
#endif
{- -------------------------------------------
(1) コード生成:
「カレントスレッドの pending_exception フィールドをクリアした後, 取得した例外ハンドラのアドレスにジャンプする」
---------------------------------------- -}
// jump to exception handler
__ jmp(handler_reg, 0);
// clear pending exception
__ delayed()->st_ptr(G0, exception_addr);
{- -------------------------------------------
(1) 以上で生成したコードの先頭アドレスをリターン
---------------------------------------- -}
return start;
}
This document is available under the GNU GENERAL PUBLIC LICENSE Version 2.