Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

>until recently

Actually, for a long time (almost 20 years, I think), the gcc subsystem gcj let you do AOT compilation of Java to ELF binaries. [1] I think they had to be dynamically linked, but only to a few shared objects (unless you pulled in a lot via native dependencies, but that's kind of "on you").

I don't recall any restrictions on how to use generated code, anymore than gcc-generated object code. So, I don't think the FSF/copyleft on the compiler itself nullifies a free beer classification. :-) gcj may not have done a great job of tracking Java language changes. So, there might be a "doesn't count as 'real Java'" semantic issue.

[1] https://manpages.ubuntu.com/manpages/trusty/man1/gcj.1.html



The interesting thing I always heard in the Java world is that AOT was actually a drawback as the virtual machine allowed for just in time optimizations according to hotspots. Actually if I remember correctly the word hotspot itself was even used as a tech trademark.

I was always a bit skeptical but given i was never much into Java i just assumed my skepticism was out of ignorance. Now with what I know about profile guided compilation I can see it happening; A JIT language should have a performance advantage, especially if the optimal code paths change dynamically according to workload. Not even profile guided compilation can easily handle that, unless I am ignorant of more than i thought.


I've heard the exact opposite. The supposed performance benefits of JIT compared to AOT (profile-guided optimization, run-time uarch-targeted optimization) never really materialized. There's been a lot of research since the late '90s into program transformation and it turned out that actually the most effective optimizations are architecture-independent and too expensive to be performed over and over again at startup or when the program is running. At the same time, deciding when it's worthwhile to reoptimize based on new profiling data turned out to be a much more difficult problem than expected.

So the end result is that while both AOT (GCC, LLVM) and JIT (JVM, CLR) toolchains have been making gradual progress in performance, the JIT toolchains never caught up with the AOT ones as was expected in the '90s.


Good luck with inlining and devirtualization across DLLs with AOT.

JIT caches with PGO get most of AOT benefits, that is why after the short stint with AOT on Android, Google decided to invest in JIT caches instead.

The best toolchains can do both, so it is never a matter of either AOT or JIT.

GCC and clang aren't investing in JIT features just for fun.


What's with the snappy tone?

>Good luck with inlining and devirtualization across DLLs with AOT.

An AOT compiler/linker is unable to inline calls across DLL boundaries because DLLs present a black-box interface. A JIT compiler would run into the exact same problem when presented with a DLL whose interface it doesn't understand or is incompatible with. If you really want a call inlined the solution is to link the caller and function statically (whether the native code generation happens at compile- or run-time), not to depend on unknown capabilities of the run-time.

>The best toolchains can do both, so it is never a matter of either AOT or JIT.

You're refuting a false dichotomy no one raised.


I am sarcastic by nature, that is why.

JIT compilers for Java and .NET do inline across shared libraries and devirtualization, including native calls.

When people discuss A vs B there is always a dichotomy.


Theory and practice can diverge and it's easy to over-conclude based on either with such complex systems. For example, I have seen gcc PGO make the very same training case used to measure the profile run more slowly. One might think that impossible naively, but maybe it sounds more plausible if I put it differently - "steering the many code generation heuristics with the profile failed in practice in that case". As with almost everything in computer systems, "it all depends...."


Sun was ideologically against AOT, as all commercial vendors always had some form of either AOT or JIT caches.

In fact, the JIT caches in OpenJDK come from Oracle/Bea's J/Rockit, while IBM's OpenJ9 AOT compilation is from WebSphere Real Time JVM implementation.


I seldom mention it, because gcj was abandoned in 2009 when most contributors moved into the newly released OpenJDK, eventually removed from GCC tree, and it never was as foolproof as the commercial versions.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: