ldc

作者: asdf____ | 来源:发表于2020-04-25 16:47 被阅读0次

    根据 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 称为字符串字面量,但它同样有解析过程。

    相关文章

      网友评论

          本文标题:ldc

          本文链接:https://www.haomeiwen.com/subject/pixkwhtx.html