From af2b93c81fedff73a946dc587da6722e557cea2e Mon Sep 17 00:00:00 2001 From: EgorBo Date: Tue, 7 Mar 2023 01:20:29 +0100 Subject: [PATCH 1/2] Remove s_default field from EqualityComparer.NativeAot.cs and Comparer.NativeAot.cs --- .../Collections/Generic/Comparer.NativeAot.cs | 21 +++++-------------- .../Generic/EqualityComparer.NativeAot.cs | 21 +++++-------------- .../TypeSystem/IL/Stubs/ComparerIntrinsics.cs | 18 ---------------- 3 files changed, 10 insertions(+), 50 deletions(-) diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Collections/Generic/Comparer.NativeAot.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Collections/Generic/Comparer.NativeAot.cs index d22979ebb33652..18726d63d9cec3 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Collections/Generic/Comparer.NativeAot.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Collections/Generic/Comparer.NativeAot.cs @@ -12,8 +12,6 @@ namespace System.Collections.Generic { public abstract partial class Comparer : IComparer, IComparer { - private static Comparer s_default; - // The AOT compiler can flip this to false under certain circumstances. private static bool SupportsGenericIComparableInterfaces => true; @@ -25,23 +23,14 @@ private static Comparer Create() // This body serves as a fallback when instantiation-specific implementation is unavailable. // If that happens, the compiler ensures we generate data structures to make the fallback work // when this method is compiled. - Interlocked.CompareExchange(ref s_default, - SupportsGenericIComparableInterfaces - ? Unsafe.As>(ComparerHelpers.GetComparer(typeof(T).TypeHandle)) - : new ObjectComparer(), - null); - return s_default; - } - - public static Comparer Default - { - [Intrinsic] - get + if (SupportsGenericIComparableInterfaces) { - // Lazy initialization produces smaller code for AOT compilation than initialization in constructor - return s_default ?? Create(); + return Unsafe.As>(ComparerHelpers.GetComparer(typeof(T).TypeHandle)); } + return new ObjectComparer(); } + + public static Comparer Default { [Intrinsic] get; } = Create(); } internal sealed partial class EnumComparer : Comparer where T : struct, Enum diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Collections/Generic/EqualityComparer.NativeAot.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Collections/Generic/EqualityComparer.NativeAot.cs index e88a62173b6a23..0b5c3d2914aa9e 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Collections/Generic/EqualityComparer.NativeAot.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Collections/Generic/EqualityComparer.NativeAot.cs @@ -12,8 +12,6 @@ namespace System.Collections.Generic { public abstract partial class EqualityComparer : IEqualityComparer, IEqualityComparer { - private static EqualityComparer s_default; - // The AOT compiler can flip this to false under certain circumstances. private static bool SupportsGenericIEquatableInterfaces => true; @@ -25,23 +23,14 @@ private static EqualityComparer Create() // This body serves as a fallback when instantiation-specific implementation is unavailable. // If that happens, the compiler ensures we generate data structures to make the fallback work // when this method is compiled. - Interlocked.CompareExchange(ref s_default, - SupportsGenericIEquatableInterfaces - ? Unsafe.As>(EqualityComparerHelpers.GetComparer(typeof(T).TypeHandle)) - : new ObjectEqualityComparer(), - null); - return s_default; - } - - public static EqualityComparer Default - { - [Intrinsic] - get + if (SupportsGenericIEquatableInterfaces) { - // Lazy initialization produces smaller code for AOT compilation than initialization in constructor - return s_default ?? Create(); + return Unsafe.As>(EqualityComparerHelpers.GetComparer(typeof(T).TypeHandle)); } + return new ObjectEqualityComparer(); } + + public static EqualityComparer Default { [Intrinsic] get; } = Create(); } public sealed partial class EnumEqualityComparer : EqualityComparer where T : struct, Enum diff --git a/src/coreclr/tools/Common/TypeSystem/IL/Stubs/ComparerIntrinsics.cs b/src/coreclr/tools/Common/TypeSystem/IL/Stubs/ComparerIntrinsics.cs index 0b7161bb207347..95a29ae04fc181 100644 --- a/src/coreclr/tools/Common/TypeSystem/IL/Stubs/ComparerIntrinsics.cs +++ b/src/coreclr/tools/Common/TypeSystem/IL/Stubs/ComparerIntrinsics.cs @@ -65,25 +65,7 @@ private static MethodIL EmitComparerAndEqualityComparerCreateCommon(MethodDesc m ILEmitter emitter = new ILEmitter(); var codeStream = emitter.NewCodeStream(); - FieldDesc defaultField = owningType.GetKnownField("s_default"); - - TypeSystemContext context = comparerType.Context; - TypeDesc objectType = context.GetWellKnownType(WellKnownType.Object); - MethodDesc compareExchangeObject = context.SystemModule. - GetKnownType("System.Threading", "Interlocked"). - GetKnownMethod("CompareExchange", - new MethodSignature( - MethodSignatureFlags.Static, - genericParameterCount: 0, - returnType: objectType, - parameters: new TypeDesc[] { objectType.MakeByRefType(), objectType, objectType })); - - codeStream.Emit(ILOpcode.ldsflda, emitter.NewToken(defaultField)); codeStream.Emit(ILOpcode.newobj, emitter.NewToken(comparerType.GetParameterlessConstructor())); - codeStream.Emit(ILOpcode.ldnull); - codeStream.Emit(ILOpcode.call, emitter.NewToken(compareExchangeObject)); - codeStream.Emit(ILOpcode.pop); - codeStream.Emit(ILOpcode.ldsfld, emitter.NewToken(defaultField)); codeStream.Emit(ILOpcode.ret); return emitter.Link(methodBeingGenerated); From 0f696a95a24f30bdaf5ef98f7db3633bd7cf615c Mon Sep 17 00:00:00 2001 From: EgorBo Date: Tue, 7 Mar 2023 01:39:34 +0100 Subject: [PATCH 2/2] formatting --- .../src/System/Collections/Generic/Comparer.NativeAot.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Collections/Generic/Comparer.NativeAot.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Collections/Generic/Comparer.NativeAot.cs index 18726d63d9cec3..c14dc49f0e61aa 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Collections/Generic/Comparer.NativeAot.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Collections/Generic/Comparer.NativeAot.cs @@ -29,7 +29,7 @@ private static Comparer Create() } return new ObjectComparer(); } - + public static Comparer Default { [Intrinsic] get; } = Create(); }