summaryrefslogtreecommitdiff
path: root/src/vm/prestub.cpp
diff options
context:
space:
mode:
authorJan Vorlicek <janvorli@microsoft.com>2016-03-18 15:46:20 +0100
committerJan Vorlicek <janvorli@microsoft.com>2016-03-18 19:50:25 +0100
commitfde6f26b140c5fcfa9a01267565686efcfff361f (patch)
tree40d73f4793554f5df528287c880f987e67544acb /src/vm/prestub.cpp
parent586ce538403c1b859f73d97abec9bb4bfad4cab7 (diff)
downloadcoreclr-fde6f26b140c5fcfa9a01267565686efcfff361f.tar.gz
coreclr-fde6f26b140c5fcfa9a01267565686efcfff361f.tar.bz2
coreclr-fde6f26b140c5fcfa9a01267565686efcfff361f.zip
Fix instantiating stub for methods of value types
This change fixes a problem with instantiating stubs for methods of value types. The problem was that the CreateInstantiatingILStub didn't take into account the fact that methods of value types need to have "this" passed "byref". The issue manifested itself as a rare corruption of references in array of structs that were thin wrappers for string reference during GC stack scan. GC thought that the reference to an array entry is an object reference that starts with method table. GC marks method table pointers by setting their bit zero to 1. But in this case, it has accidentally modified an object reference instead and a test was crashing with wrong object address. The root cause of the problem is that the instantiating stubs were placed on a global singleton reference class no matter whether the target method was on a reference class or a value type. I have fixed it by putting the stubs on the instantiated target generic type instead.
Diffstat (limited to 'src/vm/prestub.cpp')
-rw-r--r--src/vm/prestub.cpp8
1 files changed, 6 insertions, 2 deletions
diff --git a/src/vm/prestub.cpp b/src/vm/prestub.cpp
index 2bedb83571..aeb9c3063a 100644
--- a/src/vm/prestub.cpp
+++ b/src/vm/prestub.cpp
@@ -780,15 +780,19 @@ Stub * CreateInstantiatingILStub(MethodDesc* pTargetMD, void* pHiddenArg)
CONTRACT_END;
SigTypeContext typeContext;
+ MethodTable* pStubMT;
if (pTargetMD->HasMethodInstantiation())
{
// The pHiddenArg shall be a MethodDesc*
- SigTypeContext::InitTypeContext(static_cast<MethodDesc *>(pHiddenArg), &typeContext);
+ MethodDesc* pMD = static_cast<MethodDesc *>(pHiddenArg);
+ SigTypeContext::InitTypeContext(pMD, &typeContext);
+ pStubMT = pMD->GetMethodTable();
}
else
{
// The pHiddenArg shall be a MethodTable*
SigTypeContext::InitTypeContext(TypeHandle::FromPtr(pHiddenArg), &typeContext);
+ pStubMT = static_cast<MethodTable *>(pHiddenArg);
}
MetaSig msig(pTargetMD);
@@ -837,7 +841,7 @@ Stub * CreateInstantiatingILStub(MethodDesc* pTargetMD, void* pHiddenArg)
pTargetMD->GetSig(&pSig,&cbSig);
PTR_Module pLoaderModule = pTargetMD->GetLoaderModule();
MethodDesc * pStubMD = ILStubCache::CreateAndLinkNewILStubMethodDesc(pTargetMD->GetLoaderAllocator(),
- pLoaderModule->GetILStubCache()->GetOrCreateStubMethodTable(pLoaderModule),
+ pStubMT,
ILSTUB_INSTANTIATINGSTUB,
pTargetMD->GetModule(),
pSig, cbSig,