Top


定義場所(file name)

hotspot/src/cpu/sparc/vm/templateTable_sparc.cpp

説明(description)

(なお, スタックフレーム中の BasicObjectLock 領域のレイアウトについては, frame_sparc.hpp 参照とのこと.)

// See frame_sparc.hpp for monitor block layout.
// Monitor elements are dynamically allocated by growing stack as needed.

名前(function name)

void TemplateTable::monitorenter() {

本体部(body)

  {- -------------------------------------------
  (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.