The way JIT works in .NET is that before the method has been tagged, writing a method table indicates a small stub that will be the JIT method when invoked. After that, the method table is updated to refer to the location of the compiled JIT code.
Given that only methods that invoke JIT are compiled there is no JIT overhead for methods that are not invoked.
The JIT compiler will compile the whole method if necessary. If this is release build code, it can be optimized, but otherwise the method will be compiled completely.
You can check method tables using WinDbg / SOS. Consider the following:
class SomeType { public void Called() { Console.WriteLine("called"); } public void NotCalled() { Console.WriteLine("not called"); } }
Suppose we create an instance of SomeType , call Called , and then check the method table for SomeType . On x86 you will see something like this:
0:000> !dumpmt -md 00a7381c EEClass: 00a712d0 Module: 00a72e94 Name: ConsoleApplication1.SomeType mdToken: 02000002 File: c:\temp\ConsoleApplication1\ConsoleApplication1\bin\Debug\ConsoleApplication1.exe BaseSize: 0xc ComponentSize: 0x0 Slots in VTable: 7 Number of IFaces in IFaceMap: 0 -------------------------------------- MethodDesc Table Entry MethodDe JIT Name 72ca4960 729a6728 PreJIT System.Object.ToString() 72c98790 729a6730 PreJIT System.Object.Equals(System.Object) 72c98360 729a6750 PreJIT System.Object.GetHashCode() 72c916f0 729a6764 PreJIT System.Object.Finalize() 00df00d8 00a73814 JIT ConsoleApplication1.SomeType..ctor() 00df0110 00a737fc JIT ConsoleApplication1.SomeType.Called() 00a7c031 00a73808 NONE ConsoleApplication1.SomeType.NotCalled()
Note that Called compiled by JIT, but since we had not yet called NotCalled , it was not compiled by JIT.
Also note that the methods from object all been compiled by PreJIT.
Keep in mind that short methods can be embedded in the build release, in which case they are not called methods, but are simply included as part of the generated code for the call site.
Brian rasmussen
source share