Что на самом деле делает зажигание V8?
На https://v8.dev/docs/ignition мы видим, что:
Ignition - это быстрый низкоуровневый интерпретатор на основе регистров, написанный с использованием бэкэнда TurboFan.
на https://docs.google.com/document/d/11T2CRex9hXxoJwbYqVQ32yIPMh0uouUZLdyrtmMoL44/edit?ts=56f27d9d
Целью проекта Ignition является создание интерпретатора для V8, который выполняет низкоуровневый байт-код, что позволяет более компактно сохранять однократный или не горячий код в виде байт-кода.
Сам интерпретатор состоит из набора фрагментов кода обработчика байт-кода, каждый из которых обрабатывает определенный байт-код и отправляет обработчику следующий байт-код. Эти обработчики байт-кода
Чтобы скомпилировать функцию в байт-код, код JavaScript анализируется для генерации его AST (абстрактного синтаксического дерева). BytecodeGenerator обходит этот AST и генерирует байт-код для каждого из узлов AST соответствующим образом.
После создания графика для обработчика байт-кода он пропускается через упрощенную версию конвейера Turbofan и присваивается соответствующей записи в таблице интерпретатора.
Таким образом, похоже, что задание Ignition заключается в том, чтобы взять байт-код, сгенерированный BytecodeGenerator, преобразовать его в обработчики байт-кода и выполнить его через Turbofan
,
Но здесь:
и здесь:
Вы можете видеть, что это зажигание производит байт-код.
Более того, в этом видео https://youtu.be/p-iiEDtpy6I?t=722 говорится, что Ignition является базовым компилятором.
Так что это? Базовый компилятор? Интерпретатор байт-кода? AST для преобразования байтового кода?
Это изображение кажется наиболее подходящим:
где зажигание - это просто интерпретатор, а все, что раньше, - генератор и оптимизатор байт-кода без имен.
2 ответа
Разработчик V8 здесь.
На https://v8.dev/docs/ignition мы видим, что:
Ignition - это быстрый низкоуровневый интерпретатор на основе регистров, написанный с использованием бэкэнда TurboFan.
Да, это подводит итог. Чтобы добавить немного больше деталей:
- Название "Зажигание" относится как к Генератору байт-кода, так и к интерпретатору байт-кода. Часто все это также рассматривается как один большой черный ящик и случайно называется "переводчик", что иногда может привести к некоторой путанице вокруг терминов.
- Генератор байт-кода берет AST, созданный анализатором для данной функции JavaScript, и генерирует из нее байт-код.
- Интерпретатор байт-кода берет байт-код, сгенерированный Генератором байт-кода, и исполняет его, интерпретируя его, отправляя его в набор обработчиков байт-кода.
- Обработчики байт-кода, которые составляют интерпретатор байт-кода, генерируются с использованием частей конвейера Turbofan. Это происходит во время компиляции V8, а не во время выполнения. Другими словами, вам нужен Turbofan для создания (частей) зажигания, но не для запуска зажигания.
- Парсер (и AST/ Абстрактное Синтаксическое Дерево, которое он производит, не являются частью Ignition.
После создания графика для обработчика байт-кода он пропускается через упрощенную версию конвейера Turbofan и присваивается соответствующей записи в таблице интерпретатора.
Таким образом, похоже, что работа Ignition заключается в том, чтобы взять байт-код, сгенерированный BytecodeGenerator, преобразовать его в обработчики байт-кода и выполнить его через Turbofan.
В этом разделе конструкторского документа говорится о генерации обработчиков байт-кода, что происходит "заранее" (т. Е. При компиляции V8) с использованием частей Turbofan. Во время выполнения байт-код не преобразуется в обработчики, он "обрабатывается" (= выполняется, выполняется, интерпретируется) существующим фиксированным набором обработчиков, и Turbofan не участвует.
Более того, в этом видео https://youtu.be/p-iiEDtpy6I?t=722 говорится, что Ignition является базовым компилятором.
В этот момент речь идет об общей идее о том, что все современные движки JavaScript имеют "базовый компилятор" (в очень общем, концептуальном смысле - я согласен, что слайд мог бы сделать это более понятным). Обратите внимание, что слайд ничего не говорит о зажигании. Следующий слайд говорит, что зажигание выполняет эту роль в V8. Поэтому точнее было бы сказать "Зажигание заменяет базовый компилятор" или "Зажигание - базовый механизм выполнения". Или вы можете немного переопределить свои термины и сказать: "Ignition - это компилятор, который создает байт-код, а затем интерпретирует его".
Зажигание - это просто интерпретатор, а все, что раньше, - генератор байтовых кодов без имен
На этом слайде показано поле "Интерпретатор" как часть "Конвейера байт-кода зажигания". Генератор / оптимизатор байт-кода также является частью Ignition.
Как я уже упоминал в комментарии, к сожалению, некоторые из документов устарели, в том числе тот, на котором вы видите первый рисунок выше. Full-codegen и Crankshaft больше не используются вообще, это просто разбор и Ignition + TurboFan. (вы удалили изображение из устаревших документов, которые, к сожалению, все еще связаны некоторыми документами V8)
Зажигание - это высокоскоростной интерпретатор байт-кода.
Парсер V8 производит байт-код Ignition. Этот байт-код выполняется (интерпретируется) зажиганием. Код, который выполняется только один раз (код запуска и т. Д.) Или не выполняется, часто остается на уровне байт-кода и продолжает выполняться Ignition.
"Горячий" код переходит ко второму этапу, когда TurboFan начинает работать: вход TurboFan - это тот же байт-код, который интерпретирует Ignition (а не исходный код, как это было с Crankshaft), который затем агрессивно компилируется в высокооптимизированный машинный код, который выполняется напрямую (а не интерпретировать).
Связанная статья посвящена мотивам перехода с Full-codegen и Crankshaft (экономия памяти в первом случае, трудности с реализацией и, в частности, оптимизация языковых функций во втором). Конструкция TurboFan также помогает авторам V8 минимизировать объем платформо-зависимого кода, который они должны писать (имея промежуточное представление, которое, помимо прочего, они также могут использовать для написания обработчиков байт-кода Ignition).
Исправьте мою ошибку в понимании процесса конвертации:
- Код JS анализируется в AST
- AST отправляется в Ignition для преобразования в байт-код
- Сгенерировать машинный код
- Если байт-код оптимален, отправьте его в ЦП для обработки
- Если байт-код требует оптимизации, он отправляется в Турбофан для оптимизации.
- Если Turbofan получил байт-код, он дополнительно оптимизируется и отправляется на компьютер для обработки.