Skip to content

Commit

Permalink
Take advantage of new optimization
Browse files Browse the repository at this point in the history
  • Loading branch information
MichalStrehovsky committed Feb 6, 2020
1 parent 1615ea5 commit 6996492
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 88 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -966,7 +966,7 @@ internal static object[] GetCustomAttributes(RuntimeType type, RuntimeType caTyp
for (int i = 0; i < pcas.Count; i++)
result.Add(pcas[i]);

while (type != (RuntimeType)typeof(object) && type != null)
while (type != typeof(object) && type != null)
{
AddCustomAttributes(ref result, type.GetRuntimeModule(), type.MetadataToken, caType, mustBeInheritable, result);
mustBeInheritable = true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2325,7 +2325,6 @@ private static bool FilterApplyMethodBase(
internal static readonly RuntimeType ValueType = (RuntimeType)typeof(System.ValueType);

private static readonly RuntimeType ObjectType = (RuntimeType)typeof(object);
private static readonly RuntimeType StringType = (RuntimeType)typeof(string);
#endregion

#region Constructor
Expand Down Expand Up @@ -3074,7 +3073,7 @@ public override bool IsSubclassOf(Type type)
// pretty much everything is a subclass of object, even interfaces
// notice that interfaces are really odd because they do not have a BaseType
// yet IsSubclassOf(typeof(object)) returns true
if (rtType == ObjectType && rtType != this)
if (rtType == typeof(object) && rtType != this)
return true;

return false;
Expand Down Expand Up @@ -3317,7 +3316,6 @@ public override Type MakeArrayType(int rank)
private const BindingFlags BinderGetSetProperty = BindingFlags.GetProperty | BindingFlags.SetProperty;
private const BindingFlags BinderGetSetField = BindingFlags.GetField | BindingFlags.SetField;
private const BindingFlags BinderNonFieldGetSet = (BindingFlags)0x00FFF300;
private static readonly RuntimeType s_typedRef = (RuntimeType)typeof(TypedReference);

[MethodImpl(MethodImplOptions.InternalCall)]
private static extern bool CanValueSpecialCast(RuntimeType valueType, RuntimeType targetType);
Expand Down Expand Up @@ -3360,7 +3358,7 @@ public override Type MakeArrayType(int rank)
}
else if (value == null)
return value;
else if (this == s_typedRef)
else if (this == typeof(TypedReference))
// everything works for a typedref
return value;

Expand Down
114 changes: 36 additions & 78 deletions src/libraries/System.Private.CoreLib/src/System/Convert.cs
Original file line number Diff line number Diff line change
Expand Up @@ -94,34 +94,6 @@ public enum Base64FormattingOptions

public static partial class Convert
{
// A typeof operation is fairly expensive (does a system call), so we'll cache these here
// statically. These are exactly lined up with the TypeCode, eg. ConvertType[TypeCode.Int16]
// will give you the type of an short.
internal static readonly Type[] ConvertTypes = {
typeof(System.Empty),
typeof(object),
typeof(System.DBNull),
typeof(bool),
typeof(char),
typeof(sbyte),
typeof(byte),
typeof(short),
typeof(ushort),
typeof(int),
typeof(uint),
typeof(long),
typeof(ulong),
typeof(float),
typeof(double),
typeof(decimal),
typeof(DateTime),
typeof(object), // TypeCode is discontinuous so we need a placeholder.
typeof(string)
};

// Need to special case Enum because typecode will be underlying type, e.g. Int32
private static readonly Type EnumType = typeof(Enum);

internal static readonly char[] base64Table = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd',
'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's',
Expand All @@ -130,20 +102,6 @@ public static partial class Convert

private const int base64LineBreakPosition = 76;

#if DEBUG
static Convert()
{
Debug.Assert(ConvertTypes != null, "[Convert.cctor]ConvertTypes!=null");
Debug.Assert(ConvertTypes.Length == ((int)TypeCode.String + 1), "[Convert.cctor]ConvertTypes.Length == ((int)TypeCode.String + 1)");
Debug.Assert(ConvertTypes[(int)TypeCode.Empty] == typeof(System.Empty),
"[Convert.cctor]ConvertTypes[(int)TypeCode.Empty]==typeof(System.Empty)");
Debug.Assert(ConvertTypes[(int)TypeCode.String] == typeof(string),
"[Convert.cctor]ConvertTypes[(int)TypeCode.String]==typeof(System.String)");
Debug.Assert(ConvertTypes[(int)TypeCode.Int32] == typeof(int),
"[Convert.cctor]ConvertTypes[(int)TypeCode.Int32]==typeof(int)");
}
#endif

public static readonly object DBNull = System.DBNull.Value;

// Returns the type code for the given object. If the argument is null,
Expand Down Expand Up @@ -235,49 +193,49 @@ internal static object DefaultToType(IConvertible value, Type targetType, IForma
throw new ArgumentNullException(nameof(targetType));
}

if (ReferenceEquals(value.GetType(), targetType))
if (value.GetType() == targetType)
{
return value;
}

if (ReferenceEquals(targetType, ConvertTypes[(int)TypeCode.Boolean]))
if (targetType == typeof(bool))
return value.ToBoolean(provider);
if (ReferenceEquals(targetType, ConvertTypes[(int)TypeCode.Char]))
if (targetType == typeof(char))
return value.ToChar(provider);
if (ReferenceEquals(targetType, ConvertTypes[(int)TypeCode.SByte]))
if (targetType == typeof(sbyte))
return value.ToSByte(provider);
if (ReferenceEquals(targetType, ConvertTypes[(int)TypeCode.Byte]))
if (targetType == typeof(byte))
return value.ToByte(provider);
if (ReferenceEquals(targetType, ConvertTypes[(int)TypeCode.Int16]))
if (targetType == typeof(short))
return value.ToInt16(provider);
if (ReferenceEquals(targetType, ConvertTypes[(int)TypeCode.UInt16]))
if (targetType == typeof(ushort))
return value.ToUInt16(provider);
if (ReferenceEquals(targetType, ConvertTypes[(int)TypeCode.Int32]))
if (targetType == typeof(int))
return value.ToInt32(provider);
if (ReferenceEquals(targetType, ConvertTypes[(int)TypeCode.UInt32]))
if (targetType == typeof(uint))
return value.ToUInt32(provider);
if (ReferenceEquals(targetType, ConvertTypes[(int)TypeCode.Int64]))
if (targetType == typeof(long))
return value.ToInt64(provider);
if (ReferenceEquals(targetType, ConvertTypes[(int)TypeCode.UInt64]))
if (targetType == typeof(ulong))
return value.ToUInt64(provider);
if (ReferenceEquals(targetType, ConvertTypes[(int)TypeCode.Single]))
if (targetType == typeof(float))
return value.ToSingle(provider);
if (ReferenceEquals(targetType, ConvertTypes[(int)TypeCode.Double]))
if (targetType == typeof(double))
return value.ToDouble(provider);
if (ReferenceEquals(targetType, ConvertTypes[(int)TypeCode.Decimal]))
if (targetType == typeof(decimal))
return value.ToDecimal(provider);
if (ReferenceEquals(targetType, ConvertTypes[(int)TypeCode.DateTime]))
if (targetType == typeof(DateTime))
return value.ToDateTime(provider);
if (ReferenceEquals(targetType, ConvertTypes[(int)TypeCode.String]))
if (targetType == typeof(string))
return value.ToString(provider);
if (ReferenceEquals(targetType, ConvertTypes[(int)TypeCode.Object]))
if (targetType == typeof(object))
return (object)value;
// Need to special case Enum because typecode will be underlying type, e.g. Int32
if (ReferenceEquals(targetType, EnumType))
if (targetType == typeof(Enum))
return (Enum)value;
if (ReferenceEquals(targetType, ConvertTypes[(int)TypeCode.DBNull]))
if (targetType == typeof(DBNull))
throw new InvalidCastException(SR.InvalidCast_DBNull);
if (ReferenceEquals(targetType, ConvertTypes[(int)TypeCode.Empty]))
if (targetType == typeof(Empty))
throw new InvalidCastException(SR.InvalidCast_Empty);

throw new InvalidCastException(SR.Format(SR.InvalidCast_FromTo, value.GetType().FullName, targetType.FullName));
Expand Down Expand Up @@ -315,37 +273,37 @@ internal static object DefaultToType(IConvertible value, Type targetType, IForma
throw new InvalidCastException(SR.InvalidCast_IConvertible);
}

if (ReferenceEquals(conversionType, ConvertTypes[(int)TypeCode.Boolean]))
if (conversionType == typeof(bool))
return ic.ToBoolean(provider);
if (ReferenceEquals(conversionType, ConvertTypes[(int)TypeCode.Char]))
if (conversionType == typeof(char))
return ic.ToChar(provider);
if (ReferenceEquals(conversionType, ConvertTypes[(int)TypeCode.SByte]))
if (conversionType == typeof(sbyte))
return ic.ToSByte(provider);
if (ReferenceEquals(conversionType, ConvertTypes[(int)TypeCode.Byte]))
if (conversionType == typeof(byte))
return ic.ToByte(provider);
if (ReferenceEquals(conversionType, ConvertTypes[(int)TypeCode.Int16]))
if (conversionType == typeof(short))
return ic.ToInt16(provider);
if (ReferenceEquals(conversionType, ConvertTypes[(int)TypeCode.UInt16]))
if (conversionType == typeof(ushort))
return ic.ToUInt16(provider);
if (ReferenceEquals(conversionType, ConvertTypes[(int)TypeCode.Int32]))
if (conversionType == typeof(int))
return ic.ToInt32(provider);
if (ReferenceEquals(conversionType, ConvertTypes[(int)TypeCode.UInt32]))
if (conversionType == typeof(uint))
return ic.ToUInt32(provider);
if (ReferenceEquals(conversionType, ConvertTypes[(int)TypeCode.Int64]))
if (conversionType == typeof(long))
return ic.ToInt64(provider);
if (ReferenceEquals(conversionType, ConvertTypes[(int)TypeCode.UInt64]))
if (conversionType == typeof(ulong))
return ic.ToUInt64(provider);
if (ReferenceEquals(conversionType, ConvertTypes[(int)TypeCode.Single]))
if (conversionType == typeof(float))
return ic.ToSingle(provider);
if (ReferenceEquals(conversionType, ConvertTypes[(int)TypeCode.Double]))
if (conversionType == typeof(double))
return ic.ToDouble(provider);
if (ReferenceEquals(conversionType, ConvertTypes[(int)TypeCode.Decimal]))
if (conversionType == typeof(decimal))
return ic.ToDecimal(provider);
if (ReferenceEquals(conversionType, ConvertTypes[(int)TypeCode.DateTime]))
if (conversionType == typeof(DateTime))
return ic.ToDateTime(provider);
if (ReferenceEquals(conversionType, ConvertTypes[(int)TypeCode.String]))
if (conversionType == typeof(string))
return ic.ToString(provider);
if (ReferenceEquals(conversionType, ConvertTypes[(int)TypeCode.Object]))
if (conversionType == typeof(object))
return (object)value;

return ic.ToType(conversionType, provider);
Expand Down
10 changes: 5 additions & 5 deletions src/libraries/System.Private.CoreLib/src/System/RuntimeType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -189,19 +189,19 @@ protected override TypeCode GetTypeCodeImpl()
case CorElementType.ELEMENT_TYPE_R8:
typeCode = TypeCode.Double; break;
case CorElementType.ELEMENT_TYPE_VALUETYPE:
if (this == Convert.ConvertTypes[(int)TypeCode.Decimal])
if (this == typeof(decimal))
typeCode = TypeCode.Decimal;
else if (this == Convert.ConvertTypes[(int)TypeCode.DateTime])
else if (this == typeof(DateTime))
typeCode = TypeCode.DateTime;
else if (IsEnum)
typeCode = GetTypeCode(Enum.GetUnderlyingType(this));
else
typeCode = TypeCode.Object;
break;
default:
if (this == Convert.ConvertTypes[(int)TypeCode.DBNull])
if (this == typeof(DBNull))
typeCode = TypeCode.DBNull;
else if (this == Convert.ConvertTypes[(int)TypeCode.String])
else if (this == typeof(string))
typeCode = TypeCode.String;
else
typeCode = TypeCode.Object;
Expand Down Expand Up @@ -250,7 +250,7 @@ public override bool IsEnumDefined(object value)
}

// If a string is passed in
if (valueType == StringType)
if (valueType == typeof(string))
{
// Get all of the Fields, calling GetHashEntry directly to avoid copying
string[] names = Enum.InternalGetNames(this);
Expand Down

0 comments on commit 6996492

Please sign in to comment.