javajvmjvm-hotspot

Does jvm inline the final method?


When I read the java8 spec, I get the declaration that

At run time, a machine-code generator or optimizer can "inline" the body of a final method, replacing an invocation of the method with the code in its body.

https://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.4.3.3

So my question is that does the hotspot really inline the final method?

Or, is there only the final method can be inlined?


Solution

  • It's way more complicated than that.

    Hotspot will do whatever it needs to do to make things run fast. The only rule is: It cannot break any of the guarantees provided by the java specification.

    These guarantees do not mention things like 'this will be inlined'. It is not possible to observe that you are being inlined unless you try to figure it out by using nanoTime(), and the java spec obviously makes no hard guarantees on timing issues - things that cannot be observed are rarely if ever guaranteed one way or another in the java spec. Why bother guaranteeing such things? It only handicaps the JVM engineers.

    Current popular JVM implementations use this rough and oversimplified plan for inlining:

    1. Any method, final or not, will be inlined if it seems like a good idea to do that.

    2. This never happens immediately. It only happens if method X is selected for hotspot recompilation, and X calls method Y, and Y seems like a fine way to inline.

    3. If a non-final method is inlined, that seems like an illegal move. However, it's not: The VM just made a falsifiable assumption: "This method, while not final, is nevertheless not overridden by anything anywhere in any class loaded in the VM". If it is true right now, the method can be inlined, even if it might not be true later on.

    4. Any time new classes are loaded in (this boils down to: A new class is thrown at ClassLoader's native defineClass method), a check is done if this causes any assumptions to cease to be true. If that happens, the hotspotted versions of all methods that depend on this assumption are invalidated and will revert back to normal (slowish, more or less interpreted) operation. If they are still run a lot, they will be hotspotted again, this time keeping in mind that the method cannot easily be inlined anymore due to it being actually overridden.

    5. As I said, this is just how it works now. It might work differently in a future java version because none of this is guaranteed. It's also oversimplified; for example, I didn't mention annotations like @jdk.internal.HotSpotIntrinsicCandidate or @java.lang.invokeForceInline. It's not relevant and you should as a rule not be writing code with presupositions about how inlining works. The whole point is that you don't need to know.