Автор Тема: Улучшение производительности JavaScript с JägerMonkey  (Прочитано 1732 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн x-pilot

  • Редактор wiki
  • Сообщений: 9
    • Просмотр профиля
В августе 2008, Mozilla представила миру TraceMonkey. Новый движок, который мы добавили в Firefox 3.5, возвестил о новой эре производительности для построения следующего поколения веб бразуров и веб приложений. Сразу после представления нашего нового движка, Google представил V8 с Chrome. Apple также представила их собственный движок, который используется в Safari, и даже у Opera появился новый движок, который они представили с их последней бета версией браузера.

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

Мы, в Mozilla, узнали две вещи о том, как наш JavaScript движок взаимодействует с этими новыми приложениями:

   1. Во-первых, подход, который мы избрали с трассировкой имеет тенденцию к плохому взаимодействию с некоторыми типами кода. (К примеру, этот образец игры для NES выше, очень плохо выполняется в нашем движке – он является гигантской конструкцией switch.)
   2. А во-вторых, когда мы имем возможность “оставаться на тропе” (об этом ниже) TraceMonkey выигрывает против другого движка.

Движок от Mozilla фундаментально отличается от любого другого движка: все остальные используют то, что называется “JIT основанный на методах”. Это то, что забирает весь приходящий JS код, компилирует его в машинный код и затем исполняет его. Firefox использует “трассирующий JIT.” Мы интерпретируем весь приходящий JS код и записываем, как мы его интерпретируем. Когда мы определяем "горячий путь", мы представляем его в машинный код и затем исполняем эту внутреннюю часть. (Для большей информации о трассировке, посмотрите эту прошлогоднюю запись на hacks.)

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

Поэтому то, над чем мы работаем во втором поколении нашего движка - это комбинация лучших элементов обоих методов:

   1. Мы используем некоторые части из JS движка от WebKit и построим "полный, основанный на методах, JIT" для выполнения JavaScript кода. Это должно дать нам быструю производительность основной части JS, как и в других движках. И что самое главное, оно будет совместимым – больше никаких прыжков с и на трассировку, в результате чего тратилась большая часть времени из-за интерпретируемого кода.
   2. Мы выстрелим нашим трассирующим движком в тыл машинного кода для генерирования супер-быстрого кода для внутренних циклов. Это означает, что мы будем способны иметь преимущества трассирующего движка совместно с JIT, основанном на методах.

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

Вы можете найти больше информации об этом в блогах Дэвида Манделина (David Mandelin) и Дэвида Андерсона (David Anderson), а также на странице проекта для нового движка.

[Заметка: Данная статья является  вольным переводом статьи с Mozilla Hacks. Оригинальный автор - Кристофер Близзард (Christopher Blizzard), лицензия CC-BY-SA v3.0+]