ldc

2020-04-25  本文已影响0人  asdf____

根据 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_IntegerJVM_CONSTANT_FloatJVM_CONSTANT_StringJVM_CONSTANT_ClassJVM_CONSTANT_UnresolvedClassJVM_CONSTANT_UnresolvedClassInError
(2)根据不同类型的常量,执行不同的逻辑。

接下来着重看下 JVM_CONSTANT_IntegerJVM_CONSTANT_FloatJVM_CONSTANT_String 这几种类型常量的执行逻辑。

JVM_CONSTANT_IntegerJVM_CONSTANT_Float 这两个类似:
(1)直接获取常量中保存的 intfloat 值;
(2)将 intfloat 值压入操作数栈;

JVM_CONSTANT_String
(1)判断该常量是否已经解析过,如果已经解析过直接返回常量池中保存的 String对象 引用;
(2)否则进行解析:调用 StringTable::intern 判断是否字符串常量池已有相同值的 String 对象引用,有就直接返回引用,没有则根据对应字符串值创建对象并把引用保存在 StringTable 中,并发这个引用保存到 ConstantPoolresolved_references 中,最后返回这个引用。
resolved_referencesConstantPool 中的一个 objArrayOop 对象,
所以虽然 Constant_String_info 称为字符串字面量,但它同样有解析过程。

上一篇下一篇

猜你喜欢

热点阅读