summaryrefslogtreecommitdiff
path: root/src/vm/genericdict.cpp
diff options
context:
space:
mode:
authorJohnChen0 <jochen@microsoft.com>2016-05-26 15:07:00 -0700
committerJohn Chen <jochen@microsoft.com>2016-05-26 22:28:27 -0700
commit4fd217d564b743f995426de7bd642166e0a84849 (patch)
tree4fbd1d4b3022b4795c5eabb0d454d3cc8448c72f /src/vm/genericdict.cpp
parent02eada1015063befd713e1bd60685f3a8bb38184 (diff)
downloadcoreclr-4fd217d564b743f995426de7bd642166e0a84849.tar.gz
coreclr-4fd217d564b743f995426de7bd642166e0a84849.tar.bz2
coreclr-4fd217d564b743f995426de7bd642166e0a84849.zip
Fix generic non-virtual method call in Ready-to-Run images
Issue #5201 revealed a bug in the Ready-to-Run implementation. This bug can cause the runtime to dispatch a method call to the wrong target when all the following conditions are met: * A shared generic method in a Ready-to-Run module calls a method in a shared generic class. * The target is a non-virtual instance method, but is called through callvirt instruction (as C# compiler normally does). * The target is in a different module. * The target method is defined in a base class, while the actual object instance is of a derived class. This commit fixes this bug by changing a virtual call to a regular call when the target is non-virtual.
Diffstat (limited to 'src/vm/genericdict.cpp')
-rw-r--r--src/vm/genericdict.cpp8
1 files changed, 8 insertions, 0 deletions
diff --git a/src/vm/genericdict.cpp b/src/vm/genericdict.cpp
index 87eef8749c..04e2550e1e 100644
--- a/src/vm/genericdict.cpp
+++ b/src/vm/genericdict.cpp
@@ -880,6 +880,14 @@ Dictionary::PopulateEntry(
result = (CORINFO_GENERIC_HANDLE)pMethod->GetMultiCallableAddrOfCode();
}
else
+ if (kind == DispatchStubAddrSlot)
+ {
+ _ASSERTE((methodFlags & ENCODE_METHOD_SIG_SlotInsteadOfToken) == 0);
+ PCODE *ppCode = (PCODE*)(void*)pMethod->GetLoaderAllocator()->GetHighFrequencyHeap()->AllocMem(S_SIZE_T(sizeof(PCODE)));
+ *ppCode = pMethod->GetMultiCallableAddrOfCode();
+ result = (CORINFO_GENERIC_HANDLE)ppCode;
+ }
+ else
{
_ASSERTE(kind == MethodDescSlot);
result = (CORINFO_GENERIC_HANDLE)pMethod;