hotspot/src/share/vm/interpreter/rewriter.cpp
void Rewriter::rewrite_invokedynamic(address bcp, int offset, bool reverse) {
{- -------------------------------------------
(1) reverse 引数が false の場合には,
バイトコード命令中の Constant Pool index が埋まっている 4byte を
対応する Constant Pool Cache index に置き換える.
(また, この 4byte は実行環境のエンディアンに従って書き込む)
reverse 引数が true の場合には, 逆に元に戻す処理が行われる.
---------------------------------------- -}
address p = bcp + offset;
assert(p[-1] == Bytecodes::_invokedynamic, "not invokedynamic bytecode");
if (!reverse) {
int cp_index = Bytes::get_Java_u2(p);
int cpc = maybe_add_cp_cache_entry(cp_index); // add lazily
int cpc2 = add_secondary_cp_cache_entry(cpc);
// Replace the trailing four bytes with a CPC index for the dynamic
// call site. Unlike other CPC entries, there is one per bytecode,
// not just one per distinct CP entry. In other words, the
// CPC-to-CP relation is many-to-one for invokedynamic entries.
// This means we must use a larger index size than u2 to address
// all these entries. That is the main reason invokedynamic
// must have a five-byte instruction format. (Of course, other JVM
// implementations can use the bytes for other purposes.)
Bytes::put_native_u4(p, constantPoolCacheOopDesc::encode_secondary_index(cpc2));
// Note: We use native_u4 format exclusively for 4-byte indexes.
} else {
int cache_index = constantPoolCacheOopDesc::decode_secondary_index(
Bytes::get_native_u4(p));
int secondary_index = cp_cache_secondary_entry_main_index(cache_index);
int pool_index = cp_cache_entry_pool_index(secondary_index);
assert(_pool->tag_at(pool_index).is_invoke_dynamic(), "wrong index");
// zero out 4 bytes
Bytes::put_Java_u4(p, 0);
Bytes::put_Java_u2(p, pool_index);
}
}
This document is available under the GNU GENERAL PUBLIC LICENSE Version 2.