LanguageKit has supported just-in-time (JIT) compiling for a while, but in my last commit I added support for just-too-late (JTL) compiling too. The idea behind JIT compilation is that you only generate the executable code just before it's called. With JTL compilation, we generate it afterwards.
On the face of it, this isn't very useful. In practice, applications run more than once, and the second time is now a fair bit faster. If you've run Melodie, you'll have noticed that it takes a while longer to start than most GNUstep / Étoilé applications. This is because it is parsing all of the Smalltalk code, compiling it to LLVM bitcode, optimising this, and then starting.
If you use the latest LanguageKit svn (note: it needs a very recent LLVM svn build), you will notice that the second time you load it, it starts a lot faster. This is because it's loading a shared object (.so) file that was generated in the background the first time the program ran. It's currently quite conservative about regenerating this; if any framework or source file is modified then it should fall back to the JIT and run the JTL compiler in the background to refresh the cache.
So, as I write this, Melodie is playing my test album (Bitter Sweet Symphony EP, courtesy of iTunes Plus), without having done any compilation. It doesn't even load the code generation bundles, because the code generator is never instantiated (the bundle with the code generation support is loaded on-demand).
The performance is not yet ideal. In future, the JIT compiler will do some run-time profiling and the JTL compiler will then use the profiled version of the library. This means that every Étoilé application written in a LanguageKit language (e.g. Pragmatic Smalltalk or EScript) will benefit from profiling-driven optimisations, and may even out-perform statically-compiled Objective-C (although profiled Objective-C is likely to still be faster).
There are currently two places where LanguageKit will store the caches; in the source bundle or in the user's home directory. This means that you can benefit from static compilation even when you don't have write access to the bundle (e.g. it's an application installed by root).
This is something I've been meaning to do with LanguageKit for a long time, so it's nice to see it working properly. Note that this works with all LanguageKit bundles, not just applications. If you put a plugin in your LKPlugins directory, for example, it will benefit from the same kind of caching.