hotspot/src/cpu/sparc/vm/templateTable_sparc.cpp
void TemplateTable::resolve_cache_and_index(int byte_no,
Register result,
Register Rcache,
Register index,
size_t index_size) {
{- -------------------------------------------
(1) (cpCacheOop のレイアウトに依存していることに注意!)
---------------------------------------- -}
// Depends on cpCacheOop layout!
{- -------------------------------------------
(1) (変数宣言など)
---------------------------------------- -}
Label resolved;
{- -------------------------------------------
(1) InterpreterMacroAssembler::get_cache_and_index_at_bcp() を呼んで, 以下のようなコードを生成.
「現在箇所のバイトコード(bcp)に対応する CPCache エントリのアドレスを Rcache に取得.
(ただし, まだ対応する CPCache エントリのアドレスを作っていなかった場合は, ...#TODO が取得される)」
---------------------------------------- -}
__ get_cache_and_index_at_bcp(Rcache, index, 1, index_size);
{- -------------------------------------------
(1) 引数の byte_no に応じて以下の 2通りのコードを生成する.
どちらの場合も, ...#TODO
* f1_oop の場合:
「取得した CPCache エントリの f1 フィールドをロードし, NULL かどうかチェックする.
NULL でなければ(= 既にそのエントリは作成済みであれば), resolved ラベルまでジャンプする.
そうでなければ, このままフォールスルーして作成処理を行う.」
* それ以外の場合 (f1_byte または f2_byte):
「取得した CPCache エントリの ... かどうかチェックする. #TODO
同じであれば(= 既にそのエントリは作成済みであれば), resolved ラベルまでジャンプする.
そうでなければ, このままフォールスルーして作成処理を行う.」
---------------------------------------- -}
if (byte_no == f1_oop) {
// We are resolved if the f1 field contains a non-null object (CallSite, etc.)
// This kind of CP cache entry does not need to match the flags byte, because
// there is a 1-1 relation between bytecode type and CP entry type.
assert_different_registers(result, Rcache);
__ ld_ptr(Rcache, constantPoolCacheOopDesc::base_offset() +
ConstantPoolCacheEntry::f1_offset(), result);
__ tst(result);
__ br(Assembler::notEqual, false, Assembler::pt, resolved);
__ delayed()->set((int)bytecode(), O1);
} else {
assert(byte_no == f1_byte || byte_no == f2_byte, "byte_no out of range");
assert(result == noreg, ""); //else change code for setting result
const int shift_count = (1 + byte_no)*BitsPerByte;
__ ld_ptr(Rcache, constantPoolCacheOopDesc::base_offset() +
ConstantPoolCacheEntry::indices_offset(), Lbyte_code);
__ srl( Lbyte_code, shift_count, Lbyte_code );
__ and3( Lbyte_code, 0xFF, Lbyte_code );
__ cmp( Lbyte_code, (int)bytecode());
__ br( Assembler::equal, false, Assembler::pt, resolved);
__ delayed()->set((int)bytecode(), O1);
}
{- -------------------------------------------
(1) (変数宣言など)
(entry は, まだ CPCache エントリが生成されてなかった場合に呼び出すべき関数 (CPCache エントリ生成用の関数).
以下の通り, 現在箇所のバイトコードに応じて呼び出す関数は変わる.)
---------------------------------------- -}
address entry;
switch (bytecode()) {
case Bytecodes::_getstatic : // fall through
case Bytecodes::_putstatic : // fall through
case Bytecodes::_getfield : // fall through
case Bytecodes::_putfield : entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_get_put); break;
case Bytecodes::_invokevirtual : // fall through
case Bytecodes::_invokespecial : // fall through
case Bytecodes::_invokestatic : // fall through
case Bytecodes::_invokeinterface: entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_invoke); break;
case Bytecodes::_invokedynamic : entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_invokedynamic); break;
case Bytecodes::_fast_aldc : entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_ldc); break;
case Bytecodes::_fast_aldc_w : entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_ldc); break;
default : ShouldNotReachHere(); break;
}
{- -------------------------------------------
(1) コード生成:
「CPCache エントリ生成用の関数(以下の entry)を呼び出す.
その後, 改めて get_cache_and_index_at_bcp() が生成したコードを実行し,
現在箇所のバイトコード(bcp)に対応する CPCache エントリのアドレスを Rcache に取得する.」
(もし...#TODO であれば, 以下のコードも生成しておく.
「取得しなおした CPCache エントリの f1 フィールドを, result レジスタにロードする.」)
---------------------------------------- -}
// first time invocation - must resolve first
__ call_VM(noreg, entry, O1);
// Update registers with resolved info
__ get_cache_and_index_at_bcp(Rcache, index, 1, index_size);
if (result != noreg)
__ ld_ptr(Rcache, constantPoolCacheOopDesc::base_offset() +
ConstantPoolCacheEntry::f1_offset(), result);
{- -------------------------------------------
(1) (ここが resolved ラベルの位置.
CPCache エントリが既に生成されていた場合は, この地点まで飛んでくる)
---------------------------------------- -}
__ bind(resolved);
}
This document is available under the GNU GENERAL PUBLIC LICENSE Version 2.