Skip to content
This repository has been archived by the owner on Jan 23, 2023. It is now read-only.

Generic Enum implementation #22161

Closed
wants to merge 56 commits into from
Closed
Show file tree
Hide file tree
Changes from 31 commits
Commits
Show all changes
56 commits
Select commit Hold shift + click to select a range
fff3814
Refactored enum implementation to natively use generics and improve p…
TylerBrinkley Dec 18, 2018
00c5ab5
Revert changes to solution
TylerBrinkley Dec 18, 2018
fd8ad55
More improvements
TylerBrinkley Dec 22, 2018
4f7f1ac
More enum improvements
TylerBrinkley Dec 27, 2018
a7cdf92
More enum stuff
TylerBrinkley Dec 28, 2018
d28b4ad
Bug fixes for passing tests
TylerBrinkley Jan 4, 2019
5340f6d
Fix for Reflection.Emit test
TylerBrinkley Jan 7, 2019
adffe50
cache is now only initialized when required
TylerBrinkley Jan 7, 2019
22490ad
Integrated EnumMembers directly in EnumCache.
TylerBrinkley Jan 8, 2019
4e8fddd
Merge from master
TylerBrinkley Jan 8, 2019
4db150f
Fix merge conflicts
TylerBrinkley Jan 8, 2019
a81c09b
More updates
TylerBrinkley Jan 14, 2019
0538fcb
Some performance improvements
TylerBrinkley Jan 16, 2019
9e54144
small updates
TylerBrinkley Jan 17, 2019
0bf0abd
More performance updates
TylerBrinkley Jan 18, 2019
1a685e3
More changes
TylerBrinkley Jan 18, 2019
ab2370b
More updates
TylerBrinkley Jan 18, 2019
2c929f4
More updates
TylerBrinkley Jan 18, 2019
e38eb2f
More updates
TylerBrinkley Jan 18, 2019
b98f63b
More updates
TylerBrinkley Jan 18, 2019
be0c69b
More updates
TylerBrinkley Jan 18, 2019
13e1b3a
More updates
TylerBrinkley Jan 18, 2019
cd35ff1
More updates
TylerBrinkley Jan 19, 2019
d3019e7
More updates
TylerBrinkley Jan 19, 2019
ebe210c
More updates
TylerBrinkley Jan 19, 2019
36cffa3
More updates
TylerBrinkley Jan 19, 2019
3ba2ff1
More updates
TylerBrinkley Jan 22, 2019
7600eba
More updates
TylerBrinkley Jan 23, 2019
10535fe
More updates
TylerBrinkley Jan 23, 2019
cb609e4
small bug fix for empty enums
TylerBrinkley Jan 23, 2019
0e4c165
Merge branch 'master' into enum-perf
TylerBrinkley Jan 23, 2019
a9f9d30
Refactored to reduce static costs, i.e. minimize code in EnumCache<TE…
TylerBrinkley Jan 24, 2019
92f1577
Merge branch 'enum-perf' of https://github.com/TylerBrinkley/coreclr …
TylerBrinkley Jan 24, 2019
6fdc52f
Renamed EnumCache to EnumBridge
TylerBrinkley Jan 25, 2019
d538752
Small update
TylerBrinkley Jan 28, 2019
e36097c
More updates
TylerBrinkley Jan 31, 2019
6e25a9b
Undo comparer changes
TylerBrinkley Jan 31, 2019
7f84a7a
Cleaned up formatting issue
TylerBrinkley Jan 31, 2019
c004a81
Undo formatting change
TylerBrinkley Jan 31, 2019
2e80387
Switched back to storing the values as TUnderlying[] instead of ulong…
TylerBrinkley Feb 2, 2019
82186e9
fix contiguous determination
TylerBrinkley Feb 4, 2019
7d0646e
Small updates
TylerBrinkley Feb 25, 2019
7b021be
Merge remote-tracking branch 'upstream/master' into enum-perf
TylerBrinkley Mar 4, 2019
6586eb3
Fix ToStringFlags IndexOutOfRangeException
TylerBrinkley Mar 5, 2019
86dda15
Made exceptions more consistent with existing logic.
TylerBrinkley Mar 6, 2019
e0a8ded
Reduced use of generics with an Enum type argument
TylerBrinkley Mar 22, 2019
561cf85
Removed use of Activator.CreateInstance and one case of Type.GetField
TylerBrinkley Mar 22, 2019
d5bdb19
Removed the EnumBridge type entirely so we no longer instantiate gene…
TylerBrinkley Apr 23, 2019
e2ab8e1
Fix merge conflicts
TylerBrinkley Apr 24, 2019
b915a80
Fix merge conflicts
TylerBrinkley Apr 24, 2019
1a965bd
Fix merge conflict
TylerBrinkley Apr 24, 2019
291c7c8
Fix bug introduced when fixing merge conflicts
TylerBrinkley Apr 24, 2019
9d11018
Fix flag parsing bug
TylerBrinkley Apr 25, 2019
66677f7
Fix exception body
TylerBrinkley Apr 25, 2019
536bc66
Merge branch 'master' into enum-perf
TylerBrinkley May 2, 2019
22c3745
Fix nullability warnings
TylerBrinkley May 3, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ internal static object CreateDefaultComparer(Type type)
// The comparer for enums is specialized to avoid boxing.
else if (type.IsEnum)
{
result = TryCreateEnumComparer(runtimeType);
result = CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(EnumComparer<DayOfWeek>), runtimeType);
TylerBrinkley marked this conversation as resolved.
Show resolved Hide resolved
}

