Back to the Ruby Compiler Survey, Rubinius

The Ruby Compiler Survey

Building Rubinius

Start with Ubuntu Linux 14.04 Trusty 64-bit server. Run a basic install and then run this script as the user. You will need 4 GB of memory to build Rubinius.

We’re building Rubinius 3.19, 1cc41ddc7c2d3f4a2a70cc39a49e45233f7bc4b3.

% sudo apt-get update
% sudo apt-get install -y wget build-essential gdb zlib1g-dev libssl-dev libreadline-dev libyaml-dev git clang-3.5 llvm-3.5-dev libedit-dev libncurses-dev

% wget https://cache.ruby-lang.org/pub/ruby/2.2/ruby-2.2.0.tar.gz
% tar -zxf ruby-2.2.0.tar.gz

% pushd ruby-2.2.0
% ./configure --prefix=$PWD/installed
% make install
% PATH=$PWD/installed/bin:$PATH
% gem install bundler -v 1.11.2
% popd

% git clone https://github.com/ruby-compiler-survey/rubinius.git
% pushd rubinius
% git checkout 1cc41ddc7c2d3f4a2a70cc39a49e45233f7bc4b3
% patch -p1 < bundler.patch
% bundle
% ./configure --llvm-config llvm-config-3.5 --prefix=$PWD/installed
% rake build
% rake install
% PATH=$PWD/installed/bin:$PATH
% popd

% echo PATH=$PATH >> .bashrc

We were not able to install the bundled gem bundler 1.11.2 using Rubinius itself - the gem file was always reported as corrupt, so we remove this from gems_list.txt before building.

The build occasionally fails. You may need to retry a few times to get a successful build.

Now we can run Rubinius.

% ruby -Xjit.show fib.rb
[[[ JIT queued Object#fib (method)  (32000)  ]]]
832040
832040
832040
[[[ JIT finished background compiling 832040Object#fib (method) ]]]
832040
832040
832040
832040
832040
832040
...

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

Note that -Xjit.log= doesn’t appear to work.

To view the AST for a file, use rbx compile --print-ast file.rb. To print bytecode use --print-bytecode.

The disassembler in Rubinius appears to show all jumps as having a positive offset, even if they are backward jumps. This makes understanding the machine code very complicated. Something about how LLVM basic blocks are created also appears to cause poor scheduling, so not all backward jumps are loops, even in simple cases. To get usable assembly output we used gcore to dump a core file and logged the assembly to get addresses of the code to disassemble from.

With Vagrant

Use the ruby-compiler-survey repository.

% cd rubinius
% vagrant up
% vagrant ssh
% ruby -Xjit.show /var/examples/fib.rb
[[[ JIT queued Object#fib (method)  (32000)  ]]]
832040
832040
832040
[[[ JIT finished background compiling 832040Object#fib (method) ]]]
832040
832040
832040
832040
832040
832040
...