Native code compilation

All methods are compiled before being executed. At first, the method is "compiled" to a stub that calls the most basic compiler and then invokes the compiled code.

Better compilers are invoked when the VM detects that a method is invoked often. These compilers perform more optimizations.

L2 Compiler Phases

The L2 compiler operates in four phases:

1. Generate intermediate representation (IR)
2. Perform second pass optimizations (pass2)
3. Register allocation
4. Generate native code

The first phase parses bytecodes and generates a set of Quads. This phase also performs simple optimizations, such as copy propagation and constant folding.

Pass2 simplifies operands and tries to eliminate dead code.

Register allocation is an attempt to assign live variable ranges to available machine registers. As register access is significantly faster than memory access, register allocation is an important optimization technique. In general, it is not always possible to assign all live variable ranges to machine registers. Variables that cannot be allocated to registers are said to be 'spilled' and must reside in memory.

Code is generated by iterating over the set of IR quads and producing machine instructions.