Improving your C# Skills
上QQ阅读APP看书,第一时间看更新

From compilation to execution – Under the hood

The .NET Core compilation process is like the one used with the .NET Framework. When the project is built, the internal .NET CLI command is invoked by the MSBuild system, which builds the project and generates the assembly (.dll) or executable (.exe) file. This assembly contains the manifest that contains the assembly's metadata, and includes the version number, culture, type-reference information, information about the referenced assemblies, and a list of other files in the assembly and their association. This assembly manifest is stored either in the MSIL code or in a standalone portable executable (PE) file:

Now, when the executable is run, a new process is started and bootstraps the .NET Core runtime, which then initializes the execution environment, sets up the heap and thread pool, and loads the assembly into the process address space. Based on the program, it then executes the main entry point method (Main) and performs a JIT compilation. From here, the code starts executing and the objects start allocating memory on heap, where primitive types store on stack. For each method, the JIT compilation is done and the native machine code gets generated.

When JIT compilation is done, and before generating a native machine code, however, it also performs a few validations. These validations include the following:

  • Verifying, that the MSIL was generated during the build process
  • Verifying, whether any code was modified or new types added during the JIT compilation process
  • Verifying, that the optimized code for the target machine has been generated