Как работает директива .NET IL .maxstack? - PullRequest
23 голосов
/ 07 августа 2009

Я хотел бы знать, как на самом деле работает .maxstack. Я знаю, что это связано не с реальным размером типов, которые вы объявляете, а с их количеством. Мои вопросы:

  1. это относится только к функция или для всех функций что мы призываем?
  2. , даже если это только для функции где .maxstack объявляется, откуда вы знаете, что такое maxstack у тебя ветвление? Вы идете и видите все "пути" и вернуть максимально возможное значение?
  3. Что произойдет, если я установлю его на 16 и на самом деле есть 17 переменных?
  4. Есть ли слишком большой штраф, если я установить его на 256?

Ответы [ 3 ]

25 голосов
/ 07 августа 2009

.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

Как видите, в стеке не более 3 предметов одновременно. Если вы установите для .maxstack значение 2 (или меньше) для этого метода, код не запустится.

Кроме того, вы не можете получить что-то подобное, так как для этого потребуется бесконечный размер стека:

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

Чтобы ответить на ваши вопросы:

  1. это относится только к функции или ко всем функциям, к которым мы обращаемся?

Только для функции

  1. , даже если это только для функции, в которой объявляется .maxstack, как узнать, что такое maxstack, если у вас есть ветвление? Вы идете и видите все «пути» и возвращаете максимально возможное значение?

Вы идете и видите все пути и возвращаете максимально возможное значение

  1. Что произойдет, если я установлю 16, а на самом деле будет 17 переменных?

Это не связано с количеством переменных, см. Lasse V. Karlsen ответ

  1. Будет ли слишком большой штраф, если я установлю его на 256?

Не похоже на хорошую идею, но я не знаю.

Вы действительно должны рассчитать .maxstack самостоятельно? System.Reflection.Emit рассчитывает для вас IIRC.

5 голосов
/ 07 августа 2009

Это не имеет ничего общего с числом объявленных переменных, но вместо этого все, что связано с тем, сколько значений нужно поместить в стек в любой момент времени для вычисления некоторого выражения.

Например, в следующем выражении я бы предположил, что в стек нужно поместить 2 значения:

x = y + z;

Это не связано с тем фактом, что присутствуют как минимум 3 переменные, x, y и z, а также, возможно, и другие.

К сожалению, я не знаю ответа на другие ваши вопросы, и я предполагаю, что эксперименты - это один из способов найти некоторые ответы.

0 голосов
/ 19 января 2018

Вы можете обратиться к следующему и стандарту ECMA, чтобы лучше понять:

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

msd("a","b","c","d","e");

Когда я бегу ildasm.exe я получаю это:

{
  .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

из вышесказанного. Я нашел максимальное значение stakc, которое не определяется инструкциями push & pop.

Я не знал, каковы реальные значения стековых чисел. Итак, я ссылаюсь на код разборки ildasm, чтобы определить реальное максимальное значение стека.

...