1 Архитектура виртуальной машины языка Ява
1.1 - Поддерживаемые типы данных
1.2 - Регистры
1.3 - Локальные переменные
1.4 - Стек операндов
1.5 - Среда выполнения
1.6 - Куча и сборщик мусора
1.7 - Область метода
1.8 - Набор инструкций Ява
1.9 - Ограничения
1.1 Поддерживаемые типы данных
Типы данных виртуальной машины содержат основные типы данных языка Ява:
byte // 1-байтовое со
знаком,представленное в дополнительном обратном
коде
short // 2-байтовое со знаком,представленное в
дополнительном обратном коде
int // 4-байтовое со
знаком,представленное в дополнительном обратном
коде
long // 8-байтовое со
знаком,представленное в дополнительном обратном
коде
float // вещественное число одинарной
точности стандарта IEEE 754, занимающее 4 байта
double // вещественное число двойной точности
стандарта IEEE 754, занимающее 8 байт
char // символ Unicode, занимающий 2 байта
В Яве проверка почти всех типов производится во время компиляции. Данные элементарных типов, указанных выше, не требуют аппаратной поддержки тегов чтобы обеспечит исполнение Ява-кода. Вместо этого, существуют байткоды, которые работают с элементарными значениями и указывают типы операндов, например, каждая из инструкций iadd, ladd, fadd, и dadd складывает два числа имеющих типы int, long, float, и double, соответственно.
Виртуальная машина не содержит отдельных инструкций для типов boolean. Вместо этого, используются инструкции для целых, включающие целочисленный return, используемый для работы с логическими переменными; массивы из байтов используются для массивов из логических.
Виртуальная машина устанавливает, что вещественные соответствуют формату IEEE 754 с поддержкой постепенной потери значимости. На более ранних компьютерных архитектурах, не поддерживающих IEEE формат, числовые программы Явы работают очень медленно.
Другие типы данных виртуальной машины включают:
object // ссылка на объект Явы, занимающая 4 байта
returnAddress // 4 байта, используемые с инструкциями
jsr/ret/jsr_w/ret_w
Заметьте: в Яве массивы трактуются как объекты.
Эта спецификация не определяет никакой внутренней структуры для объектов. В нашей реализации объектная ссылка - это дескриптор, который является парой указателей: один на таблицу методов для объекта, и другой на данные, соответствующие объекту. Другие реализации могут использовать встроенное кэширование вместо таблицы методов; такие методы, вероятно, будут работать быстрее на аппаратных средствах ЭВМ, которые будут появляться до 2000 года.
Программы, представленные байткодами Виртуальной Машины Ява, предполагают соблюдение соответствующей дисциплтны типов, и реализация может отказаться выполнять байткод-программу, если есть вероятность того, что она нарушает эту дисциплину.
Может показаться, что Виртуальная Машина языка Ява предусматривает исполнение байткода только на компьютерах 32-битной адресацией. Однако возможно построение версии Виртуальной Машины языка Ява, которая автоматически переводит байткоды в 64-битную форму. Описание такого преобразования не содержится в этой спецификации.
Виртуальная машина в любой момент времени выполняет код отдельного метода, и регистр PC содержит адрес следующего байткода, который будет выполнятся.
Для каждого метода выделяется место в памяти для хранения:
Все эти места могут быть отведены сразу, начиная с размера локальных переменных и стека операндов, определяемых во время компиляции, и размера структуры окружающей среды выполнения известного интерпретатору.
Все эти регистры 32 битные.
Каждый Ява-метод использует набор локальных переменных фиксированного размера. Они адресуются, как смещения слова от регистра vars. Ширина локальных переменных 32 бита.
Длинные целые и вещественные двойной точности рассматриваются, как располагающиеся в двух локальных переменных, и адресуются индексом первой локальной переменной. (Например, локальная переменная с индексом n содержащая вещественное двойной точности фактически занимает место, соответствующее индексам n и n + 1.) Спецификация виртуальной машины не требует выравнивания 64-битных значений локальных переменных на 64 битную границу. Разработчикам предоставляется право самим разделять длинные целые и вещественные двойной точности на два слова.
Инструкции обеспечивают загрузку значения локальных переменных в стек операндов и сохранение значений из стека операндов в локальных переменных.
Все инструкции машины берут операнды от стека операндов, работают с ними, и возвращают результат обратно в стек. Мы выбрали стековую организацию так, чтобы было легко эффективно эмулировать машину на машинах
с немногими регистрами или при нерегулярном наборе регистров типа Intel 486.Ширина стека операндов 32 бита. Он используется для передачи параметров методам и получения результатов метода, а также и для обеспечения действий с параметрами и сохранения результатов действий.
Например, инструкция iadd складывает два целых. Для этого ей необходимо, чтобы целые были в двух словах на вершине стека, помещенные туда предыдущими инструкциями. Оба целых извлекаются из стека, складываются, и их сумма помещается обратно в стек операндов. Промежуточные значения хранятся в стеке опреандов, что обеспечивает поддержку вложенных вычислений.
Каждый простейший тип данных имеет специализированные инструкции, которые знают как работать с операндами этого типа. Каждый операнд требует одной ячейки на стеке, кроме long и double, которым необходимо две ячейки.
Операнды должны использоваться операциями, соответствующими их типу. Например, нельзя помещать на стек два целых и потом использовать их как длинный целый. в реализации Sun это ограничение контролируется верификатором байткода. Однако, нескоторые операции (коды операции dup и swap) работают с областями данных как со значениями данной ширины, не обращая внимания на тип.
Ниже в нашем описании инструкций виртуальной машины результат выполнения инструкции на стеке операндов представлен текстуально, каждое 32-битное слово на стеке записывается отдельно, в порядке слева направо. Таким образом:
Стек: ..., value1, value2 = > ..., value3
показывает действие, которое начинается при наличии value2 на вершине стека и
value1 под ним. В результате выполнения инструкции, value1 и value2 извлекаются из стека и заменяются на value3, которое было вычислено инструкцией. Остаток стека, представленный многоточием, не затрагивается при выполнении инструкции.
Типы long и double занимают два 32-битных слова на стеке операндов:
Стек: ... = > ..., value-word1, value-word2
Эта спецификация не описывает, как два слова выделяются из 64-битного long или double; надо только учитывать, чтобы конкретная реализация была внутренне непротиворечивой.
Информация, содержащаяся в среде выполнения используется для динамической компоновки, нормальных возвратов из методов, и распространения исключений.
Динамическая компоновка
Среда выполнения содержит ссылки на таблицу символов интерпретатора для текущего метода и класса, для поддержки динамической компоновки кода метода. Код файла класса для метода обращается к методам, которые будут вызваны и к переменным, используя символические ссылки . Динамическая компоновка переводит эти символические вызовы методов в фактические вызовы методов, загружая классы по мере необходимости, для разрешения неопределенных ссылок, и переводит обращения к переменным в соответствующие смещения
в структурах хранения, соответствующие размещению этих переменных во время выполнения.Это позднее связывание методов и переменных делает менее вероятным нарушения в данном методе при изменениях классов, которые использует этот метод.
Нормальные возвраты из методов
Если выполнение текущего метода заканчивается, то значение возвращается в вызывающий метод. Это происходит когда вызываемый метод выполняет инструкцию возврата, соответствующую возвращаемому типу.
Среда выполнения используется в этом случае, чтобы восстановить регистры вызывающей программы и увеличить программный счетчик вызывающей программы для пропуска инструкции вызова метода. Выполнение продолжается в среде выполнения вызывающего метода.
Исключение и распространение ошибки
Исключительные состояния, известные в Яве как Error или Exception, являются подклассами Throwable и могут возникать в программе из-за:
Когда генерируется исключение:
Дополнительная информация
Среда выполнения может быть расширена
дополнительной информацией специфической реализации, такой как отладочная информация.Куча в Яве является областью данных времени выполнения, в которой размещаются экземпляры классов (объекты). В языке Ява предусмотрен сборщик мусора - это дает программисту возможность не освобождать память для объектов явно. Ява не предполагает никакого конкретного варианта сборщика мусора; могут
использоваться различные алгоритмы в зависимости от требований системы.Область метода аналогична месту в памяти, которое отводится для компилируемого кода в обычных языках или текстовому сегменту в процессе UNIX. Она хранит код метода (скомпилированный Ява-код) и таблицы символов. В текущей реализации Явы код метода - это не часть кучи, обслуживаемой сборщиком мусора, хотя это планируется сделать в следующем выпуске.
1.8 Набор инструкций языка Ява
Инструкция в наборе инструкций языка Ява состоит из однобайтового кода операции, определяющего действие, которое будет выполнено, и также может содержать операнды, являющиеся параметрами или данными, которые будут использоваться этой операцией. Многие инструкции не содержат операндов и состоят только из кода операции.
Внутренний цикл исполнения виртуальной машины эффективен:
do {
выбор байт кода операции
выполнение действия в зависимости от
значения кода
} while (еще нужно выполнять);
Число и размер дополнительных операндов определяется кодом операции. Если дополнительный операнд содержит более одного байта, то они хранятся в порядке от старшего к младщему - первым является старший байт. Например, 16-битный параметр хранится как два байта, значение которого:
first_byte * 256 + second_byte
Поток команд байткода выравнивается только по границе байта, за исключением инструкций tableswitch и lookupswitch, которые выравниваются по 4-байтовой границе в пределах этих инструкций.
Эти соглашения сохраняют код виртуальной машины для скомпилированных Ява-программ компактным и отражают преимущественное стремление к компактности.
На один класс в константном пуле отводится максимум 65535 элементов. Это ограничение является внутренним пределом для общей сложности одного класса.
Длина кода метода ограничена 65535 байтами, определяемыми размерами индексов в коде, в таблице исключений, таблице номеров строк и таблице локальных переменных. Это может быть зафиксировано для 1.0beta2.
Кроме этого предела, существует только одно ограничение - число слов аргументов в вызове метода ограничено 255.