javascript and v8rossberg/papers/cefp-11.pdf · 2011-07-01 · first-class functions function...
TRANSCRIPT
![Page 1: JavaScript and V8rossberg/papers/CEFP-11.pdf · 2011-07-01 · First-class functions function adder(x) {return function(y) { return x + y }} function makeCounter() {var i = 0 return](https://reader036.vdocuments.us/reader036/viewer/2022062915/5ea56c1d96f795609a33871f/html5/thumbnails/1.jpg)
JavaScript and V8A functional-ish language and implementation in the mainstream
Andreas Rossberg, Google [email protected] 2011, Budapest
![Page 2: JavaScript and V8rossberg/papers/CEFP-11.pdf · 2011-07-01 · First-class functions function adder(x) {return function(y) { return x + y }} function makeCounter() {var i = 0 return](https://reader036.vdocuments.us/reader036/viewer/2022062915/5ea56c1d96f795609a33871f/html5/thumbnails/2.jpg)
Outline
JavaScript
Background
Functional concepts
V8
Inline Caching
Crankshaft
![Page 3: JavaScript and V8rossberg/papers/CEFP-11.pdf · 2011-07-01 · First-class functions function adder(x) {return function(y) { return x + y }} function makeCounter() {var i = 0 return](https://reader036.vdocuments.us/reader036/viewer/2022062915/5ea56c1d96f795609a33871f/html5/thumbnails/3.jpg)
JavaScript
Originally just a language for scripting Netscape
Now the lingua franca of the web
Increasingly used on the server-side as well
cf. the hype around node.js
Dozens of compilers have JS back-ends
More applications written in JS these days than in any other language!
![Page 4: JavaScript and V8rossberg/papers/CEFP-11.pdf · 2011-07-01 · First-class functions function adder(x) {return function(y) { return x + y }} function makeCounter() {var i = 0 return](https://reader036.vdocuments.us/reader036/viewer/2022062915/5ea56c1d96f795609a33871f/html5/thumbnails/4.jpg)
JavaScript Applications
Large applications are written in JavaScript
GMail consists of ~1Mloc
Performance-relevant ones, too!
Angry Birds, now natively in JS/HTML5 :-)
Mandreel, a game development framework that compiles existing C++/OpenGL code to JS/WebGL
Emscripten, LLVM to JS compiler that can run Doom
jslinux, a software x86 PC emulator that can boot Linux
![Page 5: JavaScript and V8rossberg/papers/CEFP-11.pdf · 2011-07-01 · First-class functions function adder(x) {return function(y) { return x + y }} function makeCounter() {var i = 0 return](https://reader036.vdocuments.us/reader036/viewer/2022062915/5ea56c1d96f795609a33871f/html5/thumbnails/5.jpg)
First-class functions
function adder(x) { return function(y) { return x + y }}
function makeCounter() { var i = 0 return function() { return ++i }}
function curry2(f) { return function(x) { return function(y) { return f(x, y) } }}
![Page 6: JavaScript and V8rossberg/papers/CEFP-11.pdf · 2011-07-01 · First-class functions function adder(x) {return function(y) { return x + y }} function makeCounter() {var i = 0 return](https://reader036.vdocuments.us/reader036/viewer/2022062915/5ea56c1d96f795609a33871f/html5/thumbnails/6.jpg)
Higher-order functions
var a = [3, 0, -4, 5, 10]
var sum = a.reduce(function(x, y) { return x + y }, 0)
var b = a.filter(function(x) { return x >= 0 }) .map(Math.sqrt) .sort (function(x, y) { return y - x })
b.forEach(print)
![Page 7: JavaScript and V8rossberg/papers/CEFP-11.pdf · 2011-07-01 · First-class functions function adder(x) {return function(y) { return x + y }} function makeCounter() {var i = 0 return](https://reader036.vdocuments.us/reader036/viewer/2022062915/5ea56c1d96f795609a33871f/html5/thumbnails/7.jpg)
Objects as records-of-closures
function Point(x, y) { this.getX = function() { return x } this.getY = function() { return y } this.move = function(dx, dy) { x += dx; y += dy }}
var p = new Point(3, 4)p.move(-5, +1)
![Page 8: JavaScript and V8rossberg/papers/CEFP-11.pdf · 2011-07-01 · First-class functions function adder(x) {return function(y) { return x + y }} function makeCounter() {var i = 0 return](https://reader036.vdocuments.us/reader036/viewer/2022062915/5ea56c1d96f795609a33871f/html5/thumbnails/8.jpg)
Functional Encapsulation
(function() { // do or compute stuff... return result})()
![Page 9: JavaScript and V8rossberg/papers/CEFP-11.pdf · 2011-07-01 · First-class functions function adder(x) {return function(y) { return x + y }} function makeCounter() {var i = 0 return](https://reader036.vdocuments.us/reader036/viewer/2022062915/5ea56c1d96f795609a33871f/html5/thumbnails/9.jpg)
Continuation-passingfunction post(url, data, callback) { var client = http.createClient(url.port, url.hostname) var request = client.request("POST", url.pathname, ...) request.write(data) request.end() request.on("response", function(response) { var body = "" request.on("data", function(chunk) { body += chunk }) request.on("end", function() { callback(response.statusCode, body) }) })}
![Page 10: JavaScript and V8rossberg/papers/CEFP-11.pdf · 2011-07-01 · First-class functions function adder(x) {return function(y) { return x + y }} function makeCounter() {var i = 0 return](https://reader036.vdocuments.us/reader036/viewer/2022062915/5ea56c1d96f795609a33871f/html5/thumbnails/10.jpg)
Continuation-passing
ioThis(theseArgs, function(thisResult) { ioThat(thoseArgs, function(thatResult) { ioYonder(yonderArgs, function(yonderResult) { // ... }) })})
![Page 11: JavaScript and V8rossberg/papers/CEFP-11.pdf · 2011-07-01 · First-class functions function adder(x) {return function(y) { return x + y }} function makeCounter() {var i = 0 return](https://reader036.vdocuments.us/reader036/viewer/2022062915/5ea56c1d96f795609a33871f/html5/thumbnails/11.jpg)
The Not-so-functional
Statements vs expressions, C-like syntax
Everything is mutable for everybody
Emphasis on object-oriented programming
Weak type structure
Parts were “designed” in a semantics-free space
But things will improve significantly with EcmaScript 6 (due 2013)
![Page 12: JavaScript and V8rossberg/papers/CEFP-11.pdf · 2011-07-01 · First-class functions function adder(x) {return function(y) { return x + y }} function makeCounter() {var i = 0 return](https://reader036.vdocuments.us/reader036/viewer/2022062915/5ea56c1d96f795609a33871f/html5/thumbnails/12.jpg)
The Bad: Scoping
function f(n) { for (i = 0; i < n; ++i) { // do something... }}
function g() { for (i = 0; i < 100; ++i) { f(10) }}
// oops, introduces global variable!
// double oops, never terminates!
![Page 13: JavaScript and V8rossberg/papers/CEFP-11.pdf · 2011-07-01 · First-class functions function adder(x) {return function(y) { return x + y }} function makeCounter() {var i = 0 return](https://reader036.vdocuments.us/reader036/viewer/2022062915/5ea56c1d96f795609a33871f/html5/thumbnails/13.jpg)
The Bad: “this”
var myObject = { value: 5, output: function() { print(this.value) }}
myObject.output()myObject.output()myObject.output()
![Page 14: JavaScript and V8rossberg/papers/CEFP-11.pdf · 2011-07-01 · First-class functions function adder(x) {return function(y) { return x + y }} function makeCounter() {var i = 0 return](https://reader036.vdocuments.us/reader036/viewer/2022062915/5ea56c1d96f795609a33871f/html5/thumbnails/14.jpg)
The Bad: “this”
var myObject = { value: 5, output: function() { print(this.value) }}
var f = myObject.outputf(); f(); f() // oops, prints “undefined”!?!?
![Page 15: JavaScript and V8rossberg/papers/CEFP-11.pdf · 2011-07-01 · First-class functions function adder(x) {return function(y) { return x + y }} function makeCounter() {var i = 0 return](https://reader036.vdocuments.us/reader036/viewer/2022062915/5ea56c1d96f795609a33871f/html5/thumbnails/15.jpg)
The Stupefying:“arguments”, “caller”, “callee”
function f(x) { g() return x}
f(42)
function g() { f.arguments[0] = 666}
// wtf?!?
![Page 16: JavaScript and V8rossberg/papers/CEFP-11.pdf · 2011-07-01 · First-class functions function adder(x) {return function(y) { return x + y }} function makeCounter() {var i = 0 return](https://reader036.vdocuments.us/reader036/viewer/2022062915/5ea56c1d96f795609a33871f/html5/thumbnails/16.jpg)
The Stupefying:“arguments”, “caller”, “callee”
function h() { h.caller.caller.arguments[1] = "boo!"}
// Please don’t ever call this function,// your callers will thank you!
![Page 17: JavaScript and V8rossberg/papers/CEFP-11.pdf · 2011-07-01 · First-class functions function adder(x) {return function(y) { return x + y }} function makeCounter() {var i = 0 return](https://reader036.vdocuments.us/reader036/viewer/2022062915/5ea56c1d96f795609a33871f/html5/thumbnails/17.jpg)
V8
Google’s open source virtual machine for JavaScript
used in Chrome and other environments (e.g. Android, node.js)
no interpreter, just-in-time compilation through-out
two compilers: “full” and optimizing (aka Crankshaft)
adaptive optimization in Crankshaft
![Page 18: JavaScript and V8rossberg/papers/CEFP-11.pdf · 2011-07-01 · First-class functions function adder(x) {return function(y) { return x + y }} function makeCounter() {var i = 0 return](https://reader036.vdocuments.us/reader036/viewer/2022062915/5ea56c1d96f795609a33871f/html5/thumbnails/18.jpg)
V8 Performance (early days)
![Page 19: JavaScript and V8rossberg/papers/CEFP-11.pdf · 2011-07-01 · First-class functions function adder(x) {return function(y) { return x + y }} function makeCounter() {var i = 0 return](https://reader036.vdocuments.us/reader036/viewer/2022062915/5ea56c1d96f795609a33871f/html5/thumbnails/19.jpg)
The ProblemJavaScript is a “dynamic” language
...which means that every primitive operation is expensive
For example: field lookup is (very!) expensive, due to
untyped objects, dynamic field names, dynamic field addition & removal, mutable inheritance chain, arrays as objects, interceptors...
Likewise, many other operations:
field access, global variable access, array access, stores,function calls, overloaded operators, conversions,other builtin functions...
![Page 20: JavaScript and V8rossberg/papers/CEFP-11.pdf · 2011-07-01 · First-class functions function adder(x) {return function(y) { return x + y }} function makeCounter() {var i = 0 return](https://reader036.vdocuments.us/reader036/viewer/2022062915/5ea56c1d96f795609a33871f/html5/thumbnails/20.jpg)
Inline Caching
Solution: cache lookup path for given object type
In fact, do it inline in generated code
Self-modifying code!
Originally invented in the context of Smalltalk[Deutsch & Schiffmann POPL’84]
V8 was first JavaScript VM to employ it
Requires efficient structural type checks (“maps”)
![Page 21: JavaScript and V8rossberg/papers/CEFP-11.pdf · 2011-07-01 · First-class functions function adder(x) {return function(y) { return x + y }} function makeCounter() {var i = 0 return](https://reader036.vdocuments.us/reader036/viewer/2022062915/5ea56c1d96f795609a33871f/html5/thumbnails/21.jpg)
Maps
function Point(x, y) { this.x = x this.y = y}
var p = new Point(3, 4)p.y
pmap 0
map 1
map 2
“x” ↦ 0
“x” ↦ 0“y” ↦ 1
34
>>
>>
+”x”
+”y”
Point
>
![Page 22: JavaScript and V8rossberg/papers/CEFP-11.pdf · 2011-07-01 · First-class functions function adder(x) {return function(y) { return x + y }} function makeCounter() {var i = 0 return](https://reader036.vdocuments.us/reader036/viewer/2022062915/5ea56c1d96f795609a33871f/html5/thumbnails/22.jpg)
Maps
function Point(x, y) { this.x = x this.y = y}
var p = new Point(3, 4)p.yvar q = new Point(1, 1)
qmap 0
map 1
map 2
“x” ↦ 0
“x” ↦ 0“y” ↦ 1
11
>>
>
+”x”
+”y”
Point
![Page 23: JavaScript and V8rossberg/papers/CEFP-11.pdf · 2011-07-01 · First-class functions function adder(x) {return function(y) { return x + y }} function makeCounter() {var i = 0 return](https://reader036.vdocuments.us/reader036/viewer/2022062915/5ea56c1d96f795609a33871f/html5/thumbnails/23.jpg)
Inline Caching
...p.y...
Runtime::Load:
1. looks up p.y in a slow but generic manner,2. generates a lookup stub specialized for y and map2,3. patches its caller’s call instruction to target the stub.
Source
...mov eax, pmov ebx, ycall Runtime::Load...
Machine code
cmp [eax], map2jne Runtime::Loadmov eax, [eax + 4]mov eax, [eax + 8]ret
Stub (cached)
![Page 24: JavaScript and V8rossberg/papers/CEFP-11.pdf · 2011-07-01 · First-class functions function adder(x) {return function(y) { return x + y }} function makeCounter() {var i = 0 return](https://reader036.vdocuments.us/reader036/viewer/2022062915/5ea56c1d96f795609a33871f/html5/thumbnails/24.jpg)
Runtime::Load:
1. looks up p.y in a slow but generic manner,2. generates a lookup stub specialized for y and map2,3. patches its caller’s call instruction to target the stub.
Inline Caching
...p.y...
...mov eax, pmov ebx, ycall stub...
Source Machine code
cmp [eax], map2jne Runtime::Loadmov eax, [eax + 4]mov eax, [eax + 8]ret
Stub (cached)
![Page 25: JavaScript and V8rossberg/papers/CEFP-11.pdf · 2011-07-01 · First-class functions function adder(x) {return function(y) { return x + y }} function makeCounter() {var i = 0 return](https://reader036.vdocuments.us/reader036/viewer/2022062915/5ea56c1d96f795609a33871f/html5/thumbnails/25.jpg)
Crankshaft
Separate, optimizing backend for V8 (Chrome 10+)
Used only for hot paths through hot functions
Based on statistical profiling and type feedback
Type information harvested directly from stub code!
Inlines IC code stubs
...which enables a lot of additional optimizations
Deoptimization upon type miss
![Page 26: JavaScript and V8rossberg/papers/CEFP-11.pdf · 2011-07-01 · First-class functions function adder(x) {return function(y) { return x + y }} function makeCounter() {var i = 0 return](https://reader036.vdocuments.us/reader036/viewer/2022062915/5ea56c1d96f795609a33871f/html5/thumbnails/26.jpg)
Inline Caching
cmp [eax], map2jne Runtime::Loadmov eax, [eax + 4]mov eax, [eax + 8]ret
...p.y...
Source
...mov eax, pmov ebx, ycall stub...
Machine code Stub (cached)
![Page 27: JavaScript and V8rossberg/papers/CEFP-11.pdf · 2011-07-01 · First-class functions function adder(x) {return function(y) { return x + y }} function makeCounter() {var i = 0 return](https://reader036.vdocuments.us/reader036/viewer/2022062915/5ea56c1d96f795609a33871f/html5/thumbnails/27.jpg)
Optimized Code
cmp [eax], map2jne Runtime::Loadmov eax, [eax + 4]mov eax, [eax + 8]ret
...p.y...
Source...mov eax, pcmp [eax], map2jne Runtime::Deoptmov eax, [eax + 4]mov eax, [eax + 8]...
Optimized machine code Stub (cached)
Runtime::Deopt:
1. discards optimized code for entire function,2. (lazily) rewrites all active stack frames for that function,3. jumps to corresponding point in unoptimized code.
![Page 28: JavaScript and V8rossberg/papers/CEFP-11.pdf · 2011-07-01 · First-class functions function adder(x) {return function(y) { return x + y }} function makeCounter() {var i = 0 return](https://reader036.vdocuments.us/reader036/viewer/2022062915/5ea56c1d96f795609a33871f/html5/thumbnails/28.jpg)
IC Statesuninitalized
initialized
monomorphic
polymorphic
megamorphic
first execution
N executionsmiss
2..M different misses
more than M misses
![Page 29: JavaScript and V8rossberg/papers/CEFP-11.pdf · 2011-07-01 · First-class functions function adder(x) {return function(y) { return x + y }} function makeCounter() {var i = 0 return](https://reader036.vdocuments.us/reader036/viewer/2022062915/5ea56c1d96f795609a33871f/html5/thumbnails/29.jpg)
The Big Picture
source function
unoptimizedmachine code
Runtime::Load
IC stub
optimizedmachine code
Runtime::Deopt
IC stub
IC stub
calls(upon deopt)
compiles
to
compiles to
(when hot)ca
lls
calls
calls
calls
calls
patc
hes
patches
generates
JS source code
generated machine code
C++ runtime code
![Page 30: JavaScript and V8rossberg/papers/CEFP-11.pdf · 2011-07-01 · First-class functions function adder(x) {return function(y) { return x + y }} function makeCounter() {var i = 0 return](https://reader036.vdocuments.us/reader036/viewer/2022062915/5ea56c1d96f795609a33871f/html5/thumbnails/30.jpg)
Summary
JavaScript is the most used functional-ish language
Vital to web infrastructure, increasing server-side use
V8 repeatedly raised bar for JS performance
Uses advanced dynamic compilation techniques
http://code.google.com/p/v8