Байт-код Java - Java bytecode

Байт-код Java это Набор инструкций из Виртуальная машина Java (JVM).

Отношение к Java

А Ява программисту вообще не нужно знать или понимать байт-код Java. Однако, как предлагается в IBM журнал developerWorks, "Понимание байт-кода и того, какой байт-код может быть сгенерирован Компилятор Java помогает программисту на Java так же, как и знание сборка помогает C или же C ++ программист."[1]

Архитектура набора команд

JVM - это одновременно штабелеукладчик и зарегистрировать машину. Каждый Рамка для вызова метода есть «стек операндов» и массив «локальных переменных».[2]:2.6 Стек операндов используется для операндов для вычислений и для получения возвращаемого значения вызываемого метода, в то время как локальные переменные служат той же цели, что и регистры а также используются для передачи аргументов метода. Максимальный размер стека операндов и массива локальных переменных, вычисляемый компилятором, является частью атрибутов каждого метода.[2]:4.7.3 Каждый может иметь независимый размер от 0 до 65 535 значений, где каждое значение составляет 32 бита. длинный и двойной типы, которые являются 64-битными, занимают две последовательные локальные переменные[2]:2.6.1 (которые не должны быть выровнены по 64 бита в массиве локальных переменных) или одно значение в стеке операндов (но учитываются как две единицы в глубине стека).[2]:2.6.2

Набор инструкций

Каждый байт-код состоит из одного байта, который представляет код операции, а также ноль или более байтов для операндов.[2]:2.11

Из 256 возможных байтов коды операций, по состоянию на 2015 год, 202 используются (~ 79%), 51 зарезервированы для использования в будущем (~ 20%), а 3 инструкции (~ 1%) постоянно зарезервированы для использования реализациями JVM.[2]:6.2 Два из них (impdep1 и impdep2) должны обеспечивать ловушки для программного и аппаратного обеспечения, зависящего от реализации, соответственно. Третий используется отладчиками для реализации точек останова.

Инструкции делятся на несколько больших групп:

  • Загрузить и сохранить (например, aload_0, istore)
  • Арифметика и логика (например, лестница, fcmpl)
  • Преобразование типа (например, i2b, d2i)
  • Создание и управление объектами (новый, путфилд)
  • Управление стеком операндов (например, замена, dup2)
  • Передача управления (например, ifeq, идти к)
  • Вызов и возврат метода (например, вызывает особый, возвращение)

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

Многие инструкции имеют префиксы и / или суффиксы, относящиеся к типам операндов, с которыми они работают.[2]:2.11.1 Это следующие:

Префикс СуффиксТип операнда
яцелое число
лдлинный
sкороткая
ббайт
cперсонаж
жплавать
dдвойной
ассылка

Например, я добавить добавит два целых числа, а папа добавит два дубля. В const, нагрузка, и хранить инструкции также могут иметь суффикс в форме _п, куда п это число от 0 до 3 для нагрузка и хранить. Максимум п за const отличается по типу.

В const инструкции помещают значение указанного типа в стек. Например, iconst_5 поместит в стек целое число (32-битное значение) со значением 5, а dconst_1 поместит в стек двойное (64-битное значение с плавающей запятой) со значением 1. Также есть aconst_null, что подталкивает ноль ссылка. В п для нагрузка и хранить Инструкции задают индекс в массиве локальных переменных для загрузки или сохранения. В aload_0 инструкция помещает объект в локальной переменной 0 в стек (обычно это это объект). istore_1 сохраняет целое число наверху стека в локальную переменную 1. Для локальных переменных, превышающих 3, суффикс отбрасывается, и необходимо использовать операнды.

Пример

Рассмотрим следующий код Java:

внешний:за (int я = 2; я < 1000; я++) {    за (int j = 2; j < я; j++) {        если (я % j == 0)            Продолжить внешний;    }    Система.из.println (я);}

Компилятор Java может преобразовать приведенный выше код Java в байт-код следующим образом, предполагая, что это было помещено в метод:

