2011-01-31 2 views
5

Ho scritto un modulo logger/exceptionfactory, che utilizza System.Diagnostics.StackTrace, per ottenere attributi dai metodi di chiamata e dai loro tipi di dichiarazione. Tuttavia, ho notato che se eseguo il codice all'esterno di Visual Studio in modalità di rilascio, alcuni dei miei metodi più brevi risultano in linea e mancanti nella traccia dello stack. Ora non ho modo di testare se un metodo verrà ritorto in runtime, ma non voglio il metodo [MethodImpl(MethodImplOptions.NoInlining)] ogni importante. Ma se un metodo delle mie classi base mancherà a causa di esso, posso interpretare erroneamente il livello e le informazioni sull'operazione e questo potrebbe portare a false log o eccezioni misparameterizzate.Stack Trace per l'accesso .NET

Esiste una regola empirica su cosa viene indicato dove e quando? I metodi virtuali, i metodi statici, i metodi della classe base sono trattati in modo diverso? Devo solo preoccuparmi di inlining all'interno dell'assemblaggio? All'interno dello spazio dei nomi?

+0

possibile duplicato di [Quando è possibile che un metodo sia in linea con il CLR?] (Http://stackoverflow.com/questions/4660004/when-is-a-method- ammissibile-di-essere-infinito-di -the-clr) –

risposta

5

Sì, ci sono alcune regole, ma sono euristiche utilizzate dal compilatore JIT e queste euristiche possono cambiare in qualsiasi momento.

  1. I metodi virtuali non possono essere in linea.
  2. I metodi di interfaccia, d'altra parte, possono essere in linea, anche se non sono sicuro al 100% se ciò accorcerebbe o meno la traccia dello stack.
  3. I metodi statici e i metodi di istanza non virtuali possono essere sicuramente sottolineati.
  4. Inlining può incrociare spazi dei nomi (ovviamente) e assiemi (non così ovvio) perché si verifica in fase di esecuzione, quando il JIT compila la chiamata al metodo.
  5. I metodi "pesanti" non saranno in linea. Questo dipende dalla definizione di "pesante" e fa parte dell'euristica applicata dal JIT.

Alcune delle euristiche per "pesante", che io sappia:

  • I metodi che utilizzano la gestione delle eccezioni (cioè try-catch-o provare finalmente blocchi) non sono inline.
  • I metodi con codice grande (~ 32 byte IL ma potrebbe essere errato ricordare) non sono in linea.
  • I metodi con loop non sono in linea (a meno che il ciclo non possa essere completamente srotolato o eliminato).
+0

semplicemente perfetto :). Tutti i miei metodi importanti iniziano con try catch ... – TDaver

2

Le euristiche sono tutti dettagli di implementazione del jitter, il che significa che non sono documentati ufficialmente e sono presumibilmente soggetti a modifiche in qualsiasi momento.

Detto questo, qui ci sono alcuni articoli che potreste trovare interessante (anche se alcuni di loro sono un po 'lungo-in-the-dente ora):