hotspot/src/share/vm/interpreter/interpreterRuntime.cpp
IRT_ENTRY(void, InterpreterRuntime::resolve_get_put(JavaThread* thread, Bytecodes::Code bytecode))
{- -------------------------------------------
(1) (変数宣言など)
---------------------------------------- -}
// resolve field
FieldAccessInfo info;
constantPoolHandle pool(thread, method(thread)->constants());
bool is_static = (bytecode == Bytecodes::_getstatic || bytecode == Bytecodes::_putstatic);
{- -------------------------------------------
(1) LinkResolver::resolve_field() を呼んで, フィールド情報の解決を行う.
(引数で渡した FieldAccessInfo オブジェクト(以下の info)に, 解決結果がセットされて返される)
(もしおかしなフィールドアクセスであれば, ここで例外が出る)
(なお, この処理の間は SingleStep イベントは無効にしている. (See: JvmtiHideSingleStepping))
---------------------------------------- -}
{
JvmtiHideSingleStepping jhss(thread);
LinkResolver::resolve_field(info, pool, get_index_u2_cpcache(thread, bytecode),
bytecode, false, CHECK);
} // end JvmtiHideSingleStepping
{- -------------------------------------------
(1) もし, 対象スレッドが現在実行しているバイトコード箇所の
CPCache エントリが既に resolve 済みであれば,
(することはないので) ここでリターン.
---------------------------------------- -}
// check if link resolution caused cpCache to be updated
if (already_resolved(thread)) return;
{- -------------------------------------------
(1) (変数宣言など)
(state は, 最終的に生成する CPCache エントリにセットする値.
field_type 情報の一部として _flags に格納されることになる.#TODO)
---------------------------------------- -}
// compute auxiliary field attributes
TosState state = as_TosState(info.field_type());
{- -------------------------------------------
(1) (変数宣言など)
(以下の箇所で, CPCache エントリに設定する以下の 2つの値を計算.
これらはアクセスしようとしたバイトコード種別を表し,
最終的には CPCache entry の _indices フィールドに格納されることになる. #TODO
* get_code
とりうる値は 3 通り.
0, Bytecodes::_getstatic, Bytecodes::_getfield #TODO
* put_code
とりうる値は 3 通り.
0, Bytecodes::_putstatic, Bytecodes::_putfield #TODO )
(コメントによると #TODO)
---------------------------------------- -}
// We need to delay resolving put instructions on final fields
// until we actually invoke one. This is required so we throw
// exceptions at the correct place. If we do not resolve completely
// in the current pass, leaving the put_code set to zero will
// cause the next put instruction to reresolve.
bool is_put = (bytecode == Bytecodes::_putfield ||
bytecode == Bytecodes::_putstatic);
Bytecodes::Code put_code = (Bytecodes::Code)0;
// We also need to delay resolving getstatic instructions until the
// class is intitialized. This is required so that access to the static
// field will call the initialization function every time until the class
// is completely initialized ala. in 2.17.5 in JVM Specification.
instanceKlass *klass = instanceKlass::cast(info.klass()->as_klassOop());
bool uninitialized_static = ((bytecode == Bytecodes::_getstatic || bytecode == Bytecodes::_putstatic) &&
!klass->is_initialized());
Bytecodes::Code get_code = (Bytecodes::Code)0;
if (!uninitialized_static) {
get_code = ((is_static) ? Bytecodes::_getstatic : Bytecodes::_getfield);
if (is_put || !info.access_flags().is_final()) {
put_code = ((is_static) ? Bytecodes::_putstatic : Bytecodes::_putfield);
}
}
{- -------------------------------------------
(1) ConstantPoolCacheEntry::set_field() を呼んで,
対象スレッドが現在実行しているバイトコード箇所の CPCache エントリに値をセットする.
---------------------------------------- -}
cache_entry(thread)->set_field(
get_code,
put_code,
info.klass(),
info.field_index(),
info.field_offset(),
state,
info.access_flags().is_final(),
info.access_flags().is_volatile()
);
IRT_END
This document is available under the GNU GENERAL PUBLIC LICENSE Version 2.