Posterous theme by Cory Watilo

Jato status update for August 2011

In August, people have mostly wrapped up their Google Summer of Code projects.

Ana Farcasi added a SSA-based array bound check elimination optimization. It does not work with loops so we haven't seen major speed gains. Ana is working on improving the optimization to include loops as well.

Ankit Laddha added support for more bytecodes (istore, iadd, and isub) to the ARM architecture port. Likewise, I was able to fix trampolines in the PowerPC port which now is able to successfully JIT and execute iconst and ireturn bytecodes. There's quite a bit of work to be done for both architectures, so people interested in hacking on JVM on ARM and PPC are more than welcome to join the effort.

Theo Dzierzbicki was finally able to make the verifier is fully functional. It's limited in scope but is able to detect some classfile corruption and throw VerifyError:

$ ./jato -cp test/functional corrupt/CorruptedMaxLocalVar
error: corrupt/CorruptedMaxLocalVar: could not load
Exception in thread "main" java.lang.VerifyError: Reference to a too high local variable
   at java.lang.VMClassLoader.defineClass(Native Method)
   at java.lang.VMClassLoader.defineClassWithTransformers(VMClassLoader.java:428)
   at java.lang.ClassLoader.defineClass(ClassLoader.java:471)
   at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:83)
   at java.net.URLClassLoader.findClass(URLClassLoader.java:617)
   at java.lang.ClassLoader.loadClass(ClassLoader.java:341)
   at java.lang.ClassLoader$1.loadClass(ClassLoader.java:1112)
   at java.lang.ClassLoader.loadClass(ClassLoader.java:293)

Finally, Nikhil Sarda resumed Jato hacking after few months of silence fixing up some bugs and adding more test cases. He also announced on IRC that he's interested in hacking on our own garbage collector which hasn't seen much development in over a year.

That's it for August!

Jato status update for July 2011

Here's a summary of what's been going on in Jato development in July. There has been 129 commits merged:

70 Pekka Enberg
27 Ana Farcasi
25 Ankit Laddha
5 Theo Dzierzbicki
2 Balagopal

SSA and optimizations. It's pretty insane what Ana Farcasi has been able to do in just one month. She implemented SSA-based dead code elimination optimization and fixed tons of issues in the SSA conversion code. Both are now enabled by default and the JIT also does simple array bounds check elimination (also implemented by Ana).

Verifier. Theo Dzierzbicki's verifier patches are now merged to master. It verifies some simple error cases but the infrastructure should be in pretty good shape for future improvements. There's still some issues with actually throwing proper exceptions upon verify errors and there hasn't been updates to the code in the past few weeks.

Inline caching hasn't changed since June. Balagopal has been doing performance analysis on the code and is currently looking at method inlining optimizations.

ARM. Ankit Laddha has made excellent progress on the ARM port and we're actually JIT'ing some simple bytecodes such as iconst and ireturn. There's still lots to do so help is much appreciated! We're especially interested in knowing how things work on ARM hardware as we've only run Jato with QEMU in Scratchbox.

PowerPC. I was inspired by Ankit's progress on ARM so I dug up my old PowerBook G4 and resurrected the PPC port. I was able to copy-paste much of Ankit's ARM code under arch/ppc and started hacking on trampoline support. Trampolines sort of work but there's still some register clobbering issues so we're not able to succesfully JIT bytecodes yet. If you're intereted in helping out, let me know and I'll help you get started.

x86-64. I've also been squashing bugs in the x86-64 port and gotten more tests to run. The x86-64 port needs more love and I think we need to fix method tracing and other infrastructure to make debugging easier. Hopefully this will be easier once Eduard Munteanu's work in moving more code generation into the instruction selector is finished.

VM startup time. Ana has been speeding up SSA code and as part of that, I've also been looking at Jato startup performance profiles and speeding up things here and there which has made startup times faster. Most of our problems are related to JIT compiler data structures that are quite frankly way too memory hungry. Fortunately this doesn't matter that much for long-lived applications.

That's it! As always, if you're interested in helping out Jato by testing, hacking, or improving the documentation, please drop by the #jato channel on irc.freenode.net.

Jato status update for June 2011

Another month has passed and Google Summer of Code is in full swing. Here's a brief summary of interesting developments in Jato since May.

Monomorphic inline caching for 32-bit x86 has been merged to master and enabled by default. It doesn't seem to either improve or degrade performance so there's still some tuning left to do for Balagopal.

SSA conversion from and LIR has been merged to master. It's still disabled by default because some regression tests are known to break but you can enable it with '-Xssa' if you want to give it a shot. Ana has already begun experimenting with SSA-based dead code elimination optimization so we'll probably see some performance benefits from her project in the coming month.

ARM porting project was stalled a bit in June but Ankit has managed to implement instruction selection for EXPR_VALUE and EXPR_LOCAL so far. This hasn't been an easy project to work on but I'm hoping we'll see end-to-end arm JIT support for some bytecodes in July.

The verifier project hasn't resulted in any patches in Jato's git master yet.

