A Comparison of JavaScript Engines
When I was writing the History of JavaScript series I collected a lot of notes about JavaScript interpreters. If you’re wondering why people keep talking about V8 engines, monkeys and rhinos, read on.
Name | Type | Garbage Collection | Security | Implemented In |
---|---|---|---|---|
Rhino | Compiler and interpreter | Java runtime | SecuritySupport interface, domain-based | Java |
SpiderMonkey | Compiler and interpreter | Mark-and-Sweep, non-conservative (exact) collector | Java principals security model | C |
V8 | Virtual machine | Generational stop-the-world collector | Context-based, with security tokens | C++ |
Engine Types
Rhino and SpiderMonkey can run as compilers or interpreters. They parse JavaScript into an intermediate stage. V8 is different in that it has no intermediate parser — it generates assembler. This makes it sound more like a compiler than anything, but it does include a runtime environment of its own.
Garbage Collection
SpiderMonkey works by recursively searching all properties of all objects in the current scope and deallocating any without references. V8 stops execution to reclaim memory, but it only usually processes part of the heap to reduce the impact of stopping the program. The disadvantage of V8’s approach is that it has to stop the program — imagine a JavaScript program suddenly pausing and beachballing or egg-timering. However, because it’s simple, it’s also fast.
Trace Trees
SpiderMonkey 1.8.1 has a just-in-time compiler that can convert bytecode into machine code to improve performance. This was contributed by Adobe and now co-maintained by Mozilla. The JIT watches for commonly executed code and attempts to optimise the equivalent native code. The Tracing JIT page on Mozilla’s site has more details.
This is one of the reasons that recent performance graphs show Mozilla’s JavaScript engines catching up with V8. V8’s core innovation was compiling straight into native code.