V8_Meetup

43
Turbocharging JavaScript: V8 Rahul Dé Compiler Junkie @ThoughtWorks

Transcript of V8_Meetup

Page 1: V8_Meetup

Turbocharging JavaScript: V8

Rahul DéCompiler Junkie @ThoughtWorks

Page 2: V8_Meetup

ProblemFind the 25, 000th Prime number

Page 3: V8_Meetup

JavaScript

Page 4: V8_Meetup

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.

Page 5: V8_Meetup

Implementing the Good, Bad and the Ugly.

Page 6: V8_Meetup

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.

Page 7: V8_Meetup

Fully Compiled Languages

C, C++, Pascal, Fortan etc…

Page 8: V8_Meetup

Tokenizer Parser Optimiz

erGramm

ar

Code Gen

Assembly Code

Tokens AST IR

Page 9: V8_Meetup

Abstract Syntax Treehttp://jointjs.com/demos/javascript-ast

Page 10: V8_Meetup

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

Page 11: V8_Meetup

Assembly Language

mov rax, 05Hmov rbx, 0AHadd rax, rbx

mov rax, [1000]

Page 12: V8_Meetup

Partly Compiled LanguagesJava, Python, Ruby

etc.

Page 13: V8_Meetup

Tokenizer Parser Optimiz

erGramm

ar

Code Gen Byte Code

Tokens AST

VM

Page 14: V8_Meetup

Byte Codes

a = 5;b = 10;

c = a + b;

iconst 5set a

iconst 10set b

push apush b

addset c

Page 15: V8_Meetup

Virtual Machines

Stack VM - JVM, Python VM, Ruby VM(YARV) etc.

Register VM - Dalvik VM, Lua VM, LLVM etc.

Page 16: V8_Meetup

Running Byte codesiconst 5

set aiconst 10

set bpush apush b

addset c

5pop10popa

a ba + bpop

a = 5

b = 10

c = 15

Page 17: V8_Meetup

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

Page 18: V8_Meetup

JIT VMJVM, CLR, V8

Page 19: V8_Meetup

Tokenizer Parser Optimiz

erGramm

ar

Code Gen Byte Code

Tokens AST

VM JIT

Page 20: V8_Meetup

JITiconst 5

set aiconst 10

set bpush apush b

addset c

mov rax, 05Hmov rbx, 0AHadd rax, rbx

mov rax, [1000]At Runtime

Page 21: V8_Meetup

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

Page 22: V8_Meetup

Can JavaScript ever be faster than C++?

Page 23: V8_Meetup
Page 24: V8_Meetup
Page 25: V8_Meetup
Page 26: V8_Meetup

FeaturesNO BYTECODES!

Full Register JIT

Advanced runtime/compile time optimizations

Highly embeddable

Implements the full ES6 spec

Page 27: V8_Meetup

Architecture and Design

Compiler Full Code Gen Crankshaft

Compiler

Hydrogen DFG Lithium IR

Optimized Code Gen

Inline Caches

Page 28: V8_Meetup

CompilerReads the JavaScript source.

Tokenizes, Parses and checks for syntax errors.

Produces a persistant AST or pAST.

Very VERY fast.

Page 29: V8_Meetup

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.

Page 30: V8_Meetup

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

Page 31: V8_Meetup

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.

Page 32: V8_Meetup

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.

Page 33: V8_Meetup

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.

Page 34: V8_Meetup

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.

Page 35: V8_Meetup

Can I help V8 to execute my code better??

Page 36: V8_Meetup

Of course. By now you know a lot about V8. And definitely you can

now write much better code.

Page 37: V8_Meetup

Writing V8 friendly JavaScript.

Page 38: V8_Meetup

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

Page 39: V8_Meetup

Hidden Classes

var p1 = new Point(5, 6);p1.z = 4;delete p1.z;

xy

xyz

x 5y 6z 4

Page 40: V8_Meetup

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.

Page 41: V8_Meetup

Turbocharging JavaScript

Page 42: V8_Meetup

Fixing the ProblemFind the 25, 000th Prime number