In related news, I've added a dead simple interpreter in vm/interp.c that supports the nop and return bytecodes. You can enable the interpreter with '-Xint' command line option and run test/functional/jvm/EntryTest.j with it! Admittedly, we're cheating a little bit as GNU Classpath initialization is JIT'd at the moment. That said, if anyone is interested in hacking on a JVM interpreter, drop by #jato on irc.freenode.net and I'm happy to help out. I think the feature is going to be important in future porting efforts and quite possibly reducing Jato startup times.

GNU Classpath five months later

It's now been five months since I wrote my slightly controversial Future of GNU Classpath blog post so I thought I'd take the time to whine some more. It seemed to have a net positive effect the last time.

I have had GNU Classpath commit rights for the past four months or so and have committed total of 9 patches to CVS HEAD. I've fixed compatibility problems that prevented the use of JRuby, Jython, and Redline Smalltalk. It's not a huge amount of work but I've still been able to help GNU Classpath become more useful to end-users and be more compatible with OpenJDK.

So what do I think need to improve in GNU Classpath still?

CVS. It's still painful to use. I think most of the remaining core developers agreed to switch to Mercurial or Git but nothing has happened after that.

No release in two years. Having no recent release is a problem for Jato, at least. CVS HEAD is already in much better shape than the latest 0.98 release which is already over two years old. Anyone interested in trying out Jato now needs to use CVS to fetch the latest sources which is an unnecessary barrier for newcomers.

Automated tests. Mauve is great. It has tons of important compatibility test cases. However, Mauve has couple of problems: (1) running the whole test suite is slow, (2) not all tests pass with OpenJDK, and (3) the output is very verbose which makes it difficult to notice test breakage. Malva has caught bugs in GNU Classpath, Jato, Jam VM, and CACAO. It fixes most of the problems I see in Mauve but it's of limited use because the number of test cases is still so small.

JDK APIs. The 1.7 release of OpenJDK is close and there's bunch of shiny new APIs queued for 1.8. The cold reality is that with every new JDK release, GNU Classpath becomes less and less relevant unless it's able to implement at least the major new APIs. JRuby, for example, is switching over to the invokedynamic APIs that are introduced in 1.7 so in not so distant future, we won't even be able to compile it with GNU Classpath.

JVM support. CACAO and JamVM support OpenJDK now and most of the interesting open source work seems to happen in the IcedTea project. This is a big problem because there's very little positive pressure from JVM developers to fix up GNU Classpath compatibility issues. One possible solution here is to make GNU Classpath binary compatible with OpenJDK so that any JVM out there that supports the OpenJDK VM ABI would be able to use GNU Classpath out-of-the-box.

I guess that's enough whining. See you again in six months!

Jato status update for March - May 2011

Jato was accepted to Google Summer of Code 2011 and work on the following projects has now started:

Meanwhile Eduard-Gabriel Munteanu and Sergey Mashkov squashed bugs in the x86-64 port and Joonas Reynders and Nikhil Sarda implemented bunch of missing core Java and JNI APIs. Tomek Grabiec and Vegard Nossum also threw in some critical bug fixes putting us one step closer to a new release.

Needless to say, I'm looking forward to an interesting summer and hopefully an impressive release!

Jato is participating in Google Summer of Code 2011!

Jato will be participating in Google Summer of Code again this year! If you're a student looking for interesting things to hack on, look no further! You can find our organization profile here:

http://www.google-melange.com/gsoc/org/show/google/gsoc2011/jato

