9. JägerMonkey
• x+y
• Is x int32?
• Yes: Is y int32?
• Yes: add, check overflow
• No: Is y double?
• Yes: Convert x to double, add
• No: ...
10. IonMonkey Goals
• Clean architecture
• Typed compilation
• Fastest JS
• Shoot lasers from space
11. Architecture Goals
• Ion looks like a textbook compiler
• IRs, CFGs, blah blah
• Passes are easy to add, remove, debug
• Platform for future research and
experimentation
15. Astronaut View
IR
Optimization
Register Allocation
Code Generation
16. MIR
• Middle-level IR in SSA form
• Actual control-flow graph built from
SpiderMonkey bytecode
• Single pass, yields semi-pruned SSA
• Φs pruned in second pass
17. MIR Typing
• Ion has a “type oracle” interface
• MIR builds SSA based on oracle results
• TypeInference provides an oracle
implementation
20. MIR Pre-Optimization
• MIR is untyped, but annotated with hints
x y
Unbox(x, INT32) Unbox(x, INT32)
add-i32(x2, y2)
21. MIR Optimizations
• Global Value Numbering
• Constant folding
• Redundancy elimination
• Loop Invariant Code Motion
22. LIR
• Low-level IR, also SSA
• Per-architecture differentiation
• MIR is transformed to LIR in a single pass
• LIR specifies register policies
23. Two Register Allocators
• Greedy
• Fast runtime, poor results
• Linear Scan
• Slow runtime, good results
• “Linear Scan Register Allocation on SSA
Form” (Wimmer et al)
24. Code Generation
• New macro assembler interface
• One codegen function per LIR, per $ARCH
• Code is managed by GC
25. Ion Frames
• Ion code runs in its own frames, on the C
stack - no js::StackFrame!
• VM has limited interface to ask questions
about Ion frames
28. Example Codegen
cmp [esp+0x10], INT32
Unbox jne _bailout
mov [esp+0x14] -> ecx
cmp [esp+0x18], INT32
Unbox jne _bailout
mov [esp+0x1C] -> edx
Add add edx -> ecx
jo _bailout
Return mov INT32 -> edx
ret
29. Bailouts
• Guards indicate an assumption that must
hold for JIT code to continue running
• If a guard fails, the current Ion frame is
converted to a js::StackFrame
• Execution continues in the interpreter
30. Resume Points
• Can only resume at certain points:
• Beginning of a basic block
• After the result of a non-idempotent
operation has been pushed
• We might re-run a few idempotent
operations
31. Resume Points
function f(x, y) {
var ret = 0;
for (var i = 0; i < 100000; i++) {
if (...)
...
ret += x + y;
}
...
}
32. Resume Points
function f(x, y) {
var ret = 0;
for (var i = 0; i < 100000; i++) {
if (...)
...
ret += x + y;
}
...
}
33. Snapshots
• Describe how to convert an Ion frame to
an interpreter frame
• Compressed map of registers/stack
• No need to actively maintain interpreter
state
34. On the Horizon
• ARM
• Type Inference
• Method Inlining
• Inline Caching
• On-Stack Replacement