return result ?? CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(ObjectComparer<object>), runtimeType);
Expand All @@ -75,38 +75,6 @@ private static object TryCreateNullableComparer(RuntimeType nullableType)
return null;
}

/// <summary>
/// Creates the default <see cref="Comparer{T}"/> for an enum type.
/// </summary>
/// <param name="enumType">The enum type to create the default comparer for.</param>
private static object TryCreateEnumComparer(RuntimeType enumType)
{
Debug.Assert(enumType != null);
Debug.Assert(enumType.IsEnum);

// Explicitly call Enum.GetUnderlyingType here. Although GetTypeCode
// ends up doing this anyway, we end up avoiding an unnecessary P/Invoke
// and virtual method call.
TypeCode underlyingTypeCode = Type.GetTypeCode(Enum.GetUnderlyingType(enumType));

// Depending on the enum type, we need to special case the comparers so that we avoid boxing.
// Specialize differently for signed/unsigned types so we avoid problems with large numbers.
switch (underlyingTypeCode)
{
case TypeCode.SByte:
case TypeCode.Int16:
case TypeCode.Int32:
case TypeCode.Byte:
case TypeCode.UInt16:
case TypeCode.UInt32:
case TypeCode.Int64:
case TypeCode.UInt64:
return RuntimeTypeHandle.CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(EnumComparer<>), enumType);
}

return null;
}

/// <summary>
/// Creates the default <see cref="EqualityComparer{T}"/>.
/// </summary>
Expand Down Expand Up @@ -143,7 +111,7 @@ internal static object CreateDefaultEqualityComparer(Type type)
// The equality comparer for enums is specialized to avoid boxing.
else if (type.IsEnum)
{
result = TryCreateEnumEqualityComparer(runtimeType);
result = CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(EnumEqualityComparer<DayOfWeek>), runtimeType);
}

return result ?? CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(ObjectEqualityComparer<object>), runtimeType);
Expand All @@ -167,36 +135,5 @@ private static object TryCreateNullableEqualityComparer(RuntimeType nullableType

return null;
}

/// <summary>
/// Creates the default <see cref="EqualityComparer{T}"/> for an enum type.
/// </summary>
/// <param name="enumType">The enum type to create the default equality comparer for.</param>
private static object TryCreateEnumEqualityComparer(RuntimeType enumType)
{
Debug.Assert(enumType != null);
Debug.Assert(enumType.IsEnum);

// See the METHOD__JIT_HELPERS__UNSAFE_ENUM_CAST and METHOD__JIT_HELPERS__UNSAFE_ENUM_CAST_LONG cases in getILIntrinsicImplementation
// for how we cast the enum types to integral values in the comparer without boxing.

TypeCode underlyingTypeCode = Type.GetTypeCode(Enum.GetUnderlyingType(enumType));

// Depending on the enum type, we need to special case the comparers so that we avoid boxing.
switch (underlyingTypeCode)
{
case TypeCode.Int32:
case TypeCode.UInt32:
case TypeCode.SByte:
case TypeCode.Byte:
case TypeCode.Int16:
case TypeCode.Int64:
case TypeCode.UInt64:
case TypeCode.UInt16:
return RuntimeTypeHandle.CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(EnumEqualityComparer<>), enumType);
}

return null;
}
}
}
Loading