为什么 JVM 有最大内联深度?

Why does the JVM have a maximum inline depth?

java 有一个参数 -XX:MaxInlineLevel(默认值为 9),它控制对内联的最大嵌套调用数。为什么会有这样的限制?为什么通常基于频率和代码大小的启发式方法不足以让 JVM 自行决定内联的深度?

(这是由 JitWatch 提示的,向我展示了深度嵌套的 Guava checkArgument 调用由于深度而未被内联)

一些重要的搜索发现了这个有趣的小东西 fragment(实际上我在 Google 搜索中找到了第 4 页):

    if (inline_depth() > MaxInlineLevel) {
        return "inlining too deep";
    }
    if (method() == callee_method
            && inline_depth() > MaxRecursiveInlineLevel) {
        return "recursively inlining too deep";
    }

这表明 MaxInlineLevel 正如预期的那样是对停止内联之前的深度的硬性限制。它还表明 MaxRecursiveInlineLevel 仅指直接递归调用,而不是相互递归调用,例如 foo() 调用 bar() 调用 foo().

所以我认为我的猜测评论是正确的 - MaxInlineLevel 是为了防止 相互 递归,因为要检测到您需要保留对完整内容的引用内联调用堆栈的深度。

MaxInlineResursionLevel 控制 foo() 调用 foo() 内联。

请注意,引用的代码可能不是真正的 JVM。

@apangin 的评论从 Open JDK 8 中找到了一个更现代的热点版本,这表明它现在不再那么简单了。看起来整个堆栈都在搜索递归调用,因此现在也可能阻止相互递归超过 MaxRecursiveInlineLevel.