hotspot/src/cpu/x86/vm/templateTable_x86_64.cpp
void TemplateTable::fast_accessfield(TosState state) {
{- -------------------------------------------
(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.