Следующий набор псевдо-команд представляет быстрые варианты команд виртуальной машины языка Ява. Они используются, чтобы улучшить скорость интерпретирования байт-кодов. Они не являются частью описания виртуальной машины или множества инструкций, и невидимы вне реализации виртуальной машины языка Ява. Однако, внутри реализации виртуальной машины они используются для эффективной оптимизации.
Компилятор языка Ява — первоначальный
код из множества команд виртуальной машины языка Ява, которое состоит из non-_quick команд. Если используются _quick псевдо-команды, то каждое выполнение non-_quick команды с _quick вариантом является перезаписыванием с исполнением _quick варианта. Последующее выполнение этой команды будет иметь _quick вариант.Во всех случаях, если команда имеет альтернативную
версию с suffix _quick, команда ссылается на константный пул. Если используется _quick оптимизация, каждая non-_quick команда с _quick вариантом выполняет следующее:Это идентично действию команды
без _quick оптимизации, кроме дополнительного шага, в котором команда перезаписывает себя с _quick вариантом. _quick вариант команды присваивает себе то значение,которое уже было найдено в константном пуле, и что это решение не приводит к большинсву ошибок. Просто исполняется полученное действие на найденном элементе.Заметьте:
некоторые из описанных методов только поддерживают смещение байта со знаком в таблице объектов метода; для объектов с 256 или более методами некоторыевызовы не могут быть "убыстрены” только этими байткодами. Мы также нуждаемся в определении или изменении существующих
getfield и putfield байткодов, чтобы получить смещение более чем на байт.Это Приложение не дает значений кода операции для псевдо-команды, так как они невидимые и могут изменяться.
A.1 Обработка константного пула
Когда класс читается, создается массив
constant_pool размера nconstants и присваивается полю класса. constant_pool[0] устанавливается на точку динамически размещенного массива, которая указывает какие поля в constant_pool уже обработаны. Элементы от сonstant_pool[1] до сonstant_pool[nconstants - 1] устанавливаются, чтобы указывать на поле "типа", соответствующее данной константе.Когда выполняется инструкция, ссылающаяся на константный пул, генерируется индекс, и проверяется значение
constant_pool[0] чтобы узнать, разрешен ли уже этот индекс. Если да, то возвращается значение constant_pool[index]. Если нет, то значение constant_pool[index] определяется как фактический указатель или данные, и записывается в сonstant_pool[index].A. 2 Помещение констант на стек (_quick варианты)
ldc1_quick
Помещение элемента константного пула на стек
ldc1_quick |
indexbyte1 |
Стек: ... = > ..., item
indexbyte1 представляет собой беззнаковый 8-битный индекс константного пула текущего класса. item индекса помещается на стек.
ldc2_quick
Помещение элемента константного пула на стек
ldc2_quick |
indexbyte1 |
indexbyte2 |
Стек: ... = > ..., item
indexbyte1 и indexbyte2 используются для конструирования индекса константного пула текущего класса. Находится constant индекса и item его помещается на стек.
ldc2w_quick
Помещение длинного целого или числа с плавающей точкой двойной точности из константного пула на стек.
ldc2w_quick |
indexbyte1 |
indexbyte2 |
Стек: ... = > ..., constant-word1, constant-word2
indexbyte1 и indexbyte2 используются для конструирования индекса константного пула текущего класса. constant индекса помещается на стек.
A. 3 Управление массивами (_quick варианты).
anewarray_quick
Создание нового массива из ссылок на объекты.
anewarray_quick |
indexbyte1 |
indexbyte2 |
Стек: ..., size = > result
size должна быть целой. Она представляет собой число элементов в новом массиве.
indexbyte1 и indexbyte2 используются для построения индекса в константном пуле текущего класса. Вход должен быть классом.Новый массив обозначенного типа класса и допускающий размещение элементов полученого размера, result - есть ссылка на этот новый массив. Размещение достаточно большого массива пытается содержать размеры элементов, дающиеся типом класса. Все элементы массива инициализируются нулем
.Если размер меньше чем ноль, генерируется
NegativeArraySizeException . Если не достаточно памяти для размещения массива, генерируется OutOfMemoryError .multianewarray_quick
Размещение нового многомерного массива.
multianewarray_quick |
indexbyte1 |
indexbyte2 |
dimensions |
Стек: ..., size1, size2, ... sizen = > result
Каждая size должна быть целой.
Каждая представляет собой число элементов в размерности массива.indexbyte1 и indexbyte2 используются для построения индекса в константном пуле текущего класса. Результирующий вход должен быть классом.
dimensions имеют следующие аспекты:
Если любой из аргументов size на стеке - меньше чем ноль, генерируется
NegativeArraySizeException. Если не достаточно памяти для размещения массива, генерируется OutOfMemoryError.result - ссылка на новый объект массива.
Заметьте: Необходимо дать исчерпывающие объяснения относительно массива из массивов.
Управляющие объектные поля (_quick варианты)putfield_quick
Устанавливает поля в объекте
putfield_quick |
offset |
unused |
Стек: ..., objectref, value = > ...
objectref должна быть ссылкой на объект. value должно быть значением типа,
соответствующего определенному полю. offset - смещение для поля в этом объекте. value - значение, соответствующее этому offset в объекте. И objectref и value извлекаются из стека.
Если objectref пустая ссылка (
null ), то генерируется NullPointerException.putfield2_quick
Устанавливает длинное целое или двойное вещественное поле в объекте
putfield2_quick |
offset |
unused |
Стек: ..., objectref, value-word1, value-word2= > ...
objectref должна быть ссылкой на объект. value должно быть значением типа, соответствующего определенному полю. offset - смещение для поля в этом объекте. value - значение, соответствующее этому offset в объекте. И objectref и value извлекаются из стека.
Если objectref пустая ссылка (
null ), то генерируется NullPointerException.getfield_quick
Узнает значение поля объекта
getfield_quick |
offset |
unused |
Стек: ..., objectref =
> ..., value
objectref должна соответствовать объекту. Значение value, соответствующее
offset ввызываемом при помощи objectref объекте заменяет objectref, лежащую на вершине стека.
Если objectref пустая ссылка (
null ), то генерируется NullPointerException.getfield2_quick
Узнает значение поля объекта
getfield2_quick |
offset |
unused |
Стек: ..., objectref = > ..., value-word1, value-word2
objectref должна соответствовать объекту. Значение value, соответствующее
offset ввызываемом при помощи objectref объекте заменяет objectref, лежащую на вершине стека.
Если objectref пустая ссылка (
null), то генерируется NullPointerException.putstatic_quick
Устанавливает статическое поле в классе
putstatic_quick |
indexbyte1 |
indexbyte2 |
Стек: ..., value = > ...
indexbyte1 и indexbyte2 используются для формирования индекса в константном пуле
текущего класса. Элементом константного пула будет ссылка поля на статическое поле класса. Значение должно иметь тип, соответствующий этому полю. Поле будет установлено так, что в качестве значение у него будет value.
putstatic2_quick
Устанавливает статическое поле в классе
putstatic2_quick |
indexbyte1 |
indexbyte2 |
Стек: ..., value-word1, value-word2 = > ...
indexbyte1 и indexbyte2 используются для формирования индекса в константном пуле текущего класса. Элементом константного пула будет ссылка поля на статическое поле класса. Поле должно быть или длинным целым или вещественным числом двойной точности. Значение должно иметь тип, соответствующий этому полю. Поле будет установлено так, что в качестве значения у него будет value.
getstatic_quick
Узнает значение статического поля класса
getstatic_quick |
indexbyte1 |
indexbyte2 |
Стек: ..., = > ..., value
indexbyte1 и indexbyte2 используются для формирования индекса в константном пуле текущего класса. Элементом константного пула будет ссылка поля на статическое поле класса. Значение которого(того поля) заменяет обработчика в стеке.
getstatic2_quick
Узнает значение статического поля класса
getstatic2_quick |
indexbyte1 |
indexbyte2 |
Стек: ..., = > ..., value-word1, value-word2
indexbyte1 и indexbyte2 используются для формирования индекса в константном пуле текущего класса. Элементом константного пула будет ссылка поля на статическое поле класса. Поле должно быть длинным целым или вещественным числом двойной
точности. Значение этого поля заменяет обработчика в стеке.
A. 5 Вызов метода (_quick варианты)
invokevirtual_quick
Вызывает метод экземпляра, диспетчеризация основана на типе во время выполнения
invokevirtual_quick |
offset |
nargs |
Стек: ..., objectref, [arg1, [arg2 ...]] = > ...
Стек операндов должен содержать objectref, ссылку на объект и
параметры nargs-1. Определяется блок метода, соответствующий offset в таблице метода объекта,как определено динамическим типом объекта. Блок метода указывает тип метода
(исходный, синхронизированный, и т.д.).Если тип метода является
синхронизированным,то вводится монитор, связанный с объектом.Основа массива из локальных переменных для новой структуры стека Ява назначена, чтобы указывать на
objectref в стеке, создавая objectref и обеспечивающий параметры (arg1, arg2, ...) первые nargs локальные переменные новой структуры. Общее количество локальных переменных, используемых методом определено, и среда выполнения нового фрейма помещается на стек после того, как освободится достаточный участок памяти для локальных переменных. Основа стека операндов для этого метода вызова применяется к первому слову после среды выполнения. После этого(В заключение), выполнение продолжается с первой команды(ой), соответствующей методу.Если objectref является пустой (
null), то генерируется NullPointerException. При переполнении стека в течение метода вызывания генерируется StackOverflowError.invokevirtualobject_quick
Вызывает метод экземпляра из класса
java.lang.Object, определенного для увеличения(прибыли,пользы) массивов
invokevirtualobject_quick |
offset |
nargs |
Стек: ..., objectref, [arg1, [arg2 ...]] = > ...
Стек операндов должен содержать objectref, ссылка
на объект или на массив и параметры nargs-1. Определяется блок метода соответствующий offset в таблице метода java.lang.Object. Блок метода указывает тип метода (исходный, синхронизированный, и т.д.).Если тип метода является
синхронизированным, то вводится монитор связанный с обработчиком.Основа массива из локальных переменных для новой структуры стека Ява назначена, чтобы указывать на
objectref в стеке, создавая objectref и обеспечивающий параметры (arg1, arg2, ...) первые nargs локальные переменные новой структуры. Общее количество локальных переменных, используемых методом определено, и среда выполнения нового фрейма помещается на стек после того, как освободится достаточный участок памяти для локальных переменных. Основа стека операндов для этого метода вызова применяется к первому слову после среды выполнения. После этого(В заключение), выполнение продолжается с первой команды(ой), соответствующей методу.Если objectref является пустой (
null), то генерируется NullPointerException. При переполнении стека в течение метода вызывания генерируется StackOverflowError.invokenonvirtual_quick
Вызывает метод экземпляра, диспетчеризация которого основана
на собирать-разовом типе
invokenonvirtual_quick |
indexbyte1 |
indexbyte2 |
Стек: ..., objectref, [arg1, [arg2 ...]] = > ...
Стек операндов должен содержать objectref, ссылка
на объект и некоторыепараметры.
indexbyte1 и indexbyte2 используются для формирования индекса в константном пуле текущего класса. Элемент, соответствующий этому индексу в константном пуле содержит индекс слота метода и указатель на класс. Определяется блок метода, соответствующий индексу слота метода в обозначенном классе. Блок метода указывает тип метода (исходный, синхронизированный, и т.д.) и число параметров (nargs) ожидаемых в стеке операнда.Если тип метода является
синхронизированным, то вводится монитор, связанный с объектом.Основа массива из локальных переменных для новой структуры стека Ява назначена, чтобы указывать на
objectref в стеке, создавая objectref и обеспечивающий параметры (arg1, arg2, ...) первые nargs локальные переменные новой структуры. Общее количество локальных переменных, используемых методом определено, и среда выполнения нового фрейма помещается на стек после того, как освободится достаточный участок памяти для локальных переменных. Основа стека операндов для этого метода вызова применяется к первому слову после среды выполнения. После этого(В заключение), выполнение продолжается с первой команды(ой), соответствующей методу.Если objectref является пустой (
null), то генерируется NullPointerException. При переполнении стека в течение метода вызывания генерируется StackOverflowError.invokestatic_quick
Вызывает метод класса (статический)
invokestatic_quick |
indexbyte1 |
indexbyte2 |
Стек: ..., [arg1, [arg2 ...]] = > ...
Стек операндов должен содержать некоторое число параметров.
indexbyte1 и indexbyte2 используются для создания индекса в константном пуле текущего класса. Элемент, соответствующий индексу в константном пуле содержит индекс слота метода и указатель на класс. Определяется блок метода в индексе слота метода в обозначенном классе. Блок метода указывает тип метода (исходный, синхронизированный, и т.д.) и число параметров (nargs) ожидаемых в стеке операндов.Если тип метода является
синхронизированным, то вводится монитор, связанный склассом метода.
Основа массива из локальных переменных для новой структуры стека Ява назначена, чтобы указывать на первый параметр стека, обеспечивая параметры (
arg1, arg2, ...) первые nargs локальные переменные новой структуры. Общее количество локальных переменных, используемых методом определено, и среда выполнения нового фрейма помещается на стек после того, как освободится достаточный участок памяти для локальных переменных. Основа стека операндов для этого метода вызова применяется к первому слову после среды выполнения. После этого(В заключение), выполнение продолжается с первой команды(ой), соответствующей методу.Если objectref является пустой (
null), то генерируется NullPointerException. При переполнении стека в течение метода вызывания генерируется StackOverflowError.
invokeinterface_quick
Вызывает метод интерфейса
invokeinterface_quick |
idbyte1 |
idbyte2 |
nargs |
guess |
Стек: ..., objectref, [arg1, [arg2 ...]] = > ...
Стек операндов должен содержать objectref, ссылку на объект,
и параметры nargs-1. idbyte1 и idbyte2 используются для формирования индекса в константном пуле текущего класса. Элемент, соответствующий этому индексу в константном пуле содержит полную сигнатуру метода. Указатель на таблицу метода объекта определяется из дескриптора объекта.Сигнатуру метода ищут в таблице метода объекта. Как Сокращенный, сигнатуру метода в
guess слота ищут сначала. Если это не приводит к нужному результату, то производится полный поиск в таблице метода. Гарантируется, что сигнатура метода будет точно соответствовать одной из сигнатур метода в таблице.Результатом
поисковой таблицы является блок метода. Блок метода указывает тип метода (исходный, синхронизированный, и т.д.) но число доступных параметров (nargs) берется из байткода.Если тип метода является
синхронизированным, то вводится монитор, связанный с обработчиком.Основа массива из локальных переменных для новой структуры стека Ява назначена, чтобы указывать на
handle в стеке, создавая handle и обеспечивая параметры (arg1, arg2, ...) первые nargs локальные переменные новой структуры. Общее количество локальных переменных, используемых методом определено, и среда выполнения нового фрейма помещается на стек после того, как освободится достаточный участок памяти для локальных переменных. Основа стека операндов для этого метода вызова применяется к первому слову после среды выполнения. После этого(В заключение), выполнение продолжается с первой команды(ой), соответствующей методу.Если objectref является пустой (
null), то генерируется NullPointerException. При переполнении стека в течение метода вызывания генерируется StackOverflowError.guess
является последним guess(предположением). Периодически(Каждый раз через), guess(предположение) применяется к смещению метода, которое использовалось. Операции с различными объектами (_quick варианты)new_quick
Создает новый объект
new_quick |
indexbyte1 |
indexbyte2 |
Стек: ... = > ..., objectref
indexbyte1 и indexbyte2 используются для формирования индекса в константном пуле текущего класса. Элемент, соответствующий этому индексу, должен быть классом. Затем создается новый элемент(образец) этого класса и objectref, ссылка на этот объект, помещается в стек.
checkcast_quick
Проверяет принадлежности объекта данному типу
checkcast_quick |
indexbyte1 |
indexbyte2 |
Стек: ..., objectref = > ..., objectref
objectref должна быть ссылкой на объект.
indexbyte1 и indexbyte2 используются для формирования индекса в константном пуле текущего класса. Объект, соответветствующий этому индексу константного пула уже должен быть определен.checkcast
затем определяет, может ли objectref приводиться к ссылке на объект класса класса(класс объекта класса). Пустая (null) ссылка может приводиться к любомуклассу, и иначе суперклассы типа objectref ищут класс. Если класс определен, чтобы быть суперклассом типа objectref, или если objectref является пустой(null), он может приводиться к objectref, которая не может приводиться к классу, то генерируетсяClassCastException.
Заметьте: здесь (и вероятно в других местах) мы принимаем, что приведения не изменяют
ссылок; это - зависимая(не объективная) реализация.
instanceof_quick
instanceof_quick |
indexbyte1 |
indexbyte2 |
Проверяет принадлежность объекта данному типу
Стек: ..., objectref = > ..., result
objectref должна быть ссылкой на объект.
indexbyte1 и indexbyte2 используются для формирования индекса в константном пуле текущего класса. Объект, соответветствующий этому индексу константного пула уже должен быть определен.instanseof
определяет, может ли objectref приводиться к объекту класса класса(класс объекта класса). Пустая (null) ссылка может приводиться к любому классу, и иначе суперклассы типа objectref ищут класс. Если класс определен, чтобы быть суперклассом типа objectref, то result принимает значение 1(true). Иначе result принимает значение (false). Если программа обработки является пустой(null), то result принимает значени 0 (false).