Стековая и регистровая архитектура виртуальной машины и Dalvik VM

Эта статья – перевод статьи

Виртуальная машина (VM) это абстракция над уровнем операционной системы, которая позволяет эмулировать физическую машину. Виртуальная машина позволяет запускать одну и ту же платформу под различными операционными системами и аппаратными архитектурами. Интерпретаторы Java и Python можно рассматривать как примеры, в которых код компилируется в специфический для их виртуальных машин байт код. Тоже можно наблюдать и в архитектуре Microsoft .Net, где код компилируется в промежуточный язык для CLR (Common Language Runtime).

Что должно входить в реализацию виртуальной машины? Она должна эмулировать операции физического процессора, а так же в идеале содержать следующие концепции:

  • компиляция исходного кода в специфический для данной виртуальной машины байткод
  • структуры данных для хранения инструкций и операндов (данные и процесс их обработки)
  • стек вызовов для выполнения операций в функции
  • “указатель инструкции” (IP) указывающий на следующию выполняемую инструкцию
  • виртуальный ЦП – обрабатывающего инструкции
    • доставляемые указателем инструкции
    • декодирование операндов
    • выполнение инструкции

Существует два основных способа реализации виртуальной машины: стековый и регистровый. Пример стековой виртуальной машины – виртуальная машина Java, .Net CLR, это широко используемый метод реализации виртуальной машины. В качестве регистровой виртуальной машины можно назвать Lua VM и Dalvik VM (которую мы кратко рассмотрим). Разница между этими двумя подходами в механизме используемом для записи и получения операндов и результатов выполнения команд.

Стековая виртуальная машина

Стековая виртуальная машина реализует основные, выше описанные свойства виртуальной машины, но в качестве структуры данных, куда помещаются операнды, используется стек. Операции получают данные из стека, обрабатывают их и заносят в стек результат по правилу LIFO (последний пришел, первый ушел). В стековой виртуальной машине, операция сложения двух чисел должна выполняться следующим способом (где 20, 7, и "результат" – операнды):

    POP   20
    POP   7
    ADD   20, 7, result
    PUSH  result

Из-за операций PUSH и POP для операции сложения требуется 4 инструкции. Преимущество стековой модели в том, что операнды задаются неявно указателем стека (на рисунке – SP). Это означает, что виртуальной машине не нужно явно указывать адреса операндов, указатель стека указывает на следующий операнд. В стековых виртуальных машинах все арифметические и логические операции выполняются посредством получения операндов и возврата результатов в стек.

Регистровые виртуальные машины

В регистровой реализации виртуальной машины структура данных, в которую помещаются операнды, основана на регистрах процессора. При этом не требуются операции PUSH или POP, но инструкции должны явно содержать адреса (регистры) в которых содержатся операнды. То есть, операнды для инструкций, в отличии от стековой модели, указываются явно. Например, операция сложения в регистровой виртуальной машине выглядит приблизительно так:

   ADD R1, R2, R3; # складывает содержимое R1 и R2, результат  заносит в R3

За счет отсутствия операций POP и PUSH команды в регистровой виртуальной машине выполняются быстрее аналогичных команд стековой виртуальной машины.

Другое преимущество регистровой модели в том что она позволяет провести оптимизацию, которая не может быть выполнена при стековом подходе. Например несколько раз встречающееся выражение при регистровом подходе может быть вычислено лиш однажды и сохранено в регистре для последующего использования, что экономит время необходимое для пересчета выражения.

Но с другой стороны в среднем инструкция регистровой машины длиннее чем в стековой машине, так как в ней тредуется явное указание операндов.

Интересная статья, в которой содержится простая реализация на С регистровой виртуальной машины. Если вы интересуетесь реализацией виртуальных машин и интерпретаторов то вас может заинтересовать книга автора ANTLR Теренса Парра "Language Implementation Pattern: Create your own domain-specific and general programming languages".

Виртуальная машина DALVIK

DALVIK – реализованная google виртуальная машина для Android и выполняющая функцию интерпретатора java кода на устройствах под управлением этой ОС. Для выполнения процесса Android создает отдельный экземпляр виртуальной машины. Это снижает вероятность краха системы при падении одного из приложений. Dalvik реализует регистровую модель и в отличаи от стандартного java байткода, который выполняет 8 битные инструкции на стековой JVM, использует 16 битные инструкции. Регистры реализованы в Dalvik в виде 4 битных полей.

Если мы хотим получить более детальную информацию о том как процесс получает экземпляр виртуальной машины, мы должны начать рассмотрение с момента загрузки ядра Linux в Android:

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

  • ядро запускает инициализирующую программу, которая является родительским процессом по отношении ко всем другим процессам.
  • инициализирующая программа запускает системные демоны и очень важный сервис "Зиготу".
  • процесс зиготы создает экземпляр Dalvik, являющийся прародителем всех экземпляров Dalvik в системе.
  • процесс зиготы так же запускает BSD сокет, который прослушивает входящие запросы.
  • при получении очередного запроса на создание нового экземпляра Dalvik VM, процесс зиготы разветвляет родительский Dalvik VM процесс и передает дочерний процесс запрашивающему приложению.

Это краткое описание того, как создается и используется виртуальная машина Dalvik в ОС Android.

Возвращаясь к теме виртуальных машин, Dalvik отличается от обычной виртуальной машины Java тем, что она выполняет байткод Dalvik, отличный от обычного java байткода. Промежуточный шаг между Java компилятором и Dalvik VM, на котором происходит преобразование Java байткода в байткод Dalvik берет на себя DEX компилятор. Раличие между JVM и Dalvik проилюстрировано на следующей диаграмме (заимствованной из книги – Learning Android).

DEX компилятор преобразует .class файлы java в .dex файлы, которые имеют меньший размер и оптимизированы для Dalvik VM.

В заключение …

Нельзя однозначно сказать, что стековая виртуальная машина лучше чем регистровая или наоборот. Этот вопрос остается дискуссионным и интересной областью для исследований. Вот интересная статья в которой автор реализует традиционную JVM как регистровую VM, и описывает некоторые полученные интересные результаты.

2 thoughts on “Стековая и регистровая архитектура виртуальной машины и Dalvik VM

  1. Pingback: Stack based vs Register based Virtual Machine Architecture, and the Dalvik VM | Forays in software development

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>