Search code examples
.netclrintermediate-language

How and when does .NET actually compile code?


Let's say you write an app in C#, VB, anything with .NET When you hit build, does it really compile your code? I thought so until I started using redgates reflector on some of my assemblies and saw my code verbatim. I would have expected loops to be unrolled and another plethora of optimizations, instead nothing.

So when does the compilation actually happen? I think when it is built, code become IL (Intermediary Language) and when execution occurs, it is loading in the CLR? Is it optimized during CLR only and never at build time?


Solution

  • When you compile in VS

    1. Your source code is compiled into a byte code known as the common intermediate language (CIL) or MSIL (Microsoft Intermediate Language).
    2. Metadata from every class and every methods (and every other thing :O) is included in the PE header of the resulting executable (be it a dll or an exe).
    3. If you're producing an executable the PE Header also includes a conventional bootstrapper which is in charge of loading the CLR (Common language runtime) when you execute you executable.

    When you execute:

    1. The bootstraper initializes the CLR (mainly by loading the mscorlib assembly) and instructs it to execute your assembly.
    2. The CLR executes your main entry.
    3. Now, classes have a vector table which hold the addresses of the method functions, so that when you call MyMethod, this table is searched and then a corresponding call to the address is made. Upon start ALL entries for all tables have the address of the JIT compiler.
    4. When a call to one of such method is made, the JIT is invoked instead of the actual method and takes control. The JIT then compiles the CIL code into actual assembly code for the appropiate architecture.
    5. Once the code is compiled the JIT goes into the method vector table and replaces the address with the one of the compiled code, so that every subsequent call no longer invokes the JIT.
    6. Finally, the JIT handles the execution to the compiled code.
    7. If you call another method which haven't yet being compiled then go back to 4... and so on...

    I post the answer here too as the other question was not really about this...