ldc
根据 bytecodeInterpreter.cpp
找到 ldc
指令:
CASE(_ldc):
{
u2 index;
bool wide = false;
int incr = 2; // frequent case
if (opcode == Bytecodes::_ldc) {
index = pc[1];
} else {
index = Bytes::get_Java_u2(pc+1);
incr = 3;
wide = true;
}
ConstantPool* constants = METHOD->constants();
switch (constants->tag_at(index).value()) {
case JVM_CONSTANT_Integer:
SET_STACK_INT(constants->int_at(index), 0);
break;
case JVM_CONSTANT_Float:
SET_STACK_FLOAT(constants->float_at(index), 0);
break;
case JVM_CONSTANT_String:
{
oop result = constants->resolved_references()->obj_at(index);
if (result == NULL) {
CALL_VM(InterpreterRuntime::resolve_ldc(THREAD, (Bytecodes::Code) opcode), handle_exception);
SET_STACK_OBJECT(THREAD->vm_result(), 0);
THREAD->set_vm_result(NULL);
} else {
VERIFY_OOP(result);
SET_STACK_OBJECT(result, 0);
}
break;
}
case JVM_CONSTANT_Class:
VERIFY_OOP(constants->resolved_klass_at(index)->java_mirror());
SET_STACK_OBJECT(constants->resolved_klass_at(index)->java_mirror(), 0);
break;
case JVM_CONSTANT_UnresolvedClass:
case JVM_CONSTANT_UnresolvedClassInError:
CALL_VM(InterpreterRuntime::ldc(THREAD, wide), handle_exception);
SET_STACK_OBJECT(THREAD->vm_result(), 0);
THREAD->set_vm_result(NULL);
break;
default: ShouldNotReachHere();
}
UPDATE_PC_AND_TOS_AND_CONTINUE(incr, 1);
}
执行流程:
(1)根据 ldc
的操作数值,也就是运行时常量池中某项常量的索引值,到常量池中获取到对应的常量,这里可能是 JVM_CONSTANT_Integer
、JVM_CONSTANT_Float
、JVM_CONSTANT_String
、JVM_CONSTANT_Class
、JVM_CONSTANT_UnresolvedClass
、JVM_CONSTANT_UnresolvedClassInError
。
(2)根据不同类型的常量,执行不同的逻辑。
接下来着重看下 JVM_CONSTANT_Integer
、JVM_CONSTANT_Float
、JVM_CONSTANT_String
这几种类型常量的执行逻辑。
JVM_CONSTANT_Integer
、JVM_CONSTANT_Float
这两个类似:
(1)直接获取常量中保存的 int
或 float
值;
(2)将 int
或 float
值压入操作数栈;
JVM_CONSTANT_String
:
(1)判断该常量是否已经解析过,如果已经解析过直接返回常量池中保存的 String对象 引用;
(2)否则进行解析:调用 StringTable::intern
判断是否字符串常量池已有相同值的 String 对象引用,有就直接返回引用,没有则根据对应字符串值创建对象并把引用保存在 StringTable 中,并发这个引用保存到 ConstantPool
的 resolved_references
中,最后返回这个引用。
resolved_references
是 ConstantPool
中的一个 objArrayOop
对象,
所以虽然 Constant_String_info
称为字符串字面量,但它同样有解析过程。