.NET IL .maxstack指令如何工作?

dev*_*ium 24 .net c# vb.net reflection intermediate-language

我想知道.maxstack是如何工作的.我知道它与您声明的类型的实际大小无关,而与它们的数量有关.我的问题是:

  1. 这仅适用于函数,还适用于我们要求的所有函数?
  2. 即使只是为了函数而声明了.maxstack,如果你有分支,你怎么知道maxstack是什么?你去看看所有的"路径"并尽可能返回最大值?
  3. 如果我将它设置为16并且实际上有17个变量会发生什么?
  4. 如果我把它设置为256,会有太大的惩罚吗?

dtb*_*dtb 26

.maxstack是IL验证的一部分.基本上.maxstack告诉JIT它需要为方法保留的最大堆栈大小.例如,x = y + (a - b)转换为

(伪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
Run Code Online (Sandbox Code Playgroud)

如您所见,每次堆叠最多有3个项目.如果.maxstack为此方法设置为2(或更低),则代码将无法运行.

此外,您不能拥有这样的东西,因为它需要无限的堆栈大小:

1. Push x on the stack
2. Jump to step 1
Run Code Online (Sandbox Code Playgroud)

回答你的问题:

  1. 这仅适用于函数,还适用于我们要求的所有函数?

只为功能

  1. 即使只是为了函数而声明了.maxstack,如果你有分支,你怎么知道maxstack是什么?你去看看所有的"路径"并尽可能返回最大值?

您可以查看所有路径并返回可能的最大值

  1. 如果我将它设置为16并且实际上有17个变量会发生什么?

这与变量的数量无关,参见Lasse V. Karlsen的回答

  1. 如果我把它设置为256,会有太大的惩罚吗?

似乎不是一个好主意,但我不知道.

你真的需要.maxstack自己计算一下吗?System.Reflection.Emit为你计算IIRC.


ang*_*son 5

它与声明的变量数量无关,而是与在任何给定时间推送堆栈需要多少值以计算某些表达式有关.

例如,在下面的表达式中,我假设需要将2个值压入堆栈:

x = y + z;
Run Code Online (Sandbox Code Playgroud)

这与存在至少3个变量x,y和z以及可能还有其他变量的事实无关.

不幸的是,我不知道你的其他问题的答案,我猜想实验将是找到答案的一种方法.