runtime
runtime copied to clipboard
Do not check object references for equality after hot reload
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 https://github.com/dotnet/runtime/issues/69427
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 https://github.com/dotnet/runtime/issues/69427
| Author: | buyaa-n |
|---|---|
| Assignees: | - |
| Labels: |
|
| Milestone: | - |
CI test failures on Microsoft.CSharp.RuntimeBinder.Tests, System.Dynamic.Runtime.Tests, System.Composition.Convention.Tests etc could be related, I can repro locally and seems not reproduceable in other branch, looking
Comparing RuntimeMethodInfo handles for equality causing the CI test failures in above projects, reverted that
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
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)
Looking at the test failures - the reflected type needs to be also included in Equals method.
@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.
@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
Looks good to me, modulo the last two comments
Failures unrelated and known issue, merging