java - LDC 指令代码的负值是什么意思?

标签 java jvm bytecode jacoco java-11

我是 java 字节码世界的新手。我有一些涉及字节码的调试任务。在经历那件事时,我注意到一些看起来可疑的值,但我不确定。这是完整字节码的一部分

// access flags 0x100A
  private static synthetic $jacocoInit()[Z
    GETSTATIC ClassUnderTest.$jacocoData : [Z
    DUP
    IFNONNULL L0
    POP
    LDC -1475355800743669619
    LDC "ClassUnderTest"
    BIPUSH 64
    INVOKESTATIC org/jacoco/agent/rt/internal_1f1cc91/Offline.getProbes (JLjava/lang/String;I)[Z
    DUP
    PUTSTATIC ClassUnderTest.$jacocoData : [Z
   L0

这里 LDC -1475355800743669619 是我关心的。到目前为止我所学到的是,这是一个类中常量值的字段。

我很困惑 LDC 值是否可以为负数?

我遇到的另一个问题是,对于 JDK-8,同一类的 LDC 值为正,而对于 JDK-11,则为负。所以我的问题是,它是否也依赖于 JDK?

最佳答案

Java 程序集没有标准化格式,因此可能存在差异,具体取决于您使用哪种工具获取文本形式。

显然,您使用的工具不会打印 LDC 指令使用的常量池索引(确实必须为正数),而是打印池中的实际常量值。最强的指标是显示实际 String 值而不是常量池索引的后续指令。

这适合随后调用 getProbes(JLjava/lang/String;I),它需要一个 long,一个 String,和堆栈上的 int

  • LDC -1475355800743669619 将文字 long-1475355800743669619 压入堆栈,有效为 -1475355800743669619 适合 long 值范围(已签名)
  • LDC "ClassUnderTest" 将对表示 "ClassUnderTest"String 的引用推送到堆栈
  • BIPUSH 64 将文字 int64 压入堆栈

那么,您在堆栈上有一个 long、一个 String 和一个 int 用于调用 getProbes.

由于 long 值是 getProbes 的第一个参数,方法 getProbes 确定其含义以及是负值还是正值是合理的论点,以及 JDK 8 或 JDK 11 的值是否必须相同。

https://www.jacoco.org/jacoco/trunk/doc/implementation.html说:

Each class loaded at runtime needs a unique identity to associate coverage data with. JaCoCo creates such identities by a CRC64 hash code of the raw class definition.

如果这是我们在这里看到的 long 值,只需使用不同的 JDK 版本重新编译一个类,可能就会改变实际值,而负值是完全合理的。

请注意,如果您改用 javap 来获取文本输出,它看起来更像

 0: getstatic       #42             // ClassUnderTest.$jacocoData : [Z
 3: dup
 4: ifnonnull       22
 7: pop
 9: ldc2_w          #43             // long -1475355800743669619l
11: ldc             #44             // String ClassUnderTest
13: bipush          64
15: invokestatic    #45             // org/jacoco/agent/rt/internal_1f1cc91/Offline."getProbes":(JLjava/lang/String;I)[Z
18: dup
19: putstatic       #42             // ClassUnderTest.$jacocoData : [Z

确实在行尾的注释表单中显示了正常量池索引和实际值。当然,我只是编造了数字,因为我没有原始的类文件。这只是为了说明答案开头所述的事实,Java 程序集输出没有标准化形式。您可以在实际的字节代码上运行 javap

关于java - LDC 指令代码的负值是什么意思?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56003435/

相关文章:

java - 安卓开发 : Navigation View vs App Bar

Java Random - 总是打印 1

java - 如何判断我是在 64 位 JVM 还是 32 位 JVM 中运行(从程序中)?

java - 执行后在Java代理中运行代码?帖子主要?

java - Spring @Transactional - 在持久/合并后使用集合

java - 使用java计算求和中的处理构造函数

java - JVM 的默认编码是什么?

java - 如何将新的货币代码添加到 Java?

flash - 如何反汇编 ABC 字节码?

c - 如何为位掩码创建 48 位 uint