From 2f297c2b55d8303a317fa7aa111ac275fe753d66 Mon Sep 17 00:00:00 2001 From: Huo Yaoyuan Date: Thu, 23 Dec 2021 16:42:08 +0800 Subject: [PATCH 1/7] Remove ternary workaround for string.IsNullOrEmpty --- src/libraries/System.Private.CoreLib/src/System/String.cs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/String.cs b/src/libraries/System.Private.CoreLib/src/System/String.cs index 260c87b5fd911..08a7a913afea2 100644 --- a/src/libraries/System.Private.CoreLib/src/System/String.cs +++ b/src/libraries/System.Private.CoreLib/src/System/String.cs @@ -485,9 +485,7 @@ public char[] ToCharArray(int startIndex, int length) [NonVersionable] public static bool IsNullOrEmpty([NotNullWhen(false)] string? value) { - // Ternary operator returning true/false prevents redundant asm generation: - // https://github.com/dotnet/runtime/issues/4207 - return (value == null || 0 == value.Length) ? true : false; + return value == null || value.Length == 0; } public static bool IsNullOrWhiteSpace([NotNullWhen(false)] string? value) From a1a9f025614fcebd8d2d7b63d4b8ecfc854753d7 Mon Sep 17 00:00:00 2001 From: Huo Yaoyuan Date: Sat, 25 Dec 2021 16:27:12 +0800 Subject: [PATCH 2/7] Remove workaround in operator== --- .../src/System/MulticastDelegate.cs | 10 ++-------- .../src/System/MulticastDelegate.cs | 11 ++--------- .../System.Private.CoreLib/src/System/Delegate.cs | 11 ++--------- .../src/System/Globalization/SortVersion.cs | 7 ++----- .../src/System/Reflection/Assembly.cs | 7 ++----- .../src/System/Reflection/ConstructorInfo.cs | 7 ++----- .../src/System/Reflection/EventInfo.cs | 7 ++----- .../src/System/Reflection/FieldInfo.cs | 7 ++----- .../src/System/Reflection/MemberInfo.cs | 7 ++----- .../src/System/Reflection/MethodBase.cs | 7 ++----- .../src/System/Reflection/MethodInfo.cs | 7 ++----- .../src/System/Reflection/Module.cs | 7 ++----- .../src/System/Reflection/PropertyInfo.cs | 7 ++----- .../System.Private.CoreLib/src/System/Version.cs | 12 ++++-------- 14 files changed, 30 insertions(+), 84 deletions(-) diff --git a/src/coreclr/System.Private.CoreLib/src/System/MulticastDelegate.cs b/src/coreclr/System.Private.CoreLib/src/System/MulticastDelegate.cs index 6abac717392c3..346a0b264b6eb 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/MulticastDelegate.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/MulticastDelegate.cs @@ -4,7 +4,6 @@ using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Reflection; -using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Serialization; @@ -430,23 +429,18 @@ public sealed override Delegate[] GetInvocationList() return del; } - // Force inline as the true/false ternary takes it above ALWAYS_INLINE size even though the asm ends up smaller - [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool operator ==(MulticastDelegate? d1, MulticastDelegate? d2) { // Test d2 first to allow branch elimination when inlined for null checks (== null) // so it can become a simple test if (d2 is null) { - // return true/false not the test result https://github.com/dotnet/runtime/issues/4207 - return (d1 is null) ? true : false; + return d1 is null; } return ReferenceEquals(d2, d1) ? true : d2.Equals((object?)d1); } - // Force inline as the true/false ternary takes it above ALWAYS_INLINE size even though the asm ends up smaller - [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool operator !=(MulticastDelegate? d1, MulticastDelegate? d2) { // Can't call the == operator as it will call object== @@ -456,7 +450,7 @@ public sealed override Delegate[] GetInvocationList() if (d2 is null) { // return true/false not the test result https://github.com/dotnet/runtime/issues/4207 - return (d1 is null) ? false : true; + return d1 is not null; } return ReferenceEquals(d2, d1) ? false : !d2.Equals(d1); diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/MulticastDelegate.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/MulticastDelegate.cs index eda6c45aa296c..a7144e227c7d2 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/MulticastDelegate.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/MulticastDelegate.cs @@ -6,7 +6,6 @@ using System.Reflection; using System.Runtime; using System.Runtime.Serialization; -using System.Runtime.CompilerServices; using Internal.Runtime.CompilerServices; @@ -108,23 +107,18 @@ public override sealed int GetHashCode() } } - // Force inline as the true/false ternary takes it above ALWAYS_INLINE size even though the asm ends up smaller - [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool operator ==(MulticastDelegate? d1, MulticastDelegate? d2) { // Test d2 first to allow branch elimination when inlined for null checks (== null) // so it can become a simple test if (d2 is null) { - // return true/false not the test result https://github.com/dotnet/runtime/issues/4207 - return (d1 is null) ? true : false; + return d1 is null; } return ReferenceEquals(d2, d1) ? true : d2.Equals((object?)d1); } - // Force inline as the true/false ternary takes it above ALWAYS_INLINE size even though the asm ends up smaller - [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool operator !=(MulticastDelegate? d1, MulticastDelegate? d2) { // Can't call the == operator as it will call object== @@ -133,8 +127,7 @@ public override sealed int GetHashCode() // so it can become a simple test if (d2 is null) { - // return true/false not the test result https://github.com/dotnet/runtime/issues/4207 - return (d1 is null) ? false : true; + return d1 is not null; } return ReferenceEquals(d2, d1) ? false : !d2.Equals(d1); diff --git a/src/libraries/System.Private.CoreLib/src/System/Delegate.cs b/src/libraries/System.Private.CoreLib/src/System/Delegate.cs index 9f22b48fde707..bd26237daeda6 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Delegate.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Delegate.cs @@ -3,7 +3,6 @@ using System.Diagnostics.CodeAnalysis; using System.Reflection; -using System.Runtime.CompilerServices; using System.Runtime.Serialization; namespace System @@ -93,31 +92,25 @@ public abstract partial class Delegate : ICloneable, ISerializable return newDelegate; } - // Force inline as the true/false ternary takes it above ALWAYS_INLINE size even though the asm ends up smaller - [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool operator ==(Delegate? d1, Delegate? d2) { // Test d2 first to allow branch elimination when inlined for null checks (== null) // so it can become a simple test if (d2 is null) { - // return true/false not the test result https://github.com/dotnet/runtime/issues/4207 - return (d1 is null) ? true : false; + return d1 is null; } return ReferenceEquals(d2, d1) ? true : d2.Equals((object?)d1); } - // Force inline as the true/false ternary takes it above ALWAYS_INLINE size even though the asm ends up smaller - [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool operator !=(Delegate? d1, Delegate? d2) { // Test d2 first to allow branch elimination when inlined for not null checks (!= null) // so it can become a simple test if (d2 is null) { - // return true/false not the test result https://github.com/dotnet/runtime/issues/4207 - return (d1 is null) ? false : true; + return d1 is not null; } return ReferenceEquals(d2, d1) ? false : !d2.Equals(d1); diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/SortVersion.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/SortVersion.cs index 93ca171b29e31..9231bb79f2dee 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/SortVersion.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/SortVersion.cs @@ -7,7 +7,7 @@ namespace System.Globalization { [Serializable] - [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] + [TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] public sealed class SortVersion : IEquatable { private readonly int m_NlsVersion; // Do not rename (binary serialization) @@ -59,16 +59,13 @@ public override int GetHashCode() return m_NlsVersion * 7 | m_SortId.GetHashCode(); } - // Force inline as the true/false ternary takes it above ALWAYS_INLINE size even though the asm ends up smaller - [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool operator ==(SortVersion? left, SortVersion? right) { // Test "right" first to allow branch elimination when inlined for null checks (== null) // so it can become a simple test if (right is null) { - // return true/false not the test result https://github.com/dotnet/runtime/issues/4207 - return (left is null) ? true : false; + return left is null; } return right.Equals(left); diff --git a/src/libraries/System.Private.CoreLib/src/System/Reflection/Assembly.cs b/src/libraries/System.Private.CoreLib/src/System/Reflection/Assembly.cs index 3612e751aee28..f8a87b207c52f 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Reflection/Assembly.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Reflection/Assembly.cs @@ -8,7 +8,6 @@ using System.Diagnostics.CodeAnalysis; using System.Runtime.Serialization; using System.Security; -using System.Runtime.CompilerServices; using System.Runtime.Loader; namespace System.Reflection @@ -179,19 +178,17 @@ public override string ToString() public override bool Equals(object? o) => base.Equals(o); public override int GetHashCode() => base.GetHashCode(); - [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool operator ==(Assembly? left, Assembly? right) { // Test "right" first to allow branch elimination when inlined for null checks (== null) // so it can become a simple test if (right is null) { - // return true/false not the test result https://github.com/dotnet/runtime/issues/4207 - return (left is null) ? true : false; + return left is null; } // Try fast reference equality and opposite null check prior to calling the slower virtual Equals - if ((object?)left == (object)right) + if (ReferenceEquals(left, right)) { return true; } diff --git a/src/libraries/System.Private.CoreLib/src/System/Reflection/ConstructorInfo.cs b/src/libraries/System.Private.CoreLib/src/System/Reflection/ConstructorInfo.cs index 178c872b34b1d..8f3647251ed62 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Reflection/ConstructorInfo.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Reflection/ConstructorInfo.cs @@ -3,7 +3,6 @@ using System.Diagnostics; using System.Globalization; -using System.Runtime.CompilerServices; namespace System.Reflection { @@ -21,19 +20,17 @@ protected ConstructorInfo() { } public override bool Equals(object? obj) => base.Equals(obj); public override int GetHashCode() => base.GetHashCode(); - [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool operator ==(ConstructorInfo? left, ConstructorInfo? right) { // Test "right" first to allow branch elimination when inlined for null checks (== null) // so it can become a simple test if (right is null) { - // return true/false not the test result https://github.com/dotnet/runtime/issues/4207 - return (left is null) ? true : false; + return left is null; } // Try fast reference equality and opposite null check prior to calling the slower virtual Equals - if ((object?)left == (object)right) + if (ReferenceEquals(left, right)) { return true; } diff --git a/src/libraries/System.Private.CoreLib/src/System/Reflection/EventInfo.cs b/src/libraries/System.Private.CoreLib/src/System/Reflection/EventInfo.cs index 02f19f16bbbd5..a453dad6f0f3a 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Reflection/EventInfo.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Reflection/EventInfo.cs @@ -2,7 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Diagnostics; -using System.Runtime.CompilerServices; namespace System.Reflection { @@ -84,19 +83,17 @@ public virtual void RemoveEventHandler(object? target, Delegate? handler) public override bool Equals(object? obj) => base.Equals(obj); public override int GetHashCode() => base.GetHashCode(); - [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool operator ==(EventInfo? left, EventInfo? right) { // Test "right" first to allow branch elimination when inlined for null checks (== null) // so it can become a simple test if (right is null) { - // return true/false not the test result https://github.com/dotnet/runtime/issues/4207 - return (left is null) ? true : false; + return left is null; } // Try fast reference equality and opposite null check prior to calling the slower virtual Equals - if ((object?)left == (object)right) + if (ReferenceEquals(left, right)) { return true; } diff --git a/src/libraries/System.Private.CoreLib/src/System/Reflection/FieldInfo.cs b/src/libraries/System.Private.CoreLib/src/System/Reflection/FieldInfo.cs index a50821d7ed02b..08c05569af56f 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Reflection/FieldInfo.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Reflection/FieldInfo.cs @@ -3,7 +3,6 @@ using System.Diagnostics; using System.Globalization; -using System.Runtime.CompilerServices; namespace System.Reflection { @@ -39,19 +38,17 @@ protected FieldInfo() { } public override bool Equals(object? obj) => base.Equals(obj); public override int GetHashCode() => base.GetHashCode(); - [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool operator ==(FieldInfo? left, FieldInfo? right) { // Test "right" first to allow branch elimination when inlined for null checks (== null) // so it can become a simple test if (right is null) { - // return true/false not the test result https://github.com/dotnet/runtime/issues/4207 - return (left is null) ? true : false; + return left is null; } // Try fast reference equality and opposite null check prior to calling the slower virtual Equals - if ((object?)left == (object)right) + if (ReferenceEquals(left, right)) { return true; } diff --git a/src/libraries/System.Private.CoreLib/src/System/Reflection/MemberInfo.cs b/src/libraries/System.Private.CoreLib/src/System/Reflection/MemberInfo.cs index 61381b7edc8f2..c7a9391bcaf0d 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Reflection/MemberInfo.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Reflection/MemberInfo.cs @@ -2,7 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Collections.Generic; -using System.Runtime.CompilerServices; namespace System.Reflection { @@ -43,19 +42,17 @@ public virtual Module Module public override bool Equals(object? obj) => base.Equals(obj); public override int GetHashCode() => base.GetHashCode(); - [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool operator ==(MemberInfo? left, MemberInfo? right) { // Test "right" first to allow branch elimination when inlined for null checks (== null) // so it can become a simple test if (right is null) { - // return true/false not the test result https://github.com/dotnet/runtime/issues/4207 - return (left is null) ? true : false; + return left is null; } // Try fast reference equality and opposite null check prior to calling the slower virtual Equals - if ((object?)left == (object)right) + if (ReferenceEquals(left, right)) { return true; } diff --git a/src/libraries/System.Private.CoreLib/src/System/Reflection/MethodBase.cs b/src/libraries/System.Private.CoreLib/src/System/Reflection/MethodBase.cs index a9d065ffbc345..84520a381416e 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Reflection/MethodBase.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Reflection/MethodBase.cs @@ -4,7 +4,6 @@ using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Globalization; -using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Text; using Internal.Runtime.CompilerServices; @@ -64,19 +63,17 @@ this is ConstructorInfo && public override bool Equals(object? obj) => base.Equals(obj); public override int GetHashCode() => base.GetHashCode(); - [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool operator ==(MethodBase? left, MethodBase? right) { // Test "right" first to allow branch elimination when inlined for null checks (== null) // so it can become a simple test if (right is null) { - // return true/false not the test result https://github.com/dotnet/runtime/issues/4207 - return (left is null) ? true : false; + return left is null; } // Try fast reference equality and opposite null check prior to calling the slower virtual Equals - if ((object?)left == (object)right) + if (ReferenceEquals(left, right)) { return true; } diff --git a/src/libraries/System.Private.CoreLib/src/System/Reflection/MethodInfo.cs b/src/libraries/System.Private.CoreLib/src/System/Reflection/MethodInfo.cs index 7e16e554c0807..4b1dd57b8696e 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Reflection/MethodInfo.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Reflection/MethodInfo.cs @@ -2,7 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Diagnostics.CodeAnalysis; -using System.Runtime.CompilerServices; namespace System.Reflection { @@ -38,19 +37,17 @@ protected MethodInfo() { } public override bool Equals(object? obj) => base.Equals(obj); public override int GetHashCode() => base.GetHashCode(); - [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool operator ==(MethodInfo? left, MethodInfo? right) { // Test "right" first to allow branch elimination when inlined for null checks (== null) // so it can become a simple test if (right is null) { - // return true/false not the test result https://github.com/dotnet/runtime/issues/4207 - return (left is null) ? true : false; + return left is null; } // Try fast reference equality and opposite null check prior to calling the slower virtual Equals - if ((object?)left == (object)right) + if (ReferenceEquals(left, right)) { return true; } diff --git a/src/libraries/System.Private.CoreLib/src/System/Reflection/Module.cs b/src/libraries/System.Private.CoreLib/src/System/Reflection/Module.cs index fc762fee94977..50b019680a940 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Reflection/Module.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Reflection/Module.cs @@ -3,7 +3,6 @@ using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; -using System.Runtime.CompilerServices; using System.Runtime.Serialization; namespace System.Reflection @@ -145,19 +144,17 @@ public virtual Type[] FindTypes(TypeFilter? filter, object? filterCriteria) public override bool Equals(object? o) => base.Equals(o); public override int GetHashCode() => base.GetHashCode(); - [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool operator ==(Module? left, Module? right) { // Test "right" first to allow branch elimination when inlined for null checks (== null) // so it can become a simple test if (right is null) { - // return true/false not the test result https://github.com/dotnet/runtime/issues/4207 - return (left is null) ? true : false; + return left is null; } // Try fast reference equality and opposite null check prior to calling the slower virtual Equals - if ((object?)left == (object)right) + if (ReferenceEquals(left, right)) { return true; } diff --git a/src/libraries/System.Private.CoreLib/src/System/Reflection/PropertyInfo.cs b/src/libraries/System.Private.CoreLib/src/System/Reflection/PropertyInfo.cs index 1208a88b6b3d8..e389fd866e70a 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Reflection/PropertyInfo.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Reflection/PropertyInfo.cs @@ -3,7 +3,6 @@ using System.Diagnostics; using System.Globalization; -using System.Runtime.CompilerServices; namespace System.Reflection { @@ -58,19 +57,17 @@ protected PropertyInfo() { } public override bool Equals(object? obj) => base.Equals(obj); public override int GetHashCode() => base.GetHashCode(); - [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool operator ==(PropertyInfo? left, PropertyInfo? right) { // Test "right" first to allow branch elimination when inlined for null checks (== null) // so it can become a simple test if (right is null) { - // return true/false not the test result https://github.com/dotnet/runtime/issues/4207 - return (left is null) ? true : false; + return left is null; } // Try fast reference equality and opposite null check prior to calling the slower virtual Equals - if ((object?)left == (object)right) + if (ReferenceEquals(left, right)) { return true; } diff --git a/src/libraries/System.Private.CoreLib/src/System/Version.cs b/src/libraries/System.Private.CoreLib/src/System/Version.cs index 469da80ebe7cf..6391a6ec63396 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Version.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Version.cs @@ -1,11 +1,10 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Globalization; using System.Diagnostics; -using System.Text; -using System.Runtime.CompilerServices; using System.Diagnostics.CodeAnalysis; +using System.Globalization; +using System.Runtime.CompilerServices; namespace System { @@ -16,7 +15,7 @@ namespace System // specified component. [Serializable] - [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] + [TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] public sealed class Version : ICloneable, IComparable, IComparable, IEquatable, ISpanFormattable { // AssemblyName depends on the order staying the same @@ -375,16 +374,13 @@ private static bool TryParseComponent(ReadOnlySpan component, string compo return int.TryParse(component, NumberStyles.Integer, CultureInfo.InvariantCulture, out parsedComponent) && parsedComponent >= 0; } - // Force inline as the true/false ternary takes it above ALWAYS_INLINE size even though the asm ends up smaller - [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool operator ==(Version? v1, Version? v2) { // Test "right" first to allow branch elimination when inlined for null checks (== null) // so it can become a simple test if (v2 is null) { - // return true/false not the test result https://github.com/dotnet/runtime/issues/4207 - return (v1 is null) ? true : false; + return v1 is null; } // Quick reference equality test prior to calling the virtual Equality From 122683d7e9621f37fd62f7d4307cfb7a8caed6bb Mon Sep 17 00:00:00 2001 From: Huo Yaoyuan Date: Sat, 25 Dec 2021 16:28:51 +0800 Subject: [PATCH 3/7] Remove workarond in character manipulation --- src/libraries/System.Private.CoreLib/src/System/DateTime.cs | 3 +-- .../src/System/Globalization/Ordinal.cs | 4 +--- .../System.Private.CoreLib/src/System/Number.Parsing.cs | 3 +-- 3 files changed, 3 insertions(+), 7 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/DateTime.cs b/src/libraries/System.Private.CoreLib/src/System/DateTime.cs index 1783d197b8ab8..46539e066d9a5 100644 --- a/src/libraries/System.Private.CoreLib/src/System/DateTime.cs +++ b/src/libraries/System.Private.CoreLib/src/System/DateTime.cs @@ -1093,8 +1093,7 @@ public static bool IsLeapYear(int year) } if ((year & 3) != 0) return false; if ((year & 15) == 0) return true; - // return true/false not the test result https://github.com/dotnet/runtime/issues/4207 - return (uint)year % 25 != 0 ? true : false; + return (uint)year % 25 != 0; } // Constructs a DateTime from a string. The string must specify a diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/Ordinal.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/Ordinal.cs index 7c09e69253439..d64069bc36443 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/Ordinal.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/Ordinal.cs @@ -166,9 +166,7 @@ internal static bool EqualsIgnoreCase(ref char charA, ref char charB, int length return false; // not exact match, and first input isn't in [A-Za-z] } - // The ternary operator below seems redundant but helps RyuJIT generate more optimal code. - // See https://github.com/dotnet/runtime/issues/4207. - return (valueA == (valueB | 0x20u)) ? true : false; + return valueA == (valueB | 0x20u); } Debug.Assert(length == 0); diff --git a/src/libraries/System.Private.CoreLib/src/System/Number.Parsing.cs b/src/libraries/System.Private.CoreLib/src/System/Number.Parsing.cs index 40e2fa9a76ee3..e71ecfc80158f 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Number.Parsing.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Number.Parsing.cs @@ -2069,8 +2069,7 @@ private static bool TrailingZeros(ReadOnlySpan value, int index) return null; } - // Ternary op is a workaround for https://github.com/dotnet/runtime/issues/4207 - private static bool IsWhite(int ch) => ch == 0x20 || (uint)(ch - 0x09) <= (0x0D - 0x09) ? true : false; + private static bool IsWhite(int ch) => ch == 0x20 || (uint)(ch - 0x09) <= (0x0D - 0x09); private static bool IsDigit(int ch) => ((uint)ch - '0') <= 9; From e3937c72de3c9b810c49860c0476c10c25cbcf14 Mon Sep 17 00:00:00 2001 From: Huo Yaoyuan Date: Thu, 23 Dec 2021 18:02:01 +0800 Subject: [PATCH 4/7] Remove workaround in ArraySortHelper --- .../Collections/Generic/ArraySortHelper.cs | 110 +++++++++--------- 1 file changed, 54 insertions(+), 56 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/ArraySortHelper.cs b/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/ArraySortHelper.cs index 0f50840b6fabe..be6f2d48064c9 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/ArraySortHelper.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/ArraySortHelper.cs @@ -557,45 +557,44 @@ private static void InsertionSort(Span keys) // - The floating-point comparisons here assume no NaNs, which is valid only because the sorting routines // themselves special-case NaN with a pre-pass that ensures none are present in the values being sorted // by moving them all to the front first and then sorting the rest. - // - The `? true : false` is to work-around poor codegen: https://github.com/dotnet/runtime/issues/37904#issuecomment-644180265. // - These are duplicated here rather than being on a helper type due to current limitations around generic inlining. [MethodImpl(MethodImplOptions.AggressiveInlining)] // compiles to a single comparison or method call private static bool LessThan(ref T left, ref T right) { - if (typeof(T) == typeof(byte)) return (byte)(object)left < (byte)(object)right ? true : false; - if (typeof(T) == typeof(sbyte)) return (sbyte)(object)left < (sbyte)(object)right ? true : false; - if (typeof(T) == typeof(ushort)) return (ushort)(object)left < (ushort)(object)right ? true : false; - if (typeof(T) == typeof(short)) return (short)(object)left < (short)(object)right ? true : false; - if (typeof(T) == typeof(uint)) return (uint)(object)left < (uint)(object)right ? true : false; - if (typeof(T) == typeof(int)) return (int)(object)left < (int)(object)right ? true : false; - if (typeof(T) == typeof(ulong)) return (ulong)(object)left < (ulong)(object)right ? true : false; - if (typeof(T) == typeof(long)) return (long)(object)left < (long)(object)right ? true : false; - if (typeof(T) == typeof(nuint)) return (nuint)(object)left < (nuint)(object)right ? true : false; - if (typeof(T) == typeof(nint)) return (nint)(object)left < (nint)(object)right ? true : false; - if (typeof(T) == typeof(float)) return (float)(object)left < (float)(object)right ? true : false; - if (typeof(T) == typeof(double)) return (double)(object)left < (double)(object)right ? true : false; - if (typeof(T) == typeof(Half)) return (Half)(object)left < (Half)(object)right ? true : false; - return left.CompareTo(right) < 0 ? true : false; + if (typeof(T) == typeof(byte)) return (byte)(object)left < (byte)(object)right; + if (typeof(T) == typeof(sbyte)) return (sbyte)(object)left < (sbyte)(object)right; + if (typeof(T) == typeof(ushort)) return (ushort)(object)left < (ushort)(object)right; + if (typeof(T) == typeof(short)) return (short)(object)left < (short)(object)right; + if (typeof(T) == typeof(uint)) return (uint)(object)left < (uint)(object)right; + if (typeof(T) == typeof(int)) return (int)(object)left < (int)(object)right; + if (typeof(T) == typeof(ulong)) return (ulong)(object)left < (ulong)(object)right; + if (typeof(T) == typeof(long)) return (long)(object)left < (long)(object)right; + if (typeof(T) == typeof(nuint)) return (nuint)(object)left < (nuint)(object)right; + if (typeof(T) == typeof(nint)) return (nint)(object)left < (nint)(object)right; + if (typeof(T) == typeof(float)) return (float)(object)left < (float)(object)right; + if (typeof(T) == typeof(double)) return (double)(object)left < (double)(object)right; + if (typeof(T) == typeof(Half)) return (Half)(object)left < (Half)(object)right; + return left.CompareTo(right) < 0; } [MethodImpl(MethodImplOptions.AggressiveInlining)] // compiles to a single comparison or method call private static bool GreaterThan(ref T left, ref T right) { - if (typeof(T) == typeof(byte)) return (byte)(object)left > (byte)(object)right ? true : false; - if (typeof(T) == typeof(sbyte)) return (sbyte)(object)left > (sbyte)(object)right ? true : false; - if (typeof(T) == typeof(ushort)) return (ushort)(object)left > (ushort)(object)right ? true : false; - if (typeof(T) == typeof(short)) return (short)(object)left > (short)(object)right ? true : false; - if (typeof(T) == typeof(uint)) return (uint)(object)left > (uint)(object)right ? true : false; - if (typeof(T) == typeof(int)) return (int)(object)left > (int)(object)right ? true : false; - if (typeof(T) == typeof(ulong)) return (ulong)(object)left > (ulong)(object)right ? true : false; - if (typeof(T) == typeof(long)) return (long)(object)left > (long)(object)right ? true : false; - if (typeof(T) == typeof(nuint)) return (nuint)(object)left > (nuint)(object)right ? true : false; - if (typeof(T) == typeof(nint)) return (nint)(object)left > (nint)(object)right ? true : false; - if (typeof(T) == typeof(float)) return (float)(object)left > (float)(object)right ? true : false; - if (typeof(T) == typeof(double)) return (double)(object)left > (double)(object)right ? true : false; - if (typeof(T) == typeof(Half)) return (Half)(object)left > (Half)(object)right ? true : false; - return left.CompareTo(right) > 0 ? true : false; + if (typeof(T) == typeof(byte)) return (byte)(object)left > (byte)(object)right; + if (typeof(T) == typeof(sbyte)) return (sbyte)(object)left > (sbyte)(object)right; + if (typeof(T) == typeof(ushort)) return (ushort)(object)left > (ushort)(object)right; + if (typeof(T) == typeof(short)) return (short)(object)left > (short)(object)right; + if (typeof(T) == typeof(uint)) return (uint)(object)left > (uint)(object)right; + if (typeof(T) == typeof(int)) return (int)(object)left > (int)(object)right; + if (typeof(T) == typeof(ulong)) return (ulong)(object)left > (ulong)(object)right; + if (typeof(T) == typeof(long)) return (long)(object)left > (long)(object)right; + if (typeof(T) == typeof(nuint)) return (nuint)(object)left > (nuint)(object)right; + if (typeof(T) == typeof(nint)) return (nint)(object)left > (nint)(object)right; + if (typeof(T) == typeof(float)) return (float)(object)left > (float)(object)right; + if (typeof(T) == typeof(double)) return (double)(object)left > (double)(object)right; + if (typeof(T) == typeof(Half)) return (Half)(object)left > (Half)(object)right; + return left.CompareTo(right) > 0; } } @@ -1055,44 +1054,43 @@ private static void InsertionSort(Span keys, Span values) // - The floating-point comparisons here assume no NaNs, which is valid only because the sorting routines // themselves special-case NaN with a pre-pass that ensures none are present in the values being sorted // by moving them all to the front first and then sorting the rest. - // - The `? true : false` is to work-around poor codegen: https://github.com/dotnet/runtime/issues/37904#issuecomment-644180265. // - These are duplicated here rather than being on a helper type due to current limitations around generic inlining. [MethodImpl(MethodImplOptions.AggressiveInlining)] // compiles to a single comparison or method call private static bool LessThan(ref TKey left, ref TKey right) { - if (typeof(TKey) == typeof(byte)) return (byte)(object)left < (byte)(object)right ? true : false; - if (typeof(TKey) == typeof(sbyte)) return (sbyte)(object)left < (sbyte)(object)right ? true : false; - if (typeof(TKey) == typeof(ushort)) return (ushort)(object)left < (ushort)(object)right ? true : false; - if (typeof(TKey) == typeof(short)) return (short)(object)left < (short)(object)right ? true : false; - if (typeof(TKey) == typeof(uint)) return (uint)(object)left < (uint)(object)right ? true : false; - if (typeof(TKey) == typeof(int)) return (int)(object)left < (int)(object)right ? true : false; - if (typeof(TKey) == typeof(ulong)) return (ulong)(object)left < (ulong)(object)right ? true : false; - if (typeof(TKey) == typeof(long)) return (long)(object)left < (long)(object)right ? true : false; - if (typeof(TKey) == typeof(nuint)) return (nuint)(object)left < (nuint)(object)right ? true : false; - if (typeof(TKey) == typeof(nint)) return (nint)(object)left < (nint)(object)right ? true : false; - if (typeof(TKey) == typeof(float)) return (float)(object)left < (float)(object)right ? true : false; - if (typeof(TKey) == typeof(double)) return (double)(object)left < (double)(object)right ? true : false; - if (typeof(TKey) == typeof(Half)) return (Half)(object)left < (Half)(object)right ? true : false; + if (typeof(TKey) == typeof(byte)) return (byte)(object)left < (byte)(object)right; + if (typeof(TKey) == typeof(sbyte)) return (sbyte)(object)left < (sbyte)(object)right; + if (typeof(TKey) == typeof(ushort)) return (ushort)(object)left < (ushort)(object)right; + if (typeof(TKey) == typeof(short)) return (short)(object)left < (short)(object)right; + if (typeof(TKey) == typeof(uint)) return (uint)(object)left < (uint)(object)right; + if (typeof(TKey) == typeof(int)) return (int)(object)left < (int)(object)right; + if (typeof(TKey) == typeof(ulong)) return (ulong)(object)left < (ulong)(object)right; + if (typeof(TKey) == typeof(long)) return (long)(object)left < (long)(object)right; + if (typeof(TKey) == typeof(nuint)) return (nuint)(object)left < (nuint)(object)right; + if (typeof(TKey) == typeof(nint)) return (nint)(object)left < (nint)(object)right; + if (typeof(TKey) == typeof(float)) return (float)(object)left < (float)(object)right; + if (typeof(TKey) == typeof(double)) return (double)(object)left < (double)(object)right; + if (typeof(TKey) == typeof(Half)) return (Half)(object)left < (Half)(object)right; return left.CompareTo(right) < 0 ? true : false; } [MethodImpl(MethodImplOptions.AggressiveInlining)] // compiles to a single comparison or method call private static bool GreaterThan(ref TKey left, ref TKey right) { - if (typeof(TKey) == typeof(byte)) return (byte)(object)left > (byte)(object)right ? true : false; - if (typeof(TKey) == typeof(sbyte)) return (sbyte)(object)left > (sbyte)(object)right ? true : false; - if (typeof(TKey) == typeof(ushort)) return (ushort)(object)left > (ushort)(object)right ? true : false; - if (typeof(TKey) == typeof(short)) return (short)(object)left > (short)(object)right ? true : false; - if (typeof(TKey) == typeof(uint)) return (uint)(object)left > (uint)(object)right ? true : false; - if (typeof(TKey) == typeof(int)) return (int)(object)left > (int)(object)right ? true : false; - if (typeof(TKey) == typeof(ulong)) return (ulong)(object)left > (ulong)(object)right ? true : false; - if (typeof(TKey) == typeof(long)) return (long)(object)left > (long)(object)right ? true : false; - if (typeof(TKey) == typeof(nuint)) return (nuint)(object)left > (nuint)(object)right ? true : false; - if (typeof(TKey) == typeof(nint)) return (nint)(object)left > (nint)(object)right ? true : false; - if (typeof(TKey) == typeof(float)) return (float)(object)left > (float)(object)right ? true : false; - if (typeof(TKey) == typeof(double)) return (double)(object)left > (double)(object)right ? true : false; - if (typeof(TKey) == typeof(Half)) return (Half)(object)left > (Half)(object)right ? true : false; + if (typeof(TKey) == typeof(byte)) return (byte)(object)left > (byte)(object)right; + if (typeof(TKey) == typeof(sbyte)) return (sbyte)(object)left > (sbyte)(object)right; + if (typeof(TKey) == typeof(ushort)) return (ushort)(object)left > (ushort)(object)right; + if (typeof(TKey) == typeof(short)) return (short)(object)left > (short)(object)right; + if (typeof(TKey) == typeof(uint)) return (uint)(object)left > (uint)(object)right; + if (typeof(TKey) == typeof(int)) return (int)(object)left > (int)(object)right; + if (typeof(TKey) == typeof(ulong)) return (ulong)(object)left > (ulong)(object)right; + if (typeof(TKey) == typeof(long)) return (long)(object)left > (long)(object)right; + if (typeof(TKey) == typeof(nuint)) return (nuint)(object)left > (nuint)(object)right; + if (typeof(TKey) == typeof(nint)) return (nint)(object)left > (nint)(object)right; + if (typeof(TKey) == typeof(float)) return (float)(object)left > (float)(object)right; + if (typeof(TKey) == typeof(double)) return (double)(object)left > (double)(object)right; + if (typeof(TKey) == typeof(Half)) return (Half)(object)left > (Half)(object)right; return left.CompareTo(right) > 0 ? true : false; } } From e4b6a1c1297fbaecd62da4a651f4c4ac178ce0df Mon Sep 17 00:00:00 2001 From: Huo Yaoyuan Date: Thu, 3 Mar 2022 22:57:15 +0800 Subject: [PATCH 5/7] Fix compilation --- .../System.Private.CoreLib/src/System/MulticastDelegate.cs | 1 + .../System.Private.CoreLib/src/System/MulticastDelegate.cs | 1 + .../System.Private.CoreLib/src/System/Reflection/MethodBase.cs | 1 + 3 files changed, 3 insertions(+) diff --git a/src/coreclr/System.Private.CoreLib/src/System/MulticastDelegate.cs b/src/coreclr/System.Private.CoreLib/src/System/MulticastDelegate.cs index 8d728a6b48fb1..5ede5c5d926bc 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/MulticastDelegate.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/MulticastDelegate.cs @@ -4,6 +4,7 @@ using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Reflection; +using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Serialization; diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/MulticastDelegate.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/MulticastDelegate.cs index 5afcf6ddd4bf9..8cdb8889e5b91 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/MulticastDelegate.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/MulticastDelegate.cs @@ -5,6 +5,7 @@ using System.Diagnostics.CodeAnalysis; using System.Reflection; using System.Runtime; +using System.Runtime.CompilerServices; using System.Runtime.Serialization; using Internal.Runtime.CompilerServices; diff --git a/src/libraries/System.Private.CoreLib/src/System/Reflection/MethodBase.cs b/src/libraries/System.Private.CoreLib/src/System/Reflection/MethodBase.cs index 1d02221b0d521..84f96e766d58d 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Reflection/MethodBase.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Reflection/MethodBase.cs @@ -4,6 +4,7 @@ using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Globalization; +using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Text; From db8b7d5dcd4ae0f228b5c85a82925027def62bd1 Mon Sep 17 00:00:00 2001 From: Huo Yaoyuan Date: Fri, 4 Mar 2022 01:51:04 +0800 Subject: [PATCH 6/7] Add back aggressiveinline --- .../System.Private.CoreLib/src/System/MulticastDelegate.cs | 2 ++ .../System.Private.CoreLib/src/System/MulticastDelegate.cs | 2 ++ src/libraries/System.Private.CoreLib/src/System/Delegate.cs | 3 +++ .../src/System/Globalization/SortVersion.cs | 1 + .../System.Private.CoreLib/src/System/Reflection/Assembly.cs | 2 ++ .../src/System/Reflection/ConstructorInfo.cs | 2 ++ .../System.Private.CoreLib/src/System/Reflection/EventInfo.cs | 2 ++ .../System.Private.CoreLib/src/System/Reflection/FieldInfo.cs | 2 ++ .../System.Private.CoreLib/src/System/Reflection/MemberInfo.cs | 2 ++ .../System.Private.CoreLib/src/System/Reflection/MethodBase.cs | 1 + .../System.Private.CoreLib/src/System/Reflection/MethodInfo.cs | 2 ++ .../System.Private.CoreLib/src/System/Reflection/Module.cs | 2 ++ .../src/System/Reflection/PropertyInfo.cs | 2 ++ src/libraries/System.Private.CoreLib/src/System/Version.cs | 1 + 14 files changed, 26 insertions(+) diff --git a/src/coreclr/System.Private.CoreLib/src/System/MulticastDelegate.cs b/src/coreclr/System.Private.CoreLib/src/System/MulticastDelegate.cs index 5ede5c5d926bc..361844b391562 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/MulticastDelegate.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/MulticastDelegate.cs @@ -428,6 +428,7 @@ public sealed override Delegate[] GetInvocationList() return del; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool operator ==(MulticastDelegate? d1, MulticastDelegate? d2) { // Test d2 first to allow branch elimination when inlined for null checks (== null) @@ -440,6 +441,7 @@ public sealed override Delegate[] GetInvocationList() return ReferenceEquals(d2, d1) ? true : d2.Equals((object?)d1); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool operator !=(MulticastDelegate? d1, MulticastDelegate? d2) { // Can't call the == operator as it will call object== diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/MulticastDelegate.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/MulticastDelegate.cs index 8cdb8889e5b91..e70515b0d53da 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/MulticastDelegate.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/MulticastDelegate.cs @@ -109,6 +109,7 @@ public override sealed int GetHashCode() } } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool operator ==(MulticastDelegate? d1, MulticastDelegate? d2) { // Test d2 first to allow branch elimination when inlined for null checks (== null) @@ -121,6 +122,7 @@ public override sealed int GetHashCode() return ReferenceEquals(d2, d1) ? true : d2.Equals((object?)d1); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool operator !=(MulticastDelegate? d1, MulticastDelegate? d2) { // Can't call the == operator as it will call object== diff --git a/src/libraries/System.Private.CoreLib/src/System/Delegate.cs b/src/libraries/System.Private.CoreLib/src/System/Delegate.cs index bd26237daeda6..b9cb7624fc6d2 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Delegate.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Delegate.cs @@ -3,6 +3,7 @@ using System.Diagnostics.CodeAnalysis; using System.Reflection; +using System.Runtime.CompilerServices; using System.Runtime.Serialization; namespace System @@ -92,6 +93,7 @@ public abstract partial class Delegate : ICloneable, ISerializable return newDelegate; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool operator ==(Delegate? d1, Delegate? d2) { // Test d2 first to allow branch elimination when inlined for null checks (== null) @@ -104,6 +106,7 @@ public abstract partial class Delegate : ICloneable, ISerializable return ReferenceEquals(d2, d1) ? true : d2.Equals((object?)d1); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool operator !=(Delegate? d1, Delegate? d2) { // Test d2 first to allow branch elimination when inlined for not null checks (!= null) diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/SortVersion.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/SortVersion.cs index 9231bb79f2dee..4b2cbae329bec 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/SortVersion.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/SortVersion.cs @@ -59,6 +59,7 @@ public override int GetHashCode() return m_NlsVersion * 7 | m_SortId.GetHashCode(); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool operator ==(SortVersion? left, SortVersion? right) { // Test "right" first to allow branch elimination when inlined for null checks (== null) diff --git a/src/libraries/System.Private.CoreLib/src/System/Reflection/Assembly.cs b/src/libraries/System.Private.CoreLib/src/System/Reflection/Assembly.cs index 84696befb2913..59bb4d1a8862e 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Reflection/Assembly.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Reflection/Assembly.cs @@ -9,6 +9,7 @@ using System.Runtime.Serialization; using System.Security; using System.Runtime.Loader; +using System.Runtime.CompilerServices; namespace System.Reflection { @@ -178,6 +179,7 @@ public override string ToString() public override bool Equals(object? o) => base.Equals(o); public override int GetHashCode() => base.GetHashCode(); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool operator ==(Assembly? left, Assembly? right) { // Test "right" first to allow branch elimination when inlined for null checks (== null) diff --git a/src/libraries/System.Private.CoreLib/src/System/Reflection/ConstructorInfo.cs b/src/libraries/System.Private.CoreLib/src/System/Reflection/ConstructorInfo.cs index 8f3647251ed62..c4619fdead121 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Reflection/ConstructorInfo.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Reflection/ConstructorInfo.cs @@ -3,6 +3,7 @@ using System.Diagnostics; using System.Globalization; +using System.Runtime.CompilerServices; namespace System.Reflection { @@ -20,6 +21,7 @@ protected ConstructorInfo() { } public override bool Equals(object? obj) => base.Equals(obj); public override int GetHashCode() => base.GetHashCode(); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool operator ==(ConstructorInfo? left, ConstructorInfo? right) { // Test "right" first to allow branch elimination when inlined for null checks (== null) diff --git a/src/libraries/System.Private.CoreLib/src/System/Reflection/EventInfo.cs b/src/libraries/System.Private.CoreLib/src/System/Reflection/EventInfo.cs index a453dad6f0f3a..07e1f5bd15c07 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Reflection/EventInfo.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Reflection/EventInfo.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Diagnostics; +using System.Runtime.CompilerServices; namespace System.Reflection { @@ -83,6 +84,7 @@ public virtual void RemoveEventHandler(object? target, Delegate? handler) public override bool Equals(object? obj) => base.Equals(obj); public override int GetHashCode() => base.GetHashCode(); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool operator ==(EventInfo? left, EventInfo? right) { // Test "right" first to allow branch elimination when inlined for null checks (== null) diff --git a/src/libraries/System.Private.CoreLib/src/System/Reflection/FieldInfo.cs b/src/libraries/System.Private.CoreLib/src/System/Reflection/FieldInfo.cs index 08c05569af56f..a2090f56d483a 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Reflection/FieldInfo.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Reflection/FieldInfo.cs @@ -3,6 +3,7 @@ using System.Diagnostics; using System.Globalization; +using System.Runtime.CompilerServices; namespace System.Reflection { @@ -38,6 +39,7 @@ protected FieldInfo() { } public override bool Equals(object? obj) => base.Equals(obj); public override int GetHashCode() => base.GetHashCode(); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool operator ==(FieldInfo? left, FieldInfo? right) { // Test "right" first to allow branch elimination when inlined for null checks (== null) diff --git a/src/libraries/System.Private.CoreLib/src/System/Reflection/MemberInfo.cs b/src/libraries/System.Private.CoreLib/src/System/Reflection/MemberInfo.cs index c7a9391bcaf0d..89cc304a0ef42 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Reflection/MemberInfo.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Reflection/MemberInfo.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Collections.Generic; +using System.Runtime.CompilerServices; namespace System.Reflection { @@ -42,6 +43,7 @@ public virtual Module Module public override bool Equals(object? obj) => base.Equals(obj); public override int GetHashCode() => base.GetHashCode(); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool operator ==(MemberInfo? left, MemberInfo? right) { // Test "right" first to allow branch elimination when inlined for null checks (== null) diff --git a/src/libraries/System.Private.CoreLib/src/System/Reflection/MethodBase.cs b/src/libraries/System.Private.CoreLib/src/System/Reflection/MethodBase.cs index 84f96e766d58d..d8b78883150b7 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Reflection/MethodBase.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Reflection/MethodBase.cs @@ -63,6 +63,7 @@ this is ConstructorInfo && public override bool Equals(object? obj) => base.Equals(obj); public override int GetHashCode() => base.GetHashCode(); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool operator ==(MethodBase? left, MethodBase? right) { // Test "right" first to allow branch elimination when inlined for null checks (== null) diff --git a/src/libraries/System.Private.CoreLib/src/System/Reflection/MethodInfo.cs b/src/libraries/System.Private.CoreLib/src/System/Reflection/MethodInfo.cs index 4b1dd57b8696e..5e8afa6d70e30 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Reflection/MethodInfo.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Reflection/MethodInfo.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Diagnostics.CodeAnalysis; +using System.Runtime.CompilerServices; namespace System.Reflection { @@ -37,6 +38,7 @@ protected MethodInfo() { } public override bool Equals(object? obj) => base.Equals(obj); public override int GetHashCode() => base.GetHashCode(); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool operator ==(MethodInfo? left, MethodInfo? right) { // Test "right" first to allow branch elimination when inlined for null checks (== null) diff --git a/src/libraries/System.Private.CoreLib/src/System/Reflection/Module.cs b/src/libraries/System.Private.CoreLib/src/System/Reflection/Module.cs index 6a15d9d67c8d2..5ff7b76335d80 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Reflection/Module.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Reflection/Module.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; +using System.Runtime.CompilerServices; using System.Runtime.Serialization; namespace System.Reflection @@ -136,6 +137,7 @@ public virtual Type[] FindTypes(TypeFilter? filter, object? filterCriteria) public override bool Equals(object? o) => base.Equals(o); public override int GetHashCode() => base.GetHashCode(); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool operator ==(Module? left, Module? right) { // Test "right" first to allow branch elimination when inlined for null checks (== null) diff --git a/src/libraries/System.Private.CoreLib/src/System/Reflection/PropertyInfo.cs b/src/libraries/System.Private.CoreLib/src/System/Reflection/PropertyInfo.cs index e389fd866e70a..89f398f1f9172 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Reflection/PropertyInfo.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Reflection/PropertyInfo.cs @@ -3,6 +3,7 @@ using System.Diagnostics; using System.Globalization; +using System.Runtime.CompilerServices; namespace System.Reflection { @@ -57,6 +58,7 @@ protected PropertyInfo() { } public override bool Equals(object? obj) => base.Equals(obj); public override int GetHashCode() => base.GetHashCode(); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool operator ==(PropertyInfo? left, PropertyInfo? right) { // Test "right" first to allow branch elimination when inlined for null checks (== null) diff --git a/src/libraries/System.Private.CoreLib/src/System/Version.cs b/src/libraries/System.Private.CoreLib/src/System/Version.cs index 8672d284fefa3..431c0a1e81cd3 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Version.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Version.cs @@ -369,6 +369,7 @@ private static bool TryParseComponent(ReadOnlySpan component, string compo return int.TryParse(component, NumberStyles.Integer, CultureInfo.InvariantCulture, out parsedComponent) && parsedComponent >= 0; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool operator ==(Version? v1, Version? v2) { // Test "right" first to allow branch elimination when inlined for null checks (== null) From 364b7add7506846f8691a57927780bfd70553677 Mon Sep 17 00:00:00 2001 From: Huo Yaoyuan Date: Thu, 31 Mar 2022 00:56:26 +0800 Subject: [PATCH 7/7] Remove outdated comment --- .../System.Private.CoreLib/src/System/MulticastDelegate.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/coreclr/System.Private.CoreLib/src/System/MulticastDelegate.cs b/src/coreclr/System.Private.CoreLib/src/System/MulticastDelegate.cs index 361844b391562..02c57d247eaa8 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/MulticastDelegate.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/MulticastDelegate.cs @@ -450,7 +450,6 @@ public sealed override Delegate[] GetInvocationList() // so it can become a simple test if (d2 is null) { - // return true/false not the test result https://github.com/dotnet/runtime/issues/4207 return d1 is not null; }