System.Internal中的HACK方法(x64上的.net 4.0)
在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);
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>();
}
}
我认为它已经涵盖,但加入我自己的解释。 这是一个代码生成优化。 当抖动为泛型类生成代码时,它只需要生成它的几个版本。 有一个涵盖任何引用类型,这就是为什么你看到代码中使用对象。 每个不同的值类型都有一个。 这就是为什么你会看到byte,bool,short,int,uint受欢迎的原因。
此代码位于mscorlib.dll中,因此可在ngen-ed映像中预编译。 抖动可以直接使用,而不需要即时生成机器码。 实际上,这是ngen无法事先猜测哪些泛型实例是必需的解决方法。 显然,穷举每一种可能的组合都是不切实际的,特别是像Dictionary <>这样的类。 毫无疑问,他们分析了一堆代码,以查看哪些泛型类型参数最受欢迎,可能从框架本身开始。
代码似乎确保这些函数和对象已经被实例化(根据@usr,NGEN会做这些实例化)。 该技术在C ++中也很常见,以确保将特定模板实例化编译到库中。
Jeremiah Willcock并不完全正确:这不是针对JIT,而是针对NGEN编译器。 它从受管dll创建一个大部分是静态的原生dll。 JIT不关心这些实例。
链接地址: http://www.djcxy.com/p/51207.html