Целью настоящего проекта явилась разработка простой и удобной в использовании платформы для машинно-независимого исполнения программного кода в стековой виртуальной машине с поддержкой JIT-компиляции в машинный код центрального процессора Intel x86_64. Работа выполнена на языке C++ без использования каких-либо библиотек помимо стандартной, что позволило обеспечить кроссплатформенность проекта на уровне исходного кода наряду с достаточно высокой скоростью работы и простотой реализации. Платформа выполнена в соответствии с модульным конвейерным подходом. В её состав входят уровень абстракции от ОС, неизменяемое ядро, реализующее пользовательское API и определяющее межмодульные интерфейсы, и набор модулей, каждый из которых реализует определённый функциональный интерфейс. Задачей уровня абстракции является переопределение ОС-зависимых реализаций некоторых вспомогательных методов для каждой распространённой ОС и обеспечение "заглушек" для неподдерживаемых систем. Основной конвейер, реализующий клиентское API, находится в составе ядра. Он состоит из четырёх шагов: загрузка исходного текста, сохранение частичного промежуточного образа, компоновка и исполнение байт-кода в виртуальной машине; на последнем этапе вместо исполнения в виртуальной машине возможна передача данных в JIT-транслятор. Абстракция от языка исходного текста обеспечивается путём трансляции кода в промежуточное представление (байт-код), с которым и происходит дальнейшая работа. Байт-код, полученный в результате считывания одного исходного файла, помещается в так называемый контекст исполнения. Каждый контекст в дальнейшем можно объединить с любым количеством других загруженных контекстов, за счёт чего обеспечивается возможность раздельной компиляции и объединения исходных текстов, написанных на разных языках программирования. Также существует возможность сериализации контекстов в файл, по структуре похожий на объектный файл, и загрузки таких "объектных файлов" в полнофункциональные контексты. Исполнение контекста возможно с помощью стековой виртуальной машины со строгой типизацией, изменяемым командным набором и возможностью программного управления исполнением (в т. ч. трассировки) с помощью перехвата соответствующих методов в интерфейсе модуля логики исполнения. Необходимо заметить, что скорость исполнения не является основным требованием, предъявляемым к виртуальной машине, и в том случае, если она недостаточно высока для конкретной задачи, возможно использование JIT-транслятора для построения машинного образа и исполнения кода непосредственно на центральном процессоре. В настоящий момент с помощью уровня абстракции реализована отладочная печать, выделение памяти с необходимыми правами доступа для исполнения JIT-компилированного машинного кода и подсистема безопасной обработки исключительных ситуаций (сигналов). Последнее особенно важно при исполнении сгенерированного машинного кода, так как почти никаких проверок в этом режиме не производится. Перехват же исключения ошибки сегментации позволяет в случае неполадок корректно завершить выполнение приложения или же передать управление интерпретатору для безопасного исполнения проблемного кода. Презентация Исходный текст в репозитории: GitHub.com/intelfx/Homework_2011 (ветка "master") Материалы доклада
|