The Dark Side of JavaScript
Ali Arafati









What’s faster, C++ or JavaScript?





C++ developers
Franziska Hinkelmann

Marja Hölttä
Benedikt Meurer

const primes = [2, 3, 5, 7];
const nextPrime = calculateNextPrime(primes);
primes.push(nextPrime);

const a = [2, 3, 5, 7];
const b = c(a);
a.d(b);
https://medium.com/dailyjs/317d46c94775 by Franziska Hinkelmann
[
{
"type": "VariableDeclaration",
"declarations": [
{
"type": "VariableDeclarator",
"id": {
"type": "Identifier",
"loc": {
"identifierName": "primes"
},
"name": "primes"
},
"init": {
"type": "ArrayExpression",
"elements": [
{
"type": "NumericLiteral",
"value": 2
},
{
"type": "NumericLiteral",
"value": 3
},
{
"type": "NumericLiteral",
"value": 5
},
{
"type": "NumericLiteral",
"value": 7
}
]
}
}
],
"kind": "const"
}
] 0x2e3c1f51eb75 @ 3 : 26 f7 Star r4
0x2e3c1f51eb77 @ 5 : 0c 25 LdaSmi [37]
0x2e3c1f51eb79 @ 7 : 26 f6 Star r5
0x2e3c1f51eb7b @ 9 : 61 c0 00 f7 02 CallRuntime [CreateArrayLiteralWithoutAllocationSite], r4-r5
0x2e3c1f51eb80 @ 14 : 26 fb Star r0
73 S> 0x2e3c1f51eb82 @ 16 : 0d LdaUndefined
0x2e3c1f51eb83 @ 17 : 26 f8 Star r3
0x2e3c1f51eb85 @ 19 : 13 01 00 LdaGlobal [1], [0]
0x2e3c1f51eb88 @ 22 : 26 f9 Star r2
0x2e3c1f51eb8a @ 24 : 27 fb f7 Mov r0, r4
73 E> 0x2e3c1f51eb8d @ 27 : 5f f9 f8 02 CallNoFeedback r2, r3-r4
0x2e3c1f51eb91 @ 31 : 26 fa Star r1
110 S> 0x2e3c1f51eb93 @ 33 : 29 fb 02 LdaNamedPropertyNoFeedback r0, [2]
0x2e3c1f51eb96 @ 36 : 26 f9 Star r2
0x2e3c1f51eb98 @ 38 : 27 fb f8 Mov r0, r3
0x2e3c1f51eb9b @ 41 : 27 fa f7 Mov r1, r4
110 E> 0x2e3c1f51eb9e @ 44 : 5f f9 f8 02 CallNoFeedback r2, r3-r4Instructions (size = 1108)
0x10e479600 0 488d1df9ffffff REX.W leaq rbx,[rip+0xfffffff9]
0x10e479607 7 483bd9 REX.W cmpq rbx,rcx
0x10e47960a a 7410 jz 0x10e47961c (LdaNamedPropertyNoFeedbackWideHandler)
0x10e47960c c 48ba0000000037000000 REX.W movq rdx,0x3700000000
0x10e479616 16 e885c2b4ff call 0x10dfc58a0 (Abort)
0x10e47961b 1b cc int3l
0x10e47961c 1c 55 push rbp
0x10e47961d 1d 4889e5 REX.W movq rbp,rsp
0x10e479620 20 6a18 push 0x18
0x10e479622 22 4883ec38 REX.W subq rsp,0x38
0x10e479626 26 4f0fbf440e01 REX.W movsxwq r8,[r14+r9*1+0x1]
0x10e47962c 2c 4c8b5d00 REX.W movq r11,[rbp+0x0]
0x10e479630 30 4f8b04c3 REX.W movq r8,[r11+r8*8]
0x10e479634 34 470fb7640e03 movzxwl r12,[r14+r9*1+0x3]
0x10e47963a 3a 49ba0000000001000000 REX.W movq r10,0x100000000
0x10e479644 44 4d39e2 REX.W cmpq r10,r12
0x10e479647 47 730d jnc 0x10e479656 (LdaNamedPropertyNoFeedbackWideHandler)
0x10e479649 49 488b15ecffffff REX.W movq rdx,[rip+0xffffffec]
0x10e479650 50 e84bc2b4ff call 0x10dfc58a0 (Abort)
0x10e479655 55 cc int3l
0x10e479656 56 498bc6 REX.W movq rax,r14
0x10e479659 59 4883e003 REX.W andq rax,0x3
0x10e47965d 5d 4c894de0 REX.W movq [rbp-0x20],r9
0x10e479661 61 4c897de8 REX.W movq [rbp-0x18],r15
0x10e479665 65 4c895dd8 REX.W movq [rbp-0x28],r11
0x10e479669 69 4c8965c8 REX.W movq [rbp-0x38],r12
0x10e47966d 6d 4c8945f0 REX.W movq [rbp-0x10],r8
0x10e479671 71 4883f801 REX.W cmpq rax,0x1
const obj = {
language: "JavaScript"
};class Object {
public:
string language;
};
Object obj = new Object
obj.language = "C++"case class Object(language: String)
val obj = new Object("Scala")const obj = {
language: "JavaScript"
}
obj.compiler = "V8"
obj.history = ["dark", "good parts", "bad parts"]
obj.history = 1337;
delete obj.history
const dictionary = {
"hej": "yo",
"hej då": "so long",
"lagom": NaN,
"gift": ["married", "poison"],
"fart-hinder": "speed bump"
}
dictionary["hej"] // yo

