Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

280
Vistas
¿Algún compilador para JVM usa el goto "ancho"?

Me imagino que la mayoría de ustedes saben que goto es una palabra clave reservada en el lenguaje Java pero que en realidad no se usa. Y probablemente también sepa que goto es un código de operación de Java Virtual Machine (JVM). Considero que todas las estructuras de flujo de control sofisticadas de Java, Scala y Kotlin están, a nivel de JVM, implementadas usando alguna combinación de goto e ifeq , ifle , iflt , etc.

Mirando la especificación JVM https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-6.html#jvms-6.5.goto_w Veo que también hay un código de operación goto_w . Mientras que goto toma un desplazamiento de rama de 2 bytes, goto_w toma un desplazamiento de rama de 4 bytes. La especificación establece que

Aunque la instrucción goto_w toma un desplazamiento de rama de 4 bytes, otros factores limitan el tamaño de un método a 65535 bytes (§4.11). Este límite puede aumentar en una versión futura de Java Virtual Machine.

Me parece que goto_w está preparado para el futuro, como algunos de los otros códigos de *_w . Pero también se me ocurre que tal vez goto_w podría usarse con los dos bytes más significativos puestos a cero y los dos bytes menos significativos igual que para goto , con los ajustes necesarios.

Por ejemplo, dado este Java Switch-Case (o Scala Match-Case):

 12: lookupswitch { 112785: 48 // case "red" 3027034: 76 // case "green" 98619139: 62 // case "blue" default: 87 } 48: aload_2 49: ldc #17 // String red 51: invokevirtual #18 // Method java/lang/String.equals:(Ljava/lang/Object;)Z 54: ifeq 87 57: iconst_0 58: istore_3 59: goto 87 62: aload_2 63: ldc #19 // String green 65: invokevirtual #18 // Method java/lang/String.equals:(Ljava/lang/Object;)Z 68: ifeq 87 71: iconst_1 72: istore_3 73: goto 87 76: aload_2 77: ldc #20 // String blue 79: invokevirtual #18 // etc.

Podríamos reescribirlo como

 12: lookupswitch { 112785: 48 3027034: 78 98619139: 64 default: 91 } 48: aload_2 49: ldc #17 // String red 51: invokevirtual #18 // Method java/lang/String.equals:(Ljava/lang/Object;)Z 54: ifeq 91 // 00 5B 57: iconst_0 58: istore_3 59: goto_w 91 // 00 00 00 5B 64: aload_2 65: ldc #19 // String green 67: invokevirtual #18 // Method java/lang/String.equals:(Ljava/lang/Object;)Z 70: ifeq 91 73: iconst_1 74: istore_3 75: goto_w 91 79: aload_2 81: ldc #20 // String blue 83: invokevirtual #18 // etc.

En realidad, no he probado esto, ya que probablemente cometí un error al cambiar los "números de línea" para acomodar los goto_w s. Pero como está en la especificación, debería ser posible hacerlo.

Mi pregunta es si hay una razón por la que un compilador u otro generador de código de bytes podría usar goto_w con el límite actual de 65535 que no sea para mostrar que se puede hacer.

over 4 years ago · Santiago Trujillo
3 Respuestas
Responde la pregunta

0

El tamaño del código del método puede ser tan grande como 64K.

El desplazamiento de rama del goto corto es un entero de 16 bits con signo: de -32768 a 32767.

Por lo tanto, el desplazamiento corto no es suficiente para dar un salto desde el principio del método de 65K hasta el final.

Incluso javac a veces emite goto_w . Aquí hay un ejemplo:

 public class WideGoto { public static void main(String[] args) { for (int i = 0; i < 1_000_000_000; ) { i += 123456; // ... repeat 10K times ... } } }

Descompilando con javap -c :

 public static void main(java.lang.String[]); Code: 0: iconst_0 1: istore_1 2: iload_1 3: ldc #2 5: if_icmplt 13 8: goto_w 50018 // <<< Here it is! A jump to the end of the loop ...
over 4 years ago · Santiago Trujillo Denunciar

0

No hay razón para usar goto_w cuando la rama se ajusta a un goto . Pero parece que te has perdido que las ramas son relativas , usando un desplazamiento firmado, ya que una rama también puede ir hacia atrás.

No lo nota cuando mira la salida de una herramienta como javap , ya que calcula la dirección de destino absoluta resultante antes de imprimir.

Por lo tanto, el rango de -327678 … +32767‬ de goto no siempre es suficiente para abordar cada ubicación de destino posible en el rango de 0 … +65535 .

Por ejemplo, el siguiente método tendrá una instrucción goto_w al principio:

 public static void methodWithLargeJump(int i) { for(; i == 0;) { try {x();} finally { switch(i){ case 1: try {x();} finally { switch(i){ case 1: try {x();} finally { switch(i){ case 1: try {x();} finally { switch(i){ case 1: try {x();} finally { switch(i){ case 1: try {x();} finally { switch(i){ case 1: try {x();} finally { switch(i){ case 1: try {x();} finally { switch(i){ case 1: try {x();} finally { switch(i){ case 1: try {x();} finally { switch(i){ case 1: } } } } } } } } } } } } } } } } } } } } } } static void x() {}

Demostración en Ideone

 Compiled from "Main.java" class LargeJump { public static void methodWithLargeJump(int); Code: 0: iload_0 1: ifeq 9 4: goto_w 57567 …
over 4 years ago · Santiago Trujillo Denunciar

0

Parece que en algunos compiladores (probado en 1.6.0 y 11.0.7), si un método es lo suficientemente grande como para necesitar goto_w, usa exclusivamente goto_w. Incluso cuando tiene saltos muy locales, todavía usa goto_w.

over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda