Feedback → specialization → deopt09 / 19

Оптимизация строится на предположениях

Что меняется, когда в числовой код приходит строка.

Если add(a, b) часто получает числа, оптимизирующий компилятор может подготовить специализированный путь с проверками предположений. Это способ ускорить динамический язык без изменения его правил.

function add(a, b) { return a + b; }
add(2, 3);     // 5
add('2', 3);   // '23'

Когда предположение не выполняется, возможны другой путь выполнения или deoptimization: восстановление состояния для менее специализированного кода. Программа должна по-прежнему вернуть '23', а не выполнить неверное числовое сложение.

После повторных вызовов с числами V8 может создать машинный код для числового сложения

В нём проверяется предположение: a и b — числа.

add(2, 3) ✓ Проверка пройдена

Оба аргумента — числа.

Числовое сложение

Выполняется подготовленный машинный код.

Результат · число5
add('2', 3) × Проверка не пройдена

Первый аргумент — строка.

Возможна деоптимизация

V8 восстанавливает состояние и продолжает выполнение через Ignition.

Результат · строка'23'
Показан возможный сценарий. Передача строки не обязательно вызывает деоптимизацию: у функции может быть и другой подходящий путь выполнения.

Формы объектов и inline caches тоже дают обратную связь — подробно разберём их в разделе об оптимизации.

Прежде чем менять работу с динамическими объектами ради JIT, нужно записать профиль, найти участок с высокими затратами и определить причину этих затрат.

Основной вывод

Deoptimization сохраняет семантику программы, когда предположения оптимизированного кода больше не подходят.

Проверить по первоисточнику ↗

V8 · Maglev↗Уровни исполнения, обратная связь и спекулятивная оптимизация.V8 · Maps / Hidden Classes↗Обратная связь о формах объектов и зависимость оптимизированного кода от предположений.ECMA-262 · Addition↗Семантика числового сложения и конкатенации строк.