stringtranslate.com

байт-код Java

Байт-код Java — это набор инструкций виртуальной машины Java (JVM), языка, на котором компилируется исходный код Java и других совместимых с JVM программ . [1] Каждая инструкция представлена ​​одним байтом , отсюда и название байт-код , что делает его компактной формой данных . [2]

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

Байт-код Java используется во время выполнения и либо интерпретируется JVM, либо компилируется в машинный код с помощью JIT -компиляции и запускается как собственное приложение.

Поскольку байт-код Java разработан для обеспечения кроссплатформенной совместимости и безопасности, приложение с байт-кодом Java имеет тенденцию работать одинаково на различных аппаратных и программных конфигурациях. [3]

Отношение к Java

В общем, программисту Java не нужно понимать байт-код Java или даже знать о нем. Однако, как предполагается в журнале IBM developerWorks, «Понимание байт-кода и того, какой байт-код, скорее всего, будет сгенерирован компилятором Java , помогает программисту Java так же, как знание ассемблера помогает программисту C или C++ ». [4]

Архитектура набора инструкций

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

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

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

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

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

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

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

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

Например, iaddбудет складывать два целых числа, в то время как daddбудет складывать два двойных числа. Инструкции const, load, и storeмогут также принимать суффикс в форме , где n — число от 0 до 3 для и . Максимальное n для отличается в зависимости от типа._nloadstoreconst

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

Пример

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

внешний : for ( int i = 2 ; i < 1000 ; i ++ ) { for ( int j = 2 ; j < i ; j ++ ) { if ( i % j == 0 ) continue external ; } System.out.println ( i ) ; }                              

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

0 : iconst_2 1 : istore_1 2 : iload_1 3 : sipush 1000 6 : if_icmpge 44 9 : iconst_2 10 : istore_2 11 : iload_2 12 : iload_1 13 : if_icmpge 31 16 : iload_1 17 : iload_2 18 : irem 19 : ifne 25 22 : goto 38 25 : iinc 2, 1 28 : goto 11 31 : getstatic #84; // Поле java/lang/System.out : Ljava/io/PrintStream; 34 : iload_1 35 : invokevirtual #85 ; // Метод java/io/PrintStream.println:(I)V 38 : iinc 1, 1 41 : переход к 2 44 : возврат                                       

Поколение

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

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

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

Исполнение

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

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

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

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

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

Ссылки

  1. ^ ab "Спецификация виртуальной машины Java". Oracle . Получено 14 ноября 2023 г.
  2. ^ ab Линдхольм, Тим (2015). Спецификация виртуальной машины Java . Oracle. ISBN 978-0133905908.
  3. ^ Арнольд, Кен (1996). «Язык программирования Java». Sun Microsystems . 1 (1): 30–40.
  4. ^ "IBM Developer". developer.ibm.com . Получено 20 февраля 2006 г. .
  5. ^ abcdefg Линдхольм, Тим; Йеллин, Фрэнк; Браха, Гилад; Бакли, Алекс (13 февраля 2015 г.). Спецификация виртуальной машины Java (Java SE 8 ред.).
  6. ^ "Домашняя страница Jasmin". jasmin.sourceforge.net . Получено 2 июня 2024 г. .
  7. ^ "Ямайка: Макроассемблер виртуальной машины Java (JVM)" . Получено 2 июня 2024 г. .
  8. ^ "Рассказчик/Кракатау". 1 июня 2024 г. Получено 2 июня 2024 г. - через GitHub.
  9. ^ "Lilac - ассемблер Java". lilac.sourceforge.net . Получено 2 июня 2024 г. .
  10. ^ "FPC New Features 3.0.0 - Free Pascal wiki". wiki.freepascal.org . Получено 2 июня 2024 г. .
  11. ^ "FPC JVM - Free Pascal wiki". wiki.freepascal.org . Получено 2 июня 2024 г. .
  12. Наттер, Чарльз (3 января 2007 г.). «InvokeDynamic: на самом деле полезен?» . Получено 25 января 2008 г.
  13. ^ "Программа Java Community Process (SM) - JSR: Запросы спецификации Java - подробный JSR# 292". www.jcp.org . Получено 2 июня 2024 г.

Внешние ссылки