Why there is no infrastrucutre for hinting JIT compiler in JVM?

1.2k views Asked by At

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.

2

There are 2 answers

1
apangin On BEST ANSWER

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

inline java.util.ArrayList::add
exclude *::<clinit>
print com.example.MyClass::*

2. Annotations

JDK-specific annotations are another way to control JVM optimizations. There are certain annotations that HotSpot JVM knows about, e.g.

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.

4
Holger On

Well, the are hints to the JVM’s optimizer that this method is a good candidate for inlining:

  • It’s static or private, i.e. non-overridable
  • It’s extremely short
  • It’s called several times within a loop

In fact, your assumption that this method is a good candidate is based on the same technical evidence, so adding a hint that you think that this is a good inlining candidate would not add any new information, only redundancy.

So if the JVM still doesn’t inline the method, for whatever reason, despite all these technical properties speaking for inlining, there is no reason to assume that a non-mandatory, non-technical hint, most likely stemming from the same technical properties will turn the JVM’s decision.

You can pick any potential reason you want, protection against certain problems, too restrictive limits, even a flawed JVM implementation, in either case, you’ll see that the same reason applies to a method having your hint as well, even if it turns out to be an unfounded reason, as that also applies to a method without your hint. So in the latter case, the obvious solution would be to fix the flaws within the JVM, rather than adding a general hint mechanism.

A general hinting mechanism is especially questionable, as the code is supposed to be platform independent. If you look at a particular run in a known environment with a particular JVM implementation, things look different. E.g. HotSpot supports the -XX:CompileCommand option. So in your case, you could use -XX:CompileCommand=inline,your/class/Name,multiplyByTwo to try to convince the JVM to inline the method. Of course, the correct spelling is important. In your question, the method is once named multipleByTwo, then multiplyByTwo