stringtranslate.com

código de bytes de Java

El código de bytes de Java es el conjunto de instrucciones de la máquina virtual Java (JVM), crucial para ejecutar programas escritos en el lenguaje Java y otros lenguajes compatibles con JVM. [1] Cada operación de código de bytes en la JVM está representada por un solo byte, de ahí el nombre " código de bytes ", lo que la convierte en una forma compacta de instrucción. [2] Esta forma intermedia permite que los programas Java sean independientes de la plataforma, ya que no se compilan en código de máquina nativo sino en un formato universalmente ejecutable en diferentes implementaciones de JVM.

La JVM interpreta este código de bytes o lo compila sobre la marcha en código de máquina nativo utilizando un compilador Just-In-Time (JIT), mejorando el rendimiento de las aplicaciones Java. El diseño del código de bytes de Java apunta a un alto grado de compatibilidad y seguridad entre plataformas, ejecutado dentro del entorno controlado de la JVM. Esta arquitectura permite que las aplicaciones Java se ejecuten de manera consistente en varias configuraciones de hardware y software. [3] Si bien los programadores de Java normalmente no interactúan directamente con el código de bytes, comprender su estructura y ejecución puede ser ventajoso para fines de optimización y depuración.

En la JVM, el código de bytes de Java opera como un conjunto de instrucciones tanto para una máquina de pila como para una máquina de registro, utilizando una pila de operandos y variables locales para ejecutar operaciones. [2] El código de bytes comprende varios tipos de instrucciones, incluida la manipulación de datos, la transferencia de control, la creación y manipulación de objetos y la invocación de métodos, todos ellos integrales al modelo de programación orientada a objetos de Java. [1]

Relación con Java

Un programador de Java no necesita conocer ni comprender el código de bytes de Java en absoluto. Sin embargo, como se sugiere en la revista IBM DeveloperWorks, "Comprender el código de bytes y qué código de bytes es probable que genere un compilador de Java ayuda al programador de Java de la misma manera que el conocimiento del ensamblador ayuda al programador de C o C++ ". [4]

Set de instrucciones arquitectura

La JVM es a la vez una máquina de pila y una máquina de registro . Cada cuadro de una llamada a un método tiene una "pila de operandos" y una matriz de "variables locales". [5] : 2.6  La pila de operandos se usa para operandos de cálculos y para recibir el valor de retorno de un método llamado, mientras que las variables locales tienen el mismo propósito que los registros y también se usan para pasar argumentos de método. El tamaño máximo de la pila de operandos y la matriz de variables locales, calculados por el compilador, es parte de los atributos de cada método. [5] : 4.7.3  Cada uno puede tener un tamaño independiente de 0 a 65535 valores, donde cada valor es de 32 bits. longy doublelos tipos, que son de 64 bits, toman dos variables locales consecutivas [5] : 2.6.1  (que no necesitan estar alineadas en 64 bits en la matriz de variables locales) o un valor en la pila de operandos (pero se cuentan como dos unidades en la profundidad de la pila). [5] : 2.6.2 

Conjunto de instrucciones

Cada código de bytes se compone de un byte que representa el código de operación , junto con cero o más bytes para los operandos. [5] : 2.11 

De los 256 posibles códigos de operación de bytes de longitud , a partir de 2015 , 202 están en uso (~79%), 51 están reservados para uso futuro (~20%) y 3 instrucciones (~1%) están reservadas permanentemente para implementaciones de JVM para usar. [5] : 6.2  Dos de estos ( impdep1y impdep2) son para proporcionar trampas para software y hardware específicos de la implementación, respectivamente. El tercero se utiliza para que los depuradores implementen puntos de interrupción.

Las instrucciones se dividen en varios grupos amplios:

También hay algunas instrucciones para una serie de tareas más especializadas, como generación de excepciones, sincronización, etc.

Muchas instrucciones tienen prefijos y/o sufijos que se refieren a los tipos de operandos con los que operan. [5] : 2.11.1  Son los siguientes:

Por ejemplo, iaddsumará dos números enteros, mientras que daddsumará dos dobles. Las instrucciones const, loady storetambién pueden tener un sufijo de la forma , donde n es un número del 0 al 3 para y . El máximo n para difiere según el tipo._nloadstoreconst

Las constinstrucciones insertan un valor del tipo especificado en la pila. Por ejemplo, iconst_5enviará un número entero (valor de 32 bits) con el valor 5 a la pila, mientras que dconst_1enviará un número doble (valor de coma flotante de 64 bits) con el valor 1 a la pila. También hay un aconst_null, que envía una nullreferencia. La n para las instrucciones loady storeespecifica el índice en la matriz de variables locales desde donde se carga o se almacena. La aload_0instrucción empuja el objeto en la variable local 0 a la pila (este suele ser el thisobjeto). istore_1almacena el número entero en la parte superior de la pila en la variable local 1. Para las variables locales más allá de 3, el sufijo se elimina y se deben usar operandos.

