ARC413: Whidbey CLR Internals

ARC413: Whidbey CLR Internals

  • Comments 2

Reader warning: this session was deep! I take no responsibility for any subtle inaccuracies I've introduced. I've missed out some of the most complex stuff to minimise the risk of error...

Generics
Generics are not a new concept; they have been around for many years in other languages, including C++ (as templates). Generics are commonly used for collections. In C++, if you create an object such as a Stack<T> and use it as Stack<int>, Stack<double>, and Stack<point>, the C++ compiler does the work of turning this into three separate classes. In C#, the compiler doesn't do this, but instead this is handled through extensions to the runtime.

In the IL, parameters are represented as !x, where x is the ordinal of the specific type parameter. IL is of course a stack-based machine. A line such as:

   T retval = _array[index];

is represented as:

   ldarg.0
   ldfld !0[] class GenericsDemo.GenericStack<!0>::_array
   ldloc.0
   ldelem !0
   stloc.1

Detailed metadata information on the generics can be viewed using MetaInfo (choose View / MetaInfo). Using this tool, you can view the heap as well as the metadata tables. The TypeDef table contains the definitions of each generic; you can use this to drill into the heap and via the string tables identify the various different elements of the generic. A metadata table GenericParam, for example, can be viewed to see all the generic types used as parameters.

Each method has a signature. The first byte of every signature highlights the calling convention (e.g. 20 is an instance method). The remaining bytes highlight the number of parameters, the return type and the parameter types. So a signature commencing 20 01 01 indicates an instance method with one parameter that returns void. The parameter types are lookups; for generics, the parameter type is 13 and the parameter number is then referenced (an ordinal for the generic commencing at 0).

Edit and Continue
As with generics, EnC is an extension to the CLR, rather than a language feature. It's up to the specific language to decide which features of EnC to support. Visual Basic "Whidbey" supports EnC, but even this isn't a full implementation of everything that's available in the CLR. (The C# team have chosen not to support EnC in the Whidbey release.)

When you make changes at a breakpoint, the debugger creates a separate set of metadata tables called delta metadata. This contains just the additional or changed metadata. The debugger also creates delta IL with an RVA (relative virtual address).  Other tables (EnCLog and EnCMap) handle the mapping into the original IL. The CLR then copies the delta into the original metadata, so that the new code can be found. Once this has happened, the running state needs to be remapped to ensure that the stack and registers are still valid.

  • Nice... could you be coaxed into sharing more info about generic IL? If there's any more you know, that is.
  • Richard, that's a great question. Let me see if I can get some pointers to some other useful links as post them here. Tim
Page 1 of 1 (2 items)