Перейти к содержимому

V8 Overview

V8 — JIT-компилятор с многоуровневым пайплайном (Ignition → Sparkplug → Maglev → TurboFan); понимание пути от исходника до машинного кода объясняет, почему “горячий” код работает быстрее и как его непреднамеренно деоптимизировать.

// V8 pipeline: Parsing → AST → Bytecode → JIT
// 1. Parser (lazy/eager): source → AST
// - Lazy parsing: тела функций парсятся при первом вызове
// - Eager parsing: IIFE, eval, export default function
// 2. Ignition (interpreter): AST → bytecode
// - Собирает type feedback (IC профиль)
// 3. Sparkplug: baseline JIT без оптимизаций (~x2 vs Ignition)
// 4. Maglev (V8 v12+): mid-tier JIT, speculative optimizations
// 5. TurboFan: полная оптимизация для "горячих" функций
// - Escape analysis, inlining, loop unrolling
// - Требует стабильных типов (monomorphic IC)
// Lazy parsing пример: скобки вынуждают eager parse
(function eager() { /* парсится при загрузке */ });
function lazy() { /* парсится при первом вызове */ }
// Deoptimization триггеры
function add(a, b) { return a + b; }
// TurboFan компилирует под int32 после прогрева
for (let i = 0; i < 100_000; i++) add(1, 2);
// Смена типа → deopt, функция "падает" обратно в Ignition
add('hello', 'world'); // deopt!
// V8 помечает как "megamorphic" при частых deopt-ах
// → больше не пытается оптимизировать TurboFan-ом
// Другие триггеры deopt:
// - typeof x === 'undefined' (не всегда, зависит от версии)
// - arguments object (escaped) — мешает escape analysis
// - Функции с try/catch (исторически, в V8 9+ частично исправлено)
// Диагностика с --allow-natives-syntax (Node.js dev/test only)
// node --allow-natives-syntax script.js
function hot(x) { return x * 2; }
for (let i = 0; i < 1e5; i++) hot(i); // прогрев
// %GetOptimizationStatus(hot):
// 2 = not optimized
// 65 = optimized (Maglev)
// 1 = optimized (TurboFan)
// 128 = turbofan compiled, embedded
// node --trace-opt --trace-deopt script.js
// → показывает когда TurboFan оптимизирует/деоптимизирует
// node --print-bytecode --print-opt-code script.js
// → показывает bytecode Ignition и машинный код TurboFan

Итог: V8 использует многоуровневый JIT: Ignition собирает type feedback, TurboFan генерирует оптимизированный машинный код для горячих функций с мономорфными типами; деоптимизация откатывает функцию к интерпретатору.