hotspot/src/share/vm/prims/jvmtiClassFileReconstituter.cpp
void JvmtiClassFileReconstituter::copy_bytecodes(methodHandle mh,
unsigned char* bytecodes) {
{- -------------------------------------------
(1) (この関数では BytecodeStream を用いてバイトコードに対する iterate 処理を行う.
JVM/fast bytecodes や breakpoint bytecode は辿る際には元々のバイトコードに変換される.)
---------------------------------------- -}
// use a BytecodeStream to iterate over the bytecodes. JVM/fast bytecodes
// and the breakpoint bytecode are converted to their original bytecodes.
{- -------------------------------------------
(1) (変数宣言など)
---------------------------------------- -}
BytecodeStream bs(mh);
unsigned char* p = bytecodes;
Bytecodes::Code code;
bool is_rewritten = instanceKlass::cast(mh->method_holder())->is_rewritten();
{- -------------------------------------------
(1) (以下の while ループで, bytecode 全部に対して処理が終わるまでループ)
---------------------------------------- -}
while ((code = bs.next()) >= 0) {
{- -------------------------------------------
(1.1) (assert)
---------------------------------------- -}
assert(Bytecodes::is_java_code(code), "sanity check");
assert(code != Bytecodes::_breakpoint, "sanity check");
{- -------------------------------------------
(1.1) (変数宣言など)
---------------------------------------- -}
// length of bytecode (mnemonic + operands)
address bcp = bs.bcp();
int len = bs.instruction_size();
assert(len > 0, "length must be > 0");
{- -------------------------------------------
(1.1) バイトコードの内容をコピーする (複数 byte あれば memcpy)
---------------------------------------- -}
// copy the bytecodes
*p = (unsigned char) (bs.is_wide()? Bytecodes::_wide : code);
if (len > 1) {
memcpy(p+1, bcp+1, len-1);
}
{- -------------------------------------------
(1.1) get/put や invoke 命令については, リンク時に書き換えた場合には元の情報をコピーする.
---------------------------------------- -}
// During linking the get/put and invoke instructions are rewritten
// with an index into the constant pool cache. The original constant
// pool index must be returned to caller. Rewrite the index.
if (is_rewritten && len >= 3) {
switch (code) {
case Bytecodes::_getstatic : // fall through
case Bytecodes::_putstatic : // fall through
case Bytecodes::_getfield : // fall through
case Bytecodes::_putfield : // fall through
case Bytecodes::_invokevirtual : // fall through
case Bytecodes::_invokespecial : // fall through
case Bytecodes::_invokestatic : // fall through
case Bytecodes::_invokedynamic : // fall through
case Bytecodes::_invokeinterface :
assert(len == 3 || (code == Bytecodes::_invokeinterface && len ==5),
"sanity check");
int cpci = Bytes::get_native_u2(bcp+1);
bool is_invokedynamic = (EnableInvokeDynamic && code == Bytecodes::_invokedynamic);
if (is_invokedynamic)
cpci = Bytes::get_native_u4(bcp+1);
// cache cannot be pre-fetched since some classes won't have it yet
ConstantPoolCacheEntry* entry =
mh->constants()->cache()->main_entry_at(cpci);
int i = entry->constant_pool_index();
assert(i < mh->constants()->length(), "sanity check");
Bytes::put_Java_u2((address)(p+1), (u2)i); // java byte ordering
if (is_invokedynamic) *(p+3) = *(p+4) = 0;
break;
}
}
p += len;
}
}
This document is available under the GNU GENERAL PUBLIC LICENSE Version 2.