Uh oh!
There was an error while loading. Please reload this page.
Fix ValueType.GetHashCode not calling overriden method on nested field - #98754
Conversation
Uh oh!
There was an error while loading. Please reload this page.
| { | ||
| hashCode = fieldValue.GetHashCodeImpl(); | ||
| // call virtual method to handle overriden case | ||
| hashCode = fieldValue.GetHashCode(); |
There was a problem hiding this comment.
I think GetHashCodeImpl can now be inlined into GetHashCode.
The only reason we had GetHashCodeImpl was because it was emulating CoreCLR behavior that did not call the GetHashCode on the field type (even if it had one) but instead used the fallback algorithm.
There was a problem hiding this comment.
Is it feasible to use System.HashCode for NativeAOT here? Will it bring unintended dependency or complexity?
There was a problem hiding this comment.
I think it would be fine to use System.HashCode. This was mirroring the CoreCLR-JIT logic but now it diverged because that's how forks usually end up.
If we really wanted to, we could probably unify this to the point of sharing a part of this file, maybe with an ifdef or two. From a quick look GetHashCodeStrategy could be implemented using NativeAOT's __GetFieldHelper.
Uh oh!
There was an error while loading. Please reload this page.
| { | ||
| int hashCode = (int)this.GetMethodTable()->HashCode; | ||
| HashCode hashCode = default; | ||
| hashCode.Add(this.GetMethodTable()->HashCode); |
There was a problem hiding this comment.
| hashCode.Add(this.GetMethodTable()->HashCode); | |
| hashCode.Add((IntPtr)this.GetMethodTable()); |
to match CoreCLR
| else if (fieldType->IsPrimitive) | ||
| { | ||
| hashCode = FastGetValueTypeHashCodeHelper(fieldType, ref fieldData); | ||
| HashCode hash = default; |
There was a problem hiding this comment.
The method should take ref HashCode argument instead of creating a new instance here.
There was a problem hiding this comment.
I meant change RegularGetValueTypeHashCode to take ref HashCode argument and delete HashCode hash = default; that this comment is attached to.
huoyaoyuan
commented
Feb 25, 2024
Noticed that the test case doesn't actually cover this case. It should not match the default comparison/hashcode strategy of nested field. Using manual version of int Abs to avoid introducing any dependency. |
jkotas
commented
Feb 25, 2024
What is the test case that you are talking about?
Nit: Dependencies like this are not a problem in the tests. |
| } | ||
| private static unsafe int FastGetValueTypeHashCodeHelper(MethodTable* type, ref byte data) | ||
| private static unsafe void AddHashCodeForField(ref HashCode hashCode, MethodTable* type, ref byte data) |
There was a problem hiding this comment.
This method name is a bit misleading. It cannot be used to add hashcode for any field.
I like the Span returning method that you had here before better.
huoyaoyuan
commented
Feb 26, 2024
Describing the failing case:
The original reproduction uses |
Follow up for #97590 (comment)
This is indeed a bug, since
GetHashCodecan return different result whenEqualsis returningtrue.