Skip to content

Do not check object references for equality after hot reload - #73009

Merged
buyaa-n merged 20 commits into
dotnet:mainfrom
buyaa-n:hot-reload
Aug 8, 2022
Merged

Do not check object references for equality after hot reload#73009
buyaa-n merged 20 commits into
dotnet:mainfrom
buyaa-n:hot-reload

Conversation

@buyaa-n

Copy link
Copy Markdown
Contributor

RuntimeType member's cache is purged after hot reload, therefore same member references are not equal after hotreload which causing issue like mentioned in Hot Reload breaks MethodInfo equality

Updated/added Object.Equals overloads to compare metadata token and module in case hot reload taken place instead of comparing object references.

Fixes#69427

@ghost

Copy link
Copy Markdown

Tagging subscribers to this area: @dotnet/area-system-reflection
See info in area-owners.md if you want to be subscribed.

Issue Details

RuntimeType member's cache is purged after hot reload, therefore same member references are not equal after hotreload which causing issue like mentioned in Hot Reload breaks MethodInfo equality

Updated/added Object.Equals overloads to compare metadata token and module in case hot reload taken place instead of comparing object references.

Fixes #69427

Author:buyaa-n
Assignees:-
Labels:

area-System.Reflection

Milestone:-

Comment threadsrc/coreclr/System.Private.CoreLib/src/System/Reflection/MdFieldInfo.cs Outdated
@ghostghost added the needs-author-action An issue or pull request that requires more info or actions from the author. label Aug 4, 2022
@buyaa-n

buyaa-n commented Aug 4, 2022

Copy link
Copy Markdown
ContributorAuthor

Do you understand why? Have you been able to create a small standalone repro using just the reflection APIs?

No, I could not understood why, a typical failure log looks like this:

Dynamic.Operator.Tests.PlusEqualTypeTests.Byte [FAIL]
System.ArgumentException : ParameterExpression of type 'System.String' cannot be used for delegate parameter of type 'System.Object'
Stack Trace:
D:\dotnet\pr2\src\libraries\System.Linq.Expressions\src\System\Linq\Expressions\LambdaExpression.cs(954,0): at System.Linq.Expressions.Expression.ValidateLambdaArgs(Type delegateType, Expres
sion& body, ReadOnlyCollection`1 parameters, String paramName)
D:\dotnet\pr2\src\libraries\System.Linq.Expressions\src\System\Linq\Expressions\LambdaExpression.cs(717,0): at System.Linq.Expressions.Expression.Lambda[TDelegate](Expression body, String na
me, Boolean tailCall, IEnumerable`1 parameters)
D:\dotnet\pr2\src\libraries\System.Linq.Expressions\src\System\Runtime\CompilerServices\CallSiteBinder.cs(192,0): at System.Runtime.CompilerServices.CallSiteBinder.Stitch[T](Expression bindi
ng, LambdaSignature`1 signature)
D:\dotnet\pr2\src\libraries\System.Linq.Expressions\src\System\Runtime\CompilerServices\CallSiteBinder.cs(132,0): at System.Runtime.CompilerServices.CallSiteBinder.BindCore[T](CallSite`1 sit
e, Object[] args)
D:\dotnet\pr2\src\libraries\System.Linq.Expressions\src\System\Dynamic\UpdateDelegates.Generated.cs(157,0): at System.Dynamic.UpdateDelegates.UpdateAndExecute2[T0,T1,TRet](CallSite site, T0
arg0, T1 arg1)
D:\dotnet\pr2\src\libraries\System.Dynamic.Runtime\tests\Dynamic.Context\Conformance.dynamic.context.operator.compound.type.PlusEqual.cs(76,0): at Dynamic.Operator.Tests.PlusEqualTypeTests.B
yte()
at System.RuntimeMethodHandle.InvokeMethod(Object target, Void** arguments, Signature sig, Boolean isConstructor)
D:\dotnet\pr2\src\libraries\System.Private.CoreLib\src\System\Reflection\MethodInvoker.cs(69,0): at System.Reflection.MethodInvoker.Invoke(Object obj, IntPtr* args, BindingFlags invokeAttr)

just know reverting back the Equals logic fixes those failures, will dig more

@ghostghost removed the needs-author-action An issue or pull request that requires more info or actions from the author. label Aug 4, 2022
@buyaa-n

Copy link
Copy Markdown
ContributorAuthor

Another log

