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

Без JIT в V8

· 3 мин. чтения
Якоб Грубер ([@schuay](https://twitter.com/schuay))

V8 версии 7.4 теперь поддерживает выполнение JavaScript без выделения исполняемой памяти во время выполнения.

В своей стандартной конфигурации V8 сильно зависит от возможности выделять и изменять исполняемую память во время выполнения. Например, оптимизирующий компилятор TurboFan создает машинный код для «горячих» функций JavaScript (JS) непосредственно перед выполнением, а большинство регулярных выражений JS компилируются в машинный код с помощью движка irregexp. Создание исполняемой памяти во время выполнения — одна из ключевых причин высокой скорости V8.

Но в некоторых ситуациях может быть полезно запускать V8 без выделения исполняемой памяти:

  1. Некоторые платформы (например, iOS, смарт-телевизоры, игровые консоли) запрещают доступ на запись к исполняемой памяти для приложений без привилегий, что до сих пор делало использование V8 невозможным; и
  2. запрет на запись в исполняемую память снижает поверхность атаки приложения для эксплуатации уязвимостей.

Новый режим V8 без JIT предназначен для решения этих задач. Когда V8 запускается с флагом --jitless, V8 работает без какого-либо выделения исполняемой памяти во время выполнения.

Как это работает? По сути, V8 переключается в режим только интерпретации, используя существующие технологии: весь пользовательский код JS выполняется через интерпретатор Ignition, а сопоставление шаблонов регулярных выражений также интерпретируется. Веб-ассемблер в настоящее время не поддерживается, но интерпретация — это тоже возможный вариант. Встроенные функции V8 по-прежнему компилируются в машинный код, но больше не являются частью управляемой кучи JS благодаря нашим последним усилиям по встраиванию их в бинарный файл V8.

В конечном итоге эти изменения позволили нам создать кучу V8 без необходимости предоставления исполняемых разрешений для любых ее регионов памяти.

Результаты

Поскольку режим без JIT отключает оптимизирующий компилятор, он приводит к потере производительности. Мы изучили различные тесты, чтобы лучше понять, как изменяются характеристики производительности V8. Speedometer 2.0 предназначен для отображения типичного веб-приложения; Web Tooling Benchmark включает набор распространенных инструментов разработчика JS; мы также добавили тест, которые симулирует рабочий процесс просмотра в приложении YouTube для гостиной. Все измерения проводились локально на x64 Linux настольном компьютере в течение 5 запусков.

Без JIT против стандартного V8. Результаты нормализованы до 100 для стандартной конфигурации V8.

Speedometer 2.0 примерно на 40% медленнее в режиме без JIT. Примерно половина падения производительности связана с отключенным оптимизирующим компилятором. Другая половина вызвана интерпретатором регулярных выражений, который изначально был разработан как средство отладки и будет улучшен в будущем.

Web Tooling Benchmark, как правило, требует больше времени на выполнение кода, оптимизированного с помощью TurboFan, и показывает большую потерю производительности в 80%, когда включен режим без JIT.

Наконец, мы измерили симулированную сессию просмотра в приложении YouTube для гостиной, которая включает воспроизведение видео и навигацию по меню. Здесь режим без JIT примерно сопоставим и показывает только 6% замедление выполнения JS по сравнению с стандартной конфигурацией V8. Этот тест демонстрирует, что производительность оптимизированного кода не всегда коррелирует с реальной производительностью, и во многих ситуациях встроенные приложения могут поддерживать приемлемую производительность даже в режиме без JIT.

Потребление памяти изменилось незначительно, со снижением медианы на 1,7% размера кучи V8 при загрузке представительного набора веб-сайтов.

Мы рекомендуем встроенным приложениям на ограниченных платформах или с особенными требованиями безопасности рассмотреть новый режим без JIT для V8, доступный сейчас в версии V8 7.4. Как всегда, вопросы и отзывы приветствуются в группе обсуждения v8-users.

Часто задаваемые вопросы

В чем разница между --jitless и --no-opt?

--no-opt отключает оптимизирующий компилятор TurboFan. --jitless отключает любое выделение исполняемой памяти во время выполнения.