作者:XL | 来源:互联网 | 2022-10-25 17:01
我对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吗?
1> Holger..:
Java程序集没有标准化的格式,因此,可能会有所不同,具体取决于您用来获取文本形式的工具。
显然,您使用的工具不会打印LDC
指令使用的常量池索引(确实必须为正数),而是打印池中的实际常量值。最强的指示符是显示实际String
值的后续指令,而不是恒定池索引。
这与随后的调用相符getProbes(JLjava/lang/String;I)
,后者在堆栈上期望a long
,a String
和an int
。
LDC -1475355800743669619
将文字long
值压-1475355800743669619
入堆栈,该值-1475355800743669619
在long
值范围内有效(已签名)
LDC "ClassUnderTest"
推到一个参考String
表示"ClassUnderTest"
到堆栈
BIPUSH 64
pushes the literal int
value 64
to the stack
So then, you have a long
, a String
, and an int
on the stack for the invocation of getProbes
.
Since the long
value is the argument to getProbes
’s first parameter, the method getProbes
determines its meaning and whether negative or positive values are plausible arguments, as well as whether the value has to be the same for JDK 8 or JDK 11.
https://www.jacoco.org/jacoco/trunk/doc/implementation.html says:
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.
If that’s the long
value we see here, just recompiling a class with a different JDK version might change the actual value and negative values are entirely plausible.
Note that if you used javap
instead, to get the textual output, it looked more like
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
indeed showing the positive constant pool indices and the actual values in a comment form at the end of the line. Of course, I just made up the numbers as I don’t have the original class file. This is just for illustration of the fact stated at the beginning of the answer, there is no standardized form for Java assembly output. You may run javap
on the actual byte code.