Thursday, May 6, 2010

Jaclyn: The Jarc Compiler

The Fandle R & D team has been busy writing a compiler for Jarc. Today we have released Jarc 12, which includes Jaclyn, the compiler.  Jaclyn compiles to JVM byte code.  Actually, Jaclyn generates a Jasmin assembler source code file and then calls Jasmin to create a .class file.

Usage

  Jarc> (compile "foo.arc")
  ...
  Generated: ./foo.class
  Jarc> (iload "foo.class")

Performance Improvements

This had a 5x improvement on the startup time for Jarc. From 2.5 seconds to 0.4 seconds.

The run-time improvement is interesting. Initially the compiled code runs more slowly, but then improves after the first two runs.  I ran the Jarc unit tests 10 times and recorded the time for each run.


This may be partially due to the JIT compiler.  Ignoring the initial runs, the compiled code runs about 1/3 faster.

This should shave a few seconds off the cold-startup time for Fandle on Google App Engine and allow slightly more processing per page hit or task.  Page hits (and tasks) have a 30 second limit on App Engine so applications have to be designed to do their processing in 30 second increments.

Tail Recursion

Jaclyn optimizes tail recursive functions to avoid using unnecessary stack space.  It's not generic tail call elimination, which is not possible in the JVM, but when a method calls itself, the compiler generates a jump to the top of the function instead of invoking the function.  This makes recursion feasible for iteration and avoids StackOverflowError exceptions.

Optimizations

These optimizations are needed to optimize tail calls.  If certain macros (like let) are not optimized then the recursive call winds up in a separate function and can't be optimized.  But by optimizing:

  • afn
  • rfn
  • do
  • let

Jaclyn can optimize many instances of tail recursion.

You can download Jarc 12 from SourceForge and you can also browse the source code.