3. About Me
• Programming language and virtual machine
enthusiast
• Worked on the HotSpot JVM at Taobao and
Oracle
• Also worked on a JavaScript engine project
• Twitter / Sina Weibo: @rednaxelafx
• Blog: English / Chinese
5. The roots of JavaScript language and modern JavaScript engines
KNOW THE HERITAGE
6. Heritage of the Language
Scheme
function closure
Self
prototype-based OO
C-like syntax,
built-in objects
Java
…
JavaScript
7. Language Comparison
Self
• Prototype-based OO
• Multiple Prototype
• Dynamically Typed
• Dynamically Extend Objects
• Mirror-based Reflection
• Block (closure)
• Support Non-local Return
• (pass a error handler to
methods that might one)
JavaScript (ECMAScript 5)
• Prototype-based OO
• Single Prototype
• Dynamically Typed
• Dynamically Extend Objects
• Reflection
• First-class Function (closure)
• (no non-local return)
• Exception Handling
8. Heritage of the Language
function MyPoint(x, y) {
this.x = x;
this.y = y;
}
MyPoint.prototype.distance = function (p) {
var xd = this.x - p.x,
yd = this.y - p.y;
return Math.sqrt(xd*xd + yd*yd);
}
var p = new Point(2013, 11);
9. Heritage of the Language
traits myPoint = (|
parent* = traits clonable.
initX: newX Y: newY = (x: newX. y: newY)
distance: p = (| xd. yd |
xd: x - p x.
yd: y - p y.
(xd squared + yd squared) squareRooted
).
|).
myPoint = (|
parent* = traits myPoint.
x <- 0.
y <- 0
|).
p: myPoint copy initX: 2013 Y: 11
13. VM Comparison
Self VM (3rd Generation)
V8 (with Crankshaft)
• Fast Object w/Hidden Class
• Tiered Compilation
• Fast Object w/Hidden Class
• Tiered Compilation
– OSR and deoptimization
– support for full-speed
debugging
– OSR and deoptimization
– support for full-speed
debugging
• Type Feedback
– Polymorphic Inline Caching
•
•
•
•
Type Inference
Method/Block Inlining
Method Customization
Generational Scavenging
– Scavenging + Mark-Compact
• Type Feedback
– Polymorphic Inline Caching
• Type Inference
• Function Inlining
• Generational Scavenging
– Scavenging + MarkSweep/Mark-Compact
14. To Implement a High Performance
JavaScript Engine
• Learn from Self VM as a basis!
15. Themes
• Pay-as-you-go / Lazy
• Take advantage of runtime information
– Type feedback
• Take advantage of actual code stability
– Try to behave as static as possible
16. Outline of the main components
JAVASCRIPT ENGINE OVERVIEW
17. Components of a JavaScript Engine
•
•
•
•
•
•
Parser
Runtime
Execution Engine
Garbage Collector (GC)
Foreign Function Interface (FFI)
Debugger and Diagnostics
18. Components of a JavaScript Engine
Source
Code
Parser
F
F
I
host /
external
library
AST
Execution
Engine
Memory (Runtime Data Areas)
Call
Stack
JavaScript
Objects
GC
19. Components of a JavaScript Engine
•
•
•
•
•
•
Parser
Runtime
Execution Engine
Garbage Collector (GC)
Foreign Function Interface (FFI)
Debugger and Diagnostics
20. Parser
• Parse source code into internal representation
• Usually generates AST
VarDecl: z
var z = x + y
BinaryArith: +
x
y
21. Components of a JavaScript Engine
•
•
•
•
•
•
Parser
Runtime
Execution Engine
Garbage Collector (GC)
Foreign Function Interface (FFI)
Debugger and Diagnostics
27. Components of a JavaScript Engine
•
•
•
•
•
•
Parser
Runtime
Execution Engine
Garbage Collector (GC)
Foreign Function Interface (FFI)
Debugger and Diagnostics
28. Foreign Function Interface
• Handle interaction between JavaScript and
“the outside world”
• JavaScript call out to native function
• Native function call into JavaScript function, or
access JavaScript object
29. Components of a JavaScript Engine
•
•
•
•
•
•
Parser
Runtime
Execution Engine
Garbage Collector (GC)
Foreign Function Interface (FFI)
Debugger and Diagnostics
34. Value Representation
• Pointers, and all values allocated on heap
• Discriminated Union
• Tagged Value / Tagged Pointer
Tag_Int
2013
typedef Object* JSValue;
35. Value Representation
• Pointers, and all values allocated on heap
• Discriminated Union
• Tagged Value / Tagged Pointer
Tag_Int
2013
class JSValue {
ObjectType ot;
union {
double n;
bool
b;
Object* o;
// …
} u;
}
36. Tagged
• Tagged Pointer
small integer
00
pointer
01
– Non-zero tag on pointer
– Favor small integer arithmetics
• Tagged Value
– Non-zero tag on non-pointer
– Favor pointer access
• NaN-boxing
– use special NaN value as box
37. Tagged
• Tagged Pointer
– Non-zero tag on pointer
– Favor small integer arithmetics
• Tagged Value
– Non-zero tag on non-pointer
– Favor pointer access
• NaN-boxing
– use special NaN value as box
small integer
01
pointer
00
38. Tagged
• Tagged Pointer
– Non-zero tag on pointer
– Favor small integer arithmetics
• Tagged Value
– Non-zero tag on non-pointer
00000000
– Favor pointer access
• NaN-boxing
pointer
xxxxxxxx
11111111
double
00000000
– use special QNaN value as box
integer
44. Nashorn Object Model
Key
Setter
“x”
x getter
x setter
“y”
map
Getter
y getter
y setter
map
__proto__
context
…
flags
0
spill
__proto__
null
…
arrayData
EMPTY_ARRAY
L0
x
L1
y
L2
(unused)
2013
L3
(unused)
42
45. Let’s ignore
some fields
for now
Getter
Setter
“x”
x getter
x setter
“y”
map
Key
y getter
y setter
map
__proto__
context
…
flags
0
spill
__proto__
null
…
arrayData
EMPTY_ARRAY
L0
x
L1
y
L2
(unused)
2013
L3
(unused)
42
46. … and we’ll
get this
Key
Getter
Setter
“x”
x getter
x setter
“y”
y getter
y setter
map
L0
x
L1
y
2013
42
47. looks just
like a Java
object
Key
Offset
“x”
+12
“y”
+16
metadata
x
class Point {
Object x;
Object y;
}
y
2013
… with
boxed fields
42
48. would be
even better
if …
Key
Offset
“x”
+12
“y”
+16
metadata
x
2013
y
42
class Point {
int x;
int y;
}
but Nashorn
doesn’t go
this far yet
49. Key
Setter
“x”
x getter
x setter
“y”
y getter
y setter
“z”
z getter
z setter
“a”
a getter
a setter
“b”
map
Getter
b getter
b setter
__proto__
context
…
flags
0
map
__proto__
…
spill
arrayData
b
L0
x
L1
y
L2
z
L3
a
0
6
1
7
1
2
3
4
5
50. Inline Cache
• Facilitated by use of hidden class
• Improve property access efficiency
• Collect type information for type feedback
– later fed to JIT compilers for better optimization
• Works with both interpreted and compiled
code
53. Call Stack
• Native or separate?
• Native
– fast
– easier transition between execution modes
– harder to implement
• Separate (aka “stack-less”)
– easy to implement
– slow
– overhead when transitioning between exec modes
71. GC Concurrency
(Mostly) Concurrent Mark-Sweep
Application Thread
JavaScript
GC Thread
GC
reset
initial mark
remark
concurrent mark concurrent sweep
72. A new high performance JavaScript on top of the JVM
A BIT ABOUT NASHORN
73. What is Nashorn?
Overview
• Oracle’s ECMAScript 5.1 implementation, on
the JVM
• Clean code base, 100% Java
– started from scratch; no code from Rhino
• An OpenJDK project
• GPLv2 licensed
81. Nashorn Execution Model
JavaScript Source Code
Compiler Backend
Constant Folding
Parser (Compiler Frontend)
Control-flow Lowering
Lexical Analysis
Type Annotating
Syntax Analysis
Range Analysis (*)
Code Splitting
AST
Type Hardening
Bytecode Generation
* Not complete yet
Java Bytecode
Editor's Notes
Self 4.0 cannot run a block after its enclosing method has returned.
http://blogs.msdn.com/b/ie/archive/2012/06/13/advances-in-javascript-performance-in-ie10-and-windows-8.aspxChakra employs a conservative, quasi-generational, mark and sweep, garbage collector that does most of its work concurrently on a dedicated thread to minimize script execution pauses that would interrupt the user experience.