The method JIT compiler for Ruby 2.6

What's "MJIT"?

The RTL instruction project

MJIT: JIT compiler that runs on RTL instructions

YARV-MJIT: Yet another JIT compiler that runs on YARV instructions

Ruby's JIT status

  • JIT Compiler: YARV-MJIT
  • JIT Infrastructure: MJIT

JIT compiler benchmarks

Optcarrot

Benchmark in “Playing with ruby’s new JIT”

def calculate(a, b, n = 40_000_000)
i = 0
c = 0
while i < n
a = a * 16807 % 2147483647
b = b * 48271 % 2147483647
c += 1 if (a & 0xffff) == (b & 0xffff)
i += 1
end
c
end
Benchmark.ips do |x|
x.iterations = 3
x.report("calculate") do |times|
calculate(65, 8921, 100_000)
end
end
$ ruby -v
ruby 2.6.0dev (2018-02-15 trunk 62410) [x86_64-linux]
$ ruby bench.rb
Warming up --------------------------------------
calculate 13.000 i/100ms
calculate 13.000 i/100ms
calculate 13.000 i/100ms
Calculating -------------------------------------
calculate 1.800k (± 2.7%) i/s - 8.996k in 5.002504s
calculate 1.785k (± 7.4%) i/s - 8.853k in 5.003616s
calculate 1.802k (± 4.0%) i/s - 8.996k in 5.006199s
$ ruby --jit bench.rb
Warming up --------------------------------------
calculate 13.000 i/100ms
calculate 18.000 i/100ms
calculate 27.000 i/100ms
Calculating -------------------------------------
calculate 7.182k (± 9.1%) i/s - 35.397k in 5.000332s
calculate 7.296k (± 2.9%) i/s - 36.450k in 5.001392s
calculate 7.295k (± 3.1%) i/s - 36.450k in 5.002572s

Other benchmarks

VM-Generated JIT Compiler

switch (insn) {
% RubyVM::BareInstructions.to_a.each do |insn|
case BIN(<%= insn.name %>):
<%= render 'mjit_compile_insn', locals: { insn: insn } -%>
break;
% end
}
% expand_simple_macros.call(insn.expr.expr).each_line do |line|
% if line =~ /\A\s+JUMP\((?<dest>[^)]+)\);\s+\z/
/* Dynamic generation of JUMP code */
% else
fprintf(f, <%= to_cstr.call(line) %>);
% end
% end
switch (insn) {
case BIN(nop):
fprintf(f, "{\n");
{
fprintf(f, " reg_cfp->pc = original_body_iseq + %d;\n", pos);
fprintf(f, " reg_cfp->sp = (VALUE *)reg_cfp->bp + %d;\n", b->stack_size + 1);
fprintf(f, " {\n");
fprintf(f, " /* none */\n");
fprintf(f, " }\n");
b->stack_size += attr_sp_inc_nop();
}
fprintf(f, "}\n");
break;
case BIN(getlocal):
/* ... */
}
VALUE
_mjit0(rb_execution_context_t *ec, rb_control_frame_t *reg_cfp)
{
VALUE *stack = reg_cfp->sp;
static const VALUE *const original_body_iseq = (VALUE *)0x5643d9a852a0;
if (reg_cfp->pc != original_body_iseq) {
return Qundef;
}
label_0: /* nop */
{
reg_cfp->pc = original_body_iseq + 1;
reg_cfp->sp = (VALUE *)reg_cfp->bp + 2;
{
/* none */
}
}
/* snip... */} /* end of _mjit0 */

How is JIT infrastructure?

Support status of platforms

  • NetBSD
  • Solaris
  • AIX
  • Intel C/C++ Compiler
  • Old Visual Studio

Security

Others

About "Startup Time"

  • Building precompiled header on Ruby's build, not on runtime
  • Immediately cancel JIT compiler thread regardless of its state

`--jit-cc` does no longer exist

Acknowledgements

  • The inventor of MJIT: Vladimir Makarov
  • Ruby's father: Matz
  • Reviewers of YARV-MJIT code: ko1, mame
  • Many bug reports and fixes: wanabe
  • The first MinGW support patch: Lars Kannis
  • Maintainer of many build environments: hsbt
  • Core committers fixing MJIT infrastructure: nobu, usa, znz, knu
  • Recent VM improvements: shyouhei

What's next?

--

--

--

Software engineer at Treasure Data. https://twitter.com/k0kubun https://github.com/k0kubun https://speakerdeck.com/k0kubun

Love podcasts or audiobooks? Learn on the go with our new app.

Recommended from Medium

Announcement of the start of the new service, “E-Counter”.

What you can learn about Web Agencies from Hot Rod TV Shows

Testing in Microservice Architectures

How to Write Better Code in Python

Visual Studio Code on iPadOS, ChromeOS or Windows 11 SE — in the Browser

Preliminary data analysis on Spotify data using API

C# Extension Methods

Dev Log 11

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
k0kubun

k0kubun

Software engineer at Treasure Data. https://twitter.com/k0kubun https://github.com/k0kubun https://speakerdeck.com/k0kubun

More from Medium

Probabilistic Data Structures | Using the Bloom Filter to detect similarities

Dynamic Programming

Classes in Ruby — simple explanation

Singleton Pattern in Ruby