对于HotSpot JIT,"已编译为一个大方法"是什么意思?

6
我正在查看JIT HotSpot编译器日志 (-XX:+PrintCompilation -XX:+UnlockDiagnosticVMOptions -XX:+PrintInlining),以确保一个重要/热门方法被正确优化/编译。该方法显示为:

已编译成一个大的方法

这是什么意思?我的方法是否被JIT正确地优化/内联?
来自Oracle wiki的解释没有给我任何结论:

已编译成一个大的方法:对于从调用站点调用的方法已经有了编译代码,并且生成的代码比InlineSmallCode更大。

这是什么意思?它是指我的代码已被优化/内联,还是HotSpot现在跳过它,因为它已经在其他地方编译过了?

Hotspot的诊断信息在https://wikis.oracle.com/display/HotSpotInternals/Server+Compiler+Inlining+Messages中有描述。你看过这个文档吗? - wero
@wero 我已经看过了,但不幸的是它并没有给我带来任何结论。这是什么意思?这是否意味着我的代码被优化/内联或者HotSpot现在跳过它,因为它在其他地方被编译了? - LatencyGuy
1
代码是“内联”的,当它很小并且可以被替换而不是调用函数时。请查看有关Java字节码分析的资源,例如此播客:http://www.podcastchart.com/podcasts/webobjects-podcasts/episodes/java-bytecode-analysis - user813853
@LatencyGuy:对我来说,这意味着您的方法没有被内联,因为它的编译大小超过了InlineSmallCode的阈值大小。您能验证一下您的方法吗? - wero
@wero 它在其他地方被内联了。我在日志中看到 hot (inlined),但也在其他地方看到 已编译为一个大方法 对于同一个方法。可能是我的某个调用者太大了,因此没有包含我的热方法? - LatencyGuy
1个回答

8
看一下 热点源码(搜索“已编译成一个大方法”),很明显,如果用于内联的候选方法已经编译成本地代码且本地代码大小超过 InlineSmallCode 阈值(这是平台相关的,并可通过 -XX:InlineSmallCode=n 设置),则会出现该消息。因此,此消息不取决于调用者。
如你所评论的那样,“已编译成一个大方法”的消息是如何产生的,有可能的解释是 a() 方法调用另一个方法 b(),优化过程如下:
  1. 对 a() 的调用被内联
  2. 现在 a() 本身被优化,它内联了对 b() 的调用,使其本地代码大小大于 InlineSmallCode
  3. 随后对 a() 的调用就不再被内联
也许您可以根据自己的内联日志来验证这个理论。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接