Skip to content
This repository has been archived by the owner on Nov 1, 2020. It is now read-only.

Commit

Permalink
Function pointer equality comparison was not handling cross-module po…
Browse files Browse the repository at this point in the history
…inters correctly when optimizations were enabled (causes target pointers to be wrapped in jump stubs sometimes). The delegate equality comparison was hitting this bug.

The DynamicGenerics test was failing in one of its delegate tests when the delegate's construction method from the shared library got inlined in the test code:
         1) One delegate was created by new'ing up a Func<> delegate (ends up creating a delegate where the delegate's thunk pointer is a jump stub to the thunk code)
         2) Another delegate was created by calling MethodInfo.CreateDelegate (ends up creating a delegate where the delegate's thunk pointer is the thunk code directly)
         3) The test was comparing the 2 delegates for equality. MulticastDelegate.Equals returned false because of the difference in the thunk pointers, even though they really point at the same target code.

[tfs-changeset: 1572883]
  • Loading branch information
Fadi Hanna committed Feb 5, 2016
1 parent 2182827 commit 08d78ae
Show file tree
Hide file tree
Showing 2 changed files with 8 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using Internal.Runtime.Augments;

namespace Internal.Runtime.CompilerServices
{
Expand Down Expand Up @@ -140,7 +141,9 @@ public static unsafe bool Compare(IntPtr functionPointerA, IntPtr functionPointe
{
if (!IsGenericMethodPointer(functionPointerA))
{
return functionPointerA == functionPointerB;
IntPtr codeTargetA = RuntimeAugments.GetCodeTarget(functionPointerA);
IntPtr codeTargetB = RuntimeAugments.GetCodeTarget(functionPointerB);
return codeTargetA == codeTargetB;
}
else
{
Expand All @@ -153,7 +156,9 @@ public static unsafe bool Compare(IntPtr functionPointerA, IntPtr functionPointe
if (pointerDefA->InstantiationArgument != pointerDefB->InstantiationArgument)
return false;

return pointerDefA->MethodFunctionPointer == pointerDefB->MethodFunctionPointer;
IntPtr codeTargetA = RuntimeAugments.GetCodeTarget(pointerDefA->MethodFunctionPointer);
IntPtr codeTargetB = RuntimeAugments.GetCodeTarget(pointerDefB->MethodFunctionPointer);
return codeTargetA == codeTargetB;
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/System.Private.CoreLib/src/System/MulticastDelegate.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ public override sealed bool Equals(Object obj)
{
if (!Object.ReferenceEquals(m_helperObject, d.m_helperObject) ||
(!FunctionPointerOps.Compare(m_extraFunctionPointerOrData, d.m_extraFunctionPointerOrData)) ||
(m_functionPointer != d.m_functionPointer))
(!FunctionPointerOps.Compare(m_functionPointer, d.m_functionPointer)))
{
return false;
}
Expand Down

0 comments on commit 08d78ae

Please sign in to comment.