I was reviewing one conference presentation that touched JIT inlining semantics where author pinned down weird behavior (weird only for first look, of course) - C2 was slower than C1 because it couldn't inline method due to excessive inlining depth. It may be represented in following example:
public static int multipleByTwo(int x) {
return x * 2;
}
public static void entrypoint() {
int sum = 0;
for (int i = 0; i < 10_000_000; i++) {
// due to some arbitrary cause, multiplyByTwo doesn't get inlined
sum += multiplyByTwo(i);
}
}
As a programmer, i may know there is a field for optimization that compiler doesn't know about. E.g. there is plenty of optimization possible if multiplyByTwo
would be forcibly inlined, but due to various constraints (e.g. method size or inlining depth) it may be omitted from inlining. Why there is no way to tell the compiler "hey, i'm pretty sure you should prefer inlining that method rather not"? I'm sure i'm not the first one to think about this and there was discussion that resulted in not implementing such feature - why?
p.s. please note that i'm talking about hints rather than directives; i do understand that latter choice would result in more harm than benefit.
In fact, there is an infrastructure to control HotSpot JVM compiler.
1. Compiler command file
You may specify a file containing compiler commands with
-XX:CompileCommandFile=
JVM option. There are commands to force inlining, to exclude a method from compilation, to set a per-method option (e.g.MaxNodeLimit
) and so on. The full list of available commands can be found here.An example Compiler command file may look like
2. Annotations
JDK-specific annotations are another way to control JVM optimizations. There are certain annotations that HotSpot JVM knows about, e.g.
@java.lang.invoke.ForceInline
@java.lang.invoke.DontInline
@java.lang.invoke.Stable
@sun.misc.Contended
Note: All these mechanisms are non-standard. They apply only to OpenJDK and Oracle JDK. There is no standard way to hint JVM compiler, because there are many JVM implementations with completely different compilation strategies. Particularly, there are JVMs with no JIT compilation at all.