Summary
In an extensive blog post, JRuby project lead Charles Nutter discusses the history of the JRuby interpreter, and the decisions that led him to come up with a new design. He also gives a road-map for JRuby 1.0.
Advertisement
Last month, Sun hired the two lead figures behind the JRuby project, with the stated goal to create a first-class Ruby implementation on the JVM. In a recent blog post, Another Year, Another Interpreter, Charles Nutter describes the evolution of the JRuby interpreter, including some of the challenges the project faced is it looked forward to Ruby 2.0:
Sometime around JavaOne we heard about ... a Ruby conference or get-together of some sort. If RubyConf is the big conference for us Westerners, this at least provided a mid-year update for English-speaking Rubyists. Matz was there, Koichi was there, and I believe other Ruby dignitaries made the trip as well...
And then Matz and Koichi dropped the bomb: Ruby 2.0 would support neither continuations nor green threads... As many of you know, Koichi's next-generation Ruby interpreter engine, YARV, has been coming along in fits and starts. Because of the desire to keep existing extensions working and because of a lack of resources to work on Ruby internals, YARV has had many difficult problems to overcome. How do you write a next-generation interpreter without actually changing how the runtime works? Is it possible to do it without a new threading implementation, a new memory manager, a new garbage collector? Can you keep all your internal APIs exposed to C extensions and successfully migrate to a new interpreter design?
I think the answer is that yes, you can, but it's really, really hard. And along with the announcement about continuations and green threads came the YARV/Rite (Ruby 2.0 + YARV) beta time-line: no earlier than Christmas 2007.
Since threads and support for continuations were at the top of the JRuby team's agenda, the news that Ruby 2.0 won't support continuations and green threads forced the JRuby team to make a few decisions:
Eventually we decided that under the circumstances, the Ruby and JRuby communities would be better served by having a solid, native-threaded, continuation-free implementation on the JVM. We were unable to find any use of continuations in the most popular applications, and it seemed that very few people had a good reason to use them. In addition, there was growing concern over Ruby's lack of support for native threads; so there too was a opportunity for JRuby to shine.
Nutter then started to work on a new interpreter:
The new interpreter is...a large switch statement. Each AST node is assigned an int, so the main "eval" call can quickly determine the correct code to execute for each. The new design does result in faster deepening of the Java stack (about a 15-20% hit to fib max-depth), but it still performs far better than the original visitor-based implementation. And although we'd only theorized up to this point, it does perform a good bit better than the Instruction-based engine.
In the same blog post, Nutter also provides a roadmap for a JRuby 1.0 release:
We have also started to iron out what a JRuby 1.0 release should look like. A few major points come up again and again:
Compatibility should be such that we can safely claim "Rails is supported"
Java integration should look like we want it to look for the future, and should be performant, lightweight, and seamless
All major codebase refactorings should be complete; this includes a solid design for wiring up Java-based method implementations, external extensions, and IO channels
Unicode should be supported out-of-the-box, giving Ruby code access to everything Java is capable of
Threading should work perfectly, both for JRuby-launched threads and for "adopted" threads from outside the runtime
Performance should be markedly improved
What features in the 1.0 release would make JRuby a useful tool in your projects?
I want to write Ruby applications that utilize Java libraries. As a such, the following would be my killer feature:
An easy way to progressively "Rubify" Java libraries. By that, I mean interfacing a library from Ruby and have it "feel like" a Ruby library.
This is less trivial than it seems - Ruby libraries tend to actively use Ruby-based DSLs, default values and procs (the Ruby iterator syntax). So, Rubifying a Java library would include changes from the Java API, sometimes fairly large changes.
Apart from that, I'll hopefully also be able to phase in JRuby at work, for implementing the non-performance-critical parts of our systems that are presently in Java. That would be doable with JRuby as soon as it worked even reasonably - though the above would be of large benefit for that, too.