3 ms·
Many of the techniques used in modern JS VMs like v8 or JavaScriptCore could totally be applied to a Python interpreter, and it wouldn't take 50 people. Someone
by om2 7y ago
Many of the techniques used in modern JS VMs like v8 or JavaScriptCore could totally be applied to a Python interpreter, and it wouldn't take 50 people. Someone just needs to invest the effort. The core techniques are a fast-start interpreter, a templatized baseline JIT, polymorphic inline caches, and runtime type information combined with higher JIT tiers that speculatively optimize for observed types, which allows many checks throughout the generated code to be replaced by side exits. (Also a good garbage collector, and escape analysis to avoid allocating temporaries).
I believe most of these could be applicable to Python. JavaScript has crazy levels of dynamism too, and the above methods are the short version of how you deal with it.
It seems like no one in the Python community has had the knowledge + motivation to try these approaches.
- jashmatthews 7y agoEvan 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.