hotspot/src/cpu/sparc/vm/templateTable_sparc.cpp
(なお, スタックフレーム中の BasicObjectLock 領域のレイアウトについては, frame_sparc.hpp 参照とのこと.)
// See frame_sparc.hpp for monitor block layout.
// Monitor elements are dynamically allocated by growing stack as needed.
void TemplateTable::monitorenter() {
{- -------------------------------------------
(1) (assert) (See: TemplateTable::transition())
---------------------------------------- -}
transition(atos, vtos);
{- -------------------------------------------
(1) コード生成: (verify)
---------------------------------------- -}
__ verify_oop(Otos_i);
{- -------------------------------------------
(1) (このコードレットでは, ロックの確保を行う.
ロック確保は失敗することもあるので成功するまでループする.)
---------------------------------------- -}
// Try to acquire a lock on the object
// Repeat until succeeded (i.e., until
// monitorenter returns true).
{- -------------------------------------------
(1) コード生成:
「もしロック確保対象のオブジェクトが null であれば, NullPointerException」
---------------------------------------- -}
{ Label ok;
__ tst(Otos_i);
__ throw_if_not_1_x( Assembler::notZero, ok);
__ delayed()->mov(Otos_i, Lscratch); // save obj
__ throw_if_not_2( Interpreter::_throw_NullPointerException_entry, G3_scratch, ok);
}
{- -------------------------------------------
(1) (assert)
---------------------------------------- -}
assert(O0 == Otos_i, "Be sure where the object to lock is");
{- -------------------------------------------
(1) コード生成:
「スタックフレーム中の BasicObjectLock 領域から空きスロットを探す」
---------------------------------------- -}
// find a free slot in the monitor block
// initialize entry pointer
__ clr(O1); // points to free slot or NULL
{
Label entry, loop, exit;
__ add( __ top_most_monitor(), O2 ); // last one to check
__ ba( false, entry );
__ delayed()->mov( Lmonitors, O3 ); // first one to check
{- -------------------------------------------
(1.1) (ここからが, 空いている BasicObjectLock を探索するループ)
---------------------------------------- -}
__ bind( loop );
__ verify_oop(O4); // verify each monitor's oop
__ tst(O4); // is this entry unused?
if (VM_Version::v9_instructions_work())
__ movcc( Assembler::zero, false, Assembler::ptr_cc, O3, O1);
else {
Label L;
__ br( Assembler::zero, true, Assembler::pn, L );
__ delayed()->mov(O3, O1); // rememeber this one if match
__ bind(L);
}
__ cmp(O4, O0); // check if current entry is for same object
__ brx( Assembler::equal, false, Assembler::pn, exit );
__ delayed()->inc( O3, frame::interpreter_frame_monitor_size() * wordSize ); // check next one
__ bind( entry );
__ cmp( O3, O2 );
__ brx( Assembler::lessEqualUnsigned, true, Assembler::pt, loop );
__ delayed()->ld_ptr(O3, BasicObjectLock::obj_offset_in_bytes(), O4);
{- -------------------------------------------
(1.1) (ここまでが探索のループ)
---------------------------------------- -}
__ bind( exit );
}
{- -------------------------------------------
(1) コード生成:
「もし空きスロットがなければ,
InterpreterMacroAssembler::add_monitor_to_stack() が生成するコードでスペースを作る」
---------------------------------------- -}
{ Label allocated;
// found free slot?
__ br_notnull(O1, false, Assembler::pn, allocated);
__ delayed()->nop();
__ add_monitor_to_stack( false, O2, O3 );
__ mov(Lmonitors, O1);
__ bind(allocated);
}
{- -------------------------------------------
(1) コード生成:
「Lbcp を次のバイトコードに進めておく」
---------------------------------------- -}
// Increment bcp to point to the next bytecode, so exception handling for async. exceptions work correctly.
// The object has already been poped from the stack, so the expression stack looks correct.
__ inc(Lbcp);
{- -------------------------------------------
(1) コード生成:
「BasicObjectLock にロック対象のオブジェクトの oop を書き込む」
---------------------------------------- -}
__ st_ptr(O0, O1, BasicObjectLock::obj_offset_in_bytes()); // store object
{- -------------------------------------------
(1) コード生成:
「InterpreterMacroAssembler::lock_object() が生成するコードにより
対象のオブジェクトにロック処理を行う」
---------------------------------------- -}
__ lock_object(O1, O0);
{- -------------------------------------------
(1) コード生成:
「InterpreterGenerator::generate_stack_overflow_check() が生成するコードにより
stack overflow のチェックを行う」
---------------------------------------- -}
// check if there's enough space on the stack for the monitors after locking
__ generate_stack_overflow_check(0);
{- -------------------------------------------
(1) コード生成:
「dispatch_next() が生成するコードで,
次のバイトコードに対応するテンプレートへとジャンプする」
---------------------------------------- -}
// The bcp has already been incremented. Just need to dispatch to next instruction.
__ dispatch_next(vtos);
This document is available under the GNU GENERAL PUBLIC LICENSE Version 2.