Browse DevX
Sign up for e-mail newsletters from DevX


Down to the Metal: Managed Code Under the Hood (Part I) : Page 2

No matter which high-level languages you use to create .NET applications, they all compile to Intermediate Language (IL). In this series, you’ll dig down inside the .NET framework and find out how IL works. Learn to write IL directly to create .NET assemblies without the need for a high-level language or sophisticated IDEs.




Building the Right Environment to Support AI, Machine Learning and Deep Learning

How the VES Works
The VES needs to be able to execute managed code on many possible platforms. Therefore, it's impossible to build the VES like an execution environment intended for specific processor architecture, such as Intel architecture. That means the CLI cannot make assumptions about registers, cache, or operations available on the target system. All those considerations must be abstracted to a form common to all platforms, or to a theoretical form that will be compiled to the real target platform by the Just In Time (JIT) compiler when the code will be executed. Method State
The .NET VES implements some interesting mechanisms for this purpose. The execution engine runs all the control threads of managed code applications and the memory management in a shared memory space. Every control thread executes methods that put their information on a managed heap, which is maintained by the garbage collector. For each method call the VES creates a new method state memory block. When one method finishes the VES hands control back to the method state that invoked the just-completed method. When the last method state returns (the entry point of an application), the application terminates. The diagram in Figure 1 (based on a diagram in the Microsoft's Tools Developers Guide) illustrates flow of methods in VES nicely:

Figure 1. State Model: The figure shows how control threads create method states on the managed heap. As each method finishes, the execution engine hands control back to the method state that invoked the completing method.
A method state always consists of several parts:
  • Instruction Pointer—points to the next instruction to be executed
  • Method Info Handle—stores read only information about the methods signature
  • Evaluation Stack—more on this later
  • Incoming Arguments—the arguments used to call this method
  • Local Variables—an array of all local objects starting at index 0
  • Local Allocations—used for dynamic allocation of local objects
  • Security Descriptor—not accessible by managed code, but used by the CLI to record security overrides (assert, permit and deny)
  • Return State Handle—restores the method state to the one from the caller (this is often referred to as a dynamic link)
Evaluation Stack
Each method state has an associated evaluation stack used by most CLI instructions to retrieve arguments for calls and store results from calls. The evaluation stack consists only of objects; it doesn't matter if you push an integer, string or a custom object on the stack—the virtual environment only counts how many things are stored on the stack and in what order. Of course, the VES is concerned about type safety as it calls methods, but for now you just need to know that if you call a method that takes three arguments you must place those three arguments on the evaluation stack before calling the method. That pattern holds true not only for this particular three-argument method, but for any CLI function that requires arguments. Another important evaluation stack rule is that the evaluation stack must contain only the return value at each possible exit point of your method (or no value when a method returns void (a Sub (subroutine) method in VB.NET).

Comment and Contribute






(Maximum characters: 1200). You have 1200 characters left.



Thanks for your registration, follow us on our social networks to keep up-to-date