JavaScript со скоростью света
01.02.2015
Дмитрий Ломов�Senior Software Engineer, V8 team
Rolling.Scopes, Минск, 01.02.2015
Rolling.Scopes, Минск, 01.02.2015
Как работает V8
Rolling.Scopes, Минск, 01.02.2015
Скрытые классы
function Point(x,y) {
this.x = x;
this.y = y;
}
x: slot 0
y: slot 1
this
class
<пусто>
this
class
x: slot 0
добавили x
this
class
добавили y
Rolling.Scopes, Минск, 01.02.2015
Скрытые классы
function Point(x,y) {
this.x = x;
this.y = y;
}
var p1 = new Point(1,2);
var p2 = new Point(3,5);
function norm(p) {
return Math.sqrt(p.x*p.x + p.y*p.y);
}
hidden class
1
2
hidden class
3
5
x: slot 0
y: slot 1
p1
p2
Тут проверяем, что скрытый класс p это
Rolling.Scopes, Минск, 01.02.2015
Представление данных
var p1 = new Point(1.5,2.5), p2 = new Point("a","b");
Поля могут быть любым значением Javascript
=>
В V8 все значения Javascript - одно машинное слово
Rolling.Scopes, Минск, 01.02.2015
Представление данных
Объекты:
Числа
Строки
…
Rolling.Scopes, Минск, 01.02.2015
Массивы
var a = new Array(3);
a.foo = "text"
a[0] = 1; a[1] = 2.5; a[2] = "abc”;
hidden class
elements
slot 1
elements_kind: FAST_ELEMENTS
foo: slot 1
length: 3 1
2.5
"abc"
"text"
Rolling.Scopes, Минск, 01.02.2015
Массивы
length: 3 1 2 3
hidden class
elements
`
elements_kind: FAST_SMI_ELEMENTS
length: 3 1.5 2.6 3.7
hidden class
elements
`
elements_kind: FAST_DOUBLE_ELEMENTS
[1, 2, 3]
[1.5, 2.6, 3.7]
Rolling.Scopes, Минск, 01.02.2015
Как V8 учится
function f(p) { return p.x; }
f(new Point(1,2)); f(new Point(3,4));
x: slot 0
y: slot 1
Хорошо
Одна машинная инструкция
Inline cache: Список скрытых классов:
Rolling.Scopes, Минск, 01.02.2015
Как V8 учится
function f(p) { return p.x; }
f({x:1,y:2}); f({y:3, x:4});
Inline cache: Список скрытых классов:
x: slot 0
y: slot 1
Хуже
y: slot 0
x: slot 1
Выбор по классу
,
Rolling.Scopes, Минск, 01.02.2015
Как V8 учится
function f(p) { return p.x; }
f({x:1,y:2}); f({y:3, x:4});
f({x:1,z:5,x:8});...
Inline cache: Список скрытых классов:
x: slot 0
y: slot 1
Плохо
y: slot 0
x: slot 1
y: slot 0
z: slot 1
x: slot 2
…
,
,
Rolling.Scopes, Минск, 01.02.2015
Как V8 учится: массивы
var a = new Array(3);
a.foo = "text"
a[0] = 1; a[1] = 2.5; a[2] = "abc”;
hidden class
elements
slot 1
elements_kind: FAST_ELEMENTS
foo: slot 1
length: 3 1
2.5
"abc"
"text"
Rolling.Scopes, Минск, 01.02.2015
Если V8 научилась неправильно
a[1000000] = 7.8
hidden class
elements
foo
elements_kind: DICTIONARY_ELEMENTS
foo: slot 1
2.5
"abc"
"text"
"0" 1
"1"
"2"
"100000"
7.8
Rolling.Scopes, Минск, 01.02.2015
Наш враг - это мы непредсказуемость!
* s/V8/любая JS-машина/
Rolling.Scopes, Минск, 01.02.2015
asm.js
Rolling.Scopes, Минск, 01.02.2015
Кое-что предсказать можно
+x всегда double
x | 0 всегда int32
var a = new Uint8Array(100)
a[10] всегда uint8
Rolling.Scopes, Минск, 01.02.2015
Кое-что предсказать можно
function fib(n) {
n = n | 0;
if (n < 3) return 1;
return (fib((n-1)|0)|0 + fib((n-2)|0)|0)|0;
}
Rolling.Scopes, Минск, 01.02.2015
asm.js - Полностью Предсказуемое Подмножество
function AsmModule(stdlib, foreign, buffer) {
'use asm';
var HEAP32 = new Int32Array(buffer);
function sum(from, to) {
from = from | 0; to = to|0;
var sum = 0;
for (i = from | 0; i < to; i = (i+1) | 0)
sum = (sum + HEAP32[i]) | 0;
return sum | 0;
}
return sum;
}
Rolling.Scopes, Минск, 01.02.2015
asm.js - Полностью Предсказуемое Подмножество
Rolling.Scopes, Минск, 01.02.2015
Как достигается предсказуемая скорость
Rolling.Scopes, Минск, 01.02.2015
asm.js: Скорость света?
Да:
Нет:
Rolling.Scopes, Минск, 01.02.2015
Stricter mode и SoundScript
(фантастические животные)
Rolling.Scopes, Минск, 01.02.2015
“use stricter”
Rolling.Scopes, Минск, 01.02.2015
“use stricter”: ограничения
Rolling.Scopes, Минск, 01.02.2015
“use stricter”: программирование без дырок (в массивах)
"use stricter";
let a = [1, 2, 3];
a[3] = 4; // Можно
a.length = 5; // Нельзя
a[2015] = "Rolling.Scopes"; // Нельзя
Только если массив создан внутри "use stricter"!
Rolling.Scopes, Минск, 01.02.2015
“use stricter”: Классы
"use stricter";
class Point {
constructor(x, y) {
this.x = x; this.y = y;
}
move(dx, dy) { … }
}
Point - нерасширяем, sealed
Point.prototype - нерасширяем, sealed
new Point(...) - нерасширяем, sealed
Rolling.Scopes, Минск, 01.02.2015
Тайное становится явным
Классы в "use stricter"
~
скрытые классы в V8
Rolling.Scopes, Минск, 01.02.2015
SoundScript
"use stricter+types";
class Point {
constructor(x : int, y : int) {
this.x = x; this.y = y;
}
move(dx : int, dy : int) : void { … }
}
function norm(p : Point) : double {
return Math.sqrt(p.x*p.x + p.y*p.y);
}
Rolling.Scopes, Минск, 01.02.2015
"use stricter" + SoundScript
Rolling.Scopes, Минск, 01.02.2015
Спасибо!
twitter: mulambda@ dslomov@google.com dslomov@chromium.org
Rolling.Scopes, Минск, 01.02.2015