【问题标题】:What is the purpose of the _HACK methods in System.Internal (.net 4.0 on x64)System.Internal(x64 上的 .net 4.0)中的 _HACK 方法的目的是什么
【发布时间】:2011-02-25 20:30:12
【问题描述】:

在 x64 上的 .net 4.0 的 mscorlib 中有一个类 System.Internal,它包含三个后缀为 _HACK 的静态方法。有人知道这些方法的目的是什么吗?

这是 .NET Reflector 的输出:

internal static class Internal
{
    // Methods
    private static void CommonlyUsedGenericInstantiations_HACK()
    {
        Array.Sort<double>(null);
        Array.Sort<int>(null);
        Array.Sort<IntPtr>(null);
        new ArraySegment<byte>(new byte[1], 0, 0);
        new Dictionary<char, object>();
        new Dictionary<Guid, byte>();
        new Dictionary<Guid, object>();
        new Dictionary<Guid, Guid>();
        new Dictionary<short, IntPtr>();
        new Dictionary<int, byte>();
        new Dictionary<int, int>();
        new Dictionary<int, object>();
        new Dictionary<IntPtr, bool>();
        new Dictionary<IntPtr, short>();
        new Dictionary<object, bool>();
        new Dictionary<object, char>();
        new Dictionary<object, Guid>();
        new Dictionary<object, int>();
        new Dictionary<object, long>();
        new Dictionary<uint, WeakReference>();
        new Dictionary<object, uint>();
        new Dictionary<uint, object>();
        new Dictionary<long, object>();
        new Dictionary<MemberTypes, object>();
        new EnumEqualityComparer<MemberTypes>();
        new Dictionary<object, KeyValuePair<object, object>>();
        new Dictionary<KeyValuePair<object, object>, object>();
        NullableHelper_HACK<bool>();
        NullableHelper_HACK<byte>();
        NullableHelper_HACK<char>();
        NullableHelper_HACK<DateTime>();
        NullableHelper_HACK<decimal>();
        NullableHelper_HACK<double>();
        NullableHelper_HACK<Guid>();
        NullableHelper_HACK<short>();
        NullableHelper_HACK<int>();
        NullableHelper_HACK<long>();
        NullableHelper_HACK<float>();
        NullableHelper_HACK<TimeSpan>();
        NullableHelper_HACK<DateTimeOffset>();
        new List<bool>();
        new List<byte>();
        new List<char>();
        new List<DateTime>();
        new List<decimal>();
        new List<double>();
        new List<Guid>();
        new List<short>();
        new List<int>();
        new List<long>();
        new List<TimeSpan>();
        new List<sbyte>();
        new List<float>();
        new List<ushort>();
        new List<uint>();
        new List<ulong>();
        new List<IntPtr>();
        new List<KeyValuePair<object, object>>();
        new List<GCHandle>();
        new List<DateTimeOffset>();
        RuntimeType.RuntimeTypeCache.Prejitinit_HACK();
        new CerArrayList<RuntimeMethodInfo>(0);
        new CerArrayList<RuntimeConstructorInfo>(0);
        new CerArrayList<RuntimePropertyInfo>(0);
        new CerArrayList<RuntimeEventInfo>(0);
        new CerArrayList<RuntimeFieldInfo>(0);
        new CerArrayList<RuntimeType>(0);
        new KeyValuePair<char, ushort>('\0', 0);
        new KeyValuePair<ushort, double>(0, double.MinValue);
        new KeyValuePair<object, int>(string.Empty, -2147483648);
        new KeyValuePair<int, int>(-2147483648, -2147483648);
        SZArrayHelper_HACK<bool>(null);
        SZArrayHelper_HACK<byte>(null);
        SZArrayHelper_HACK<DateTime>(null);
        SZArrayHelper_HACK<decimal>(null);
        SZArrayHelper_HACK<double>(null);
        SZArrayHelper_HACK<Guid>(null);
        SZArrayHelper_HACK<short>(null);
        SZArrayHelper_HACK<int>(null);
        SZArrayHelper_HACK<long>(null);
        SZArrayHelper_HACK<TimeSpan>(null);
        SZArrayHelper_HACK<sbyte>(null);
        SZArrayHelper_HACK<float>(null);
        SZArrayHelper_HACK<ushort>(null);
        SZArrayHelper_HACK<uint>(null);
        SZArrayHelper_HACK<ulong>(null);
        SZArrayHelper_HACK<DateTimeOffset>(null);
        SZArrayHelper_HACK<CustomAttributeTypedArgument>(null);
        SZArrayHelper_HACK<CustomAttributeNamedArgument>(null);
    }

    private static T NullableHelper_HACK<T>() where T: struct
    {
        Nullable.Compare<T>(null, null);
        Nullable.Equals<T>(null, null);
        T? nullable = null;
        return nullable.GetValueOrDefault();
    }

    private static void SZArrayHelper_HACK<T>(SZArrayHelper oSZArrayHelper)
    {
        oSZArrayHelper.get_Count<T>();
        oSZArrayHelper.get_Item<T>(0);
        oSZArrayHelper.GetEnumerator<T>();
    }
}

【问题讨论】:

    标签: c# generics .net-4.0 64-bit internals


    【解决方案1】:

    我认为它已涵盖但添加我自己的解释。这是一个代码生成优化。当抖动为一个泛型类生成代码时,它只需要生成它的几个版本。有一个涵盖任何引用类型,这就是为什么您会在代码中看到 object 的原因。每个不同的值类型都有一个。这就是为什么你会看到 byte、bool、short、int、uint 很流行的原因。

    此代码位于 mscorlib.dll 中,因此可在 ngen-ed 映像中预编译。然后抖动可以直接使用,而无需即时生成机器代码。实际上,这是 ngen 无法预先猜测需要哪些通用实例化的一种解决方法。显然,详尽地预先生成所有可能的组合是不切实际的,尤其是对于像 Dictionary 这样的类。毫无疑问,他们分析了一堆代码,看看哪些泛型类型参数最流行,可能从框架本身开始。

    【讨论】:

      【解决方案2】:

      代码似乎确保这些函数和对象已被实例化(根据@usr,将执行这些实例化的是 NGEN)。该技术在 C++ 中也很常见,可确保将特定模板实例化编译到库中。

      【讨论】:

        【解决方案3】:

        Jeremiah Willcock 并不完全正确:这不是针对 JIT,而是针对 NGEN 编译器。它从托管 dll 创建一个大部分是静态的本机 dll。 JIT 不关心这些实例化。

        【讨论】:

        • 所以它比我想象的更像 C++ 版本。我认为这是强制 JIT 实例化事物,因为这通常是泛型实例化的方式。
        • 我想你可以这么说。没有注意到相似之处。
        猜你喜欢
        • 1970-01-01
        • 2011-01-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-07-31
        • 2014-04-25
        相关资源
        最近更新 更多