THIS IS SLOW!





Very fast objects
Fast objects
Slow objects
JavaScript Object/Array
Memory
Hidden Class
Properties
Elements
pointer
pointer
pointer
in-object properties
Fixed Array
Fixed Array
or
Dictionary
Hidden Class
bit fields
Descriptor
Fixed Array
length
key 1
details 1
item 1
item 2
function getPlayerPosition(player) {
return player.position;
}const arya = { name: 'Arya Stark', hair: 'dark' }
const girl = { name: 'A girl has no name' }
Object.setPrototypeOf(girl, arya);
girl.hair; // dark
name
hair
function getPlayerPosition(player) {
return player.position;
}function getPlayerPosition(player) {
if (%ShapeEqual(player, @123414))
return player@2432
}
return player.position;
}function getPlayerPosition(player) {
if (%ShapeEqual(player, @986909))
return player@3446
}
if (%ShapeEqual(player, @123414))
return player@2432
}
return player.position;
}const playerA = { position: [0, 0] };
const playerB = { position: [1, 2] };
playerB.isDead = true;const playerA = { position: [0, 0] };
const playerB = { position: [1, 2] };
const IS_DEAD = 0;
playerB[IS_DEAD] = true;function getPlayerPosition(player) {
if (%ShapeEqual(player, @123414))
return player@2432
}
return player.position;
}
Demo
0x3f0c8a9e9d1 @ 23 : 61 c2 00 f8 02 CallRuntime [CreateObjectLiteralWithoutAllocationSite], r3-r4
0x3f0c8a9e9d6 @ 28 : 26 f9 Star r2
519 E> 0x3f0c8a9e9d8 @ 30 : 13 02 00 LdaGlobal [2], [0]
0x3f0c8a9e9db @ 33 : 2f f9 03 02 StaNamedOwnProperty r2, [3], [2]
0x3f0c8a9e9df @ 37 : 25 f9 Ldar r2
472 E> 0x3f0c8a9e9e1 @ 39 : 1d 04 StaCurrentContextSlot [4]
558 S> 0x3f0c8a9e9e3 @ 41 : 1b 04 LdaImmutableCurrentContextSlot [4]
0x3f0c8a9e9e5 @ 43 : 26 f9 Star r2
568 E> 0x3f0c8a9e9e7 @ 45 : 29 f9 04 LdaNamedPropertyNoFeedback r2, [4]Install d8 & some useful commands
d8 --allow-natives-syntaxconst array = [1, 2, 3, 4, 5];
%DebugPrint(array)
const obj = { name: 'JavaScript' };
%DebugPrint(obj)
const car = { name: 'BMW' };
%HaveSameMap(obj, car)
const language = {};
language.name = "JavaScript";
language.type = "Dynamic";
language.jit = true;
delete language.type;
const language = {};
language.name = "JavaScript";
language.type = "Dynamic";
language.jit = true;
delete language.type;
language ref
Memory
Hidden Class
[]
const language = {};
language.name = "JavaScript";
language.type = "Dynamic";
language.jit = true;
delete language.type;
language ref
Memory
Hidden Class
JavaScript
[name]
[]
const language = {};
language.name = "JavaScript";
language.type = "Dynamic";
language.jit = true;
delete language.type;
language ref
Memory
Hidden Class
JavaScript
[name, type]
[name]
Dynamic
[]
const language = {};
language.name = "JavaScript";
language.type = "Dynamic";
language.jit = true;
delete language.type;
language ref
Memory
Hidden Class
JavaScript
[name, type, jit]
[name, type]
Dynamic
[name]
[]
true
const language = {};
language.name = "JavaScript";
language.type = "Dynamic";
language.jit = true;
delete language.type;
language ref
Memory
Hidden Class
JavaScript
[name, jit]
[name, type, jit]
Dynamic
[name, type]
[name]
true
[]
const language = {};
language.name = "JavaScript";
language.type = "Dynamic";
[name, hobies]
[name, type]
[name]
[]
const person = {};
person.name = "Ali";
person.hobies = ["dark side"];
const languages = [
{
name: "JavaScript",
type: "Dynamic"
},
{
type: "Static",
name: "C++"
}
];

