Back to the Ruby Compiler Survey, JRuby

The Ruby Compiler Survey

Building JRuby

Start with Ubuntu Linux 18.04 Bionic 64-bit server. Run a basic install and then run this script as the user. You will need 8 GB of memory to build JRuby.

We’re building JRuby 9.2.9.0, 458ad3ed9cdb18b3e69fb96b947b978a193afeb6.

% sudo apt-get update
% sudo apt-get install -y git openjdk-8-jdk-headless wget

% git clone https://github.com/ruby-compiler-survey/jruby.git
% pushd jruby
% git checkout 458ad3ed9cdb18b3e69fb96b947b978a193afeb6
% git apply no-precompile.patch
% git apply ir-opt.patch
% git apply inlining.patch
% ./mvnw
% popd

% wget https://lafo.ssw.uni-linz.ac.at/pub/graal-external-deps/hsdis/intel/hsdis-amd64.so
% sudo mv hsdis-amd64.so /usr/lib/jvm/java-8-openjdk-amd64/jre/lib/amd64/server

% echo PATH=$PATH >> .bashrc

We build with Java 8, because that’s what their CI does.

JRuby by default will compile the entire entry-point script on load. This makes it hard to understand the compilation of individual methods, the effect of profiling, and things like compilation threshold. This feature cannot be disabled with an option, so we turn it off by patching the source code.

Now we can run JRuby.

% ruby -Xjit.logging fib.rb
2020-01-17T04:53:59.582Z [Ruby-0-JIT-1] INFO JITCompiler : method done jitting: Object fib at /var/examples/fib.rb:0
832040
832040
832040
832040

We’ll JRuby run with -Xcompile.invokedynamic to enable more extensive use of the invokedynamic instruction.

We’ll use these flags to help us understand what the JRuby JIT is doing:

We’ll use the separate ast command to print JRuby’s AST.

% ast fib.rb
AST:
    DefnNode:fib 0
      ArgsNode 0
          ArgumentNode:n 0
      IfNode 1
        CallNode:<= 1
          LocalVarNode:n 1
          ArrayNode 1
            FixnumNode 1
        FixnumNode 2
        CallNode:+ 4
          FCallNode:fib 4
            ArrayNode 4
              CallNode:- 4
                LocalVarNode:n 4
                ArrayNode 4
                  FixnumNode 4
          ArrayNode 4
            FCallNode:fib 4
              ArrayNode 4
                CallNode:- 4
                  LocalVarNode:n 4
                  ArrayNode 4
                    FixnumNode 4

The -Xir.debug.igv option allows dumping to IGV but unfortunately it isn’t compatible with modern IGV.

With Vagrant

Use the ruby-compiler-survey repository.

% cd jruby
% vagrant up
% vagrant ssh
% ruby -Xjit.logging /var/examples/fib.rb
2020-01-17T04:53:59.582Z [Ruby-0-JIT-1] INFO JITCompiler : method done jitting: Object fib at /var/examples/fib.rb:0
832040
832040
832040
832040