Alex Clark said:
Hi all,
Does anyone know if making calls to
System.Reflection.MethodBase.GetCurrentMethod is reliable in an
optimised, Release Build .NET app? I know the JITter can do some
inline optimisations, and if it does will GetCurrentMethod reflect the
calling method (i.e. the one this method was inlined into), or the
containing method? I've Googled but have found contradicting
information, and there is no indication in the MSDN online help about
what to expect (whereas there is for the StackFrame methods).
Can anyone shed some light on this?
No. Some quick tests produced GetCurrentMethod always returning the
current method, but any extra code added to the routine to try to
confirm if it was inlined (by accessing New StackTrace()) stopped the
method from being inlined.
Removing the call to GetCurrentMethod, and just leaving New
StackTrace().ToString showed the method /was/ then being inlined.
And I tried "hiding" the call to GetCurrentMethod in a delegate to try
to ensure the JIT doesn't just avoid inlining routines that call
GetCurrentMethod.
Sorry I couldn't help. BTW Remember to use Ctrl+F5 from within VS to
allow the JITter to do its thing without any debugging getting in the
way.
Here's my code just in case it helps someone else confirm or contradict
this:
Module Module1
Sub Main()
Dim fn As Func(Of Object) = AddressOf
System.Reflection.MethodBase.GetCurrentMethod
Dim fn2 As Func(Of Object) = Function() (New StackTrace())
TestRoutine(fn)
CallsTestRoutine(fn)
'CallIt(AddressOf TestRoutine)
'CallIt(AddressOf CallsTestRoutine)
TestRoutine2(fn)
CallsTestRoutine2(fn)
'CallIt(AddressOf TestRoutine2)
'CallIt(AddressOf CallsTestRoutine2)
TestRoutine(fn2)
CallsTestRoutine(fn2)
TestRoutine2(fn2)
CallsTestRoutine2(fn2)
Console.ReadLine()
End Sub
'Private Function TestRoutineExtracted() As System.Reflection.MethodBase
' Console.WriteLine(New StackTrace().ToString)
' Return System.Reflection.MethodBase.GetCurrentMethod()
'End Function
Sub TestRoutine(ByVal fn As Func(Of Object))
'Console.WriteLine(TestRoutineExtracted().Name)
'Console.WriteLine(New StackTrace().ToString)
'Console.WriteLine(System.Reflection.MethodBase.GetCurrentMethod().Name)
Console.WriteLine(fn().ToString)
End Sub
Sub CallsTestRoutine(ByVal fn As Func(Of Object))
TestRoutine(fn)
'Console.WriteLine(System.Reflection.MethodBase.GetCurrentMethod().Name)
'Console.WriteLine(fn().ToString)
End Sub
Sub CallIt(ByVal Fn As Action)
Fn()
End Sub
'Private Function TestRoutine2Extracted() As
System.Reflection.MethodBase
' Console.WriteLine(New StackTrace().ToString)
' Return System.Reflection.MethodBase.GetCurrentMethod()
'End Function
<System.Runtime.CompilerServices.MethodImpl(Runtime.CompilerServices.MethodImplOptions.NoInlining)>
_
Sub TestRoutine2(ByVal fn As Func(Of Object))
'Console.WriteLine(TestRoutine2Extracted().Name)
'Console.WriteLine(New StackTrace().ToString)
'Console.WriteLine(System.Reflection.MethodBase.GetCurrentMethod().Name)
Console.WriteLine(fn().ToString)
End Sub
Sub CallsTestRoutine2(ByVal fn As Func(Of Object))
TestRoutine2(fn)
'Console.WriteLine(System.Reflection.MethodBase.GetCurrentMethod().Name)
'Console.WriteLine(fn().ToString)
End Sub
End Module