const primes = [2, 3, 5, 7];2
3
5
7
Memory
@1234000
Hidden Class
length: 4
SMI-Packed
const primes = [2, 3, 5, 7];
primes.push(13);2
3
5
7
Memory
@1234000
Hidden Class
length: 4
SMI-Packed
const primes = [2, 3, 5, 7];
primes.push(13);2
3
5
7
Memory
@93422313
13
Hidden Class
length: 5
SMI-Packed
const primes = [2, 3, 5, 7];
primes.push(13);
primes.push(17.0);2
3
5
7
Memory
@93422313
13
Hidden Class
length: 5
SMI-Packed
const primes = [2, 3, 5, 7];
primes.push(13);
primes.push(17.0);2.0
3.0
5.0
7.0
Memory
@54223411
13.0
17.0
Hidden Class
length: 6
Double-Packed
const primes = [2, 3, 5, 7];
primes.push(13);
primes.push(17.0);
primes.push(false);2.0
3.0
5.0
7.0
Memory
@54223411
13.0
17.0
Hidden Class
length: 6
Double-Packed
const primes = [2, 3, 5, 7];
primes.push(13);
primes.push(17.0);
primes.push(false);2
3
5
7
Memory
@72419991
13
false
17.0
Hidden Class
length: 7
Object-Packed
const primes = [2, 3, 5, 7];
primes[5] = 13;
2
3
5
7
Memory
@10031234
Hidden Class
length: 4
SMI-Packed
const primes = [2, 3, 5, 7];
primes[5] = 13;
2
3
5
7
Memory
@561222101
13
Hidden Class
length: 6
Holey-SMI
const primes = [2, 3, 5, 7];
primes[10000] = 104729;
Memory
Hidden Class
length: 4
SMI-Packed
2
3
5
7
@10031234
const primes = [2, 3, 5, 7];
primes[10000] = 104729;
Memory
Hidden Class
length: 10001
Holey-SMI
2
3
5
7
@10031234
Recap


https://github.com/thlorenz/v8-perf/blob/master/data-types.md
http://jayconrod.com/posts/52/a-tour-of-v8-object-representation
The Dark Side of JavaScript
By Ali Arafati
The Dark Side of JavaScript
- 628