Где хранить константы кода при написании JIT-компилятора?

Я пишу JIT-компилятор для x86-64, и у меня есть вопрос относительно наилучшей практики для включения констант в машинный код, который я генерирую.

Мой подход пока прост:

  • Выделите кусок памяти RW с помощью VirtualAlloc или же mmap
  • Загрузите машинный код в указанную область памяти.
  • Пометить страницу как исполняемую VirtualProtect или же mprotect (и удалите привилегию записи для безопасности).
  • Выполнить.

Когда я генерирую код, я должен включать константы (числовые, строковые), и я не уверен, как лучше всего это сделать. Я имею в виду несколько подходов:

  • Сохраните все константы как непосредственные значения в кодах операций инструкций. Это кажется плохой идеей для всего, кроме, может быть, небольших скалярных значений.
  • Выделите отдельную область памяти для констант. Мне кажется, что это лучшая идея, но она немного усложняет управление памятью и рабочий процесс компиляции — мне нужно знать расположение памяти, прежде чем я смогу начать писать исполняемый код. Также я не уверен, что это как-то влияет на производительность из-за плохой локальности памяти.
  • Храните константы в том же регионе, что и код и получить к нему доступ с помощью RIP-относительной адресации. Мне нравится такой подход, поскольку он объединяет соответствующие части программы, но мне немного неловко смешивать инструкции и данные.
  • Что-то совершенно другое?

Каков предпочтительный способ пойти по этому поводу?

1

Решение

Многое зависит от того, как вы генерируете свой двоичный код. Если вы используете JIT-ассемблер, который обрабатывает метки и определяет смещения, все довольно просто. Вы можете прикрепить константы в блоке после конца кода, используя относящиеся к ПК ссылки на эти метки, и в итоге получите один блок байтов с кодом и константами (простое управление). Если вы пытаетесь сгенерировать двоичный код на лету, у вас уже есть проблема выяснения, как обрабатывать прямые относительные ссылки на ПК (например, для прямых ветвей). Если вы используете обратное исправление, вам нужно расширить его для поддержки ссылок на ваш блок констант.

Вы можете избежать вычислений относительного смещения для ПК, поместив константы в отдельный блок и передав адрес этого блока в качестве параметра в свой код. Это в значительной степени «Выделите отдельный регион для констант», который вы предлагаете. Вам не нужно знать адрес блока, если вы передаете его в качестве аргумента.

4

Другие решения


По вопросам рекламы [email protected]