Misc #18968
closedRun MJIT under a forked Ruby process
Description
Changes¶
- When MJIT compiles a method, it spawns a child Ruby process and lets it generate a C code and compile it.
- Stop supporting platforms without fork(2), i.e. mswin
- A suggested alternative to it in Windows, in general, is running the implementation for Linux on WSL. It's likely already faster than the mswin one because of recent SIGCHLD-related changes.
Background¶
To improve the maintainability of MJIT's optimization logic, I'm planning to rewrite MJIT in Ruby.
To run Ruby code safely, you need a GVL or at least be on a Ractor. Doing so in the main thread would cause performance problems. We evaluated running MJIT on a Ractor https://github.com/ruby/ruby/pull/4024, but enabling the multi-Ractor mode slows down things.
The proposed change, forking a child process, doesn't enable the multi-Ractor mode, and it's confirmed to be faster than the Ractor-based patch. If you fork a process and run it for a while, you need inter-process communication to give the latest inline cache contents. But it requires synchronization. Another option that doesn't require synchronization that much is to fork a process every time, which is what's discussed in this ticket.
Updated by chrisseaton (Chris Seaton) 10 months ago
An interesting project if you are changing the interface could be to write a generic JIT interface, which any JIT could plug into. At the moment we have custom C code to plug in MJIT and YJIT - an interface could reduce that C code and enable more experimentation with JITs.
In Java, this is called JVMCI - the JVM Compiler Interface.
Updated by k0kubun (Takashi Kokubun) 10 months ago
Yeah. Ever since I created llrb.gem, I've sometimes thought about it. Like what the description of JEP 243 says, JIT needs to know about VM data structures, which are currently just part of C code in vm.c. If we provide that and make jit_exec
pluggable, that'd be the minimum common requirement for CRuby JITs. Chances are I might end up achieving it this time by making MJIT written in Ruby because everything will be dynamically accessible and monkey-patchable.
Updated by k0kubun (Takashi Kokubun) 10 months ago
- Status changed from Open to Closed
Applied in changeset git|dc8d70e4615cdf12378322fbcd4396486270ddbe.
Execute MJIT in a forked Ruby process (#6264)
[Misc #18968]