java
有一個參數-XX:MaxInlineLevel
(默認值爲9),它控制嵌套調用的最大數量。爲什麼會有這樣的限制?爲什麼不是基於頻率和代碼大小的通常啓發式算法足以讓JVM自己決定內聯的深度?爲什麼JVM具有最大內聯深度?
(這是由JitWatch促使我展示一個深度嵌套番石榴checkArgument
呼籲沒有被內聯,由於深度)
java
有一個參數-XX:MaxInlineLevel
(默認值爲9),它控制嵌套調用的最大數量。爲什麼會有這樣的限制?爲什麼不是基於頻率和代碼大小的通常啓發式算法足以讓JVM自己決定內聯的深度?爲什麼JVM具有最大內聯深度?
(這是由JitWatch促使我展示一個深度嵌套番石榴checkArgument
呼籲沒有被內聯,由於深度)
一些顯著搜索揭示了這個有趣的小fragment(事實上,我儘可能頁谷歌搜索的):
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
。
你看看很老的來源。正確的地方在[hg.openjdk.java.net](http://hg.openjdk.java.net/jdk8u/jdk8u/hotspot/)。 'MaxRecursiveInlineLevel'計入[直接和間接](遞歸調用)(http://hg.openjdk.java.net/jdk8u/jdk8u/hotspot/file/c1374141598c/src/share/vm/opto/bytecodeInfo.cpp#l389)遞歸調用。 – apangin
@apangin - 這似乎沒有做什麼評論說。它也只是與'MaxRecursiveInlineLevel'進行比較。雖然好發現。 – OldCurmudgeon
深入挖掘。 [The loop](http://hg.openjdk.java.net/jdk8u/jdk8u/hotspot/file/c1374141598c/src/share/vm/opto/bytecodeInfo.cpp#l401)遍歷所有框架,查看被調用方法出現在堆棧的任何地方。 [MaxInlineLevel](http://hg.openjdk.java.net/jdk8u/jdk8u/hotspot/file/c1374141598c/src/share/vm/opto/bytecodeInfo.cpp#l380)現在在InlineTree構造函數中設置。 – apangin
完全不確定,但可能是爲了避免相互遞歸陷阱,這可能難以/昂貴地以其他方式進行辯護。 – OldCurmudgeon
@OldCurmudgeon,但你有MaxRecursiveInlineLevel – MrSimpleMind
@MrSimpleMind - 有趣 - 我顯然是錯的。必須是其他原因。 – OldCurmudgeon