of script to native machine code immediately prior to execution. Code is initially compiled by a baseline compiler, which can generate non-optimized machine code quickly. The compiled code is analyzed during runtime and optionally re-compiled dynamically with a more advanced optimizing compiler for peak performance. In V8, this script execution pipeline has a variety of special cases and conditions which require complex machinery to switch between the baseline compiler and two optimizing compilers, Crankshaft and TurboFan.
In Chrome 53, Ignition will be enabled for Android devices which have limited RAM (512 MB or less), where memory savings are most needed. Results from early experiments in the field show that Ignition reduces the memory of each Chrome tab by around 5%.
|V8’s compilation pipeline with Ignition enabled.|
In building Ignition’s bytecode interpreter, the team considered a number of potential implementation approaches. A traditional interpreter, written in C++ would not be able to interact efficiently with the rest of V8’s generated code. An alternative would have been to hand-code the interpreter in assembly code, however given V8 supports nine architecture ports, this would have entailed substantial engineering overhead.
Instead, we opted for an approach which leveraged the strength of TurboFan, our new optimizing compiler, which is already tuned for optimal interaction with the V8 runtime and other generated code. The Ignition interpreter uses TurboFan’s low-level, architecture-independent macro-assembly instructions to generate bytecode handlers for each opcode. TurboFan compiles these instructions to the target architecture, performing low-level instruction selection and machine register allocation in the process. This results in highly optimized interpreter code which can execute the bytecode instructions and interact with the rest of the V8 virtual machine in a low-overhead manner, with a minimal amount of new machinery added to the codebase.
As the bytecode is generated, it passes through a series of inline-optimization stages. These stages perform simple analysis on the bytecode stream, replacing common patterns with faster sequences, remove some redundant operations, and minimize the number of unnecessary register loads and transfers. Together, the optimizations further reduce the size of the bytecode and improve performance.
For further details on the implementation of Ignition, see our BlinkOn talk:
Our focus for Ignition up until now has been to reduce V8’s memory overhead. However, adding Ignition to our script execution pipeline opens up a number of future possibilities. The Ignition pipeline has been designed to enable us to make smarter decisions about when to execute and optimize code to speed up loading web pages and reduce jank and to make the interchange between V8’s various components more efficient.
Stay tuned for future developments in Ignition and V8.
by Ross McIlroy, V8 Ignition Jump Starter