Rust.Tokyo 2022
YJIT: Dive into Ruby's JITcompiler written in Rust@k0kubun / Rust.Tokyo 2022
View Slide
Me● @k0kubun● Shopify○ YJIT team● Ruby committer○ MJIT maintainer
What’s YJIT?
How does YJIT work?
How YJIT worksRuby code
How YJIT works1+2ParseRuby codeAbstractSyntaxTree
How YJIT works1+2ParseRuby codeAbstractSyntaxTreeputobject 1putobject 2opt_plusleaveCompileBytecode
How YJIT works1+2ParseRuby codeAbstractSyntaxTreeputobject 1putobject 2opt_plusleaveCompile JITBytecodeMachine code
How YJIT worksputobject 1putobject 2opt_plusleaveJIT?Machine codeBytecode
How YJIT works: Ruby 3.1putobject 1putobject 2opt_plusleavex86_64CodegenMachine codeBytecode
How YJIT works: Ruby 3.2putobject 1putobject 2opt_plusleaveMachine codeBytecode
Lazy Basic Block Versioning
Lazily compile basic blocks
getlocal agetlocal bopt_plussetlocal cgetlocal cputobject 1opt_gtbranchunlessgetlocal aleavegetlocal bleaveLazily compile basic blocks
getlocal agetlocal bopt_plussetlocal cgetlocal cputobject 1opt_gtbranchunlessBranch stub Branch stubLazily compile basic blocks
getlocal agetlocal bopt_plussetlocal cgetlocal cputobject 1opt_gtbranchunlessgetlocal aleaveBranch stubLazily compile basic blocks
Why lazy compilation?1. Better code localitya. Only compile used pathsb. Related code is put together
Why lazy compilation?1. Better code localitya. Only compile used pathsb. Related code is put together2. More type information
Type Profiling
Type Profilinggetlocal agetlocal bopt_plus
Type Profilinggetlocal agetlocal bjmp regenerate
Type Profilinggetlocal agetlocal bjmp regeneratea: 1b: 2
Type Profilinggetlocal agetlocal bopt_plus (int)setlocal cgetlocal cputobject 1opt_gtbranchunless
Passes● CodeGen -> Split -> Alloc Regs
IR
IRSplit
IRSplitAlloc Regs
Rust Challenges
Clang and BindgenClang dependency orPer-architecture codegen?
Mutable Borrow
Next steps● Code GC● Register allocation● Method inlining
Conclusion● We reviewed the architecture of YJIT● Rust has been useful for transforming IR