Transcript
Page 1: JavaScript Engines: Under the Hood

Monday, November 29, 2010

Page 2: JavaScript Engines: Under the Hood

JavaScript EnginesUnder the Hood

ARIYA HIDAYATENGINEERING DIRECTOR, SENCHA

Monday, November 29, 2010

Page 3: JavaScript Engines: Under the Hood

Get It

See It

Tweak It

JavaScript Engines

Monday, November 29, 2010

Page 4: JavaScript Engines: Under the Hood

JavaScript Engines

Monday, November 29, 2010

Page 5: JavaScript Engines: Under the Hood

SpiderMonkeyJavaScriptCore

V8

JavaScript Engines

Open

Opera CarakanMicrosoft JScript...

Closed

Monday, November 29, 2010

Page 6: JavaScript Engines: Under the Hood

SpiderMonkeyJavaScriptCore

V8

JavaScript Engines

Open

Monday, November 29, 2010

Page 7: JavaScript Engines: Under the Hood

SpiderMonkeyFirst JavaScript enginecreated by Brendan Eich

Written in CMostly used in Mozilla, Firefox, ...

License: MPL/LGPL/GPL

Monday, November 29, 2010

Page 8: JavaScript Engines: Under the Hood

JavaScriptCore (JSC)Built into WebKitForked from KDE’s KJS a long time ago

License: LGPL

Monday, November 29, 2010

Page 9: JavaScript Engines: Under the Hood

Other Names of JSCSquirrelFishbyte-code interpreter

SquirrelFish Extreme (SFX)native/machine code

Nitro, Nitro ExtremeApple’s marketing terms

Monday, November 29, 2010

Page 10: JavaScript Engines: Under the Hood

Google V8Written in C++License: BSD

Used in Chromium (Google Chrome)

Monday, November 29, 2010

Page 11: JavaScript Engines: Under the Hood

Qt ScriptUses JSC as the back-endDoes not power any web browser

Powerful bindings, debuggerUseful to make applications scriptable

Monday, November 29, 2010

Page 12: JavaScript Engines: Under the Hood

Let’s Go UNDER THE HOOD

Monday, November 29, 2010

Page 13: JavaScript Engines: Under the Hood

Let’s Go UNDER THE HOOD

Platform +Compiler

Monday, November 29, 2010

Page 14: JavaScript Engines: Under the Hood

Monday, November 29, 2010

Page 15: JavaScript Engines: Under the Hood

Get the real V8

svn checkout http://v8.googlecode.com/svn/trunk v8cd v8

git clone git://github.com/v8/v8.git v8cd v8

Monday, November 29, 2010

Page 16: JavaScript Engines: Under the Hood

Build V8

scons sample=shell mode=release snapshot=on

Monday, November 29, 2010

Page 17: JavaScript Engines: Under the Hood

Build V8

scons sample=shell mode=release snapshot=on

--jobs 4

Monday, November 29, 2010

Page 18: JavaScript Engines: Under the Hood

Build V8

scons sample=shell mode=release snapshot=on

--jobs 4

arch=x64

Monday, November 29, 2010

Page 19: JavaScript Engines: Under the Hood

perl sunspider --shell=/path/to/v8/directory/shell --args=-expose-gc

Run your-favorite-benchmark

Monday, November 29, 2010

Page 20: JavaScript Engines: Under the Hood

perl sunspider --shell=/path/to/v8/directory/shell --args=-expose-gc

Run your-favorite-benchmark

garbage collector

Monday, November 29, 2010

Page 21: JavaScript Engines: Under the Hood

Let’s Get DIRTY

Monday, November 29, 2010

Page 22: JavaScript Engines: Under the Hood

Building Blocks

Parser

Interpreter

Runtime

Monday, November 29, 2010

Page 23: JavaScript Engines: Under the Hood

Parser

Monday, November 29, 2010

Page 24: JavaScript Engines: Under the Hood

Tokenize

var answer = 42;

Monday, November 29, 2010

Page 25: JavaScript Engines: Under the Hood

Tokenize

var answer = 42;keyword equal sign

semicolon

identifier number

Monday, November 29, 2010

Page 26: JavaScript Engines: Under the Hood

>>>

>>>

