Skip to content

Commit

Permalink
Do not use RhGetCodeTarget in delegate equality (#88611)
Browse files Browse the repository at this point in the history
dotnet/corert@08d78ae

The original motivation for this was handling import stubs:
```
Function pointer equality comparison was not handling cross-module pointers correctly when optimizations were enabled
(causes target pointers to be wrapped in jump stubs sometimes). The delegate equality comparison was hitting this bug.
```
We do not have import stubs anymore and unwrapping unboxing stubs serves no purpose here.

Microbenchmarks of delegate equality show ~3x improvement with this change:
```
Bench_DelegateEquality_Positive_OpenStatic<10000000>() took: 355 ms
Bench_DelegateEquality_Positive_ClosedStatic<10000000>() took: 367 ms
Bench_DelegateEquality_Positive_ClosedInstance<10000000>() took: 371 ms

Bench_DelegateEquality_Positive_OpenStatic<10000000>() took: 121 ms
Bench_DelegateEquality_Positive_ClosedStatic<10000000>() took: 120 ms
Bench_DelegateEquality_Positive_ClosedInstance<10000000>() took: 122 ms
```

Additionally, there is some desire to upstream changes for a portable RhGetCodeTarget implementation. Not having to
deal with it at this relatively low-level layer will make things more robust.
  • Loading branch information
SingleAccretion authored Jul 12, 2023
1 parent d3d910e commit 6969e7e
Showing 1 changed file with 12 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -130,25 +130,23 @@ public static unsafe bool Compare(IntPtr functionPointerA, IntPtr functionPointe
{
if (!IsGenericMethodPointer(functionPointerA))
{
IntPtr codeTargetA = RuntimeAugments.GetCodeTarget(functionPointerA);
IntPtr codeTargetB = RuntimeAugments.GetCodeTarget(functionPointerB);
return codeTargetA == codeTargetB;
return functionPointerA == functionPointerB;
}
else

if (!IsGenericMethodPointer(functionPointerB))
{
if (!IsGenericMethodPointer(functionPointerB))
return false;
return false;
}

GenericMethodDescriptor* pointerDefA = ConvertToGenericDescriptor(functionPointerA);
GenericMethodDescriptor* pointerDefB = ConvertToGenericDescriptor(functionPointerB);
GenericMethodDescriptor* pointerDefA = ConvertToGenericDescriptor(functionPointerA);
GenericMethodDescriptor* pointerDefB = ConvertToGenericDescriptor(functionPointerB);

if (pointerDefA->InstantiationArgument != pointerDefB->InstantiationArgument)
return false;

IntPtr codeTargetA = RuntimeAugments.GetCodeTarget(pointerDefA->MethodFunctionPointer);
IntPtr codeTargetB = RuntimeAugments.GetCodeTarget(pointerDefB->MethodFunctionPointer);
return codeTargetA == codeTargetB;
if (pointerDefA->InstantiationArgument != pointerDefB->InstantiationArgument)
{
return false;
}

return pointerDefA->MethodFunctionPointer == pointerDefB->MethodFunctionPointer;
}
}
}

0 comments on commit 6969e7e

Please sign in to comment.