根據(jù) 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);
}
執(zhí)行流程:
(1)根據(jù) ldc
的操作數(shù)值,也就是運(yùn)行時(shí)常量池中某項(xiàng)常量的索引值,到常量池中獲取到對(duì)應(yīng)的常量,這里可能是 JVM_CONSTANT_Integer
较幌、JVM_CONSTANT_Float
、JVM_CONSTANT_String
、JVM_CONSTANT_Class
御毅、JVM_CONSTANT_UnresolvedClass
、JVM_CONSTANT_UnresolvedClassInError
怜珍。
(2)根據(jù)不同類型的常量端蛆,執(zhí)行不同的邏輯。
接下來著重看下 JVM_CONSTANT_Integer
酥泛、JVM_CONSTANT_Float
今豆、JVM_CONSTANT_String
這幾種類型常量的執(zhí)行邏輯。
JVM_CONSTANT_Integer
柔袁、JVM_CONSTANT_Float
這兩個(gè)類似:
(1)直接獲取常量中保存的 int
或 float
值呆躲;
(2)將 int
或 float
值壓入操作數(shù)棧;
JVM_CONSTANT_String
:
(1)判斷該常量是否已經(jīng)解析過捶索,如果已經(jīng)解析過直接返回常量池中保存的 String對(duì)象 引用插掂;
(2)否則進(jìn)行解析:調(diào)用 StringTable::intern
判斷是否字符串常量池已有相同值的 String 對(duì)象引用,有就直接返回引用情组,沒有則根據(jù)對(duì)應(yīng)字符串值創(chuàng)建對(duì)象并把引用保存在 StringTable 中燥筷,并發(fā)這個(gè)引用保存到 ConstantPool
的 resolved_references
中箩祥,最后返回這個(gè)引用院崇。
resolved_references
是 ConstantPool
中的一個(gè) objArrayOop
對(duì)象,
所以雖然 Constant_String_info
稱為字符串字面量袍祖,但它同樣有解析過程底瓣。