Look Ahead

greater than

right shift

zero-filled right shift

Monday, November 29, 2010

Page 27: JavaScript Engines: Under the Hood

>>>

>>>

Look Ahead

greater than

right shift

zero-filled right shift

>=>>=>>>=

Monday, November 29, 2010

Page 28: JavaScript Engines: Under the Hood

Tokenizer on V8

src/scanner.*

Monday, November 29, 2010

Page 29: JavaScript Engines: Under the Hood

Tokenizer on V8

src/scanner.*

hand-writtenstate machine

Monday, November 29, 2010

Page 30: JavaScript Engines: Under the Hood

Keyword vs Identifier

instanceof instanceComponent

requires checking 9 chars

Monday, November 29, 2010

Page 31: JavaScript Engines: Under the Hood

Keyword vs Identifier

instanceof instanceComponent

requires checking 9 chars

a g h j k l m o p q x y zMonday, November 29, 2010

Page 32: JavaScript Engines: Under the Hood

Grammar

SourceElement :: (Statement)*

FunctionDeclaration :: 'function' Identifier '(' FormalParameters ')' '{' FunctionBody '}'

Monday, November 29, 2010

Page 33: JavaScript Engines: Under the Hood

Syntax Tree

Variable Declaration

IdentifierLiteral Constant

answer 42Monday, November 29, 2010

Page 34: JavaScript Engines: Under the Hood

Another Syntax Tree

Condition Consequent

age < 25 “young”

Alternate

“old”

Branch

Monday, November 29, 2010

Page 35: JavaScript Engines: Under the Hood

Parser on V8

src/parser.*

Monday, November 29, 2010

Page 36: JavaScript Engines: Under the Hood

Parser on V8

src/parser.*

hand-writtenrecursive descent

Monday, November 29, 2010

Page 37: JavaScript Engines: Under the Hood

Code Trace

Script::Compile

Script::New

internal::Compiler::Compile

internal::MakeFunctionInfo

internal::ParserApi::Parse

Monday, November 29, 2010

Page 38: JavaScript Engines: Under the Hood

Interpreter

Monday, November 29, 2010

Page 39: JavaScript Engines: Under the Hood

From Code to Execution

Declare a local objectCall it “answer”

Create a (small integer) number 42Assign it to “answer”

var answer = 42;

Monday, November 29, 2010

Page 40: JavaScript Engines: Under the Hood

Traverse and Run

Variable Declaration

IdentifierLiteral Constant

answer 42Monday, November 29, 2010

Page 41: JavaScript Engines: Under the Hood

Bytecode

Serialize tree traversal intoa list of “actions”

Monday, November 29, 2010

Page 42: JavaScript Engines: Under the Hood

Machine Code

Compile the bytecodes intomachine instructions

Monday, November 29, 2010

Page 43: JavaScript Engines: Under the Hood

Machine Code

JIT (=just-in-time) compile

Compile the bytecodes intomachine instructions

Monday, November 29, 2010

Page 44: JavaScript Engines: Under the Hood

Machine Code on V8

shell_g --print-code

Global

When needed

shell_g --expose-debug-as deb

Monday, November 29, 2010

Page 45: JavaScript Engines: Under the Hood

Machine Code on V8

shell_g --print-code

Global

When needed

shell_g --expose-debug-as deb

deb.Debug.disassemble(f)

Monday, November 29, 2010

Page 46: JavaScript Engines: Under the Hood

“Lazy” Approach

foobar = function(x, y, z){....}

foobar(x, y, z);

Monday, November 29, 2010

Page 47: JavaScript Engines: Under the Hood

“Lazy” Approach

foobar = function(x, y, z){....}

foobar(x, y, z);

Analyze the syntaxMark the position of

function ‘foobar’

Monday, November 29, 2010

Page 48: JavaScript Engines: Under the Hood

“Lazy” Approach

foobar = function(x, y, z){....}

foobar(x, y, z);

Analyze the syntaxMark the position of

function ‘foobar’

Compile and run the function ‘foobar’

Monday, November 29, 2010

Page 49: JavaScript Engines: Under the Hood

Runtime

Monday, November 29, 2010

Page 50: JavaScript Engines: Under the Hood