System.Text.Tests.EncodingTests.GetEncoding_FromProvider_ByCodePage_WithDisallowedEncoding_Throws(encodingName: "utf-7", codePage: 65000) [FAIL]
System.ArgumentException : ParameterExpression of type 'System.Text.EncodingProvider' cannot be used for delegate parameter of type 'System.Reflection.Binder'
Stack Trace:
D:\dotnet\pr2\src\libraries\System.Linq.Expressions\src\System\Linq\Expressions\LambdaExpression.cs(954,0): at System.Linq.Expressions.Expression.ValidateLambdaArgs(Type delegateType, Expres
sion& body, ReadOnlyCollection`1 parameters, String paramName)
D:\dotnet\pr2\src\libraries\System.Linq.Expressions\src\System\Linq\Expressions\LambdaExpression.cs(717,0): at System.Linq.Expressions.Expression.Lambda[TDelegate](Expression body, String na
me, Boolean tailCall, IEnumerable`1 parameters)
D:\dotnet\pr2\src\libraries\System.Linq.Expressions\src\System\Linq\Expressions\LambdaExpression.cs(689,0): at System.Linq.Expressions.Expression.Lambda[TDelegate](Expression body, Boolean t
ailCall, IEnumerable`1 parameters)
D:\dotnet\pr2\src\libraries\System.Linq.Expressions\src\System\Linq\Expressions\LambdaExpression.cs(651,0): at System.Linq.Expressions.Expression.Lambda[TDelegate](Expression body, Parameter
Expression[] parameters)
D:\dotnet\pr2\src\libraries\System.Runtime\tests\System\Text\EncodingTests.cs(43,0): at System.Text.Tests.EncodingTests.GetEncoding_FromProvider_ByCodePage_WithDisallowedEncoding_Throws(Stri
ng encodingName, Int32 codePage)
at System.RuntimeMethodHandle.InvokeMethod(Object target, Void** arguments, Signature sig, Boolean isConstructor)
D:\dotnet\pr2\src\libraries\System.Private.CoreLib\src\System\Reflection\MethodInvoker.cs(64,0): at System.Reflection.MethodInvoker.Invoke(Object obj, IntPtr* args, BindingFlags invokeAttr)
System.ArgumentException : ParameterExpression of type 'System.Text.EncodingProvider' cannot be used for delegate parameter of type 'System.Reflection.Binder'
Stack Trace:
D:\dotnet\pr2\src\libraries\System.Linq.Expressions\src\System\Linq\Expressions\LambdaExpression.cs(954,0): at System.Linq.Expressions.Expression.ValidateLambdaArgs(Type delegateType, Expres
sion& body, ReadOnlyCollection`1 parameters, String paramName)
D:\dotnet\pr2\src\libraries\System.Linq.Expressions\src\System\Linq\Expressions\LambdaExpression.cs(717,0): at System.Linq.Expressions.Expression.Lambda[TDelegate](Expression body, String na
me, Boolean tailCall, IEnumerable`1 parameters)
System.Text.Tests.EncodingTests.GetEncoding_FromProvider_ByEncodingName_WithDisallowedEncoding_Throws(encodingName: "utf-7", codePage: 65000) [FAIL]
D:\dotnet\pr2\src\libraries\System.Linq.Expressions\src\System\Linq\Expressions\LambdaExpression.cs(689,0): at System.Linq.Expressions.Expression.Lambda[TDelegate](Expression body, Boolean t
ailCall, IEnumerable`1 parameters)
D:\dotnet\pr2\src\libraries\System.Linq.Expressions\src\System\Linq\Expressions\LambdaExpression.cs(651,0): at System.Linq.Expressions.Expression.Lambda[TDelegate](Expression body, Parameter
Expression[] parameters)
D:\dotnet\pr2\src\libraries\System.Runtime\tests\System\Text\EncodingTests.cs(71,0): at System.Text.Tests.EncodingTests.GetEncoding_FromProvider_ByEncodingName_WithDisallowedEncoding_Throws(
String encodingName, Int32 codePage)
at System.RuntimeMethodHandle.InvokeMethod(Object target, Void** arguments, Signature sig, Boolean isConstructor)
D:\dotnet\pr2\src\libraries\System.Private.CoreLib\src\System\Reflection\MethodInvoker.cs(64,0): at System.Reflection.MethodInvoker.Invoke(Object obj, IntPtr* args, BindingFlags invokeAttr)

@jkotas

Copy link
Copy Markdown
Member

Looking at the test failures - the reflected type needs to be also included in Equals method.

buyaa-nand others added 2 commits August 5, 2022 17:54
- No need to use GetHashCodeOfPtr when we are wrapping the hashcode using HashCode.Combine that takes care of the randomization
- Use underlying type handle for type hashcodes. It is faster than the default object hashcode.
- Delete special casing for MetadataUpdater.IsSupported from RuntimeMethodInfo.GetHashCode. It is actually a de-optimization for RuntimeMethodInfo with the two changes above, and about neutral for the rest.
- Avoid virtual call for ReflectedType comparison
- Restore comment for RuntimeMethodInfo
@jkotas

jkotas commented Aug 6, 2022

Copy link
Copy Markdown
Member

@buyaa-n I have pushed a commit with a bunch of perf tweaks and simplifications. The commit description has the details. Let me know if it looks good to you or if you have any questions.

Co-authored-by: Jan Kotas <jkotas@microsoft.com>
@buyaa-n

Copy link
Copy Markdown
ContributorAuthor

@buyaa-n I have pushed a commit with a bunch of perf tweaks and simplifications. The commit description has the details. Let me know if it looks good to you or if you have any questions.

Thanks for the description, makes sense to me

@jkotas

Copy link
Copy Markdown
Member

Looks good to me, modulo the last two comments

@buyaa-n

Copy link
Copy Markdown
ContributorAuthor

Failures unrelated and known issue, merging

@buyaa-n
buyaa-n merged commit 7e0f0b7 into dotnet:mainAug 8, 2022
@buyaa-n
buyaa-n deleted the hot-reload branch August 8, 2022 17:57
@ghostghost locked as resolved and limited conversation to collaborators Sep 7, 2022
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Hot Reload breaks MethodInfo equality

7 participants

@buyaa-n@jkotas@sbomer@IDisposable@stephentoub@steveharter@AaronRobinsonMSFT