Optimizing Javascript
Michael Stanton
- Google V8: Compiler Team/Manager
- V8: ICs and Feedback Vectors
- Cats, climbing and old typewriters :p
V8 Team, based in Munich
- ~25 people
- A few in San Francisco and London
We work on Chromium
- Open source
- Branded also as "Chrome"
- Chromium is huge - we only know a part!
V8 has many features
- "Hidden Classes"
- ICs (Inline caches) - how we learn
- Generational Garbage Collector
- Pipelined Architecture
Compilation pipeline with learning
Source
Code
Ignition
Byte
Code
Run for a while
Gather feedback
Google proprietary
Compilation pipeline with learning
Source
Code
Ignition
Turbofan
Byte
Code
Optimized
Code
Google proprietary
Compilation pipeline with learning
Source
Code
Ignition
Turbofan
Byte
Code
Optimized
Code
Deoptimization
Google proprietary
TurboFan
- The "Last Step" in the Pipeline
- Inlining
- Allocation Folding
- Escape Analysis
- Load Elimination
- Write Barrier Elimination
- etc!
Inlining
function bar(a) {
return a + 3;
}
function foo(x) {
return bar(5) + x;
}
Inlining "bar" into "foo"
function bar(a) {
return a + 3;
}
function foo(x) {
return 5 + 3 + x;
}
Inlining "bar" into "foo"
function bar(a) {
return a + 3;
}
function foo(x) {
return 8 + x;
}
Questions to ask when inlining
- Which functions are important?
- To what depth?
- You can do too much...
Array.Prototype.Map
// one of many array "built-ins"
let a = [1, 2, 3];
let mult = x => x * 2;
a.map(mult);
// prints 2, 4, 6
Array.Prototype.Map
// If you wrote it by hand...
let a = [1, 2, 3];
let mult = x => x * 2;
let b = [];
for (let i = 0; i < a.length; i++) {
b[i] = mult(a[i], i, a);
}
// b is [2, 4, 6]
We can inline Array builtins
- We know exactly what the function does
- If we ALSO inline the predicate function, we can really benefit
- Technical challenge: deoptimization in the middle of the work
Array.Prototype.Map inlining
// Consider this case...
let a = [1, 2, 3];
let mult = x => x * 2;
function foo() {
return a.map(mult);
}
Array.Prototype.Map inlining
// Consider this case...
let a = [1, 2, 3];
let mult = x => x * 2;
function foo() {
// we inlined Array.map!
let b = [];
for (let i = 0; i < a.length; i++) {
b[i] = mult(a[i]);
}
return b;
}
Array.Prototype.Map inlining
// Consider this case...
let a = [1, 2, 3];
let mult = x => x * 2;
function foo() {
// we inlined Array.map...also mult.
let b = [];
for (let i = 0; i < a.length; i++) {
b[i] = a[i] * 2;
}
return b;
}
Performance "cliffs"
- Messing with the array prototype...
- Mixing floating point numbers and integers
- etc.
Array.Prototype changes
// Arrays can have "holes"
let a = [1, , 3];
a[1];
// prints undefined
// holes "see through" to
// the prototype
Array.prototype[1] = 'oh hai';
a[1];
// oh hai :/
Questions?
Google proprietary
Shameless plug
Geektime
By ripsawridge
Geektime
Google Chrome V8
- 1,282