The CLR’s Execution Model

Compiling Source Code into Managed Modules:

The common language runtime (CLR) is just what its name says it is: a runtime that is usable by different and varied programming languages. The core features of the CLR (such as memory management, assembly loading, security, exception handling, and thread synchronization) are available to any and all programming languages that target it.

In fact, at runtime, the CLR has no idea which programming language the developer used for the source code! By the way, managed assemblies always take advantage of Data Execution Prevention (DEP) and Address Space Layout Randomization (ASLR) in Windows; these two features improve the security of your whole system.

Figure below describes the CLR compilation process

Table blow describes parts of a managed module

Combining Managed Modules into Assemblies:

The CLR doesn’t actually work with modules, it works with assemblies. An assembly is an abstract concept that can be difficult to grasp initially. First, an assembly is a logical grouping of one or more modules or resource files. Second, an assembly is the smallest unit of reuse, security, and versioning. Depending on the choices you make with your compilers or tools, you can produce a single-file or a multi-file assembly. In the CLR world, an assembly is what we would call a component.

Figure below should help explain what assemblies are about. In this figure, some managed modules and resource (or data) files are being processed by a tool. This tool produces a single PE32(+) file that represents the logical grouping of files. What happens is that this PE32(+) file contains a block of data called the manifest. The manifest is simply another set of metadata tables. These tables describe the files that make up the assembly, the publicly exported types implemented by the files in the assembly, and the resource or data files that are associated with the assembly.

Assembly can do the following for you:

  • Allows you to decouple the logical and physical notions of a reusable, securable, versionable component.
  • Assemblies are self-descriptive, so their deployment is very easy.

Loading the Common Language Runtime:

Developers who want to write code that works only on a specific version of Windows might do this when using unsafe code or when interoperating with unmanaged code that is targeted to a specific CPU architecture. To aid these developers, the C# compiler offers a /platform command-line switch. This switch allows you to specify whether the resulting assembly can run on x86 machines running 32-bit Windows versions only, x64 machines running 64-bit Windows only, or Intel Itanium machines running 64-bit Windows only. If you don’t specify a platform, the default is anycpu, which indicates that the resulting assembly can run on any version of Windows.

64-bit versions of Windows offer a technology that allows 32-bit Windows applications to run. This technology is called WoW64 (for Windows on Windows64). This technology even allows 32-bit applications with x86 native code in them to run on an Itanium machine, because the WoW64 technology can emulate the x86 instruction set; albeit with a significant performance cost.

Process of loading is describes as:

  1. Windows examines EXE file’s header to determine whether the application requires a 32-bit or 64-bit address space.
  2. Windows also checks the CPU architecture information embedded inside the header to ensure that it matches the CPU type in the computer.
  3. After Windows has examined the EXE file’s header to determine whether to create a 32-bit process, a 64-bit process, or a WoW64 process, Windows loads the x86, x64, or IA64 version of MSCorEE.dll into the process’s address space
  4. Then, the process’s primary thread calls a method defined inside MSCorEE.dll. This method initializes the CLR, loads the EXE assembly, and then calls its entry point method (Main).

Executing your Assembly Code:

To execute a method, its IL must first be converted to native CPU instructions. This is the jobof the CLR’s JIT (just-in-time) compiler. Figure below shows what the happens when WriteLine is called for the first time.

Figure below shows what the process looks like when WriteLine is called the second time.

A performance hit is incurred only the first time a method is called. All subsequent calls tothe method execute at the full speed of the native code because verification and compilationto native code don’t need to be performed again.

Benefits of CLR and managed code over unmanaged code:

  • Write optimal code depending on the current machine architecture.
  • A JIT compiler can determine when a certain test is always false on the machine that itis running on. For example, consider a method that contains the following code:
    if (numberOfCPUs> 1) { ….}
    This code could cause the JIT compiler to not generate any CPU instructions if the hostmachine has only one CPU. In this case, the native code would be fine-tuned for thehost machine; the resulting code is smaller and executes faster.
  • The CLR could profile the code’s execution and recompile the IL into native code whilethe application runs. The recompiled code could be reorganized to reduce incorrectbranch predictions depending on the observed execution patterns. Current versions ofthe CLR do not do this, but future versions might.
  • Verification:
    • Verifies the code and make sure that there are no security problems.
    • Ability to runmultiple managed applications in a single Windows virtual address space. That will save a lot of OS resources.

The Native Code Generator Tool: NGen.exe:

The NGen.exe tool that ships with the .NET Framework can be used to compile IL code tonative code when an application is installed on a user’s machine. Since the code is compiledat install time, the CLR’s JIT compiler does not have to compile the IL code at runtime, andthis can improve the application’s performance. The NGen.exe tool is interesting in twoscenarios:

  1. Improving an application’s startup time.
  2. Reducing an application’s working set.

The compiled files using NGen.exe can be found under the directory


The directory name includes theversion of the CLR and information denoting whether the native code is compiled for x86(32-bit version of Windows), x64, or Itanium (the latter two for 64-bit versions of Windows).

Now, whenever the CLR loads an assembly file, the CLR looks to see if a correspondingNGen’d native file exists. If a native file cannot be found, the CLR JIT compiles the IL code asusual.

There are several potential problems with respect to NGen’d files:

  1. No intellectual property protection (especially in customer side applications)
  2. NGen’d files can get out of sync:
    When the CLR loads an NGen’d file, it compares anumber of characteristics about the previously compiled code and the current execution environment. If any of the characteristics don’t match, the NGen’d file cannot beused, and the normal JIT compiler process is used instead. Here is a partial list of characteristicsthat must match:
    1. CLR version: this changes with patches or service packs
    2. CPU type: this changes if you upgrade your processor hardware.
    3. Windows OS version: these changes with a new service pack update.
    4. Assembly’s identity module version ID (MVID): this changes when recompiling.
    5. Referenced assembly’s version IDs: this changes when you recompile a referencedassembly.
    6. Security: this changes when you revoke permissions (such as declarative inheritance,declarative link-time, SkipVerification, or UnmanagedCode permissions),that were once granted.
  3. Inferior execution-time performance

For sure it doesn’t make sense to use NGen.exe with server-side services.

Interoperability with Unmanaged Code:

The CLR supports these interoperability scenarios

  1. Managed code can call unmanaged function in a DLL: using P/Invoke mechanism.
  2. Managed code can use an existing COM component (server)

Unmanaged code can use a managed type (server)

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s