>При работе JIT в процессе выполнения программы осуществляется перебор созданных интерпретатором инструкций байткода и копирование для каждой инструкции заранее скомпилированного машинного кода в область памяти с исполняемым кодом, а также изменение на лету инструкций для подстановки в них обрабатываемых данных (JIT копирует готовые шаблоны уже скомпилированных функций и подставляет в них необходимые значения, такие как аргументы и константы). При загрузке объектных файлов также осуществляется копирование машинного кода в память и подстановка внешних символов.Стековая машина что-ли? Я писал jit-компищятор на основе техники copy and patch. Было quick and dirty. Кончилось тем, что я это выкинул и написал x86-специфичный аллокатор регистров + энкодер инструкций (constexpr функции!) + constant size структуру для хранения инструкций + двухпроходный компилятор + кучу кода в inline assembly для интеграции отжитенного кода в остальную программу - все функции, вызываемые из горячего цикла пришлось в виде ассемблера в программу всунуть.
Пoтому что сишный и плюсовый код норовили заюзать регистры, которые я заюзал в jitе, зарезервировать их оказалось невозможно ни в gcc, ни в шланге (register type varName asm ("regName") не резервирует регистр!), сохранять на стеке перед каждым вызовом ВСЕ РЕГИСТРЫ (потому что компиляторы не имеют интерфейса, чтобы им сообщить свою calling convention для каждой функции и/или блока кода отдельно) ОЧЕНЬ тормознуто, при этом компилеро-сгенерированный код (по подстановкам в asm-блоках, не буду же я регистры напрямую юзать, это неудобно) не гнушался портить %rbp, поэтому пришлось всунуть его в clobber-list, теперь компилер орёт, что это deprecated.