java – LDC指令代码的负值是什么意思?
作者:互联网
我是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在堆栈上推送文字长值-1475355800743669619,该值有效,因为-1475355800743669619适合长值范围(已签名)
> LDC“ClassUnderTest”将对表示“ClassUnderTest”的String的引用推送到堆栈
> BIPUSH 64将文字int值64推送到堆栈
那么,你在堆栈上有一个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.
如果这是我们在这里看到的长值,那么重新编译具有不同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.
标签:jacoco,java-11,java,jvm,bytecode 来源: https://codeday.me/bug/20190827/1744626.html