Генерирует ли компилятор .NET JIT другой код для универсального параметризованного с различными перечислениями? - PullRequest
5 голосов
/ 21 июля 2011

Если я напишу (или использую) универсальный класс, например List, и параметризирую его двумя различными перечисляемыми типами, получу ли я две копии кода JITted?Учитывая следующие статьи, в которых обсуждается, как JITter генерирует одну копию для ссылочных типов и одну копию для каждого типа значения, я думаю, что это сводится к следующему: «Считается ли каждое конкретное перечисление отдельным типом значения для целей JITting?»

CLR против JIT

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

В коде C #:

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?
        }
    }
}

Мне интересно знать это вв общем, но также и специально для JIT-компилятора .NET CF 3.5 (WindowsCE) (EDIT: потому что меня интересуют возможные последствия раздувания кода).Любые предложения о том, как лучше всего это выяснить?Я думал о написании функции в классе C, которая P / вызывает в нативный код, где я могу взломать отладчик и исследовать стек вызовов - в частности, адрес возврата, но, возможно, кто-то может ответить авторитетно, основываясь на правилах языка, которые яя не в курсе ...

1 Ответ

5 голосов
/ 21 июля 2011

Итак, я собрал функцию P / Invoke для вызова из функции C .Test. Я ворвался в отладчик (окна рабочего стола, поддерживающие управляемую и собственную отладку) в нативной функции, затем перешел на сборку, а затем отследил инструкцию RET из моей нативной функции. EIP (указатель инструкций) после RET соответствовал возвращению к ДВУМЯ РАЗНЫМ подпрограммам, одна для C .Test, а другая для C .Test. Многократные вызовы через эти две функции к общей нативной функции (с моей точкой останова) показали согласованные результаты. Кроме того, после RET EIP были 0x2E0246 и 0x2E02BE, которые расположены рядом друг с другом и также не сопоставлены с адресным пространством загруженных библиотек DLL. Это указывает мне на то, что они были JITted и JITted близко по времени друг к другу, и размер методов JITted небольшой (как и ожидалось).

Таким образом, ответ, по крайней мере для настольных компьютеров, заключается в том, что дженерики, созданные с различными JIT-перечислениями для разных подпрограмм.

...