Top


定義場所(file name)

hotspot/src/cpu/x86/vm/templateTable_x86_64.cpp

名前(function name)

void TemplateTable::fast_accessfield(TosState state) {

本体部(body)

  {- -------------------------------------------
  (1) (assert) (See: TemplateTable::transition())
      ---------------------------------------- -}

      transition(atos, state);

  {- -------------------------------------------
  (1) コード生成: (JVMTI のフック点)
      ---------------------------------------- -}

      // Do the JVMTI work here to avoid disturbing the register state below
      if (JvmtiExport::can_post_field_access()) {
        // Check to see if a field access watch has been set before we
        // take the time to call into the VM.
        Label L1;
        __ mov32(rcx, ExternalAddress((address) JvmtiExport::get_field_access_count_addr()));
        __ testl(rcx, rcx);
        __ jcc(Assembler::zero, L1);
        // access constant pool cache entry
        __ get_cache_entry_pointer_at_bcp(c_rarg2, rcx, 1);
        __ verify_oop(rax);
        __ push_ptr(rax);  // save object pointer before call_VM() clobbers it
        __ mov(c_rarg1, rax);
        // c_rarg1: object pointer copied above
        // c_rarg2: cache entry pointer
        __ call_VM(noreg,
                   CAST_FROM_FN_PTR(address,
                                    InterpreterRuntime::post_field_access),
                   c_rarg1, c_rarg2);
        __ pop_ptr(rax); // restore object pointer
        __ bind(L1);
      }

  {- -------------------------------------------
  (1) InterpreterMacroAssembler::get_cache_and_index_at_bcp() を呼んで, 以下のようなコードを生成.
      「現在箇所のバイトコード(bcp)に対応する CPCache のアドレスを rcx に, 対応する index を rbx に取得.」
      ---------------------------------------- -}

      // access constant pool cache
      __ get_cache_and_index_at_bcp(rcx, rbx, 1);

  {- -------------------------------------------
  (1) (以下に, 「volatile 情報を取得する」というコードが書かれているが, コメントアウトされている.
       現状の x86 ではメモリバリアは要らないので, このコードも不要である模様.)
      ---------------------------------------- -}

      // replace index with field offset from cache entry
      // [jk] not needed currently
      // if (os::is_MP()) {
      //   __ movl(rdx, Address(rcx, rbx, Address::times_8,
      //                        in_bytes(constantPoolCacheOopDesc::base_offset() +
      //                                 ConstantPoolCacheEntry::flags_offset())));
      //   __ shrl(rdx, ConstantPoolCacheEntry::volatileField);
      //   __ andl(rdx, 0x1);
      // }

  {- -------------------------------------------
  (1) コード生成:
      「取得した CPCache のアドレス及び index をもとに, 実際のオフセット情報を rbx に取得」
      ---------------------------------------- -}

      __ movptr(rbx, Address(rcx, rbx, Address::times_8,
                             in_bytes(constantPoolCacheOopDesc::base_offset() +
                                      ConstantPoolCacheEntry::f2_offset())));

  {- -------------------------------------------
  (1) コード生成: (verify)
      ---------------------------------------- -}

      // rax: object
      __ verify_oop(rax);

  {- -------------------------------------------
  (1) コード生成: (NULL チェック)
      ---------------------------------------- -}

      __ null_check(rax);

  {- -------------------------------------------
  (1) (変数宣言など)
      ---------------------------------------- -}

      Address field(rax, rbx, Address::times_1);

  {- -------------------------------------------
  (1) コード生成:
      (バイトコードの型に応じた適切なロード命令を生成)
      ---------------------------------------- -}

      // access field
      switch (bytecode()) {
      case Bytecodes::_fast_agetfield:
        __ load_heap_oop(rax, field);
        __ verify_oop(rax);
        break;
      case Bytecodes::_fast_lgetfield:
        __ movq(rax, field);
        break;
      case Bytecodes::_fast_igetfield:
        __ movl(rax, field);
        break;
      case Bytecodes::_fast_bgetfield:
        __ movsbl(rax, field);
        break;
      case Bytecodes::_fast_sgetfield:
        __ load_signed_short(rax, field);
        break;
      case Bytecodes::_fast_cgetfield:
        __ load_unsigned_short(rax, field);
        break;
      case Bytecodes::_fast_fgetfield:
        __ movflt(xmm0, field);
        break;
      case Bytecodes::_fast_dgetfield:
        __ movdbl(xmm0, field);
        break;
      default:
        ShouldNotReachHere();
      }

  {- -------------------------------------------
  (1) (ここで終了)
      (なお, 現状の x86 ではメモリバリアは不要なので張っていない)
      ---------------------------------------- -}

      // [jk] not needed currently
      // if (os::is_MP()) {
      //   Label notVolatile;
      //   __ testl(rdx, rdx);
      //   __ jcc(Assembler::zero, notVolatile);
      //   __ membar(Assembler::LoadLoad);
      //   __ bind(notVolatile);
      //};
    }

This document is available under the GNU GENERAL PUBLIC LICENSE Version 2.