Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does .NET JIT compiler generate different code for generic parameterized with different enums?

If I write (or use) a generic class, e.g. List, and parameterize it with two different enumerated types, will I get two copies of code JITted? Given the following articles that discuss the how the JITter generates one copy for reference types, and one copy for each value type, I think this boils down to, "Is each specific enum considered a different value type for the purpose of JITting?"

CLR vs JIT

http://msdn.microsoft.com/en-us/library/ms379564%28v=vs.80%29.aspx#csharp_generics_topic1

In C# code:

using System.Collections.Generic;

namespace Z
{
    class Program
    {
        enum A {a}
        enum B {b}
        class C<T>
        {
        }

        static void Main(string[] args)
        {
            var x = new C<A>();
            var y = new C<B>(); // does this JIT a new C constructor for enum type B?
        }
    }
}

I'm interested to know this in general, but also specifically for the .NET CF 3.5 (WindowsCE) JIT compiler (EDIT: because I'm interested in possible code bloat implications). Any suggestions on the best way to find this out? I was thinking of writing a function in class C that P/Invokes to native code, where I can break into the debugger and examine the callstack - specifically the return address, but perhaps someone can answer authoritatively based on the language rules of which I'm not aware...

like image 507
Wil S Avatar asked Jul 20 '11 20:07

Wil S


1 Answers

So I went ahead and put together a P/Invoke function to call from a C<T>.Test function. I broke into the debugger (desktop windows supporting managed and native debugging) in the native function, then dropped to assembly, then tracked past the RET instruction from my native function. The EIP (instruction pointer) after the RET was consistent with returning to TWO DIFFERENT routines, one for C<A>.Test, and the other for C<B>.Test. Multiple calls through these two functions to the common native function (with my breakpoint) showed consistent results. Further, the post RET EIPs were 0x2E0246 and 0x2E02BE, which are near each other and also not mapped to a loaded DLLs's address space. This indicates to me that they were JITted, and JITted close in time to each other, and the size of the JITted methods are small (as expected).

So the answer, at least for the desktop, is that generics templated with different enums JIT to different routines.

like image 75
Wil S Avatar answered Sep 23 '22 15:09

Wil S