Date.now()

JavaScriptworld

“native”world

Monday, November 29, 2010

Page 51: JavaScript Engines: Under the Hood

Let’s GoOFF ROAD

Monday, November 29, 2010

Page 52: JavaScript Engines: Under the Hood

Bridge

Monday, November 29, 2010

Page 53: JavaScript Engines: Under the Hood

V8 Embedder’s Guide

http://code.google.com/apis/v8/embed.htmlMonday, November 29, 2010

Page 54: JavaScript Engines: Under the Hood

Handle: Local vs Persistent

{ HandleScope scope;

Handle<Value> foobar = .... .... ....}

Monday, November 29, 2010

Page 55: JavaScript Engines: Under the Hood

Handle: Local vs Persistent

{ HandleScope scope;

Handle<Value> foobar = .... .... ....}

long lived

short lived

Monday, November 29, 2010

Page 56: JavaScript Engines: Under the Hood

C++-side of Objects

Value Primitive BooleanStringNumber

Date

Object

Array

Function

ExternalMonday, November 29, 2010

Page 57: JavaScript Engines: Under the Hood

Expose a Variable

Handle<ObjectTemplate> global = ObjectTemplate::New();global->Set("foobar", String::New(“Hello”));

Monday, November 29, 2010

Page 58: JavaScript Engines: Under the Hood

Expose a Function

Handle<FunctionTemplate> systemObject = FunctionTemplate::New();systemObject->Set(String::New("exit"), FunctionTemplate::New(system_exit)->GetFunction());

static Handle<Value> system_exit(const Arguments& args){ int status = args[0]->Int32Value(); ::exit(status); return Undefined();}

Monday, November 29, 2010

Page 59: JavaScript Engines: Under the Hood

DemoCode Formatter

Monday, November 29, 2010

Page 60: JavaScript Engines: Under the Hood

DemoSyntax Checker

Monday, November 29, 2010

Page 61: JavaScript Engines: Under the Hood

DemoCanvas-based Game

Monday, November 29, 2010

Page 62: JavaScript Engines: Under the Hood

http://10k.aneventapart.com/Entry/392

Monday, November 29, 2010

Page 63: JavaScript Engines: Under the Hood

DemoSyntax Parser

Monday, November 29, 2010

Page 64: JavaScript Engines: Under the Hood

Ext.extend

