Skip to content

(Experimental) Add mrb2cs AOT compiler#187

Open
hadashiA wants to merge 1 commit into
mainfrom
jetpack-aot
Open

(Experimental) Add mrb2cs AOT compiler#187
hadashiA wants to merge 1 commit into
mainfrom
jetpack-aot

Conversation

@hadashiA

@hadashiA hadashiA commented Jun 27, 2026

Copy link
Copy Markdown
Owner

This feature significantly improves execution speed and memory footprint by converting mrb bytecode into C# code in advance.

This feature allows for a mix of regular mrb bytecode execution and mrb2cs-generated C#, and it can also fallback to the interpreter for features that mrb2cs cannot convert to C#. In other words, while maintaining full compatibility, it becomes extremely fast as long as you put in the effort for AOT-compiled release builds.

Design principle

Why AOT?

  • The main benefits are improved execution speed and, above all, the reduction of allocations through escape analysis and placing objects on the C# stack.
  • Since ChibiRuby primarily targets AOT compilation environments such as Unity IL2CPP, we chose the pre-compilation method instead of a JIT-like approach that emits IL at runtime.

Why not base it on Ruby AST?

  • By taking mrb bytecode as input, it becomes easy to mix the current interpreter and mrb2cs from the same input.
  • It can be utilized seamlessly by using the interpreter in development environments and mrb2cs (with automatic fallback to the interpreter) in release builds.
  • Since ChibiRuby and the mrb compiler are separate, a feature that takes AST as input is generally complex.

Optimization Mechanism

  • Based on ZJIT, it works as follows:
  • First, the mrb bytecode is converted into a High-Level IR representation. By adopting the SSA form, escape analysis is made easier.
  • After applying optimizations to the IR, it is converted into C# code.

Performance

Benchmark Metric Interpreter AOT Ratio
ao_render (alloc-heavy, float, cross-object) time/iter 3863 ms 503 ms 7.7× faster
alloc/iter 710.0 MB 120.2 MB 5.9× less
mandelbrot (numeric tight loop) time/iter 894 ms 18.2 ms 49× faster
alloc/iter 950 B 911 B ~same (near-zero already)
optcarrot (NES emulator, complex ruby) fps 16.4 fps 54.8 fps 3.3× faster

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant