java
has an argument -XX:MaxInlineLevel
(with a default value of 9) which controls the maximum number of nested calls to inline. Why is there any such limit? Why aren't the usual heuristics based on frequency and code size sufficient for the JVM to decide for itself how deeply to inline?
(this is prompted by JitWatch showing me that a deeply nested Guava checkArgument
call was not being inlined due to depth)
Some significant searching uncovers this interesting little fragment (I actually got as far as page 4 of the Google search):
if (inline_depth() > MaxInlineLevel) {
return "inlining too deep";
}
if (method() == callee_method
&& inline_depth() > MaxRecursiveInlineLevel) {
return "recursively inlining too deep";
}
Which suggest that the MaxInlineLevel
is as expected a hard limit to how deep you go before you stop inlining. It also suggests that the MaxRecursiveInlineLevel
refers only to direct recursive calls, not mutal recursive calls such as foo()
calls bar()
which calls foo()
.
So I think I was right in my guess comment - MaxInlineLevel
is to protect against mutual recursion because to detect that you would need to keep references to the full depth of the inlining call stack.
MaxInlineResursionLevel
controls foo()
calls foo()
inlining.
Note that the referenced code may not be a real JVM.
Comments by @apangin locates a more modern version of hotspot from Open JDK 8 suggest that it is nowadays no longer quite as simple as that. It looks like the full stack is searched for recursive calls so mutual recursion may also now be blocked from going past MaxRecursiveInlineLevel
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With