2009-08-06 16 views
20

Chciałbym wiedzieć, jak działa .maxstack. Wiem, że nie ma to związku z rzeczywistą wielkością deklarowanych typów, ale z ich liczbą. Moje pytania to:Jak działa dyrektywa .NET IL .maxstack?

  1. to się ma tylko dla funkcji lub wszystkich funkcji że wzywamy do?
  2. nawet jeśli chodzi tylko o funkcję , gdy zadeklarowano .maxstack, skąd wiesz, co to jest maxstack, jeśli masz rozgałęzienie, jeśli masz ? Idziesz i widzisz wszystkie "ścieżki" i zwracasz maksymalną wartość ?
  3. Co się stanie, jeśli ustawię go na 16 i faktycznie jest 17 zmiennych?
  4. Czy jest zbyt duża kara, jeśli ustawię ją na 256?

Odpowiedz

23

.maxstack jest częścią weryfikacji IL. Zasadniczo .maxstack informuje JIT o maksymalnym rozmiarze stosu, który musi zarezerwować dla tej metody. Na przykład, x = y + (a - b) przekłada się

(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 

Jak widać, istnieją co najwyżej 3 elementów na stosie w każdym czasie. Jeśli ustawisz .maxstack na 2 (lub mniej) dla tej metody, kod nie zostanie uruchomiony.

Ponadto, nie można mieć coś takiego jak wymagałoby nieskończonej wielkości stosu:

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

Aby odpowiedzieć na Twoje pytania:

  1. tylko dla funkcji
  2. idź i zobacz wszystkie ścieżki i zwracaj maksymalną możliwą wartość
  3. Nie ma związku z liczbą zmiennych, patrz Lasse V. Karlsen - odpowiedź
  4. Nie wydaje się dobrym pomysłem, ale nie wiem.

Czy naprawdę trzeba samodzielnie obliczyć wartość .maxstack? System.Reflection.Emit oblicza to dla ciebie IIRC.

+0

Ja też, ale po prostu pozwolę, by tak się stało. Właśnie edytuję kod IL z innych plików wykonywalnych, ale metoda, którą wstawiam, ma tylko 2 argumenty, więc myślę, że nigdy nie będzie to kolidowało z już istniejącym .maxstack w metodzie IL. –

5

To nie ma nic wspólnego z liczby zmiennych zadeklarowanych, lecz wszystko, co zrobić z ilu wartości trzeba naciskać na stosie w danym momencie w celu obliczenia jakiś wyraz.

Na przykład, w następujący ekspresji Przypuszczam 2 wartości musi być popychany na stos:

x = y + z; 

ta nie jest związana z tym, że istnieją co najmniej 3 zmienne obecny, X, Y i z, i być może także innych.

Niestety nie znam odpowiedzi na twoje inne pytania, a sądzę, że eksperymentowanie byłoby jednym ze sposobów na znalezienie odpowiedzi.

+0

Ah. Więc jeśli moje wyrażenia nigdy nie mają więcej niż 8 operandów i jakakolwiek funkcja, którą wywołuję z mojej metody nigdy nie ma więcej niż 8 argumentów, nigdy nie będę potrzebować więcej niż .maxstack 8? –

+0

'x = y + (a - b)' wymaga wielkości stosu 3, mimo że oba operatory mają tylko 2 operandy. – dtb

0

Można odwoływać się do następujących i ECMA STANDARD aby lepiej zrozumieć:

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

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

Kiedy biegnę ildasm.exe mam to:

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

z powyższych. Znalazłem wartość maks. stakc, która nie jest określona przez instrukcje pop.

Nie wiedziałem, jakie są rzeczywiste wartości numerów stosu. Dlatego odwołuję się do kodu demontażu ildasm, aby określić rzeczywistą maksymalną wartość stosu.

Powiązane problemy