ruby/ruby
JIT compilers
Ruby ships two just-in-time compilers, both written in Rust and both linked statically into the interpreter at build time:
- YJIT (
yjit/) — Yet-Another-JIT. A method-based JIT that uses Lazy Basic Block Versioning. Production-grade since Ruby 3.2 (when it was rewritten from C to Rust). Targets x86_64 and arm64. - ZJIT (
zjit/) — A newer JIT with a higher-level IR (HIR/LIR) and an offline-style optimizer. Under heavy active development as of this snapshot.
Both JITs are optional — pick at configure time:
./configure --enable-yjit --enable-zjitAt runtime, pick at most one with --yjit or --zjit. They observe iseqs running in the VM and, when one becomes hot, generate native machine code that the VM jumps into instead of interpreting.
graph LR
iseq[Compiled iseq] -->|interpret| vm[VM dispatch loop]
vm -->|hot threshold| trigger[JIT trigger]
trigger -->|--yjit| yjit[YJIT codegen]
trigger -->|--zjit| zjit[ZJIT codegen]
yjit -->|machine code| jit_call[JIT entry]
zjit -->|machine code| jit_call
jit_call -->|on side exit| vmThe shared host code:
- The build orchestrates Rust via
yjit/yjit.mkandzjit/zjit.mk, called from the mainMakefile. Cargo.tomlat the repo root is a workspace containingyjit,zjit, and a tinyjitcrate.yjit.c/zjit.care the C entry points; everything beyond them is Rust.yjit.h/zjit.hdeclare the C-callable interface.yjit.rb/zjit.rbprovide Ruby-level introspection (RubyVM::YJIT.runtime_stats,RubyVM::ZJIT.dump_*).
Pages in this section
| Page | Topic |
|---|---|
| yjit.md | Lazy basic-block versioning JIT |
| zjit.md | IR-driven JIT |
History
The journey to Ruby's current JIT story:
- 2.6 (Dec 2018): MJIT — a process-based JIT that wrote C and shelled out to GCC/Clang. Modest speedups; high startup cost.
- 3.1 (Dec 2021): YJIT merged, originally written in C, by Maxime Chevalier-Boisvert at Shopify.
- 3.2 (Dec 2022): YJIT rewritten in Rust. First Rust code in CRuby. MJIT begins deprecation.
- 3.3 (Dec 2023): MJIT replaced by RJIT (a Ruby-implemented JIT, also experimental). RJIT later removed.
- 3.4 / 4.0 (Dec 2024 / 2025): ZJIT lands.
This is the first time CRuby has shipped two JITs in parallel.
Choosing a JIT
| Use YJIT if | Use ZJIT if |
|---|---|
| You want a stable, mature JIT with years of production use | You're testing the bleeding edge |
| Your workload is method-call-heavy with relatively stable types | Your workload benefits from cross-method optimization |
| You're on a release before ZJIT is GA | You want to give feedback on the next-gen design |
Most users today should reach for --yjit.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.