Programming, Software and Code

Parrot JIT extravaganza

A lot of talk about JIT has been going on lately in Parrot world. Tewk submitted a very cool looking proposal to implement an LLVM-based JIT backend. We received another post to the list about libJIT. Here are some of my general Parrot-related thoughts right now:

  1. I don't have a particular preference for using LLVM or libJIT in Parrot. Both have associated pros and cons. Either solution (or even GNU Lightning, which hasn't been mentioned as regularly) would be far superior to what we have now.
  2. Our opcode files are written in a C-like superset, and our JIT system is responsible for providing secondary definitions of them as well. Change an opcode file without changing the corresponding JIT definition, you break JIT. Instead, what we should do is generate the JIT definitions automatically from the opcode definition files. This means that we probably can't write the opcodes in C (unless we can find a good translation engine from arbitrary C code to JIT code emitters). Begs the question: What would be the smallest number of operation primitives we would need in order to implement our various operations in a way that could be translated both to C and JIT definitions at build time?
  3. I took another long look at the Boehm collector today, and I learned something interesting that I did not know previously: The collector allows custom finalization methods to be run on destroyed data objects. This comes with some caveats, not the least of which is that finalizers of reachable objects are not run prior to program termination. This is rectifiable if we maintain a list of PMCs that absolutely must be finalized, and run through that list manually in Parrot_exit. I also don't think there is any guarantee about order-of-destruction when we're calling finalizers, so that can raise some problems for us. In any case, it's definitely doable, and a Boehm-based GC core could probably be a reality for Parrot in the not-to-distant future.


Which exactly advantages of LLVM do you happen to know of over libJIT? I do not know any for instance. libJIT is both faster, platform independent, and remarkably easier in use. I think, integration of LLVM and Parrot will be a lot of both time and resources for Parrot developers, and in the end of the day you will find that a lot of productivity has been lost. This is certainly not an issue to make one simple application work with LLVM; it is a long term thing.

I think, you will see this, that LLVM is not really suitable for Parrot at this time. Then you will start building patches to LLVM and workarounds to make LLVM and Parrot work together. And then you might find out that you have spent more time on patching LLVM bad design than on Parrot.

But I do not have a magic ball. These are only my 20c.

Good question, Krokas. But, let me turn it around a little bit in the form of two questions: (1) What are the benefits of using LLVM over Parrot's current JIT implementation, and (2) What would be the benefit to having a JIT system that is so inflexible that it only supports libJIT but does not support LLVM?

Answer to the first question is easy: Anything is better then what we have now and LLVM, even if there are some difficulties to work around, is no exception. Plus, all the work that is done trying to make LLVM work will lead to a cleaner and more encapsulated interface in Parrot, even if the end result is that LLVM is deemed unusable.

Answer to the second question is equally easy: If we can develop a sane interface that supports LLVM, then it should be easy for us to add a plugin for libJIT too. Doing one makes it easier to do the other, and it makes it easier to add other solutions that we haven't even thought about yet.

As a final note, I'll say that we're currently pursuing an LLVM-based backend because that's what our volunteer developers have proposed to do. The current work is part of a GSOC project that was laid out with a firm timeline. We can't change that proposal now that the project has started, even if we decide as a team that libJIT is the better route to go in the long run.

In the open source world, the only projects that get done are the ones that people feel compelled to work on, and an LLVM-based backend has compelled more coders then a libJIT-based one has. However, if anybody reading this has the time or expertise to write a libJIT backend for Parrot, "patches welcome".

I encourage you not to try to support multiple JIT backends. This will dilute your already thin resources. Creating a "cleaner and more encapsulated interface" is one thing, but getting it done is another. Also, dependencies in open source are frustrating for many. Parrot should try to have as few as possible, considering its nature. Consider whether JIT is really a critical path for a dynamic language that spends much more of its time doing lookups and calling into APIs than a mid-level language like Java/C#. I haven't doing any benchmarks lately, but I recall that Parrot's fast core was much better than that of Perl5 for similar code, without the JIT. There are successful VMs that do not have JIT. Dalvik is one recent one. I don't recall that MicroFocus COBOL had one either, and neither did the old p-code machines. We could probably name quite a list. I'd make Parrot a successful platform for a major language first (namely Perl6), then work the JIT out. Just a thought. -mrjoltcola

This entry was originally posted on Blogger and was automatically converted. There may be some broken links and other errors due to the conversion. Please let me know about any serious problems.