Upgrade to Pro — share decks privately, control downloads, hide ads and more …

YJIT: Dive into Ruby's JIT compiler written in Rust / Rust.Tokyo 2022

YJIT: Dive into Ruby's JIT compiler written in Rust / Rust.Tokyo 2022

Rust.Tokyo 2022

Takashi Kokubun

September 23, 2022
Tweet

More Decks by Takashi Kokubun

Other Decks in Programming

Transcript

  1. YJIT: Dive into Ruby's JIT compiler written in Rust @k0kubun

    / Rust.Tokyo 2022
  2. Me • @k0kubun • Shopify ◦ YJIT team • Ruby

    committer ◦ MJIT maintainer
  3. What’s YJIT?

  4. None
  5. None
  6. None
  7. None
  8. How does YJIT work?

  9. How YJIT works Ruby code

  10. How YJIT works 1 + 2 Parse Ruby code Abstract

    Syntax Tree
  11. How YJIT works 1 + 2 Parse Ruby code Abstract

    Syntax Tree putobject 1 putobject 2 opt_plus leave Compile Bytecode
  12. How YJIT works 1 + 2 Parse Ruby code Abstract

    Syntax Tree putobject 1 putobject 2 opt_plus leave Compile JIT Bytecode Machine code
  13. How YJIT works putobject 1 putobject 2 opt_plus leave JIT

    ? Machine code Bytecode
  14. How YJIT works: Ruby 3.1 putobject 1 putobject 2 opt_plus

    leave x86_64 Codegen Machine code Bytecode
  15. How YJIT works: Ruby 3.2 putobject 1 putobject 2 opt_plus

    leave Machine code Bytecode
  16. How YJIT works: Ruby 3.2 putobject 1 putobject 2 opt_plus

    leave Machine code Bytecode
  17. Lazy Basic Block Versioning

  18. Lazily compile basic blocks

  19. getlocal a getlocal b opt_plus setlocal c getlocal c putobject

    1 opt_gt branchunless getlocal a leave getlocal b leave Lazily compile basic blocks
  20. Lazily compile basic blocks

  21. getlocal a getlocal b opt_plus setlocal c getlocal c putobject

    1 opt_gt branchunless Branch stub Branch stub Lazily compile basic blocks
  22. getlocal a getlocal b opt_plus setlocal c getlocal c putobject

    1 opt_gt branchunless getlocal a leave Branch stub Lazily compile basic blocks
  23. getlocal a getlocal b opt_plus setlocal c getlocal c putobject

    1 opt_gt branchunless getlocal a leave Branch stub Lazily compile basic blocks
  24. getlocal a getlocal b opt_plus setlocal c getlocal c putobject

    1 opt_gt branchunless getlocal a leave getlocal b leave Lazily compile basic blocks
  25. Why lazy compilation? 1. Better code locality a. Only compile

    used paths b. Related code is put together
  26. Why lazy compilation? 1. Better code locality a. Only compile

    used paths b. Related code is put together 2. More type information
  27. Type Profiling

  28. Type Profiling getlocal a getlocal b opt_plus

  29. Type Profiling getlocal a getlocal b opt_plus

  30. Type Profiling getlocal a getlocal b jmp regenerate

  31. Type Profiling getlocal a getlocal b jmp regenerate

  32. Type Profiling getlocal a getlocal b jmp regenerate a: 1

    b: 2
  33. Type Profiling getlocal a getlocal b opt_plus (int) setlocal c

    getlocal c putobject 1 opt_gt branchunless
  34. Passes • CodeGen -> Split -> Alloc Regs

  35. Passes • CodeGen -> Split -> Alloc Regs

  36. IR

  37. IR Split

  38. IR Split Alloc Regs

  39. Rust Challenges

  40. Clang and Bindgen Clang dependency or Per-architecture codegen?

  41. Mutable Borrow

  42. Next steps • Code GC • Register allocation • Method

    inlining
  43. Conclusion • We reviewed the architecture of YJIT • Rust

    has been useful for transforming IR