Из Википедии, свободной энциклопедии
Перейти к навигации Перейти к поиску

Java байт - код является набором команд из виртуальной машины Java (JVM).

Отношение к Java [ править ]

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

Архитектура набора команд [ править ]

JVM является одновременно стековой и регистровой машиной . Каждый кадр для вызова метода имеет «стек операндов» и массив «локальных переменных». [2] : 2.6 Стек операндов используется для операндов для вычислений и для получения возвращаемого значения вызываемого метода, в то время как локальные переменные служат той же цели, что и регистры, и также используются для передачи аргументов метода. Максимальный размер стека операндов и массива локальных переменных, вычисляемый компилятором, является частью атрибутов каждого метода. [2] : 4.7.3 Каждое значение может иметь независимый размер от 0 до 65 535, где каждое значение составляет 32 бита. longиdoubleтипы, которые являются 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)
  • Арифметика и логика (например ladd, fcmpl)
  • Преобразование типа (например i2b, d2i)
  • Создание и управление объектами ( new, putfield)
  • Управление стеком операндов (например swap, dup2)
  • Передача управления (например ifeq, goto)
  • Вызов и возврат метода (например invokespecial, areturn)

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

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

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

В constинструкции нажать значение указанного типа в стек. Например, iconst_5поместит в стек целое число (32-битное значение) со значением 5, а dconst_1двойное (64-битное значение с плавающей запятой) со значением 1 в стек. Также есть aconst_null, который подталкивает nullссылку. П для 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 ;  }  Система . из . println  ( я ); }

Компилятор 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 :  goto  2 44 :  return

Поколение [ править ]

Наиболее распространенным языком, нацеленным на виртуальную машину 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 Compiler for Java (GCJ), компилирует из Java в байт-код Java; он также может компилироваться в собственный машинный код и был частью коллекции компиляторов GNU (GCC) до версии 6.

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

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

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

  • Холодный синтез
  • JRuby и Jython , два языка сценариев, основанные на Ruby и Python
  • Apache Groovy , необязательно типизированный и динамический язык общего назначения с возможностями статической типизации и статической компиляции
  • Scala , типобезопасный язык программирования общего назначения, поддерживающий объектно-ориентированное и функциональное программирование.
  • JGNAT и AppletMagic, компилируют с языка Ada в байт-код Java
  • Компиляторы байтового кода C в Java [ мертвая ссылка ]
  • Clojure , функциональный неизменяемый язык программирования общего назначения из семейства Lisp с упором на параллелизм.
  • Kawa , реализация языка программирования Scheme , также являющегося диалектом Lisp .
  • MIDletPascal
  • Код JavaFX Script компилируется в байт-код Java
  • Kotlin , статически типизированный язык программирования общего назначения с выводом типа
  • Исходный код Object Pascal компилируется в байт-код Java с помощью компилятора Free Pascal 3.0+. [7] [8]

Казнь [ править ]

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

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

Поддержка динамических языков [ править ]

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

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

См. Также [ править ]

  • Списки инструкций по байт-коду Java
  • Файл класса Java
  • Список языков JVM
  • Инструменты резервного копирования Java
  • Компиляторы виртуальных машин C в Java
  • JStik
  • Common Intermediate Language (CIL), соперник Microsoft для байт-кода Java
  • ObjectWeb ASM
  • Инженерная библиотека байтового кода

Ссылки [ править ]

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

Внешние ссылки [ править ]

  • Спецификация виртуальной машины Oracle Java
  • Языки программирования для виртуальной машины Java
  • Визуализатор байт-кода - просмотрщик и отладчик байт-кода (бесплатный плагин Eclipse)
  • AdaptJ StackTrace - отладка на уровне байт-кода с полным контролем над стеком, локальными переменными и потоком выполнения
  • Java Class Unpacker - плагин для Total Commander, он позволяет открывать файлы классов как сжатые архивы и видеть поля и методы как файлы. Байт-код можно просмотреть как текст с помощью F3.