0:   iconst_21:   istore_12:   iload_13:   сипуш  10006:   if_icmpge       449:   iconst_210:  istore_211:  iload_212:  iload_113:  if_icmpge       3116:  iload_117:  iload_218:  ирем19:  ifne    2522:  идти к    3825:  iinc    2, 128:  идти к    1131:  getstatic       #84; // Поле java / lang / System.out:Ljava / io / PrintStream;34:  iload_135:  invokevirtual   #85; // Метод java / io / PrintStream.println: (I) V38:  iinc    1, 141:  идти к    244:  возвращаться

Поколение

Самый распространенный языковой таргетинг Виртуальная машина Java путем создания байт-кода Java - это Java. Первоначально существовал только один компилятор, javac компилятор из Sun Microsystems, который компилирует Исходный код Java в байт-код Java; но поскольку теперь доступны все спецификации для байт-кода Java, другие стороны предоставили компиляторы, которые производят байт-код Java. Примеры других компиляторов:

Некоторые проекты предоставляют ассемблеры Java, позволяющие писать байт-код Java вручную. Код сборки также может быть сгенерирован машиной, например компилятором, нацеленным на Виртуальная машина Java. Известные ассемблеры Java включают:

  • Жасмин, берет текстовые описания для классов Java, написанные в простом синтаксисе, подобном ассемблере, с использованием набора команд виртуальной машины Java, и генерирует файл класса Java[3]
  • Ямайка, а макрос язык ассемблера для Виртуальная машина Java. Синтаксис Java используется для определения класса или интерфейса. Тела методов указываются с помощью инструкций байт-кода.[4]
  • Krakatau Bytecode Tools, в настоящее время содержит три инструмента: декомпилятор и дизассемблер для файлов классов Java и ассемблер для создания файлов классов.[5]
  • Lilac, ассемблер и дизассемблер для Виртуальная машина Java.[6]

Другие разработали компиляторы для разных языков программирования для виртуальной машины Java, например:

Исполнение

Сегодня доступно несколько машин, как бесплатных, так и коммерческих.

Если выполнение байт-кода Java на виртуальной машине Java нежелательно, разработчик также может скомпилировать исходный код Java или байт-код непосредственно в собственный машинный код с помощью таких инструментов, как Компилятор GNU для Java (GCJ). Некоторые процессоры могут выполнять байт-код Java изначально. Такие процессоры называют Процессоры Java.

Поддержка динамических языков

В Виртуальная машина Java оказывает некоторую поддержку динамически типизированные языки. Большая часть существующего набора инструкций JVM статически типизированный - в том смысле, что сигнатуры вызовов методов проверяются на время компиляции, без механизма, чтобы отложить это решение до время выполнения, либо выбрать способ отправки альтернативным подходом.[9]

JSR 292 (Поддержка динамически типизированных языков на платформе Java)[10] добавил новый invokedynamic инструкция на уровне JVM, чтобы разрешить вызов метода, основанного на динамическом проверка типа (вместо существующего статически проверенного типа invokevirtual инструкция). В Машина да Винчи - это прототип реализации виртуальной машины, в которой размещены расширения JVM, предназначенные для поддержки динамических языков. Все JVM с поддержкой JSE 7 также включают invokedynamic код операции.

Смотрите также

Рекомендации

  1. ^ Понимание байт-кода делает вас лучшим программистом
  2. ^ а б c d е ж грамм Линдхольм, Тим; Йеллин, Франк; Браха, Гилад; Бакли, Алекс (13 февраля 2015). Спецификация виртуальной машины Java (Java SE 8-е изд.).
  3. ^ Домашняя страница Jasmin
  4. ^ Ямайка: ассемблер макросов виртуальной машины Java (JVM)
  5. ^ Домашняя страница Кракатау
  6. ^ Домашняя страница сирени
  7. ^ Примечания к выпуску Free Pascal 3.0
  8. ^ Free Pascal JVM Target
  9. ^ Наттер, Чарльз (2007-01-03). "InvokeDynamic: Действительно полезно?". Получено 2008-01-25.
  10. ^ см. JSR 292

внешняя ссылка