Re: Java native code compilation
michaelquinlivan@gmail.com wrote:
Just one other question. When a java app is JITed, is the generated
machine code saved, or is it discarded and must be generated at each
execution (such as if I was to close down the app and start it again
half an hour later)?
There's not even any reason to suppose that it'll hold onto the JITed code
until the application closes down. It might decide to optimise the code
further (and thus discard the current version), or it might decide that the
binary code wasn't being called enough to justify taking up the space, and just
throw it away. I'm not sure what any particular JIT implementation will do
(finding specifics is difficult), but it /could/ do either of those things.
As far as I know (and my knowledge is incomplete) no Sun JVM has ever attempted
to cache generated code between runs. The 1.5.0 JVMs do have an ability to
save out and share a pre-analysed from of the standard classes (to reduce
startup time mainly, and also to allow more memory sharing between JVM
instances), but I don't think that contains JITed code.
BTW, one reason for that is that the relationship between the Java source (or
the equivalent bytecodes), and the generated code is quite dynamic, and it
would not be trivial to save our the JITed form since that depends on what else
is loaded. For instance if a class like:
class MyClass
{
private int m_value;
void
calledALot()
{
// silly example
for (int i = 0; i < getValue(); i++)
;
}
int
getValue()
{
return m_value;
}
}
Assume that MyClass has no subclasses. The JITer may quite possibly choose to
inline getValue() where it is called in calledALot(), it would then generate
code which read the instance field directly. (Or, more likely, the optimiser
would remove the whole thing, in which case calledALot() itself might be
removed from all its call-sites, but then there'd be no calls to calledALot(),
and so no point in wasting space holding onto its compiled form...)
Now, if someone loads a new class which subclasses MyClass
class Irritating
extends MyClass
{
int
getValue()
{
return systemCriticalOpWithSideEffects();
}
}
then the JITer may have to undo the optimisations it did before, since it
doesn't know, when MyClass.calledALot() is executed, whether the actual
instance is a MyClass or an Irritating. (It could also leave the optimisation
in place, but generate a duplicate of calledALot() in Irritating which lacked
the optimisation -- but that's not always possible, and takes up more space
too). So, during the life of the system, the real machine code representing
calledALot() can pass through several different forms , which version should be
saved in the code cache ?
If so, do you have any examples of this?
Not sure what you are looking for. If it's any help, you can ask a Sun JVM to
log when it JITs methods by passing a:
-XX:+PrintCompilation
flag to java.exe.
-- chris