Documenting the CLR JIT Strategy

I would like to know how much scope and sequence of the CLR relates to JIT compilation.

For example, if my application calls only one method of this class, are the unused methods of this class, JIT, compiled? And if so, are they all JITs compiled before the execution of the single method I need, or are they lazily compiled after the fact?

What about branches in a method? Does the CLR allow you to compile half the code in a method, allowing a separate branch in the same method to remain unconnected until needed?

It seems that over time I have found articles that give an idea of ​​some of these details, but right now I can’t find anything that gives a consolidated, readable summary of how and when the CLR selects the JIT section of the code. Any books or links on offer?

It would be better if any such manual would break such JIT solution logic into a .net version.

+3
clr jit
source share
1 answer

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.

+6
source share

All Articles