← На главную

Инженер скопировал трюк из F18 и x87 в стековую VM с 8 слотами

20.05.2026 15:39 · hackernews

Инженер (автор статьи) экспериментирует с реализацией стековой виртуальной машины, где стек ограничен восемью слотами. Идею он подсмотрел у F18 Чака Мура и у x87: в этих архитектурах push/pop не перемещают данные, а просто меняют модульный счётчик, указывающий на вершину стека. Автор решает применить тот же трюк — примитивы VM дублируются для каждого из восьми возможных значений счётчика, а код каждого варианта размещается с фиксированным шагом в 4288 байт. Это позволяет индексировать регистры без лишних затрат.

Первым делом он исправляет стандартную последовательность NEXT в threaded VM: убирает бесполезные байты (было 14 байт, стало 9) и заменяет абсолютные адреса в байткоде на относительные смещения от базового адреса примитивов. Для генерации машинного кода используется SBCL — прямо в REPL SLIME, с недокументированными внутренностями. Так, для каждого примитива (swap, dup, drop, add, sub, jmp, call, ret, jnz, jz, lit, inc, dec) генерируются все восемь вариантов, разложенных по страницам.

Тестируется простой цикл: декрементировать счётчик и прыгать, пока не станет нулём. Для миллиона итераций разные версии дают от 15 до 6 циклов на итерацию. Специализированный примитив djn (декремент и прыжок, если не ноль) с условным move — 8,8 млн процессорных циклов; версия djn2 с явной ветвью и дублированием NEXT — 6,2 млн. Для сравнения, нативный ассемблерный код делает ту же работу за 1 млн циклов (1 цикл на итерацию). То есть накладные расходы VM — от 6 до 15 раз.

Автор заключает: специализация примитивов под небольшой стек — практичная техника с приемлемой производительностью. Его не интересуют чистые стековые языки, но такая VM может служить хорошим внутренним IR с механизмом локальных переменных. SBCL показал себя отличным инструментом для интерактивной генерации машинного кода; LuaJIT с dynasm скоро догонит.

Читать оригинал →