Invariants in my own Ruby: some things must never change
We all love Ruby for its flexibility, but it’s a total nightmare for a JIT compiler. Redefining Integer#+ or using eval and Binding creates chaos. To go fast, JIT compilers make "optimistic bets" called invariants—assuming things won't change to skip redundant checks. But when these bets fail, we need an emergency exit to the great Mother interpreter : deoptimization.
I’ll share my journey building monoruby (a Ruby implementation written from scratch in Rust) and how I keep it fast and correct. We'll explore:
- Why JIT-generated code is faster than the interpreter.
- The specific invariants used to handle Ruby's dynamic nature.
- Implementation details in monoruby.
Let's dive into the black box of JIT internals!