diff options
Diffstat (limited to 'packaging/0006-Remove-relocations-from-SECTION_MethodDesc-for-ngene.patch')
-rw-r--r-- | packaging/0006-Remove-relocations-from-SECTION_MethodDesc-for-ngene.patch | 1017 |
1 files changed, 1017 insertions, 0 deletions
diff --git a/packaging/0006-Remove-relocations-from-SECTION_MethodDesc-for-ngene.patch b/packaging/0006-Remove-relocations-from-SECTION_MethodDesc-for-ngene.patch new file mode 100644 index 0000000000..f7511ef78a --- /dev/null +++ b/packaging/0006-Remove-relocations-from-SECTION_MethodDesc-for-ngene.patch @@ -0,0 +1,1017 @@ +From 38dd83da084cd357b9bce97a2a096b55232b57fc Mon Sep 17 00:00:00 2001 +From: gbalykov <g.balykov@samsung.com> +Date: Wed, 31 May 2017 04:25:04 +0300 +Subject: [PATCH 06/32] Remove relocations from SECTION_MethodDesc for ngened + images (#11394) + +--- + src/debug/daccess/nidump.cpp | 51 +++++++++++------------ + src/vm/dllimport.cpp | 4 +- + src/vm/dynamicmethod.cpp | 14 +++---- + src/vm/genmeth.cpp | 4 +- + src/vm/ilstubcache.cpp | 12 +++--- + src/vm/method.cpp | 33 +++++++-------- + src/vm/method.hpp | 94 ++++++++++++++++++++++++++++--------------- + src/vm/methodimpl.cpp | 69 ++++++++++++++++++------------- + src/vm/methodimpl.h | 45 +++++++++++++-------- + src/vm/methodtablebuilder.cpp | 24 +++++------ + src/vm/methodtablebuilder.h | 8 ++-- + 11 files changed, 205 insertions(+), 153 deletions(-) + +diff --git a/src/debug/daccess/nidump.cpp b/src/debug/daccess/nidump.cpp +index 77c05b5..5e8302f 100644 +--- a/src/debug/daccess/nidump.cpp ++++ b/src/debug/daccess/nidump.cpp +@@ -7829,20 +7829,20 @@ void NativeImageDumper::DumpMethodDesc( PTR_MethodDesc md, PTR_Module module ) + MethodImpl, METHODDESCS); + + } +- _ASSERTE(impl->pImplementedMD == NULL +- || isInRange(PTR_TO_TADDR(impl->pImplementedMD))); +- if ((impl->pImplementedMD != NULL) && +- isInRange(PTR_TO_TADDR(impl->pImplementedMD))) ++ _ASSERTE(impl->pImplementedMD.IsNull() ++ || isInRange(PTR_TO_TADDR(impl->GetImpMDsNonNull()))); ++ if (!impl->pImplementedMD.IsNull() && ++ isInRange(PTR_TO_TADDR(impl->GetImpMDsNonNull()))) + { + DisplayWriteFieldAddress( pImplementedMD, +- DataPtrToDisplay(dac_cast<TADDR>(impl->pImplementedMD)), +- numSlots * sizeof(MethodDesc*), ++ DataPtrToDisplay(dac_cast<TADDR>(impl->GetImpMDsNonNull())), ++ numSlots * sizeof(RelativePointer <MethodDesc*>), + MethodImpl, METHODDESCS ); + } + else + { + DisplayWriteFieldPointer( pImplementedMD, +- DataPtrToDisplay(dac_cast<TADDR>(impl->pImplementedMD)), ++ DataPtrToDisplay(dac_cast<TADDR>(impl->GetImpMDs())), + MethodImpl, METHODDESCS ); + } + DisplayEndVStructure( METHODDESCS ); +@@ -7852,19 +7852,19 @@ void NativeImageDumper::DumpMethodDesc( PTR_MethodDesc md, PTR_Module module ) + DisplayStartVStructure( "StoredSigMethodDesc", METHODDESCS ); + PTR_StoredSigMethodDesc ssmd(md); + //display signature information. +- if( isInRange(ssmd->m_pSig) ) ++ if( isInRange(ssmd->GetSigRVA()) ) + { +- DisplayWriteFieldAddress(m_pSig, DataPtrToDisplay(ssmd->m_pSig), ++ DisplayWriteFieldAddress(m_pSig, DataPtrToDisplay(ssmd->GetSigRVA()), + ssmd->m_cSig, StoredSigMethodDesc, + METHODDESCS); + } + else + { +- DisplayWriteFieldPointer(m_pSig, DataPtrToDisplay(ssmd->m_pSig), ++ DisplayWriteFieldPointer(m_pSig, DataPtrToDisplay(ssmd->GetSigRVA()), + StoredSigMethodDesc, METHODDESCS); + + } +- CoverageRead(TO_TADDR(ssmd->m_pSig), ssmd->m_cSig); ++ CoverageRead(TO_TADDR(ssmd->GetSigRVA()), ssmd->m_cSig); + DisplayWriteFieldInt( m_cSig, ssmd->m_cSig, + StoredSigMethodDesc, METHODDESCS ); + #ifdef _WIN64 +@@ -7880,10 +7880,10 @@ void NativeImageDumper::DumpMethodDesc( PTR_MethodDesc md, PTR_Module module ) + { + PTR_DynamicMethodDesc dmd(md); + DisplayStartVStructure( "DynamicMethodDesc", METHODDESCS ); +- WriteFieldStr( m_pszMethodName, PTR_BYTE(dmd->m_pszMethodName), ++ WriteFieldStr( m_pszMethodName, PTR_BYTE(dmd->GetMethodName()), + DynamicMethodDesc, METHODDESCS ); + if( !CHECK_OPT(METHODDESCS) ) +- CoverageReadString( PTR_TO_TADDR(dmd->m_pszMethodName) ); ++ CoverageReadString( PTR_TO_TADDR(dmd->GetMethodName()) ); + DisplayWriteFieldPointer( m_pResolver, + DPtrToPreferredAddr(dmd->m_pResolver), + DynamicMethodDesc, METHODDESCS ); +@@ -7927,10 +7927,10 @@ void NativeImageDumper::DumpMethodDesc( PTR_MethodDesc md, PTR_Module module ) + METHODDESCS ); + + WriteFieldStr( m_pszEntrypointName, +- PTR_BYTE(TO_TADDR(nd->m_pszEntrypointName)), ++ PTR_BYTE(dac_cast<TADDR>(ndmd->GetEntrypointName())), + NDirectMethodDesc::temp1, METHODDESCS ); + if( !CHECK_OPT(METHODDESCS) ) +- CoverageReadString(TO_TADDR(nd->m_pszEntrypointName)); ++ CoverageReadString(dac_cast<TADDR>(ndmd->GetEntrypointName())); + if (md->IsQCall()) + { + DisplayWriteFieldInt( m_dwECallID, +@@ -7941,11 +7941,11 @@ void NativeImageDumper::DumpMethodDesc( PTR_MethodDesc md, PTR_Module module ) + else + { + WriteFieldStr( m_pszLibName, +- PTR_BYTE(TO_TADDR(nd->m_pszLibName)), ++ PTR_BYTE(dac_cast<TADDR>(ndmd->GetLibNameRaw())), + NDirectMethodDesc::temp1, METHODDESCS ); + } + if( !CHECK_OPT(METHODDESCS) ) +- CoverageReadString( TO_TADDR(nd->m_pszLibName) ); ++ CoverageReadString( dac_cast<TADDR>(ndmd->GetLibNameRaw()) ); + + PTR_NDirectWriteableData wnd( nd->m_pWriteableData ); + DisplayStartStructureWithOffset( m_pWriteableData, +@@ -7959,12 +7959,7 @@ void NativeImageDumper::DumpMethodDesc( PTR_MethodDesc md, PTR_Module module ) + CoverageRead( PTR_TO_TADDR(wnd), sizeof(*wnd) ); + DisplayEndStructure( METHODDESCS ); //m_pWriteableData + +- +-#ifdef HAS_NDIRECT_IMPORT_PRECODE +- PTR_NDirectImportThunkGlue glue(nd->m_pImportThunkGlue); +-#else +- PTR_NDirectImportThunkGlue glue(PTR_HOST_MEMBER_TADDR(NDirectMethodDesc::temp1, nd, m_ImportThunkGlue)); +-#endif ++ PTR_NDirectImportThunkGlue glue(ndmd->GetNDirectImportThunkGlue()); + + #ifdef HAS_NDIRECT_IMPORT_PRECODE + if (glue == NULL) +@@ -8065,7 +8060,7 @@ void NativeImageDumper::DumpMethodDesc( PTR_MethodDesc md, PTR_Module module ) + & InstantiatedMethodDesc::KindMask; + if( kind == InstantiatedMethodDesc::SharedMethodInstantiation ) + { +- PTR_DictionaryLayout layout(TO_TADDR(imd->m_pDictLayout)); ++ PTR_DictionaryLayout layout(dac_cast<TADDR>(imd->GetDictLayoutRaw())); + IF_OPT(METHODDESCS) + { + WriteFieldDictionaryLayout( "m_pDictLayout", +@@ -8089,7 +8084,7 @@ void NativeImageDumper::DumpMethodDesc( PTR_MethodDesc md, PTR_Module module ) + else if( kind == + InstantiatedMethodDesc::WrapperStubWithInstantiations ) + { +- PTR_MethodDesc wimd(imd->m_pWrappedMethodDesc.GetValue()); ++ PTR_MethodDesc wimd(imd->IMD_GetWrappedMethodDesc()); + if( wimd == NULL || !DoWriteFieldAsFixup( "m_pWrappedMethodDesc", + offsetof(InstantiatedMethodDesc, m_pWrappedMethodDesc), + fieldsize(InstantiatedMethodDesc, m_pWrappedMethodDesc), +@@ -8101,7 +8096,7 @@ void NativeImageDumper::DumpMethodDesc( PTR_MethodDesc md, PTR_Module module ) + } + else + { +- _ASSERTE(imd->m_pDictLayout == NULL); ++ _ASSERTE(imd->m_pDictLayout.IsNull()); + DisplayWriteFieldPointer( m_pDictLayout, NULL, + InstantiatedMethodDesc, + METHODDESCS ); +@@ -8117,7 +8112,7 @@ void NativeImageDumper::DumpMethodDesc( PTR_MethodDesc md, PTR_Module module ) + else if( kind == InstantiatedMethodDesc::WrapperStubWithInstantiations ) + { + PTR_InstantiatedMethodDesc wrapped = +- PTR_InstantiatedMethodDesc(imd->m_pWrappedMethodDesc.GetValue()); ++ PTR_InstantiatedMethodDesc(imd->IMD_GetWrappedMethodDesc()); + if( CORCOMPILE_IS_POINTER_TAGGED(PTR_TO_TADDR(wrapped)) ) + { + /* XXX Mon 03/27/2006 +@@ -8131,7 +8126,7 @@ void NativeImageDumper::DumpMethodDesc( PTR_MethodDesc md, PTR_Module module ) + else + { + PTR_DictionaryLayout layout(wrapped->IsSharedByGenericMethodInstantiations() +- ? TO_TADDR(wrapped->m_pDictLayout) : NULL ); ++ ? dac_cast<TADDR>(wrapped->GetDictLayoutRaw()) : NULL ); + dictSize = DictionaryLayout::GetFirstDictionaryBucketSize(imd->GetNumGenericMethodArgs(), + layout); + } +diff --git a/src/vm/dllimport.cpp b/src/vm/dllimport.cpp +index b58ac56..cf546cd 100644 +--- a/src/vm/dllimport.cpp ++++ b/src/vm/dllimport.cpp +@@ -4368,8 +4368,8 @@ void NDirect::PopulateNDirectMethodDesc(NDirectMethodDesc* pNMD, PInvokeStaticSi + else + { + EnsureWritablePages(&pNMD->ndirect); +- pNMD->ndirect.m_pszLibName = szLibName; +- pNMD->ndirect.m_pszEntrypointName = szEntryPointName; ++ pNMD->ndirect.m_pszLibName.SetValueMaybeNull(szLibName); ++ pNMD->ndirect.m_pszEntrypointName.SetValueMaybeNull(szEntryPointName); + } + + #ifdef _TARGET_X86_ +diff --git a/src/vm/dynamicmethod.cpp b/src/vm/dynamicmethod.cpp +index 2a61f97..43f4c69 100644 +--- a/src/vm/dynamicmethod.cpp ++++ b/src/vm/dynamicmethod.cpp +@@ -272,7 +272,7 @@ DynamicMethodDesc* DynamicMethodTable::GetDynamicMethod(BYTE *psig, DWORD sigSiz + // the store sig part of the method desc + pNewMD->SetStoredMethodSig((PCCOR_SIGNATURE)psig, sigSize); + // the dynamic part of the method desc +- pNewMD->m_pszMethodName = name; ++ pNewMD->m_pszMethodName.SetValueMaybeNull(name); + + pNewMD->m_dwExtendedFlags = mdPublic | mdStatic | DynamicMethodDesc::nomdLCGMethod; + +@@ -884,16 +884,16 @@ void DynamicMethodDesc::Destroy(BOOL fDomainUnload) + LoaderAllocator *pLoaderAllocator = GetLoaderAllocatorForCode(); + + LOG((LF_BCL, LL_INFO1000, "Level3 - Destroying DynamicMethod {0x%p}\n", this)); +- if (m_pSig) ++ if (!m_pSig.IsNull()) + { +- delete[] (BYTE*)m_pSig; +- m_pSig = NULL; ++ delete[] (BYTE*)m_pSig.GetValue(); ++ m_pSig.SetValueMaybeNull(NULL); + } + m_cSig = 0; +- if (m_pszMethodName) ++ if (!m_pszMethodName.IsNull()) + { +- delete[] m_pszMethodName; +- m_pszMethodName = NULL; ++ delete[] m_pszMethodName.GetValue(); ++ m_pszMethodName.SetValueMaybeNull(NULL); + } + + GetLCGMethodResolver()->Destroy(fDomainUnload); +diff --git a/src/vm/genmeth.cpp b/src/vm/genmeth.cpp +index c50f806..d5b435b 100644 +--- a/src/vm/genmeth.cpp ++++ b/src/vm/genmeth.cpp +@@ -465,7 +465,7 @@ InstantiatedMethodDesc::NewInstantiatedMethodDesc(MethodTable *pExactMT, + { + if (pWrappedMD->IsSharedByGenericMethodInstantiations()) + { +- pDL = pWrappedMD->AsInstantiatedMethodDesc()->m_pDictLayout; ++ pDL = pWrappedMD->AsInstantiatedMethodDesc()->GetDictLayoutRaw(); + } + } + else if (getWrappedCode) +@@ -1576,7 +1576,7 @@ void InstantiatedMethodDesc::SetupSharedMethodInstantiation(DWORD numGenericArgs + _ASSERTE(FitsIn<WORD>(numGenericArgs)); + m_wNumGenericArgs = static_cast<WORD>(numGenericArgs); + +- m_pDictLayout = pDL; ++ m_pDictLayout.SetValueMaybeNull(pDL); + + + _ASSERTE(IMD_IsSharedByGenericMethodInstantiations()); +diff --git a/src/vm/ilstubcache.cpp b/src/vm/ilstubcache.cpp +index ff6bdc0..3651715 100644 +--- a/src/vm/ilstubcache.cpp ++++ b/src/vm/ilstubcache.cpp +@@ -167,7 +167,7 @@ MethodDesc* ILStubCache::CreateNewMethodDesc(LoaderHeap* pCreationHeap, MethodTa + pMD->SetMemberDef(0); + pMD->SetSlot(MethodTable::NO_SLOT); // we can't ever use the slot for dynamic methods + // the no metadata part of the method desc +- pMD->m_pszMethodName = (PTR_CUTF8)"IL_STUB"; ++ pMD->m_pszMethodName.SetValue((PTR_CUTF8)"IL_STUB"); + pMD->m_dwExtendedFlags = mdPublic | DynamicMethodDesc::nomdILStub; + + pMD->SetTemporaryEntryPoint(pMT->GetLoaderAllocator(), pamTracker); +@@ -292,11 +292,11 @@ MethodDesc* ILStubCache::CreateNewMethodDesc(LoaderHeap* pCreationHeap, MethodTa + { + switch(dwStubFlags) + { +- case ILSTUB_ARRAYOP_GET: pMD->m_pszMethodName = (PTR_CUTF8)"IL_STUB_Array_Get"; ++ case ILSTUB_ARRAYOP_GET: pMD->m_pszMethodName.SetValue((PTR_CUTF8)"IL_STUB_Array_Get"); + break; +- case ILSTUB_ARRAYOP_SET: pMD->m_pszMethodName = (PTR_CUTF8)"IL_STUB_Array_Set"; ++ case ILSTUB_ARRAYOP_SET: pMD->m_pszMethodName.SetValue((PTR_CUTF8)"IL_STUB_Array_Set"); + break; +- case ILSTUB_ARRAYOP_ADDRESS: pMD->m_pszMethodName = (PTR_CUTF8)"IL_STUB_Array_Address"; ++ case ILSTUB_ARRAYOP_ADDRESS: pMD->m_pszMethodName.SetValue((PTR_CUTF8)"IL_STUB_Array_Address"); + break; + default: _ASSERTE(!"Unknown array il stub"); + } +@@ -304,12 +304,12 @@ MethodDesc* ILStubCache::CreateNewMethodDesc(LoaderHeap* pCreationHeap, MethodTa + else + #endif + { +- pMD->m_pszMethodName = pMD->GetILStubResolver()->GetStubMethodName(); ++ pMD->m_pszMethodName.SetValue(pMD->GetILStubResolver()->GetStubMethodName()); + } + + + #ifdef _DEBUG +- pMD->m_pszDebugMethodName = pMD->m_pszMethodName; ++ pMD->m_pszDebugMethodName = RelativePointer<PTR_CUTF8>::GetValueAtPtr(PTR_HOST_MEMBER_TADDR(DynamicMethodDesc, pMD, m_pszMethodName)); + pMD->m_pszDebugClassName = ILStubResolver::GetStubClassName(pMD); // must be called after type is set + pMD->m_pszDebugMethodSignature = FormatSig(pMD, pCreationHeap, pamTracker); + pMD->m_pDebugMethodTable.SetValue(pMT); +diff --git a/src/vm/method.cpp b/src/vm/method.cpp +index 751ceac..c8c1b9f 100644 +--- a/src/vm/method.cpp ++++ b/src/vm/method.cpp +@@ -2919,7 +2919,7 @@ void MethodDesc::Save(DataImage *image) + + if (pNewSMD->HasStoredMethodSig()) + { +- if (!image->IsStored((void *) pNewSMD->m_pSig)) ++ if (!image->IsStored((void *) pNewSMD->m_pSig.GetValueMaybeNull())) + { + // Store signatures that doesn't need restore into a read only section. + DataImage::ItemKind sigItemKind = DataImage::ITEM_STORED_METHOD_SIG_READONLY; +@@ -2935,7 +2935,7 @@ void MethodDesc::Save(DataImage *image) + } + + if (FixupSignatureContainingInternalTypes(image, +- (PCCOR_SIGNATURE)pNewSMD->m_pSig, ++ (PCCOR_SIGNATURE) pNewSMD->m_pSig.GetValueMaybeNull(), + pNewSMD->m_cSig, + true /*checkOnly if we will need to restore the signature without doing fixup*/)) + { +@@ -2943,7 +2943,7 @@ void MethodDesc::Save(DataImage *image) + } + } + +- image->StoreInternedStructure((void *) pNewSMD->m_pSig, ++ image->StoreInternedStructure((void *) pNewSMD->m_pSig.GetValueMaybeNull(), + pNewSMD->m_cSig, + sigItemKind, + 1); +@@ -2964,9 +2964,9 @@ void MethodDesc::Save(DataImage *image) + if (HasMethodInstantiation()) + { + InstantiatedMethodDesc* pIMD = AsInstantiatedMethodDesc(); +- if (pIMD->IMD_IsSharedByGenericMethodInstantiations() && pIMD->m_pDictLayout != NULL) ++ if (pIMD->IMD_IsSharedByGenericMethodInstantiations() && !pIMD->m_pDictLayout.IsNull()) + { +- pIMD->m_pDictLayout->Save(image); ++ pIMD->m_pDictLayout.GetValue()->Save(image); + } + } + if (IsNDirect()) +@@ -3042,9 +3042,10 @@ void MethodDesc::Save(DataImage *image) + if (IsDynamicMethod()) + { + DynamicMethodDesc *pDynMeth = AsDynamicMethodDesc(); +- if (pDynMeth->m_pszMethodName && !image->IsStored(pDynMeth->m_pszMethodName)) +- image->StoreStructure((void *) pDynMeth->m_pszMethodName, +- (ULONG)(strlen(pDynMeth->m_pszMethodName) + 1), ++ if (!pDynMeth->m_pszMethodName.IsNull() ++ && !image->IsStored(pDynMeth->m_pszMethodName.GetValue())) ++ image->StoreStructure((void *) pDynMeth->m_pszMethodName.GetValue(), ++ (ULONG)(strlen(pDynMeth->m_pszMethodName.GetValue()) + 1), + DataImage::ITEM_STORED_METHOD_NAME, + 1); + } +@@ -3629,7 +3630,7 @@ MethodDesc::Fixup( + if (IsDynamicMethod()) + { + image->ZeroPointerField(this, offsetof(DynamicMethodDesc, m_pResolver)); +- image->FixupPointerField(this, offsetof(DynamicMethodDesc, m_pszMethodName)); ++ image->FixupRelativePointerField(this, offsetof(DynamicMethodDesc, m_pszMethodName)); + } + + if (GetClassification() == mcInstantiated) +@@ -3645,8 +3646,8 @@ MethodDesc::Fixup( + { + if (pIMD->IMD_IsSharedByGenericMethodInstantiations()) + { +- pIMD->m_pDictLayout->Fixup(image, TRUE); +- image->FixupPointerField(this, offsetof(InstantiatedMethodDesc, m_pDictLayout)); ++ pIMD->m_pDictLayout.GetValue()->Fixup(image, TRUE); ++ image->FixupRelativePointerField(this, offsetof(InstantiatedMethodDesc, m_pDictLayout)); + } + } + +@@ -3754,7 +3755,7 @@ MethodDesc::Fixup( + if (!pNMD->MarshalingRequired()) + { + // import thunk is only needed if the P/Invoke is inlinable +- image->FixupPointerField(this, offsetof(NDirectMethodDesc, ndirect.m_pImportThunkGlue)); ++ image->FixupRelativePointerField(this, offsetof(NDirectMethodDesc, ndirect.m_pImportThunkGlue)); + ((Precode*)pImportThunkGlue)->Fixup(image, this); + } + else +@@ -3767,8 +3768,8 @@ MethodDesc::Fixup( + + if (!IsQCall()) + { +- image->FixupPointerField(this, offsetof(NDirectMethodDesc, ndirect.m_pszLibName)); +- image->FixupPointerField(this, offsetof(NDirectMethodDesc, ndirect.m_pszEntrypointName)); ++ image->FixupRelativePointerField(this, offsetof(NDirectMethodDesc, ndirect.m_pszLibName)); ++ image->FixupRelativePointerField(this, offsetof(NDirectMethodDesc, ndirect.m_pszEntrypointName)); + } + + if (image->IsStored(pNMD->ndirect.m_pStubMD.GetValueMaybeNull())) +@@ -3779,7 +3780,7 @@ MethodDesc::Fixup( + + if (HasStoredSig()) + { +- image->FixupPointerField(this, offsetof(StoredSigMethodDesc, m_pSig)); ++ image->FixupRelativePointerField(this, offsetof(StoredSigMethodDesc, m_pSig)); + + // The DynamicMethodDescs used for IL stubs may have a signature that refers to + // runtime types using ELEMENT_TYPE_INTERNAL. We need to fixup these types here. +@@ -5512,7 +5513,7 @@ StoredSigMethodDesc::EnumMemoryRegions(CLRDataEnumMemoryFlags flags) + { + SUPPORTS_DAC; + // 'this' already done, see below. +- DacEnumMemoryRegion(m_pSig, m_cSig); ++ DacEnumMemoryRegion(GetSigRVA(), m_cSig); + } + + //******************************************************************************* +diff --git a/src/vm/method.hpp b/src/vm/method.hpp +index 4ef6db0..41695df 100644 +--- a/src/vm/method.hpp ++++ b/src/vm/method.hpp +@@ -2215,7 +2215,7 @@ class StoredSigMethodDesc : public MethodDesc + // Put the sig RVA in here - this allows us to avoid + // touching the method desc table when mscorlib is prejitted. + +- TADDR m_pSig; ++ RelativePointer<TADDR> m_pSig; + DWORD m_cSig; + #ifdef _WIN64 + // m_dwExtendedFlags is not used by StoredSigMethodDesc itself. +@@ -2224,10 +2224,16 @@ class StoredSigMethodDesc : public MethodDesc + DWORD m_dwExtendedFlags; + #endif + ++ TADDR GetSigRVA() ++ { ++ LIMITED_METHOD_DAC_CONTRACT; ++ return RelativePointer<TADDR>::GetValueMaybeNullAtPtr(PTR_HOST_MEMBER_TADDR(StoredSigMethodDesc, this, m_pSig)); ++ } ++ + bool HasStoredMethodSig(void) + { + LIMITED_METHOD_DAC_CONTRACT; +- return m_pSig != 0; ++ return !m_pSig.IsNull(); + } + PCCOR_SIGNATURE GetStoredMethodSig(DWORD* sigLen = NULL) + { +@@ -2238,16 +2244,16 @@ class StoredSigMethodDesc : public MethodDesc + } + #ifdef DACCESS_COMPILE + return (PCCOR_SIGNATURE) +- DacInstantiateTypeByAddress(m_pSig, m_cSig, true); ++ DacInstantiateTypeByAddress(GetSigRVA(), m_cSig, true); + #else // !DACCESS_COMPILE + g_IBCLogger.LogNDirectCodeAccess(this); +- return (PCCOR_SIGNATURE)m_pSig; ++ return (PCCOR_SIGNATURE) m_pSig.GetValueMaybeNull(); + #endif // !DACCESS_COMPILE + } + void SetStoredMethodSig(PCCOR_SIGNATURE sig, DWORD sigBytes) + { + #ifndef DACCESS_COMPILE +- m_pSig = (TADDR)sig; ++ m_pSig.SetValueMaybeNull((TADDR)sig); + m_cSig = sigBytes; + #endif // !DACCESS_COMPILE + } +@@ -2307,7 +2313,7 @@ class DynamicMethodDesc : public StoredSigMethodDesc + #endif + + protected: +- PTR_CUTF8 m_pszMethodName; ++ RelativePointer<PTR_CUTF8> m_pszMethodName; + PTR_DynamicResolver m_pResolver; + + #ifndef _WIN64 +@@ -2348,7 +2354,11 @@ public: + inline PTR_LCGMethodResolver GetLCGMethodResolver(); + inline PTR_ILStubResolver GetILStubResolver(); + +- PTR_CUTF8 GetMethodName() { LIMITED_METHOD_DAC_CONTRACT; return m_pszMethodName; } ++ PTR_CUTF8 GetMethodName() ++ { ++ LIMITED_METHOD_DAC_CONTRACT; ++ return RelativePointer<PTR_CUTF8>::GetValueMaybeNullAtPtr(PTR_HOST_MEMBER_TADDR(DynamicMethodDesc, this, m_pszMethodName)); ++ } + + WORD GetAttrs() + { +@@ -2571,11 +2581,11 @@ public: + LPVOID m_pNativeNDirectTarget; + + // Information about the entrypoint +- LPCUTF8 m_pszEntrypointName; ++ RelativePointer<PTR_CUTF8> m_pszEntrypointName; + + union + { +- LPCUTF8 m_pszLibName; ++ RelativePointer<PTR_CUTF8> m_pszLibName; + DWORD m_dwECallID; // ECallID for QCalls + }; + +@@ -2583,7 +2593,7 @@ public: + PTR_NDirectWriteableData m_pWriteableData; + + #ifdef HAS_NDIRECT_IMPORT_PRECODE +- PTR_NDirectImportThunkGlue m_pImportThunkGlue; ++ RelativePointer<PTR_NDirectImportThunkGlue> m_pImportThunkGlue; + #else // HAS_NDIRECT_IMPORT_PRECODE + NDirectImportThunkGlue m_ImportThunkGlue; + #endif // HAS_NDIRECT_IMPORT_PRECODE +@@ -2706,18 +2716,27 @@ public: + ndirect.m_dwECallID = dwID; + } + ++ PTR_CUTF8 GetLibNameRaw() ++ { ++ LIMITED_METHOD_DAC_CONTRACT; ++ ++ return RelativePointer<PTR_CUTF8>::GetValueMaybeNullAtPtr(PTR_HOST_MEMBER_TADDR(NDirectMethodDesc, this, ndirect.m_pszLibName)); ++ } ++ ++#ifndef DACCESS_COMPILE + LPCUTF8 GetLibName() const + { + LIMITED_METHOD_CONTRACT; + +- return IsQCall() ? "QCall" : ndirect.m_pszLibName; ++ return IsQCall() ? "QCall" : ndirect.m_pszLibName.GetValueMaybeNull(); + } ++#endif // !DACCESS_COMPILE + +- LPCUTF8 GetEntrypointName() const ++ PTR_CUTF8 GetEntrypointName() const + { +- LIMITED_METHOD_CONTRACT; ++ LIMITED_METHOD_DAC_CONTRACT; + +- return ndirect.m_pszEntrypointName; ++ return RelativePointer<PTR_CUTF8>::GetValueMaybeNullAtPtr(PTR_HOST_MEMBER_TADDR(NDirectMethodDesc, this, ndirect.m_pszEntrypointName)); + } + + BOOL IsVarArgs() const +@@ -2800,14 +2819,16 @@ public: + return ndirect.m_pWriteableData; + } + +- NDirectImportThunkGlue* GetNDirectImportThunkGlue() ++ PTR_NDirectImportThunkGlue GetNDirectImportThunkGlue() + { +- LIMITED_METHOD_CONTRACT; ++ LIMITED_METHOD_DAC_CONTRACT; ++ ++ TADDR base = PTR_HOST_MEMBER_TADDR(NDirectMethodDesc, this, ndirect.m_pImportThunkGlue); + + #ifdef HAS_NDIRECT_IMPORT_PRECODE +- return ndirect.m_pImportThunkGlue; ++ return RelativePointer<PTR_NDirectImportThunkGlue>::GetValueAtPtr(base); + #else +- return &ndirect.m_ImportThunkGlue; ++ return dac_cast<PTR_NDirectImportThunkGlue>(base); + #endif + } + +@@ -3281,28 +3302,37 @@ public: + } + #endif // FEATURE_COMINTEROP + ++ PTR_DictionaryLayout GetDictLayoutRaw() ++ { ++ LIMITED_METHOD_DAC_CONTRACT; ++ return RelativePointer<PTR_DictionaryLayout>::GetValueMaybeNullAtPtr(PTR_HOST_MEMBER_TADDR(InstantiatedMethodDesc, this, m_pDictLayout)); ++ } ++ ++ PTR_MethodDesc IMD_GetWrappedMethodDesc() ++ { ++ LIMITED_METHOD_DAC_CONTRACT; ++ ++ _ASSERTE(IMD_IsWrapperStubWithInstantiations()); ++ return RelativePointer<PTR_MethodDesc>::GetValueAtPtr(PTR_HOST_MEMBER_TADDR(InstantiatedMethodDesc, this, m_pWrappedMethodDesc)); ++ } ++ ++#ifndef DACCESS_COMPILE + // Get the dictionary layout, if there is one + DictionaryLayout* IMD_GetDictionaryLayout() + { + WRAPPER_NO_CONTRACT; + if (IMD_IsWrapperStubWithInstantiations() && IMD_HasMethodInstantiation()) +- return IMD_GetWrappedMethodDesc()->AsInstantiatedMethodDesc()->m_pDictLayout; ++ { ++ InstantiatedMethodDesc* pIMD = IMD_GetWrappedMethodDesc()->AsInstantiatedMethodDesc(); ++ return pIMD->m_pDictLayout.GetValueMaybeNull(); ++ } + else + if (IMD_IsSharedByGenericMethodInstantiations()) +- return m_pDictLayout; ++ return m_pDictLayout.GetValueMaybeNull(); + else + return NULL; + } +- +- MethodDesc* IMD_GetWrappedMethodDesc() +- { +- LIMITED_METHOD_CONTRACT; +- +- _ASSERTE(IMD_IsWrapperStubWithInstantiations()); +- return m_pWrappedMethodDesc.GetValue(); +- } +- +- ++#endif // !DACCESS_COMPILE + + // Setup the IMD as shared code + void SetupSharedMethodInstantiation(DWORD numGenericArgs, TypeHandle *pPerInstInfo, DictionaryLayout *pDL); +@@ -3349,9 +3379,9 @@ private: + + friend class MethodDesc; // this fields are currently accessed by MethodDesc::Save/Restore etc. + union { +- DictionaryLayout * m_pDictLayout; //SharedMethodInstantiation ++ RelativePointer<PTR_DictionaryLayout> m_pDictLayout; //SharedMethodInstantiation + +- FixupPointer<PTR_MethodDesc> m_pWrappedMethodDesc; // For WrapperStubWithInstantiations ++ RelativeFixupPointer<PTR_MethodDesc> m_pWrappedMethodDesc; // For WrapperStubWithInstantiations + }; + + public: // <TODO>make private: JITinterface.cpp accesses through this </TODO> +diff --git a/src/vm/methodimpl.cpp b/src/vm/methodimpl.cpp +index 1779c2d..c685e1c 100644 +--- a/src/vm/methodimpl.cpp ++++ b/src/vm/methodimpl.cpp +@@ -72,7 +72,10 @@ PTR_MethodDesc MethodImpl::FindMethodDesc(DWORD slot, PTR_MethodDesc defaultRetu + return defaultReturn; + } + +- PTR_MethodDesc result = pImplementedMD[slotIndex]; // The method descs are not offset by one ++ DPTR(RelativePointer<PTR_MethodDesc>) pRelPtrForSlot = GetImpMDsNonNull(); ++ // The method descs are not offset by one ++ TADDR base = dac_cast<TADDR>(pRelPtrForSlot) + slotIndex * sizeof(RelativePointer<MethodDesc *>); ++ PTR_MethodDesc result = RelativePointer<PTR_MethodDesc>::GetValueMaybeNullAtPtr(base); + + // Prejitted images may leave NULL in this table if + // the methoddesc is declared in another module. +@@ -98,13 +101,13 @@ MethodDesc *MethodImpl::RestoreSlot(DWORD index, MethodTable *pMT) + NOTHROW; + GC_NOTRIGGER; + FORBID_FAULT; +- PRECONDITION(CheckPointer(pdwSlots)); ++ PRECONDITION(!pdwSlots.IsNull()); + } + CONTRACTL_END + + MethodDesc *result; + +- PREFIX_ASSUME(pdwSlots != NULL); ++ PREFIX_ASSUME(!pdwSlots.IsNull()); + DWORD slot = GetSlots()[index]; + + // Since the overridden method is in a different module, we +@@ -126,8 +129,9 @@ MethodDesc *MethodImpl::RestoreSlot(DWORD index, MethodTable *pMT) + _ASSERTE(result != NULL); + + // Don't worry about races since we would all be setting the same result +- if (EnsureWritableExecutablePagesNoThrow(&pImplementedMD[index], sizeof(pImplementedMD[index]))) +- pImplementedMD[index] = result; ++ if (EnsureWritableExecutablePagesNoThrow(&pImplementedMD.GetValue()[index], ++ sizeof(pImplementedMD.GetValue()[index]))) ++ pImplementedMD.GetValue()[index].SetValue(result); + + return result; + } +@@ -139,7 +143,7 @@ void MethodImpl::SetSize(LoaderHeap *pHeap, AllocMemTracker *pamTracker, DWORD s + THROWS; + GC_NOTRIGGER; + PRECONDITION(CheckPointer(this)); +- PRECONDITION(pdwSlots==NULL && pImplementedMD==NULL); ++ PRECONDITION(pdwSlots.GetValueMaybeNull()==NULL && pImplementedMD.GetValueMaybeNull()==NULL); + INJECT_FAULT(ThrowOutOfMemory()); + } CONTRACTL_END; + +@@ -149,7 +153,7 @@ void MethodImpl::SetSize(LoaderHeap *pHeap, AllocMemTracker *pamTracker, DWORD s + S_SIZE_T(size) * S_SIZE_T(sizeof(DWORD)); // DWORD each for the slot numbers + + // MethodDesc* for each of the implemented methods +- S_SIZE_T cbMethodDescs = S_SIZE_T(size) * S_SIZE_T(sizeof(MethodDesc *)); ++ S_SIZE_T cbMethodDescs = S_SIZE_T(size) * S_SIZE_T(sizeof(RelativePointer<MethodDesc *>)); + + // Need to align-up the slot entries so that the MethodDesc* array starts on a pointer boundary. + cbCountAndSlots.AlignUp(sizeof(MethodDesc*)); +@@ -161,29 +165,36 @@ void MethodImpl::SetSize(LoaderHeap *pHeap, AllocMemTracker *pamTracker, DWORD s + LPBYTE pAllocData = (BYTE*)pamTracker->Track(pHeap->AllocMem(cbTotal)); + + // Set the count and slot array +- pdwSlots = (DWORD*)pAllocData; ++ pdwSlots.SetValue((DWORD*)pAllocData); + + // Set the MethodDesc* array. Make sure to adjust for alignment. +- pImplementedMD = (MethodDesc**)ALIGN_UP(pAllocData + cbCountAndSlots.Value(), sizeof(MethodDesc*)); ++ pImplementedMD.SetValue((RelativePointer<MethodDesc*> *)ALIGN_UP(pAllocData + cbCountAndSlots.Value(), sizeof(RelativePointer <MethodDesc*>))); + + // Store the count in the first entry +- *pdwSlots = size; ++ *pdwSlots.GetValue() = size; + } + } + + /////////////////////////////////////////////////////////////////////////////////////// +-void MethodImpl::SetData(DWORD* slots, MethodDesc** md) ++void MethodImpl::SetData(DWORD* slots, RelativePointer<MethodDesc*>* md) + { + CONTRACTL { + NOTHROW; + GC_NOTRIGGER; + PRECONDITION(CheckPointer(this)); +- PRECONDITION(CheckPointer(pdwSlots)); ++ PRECONDITION(!pdwSlots.IsNull()); + } CONTRACTL_END; + +- DWORD dwSize = *pdwSlots; +- memcpy(&(pdwSlots[1]), slots, dwSize*sizeof(DWORD)); +- memcpy(pImplementedMD, md, dwSize*sizeof(MethodDesc*)); ++ DWORD *pdwSize = pdwSlots.GetValue(); ++ DWORD dwSize = *pdwSize; ++ memcpy(&(pdwSize[1]), slots, dwSize*sizeof(DWORD)); ++ ++ RelativePointer<MethodDesc *> *pImplMD = pImplementedMD.GetValue(); ++ ++ for (uint32_t i = 0; i < dwSize; ++i) ++ { ++ pImplMD[i].SetValue(md[i].GetValue()); ++ } + } + + #ifdef FEATURE_NATIVE_IMAGE_GENERATION +@@ -194,10 +205,10 @@ void MethodImpl::Save(DataImage *image) + DWORD size = GetSize(); + _ASSERTE(size > 0); + +- image->StoreStructure(pdwSlots, (size+1)*sizeof(DWORD), ++ image->StoreStructure(pdwSlots.GetValue(), (size+1)*sizeof(DWORD), + DataImage::ITEM_METHOD_DESC_COLD, + sizeof(DWORD)); +- image->StoreStructure(pImplementedMD, size*sizeof(MethodDesc*), ++ image->StoreStructure(pImplementedMD.GetValue(), size*sizeof(RelativePointer<MethodDesc*>), + DataImage::ITEM_METHOD_DESC_COLD, + sizeof(MethodDesc*)); + } +@@ -214,21 +225,22 @@ void MethodImpl::Fixup(DataImage *image, PVOID p, SSIZE_T offset) + // <TODO> Why not use FixupMethodDescPointer? </TODO> + // <TODO> Does it matter if the MethodDesc needs a restore? </TODO> + +- MethodDesc * pMD = pImplementedMD[iMD]; ++ RelativePointer<MethodDesc *> *pRelPtr = pImplementedMD.GetValue(); ++ MethodDesc * pMD = pRelPtr[iMD].GetValueMaybeNull(); + + if (image->CanEagerBindToMethodDesc(pMD) && + image->CanHardBindToZapModule(pMD->GetLoaderModule())) + { +- image->FixupPointerField(pImplementedMD, iMD * sizeof(MethodDesc *)); ++ image->FixupRelativePointerField(pImplementedMD.GetValue(), iMD * sizeof(RelativePointer<MethodDesc *>)); + } + else + { +- image->ZeroPointerField(pImplementedMD, iMD * sizeof(MethodDesc *)); ++ image->ZeroPointerField(pImplementedMD.GetValue(), iMD * sizeof(RelativePointer<MethodDesc *>)); + } + } + +- image->FixupPointerField(p, offset + offsetof(MethodImpl, pdwSlots)); +- image->FixupPointerField(p, offset + offsetof(MethodImpl, pImplementedMD)); ++ image->FixupRelativePointerField(p, offset + offsetof(MethodImpl, pdwSlots)); ++ image->FixupRelativePointerField(p, offset + offsetof(MethodImpl, pImplementedMD)); + } + + #endif // FEATURE_NATIVE_IMAGE_GENERATION +@@ -247,19 +259,20 @@ MethodImpl::EnumMemoryRegions(CLRDataEnumMemoryFlags flags) + // 'this' memory should already be enumerated as + // part of the base MethodDesc. + +- if (pdwSlots.IsValid() && GetSize()) ++ if (GetSlotsRaw().IsValid() && GetSize()) + { + ULONG32 numSlots = GetSize(); +- DacEnumMemoryRegion(dac_cast<TADDR>(pdwSlots), ++ DacEnumMemoryRegion(dac_cast<TADDR>(GetSlotsRawNonNull()), + (numSlots + 1) * sizeof(DWORD)); + +- if (pImplementedMD.IsValid()) ++ if (GetImpMDs().IsValid()) + { +- DacEnumMemoryRegion(dac_cast<TADDR>(pImplementedMD), +- numSlots * sizeof(PTR_MethodDesc)); ++ DacEnumMemoryRegion(dac_cast<TADDR>(GetImpMDsNonNull()), ++ numSlots * sizeof(RelativePointer<MethodDesc *>)); + for (DWORD i = 0; i < numSlots; i++) + { +- PTR_MethodDesc methodDesc = pImplementedMD[i]; ++ DPTR(RelativePointer<PTR_MethodDesc>) pRelPtr = GetImpMDsNonNull(); ++ PTR_MethodDesc methodDesc = pRelPtr[i].GetValueMaybeNull(); + if (methodDesc.IsValid()) + { + methodDesc->EnumMemoryRegions(flags); +diff --git a/src/vm/methodimpl.h b/src/vm/methodimpl.h +index 0646367..453f4cc 100644 +--- a/src/vm/methodimpl.h ++++ b/src/vm/methodimpl.h +@@ -24,8 +24,8 @@ class MethodImpl + friend class NativeImageDumper; + #endif + +- PTR_DWORD pdwSlots; // Maintains the slots in sorted order, the first entry is the size +- DPTR(PTR_MethodDesc) pImplementedMD; ++ RelativePointer<PTR_DWORD> pdwSlots; // Maintains the slots in sorted order, the first entry is the size ++ RelativePointer<DPTR( RelativePointer<PTR_MethodDesc> )> pImplementedMD; + + public: + +@@ -49,18 +49,19 @@ public: + inline MethodDesc *GetMethodDesc() + { WRAPPER_NO_CONTRACT; return m_pImpl->FindMethodDesc(GetSlot(), (PTR_MethodDesc) m_pMD); } + }; ++#endif // !DACCESS_COMPILE + +- /////////////////////////////////////////////////////////////////////////////////////// +- inline MethodDesc** GetImplementedMDs() ++ inline DPTR(RelativePointer<PTR_MethodDesc>) GetImpMDs() + { +- CONTRACTL { +- NOTHROW; +- GC_NOTRIGGER; +- PRECONDITION(CheckPointer(this)); +- } CONTRACTL_END; +- return pImplementedMD; ++ LIMITED_METHOD_DAC_CONTRACT; ++ return RelativePointer<DPTR(RelativePointer<PTR_MethodDesc>)>::GetValueMaybeNullAtPtr(PTR_HOST_MEMBER_TADDR(MethodImpl, this, pImplementedMD)); ++ } ++ ++ inline DPTR(RelativePointer<PTR_MethodDesc>) GetImpMDsNonNull() ++ { ++ LIMITED_METHOD_DAC_CONTRACT; ++ return RelativePointer<DPTR(RelativePointer<PTR_MethodDesc>)>::GetValueAtPtr(PTR_HOST_MEMBER_TADDR(MethodImpl, this, pImplementedMD)); + } +-#endif // !DACCESS_COMPILE + + /////////////////////////////////////////////////////////////////////////////////////// + inline DWORD GetSize() +@@ -71,10 +72,10 @@ public: + PRECONDITION(CheckPointer(this)); + } CONTRACTL_END; + +- if(pdwSlots == NULL) ++ if(pdwSlots.IsNull()) + return 0; + else +- return *pdwSlots; ++ return *GetSlotsRawNonNull(); + } + + /////////////////////////////////////////////////////////////////////////////////////// +@@ -87,10 +88,22 @@ public: + SUPPORTS_DAC; + } CONTRACTL_END; + +- if(pdwSlots == NULL) ++ if(pdwSlots.IsNull()) + return NULL; + else +- return pdwSlots + 1; ++ return GetSlotsRawNonNull() + 1; ++ } ++ ++ inline PTR_DWORD GetSlotsRaw() ++ { ++ LIMITED_METHOD_DAC_CONTRACT; ++ return RelativePointer<PTR_DWORD>::GetValueMaybeNullAtPtr(PTR_HOST_MEMBER_TADDR(MethodImpl, this, pdwSlots)); ++ } ++ ++ inline PTR_DWORD GetSlotsRawNonNull() ++ { ++ LIMITED_METHOD_DAC_CONTRACT; ++ return RelativePointer<PTR_DWORD>::GetValueAtPtr(PTR_HOST_MEMBER_TADDR(MethodImpl, this, pdwSlots)); + } + + #ifndef DACCESS_COMPILE +@@ -99,7 +112,7 @@ public: + void SetSize(LoaderHeap *pHeap, AllocMemTracker *pamTracker, DWORD size); + + /////////////////////////////////////////////////////////////////////////////////////// +- void SetData(DWORD* slots, MethodDesc** md); ++ void SetData(DWORD* slots, RelativePointer<MethodDesc*> * md); + + #endif // !DACCESS_COMPILE + +diff --git a/src/vm/methodtablebuilder.cpp b/src/vm/methodtablebuilder.cpp +index 503c13a..df31c4a 100644 +--- a/src/vm/methodtablebuilder.cpp ++++ b/src/vm/methodtablebuilder.cpp +@@ -6125,8 +6125,8 @@ MethodTableBuilder::InitMethodDesc( + AllocateFromHighFrequencyHeap(S_SIZE_T(sizeof(NDirectWriteableData))); + + #ifdef HAS_NDIRECT_IMPORT_PRECODE +- pNewNMD->ndirect.m_pImportThunkGlue = Precode::Allocate(PRECODE_NDIRECT_IMPORT, pNewMD, +- GetLoaderAllocator(), GetMemTracker())->AsNDirectImportPrecode(); ++ pNewNMD->ndirect.m_pImportThunkGlue.SetValue(Precode::Allocate(PRECODE_NDIRECT_IMPORT, pNewMD, ++ GetLoaderAllocator(), GetMemTracker())->AsNDirectImportPrecode()); + #else // !HAS_NDIRECT_IMPORT_PRECODE + pNewNMD->GetNDirectImportThunkGlue()->Init(pNewNMD); + #endif // !HAS_NDIRECT_IMPORT_PRECODE +@@ -6371,7 +6371,7 @@ MethodTableBuilder::PlaceMethodImpls() + // Allocate some temporary storage. The number of overrides for a single method impl + // cannot be greater then the number of vtable slots. + DWORD * slots = new (&GetThread()->m_MarshalAlloc) DWORD[bmtVT->cVirtualSlots]; +- MethodDesc ** replaced = new (&GetThread()->m_MarshalAlloc) MethodDesc*[bmtVT->cVirtualSlots]; ++ RelativePointer<MethodDesc *> * replaced = new (&GetThread()->m_MarshalAlloc) RelativePointer<MethodDesc*>[bmtVT->cVirtualSlots]; + + DWORD iEntry = 0; + bmtMDMethod * pCurImplMethod = bmtMethodImpl->GetImplementationMethod(iEntry); +@@ -6458,7 +6458,7 @@ MethodTableBuilder::WriteMethodImplData( + bmtMDMethod * pImplMethod, + DWORD cSlots, + DWORD * rgSlots, +- MethodDesc ** rgDeclMD) ++ RelativePointer<MethodDesc *> * rgDeclMD) + { + STANDARD_VM_CONTRACT; + +@@ -6488,9 +6488,9 @@ MethodTableBuilder::WriteMethodImplData( + { + if (rgSlots[j] < rgSlots[i]) + { +- MethodDesc * mTmp = rgDeclMD[i]; +- rgDeclMD[i] = rgDeclMD[j]; +- rgDeclMD[j] = mTmp; ++ MethodDesc * mTmp = rgDeclMD[i].GetValue(); ++ rgDeclMD[i].SetValue(rgDeclMD[j].GetValue()); ++ rgDeclMD[j].SetValue(mTmp); + + DWORD sTmp = rgSlots[i]; + rgSlots[i] = rgSlots[j]; +@@ -6512,7 +6512,7 @@ MethodTableBuilder::PlaceLocalDeclaration( + bmtMDMethod * pDecl, + bmtMDMethod * pImpl, + DWORD * slots, +- MethodDesc ** replaced, ++ RelativePointer<MethodDesc *> * replaced, + DWORD * pSlotIndex) + { + CONTRACTL +@@ -6569,7 +6569,7 @@ MethodTableBuilder::PlaceLocalDeclaration( + + // We implement this slot, record it + slots[*pSlotIndex] = pDecl->GetSlotIndex(); +- replaced[*pSlotIndex] = pDecl->GetMethodDesc(); ++ replaced[*pSlotIndex].SetValue(pDecl->GetMethodDesc()); + + // increment the counter + (*pSlotIndex)++; +@@ -6580,7 +6580,7 @@ VOID MethodTableBuilder::PlaceInterfaceDeclaration( + bmtRTMethod * pDecl, + bmtMDMethod * pImpl, + DWORD* slots, +- MethodDesc** replaced, ++ RelativePointer<MethodDesc *> * replaced, + DWORD* pSlotIndex) + { + CONTRACTL { +@@ -6685,7 +6685,7 @@ MethodTableBuilder::PlaceParentDeclaration( + bmtRTMethod * pDecl, + bmtMDMethod * pImpl, + DWORD * slots, +- MethodDesc ** replaced, ++ RelativePointer<MethodDesc *> * replaced, + DWORD * pSlotIndex) + { + CONTRACTL { +@@ -6730,7 +6730,7 @@ MethodTableBuilder::PlaceParentDeclaration( + + // We implement this slot, record it + slots[*pSlotIndex] = pDeclMD->GetSlot(); +- replaced[*pSlotIndex] = pDeclMD; ++ replaced[*pSlotIndex].SetValue(pDeclMD); + + // increment the counter + (*pSlotIndex)++; +diff --git a/src/vm/methodtablebuilder.h b/src/vm/methodtablebuilder.h +index 2aa3683..6c82e54 100644 +--- a/src/vm/methodtablebuilder.h ++++ b/src/vm/methodtablebuilder.h +@@ -2749,7 +2749,7 @@ private: + bmtMDMethod * pImplMethod, + DWORD cSlots, + DWORD * rgSlots, +- MethodDesc ** rgDeclMD); ++ RelativePointer<MethodDesc *> * rgDeclMD); + + // -------------------------------------------------------------------------------------------- + // Places a methodImpl pair where the decl is declared by the type being built. +@@ -2758,7 +2758,7 @@ private: + bmtMDMethod * pDecl, + bmtMDMethod * pImpl, + DWORD* slots, +- MethodDesc** replaced, ++ RelativePointer<MethodDesc *> * replaced, + DWORD* pSlotIndex); + + // -------------------------------------------------------------------------------------------- +@@ -2768,7 +2768,7 @@ private: + bmtRTMethod * pDecl, + bmtMDMethod * pImpl, + DWORD* slots, +- MethodDesc** replaced, ++ RelativePointer<MethodDesc *> * replaced, + DWORD* pSlotIndex); + + // -------------------------------------------------------------------------------------------- +@@ -2778,7 +2778,7 @@ private: + bmtRTMethod * pDecl, + bmtMDMethod * pImpl, + DWORD* slots, +- MethodDesc** replaced, ++ RelativePointer<MethodDesc *> * replaced, + DWORD* pSlotIndex); + + // -------------------------------------------------------------------------------------------- +-- +2.7.4 + |