Abstract

Modern JavaScript engines use just-in-time (JIT) compilation to produce binary code. JIT compilers are limited in a complexity of optimizations they can perform at a runtime without delaying an execution. Static ahead-of-time (AOT) compilers do not have such limitations, but they are not well suited for compiling dynamic languages such as JavaScript. In the paper, we discuss methods for augmenting multi-tiered JIT compiler with a capability for AOT compilation, and implement some of ahead-of-time compilation ideas in two JavaScript engines - JavaScriptCore and V8. In JavaScriptCore (JSC), which is a part of open-source WebKit library, we have developed and implemented a framework, which allows saving of JavaScript programs as a binary package containing bytecode and a native code. The framework consists of two components: command-line compiler, which compiles source JavaScript program into compressed binary package, consisting of JSC internal representation called bytecode and native code produced by JSC’s non-optimized JIT compiler. The second component is patched JSC engine with a capability for loading and executing binary packages produced by the compiler. In addition, we have implemented saving of optimized internal representation in another JavaScript engine, which is called V8 and is used in Chrome and many other browsers. When running the same JavaScript program, cached internal representation can be loaded to reduce JIT-compilation time and decrease percentage of running unoptimized code before it became hot.

Highlights

  • JIT compilers are limited in a complexity of optimizations they can perform at a runtime without delaying an execution

  • In JavaScriptCore (JSC), which is a part of open-source WebKit library, we have developed and implemented a framework, which allows saving of JavaScript programs as a binary package containing bytecode and a native code

  • The framework consists of two components: command-line compiler, which compiles source JavaScript program into compressed binary package, consisting of JSC internal representation called bytecode and native code produced by JSC’s non-optimized JIT compiler

Read more

Summary

Введение

В данной работе рассматриваются две виртуальных машины для языка JavaScript. Первая виртуальная машина называется JavaScriptCore (JSC) [1] и. Baseline JIT код используется как базовая версия кода для функций, которые скомпилированы с помощью оптимизирующего JIT-компилятора. На уровне Baseline JIT, как и на LLInt сохраняется профиль — информация о типах полей объектов и аргументов функций, и выполняется кэширование для ускорения доступа к полям объектов. Информация о профиле, собранная на уровнях Baseline JIT и LLInt используется для организации спекулятивного выполнения на следующем уровне оптимизации — оптимизации с использованием графа потока данных (Data flow graph, DFG JIT, Speculative JIT). При выполнении скрипта, в любой момент времени функции, eval-блоки и глобальный код в JSC могут выполняться на любой комбинации LLInt, Baseline JIT и DFG JIT кода. В особом случае при выполнении рекурсивных функций, код одной и той же функции может существовать на стеке вызовов в разных вариантах: в одном уровне функция выполняется на LLInt, в другом на Baseline JIT, в третьем на DFG. В виртуальной машине V8 так же имеется схема On-Stack Replacement, позволяющая переходить на оптимизированный код, не дожидаясь окончания выполнения функции, и позволяющая в случае ошибочных спекулятивных предположений перейти обратно на неоптимизированную версию машинного кода

Оптимизация производительности многоуровневого JIT
Реализация предварительной оптимизации в JavaScriptCore
Сохранение и загрузка байткода
Результаты AOTB
Сохранение машинного кода Baseline JIT
Предварительная оптимизация в виртуальной машине V8
Сохранение Lithium
Результаты
Заключение
Full Text
Published version (Free)

Talk to us

Join us for a 30 min session where you can share your feedback and ask us any queries you have

Schedule a call