Download - JavaScript Engines: Under the Hood
Monday, November 29, 2010
JavaScript EnginesUnder the Hood
ARIYA HIDAYATENGINEERING DIRECTOR, SENCHA
Monday, November 29, 2010
Get It
See It
Tweak It
JavaScript Engines
Monday, November 29, 2010
JavaScript Engines
Monday, November 29, 2010
SpiderMonkeyJavaScriptCore
V8
JavaScript Engines
Open
Opera CarakanMicrosoft JScript...
Closed
Monday, November 29, 2010
SpiderMonkeyJavaScriptCore
V8
JavaScript Engines
Open
Monday, November 29, 2010
SpiderMonkeyFirst JavaScript enginecreated by Brendan Eich
Written in CMostly used in Mozilla, Firefox, ...
License: MPL/LGPL/GPL
Monday, November 29, 2010
JavaScriptCore (JSC)Built into WebKitForked from KDE’s KJS a long time ago
License: LGPL
Monday, November 29, 2010
Other Names of JSCSquirrelFishbyte-code interpreter
SquirrelFish Extreme (SFX)native/machine code
Nitro, Nitro ExtremeApple’s marketing terms
Monday, November 29, 2010
Google V8Written in C++License: BSD
Used in Chromium (Google Chrome)
Monday, November 29, 2010
Qt ScriptUses JSC as the back-endDoes not power any web browser
Powerful bindings, debuggerUseful to make applications scriptable
Monday, November 29, 2010
Let’s Go UNDER THE HOOD
Monday, November 29, 2010
Let’s Go UNDER THE HOOD
Platform +Compiler
Monday, November 29, 2010
Monday, November 29, 2010
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
Build V8
scons sample=shell mode=release snapshot=on
Monday, November 29, 2010
Build V8
scons sample=shell mode=release snapshot=on
--jobs 4
Monday, November 29, 2010
Build V8
scons sample=shell mode=release snapshot=on
--jobs 4
arch=x64
Monday, November 29, 2010
perl sunspider --shell=/path/to/v8/directory/shell --args=-expose-gc
Run your-favorite-benchmark
Monday, November 29, 2010
perl sunspider --shell=/path/to/v8/directory/shell --args=-expose-gc
Run your-favorite-benchmark
garbage collector
Monday, November 29, 2010
Let’s Get DIRTY
Monday, November 29, 2010
Building Blocks
Parser
Interpreter
Runtime
Monday, November 29, 2010
Parser
Monday, November 29, 2010
Tokenize
var answer = 42;
Monday, November 29, 2010
Tokenize
var answer = 42;keyword equal sign
semicolon
identifier number
Monday, November 29, 2010
>>>
>>>
Look Ahead
greater than
right shift
zero-filled right shift
Monday, November 29, 2010
>>>
>>>
Look Ahead
greater than
right shift
zero-filled right shift
>=>>=>>>=
Monday, November 29, 2010
Tokenizer on V8
src/scanner.*
Monday, November 29, 2010
Tokenizer on V8
src/scanner.*
hand-writtenstate machine
Monday, November 29, 2010
Keyword vs Identifier
instanceof instanceComponent
requires checking 9 chars
Monday, November 29, 2010
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
Grammar
SourceElement :: (Statement)*
FunctionDeclaration :: 'function' Identifier '(' FormalParameters ')' '{' FunctionBody '}'
Monday, November 29, 2010
Syntax Tree
Variable Declaration
IdentifierLiteral Constant
answer 42Monday, November 29, 2010
Another Syntax Tree
Condition Consequent
age < 25 “young”
Alternate
“old”
Branch
Monday, November 29, 2010
Parser on V8
src/parser.*
Monday, November 29, 2010
Parser on V8
src/parser.*
hand-writtenrecursive descent
Monday, November 29, 2010
Code Trace
Script::Compile
Script::New
internal::Compiler::Compile
internal::MakeFunctionInfo
internal::ParserApi::Parse
Monday, November 29, 2010
Interpreter
Monday, November 29, 2010
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
Traverse and Run
Variable Declaration
IdentifierLiteral Constant
answer 42Monday, November 29, 2010
Bytecode
Serialize tree traversal intoa list of “actions”
Monday, November 29, 2010
Machine Code
Compile the bytecodes intomachine instructions
Monday, November 29, 2010
Machine Code
JIT (=just-in-time) compile
Compile the bytecodes intomachine instructions
Monday, November 29, 2010
Machine Code on V8
shell_g --print-code
Global
When needed
shell_g --expose-debug-as deb
Monday, November 29, 2010
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
“Lazy” Approach
foobar = function(x, y, z){....}
foobar(x, y, z);
Monday, November 29, 2010
“Lazy” Approach
foobar = function(x, y, z){....}
foobar(x, y, z);
Analyze the syntaxMark the position of
function ‘foobar’
Monday, November 29, 2010
“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
Runtime
Monday, November 29, 2010
Date.now()
JavaScriptworld
“native”world
Monday, November 29, 2010
Let’s GoOFF ROAD
Monday, November 29, 2010
Bridge
Monday, November 29, 2010
V8 Embedder’s Guide
http://code.google.com/apis/v8/embed.htmlMonday, November 29, 2010
Handle: Local vs Persistent
{ HandleScope scope;
Handle<Value> foobar = .... .... ....}
Monday, November 29, 2010
Handle: Local vs Persistent
{ HandleScope scope;
Handle<Value> foobar = .... .... ....}
long lived
short lived
Monday, November 29, 2010
C++-side of Objects
Value Primitive BooleanStringNumber
Date
Object
Array
Function
ExternalMonday, November 29, 2010
Expose a Variable
Handle<ObjectTemplate> global = ObjectTemplate::New();global->Set("foobar", String::New(“Hello”));
Monday, November 29, 2010
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
DemoCode Formatter
Monday, November 29, 2010
DemoSyntax Checker
Monday, November 29, 2010
DemoCanvas-based Game
Monday, November 29, 2010
http://10k.aneventapart.com/Entry/392
Monday, November 29, 2010
DemoSyntax Parser
Monday, November 29, 2010
Ext.extend
Ext.ComponentFoo = Ext.extend(Ext.ComponentBar, ....
depend
declare
Monday, November 29, 2010
DemoCode Analyzer
Monday, November 29, 2010
"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
"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
"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
Debugging
Monday, November 29, 2010
http://code.google.com/p/chromedevtoolsMonday, November 29, 2010
(Remote) Debugging
v8::Debug::EnableAgent("foobar", 5858);
Monday, November 29, 2010
(Remote) Debugging
v8::Debug::EnableAgent("foobar", 5858);
listening port
application name
Monday, November 29, 2010
Profiling
Monday, November 29, 2010
Activate Profiler
scons prof=on ...
shell --prof ....
tools/mac-tick-processor v8.log
Monday, November 29, 2010
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
THANK YOU!
Monday, November 29, 2010
QUESTIONS?
ariya @ sencha.com
ariyahidayat
ariya.blogspot.com
Monday, November 29, 2010
ADDENDUM
Monday, November 29, 2010
Get SpiderMonkey
hg clone http://hg.mozilla.org/mozilla-central/cd mozilla-central/js/src
Monday, November 29, 2010
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
Build SpiderMonkey
autoconf213./configure --disable-debug --enable-optimizemake
Monday, November 29, 2010
Build JavaScriptCore
JavaScriptCore/JavaScriptCore.xcodeproj
JavaScriptCore
jsc
Monday, November 29, 2010
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
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
Build JavaScriptCoreqmake -r DerivedSources.procd JavaScriptCoremake -f Makefile.DerivedSourcesqmake && makeqmake jsc.pro && make
Monday, November 29, 2010