1 of 30

JavaScript со скоростью света

01.02.2015

Дмитрий Ломов�Senior Software Engineer, V8 team

Rolling.Scopes, Минск, 01.02.2015

Rolling.Scopes, Минск, 01.02.2015

2 of 30

Как работает V8

Rolling.Scopes, Минск, 01.02.2015

3 of 30

Скрытые классы

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

4 of 30

Скрытые классы

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

5 of 30

Представление данных

var p1 = new Point(1.5,2.5), p2 = new Point("a","b");

Поля могут быть любым значением Javascript

=>

В V8 все значения Javascript - одно машинное слово

Rolling.Scopes, Минск, 01.02.2015

6 of 30

Представление данных

Объекты:

  • Указатели в кучу

Числа

  • Small integers, 31 бит (0th bit is 0)
  • Doubles: указатели в кучу

Строки

  • Указатели в кучу

Rolling.Scopes, Минск, 01.02.2015

7 of 30

Массивы

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

8 of 30

Массивы

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

9 of 30

Как 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

10 of 30

Как 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

11 of 30

Как 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

12 of 30

Как 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

13 of 30

Если 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

14 of 30

Наш враг - это мы непредсказуемость!

  • V8* не знает, чего хочет программист
  • Программист не знает, чего хочет V8

* s/V8/любая JS-машина/

Rolling.Scopes, Минск, 01.02.2015

15 of 30

asm.js

Rolling.Scopes, Минск, 01.02.2015

16 of 30

Кое-что предсказать можно

+x всегда double

x | 0 всегда int32

var a = new Uint8Array(100)

a[10] всегда uint8

Rolling.Scopes, Минск, 01.02.2015

17 of 30

Кое-что предсказать можно

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

18 of 30

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

19 of 30

asm.js - Полностью Предсказуемое Подмножество

  • Строгое подмножество Javascript
  • Все переменные и функции типизированы
  • Можно обращаться только к заранее выделенной памяти
  • Нельзя создавать новые объекты
  • Можно грабить корованы

Rolling.Scopes, Минск, 01.02.2015

20 of 30

Как достигается предсказуемая скорость

  • Выбрано подмножество языка…
  • … которое строго типизировано

Rolling.Scopes, Минск, 01.02.2015

21 of 30

asm.js: Скорость света?

Да:

  • Программы на asm.js выполняются как native code

Нет:

  • asm.js - слишком бедное подмножество

Rolling.Scopes, Минск, 01.02.2015

22 of 30

Stricter mode и SoundScript

(фантастические животные)

Rolling.Scopes, Минск, 01.02.2015

23 of 30

“use stricter”

  • Подмножество Javascript:
    • Запрещает некоторые поведения
    • Если стереть “use stricter”, то работающие программы работают так же, но неработающие программы могут начать работать

Rolling.Scopes, Минск, 01.02.2015

24 of 30

“use stricter”: ограничения

  • Запрещены дырки в массивах
  • Классы и объекты классов нерасширяемы
  • Кое-что по мелочи...

Rolling.Scopes, Минск, 01.02.2015

25 of 30

“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

26 of 30

“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

27 of 30

Тайное становится явным

Классы в "use stricter"

~

скрытые классы в V8

Rolling.Scopes, Минск, 01.02.2015

28 of 30

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

29 of 30

"use stricter" + SoundScript

  • Не замена Javascriptу везде
  • Значения типа any: обычный Javascript, меньше гарантий
  • Если программа типизируется и не использует any, то все работает со скоростью света

Rolling.Scopes, Минск, 01.02.2015

30 of 30

Спасибо!

Rolling.Scopes, Минск, 01.02.2015