Java native code compilation

M

michaelquinlivan

Hi all

I was just reading some stuff on a Java forum about compilation to
native code. The question was how to compile Java source code to
native code (eg Windows .exe file). The thread turned into a beating
of chests about why you should/should not consider doing this, and
never really answered the question straight. So my first question is:

1) Can it be done (for the Windows platform)? If so, how and with what
tools. I don't care what your opinion is on the matter. That is the
focus of my second question

2) What are the merits of doing this. Many of the posters on the
forum stated that JIT/dynamic compilation is more efficient and faster
than static compilation such as that used in C++. Yet it is definitely
noticable that java GUI apps are slower and less responsive than native
code GUI apps. Why is this?

thanks
MQ
 
C

Chris Uppal

1) Can it be done (for the Windows platform)? If so, how and with what
tools.

Excelsior Jet. GNU gjc. There may be others (real ones, that is. Packagers
which wrap a .exe launcher around a standard JVM implementation are common too,
but not relevant here).

I don't care what your opinion is on the matter.

And why should I care about what you care about ? I shall give my opinion as
and when I wish ;-)

2) What are the merits of doing this.

Not very great, IMO. Principle benefits:

Faster startup for small apps.

Better inherent obfuscation (fewer people are comfortable reading IA32 code
than JVM bytecode -- especially when the IA32 code implements a VM, and so is
rather, um, unusual).

Different opportunities for optimisation. May make a significant difference,
may not.

Of course, the fact that the app is compiled-to-native effectively means that
it is running a different JVM implementation (different GC, for instance). And
different implementations of the same general idea will typically have
different performance tradeoffs which may benefit some applications. Much as
some apps would run better with Sun's server VM, whereas others run better with
the client VM.

Many of the posters on the
forum stated that JIT/dynamic compilation is more efficient and faster
than static compilation such as that used in C++.

My current experience is that they are more likely to be wrong than right,
given today's technology. I haven't yet seen an application or properly
written micro-benchmark where JITed Java was /faster/ than equivalent C++[*]
(though it is extremely difficult to compare like with like, since C++ lacks
GC, which radically changes the topology of the design space). OTOH,
applications where Java is significantly /slower/ than C++ are fairly rare too.
Of course, well designed Java code will beat a badly designed C++, and vice
versa.

([*] When using the best available C++ compiler for a given benchmark. It is
certainly possible for <some specific JIT> to emit better code than <some
specific C++ backend>. E.g. in one particular micro-benchmark, the Sun 1.5.0
server JIT emitted better code than GNU -O3, but not better than MSVS 2003.)

Yet it is definitely
noticable that java GUI apps are slower and less responsive than native
code GUI apps. Why is this?

I think this is a question of the design and implementation of the Swing
libraries, rather than a raw execution speed issue. Other GUI implementations,
also based on emulated widgets, exist for other languages with less magnificent
JITers than Sun's, but yet smoke Swing for speed and footprint.

-- chris
 
M

michaelquinlivan

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)? If so, do you have any examples of this?
 
C

Chris Uppal

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
 
L

ldv

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)? If so, do you have any examples of this?

Excelsior JET (http://www.excelsior-usa.com/jet.html) includes both AOT
and JIT compilers and has an option to cache JITted code to disk for
subsequent reuse. You can even stress test your app and recompile the
cached classes into one .DLL/.so using the AOT compiler before
deployment.

AFAIK other industrial-grade VMs discard the results of dynamic
compilation, though I recall reading an announcement that BEA JRockit
will have support for keeping them between runs at some point in the
future.

LDV
 
R

Roedy Green

2) What are the merits of doing this. Many of the posters on the
forum stated that JIT/dynamic compilation is more efficient and faster
than static compilation such as that used in C++. Yet it is definitely
noticable that java GUI apps are slower and less responsive than native
code GUI apps. Why is this?

The GUI slowness is not attributable to static vs hotspot compilation.
In C++ you generally code to the native API. In Java you code to Swing
which then sits atop the native API. You have an extra layer of
overhead to provide the platform independence.

Have a look at benchmark where I compared various algorithms under
various runtimes including Jet static AOT compilation.

See http://mindprod.com/jgloss/benchmark.html

Jet was producing better code than a human assembler programmer.
Hotspot was comparable. Further gains will have to come from better
hardware and retrofitting the OS to handle Java Swing more directly.
 
R

Roedy Green

When a java app is JITed, is the generated
machine code saved, or is it discarded and must be generated at each
execution

As of Java 1.5 I saw no signs of saving.
 
R

Roedy Green

Excelsior JET (http://www.excelsior-usa.com/jet.html) includes both AOT
and JIT compilers and has an option to cache JITted code to disk for
subsequent reuse. You can even stress test your app and recompile the
cached classes into one .DLL/.so using the AOT compiler before
deployment.

This Jet feature is for dynamically loaded code that was not available
at compile time. Everything else is statically compiled. Dynamically
loaded classes available at compile time are statically compiled.
 
T

Timo Stamm

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)?

The VM does save JIT data on disk. Under linux, the following files are
written for each VM:

/tmp/hsperfdata_[username]/[processid]


I don't believe that the data is re-used. The filename is the process
id, and the process id is different for each VM.


Timo
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,583
Members
45,074
Latest member
StanleyFra

Latest Threads

Top