From: Charles Oliver Nutter Date: 2008-11-19T21:57:34+09:00 Subject: Re: What would you like to know about JRuby? Maksim Ananjev wrote: > Oh, sorry. Rubyconf is over, I have not looked at the date of the > first message, shame on me :) > However I still will be grateful for the useful resources on this > topic. And looking forward for the presentation to be published > somewhere. No problem :) The talk should be published soon, but I can answer this question here too. > On Nov 19, 2:31 pm, Maksim Ananjev wrote: >> I would greatly appreciate some general overview of the internals. Are >> ruby files compiled into bytecode and then executed or java is invoked >> to execute code line by line. If the first option is possible how do >> you handle dynamic typing issues. Are any code optimizations applied >> to ruby code? JRuby is a mixed-mode implementation. We have both an interpreter that walks the Ruby AST, just like Ruby 1.8 (though quite a bit faster), and a compiler that turns Ruby into JVM bytecode. You can run all interpreted, all compiled, or allow us to compile code just-in-time (JIT) as the application runs. You can also compile all code ahead-of-time (AOT) and ship .class files. The compiled bytecode, however, is not exactly like a typical Java class. Because Ruby's class structures are very fluid, we do not (can not) present a normal Java type. So the compilation is solely to create "bytecode chunks" that will be executed independently as method, block, and class bodies. The .class that results from AOT compilation is basically just a "blob of methods" that are wired up at runtime into Ruby code bodies. Is that clear? Here's an example of the methods that result from compiling a very simple script into a .class. The name mangling shows that we're using these simply as blobs of bytecode: [headius @ cnutter:~/projects/jruby] $ cat foo.rb class Foo def bar baz { } end end [headius @ cnutter:~/projects/jruby] $ javap foo Compiled from "foo.rb" public class foo extends org.jruby.ast.executable.AbstractScript{ public foo(); public static {}; public IRubyObject __file__(...); public IRubyObject class_0$RUBY$Foo(...); public IRubyObject method__1$RUBY$bar(...); public IRubyObject block_0$RUBY$__block__(...); public IRubyObject method__1$RUBY$bar(...); public IRubyObject class_0$RUBY$Foo(...); public IRubyObject __file__(...); public IRubyObject load(...); public static void main(java.lang.String[]); } The __file__ methods correspond to the body of the script. The two class_0$RUBY$Foo methods represent the class body. The method__1$RUBY$bar methods are the body of the "bar" method. The block_0$RUBY$__block__ method is the body of the block. And finally the load and main methods are used for loading this script as a library (via require or load) and for executing it as a normal Java "main", respectively. Generally, you don't need to know about any of this to get the benefit of JIT or AOT compilation in JRuby. - Charlie