如何解释 java 中 -XX:CompileCommand="print Class::Method" 的输出

How to interpret the output of -XX:CompileCommand="print Class::Method" in java

这是我 运行 以下命令时得到的输出的摘录(40 只是 Fibonacci 程序的一个参数):

java -XX:+UnlockDiagnosticVMOptions -XX:CompileCommand="print Fibonacci::fibonacci" 斐波那契 40

谁能解释一下每个数据的含义(我估计是字节数,比如主代码占288字节)。另外,各种类别是什么意思 - 重定位、存根代码、元数据、范围数据、范围 pc、处理程序 table 等是什么意思?

...
Compiled method (c2)      93   16       4       Fibonacci::fibonacci (22 bytes)
total in heap  [0xfff8000108113dd0,0xfff8000108114440] = 1648
relocation     [0xfff8000108113f00,0xfff8000108113f48] = 72
main code      [0xfff8000108113f60,0xfff8000108114080] = 288
stub code      [0xfff8000108114080,0xfff80001081141e0] = 352
oops           [0xfff80001081141e0,0xfff80001081141e8] = 8
metadata       [0xfff80001081141e8,0xfff8000108114210] = 40
scopes data    [0xfff8000108114210,0xfff8000108114298] = 136
scopes pcs     [0xfff8000108114298,0xfff80001081143d8] = 320
dependencies   [0xfff80001081143d8,0xfff80001081143e0] = 8
handler table  [0xfff80001081143e0,0xfff8000108114440] = 96
----------------------------------------------------------------------
Fibonacci.fibonacci  [0xfff8000108113f60, 0xfff80001081141e0]  640 bytes
[Entry Point]
[Verified Entry Point]
[Constants]
# {method} {0xfff80001036243b8} 'fibonacci' '(I)J' in 'Fibonacci'
# parm0:    I0        = int
#           [sp+0x90]  (sp of caller)
...

方括号之间的十六进制数字是包含数据的内存范围的开始和结束。如您所料,= 之后的数字是以字节为单位的数据大小。

关于类别:

  • total in heap 是整个编译后的代码和元数据。它包括所有其他类别。它实际上大于所有其他类别的总和,因为还有一堆其他字段没有在这个 table 中描述(这个 table 只描述了对象中具有可变大小的部分)。
  • relocation 是允许 VM 在必要时修补代码的元数据:例如,如果代码嵌入了一个对象指针,那么如果 GC 移动该对象,则需要修改该指针。它还包含有关内联缓存、对外部常量的任何引用、运行时调用等的信息。
  • main code 是为该方法编译的大部分本机代码。
  • stub code 这是与此方法相关的更多机器代码。在某些运行时事件(例如,链接或重新链接调用站点或内联缓存、去优化、异常处理...)期间,通常是用于支持主要代码的小代码段
  • oops 普通对象指针数组(即指向垃圾收集对象的指针)。它们可以从主代码或下面的 scopes data 中引用。
  • metadata 自从在 JDK 8 中移除永久代后,VM 的关于 classes 和方法的元数据不再是标准的垃圾收集 oops,因为它们仍然需要被跟踪他们有自己的部分。所以 metadata 是指向元数据对象的指针(例如代表 classes 和方法的 VM 对象)。它们也可以从主代码或下面的 scopes data 中引用。
  • scopes pcs 这包含允许从主要本机代码中的程序计数器转到 Java 中的代码位置的元数据:本机 PC 映射到 Java 方法和字节码索引("bci")。由于内联,单个 PC 实际上与一堆 (method, bci) 对相关联。
  • scopes data 这包含进一步描述这些 PC 上的 Java 虚拟机状态的元数据。它包含将 JVM 位置(例如本地或堆栈槽)映射到本机位置(例如寄存器或本机堆栈槽)的数据。这允许 VM 知道在 GC 期间在哪里寻找 oops 以及在去优化期间重建解释器的状态。
  • dependencies 这是编译器在编译此方法时制作的 "assumptions" 列表。这样的假设可能是"class Foo has no subclasses"。这允许 VM 知道如果以后有什么东西违反了这个假设(例如加载一个新的 class,它是前面示例中 Foo 的子 class),则需要使这个方法无效。
  • handler table这是一个table,让VM知道在因为异常而展开时从哪里继续执行。