2011-02-25 8 views
7

En el mscorlib de .net 4.0 en x64 hay una clase System.Internal que contiene tres métodos estáticos con el sufijo _HACK. ¿Alguien tiene una idea de cuál es el propósito de estos métodos?Cuál es el propósito de los métodos _HACK en System.Internal (.net 4.0 en x64)

Aquí está la salida .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>(); 
    } 
} 

Respuesta

0

El código parece estar asegurándose de que esas funciones y objetos han sido instanciado (según @usr, es NGEN que estaría haciendo esas instancias). Esa técnica también es común en C++ para garantizar que las instancias de plantillas particulares se compilan en una biblioteca.

0

Jeremiah Willcock no es del todo correcto: esto no está dirigido al JIT sino al compilador NGEN. Crea una dll nativa en su mayoría estática del dll administrado. El JIT no se preocupa por estas instancias.

+0

Así que es más como la versión de C++ de lo que pensaba. Había asumido que era forzar al JIT a que creara una instancia de las cosas, ya que generalmente es así como se crean instancias de los genéricos. –

+0

Creo que podrías decir eso. No noté la similitud. – usr

+0

Edité mi respuesta para decir NGEN en lugar de JIT. –

4

Creo que está cubierto pero añado mi propia interpretación. Es una optimización de generación de código. Cuando el jitter genera código para una clase genérica, solo necesita generar algunas versiones de él. Hay uno que cubre cualquier tipo de referencia, es por eso que ve objeto que se utiliza en el código. Y hay uno para cada tipo de valor distinto. Es por eso que ves byte, bool, short, int, uint siendo popular.

Este código reside en mscorlib.dll y, por lo tanto, está disponible precompilado en la imagen ngen-ed. Que el jitter puede usar directamente sin necesidad de generar el código de la máquina sobre la marcha. En efecto, es una solución para que ngen sea incapaz de adivinar qué instancias genéricas serán necesarias. Claramente, no es práctico pregular exhaustivamente todas las combinaciones posibles, especialmente para una clase como Dictionary <>. Sin duda, analizaron un montón de código para ver qué argumentos de tipo genérico eran los más populares, probablemente comenzando con el propio marco.

Cuestiones relacionadas