Since JDK-8273712, C2 inliner has changed to reject a callee based on 'MinInlineFrequencyRatio'. In the changeset, we obtains call_site_count from intermediate object 'ciCallProfile'.
ciCallProfile is generated from its caller in Compile::call_generator(). It's worth noting that caller here may not be the root method. it's possible that the method data of caller here has not been mature yet. When ciCallProfiler is immature, ciCallProfiler::_count is -1. call_site_count is negative and can't pass freq < min_freq check. As a result, c2 inliner rejects to inline the callsite.
We develop a simple program to demonstrate this case. For simplicity, we can imagine that an inline tree that contains > 3 levels.
foo
> bar
>> baz
>>> ....
method foo is the root method that c2 compiles. It's possible that the invocation count of bar is less than foo. it's up to the control flow. We introduce a parameter 'ODD'. It indicates that foo() calls method bar() with possibility ODD%. eg. ODD=20 says that there's 20% possibility that foo() calls bar().
We found that jvm option ProfileMaturityPercentage determines whether the method data of method is regarded as 'mature'. when ODD< ProfileMaturityPercentage, it's likely that the method data of bar has not been mature when c2 is triggered to compile foo().
eg. we spot that c2 rejects baz because of 'low call site frequency'
$java -XX:+UnlockDiagnosticVMOptions -XX:CompileOnly='UnderProfiledSubprocedure.foo' -XX:+PrintInlining -XX:+PrintCompilation -XX:CompileCommand=quiet -Xbatch UnderProfiledSubprocedure 19
60 13 b 4 UnderProfiledSubprocedure::foo (9 bytes)
@ 5 UnderProfiledSubprocedure::bar (6 bytes) inline (hot)
@ 1 UnderProfiledSubprocedure::baz (19 bytes) failed to inline: low call site frequency