Node Under The Hood : V8
Matt Sprague - LoDo Labs
Javascript Engines
- JScript (IE)
- SpiderMonkey (Mozilla)
- JavascriptCore (Safari)
- Chakra (MS Edge)
- V8 (Chromium)
V8 and NodeJS
# Search for packages related to V8
# Arch Linux
$ pacman -Ss v8
community/nodejs 6.3.1-1
Evented I/O for V8 javascript
V8: Design and Architecture
- Fast Property Access
- Dynamic Machine Code Generation
- Efficient Garbage Collection
Fast Property Access
V8: Design and Architecture
Fast Property Access
Shadow Classes
Property Dictionary or Map
VS
Fast Property Access
Each subsequent invocation of the Triple constructor references the shadow class
This approach allows inline caching ala Smalltalk-80
Fast Property Access
class Triple {
constructor(a,b,c) {
this._first = a;
this._second = b;
this._third = c;
}
get first() {
return this._first;
}
get second() {
return this._second;
}
get third() {
return this._third;
}
}
Fast Property Access
Triple (JS)
Native Shadow Class
NativeTriple0
Initial Shadow Class
Fast Property Access
Triple (JS)
Offset 0 : first
Native Shadow Class
NativeTriple1
Native Shadow Class
NativeTriple0
As each property is initialized a new shadow class is created.
Fast Property Access
Triple (JS)
Offset 0 : first
Offset 1: second
Native Shadow Class
NativeTriple2
Native Shadow Class
NativeTriple0
Native Shadow Class
NativeTriple1
V8: Design and Architecture
Dynamic Machine Code Generation
const v8 = require('v8');
v8.setFlagsFromString('--print_code');
class Triple {
constructor(a,b,c) {
this._first = a;
this._second = b;
this._third = c;
}
get first() {
return this._first;
}
get second() {
return this._second;
}
get third() {
return this._third;
}
}
const myTriple = new Triple(2,-1,0);
const myOtherTriple = new Triple(-3.4,22,1.3);
console.log(myTriple);
kind = FUNCTION
name = Triple
compiler = full-codegen
Instructions (size = 180)
0x314ae6b404e0 0 55 push rbp ;; debug: position 171
0x314ae6b404e1 1 4889e5 REX.W movq rbp,rsp
0x314ae6b404e4 4 56 push rsi
0x314ae6b404e5 5 57 push rdi
0x314ae6b404e6 6 493ba5880a0000 REX.W cmpq rsp,[r13+0xa88]
0x314ae6b404ed 13 7305 jnc 20 (0x314ae6b404f4)
0x314ae6b404ef 15 e8cc91efff call StackCheck (0x314ae6a396c0) ;; code: BUILTIN
0x314ae6b404f4 20 ff7528 push [rbp+0x28] ;; debug: statement 189
;; debug: position 189
0x314ae6b404f7 23 488b4520 REX.W movq rax,[rbp+0x20] ;; debug: position 203
0x314ae6b404fb 27 48b9e1ae05a34a320000 REX.W movq rcx,0x324aa305aee1 ;; debug: position 201
;; object: 0x324aa305aee1 <String[6]: _first>
0x314ae6b40505 37 5a pop rdx
0x314ae6b40506 38 48bf0000000001000000 REX.W movq rdi,0x100000000
0x314ae6b40510 48 e86b3ceeff call 0x314ae6a24180 ;; code: STORE_IC, GENERIC
0x314ae6b40515 53 ff7528 push [rbp+0x28] ;; debug: statement 214
;; debug: position 214
0x314ae6b40518 56 488b4518 REX.W movq rax,[rbp+0x18] ;; debug: position 229
0x314ae6b4051c 60 48b901af05a34a320000 REX.W movq rcx,0x324aa305af01 ;; debug: position 227
;; object: 0x324aa305af01 <String[7]: _second>
0x314ae6b40526 70 5a pop rdx
0x314ae6b40527 71 48bf0000000003000000 REX.W movq rdi,0x300000000
0x314ae6b40531 81 e84a3ceeff call 0x314ae6a24180 ;; code: STORE_IC, GENERIC
0x314ae6b40536 86 ff7528 push [rbp+0x28] ;; debug: statement 240
;; debug: position 240
0x314ae6b40539 89 488b4510 REX.W movq rax,[rbp+0x10] ;; debug: position 254
0x314ae6b4053d 93 48b921af05a34a320000 REX.W movq rcx,0x324aa305af21 ;; debug: position 252
;; object: 0x324aa305af21 <String[6]: _third>
0x314ae6b40547 103 5a pop rdx
0x314ae6b40548 104 48bf0000000005000000 REX.W movq rdi,0x500000000
0x314ae6b40552 114 e8293ceeff call 0x314ae6a24180 ;; code: STORE_IC, GENERIC
0x314ae6b40557 119 498b45a8 REX.W movq rax,[r13-0x58]
0x314ae6b4055b 123 48bb01e705a34a320000 REX.W movq rbx,0x324aa305e701 ;; object: 0x324aa305e701 Cell for 6144
0x314ae6b40565 133 83430bd1 addl [rbx+0xb],0xd1
0x314ae6b40569 137 791f jns 170 (0x314ae6b4058a)
0x314ae6b4056b 139 50 push rax
0x314ae6b4056c 140 e80f90efff call InterruptCheck (0x314ae6a39580) ;; code: BUILTIN
0x314ae6b40571 145 58 pop rax
0x314ae6b40572 146 48bb01e705a34a320000 REX.W movq rbx,0x324aa305e701 ;; object: 0x324aa305e701 Cell for 6144
0x314ae6b4057c 156 49ba0000000000180000 REX.W movq r10,0x180000000000
0x314ae6b40586 166 4c895307 REX.W movq [rbx+0x7],r10
0x314ae6b4058a 170 c9 leave ;; debug: statement 261
0x314ae6b4058b 171 c22000 ret 0x20
0x314ae6b4058e 174 6690 nop
Three Compilers
Full - Codegen
Crankshaft
Turbofan
Parser
AST
Full Codegen
Crankshaft
Turbofan
Optimized
Code
Unoptimized
Code
Optimized
Code mk2
Full Codegen
Native Code
AST
Crankshaft
Native Code
AST
Hydrogen IR
Lithium
IR
V8: Design and Architecture
Efficient Garbage Collection
Efficient Garbage Collection
-
Execution Halting
-
Generational
-
Heap Segmenting
Efficient Garbage Collection
[
{
"space_name": "new_space",
"space_size": 2063872,
"space_used_size": 951112,
"space_available_size": 80824,
"physical_space_size": 2063872
},
{
"space_name": "old_space",
"space_size": 3090560,
"space_used_size": 2493792,
"space_available_size": 0,
"physical_space_size": 3090560
},
{
"space_name": "code_space",
"space_size": 1260160,
"space_used_size": 644256,
"space_available_size": 960,
"physical_space_size": 1260160
},
{
"space_name": "map_space",
"space_size": 1094160,
"space_used_size": 201608,
"space_available_size": 0,
"physical_space_size": 1094160
},
{
"space_name": "large_object_space",
"space_size": 0,
"space_used_size": 0,
"space_available_size": 1490980608,
"physical_space_size": 0
}
]
Efficient Garbage Collection
Current Experiments:
Strong Mode
&
SoundScript
Strong Mode: Extends Strict Mode
- No more var (only let & const)
- Objects are inherently immutable
- No sparse arrays
- Safe functions (strict arity)
- No implicity type conversions
SoundScript
- Based on Typescript
- Provides a type system IN the VM
- Efficient runtime type checking
- Aimed at improving predictability
Further Reading
lodolabs [at] gmail [.] com
Node Internals
By Matt Sprague
Node Internals
- 1,615