Ext.ComponentFoo = Ext.extend(Ext.ComponentBar, ....

depend

declare

Monday, November 29, 2010

Page 65: JavaScript Engines: Under the Hood

DemoCode Analyzer

Monday, November 29, 2010

Page 66: JavaScript Engines: Under the Hood

"type": "IfStatement","test": { "type": "BinaryExpression", "operator": "==", "left": { "type": "Identifier", "name": "x" }, "right": { "type": "Identifier", "name": "y" } }, "consequent": { "type": "ExpressionStatement", "expression": { "type": "CallExpression", "callee": { "type": "Identifier", "name": "foo" }, "arguments": [] } }, "alternate": null

if (x == y) foo();

Monday, November 29, 2010

Page 67: JavaScript Engines: Under the Hood

"type": "IfStatement","test": { "type": "BinaryExpression", "operator": "==", "left": { "type": "Identifier", "name": "x" }, "right": { "type": "Identifier", "name": "y" } }, "consequent": { "type": "ExpressionStatement", "expression": { "type": "CallExpression", "callee": { "type": "Identifier", "name": "foo" }, "arguments": [] } }, "alternate": null

if (x == y) foo();

Monday, November 29, 2010

Page 68: JavaScript Engines: Under the Hood

"type": "IfStatement","test": { "type": "BinaryExpression", "operator": "==", "left": { "type": "Identifier", "name": "x" }, "right": { "type": "Identifier", "name": "y" } }, "consequent": { "type": "ExpressionStatement", "expression": { "type": "CallExpression", "callee": { "type": "Identifier", "name": "foo" }, "arguments": [] } }, "alternate": null

if (x == y) foo();

Danger!

Monday, November 29, 2010

Page 69: JavaScript Engines: Under the Hood

Debugging

Monday, November 29, 2010

Page 70: JavaScript Engines: Under the Hood

http://code.google.com/p/chromedevtoolsMonday, November 29, 2010

Page 71: JavaScript Engines: Under the Hood

(Remote) Debugging

v8::Debug::EnableAgent("foobar", 5858);

Monday, November 29, 2010

Page 72: JavaScript Engines: Under the Hood

(Remote) Debugging

v8::Debug::EnableAgent("foobar", 5858);

listening port

application name

Monday, November 29, 2010

Page 73: JavaScript Engines: Under the Hood

Profiling

Monday, November 29, 2010

Page 74: JavaScript Engines: Under the Hood

Activate Profiler

scons prof=on ...

shell --prof ....

tools/mac-tick-processor v8.log

Monday, November 29, 2010

Page 75: JavaScript Engines: Under the Hood

Function-Level Profile [JavaScript]: ticks total nonlib name 3125 5.9% 5.9% LazyCompile: am3 crypto.js:108 1036 2.0% 2.0% KeyedLoadIC: A keyed load IC from the snapshot 386 0.7% 0.7% LazyCompile: StringReplaceRegExp native string.js:243 362 0.7% 0.7% LazyCompile: Scheduler.schedule richards.js:188 326 0.6% 0.6% LazyCompile: one_way_unify1_nboyer earley-boyer.js:3635 301 0.6% 0.6% LazyCompile: exec native regexp.js:156 280 0.5% 0.5% LazyCompile: TaskControlBlock.isHeldOrSuspended richards.js:309 279 0.5% 0.5% KeyedStoreIC: A keyed store IC from the snapshot 278 0.5% 0.5% LazyCompile: rewrite_nboyer earley-boyer.js:3604 259 0.5% 0.5% LazyCompile: BuildResultFromMatchInfo native regexp.js:121 244 0.5% 0.5% LazyCompile: TaskControlBlock.run richards.js:324 186 0.4% 0.4% Stub: Instanceof

Monday, November 29, 2010

Page 76: JavaScript Engines: Under the Hood

THANK YOU!

Monday, November 29, 2010

Page 77: JavaScript Engines: Under the Hood

QUESTIONS?

ariya @ sencha.com

ariyahidayat

ariya.blogspot.com

Monday, November 29, 2010

Page 78: JavaScript Engines: Under the Hood

ADDENDUM

Monday, November 29, 2010

Page 79: JavaScript Engines: Under the Hood

Get SpiderMonkey

hg clone http://hg.mozilla.org/mozilla-central/cd mozilla-central/js/src

Monday, November 29, 2010

Page 80: JavaScript Engines: Under the Hood

Get JavaScriptCoresvn checkout http://svn.webkit.org/repository/webkit/trunk webkitcd webkit/JavaScriptCore

git clone git://git.webkit.org/WebKit.gitcd WebKit/JavaScriptCore

Monday, November 29, 2010

Page 81: JavaScript Engines: Under the Hood

Build SpiderMonkey

autoconf213./configure --disable-debug --enable-optimizemake

Monday, November 29, 2010

Page 82: JavaScript Engines: Under the Hood

Build JavaScriptCore

JavaScriptCore/JavaScriptCore.xcodeproj

JavaScriptCore

jsc

Monday, November 29, 2010

Page 83: JavaScript Engines: Under the Hood

perl sunspider --shell=/path/to/mozilla-central/js/src/build-release/js --args=-j

perl sunspider --shell=/path/to/webkit/JavaScriptCore/jsc

perl sunspider --shell=/path/to/v8/directory/shell --args=-expose-gc

Run your-favorite-benchmark

Monday, November 29, 2010

Page 84: JavaScript Engines: Under the Hood

perl sunspider --shell=/path/to/mozilla-central/js/src/build-release/js --args=-j

perl sunspider --shell=/path/to/webkit/JavaScriptCore/jsc

perl sunspider --shell=/path/to/v8/directory/shell --args=-expose-gc

Run your-favorite-benchmark

garbage collector

Monday, November 29, 2010

Page 85: JavaScript Engines: Under the Hood

Build JavaScriptCoreqmake -r DerivedSources.procd JavaScriptCoremake -f Makefile.DerivedSourcesqmake && makeqmake jsc.pro && make

Monday, November 29, 2010


Top Related