Pull to refresh

Джаракан

Reading time4 min
Views729
Original author: Jens Lindström
Уже нескольких месяцев маленькая команда разработчиков и тестеров работает над созданием нового движка ECMAScript/JavaScript для Оперы. Когда текущий движок ECMAScript — Футарк был впервые предоставлен публике, он был самым быстрым на рынке. Футарк был разработан в основном для быстрого выполнения кода. Традиционно это правильный компромисс разных платформ под которыми работает Опера.  

Веб — это постоянно изменяющаяся среда и завтрашние продвинутые веб приложения требуют быстрого выполнения скриптов, поэтому Опера снова принимает участие в соревновании по разработке самого быстрого скриптового движка.  

Название Джаракан как и предыдущие названия движков даётся — это форма письменности. (Футарк — скандинавский алфавит; Джаракан, также известен как чаракан — слоговая письменность для яванского языка)

Усилия по улучшению сфокусированы по трём основных направлениям:

Байткод на регистрах



Последние поколения скриптовых движков Оперы использовали стэковую установку инструкции. Такой вид установки инструкций основывается на стеке значений, где большая часть инструкций берёт входящие операнды из значения стека, обрабатывает их и кладёт обратно в стэк. Некоторые инструкции просто либо кладут значения в стек, либо перемешивают значения в нём. Это даёт компактный байткод программ и обеспечивает простоту генерации байткода для них. (вообще стэк можно сравнить с этакой карточной колодой, наверх которой можно положить карты и снимать их от туда, но брать из середины и класть туда нельзя)

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

Генерация машинного кода



Несмотря на то, что новый способ установки инструкций в движке позволяет существенно ускорить выполнение байткода, всё ещё есть перегруженные операции с простым ECMAScript кодом, такие как циклы с целым числом в байткодовой интерпретации. Что бы справится с этими перегрузками мы реализовали компиляцию ECMAScript программ и функций в машинный код, целиком или частично.        

Компиляция машинного кода базируется на статическом анализе типов данных (с помощью средств лучших, чем обычно у ECMAScript), который выполняется для того, чтобы избавиться (там где это возможно) от лишних проверок типов, отложенного указания типов (с учётом неопределённых статических типов), и на распределителе регистров, который позволяет генерировать компактный машинный код  с помощью нескольких операций с регистрами и памятью.       

При работе с ECMAScript кодом, который на практике хорошо пригоден для конвертации в машинный код, наш сгенерированный код более-менее похож на код ассемблера написанный рукой, старающейся всё держать в регистрах.

Распределитель регистров разработан, чтобы исполнятся архитектурно независимо, так же как и генерация «конечного» машинного кода, что усложняет решения, который мы создаём. Сначала была реализована работа с 32 и 64х битной x86 архитиктурой, но уже началась предварительная работа, для генерации машинного кода, для других процессорных архитекрур, например, таких как ARM.

Ещё, кроме генерации машинного кода для стандартного ECMAScript, мы также генерируем машинный код, который ищет совпадения для простых регулярных выражений. Это очень увеличивает производительность при поиске совпадений в длинных строках для простых регулярных выражений. Для действительно длинных строк это делает поиск подстрок через регулярные выражения быстрее чем тот же поиск через String.prototype.indexOf. Для коротких строк скорость ограничена перегрузкой от компиляции регулярного выражения.

Генерация кода для более сложных регулярных выражений становится медленнее и даёт меньший выигрыш в производительности, потому что движок регулярных выражений достаточно быстр. Основа движка регулярных выражений разработана совсем недавно, но уже дебютировала в Престо 2.2. (Опера 10а). Можно сказать, что это обычный движок регулярных выражений, но делающий некоторые трюки, что бы избегать излишних возвратов, что даёт ему бо’льшую производительность.

Автоматическая классификация объектов



Другая область для большого увеличения производительности в нашем текущем движке — это другое представление объектов ECMAScript. В новом движке каждый объект закрепляется за классом, который в свою очередь собирается различную информацию об объекте, такую как прототип, порядок и имена некоторых или всех его свойств. Назначение классов объектам само по себе очень динамичная вещь, ведь ECMAScript динамичный язык, но он организован так, что объекты с одним прототипом и одинаковыми свойствами закрепляются за одним классом.

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

Общая таблица структур для свойств также улучшает поиск свойств между различными объектами. Для двух объектов с одним классом верно то, что если при поиске свойства «X» для первого объекта мы получаем результат «Y», то для второго объекта такой же поиск тоже даст «Y». Это используется, чтобы кэшировать выдачу для поиска индивидуальный свойств в программах ECMAScript, и это очень повышает производительность кода, содержащего множественные чтения или запись свойств.  

Производительность



Так насколько же быстр Джаракан? Используя стандартный кроссплатформенный механизм для быстрой отладки (без какого-либо сгенерированного машинного кода) Джаракан сейчас в 2,5 раза быстрее текущего движка ECMAScript в Престо 2.2 (Опера 10а). В данном случает стоит помнить, что Опера выпускает специальные версии для разных архитектур, а это немаловажно для производительности.

Генерация машинного кода в Джаракане ещё не готова для полномасштабного испытания, но несколько индивидуальных совместимых тестов показывают отрыв в 5 и 50 раз, что уже очень многообещающе.

Этот перевод редактировал zerobrain, чтобы она была написана на русском языке (аплодисменты). Пользуясь случаем также хочу попросить поправить карму хорошему человеку с ником enilight
Tags:
Hubs:
+41
Comments23

Articles