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', 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>();
}
}
In the mscorlib of .net 4.0 on x64 there is a class System.Internal
that contains three static methods with the suffix _HACK
. Does anybody have an idea what the purpose of these methods is?
Here is the .NET Reflector output:
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>();
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我认为它已被涵盖,但添加我自己的解释。这是代码生成优化。当抖动为通用类生成代码时,它只需要生成它的几个版本。有一个涵盖任何引用类型,这就是为什么您会看到代码中使用对象。每种不同的值类型都有一个。这就是为什么你看到 byte、bool、short、int、uint 流行的原因。
该代码位于 mscorlib.dll 中,因此可以在 ngen 映像中预编译。然后抖动可以直接使用,无需即时生成机器代码。实际上,这是 ngen 无法预先猜测需要哪些通用实例化的解决方法。显然,详尽地预生成所有可能的组合是不切实际的,特别是对于像 Dictionary<> 这样的类。毫无疑问,他们分析了一堆代码,以了解哪些泛型类型参数最受欢迎,可能从框架本身开始。
I think it's covered but add my own interpretation. It is a code generation optimization. When the jitter generates code for a generic class, it only needs to generate a few versions of it. There's one that covers any reference type, that's why you see object being used in the code. And there's one each for each distinct value type. That's why you see byte, bool, short, int, uint being popular.
This code lives in mscorlib.dll and is therefore available precompiled in the ngen-ed image. Which the jitter can then directly use without a need to generate the machine code on-the-fly. In effect, it is a workaround for ngen being incapable of guessing up front which generic instantiations will be required. Clearly it isn't practical to exhaustively pregen every possible combination, especially for a class like Dictionary<>. They no doubt analyzed a bunch of code to see what generic type arguments were most popular, probably starting with the framework itself.
该代码似乎确保这些函数和对象已被实例化(根据@usr,NGEN 将执行这些实例化)。该技术在 C++ 中也很常见,以确保特定的模板实例被编译到库中。
The code appears to be making sure those functions and objects have been instantiated (according to @usr, it is NGEN that would be doing those instantiations). That technique is also common in C++ to ensure that particular template instantiations are compiled into a library.
Jeremiah Willcock 并不完全正确:这不是针对 JIT 而是针对 NGEN 编译器。它从托管 dll 创建一个大部分静态的本机 dll。 JIT 不关心这些实例化。
Jeremiah Willcock is not entirely correct: This is not targeted at the JIT but at the NGEN compiler. It creates a mostly-static native dll from the managed dll. The JIT does not care about these instantiations.