There's lots of interesting areas to work on. In particular, the following are pretty high on the list:

  • JIT compiler optimizations (SSA in particular)
  • Invokedynamic
  • ARM and x86-64 architecture ports
  • Exact garbage collector (we're using boehmgc now)

You can find the full list of project ideas here:

http://www.jatovm.org/projects.html

And as always, we're also open to projects that are not on the list. Feel free to drop by at #jato on irc.freenode.net or send email to penberg@kernel.org to discuss your ideas and ask questions!

Jato status update for February 2011

Lots of cool things happened in Jato in February!

  • Joonas Reynders completed his rework on JNI. You can now build native code against Jato and use the JNI API from C code.
  • Class.getDeclaredAnnotations() mostly works now.
  • JNI mostly works on x86-64 now.
  • 60% of our test suite passes on x86-64. Up from 50% in January!
  • I started some experimental work to investigate if it’s possible to support Dalvik DEX format in Jato. You can find some preliminary DEX classloading code in experimental/dalvik branch on Github

In related news, I fixed some problems in GNU Classpath that were blocking Jython from running under JamVM. I also fixed a problem in String.format() that was causing JRuby to fail to start up. JRuby doesn't work correctly yet due to some bug in GNU Classpath regexp code.

Jato and Malva status update for January 2011

Things have been little quiet over the past two months but we've managed to get some work done for Jato and Malva. I was hoping to do a release at the beginning of January but decided to wait for the annotation support to work properly before doing it.

Jato

  • I've been hacking on annotation support. Most of the classfile parsing is now done and Class annotation reflection API is under development.
  • Joonas Reynders started working on JNI regression tests 
  • Joonas Reynders, Tomek Grabiec, and myself added some missing Classpath VM integration APIs.
  • I've fixed "make check" to only run the passing tests on x86-64. 50% of all the tests pass now.

Malva

  • Joonas Reynders added test cases for java.net.InetAddress.
  • I added more test cases for java.lang.Class.

In related news, I became a GNU Classpath committer on January 21 and hope to help getting pending patches reviewed and merged. I'm also looking at fixing issues in GNU Classpath that have been found by test cases in Malva.

 

What's the future of GNU Classpath?

The number of commits in GNU Classpath peaked at 3193 in 2006 (as measured from a git mirror of the CVS repository). Activity has since dropped significantly with an all time low of 30 commits in 2009. With 31 commits and counting this year, things aren't really improving. GNU Classpath used to be the essential free Java runtime library but that's all changed now. Ubuntu, for example, has dropped the GNU Classpath package and only ships the OpenJDK version of CACAO. Another prominent alternative JVM, JamVM, seems to be also migrating to OpenJDK. It looks like the community is moving over to OpenJDK and GNU Classpath development is grinding to a halt.

But with OpenJDK licensed under the GPL, do we still need GNU Classpath to be actively developed? Thinking about the killing of OpenSolaris, Harmony TCK dispute, and the Android lawsuit I think there's enough doubt not to bet the future of free Java on OpenJDK alone. There's also probably something to be said about the dangers of software monoculture as well but the bottom line is that it's still important to have a community-driven project around free Java if don't want big vendors to control its destiny.

So what do I think needs to happen with GNU Classpath?

The CVS repository needs to be migrated git or Mercurial. I mean, just getting the GNU Classpath sources via cvs checkout is painful enough to avoid contributing to the project not to mention how much problems it causes for developers that don't have commit rights to the centralized repository!

Patches need to be reviewed and merged more quickly. There's lots of unmerged patches waiting in bugzilla and the mailing list. When I tried to help out and get one of those patches merged, it took two whole months of waiting before it ended up in CVS. That's too long time to wait for your patch to be merged and is likely holding back potential new contributors.

More automated tests for compatibility testing. It's pretty obvious by now that there's not going to be a freely available Technology Compatibility Kit (TCK). That's why it's so important to write automated compatibility tests against OpenJDK and make sure they pass with GNU Classpath as well. The Mauve project seems to have been abandoned which is why I've started a new project called Malva that attempts to write compatibility tests for the core Java APIs.

Java 1.6 and 1.7 APIs need to be implemented. GNU Classpath APIs are currently stuck at Java 1.5 level. There's already applications out there that use the Java 1.6 APIs and the situation is only going to get worse as time passes by. It's therefore crucial that work on Java 1.6 and 1.7 APIs starts as soon as possible for GNU Classpath to stay relevant.

There's so much software written in Java that it's unlikely to go away any time soon. There's also some really cool development happening in the alternative JVM language space (Scala, Clojure, and JRuby, for example) which hopefully makes the JVM a relevant platform in the future. I do think OpenJDK is great but I don't think we should rely on it alone if we want to make sure Java stays a free and useful platform in the future as well.

How does Jato execute Java classes?

Each standalone Java application has an entry point that's the main() method of some user-defined class. For example, a "hello, world" application looks something like this:

public class Hello {
    public static void main(String[] args) {
      System.out.println("hello, world");
    }
  }

After the source code is compiled with javac to a Hello.class classfile, you execute the class as follows:

java Hello

Now there's all sorts of things Jato (like every other virtual machine) needs to do to initialize itself but how does execution actually get transferred to the Hello.main() method? Looking at the main() C function of Jato itself in vm/jato.c we see this piece of code:

switch (operation) {
  case OPERATION_MAIN_CLASS:
          status = do_main_class();
          break;
  case OPERATION_JAR_FILE:
          status = do_jar_file();
          break;
  }

As we're interested in Java class execution, we dive into do_main_class() function where we find

struct vm_method *vmm = vm_class_get_method_recursive(vmc,
          "main", "([Ljava/lang/String;)V");
  if (!vmm) {
          fprintf(stderr, "error: %s: no main method\n", classname);
          return -1;
  }

  [... snip ...]

  void (*main_method_trampoline)(void *)
          = vm_method_trampoline_ptr(vmm);
  main_method_trampoline(args);

Here we do two things: (1) look up a "struct vm_method" for the user-specified class Hello.main() method and (2) call a function pointer returned by vm_method_trampoline_ptr() which transfers control to the JIT compiled machine code of Hello.main() method. So what is a trampoline then? A trampoline is a small per-method piece of code that acts as the receiver method for methods that have not yet been compiled. For details, see arch/x86/emit-code.c::emit_trampoline() how individual trampolines are generted. The heart of it all is jit/trampoline.c::jit_magic_trampoline() function that determines the real target method by compiling the method or, in the case of native methods, looks up the address of the called native function. The same kind of approach is also used by VMs such as Mono and Kaffe.

In summary, Jato executes the Java main() by looking up an internal struct vm_method representation of it and calling it's trampoline function. The trampoline function then takes over and compiles the main method and executes the machine code. This process continues recursively until we either invoke System.exit() or return back to the VM function do_main_class() that called the first trampoline function.