Создание JIT-компилятора

Я написал реализацию Brainfuck (С++), которая работает следующим образом:

  • Прочитать входной файл brainfuck
  • Выполняют тривиальные оптимизации
  • Преобразуйте мозговой код в машинный код для VM
  • Выполнить этот машинный код в VM

Это довольно быстро, но узкое место теперь находится на виртуальной машине. Он написан на С++ и читает токен, выполняет действие (которого не так много, если вы знаете Brainfuck) и т.д.

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

Это означало бы, что шаг 3 заменяется компилятором JIT и шагом 4 с выполнением сгенерированного машинного кода.

Я не знаю, с чего начать, поэтому у меня есть несколько вопросов:

  • Как это работает, как выполняется сгенерированный машинный код?
  • Существуют ли библиотеки С++ для генерации собственного машинного кода?

Ответы

Ответ 1

  • Сгенерированный машинный код просто jmp -ed или call -ed как обычная функция. Иногда также требовалось отключить флаг отсутствия выполнения (бит NX) в памяти, содержащий сгенерированный код. В linux это делается с помощью mprotect(addr, size, PROT_READ | PROT_WRITE | PROT_EXEC.) В окнах NX называется DEP.

  • Есть некоторые... например. http://www.gnu.org/software/lightning/ - GNU Lightning (универсальный) и https://developer.mozilla.org/En/Nanojit - Nanojit, который используется в JavaScript JavaScript JIT. Более мощным и современным JIT является LLVM, вам просто нужно перевести BF-код в LLVM IR, а затем LLVM может делать оптимизацию и генерировать код для многих платформ или запускать LLVM IR на интерпретаторе (виртуальной машине) с возможностями JIT. Существует сообщение о BF и LLVM с полным компилятором LLVM JIT для BF http://www.remcobloemen.nl/2010/02/brainfuck-using-llvm/

Другой компилятор BF + LLVM находится здесь, в svn LLVM: https://llvm.org/svn/llvm-project/llvm/trunk/examples/BrainF/BrainF.cpp

Ответ 2

LLVM - полная библиотека С++ (или набор библиотек) для генерации собственного кода из промежуточной формы, в комплекте с документацией и примерами, и который использовался для создания JITters.

(Он также имеет компилятор C/С++, который использует фреймворк - однако сама фрейм может использоваться для других языков).

Ответ 4

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