Pages

Friday, April 13, 2012

IBM J9 JIT - Inlining of Virtual Methods - Invariant Argument Preexistence Optimization

With Java 6 the the IBM JIT  is aggressive in optimization leading to world class performance; however sometimes the JIT gets tripped up on itself doing certain optimizations.  If you ran into http://www-01.ibm.com/support/docview.wss?uid=swg1IZ58251 or http://www-01.ibm.com/support/docview.wss?uid=swg1IV15424 or http://www-01.ibm.com/support/docview.wss?uid=swg1IV16044 you may be wondering what is meant by JIT invariant argument optimization and if it makes sense to disable it ?

How does pre-existence work?
For a full and rigorous explanation see Chapter 5 from the paper that introduced the concept:

Assume the following scenario:

void m1(Foo arg)
{
   ...
   arg.m2(); // virtual call or interface call
   ...
}

If at the time of compilation for m1 there is only one implementation for callee m2, then the JIT knows exactly what target to expect and can safely inline the code for it with no guard.
If a class load event extends the hierarchy such that a new implementation for m2 is introduced into the system, the code for m1 may call the wrong target for some type of arguments. The JIT invalidates the old body for m1 and immediately schedules a recompilation for it. While the recompilation is in progress application threads are blocked from entering the old body of caller m1. The new body of m1 will not inline m2, but will actually execute the virtual/interface call (note that the different targets for m2 may already be compiled/optimized on their own). Pre-existence is not going to help in this case.

In a nutshell, pre-existence helps the JIT inline some targets when the class hierarchy indicates it is safe to do so.
1) If the class hierarchy is such that the JIT doesn't know what to inline, then pre-existence does nothing. With or without it it's the same thing.
2) If pre-existence was applied, but later-on the class hierarchy changed in an incompatible way, then the JIT basically needs to undo what pre-existence did. Again, disabling pre-existence from the beginning is not going to hurt this case.

Why have pre-existence enabled?
Some applications, while having deep class hierarchies, load only one implementer for various virtual calls. Experiments have shown improvements from pre-existence  Even when the class hierarchy is extended, we do not see any visible decrease in the performance of  the system due to method invalidation.

When does it make sense to disable pre-existence ?
When an application does a a lot of Dynamic class reloading and deep class hierarchies with interfaces having multiple implementations in mainline path, then it may make sense to disable pre-existence with
-Xjit:disableInvariantArgumentPreexistence generic JVM argument. 

No comments:

Post a Comment

Note: Only a member of this blog may post a comment.