Pila = 4 en el código de bytes de Java. ¿Cómo se calcula el compilador de Java el valor 4? (Profundidad de la la pila)

Youness:

Código Java:

public class SimpleRecursion {

    public int factorial(int n) {
        if (n == 0) {
            return 1;
        }
        return n * factorial(n - 1);
    }

}

Da el siguiente código de bytes para el método factorial (I ejecutado javap para generarla):

public int factorial(int); 
descriptor: (I)I 
flags: ACC_PUBLIC 
Code:   
  stack=4, locals=2, args_size=2
     0: iload_1
     1: ifne          6
     4: iconst_1
     5: ireturn
     6: iload_1
     7: aload_0
     8: iload_1
     9: iconst_1
    10: isub
    11: invokevirtual #2                  // Method factorial:(I)I
    14: imul
    15: ireturn   
  LineNumberTable:
    line 4: 0
    line 5: 4
    line 7: 6   
  StackMapTable: number_of_entries = 1
    frame_type = 6 /* same */

Entiendo que en la quinta línea del bloque anterior, de pila = 4 significa que la pila puede tener como máximo 4 objetos .

Pero, ¿cómo lo hace el cálculo compilador que?

Holger:

Dado que el estado inicial de la pila, así como el efecto de cada instrucción en él es bien sabido, se puede predecir con exactitud, qué tipo de artículos estarán en la pila de operandos en cualquier momento:

[ ]            // initially empty
[ I ]          0: iload_1
[ ]            1: ifne          6
[ I ]          4: iconst_1
[ ]            5: ireturn
[ I ]          6: iload_1
[ I O ]        7: aload_0
[ I O I ]      8: iload_1
[ I O I I ]    9: iconst_1
[ I O I ]     10: isub
[ I I ]       11: invokevirtual #2   // Method factorial:(I)I
[ I ]         14: imul
[ ]           15: ireturn   

verificador de la JVM hará exactamente eso, predecir el contenido de la pila después de cada instrucción, para comprobar si es adecuado como entrada de la instrucción posterior. Pero ayuda aquí, para tener un tamaño máximo declarado, por lo que el verificador no necesita para mantener una estructura de datos dinámica y en crecimiento o en la memoria para asignar previamente los teóricamente posibles entradas de la pila de 64k. Con el tamaño máximo declarado, se puede detener cuando se enfrentan a una instrucción que empujaría más que eso, por lo que nunca se necesita más memoria que declaró.

Como se puede ver, el tamaño de pila máxima declarada se alcanza exactamente una vez, justo después de la iconst_1instrucción en el índice 9.

Sin embargo, esto no implica que un compilador tendrá que realizar un análisis de dicha instrucción. Un compilador tiene un modelo de nivel superior del código derivado a partir del código fuente, conocida como sintaxis abstracta árbol .

Esta estructura se utiliza para generar el código de bytes resultante y también puede ser capaz de predecir el tamaño de pila requerido en ese nivel ya. Pero, ¿cómo el compilador de hecho lo hace, es dependiente de la implementación.

Supongo que te gusta

Origin http://43.154.161.224:23101/article/api/json?id=225644&siteId=1
Recomendado
Clasificación