hotspot/src/cpu/sparc/vm/interp_masm_sparc.cpp
// remove activation
//
// Unlock the receiver if this is a synchronized method.
// Unlock any Java monitors from syncronized blocks.
// Remove the activation from the stack.
//
// If there are locked Java monitors
// If throw_monitor_exception
// throws IllegalMonitorStateException
// Else if install_monitor_exception
// installs IllegalMonitorStateException
// Else
// no error processing
void InterpreterMacroAssembler::remove_activation(TosState state,
bool throw_monitor_exception,
bool install_monitor_exception) {
{- -------------------------------------------
(1) コード生成:
「InterpreterMacroAssembler::unlock_if_synchronized_method() が生成するコードで,
(もし synchronized メソッドの場合には) ロックを解放する.
モニターのロック状態がおかしければ, IllegalMonitorStateException も送出される.
(See: [here](no3059F5A.html) for details)
---------------------------------------- -}
unlock_if_synchronized_method(state, throw_monitor_exception, install_monitor_exception);
{- -------------------------------------------
(1) コード生成: (JVMTI のフック点)
---------------------------------------- -}
// save result (push state before jvmti call and pop it afterwards) and notify jvmti
notify_method_exit(false, state, NotifyJVMTI);
{- -------------------------------------------
(1) コード生成: (verify)
---------------------------------------- -}
interp_verify_oop(Otos_i, state, __FILE__, __LINE__);
verify_oop(Lmethod);
verify_thread();
{- -------------------------------------------
(1) コード生成:
「返値を適切なレジスタに移動させておく」
(この後, restore 命令によってレジスタウインドウが回ってしまうので,
restore 後でもきちんと見えるように移動させる.
具体的には, O0 レジスタ (及び O1 レジスタ) に入っているものを
I0 レジスタ (及び I1 レジスタ) に移すだけ.
引数で指定された tos (以下の state) に応じて, 適切な命令を生成している)
---------------------------------------- -}
// return tos
assert(Otos_l1 == Otos_i, "adjust code below");
switch (state) {
#ifdef _LP64
case ltos: mov(Otos_l, Otos_l->after_save()); break; // O0 -> I0
#else
case ltos: mov(Otos_l2, Otos_l2->after_save()); // fall through // O1 -> I1
#endif
case btos: // fall through
case ctos:
case stos: // fall through
case atos: // fall through
case itos: mov(Otos_l1, Otos_l1->after_save()); break; // O0 -> I0
case ftos: // fall through
case dtos: // fall through
case vtos: /* nothing to do */ break;
default : ShouldNotReachHere();
}
{- -------------------------------------------
(1) コード生成: (ただし, 32bit 環境でかつ C2 利用時でない場合には, 不要なので生成しない)
「32bit 環境では long 値だけは扱いが特殊なので調整しておく」
(正確に言うと, 32bit 環境では C2 とインタープリタで使うレジスタがずれている.
C2 は G1 を使うがインタープリタは O0 と O1 を使う)
---------------------------------------- -}
#if defined(COMPILER2) && !defined(_LP64)
if (state == ltos) {
// C2 expects long results in G1 we can't tell if we're returning to interpreted
// or compiled so just be safe use G1 and O0/O1
// Shift bits into high (msb) of G1
sllx(Otos_l1->after_save(), 32, G1);
// Zero extend low bits
srl (Otos_l2->after_save(), 0, Otos_l2->after_save());
or3 (Otos_l2->after_save(), G1, G1);
}
#endif /* COMPILER2 */
}
This document is available under the GNU GENERAL PUBLIC LICENSE Version 2.