remarks net cref c# .net vb.net reflection intermediate-language

net - remarks c#



¿Cómo funciona la directiva.NET IL.maxstack? (3)

No tiene nada que ver con el número de variables declaradas, sino que tiene que ver con la cantidad de valores que necesita empujar en una pila en un momento dado para calcular una expresión.

Por ejemplo, en la siguiente expresión, asumiría que se deben insertar 2 valores en la pila:

x = y + z;

Esto no está relacionado con el hecho de que hay al menos 3 variables presentes, x, y, yz, y posiblemente otras también.

Desafortunadamente, no conozco la respuesta a sus otras preguntas, y creo que la experimentación sería una forma de encontrar algunas respuestas.

Me gustaría saber cómo funciona realmente .maxstack. Sé que no tiene que ver con el tamaño real de los tipos que está declarando sino con el número de ellos. Mis preguntas son:

  1. ¿Esto se aplica solo para la función, o para todas las funciones que estamos solicitando?
  2. incluso si es solo para la función en la que se está declarando .maxstack, ¿cómo saber qué es maxstack si tiene sucursales? ¿Ve a ver todas las "rutas" y devuelve el valor máximo posible?
  3. ¿Qué pasa si lo configuro en 16 y en realidad hay 17 variables?
  4. ¿Hay una penalización demasiado grande si la configuro en 256?

Puede consultar lo siguiente y el ESTÁNDAR ECMA para obtener una mejor comprensión:

void msd(string a, string b, string c, string d, string e) { Console.WriteLine(a); } msd("a","b","c","d","e");

Cuando ejecuto ildasm.exe obtuve esto:

{ .entrypoint // Code size 40 (0x28) .maxstack 8 IL_0000: nop IL_0001: nop IL_0002: ldstr "a" IL_0007: ldstr "b" IL_000c: ldstr "c" IL_0011: ldstr "d" IL_0016: ldstr "e" IL_001b: call void sf.Program::''<Main>g__msd|0_0''(string, string, string, string, string) IL_0020: nop IL_0021: call string [mscorlib]System.Console::ReadLine() IL_0026: pop IL_0027: ret } // end of method Program::Main

de lo anterior. Encontré el valor de stakc máximo que no está determinado por las instrucciones push & pop.

No sabía cuáles son los valores reales del número de pila. Por lo tanto, hago referencia al código de desensamblaje de ildasm para determinar el valor de pila máximo real.


.maxstack es parte de la verificación IL. Básicamente, .maxstack le dice al JIT el tamaño de pila máximo que necesita reservar para el método. Por ejemplo, x = y + (a - b) traduce a

(Pseudo IL :)

1. Push y on the stack 2. Push a on the stack 3. Push b on the stack 4. Pop the last two items from the stack, substract them and push the result on the stack 5. Pop the last two items from the stack, add them and push the result on the stack 6. Store the last item on the stack in x and pop the last item from the stack

Como puede ver, hay como máximo 3 artículos en la pila en cada momento. Si configurara .maxstack en 2 (o menos) para este método, el código no se ejecutaría.

Además, no puedes tener algo como esto, ya que requeriría un tamaño de pila infinito:

1. Push x on the stack 2. Jump to step 1

Para responder tu pregunta:

  1. ¿Esto se aplica solo para la función, o para todas las funciones que estamos solicitando?

Solo por la funcion

  1. incluso si es solo para la función en la que se está declarando .maxstack, ¿cómo saber qué es maxstack si tiene sucursales? ¿Ve a ver todas las "rutas" y devuelve el valor máximo posible?

Ve a ver todas las rutas y devuelve el máximo valor posible.

  1. ¿Qué pasa si lo configuro en 16 y en realidad hay 17 variables?

No tiene relación con el número de variables, vea la respuesta de Lasse V. Karlsen

  1. ¿Hay una penalización demasiado grande si la configuro en 256?

No parece una buena idea, pero no lo sé.

¿Realmente tienes que calcular el .maxstack tú mismo? System.Reflection.Emit calcula para usted IIRC.