Байт-код 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. Примеры других компиляторов:
- Компилятор Eclipse для Java (ECJ)
- Jikes, компилируется из Java в байт-код Java (разработанный IBM, реализованный в C ++ )
- Espresso, компилируется из Java в байт-код Java (только для Java 1.0)
- Компилятор GNU для Java (GCJ), компилируется из Java в байт-код Java; он также может компилироваться в родной Машинный код и был частью Коллекция компиляторов GNU (GCC) до версии 6.
Некоторые проекты предоставляют ассемблеры Java, позволяющие писать байт-код Java вручную. Код сборки также может быть сгенерирован машиной, например компилятором, нацеленным на Виртуальная машина Java. Известные ассемблеры Java включают:
- Жасмин, берет текстовые описания для классов Java, написанные в простом синтаксисе, подобном ассемблере, с использованием набора команд виртуальной машины Java, и генерирует файл класса Java[3]
- Ямайка, а макрос язык ассемблера для Виртуальная машина Java. Синтаксис Java используется для определения класса или интерфейса. Тела методов указываются с помощью инструкций байт-кода.[4]
- Krakatau Bytecode Tools, в настоящее время содержит три инструмента: декомпилятор и дизассемблер для файлов классов Java и ассемблер для создания файлов классов.[5]
- Lilac, ассемблер и дизассемблер для Виртуальная машина Java.[6]
Другие разработали компиляторы для разных языков программирования для виртуальной машины Java, например:
- Холодный синтез
- JRuby и Jython, два языки сценариев на основе Рубин и Python
- Apache Groovy, необязательно типизированный и динамический язык общего назначения с возможностями статической типизации и статической компиляции
- Scala, типобезопасный язык программирования общего назначения, поддерживающий объектно-ориентированное и функциональное программирование.
- JGNAT и AppletMagic, скомпилировать из языка Ада в байт-код Java
- Компиляторы байтового кода C в Java[мертвая ссылка ]
- Clojure, функциональный неизменяемый язык программирования общего назначения на Лисп семья с упором на параллелизм
- Кава, реализация Схема язык программирования, также диалект Лисп.
- MIDletPascal
- Сценарий JavaFX код компилируется в байт-код Java
- Котлин, статически типизированный язык программирования общего назначения с выводом типа
- Object Pascal исходный код компилируется в байт-код Java с использованием Free Pascal 3.0+ компилятор.[7][8]
Исполнение
Сегодня доступно несколько машин, как бесплатных, так и коммерческих.
Если выполнение байт-кода Java на виртуальной машине Java нежелательно, разработчик также может скомпилировать исходный код Java или байт-код непосредственно в собственный машинный код с помощью таких инструментов, как Компилятор GNU для Java (GCJ). Некоторые процессоры могут выполнять байт-код Java изначально. Такие процессоры называют Процессоры Java.
Поддержка динамических языков
В Виртуальная машина Java оказывает некоторую поддержку динамически типизированные языки. Большая часть существующего набора инструкций JVM статически типизированный - в том смысле, что сигнатуры вызовов методов проверяются на время компиляции, без механизма, чтобы отложить это решение до время выполнения, либо выбрать способ отправки альтернативным подходом.[9]
JSR 292 (Поддержка динамически типизированных языков на платформе Java)[10] добавил новый invokedynamic
инструкция на уровне JVM, чтобы разрешить вызов метода, основанного на динамическом проверка типа (вместо существующего статически проверенного типа invokevirtual
инструкция). В Машина да Винчи - это прототип реализации виртуальной машины, в которой размещены расширения JVM, предназначенные для поддержки динамических языков. Все JVM с поддержкой JSE 7 также включают invokedynamic
код операции.
Смотрите также
- Списки команд байт-кода Java
- Файл класса Java
- Список языков JVM
- Инструменты резервного копирования Java
- Компиляторы виртуальных машин C в Java
- JStik
- Общий промежуточный язык (CIL), соперник байт-кода Java от Microsoft
- ObjectWeb ASM
- Инженерная библиотека байтового кода
Рекомендации
- ^ Понимание байт-кода делает вас лучшим программистом
- ^ а б c d е ж грамм Линдхольм, Тим; Йеллин, Франк; Браха, Гилад; Бакли, Алекс (13 февраля 2015). Спецификация виртуальной машины Java (Java SE 8-е изд.).
- ^ Домашняя страница Jasmin
- ^ Ямайка: ассемблер макросов виртуальной машины Java (JVM)
- ^ Домашняя страница Кракатау
- ^ Домашняя страница сирени
- ^ Примечания к выпуску Free Pascal 3.0
- ^ Free Pascal JVM Target
- ^ Наттер, Чарльз (2007-01-03). "InvokeDynamic: Действительно полезно?". Получено 2008-01-25.
- ^ см. JSR 292
внешняя ссылка
- Спецификация виртуальной машины Oracle Java
- Языки программирования для виртуальной машины Java
- Визуализатор байт-кода - средство просмотра и отладчик байт-кода (бесплатный плагин Eclipse)
- AdaptJ StackTrace - отладка на уровне байт-кода с полным контролем над стеком, локальными переменными и потоком выполнения
- Java Class Unpacker - плагин для Total Commander, он позволяет открывать файлы классов в виде сжатых архивов и видеть поля и методы как файлы. Байт-код можно просмотреть как текст с помощью F3.