JägerMonkey Update: Getting Faster
Time for another JägerMonkey update: how far we’ve come, what’s happening next, and our plan to bring it all together in time for Firefox 4.
How far we’ve come. So far this year, we’ve done two huge things:
- Written the JägerMonkey method JIT compiler for x86 (with ARM support mostly there). One of the key challenges was generating good code out from SpiderMonkey’s stack-based bytecode. Stack-based bytecodes tend to spend a lot of time reading from and writing to the stack compared to register-based bytecodes like Nitro’s. We designed a compilation strategy that works with our register allocator to boil away most of the stack traffic. We simulate stack operations during compilation and then generate “equivalent” code that keeps things in registers instead of in stack memory. The compiler also has fast paths for arithmetic, PICs, and all the other usual dynamic language JIT stuff. David Anderson led this effort, ably assisted by Sean Stangl.
At this point, our JIT can generate code about as good as Nitro or V8, except for a few optimizations that we are missing, such as fast paths for the mod operator or comparing floating-point numbers. We also need to make a few more improvements to our register allocator. And, of course, we need to bring up the x64 version of the JIT. But overall, the JIT code is looking very good.
All in all, JägerMonkey is now about 3x faster than the baseline interpreter we started with.
Remaining Performance Work. The areas where our performance is still really hurting are in the runtime: function calls, strings, and regular expressions:
- Regular expressions. The benchmarks are kind of heavy on regular expressions. We started with a simple regular expression compiler, created by me, extended by Luke Wagner. But there are still a lot of regular expressions it doesn’t compile, which run in the slower regular expression interpreter. Because we now use the same assembler that Nitro does, we can use their regular expression compiler, Yarr, too. Chris Leary took on the job of porting over Yarr to SpiderMonkey, and it’s about to land.
Once we get these items and the JIT improvements already discussed, we should be fast. There are about 30 bugs on file for JM performance, some easy, some hard, some compiler, some runtime, some big wins, some small–anyone who wants to help make us fast should check out the list.
Real Artists Ship. Being fast only counts if it ships. Getting us ready to ship is the priority focus right now. Shipping is mostly about getting out a beta and finding and fixing bugs. There are a couple of big chunks we need to do for a beta JM:
- x64 JIT compiler. Sean Stangl is moving right along from the x86 JIT compiler to the x64 version. It will be basically the same design, but should be even more effective because x64 has so many more registers.
- Integration with the trace JIT. Of course, we already have a JIT, the tracing JIT, which generates excellent code for certain programs, especially simple math kernels. So we need to be able to switch back and forth between the method JIT and the trace JIT, hopefully at the ideal times. David Anderson is now working on this. Combining the two systems most effectively will take a lot of tuning, which will have to be ongoing as the performance characteristics of both JITs are still improving.