The Mozilla Foundation has developed TraceMonkey a trace-based JIT compiler that pushes the envelope on JavaScript performance. With plans to be incorporated it in the 3.1 release of Firefox, it delivers near C performance and promises to ‘leap frog’ RIA development to a new level.
Andreas Gal talks about TraceMonkey benchmarks:
TraceMonkey is a trace-based JIT compiler and it pushes the envelope on JavaScript performance. On average, we speed up Apple’s popular SunSpider benchmarks by factor 4.6 over the last release of Firefox. The overall runtime of SunSpider improved by about 1.83x (parts of SunSpider excercise things like the regular expression engine which is outside of the scope of JIT compilation, hence the lesser overall speedup). For the SunSpider ubench suite, which focuses on core JavaScript language features, we achieve a speedup of 22x. Whichever metric you chose to apply, Firefox now has the fastest JavaScript engine in the world.
Our JIT generates code that is roughly equivalent to the performance of unoptimized C code (gcc -O0).
He also explains how tracing works:
Traditional just-in-time compilers (like Sun’s Hotspot VM) are in their design and structure very similar to static compilers (like GCC). They observe which methods get executed frequently, and translate the method into native machine code once a certaint threshold has been reached. While such methods often contain performance-critical parts (such as loops), they often also contain slow paths and non-loopy code, which barely if at all contributes to the runtime of the method. A whole-method compiler, however, has to always analyze and translate the entire method, even if parts of it are not particularly “compilation-worthy”.
Trace-based compilation takes a very different approach. We monitor the interpretation of bytecode instruction by the virtual machine and scan for frequently taken backwards branches, which are an indicator for loops in the underlying program. Once we identify such a loop start point, we follow the interpreter as it executes the program and record the sequence of bytecode instructions that get executed along the way. Since we start at a loop header, the interpreter will eventually return to this entry point once it completed an iteration through the loop. The resulting linear sequence of instructions is what we call a trace.
Traces represent a single iteration through a loop, and can span multiple methods and program modules. If a function is invoked from inside a loop, we follow the function call and inline the instructions executed inside the called method. Function calls themselves are never actually recorded. We merely verify at runtime that the same conditions that caused that function to be activated still hold.
Mike Shaver also talks about the work being put into Firefox JavaScript Engine:
Over the past year, JavaScript performance on the web has undergone a striking revolution. Virtually every browser has improved its engine to produce significant gains in execution speed; Firefox is about 3 times faster than Firefox 2 in various JavaScript benchmarks, for example. But of course, developer and user demand for performance is insatiable, and at Mozilla we demand it ourselves, since our application itself is largely and increasingly written in JavaScript. In addition to improving the performance of web applications, our work on JS performance in Firefox 3 made our own application snappier and more responsive.
Brendan Eich blogs about what these developments mean:
Pulling back from the details, a few points deserve to be called out:
- We have, right now, x86, x86-64, and ARM support in TraceMonkey. This means we are ready for mobile and desktop target platforms out of the box.
- As the performance keeps going up, people will write and transport code that was "too slow" to run in the browser as JS. This means the web can accomodate workloads that right now require a proprietary plugin.
- As we trace more of the DOM and our other native code, we increase the memory-safe codebase that must be trusted not to have an exploitable bug.
- Tracing follows only the hot paths, and builds a trace-tree cache. Cold code never gets traced or JITted, avoiding the memory bloat that whole-method JITs incur. Tracing is mobile-friendly.
- JS-driven <canvas> rendering, with toolkits, scene graphs, game logic, etc. all in JS, are one wave of the future that is about to crest.
TraceMonkey advances us toward the Mozilla 2 future where even more Firefox code is written in JS. Firefox gets faster and safer as this process unfolds.
Also John Resig talks about what these significant gains mean for the JavaScript language and the future of RIAs:
So what does this all mean? It means that JavaScript is no longer confined by the previously-challenging resource of processing power. With this improvement it's leap-frogged any sort of traditional and has gone head-to-head with computationally-powerful languages like C.
I fully expect to see more, massive, projects being written in JavaScript. Projects that expect the performance gains that we're starting to see. Applications that are number-heavy (like image manipulation) or object-heavy (like relational object structures).
One area that I'm especially excited about is in relation to Canvas. The primary thing holding back most extensive Canvas development hasn't been rendering - but the processor limitations of the language (performing the challenging mathematical operations related to vectors, matrices, or collision detection). I expect this area to absolutely explode after the release of Firefox 3.1 as we start to see this work take hold.
Seeing releases like this are absolutely exciting for me. JavaScript is absolutely the little-language-that-could - continually routing around any of its short-comings and blowing away all of its expectations. I look forward to using it for many, many, years to come.
If you want to try out TraceMonkey for yourself, you can download the Firefox 3.1 nightly, open about:config, and set the javascript.options.jit.content preference to true. Although it is still work-in-progress and buggy, John Resig claims that the nightly build should be good enough to handle most web sites.
For more news and articles about Rich Internet Applications you can visit: http://www.infoq.com/ria