Создание JIT-компилятора - PullRequest
13 голосов
/ 13 мая 2011

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

  1. Чтение входного файла brainfuck
  2. Выполнение тривиальной оптимизации
  3. Преобразование brainfuck в машинукод для ВМ
  4. Выполните этот машинный код в ВМ

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

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

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

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

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

Ответы [ 4 ]

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

  2. Есть некоторые ... Например. http://www.gnu.org/software/lightning/ - GNU Lightning (универсальная) и https://developer.mozilla.org/En/Nanojit - Nanojit, который используется в движках Firefox JavaScript JIT. Более мощным и современным JIT является LLVM, вам просто нужно перевести BF-код в LLVM IR, а затем LLVM может выполнить оптимизацию и генерацию кода для многих платформ или запустить LLVM IR на интерпретаторе (виртуальной машине) с возможностями JIT. Есть сообщение о BF & LLVM с полным JIT-компилятором LLVM для 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

5 голосов
/ 13 мая 2011

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

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

3 голосов
/ 13 мая 2011

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

1 голос
/ 14 августа 2018

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

JIT-компилятор имеет все шаги, которые есть у AOT-компилятора.Основное отличие состоит в том, что компилятор AOT выводит машинно-зависимый код в исполняемый файл, такой как exe и т. Д., В то время как JIT-компилятор загружает машинно-зависимый код в память во время выполнения (следовательно, это приводит к снижению производительности, поскольку каждый раз, когда ему нужно перекомпилировать и загружать).

Как JIT-компилятор загружает машинный код в память во время выполнения?

Я не буду учить вас машинному коду, потому что я предполагаю, что вы уже знаете об этом,

напримерассемблерный код

mov    rax,0x1

переводится в

48 c7 c0 01 00 00 00

, вы динамически генерируете переведенный код и сохраняете его в такой вектор (это вектор C)

vector machineCode{
   0x48, 0xc7, 0xc0, 0x01, 0x00, 0x00, 0x00, 
}

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

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

Извините, если что-то не понятно, вы всегда можете проверить этот пост для простоты https://solarianprogrammer.com/2018/01/10/writing-minimal-x86-64-jit-compiler-cpp/ https://github.com/spencertipping/jit-tutorial

...