3 ms·
Evan Phoenix (Rubinius) talked about applying the Self techniques of collecting type info using inline caches for CRuby in 2015. I'm using part of this idea i
by jashmatthews 7y ago
Evan Phoenix (Rubinius) talked about applying the Self techniques of collecting type info using inline caches for CRuby in 2015.
I'm using part of this idea in my prototype tracing JIT for CRuby. With a tracing JIT it's much, much easier to implement basic escape analysis because the control flow is linear. One basically gets Partial Escape Analysis (the big deal from Graal) for free.
So far it's proving unreasonably effective to re-use the method lookup info from the inline caches and use the same invalidation mechanism.
The CRuby 2.6 JIT can't use this approach because the compilation pipeline is too slow to invalidate it with the method cache, but I'm using the CraneLift compiler from Mozilla.
Post Haswell, there's not a ton of value to baseline JIT, especially for dynamic languages. Mike Pall talked at length about how the highly optimized bytecode VM of LuaJIT 2.x was sometimes faster than the baseline-ish method JIT from LuaJIT 1.x, and that was before Haswell.
I think we'll see all the major JS engines remove baseline JIT over the next few years in favour of even more optimized bytecode interpreters.
- dralley 7y agoCould you expand on exactly what Haswell did to render baseline pointless?
- jashmatthews 7y agoHaswell can branch predict the indirect branch at the end of each bytecode instruction to dispatch the next bytecode instruction much better than previous generations. In highly dynamic languages like JS, Ruby and Python it’s not even this which is the main source of branching anyway. It’s branching on the typesfor each opcode to handle all valid types.
- om2 7y ago> I'm using part of this idea in my prototype tracing JIT for CRuby. With a tracing JIT it's much, much easier to implement basic escape analysis because the control flow is linear. One basically gets Partial Escape Analysis (the big deal from Graal) for free. Maybe Ruby is different. But with JavaScript, tracing JIT turned out to not be a winning strategy. Every engine that tried it eventually moved to a more traditional multi-tiered JIT (with OSR entry/exit). > Post Haswell, there's not a ton of value to baseline JIT, especially for dynamic languages. Mike Pall talked at length about how the highly optimized bytecode VM of LuaJIT 2.x was sometimes faster than the baseline-ish method JIT from LuaJIT 1.x, and that was before Haswell. I can't say definitively for other languages, but for the JavaScriptCore implementation of JavaScript, we are very aware of the performance value of all our JIT tiers, and the baseline JIT makes a significant difference. And yes, our interpreter is very optimized. We essentially have a CPU-specific interpreter loop using assembly code generated from a meta-language. Baseline JIT on top of that is still a big perf win (as are our two higher JIT tiers, DFG and FTL/B3).
- jashmatthews 7y agoIn an ideal world we would build a multi-tier method JIT for CRuby just like JSC. Unfortunately nobody is willing to invest the resources to do that. There have been numerous failed attempts to build baseline JITs for CRuby so I'm trying tracing.