Ejemplo

Considere el siguiente código Java:

exterior : for ( int i = 2 ; i < 1000 ; i ++ ) { for ( int j = 2 ; j < i ; j ++ ) { if ( i % j == 0 ) continuar exterior ; } Sistema . afuera . imprimirln ( yo ); }                              

Un compilador de Java podría traducir el código Java anterior a código de bytes de la siguiente manera, suponiendo que lo anterior se haya incluido en un método:

0 : iconost_2 1 : istore_1 2 : iload_1 3 : sipush 1000 6 : if_icmpge 44 9 : iconost_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 : 3825 : iinc 2, 1 28 : ir a 11 31 : getstatic #84; // Campo java/lang/System.out : Ljava/io/PrintStream; 34 : iload_1 35 : invocar virtual #85 ; // Método java/io/PrintStream.println:(I)V 38 : iinc 1, 1 41 : ir a 2 44 : regresar                                       

Generación

El lenguaje más común dirigido a la máquina virtual Java mediante la producción de código de bytes Java es Java. Originalmente sólo existía un compilador, el compilador javac de Sun Microsystems , que compila el código fuente de Java en código de bytes de Java; pero debido a que todas las especificaciones para el código de bytes de Java ahora están disponibles, otras partes han proporcionado compiladores que producen código de bytes de Java. Ejemplos de otros compiladores incluyen:

Algunos proyectos proporcionan ensambladores de Java para permitir escribir código de bytes de Java a mano. El código ensamblador también puede ser generado por una máquina, por ejemplo, por un compilador dirigido a una máquina virtual Java . Los ensambladores de Java notables incluyen:

Otros han desarrollado compiladores, para diferentes lenguajes de programación, destinados a la máquina virtual Java, como por ejemplo:

Ejecución

Hay varias máquinas virtuales Java disponibles en la actualidad para ejecutar código de bytes de Java, tanto productos gratuitos como comerciales. Si no es deseable ejecutar código de bytes en una máquina virtual, un desarrollador también puede compilar código fuente de Java o código de bytes directamente en código de máquina nativo con herramientas como el Compilador GNU para Java (GCJ). Algunos procesadores pueden ejecutar código de bytes de Java de forma nativa. Estos procesadores se denominan procesadores Java .

Soporte para lenguajes dinámicos

La máquina virtual Java proporciona cierto soporte para lenguajes escritos dinámicamente . La mayor parte del conjunto de instrucciones JVM existente está escrito estáticamente , en el sentido de que las llamadas a métodos tienen sus firmas verificadas en tiempo de compilación , sin un mecanismo para posponer esta decisión al tiempo de ejecución , o para elegir el envío del método mediante un enfoque alternativo. [12]

JSR 292 ( Soporte de lenguajes de tipo dinámico en la plataforma Java ) [13] agregó una nueva invokedynamicinstrucción en el nivel JVM, para permitir la invocación de métodos que dependen de la verificación de tipo dinámico (en lugar de la instrucción de verificación de tipo estática existente invokevirtual). La Máquina Da Vinci es una implementación prototipo de máquina virtual que aloja extensiones JVM destinadas a admitir lenguajes dinámicos. Todas las JVM que admiten JSE 7 también incluyen el invokedynamiccódigo de operación.

Ver también

Referencias

  1. ^ ab "Especificación de la máquina virtual Java". Oráculo . Consultado el 14 de noviembre de 2023 .
  2. ^ ab Lindholm, Tim (2015). La especificación de la máquina virtual Java . Oráculo. ISBN 978-0133905908.
  3. ^ Arnold, Ken (1996). "El lenguaje de programación Java". Microsistemas solares . 1 (1): 30–40.
  4. ^ "Desarrollador de IBM". desarrollador.ibm.com . Consultado el 20 de febrero de 2006 .
  5. ^ abcdefg Lindholm, Tim; Grita, Frank; Brajá, Gilad; Buckley, Alex (13 de febrero de 2015). La especificación de la máquina virtual Java (Java SE 8 ed.).
  6. ^ Página de inicio de jazmín
  7. ^ Jamaica: macroensamblador de la máquina virtual Java (JVM)
  8. ^ Página de inicio de Krakatau
  9. ^ Página de inicio lila
  10. ^ Notas de la versión gratuita de Pascal 3.0
  11. ^ Objetivo Pascal JVM gratuito
  12. ^ Nutter, Charles (3 de enero de 2007). "InvokeDynamic: ¿Realmente útil?" . Consultado el 25 de enero de 2008 .
  13. ^ ver JSR 292

enlaces externos