diff options
author | Jan Vorlicek <janvorli@microsoft.com> | 2016-03-18 15:46:20 +0100 |
---|---|---|
committer | Jan Vorlicek <janvorli@microsoft.com> | 2016-03-18 19:50:25 +0100 |
commit | fde6f26b140c5fcfa9a01267565686efcfff361f (patch) | |
tree | 40d73f4793554f5df528287c880f987e67544acb /src/vm/prestub.cpp | |
parent | 586ce538403c1b859f73d97abec9bb4bfad4cab7 (diff) | |
download | coreclr-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.cpp | 8 |
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, |