Какую оптимизацию выполняют современные JavaScript-движки?

В настоящее время большинство основных браузеров приступили к интеграции оптимизирующих компиляторов JIT с их интерпретаторами/виртуальными машинами. Это хорошо для всех. Теперь мне было бы трудно узнать, какие именно оптимизации они выполняют, и как их лучше всего использовать. Что такое ссылки на оптимизацию в каждом из основных движков JavaScript?

Фон:

Я работаю над компилятором, который генерирует JavaScript с более высокого уровня и более безопасного языка (бесстыдный плагин: он называется OPA, и он очень круто), и, учитывая размер приложений, которые я создаю, я бы хотел, чтобы мой код JavaScript был таким же быстрым и максимально эффективным с точки зрения памяти. Я могу обрабатывать высокоуровневые оптимизации, но мне нужно знать больше о том, какие исполнения выполняются, чтобы узнать, какой низкоуровневый код принесет наилучшие результаты.

Один пример, с моей точки зрения: язык, который я собираю, скоро интегрирует поддержку лени. Могут ли двигатели JIT хорошо себя вести с ленивыми определениями функций?

Ответы

Ответ 1

В этой серии статей обсуждаются оптимизация V8. Вкратце:

  • Он генерирует собственный машинный код - не байт-код (элементы дизайна V8)
  • Точная сборка мусора (Wikipedia)
  • Встроенное кэширование вызываемых методов (Wikipedia)
  • Сохранение информации о переходе класса, чтобы объекты с одинаковыми свойствами были сгруппированы вместе (Элементы дизайна V8)

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

В этом сообщении в блоге обсуждаются некоторые из оптимизаций SquirrelFish Extreme:

  • Оптимизация Bytecode
  • Полиморфный встроенный кеш (например, V8)
  • Контекстная резьба JIT (введение генерации собственного машинного кода, например V8)
  • Регулярное выражение JIT

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