V8_Meetup
Transcript of V8_Meetup
Turbocharging JavaScript: V8
Rahul DéCompiler Junkie @ThoughtWorks
ProblemFind the 25, 000th Prime number
JavaScript
The LanguageInvented by Brendan Eich at Mozilla Research.
Defined by the ECMA 262 Standard - ECMAScript 6.
Dynamically Typed.
Duck Typing.
Prototype and Object based.
Asynchrony is a language feature.
Functions are first class citizens.
Has its fair share of the Good, the Bad and the Ugly.
Implementing the Good, Bad and the Ugly.
Major JavaScript Implementations
SpiderMonkey, IonMonkey and JägerMonkey JIT compilers by Mozilla powering Firefox.
V8 by Google powering the Chromium family of Browsers, Opera, Node.js, MongoDB etc.
JSCore by Apple powering Safari and WebKit based browsers.
Rhino/Nashorn by Mozilla Research and Oracle implement JavaScript in the JVM.
Fully Compiled Languages
C, C++, Pascal, Fortan etc…
Tokenizer Parser Optimiz
erGramm
ar
Code Gen
Assembly Code
Tokens AST IR
Abstract Syntax Treehttp://jointjs.com/demos/javascript-ast
Intermediate Representation
int a = 5;int b = 10;
int c = a + b;
stor a, 5mov r1, astor b, 10
mov r2, 10add r1, r2store c, r1
Assembly Language
mov rax, 05Hmov rbx, 0AHadd rax, rbx
mov rax, [1000]
Partly Compiled LanguagesJava, Python, Ruby
etc.
Tokenizer Parser Optimiz
erGramm
ar
Code Gen Byte Code
Tokens AST
VM
Byte Codes
a = 5;b = 10;
c = a + b;
iconst 5set a
iconst 10set b
push apush b
addset c
Virtual Machines
Stack VM - JVM, Python VM, Ruby VM(YARV) etc.
Register VM - Dalvik VM, Lua VM, LLVM etc.
Running Byte codesiconst 5
set aiconst 10
set bpush apush b
addset c
5pop10popa
a ba + bpop
a = 5
b = 10
c = 15
Problems??A full program executes them
Lot of context switching
A big switch case to dispatch the byte codes
Big libs to handle the ops
But, necessary as its a dynamic language and makes it cross platform
JIT VMJVM, CLR, V8
Tokenizer Parser Optimiz
erGramm
ar
Code Gen Byte Code
Tokens AST
VM JIT
JITiconst 5
set aiconst 10
set bpush apush b
addset c
mov rax, 05Hmov rbx, 0AHadd rax, rbx
mov rax, [1000]At Runtime
Whycode directly executes on CPU hence MUCH faster
no need of complex slow code to dispatch byte codes
more efficient execution with lesser machine resources used.
Enables much more runtime optimizations
but is quite difficult to implement
Can JavaScript ever be faster than C++?
FeaturesNO BYTECODES!
Full Register JIT
Advanced runtime/compile time optimizations
Highly embeddable
Implements the full ES6 spec
Architecture and Design
Compiler Full Code Gen Crankshaft
Compiler
Hydrogen DFG Lithium IR
Optimized Code Gen
Inline Caches
CompilerReads the JavaScript source.
Tokenizes, Parses and checks for syntax errors.
Produces a persistant AST or pAST.
Very VERY fast.
Full Code GenReads the AST
Blindly generates platform specific assembly code.
Generates some extra code to infer types called inline caches (IC).
Dispatches whole code to CPU directly.
Very VERY VERY fast.
Inline Caches (IC)
function add(a, b) { return a + b;}
add(5, 6)
add(“5”, 6)add(“Rahul”, “Dé”)
int, int -> intstr, int -> strstr, str -> str
asm1asm2asm3
Call Sites
Crankshaft CompilerProfiles the CPU performance via a thread.
Gathers type info from the ICs.
Generates the Hydrogen representation for advanced optimizations
From that generates platform specific Lithium IR for register allocation with more optimizations.
Finally super fast, optimized assembly is generated and is set free on the CPU.
De-optimizes wrongly optimized code to full code gen level.
Crankshaft is slower than others as it does a lot of analysis.
Hydrogen DFGDerived from type info from the ICs.
Is a Acyclic Data Flow Graphical Representation of the pAST.
Enables advanced optimizations like hotspots, unreachable code, peep hole, loop invariant code motions etc.
Used to generate the platform specific Lithium code.
Lithium IRIs a three address register representation of the Hydrogen DFG
Enables low level optimizations like register reduction
Maps exactly to the underlying architecture to maximize faster code gen.
Used to generate the fast optimized native assembly code.
Possible Future of V8Ignition Compiler
Much faster and produces streamlined, compact byte codes which saves a lot of memory with at par perf.
Turbofan Engine
Reads the ignition byte codes and JITs directly with blazing fast speed while reducing memory footprints.
Replace the pAST, full code gen and crankshaft with the ignition and turbofan compilers.
Already in pre Alpha builds.
Can I help V8 to execute my code better??
Of course. By now you know a lot about V8. And definitely you can
now write much better code.
Writing V8 friendly JavaScript.
Hidden Classes
function Point(x, y) { this.x = x; this.y = y;}
var p1 = new Point(5, 6);var p2 = new Point(7, 8);
xy
x 5y 6
x 7y 8
Hidden Classes
var p1 = new Point(5, 6);p1.z = 4;delete p1.z;
xy
xyz
x 5y 6z 4
Performance TipsTry to use homogeneous data types in Arrays.
Pre allocate arrays if non homogeneous data is needed.
Avoid pushing non homogenous types like bools into int arrays.
Initialize Function objects instead of pushing in attributes later on.
Catch blocks are not crankshaft optimizable, write the catch code in a function and call it from the catch block.
Turbocharging JavaScript
Fixing the ProblemFind the 25, 000th Prime number
Thank [email protected]
https://github.com/rahul080327