2011-02-25 2 views
7

x64의 .net 4.0 mscorlib에는 System.Internal 클래스에 세 가지 정적 메서드 (_HACK 포함)가 있습니다. 아무도이 방법의 목적이 무엇인지 생각하지 못했습니까? 여기 System.Internal (x64의 .net 4.0)에서 _HACK 메서드의 용도는 무엇입니까

는 .NET 반사판 출력 :

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>(); 
    } 
} 

답변

0

코드는 그 기능과 객체 인스턴스화되었는지 확인하고있는 것으로 보인다 (@usr에 따르면, 그 인스턴스화을하고있을 것입니다 NGEN이다). 이 기법은 특정 템플릿 인스턴스화가 라이브러리로 컴파일되도록하기 위해 C++에서도 일반적입니다.

0

Jeremiah Willcock은 완전히 정확하지 않습니다. JIT이지만 NGEN 컴파일러를 대상으로하지 않습니다. 그것은 관리 dll에서 주로 정적 네이티브 dll을 만듭니다. JIT는 이러한 인스턴스화를 신경 쓰지 않습니다.

+0

그래서 생각했던 것보다 C++ 버전에 가깝습니다. JIT가 물건을 인스턴스화하도록 강요한다고 가정했는데, 그 이유는 그것이 일반적으로 제네릭이 어떻게 인스턴스화 되었기 때문입니다. –

+0

당신이 그렇게 말할 수 있다고 생각합니다. 유사성을 느끼지 못했습니다. – usr

+0

나는 JIT보다는 NGEN이라고 대답하기 위해 나의 대답을 편집했다. –

4

나는 그것이 다룰 거라 생각하지만 내 자신의 해석을 추가하십시오. 코드 생성 최적화입니다. 지터가 제네릭 클래스 용 코드를 생성 할 때 지터가 생성되면 몇 가지 버전 만 생성하면됩니다. 참조 유형을 포함하는 코드가 있으므로 객체이 코드에 사용 된 것을 볼 수 있습니다. 각 값 유형마다 하나씩 있습니다. 그래서 byte, bool, short, int, uint가 인기있는 것을 볼 수 있습니다.

이 코드는 mscorlib.dll에 있으며 따라서 ngen-ed 이미지에 사전 컴파일되어 사용할 수 있습니다. 따라서 지터는 즉시 기계 코드를 생성 할 필요없이 직접 사용할 수 있습니다. 결과적으로, ngen이 일반적인 인스턴스화가 필요할 것으로 추측 할 수 없게되는 문제를 해결할 수 있습니다. 특히 < 사전과 같은 클래스의 경우 모든 가능한 조합을 철저하게 사전 작성하는 것이 바람직하지 않습니다. 그들은 의심 할 여지없이 프레임 워크 자체부터 시작하여 일반적인 유형의 인수가 가장 많이 사용 된 코드를 확인하기 위해 많은 코드를 분석했습니다.