diff options
author | Konstantin Baladurin <k.baladurin@partner.samsung.com> | 2018-04-26 17:34:58 +0300 |
---|---|---|
committer | Vladislav Andresov <v.andresov@partner.samsung.com> | 2018-04-26 20:04:15 +0300 |
commit | 371df401e4d8c9639035d164710d1246e0cb8548 (patch) | |
tree | b550f3433a68c80a1ff952413b7b7a0e3ab97995 /packaging/0019-Remove-relocations-from-SECTION_Readonly-for-fields-.patch | |
parent | 5e7a310b1a251937154d05cd52637ac62b6d5edc (diff) | |
download | coreclr-371df401e4d8c9639035d164710d1246e0cb8548.tar.gz coreclr-371df401e4d8c9639035d164710d1246e0cb8548.tar.bz2 coreclr-371df401e4d8c9639035d164710d1246e0cb8548.zip |
Add memory optimization patches from upstreamsubmit/tizen_4.0/20180427.011218accepted/tizen/4.0/unified/20180427.062437accepted/tizen_4.0_unified
Change-Id: Ie8ea75fa60184b77135289c8fdc0f49d40b49d87
Diffstat (limited to 'packaging/0019-Remove-relocations-from-SECTION_Readonly-for-fields-.patch')
-rw-r--r-- | packaging/0019-Remove-relocations-from-SECTION_Readonly-for-fields-.patch | 903 |
1 files changed, 903 insertions, 0 deletions
diff --git a/packaging/0019-Remove-relocations-from-SECTION_Readonly-for-fields-.patch b/packaging/0019-Remove-relocations-from-SECTION_Readonly-for-fields-.patch new file mode 100644 index 0000000000..2b4e53c176 --- /dev/null +++ b/packaging/0019-Remove-relocations-from-SECTION_Readonly-for-fields-.patch @@ -0,0 +1,903 @@ +From 9440822ceb7b6e58b840cfa4f4118e6410375df5 Mon Sep 17 00:00:00 2001 +From: Gleb Balykov <g.balykov@samsung.com> +Date: Wed, 21 Jun 2017 19:48:49 +0300 +Subject: [PATCH 19/32] Remove relocations from SECTION_Readonly for fields not + accessed from jit code on ARM + +--- + src/debug/daccess/nidump.cpp | 6 ++-- + src/inc/fixuppointer.h | 28 +++++++++++++--- + src/vm/ceeload.cpp | 31 ++++++++++-------- + src/vm/ceeload.h | 26 ++++++++++----- + src/vm/dataimage.h | 78 ++++++++++++++++++++++++++++++++++++++++++++ + src/vm/methodtable.cpp | 54 +++++++++++++++++------------- + src/vm/methodtable.h | 25 +++++++++----- + src/vm/methodtable.inl | 58 +++++++++++++++++--------------- + 8 files changed, 218 insertions(+), 88 deletions(-) + +diff --git a/src/debug/daccess/nidump.cpp b/src/debug/daccess/nidump.cpp +index 2ec5d9a..673aa39 100644 +--- a/src/debug/daccess/nidump.cpp ++++ b/src/debug/daccess/nidump.cpp +@@ -3959,7 +3959,7 @@ void NativeImageDumper::DumpModule( PTR_Module module ) + DisplayWriteFieldInt( numElementsHot, ctorInfo->numElementsHot, + ModuleCtorInfo, SLIM_MODULE_TBLS ); + DisplayWriteFieldAddress( ppMT, DPtrToPreferredAddr(ctorInfo->ppMT), +- ctorInfo->numElements * sizeof(MethodTable*), ++ ctorInfo->numElements * sizeof(RelativePointer<MethodTable*>), + ModuleCtorInfo, SLIM_MODULE_TBLS ); + /* REVISIT_TODO Tue 03/21/2006 + * is cctorInfoHot and cctorInfoCold actually have anything interesting +@@ -7301,7 +7301,7 @@ NativeImageDumper::DumpMethodTable( PTR_MethodTable mt, const char * name, + { + PTR_InterfaceInfo ifMap = mt->GetInterfaceMap(); + m_display->StartArrayWithOffset( "InterfaceMap", +- offsetof(MethodTable, m_pMultipurposeSlot2), ++ offsetof(MethodTable, m_pInterfaceMap), + sizeof(void*), + NULL ); + for( unsigned i = 0; i < mt->GetNumInterfaces(); ++i ) +@@ -7335,7 +7335,7 @@ NativeImageDumper::DumpMethodTable( PTR_MethodTable mt, const char * name, + DPtrToPreferredAddr(genStatics), + sizeof(*genStatics) ); + +- PTR_FieldDesc fieldDescs = genStatics->m_pFieldDescs; ++ PTR_FieldDesc fieldDescs = ReadPointerMaybeNull((GenericsStaticsInfo *) genStatics, &GenericsStaticsInfo::m_pFieldDescs); + if( fieldDescs == NULL ) + { + DisplayWriteFieldPointer( m_pFieldDescs, NULL, GenericsStaticsInfo, +diff --git a/src/inc/fixuppointer.h b/src/inc/fixuppointer.h +index 83ff20e..20eb9d8 100644 +--- a/src/inc/fixuppointer.h ++++ b/src/inc/fixuppointer.h +@@ -141,6 +141,12 @@ public: + LIMITED_METHOD_CONTRACT; + SetValueMaybeNull((TADDR)this, addr); + } ++ ++ FORCEINLINE void SetValueVolatile(PTR_TYPE addr) ++ { ++ LIMITED_METHOD_CONTRACT; ++ SetValue(addr); ++ } + #endif + + #ifndef DACCESS_COMPILE +@@ -264,6 +270,9 @@ public: + RelativeFixupPointer<PTR_TYPE>& operator = (const RelativeFixupPointer<PTR_TYPE> &) =delete; + RelativeFixupPointer<PTR_TYPE>& operator = (RelativeFixupPointer<PTR_TYPE> &&) =delete; + ++ // Default constructor ++ RelativeFixupPointer<PTR_TYPE>() {} ++ + // Returns whether the encoded pointer is NULL. + BOOL IsNull() const + { +@@ -468,7 +477,6 @@ public: + PTR_TYPE GetValue(TADDR base) const + { + LIMITED_METHOD_DAC_CONTRACT; +- PRECONDITION(!IsNull()); + return dac_cast<PTR_TYPE>(m_ptr); + } + +@@ -480,6 +488,13 @@ public: + } + + // Returns value of the encoded pointer. The pointer can be NULL. ++ PTR_TYPE GetValueMaybeNull() const ++ { ++ LIMITED_METHOD_DAC_CONTRACT; ++ return dac_cast<PTR_TYPE>(m_ptr); ++ } ++ ++ // Returns value of the encoded pointer. The pointer can be NULL. + PTR_TYPE GetValueMaybeNull(TADDR base) const + { + LIMITED_METHOD_DAC_CONTRACT; +@@ -493,6 +508,7 @@ public: + return dac_cast<DPTR(PlainPointer<PTR_TYPE>)>(base)->GetValueMaybeNull(base); + } + ++#ifndef DACCESS_COMPILE + void SetValue(PTR_TYPE addr) + { + LIMITED_METHOD_CONTRACT; +@@ -503,7 +519,6 @@ public: + void SetValue(TADDR base, PTR_TYPE addr) + { + LIMITED_METHOD_CONTRACT; +- PRECONDITION(addr != NULL); + m_ptr = dac_cast<TADDR>(addr); + } + +@@ -521,7 +536,6 @@ public: + m_ptr = dac_cast<TADDR>(addr); + } + +-#ifndef DACCESS_COMPILE + // Set encoded value of the pointer. The value can be NULL. + // Does not need explicit base and thus can be used in non-DAC builds only. + FORCEINLINE void SetValueMaybeNull(PTR_TYPE addr) +@@ -529,7 +543,6 @@ public: + LIMITED_METHOD_CONTRACT; + return SetValueMaybeNull((TADDR)this, addr); + } +-#endif + + // Static version of SetValueMaybeNull. It is meant to simplify access to arrays of pointers. + FORCEINLINE static void SetValueMaybeNullAtPtr(TADDR base, PTR_TYPE addr) +@@ -538,6 +551,13 @@ public: + dac_cast<DPTR(PlainPointer<PTR_TYPE>)>(base)->SetValueMaybeNull(base, addr); + } + ++ FORCEINLINE void SetValueVolatile(PTR_TYPE addr) ++ { ++ LIMITED_METHOD_CONTRACT; ++ VolatileStore((PTR_TYPE *)(&m_ptr), addr); ++ } ++#endif ++ + private: + TADDR m_ptr; + }; +diff --git a/src/vm/ceeload.cpp b/src/vm/ceeload.cpp +index cd40ad7..3a85a52 100644 +--- a/src/vm/ceeload.cpp ++++ b/src/vm/ceeload.cpp +@@ -2892,7 +2892,7 @@ BOOL Module::IsPreV4Assembly() + } + + +-ArrayDPTR(FixupPointer<PTR_MethodTable>) ModuleCtorInfo::GetGCStaticMTs(DWORD index) ++ArrayDPTR(RelativeFixupPointer<PTR_MethodTable>) ModuleCtorInfo::GetGCStaticMTs(DWORD index) + { + LIMITED_METHOD_CONTRACT; + +@@ -8282,6 +8282,8 @@ void Module::SaveTypeHandle(DataImage * image, + #endif // _DEBUG + } + ++#ifndef DACCESS_COMPILE ++ + void ModuleCtorInfo::Save(DataImage *image, CorProfileData *profileData) + { + STANDARD_VM_CONTRACT; +@@ -8303,7 +8305,7 @@ void ModuleCtorInfo::Save(DataImage *image, CorProfileData *profileData) + // items numElementsHot...i-1 are cold + for (i = 0; i < numElements; i++) + { +- MethodTable *ppMTTemp = ppMT[i]; ++ MethodTable *ppMTTemp = ppMT[i].GetValue(); + + // Count the number of boxed statics along the way + totalBoxedStatics += ppMTTemp->GetNumBoxedRegularStatics(); +@@ -8317,8 +8319,8 @@ void ModuleCtorInfo::Save(DataImage *image, CorProfileData *profileData) + if (hot) + { + // swap ppMT[i] and ppMT[numElementsHot] to maintain the loop invariant +- ppMT[i] = ppMT[numElementsHot]; +- ppMT[numElementsHot] = ppMTTemp; ++ ppMT[i].SetValue(ppMT[numElementsHot].GetValue()); ++ ppMT[numElementsHot].SetValue(ppMTTemp); + + numElementsHot++; + } +@@ -8343,11 +8345,11 @@ void ModuleCtorInfo::Save(DataImage *image, CorProfileData *profileData) + + for (i = 0; i < numElementsHot; i++) + { +- hashArray[i] = GenerateHash(ppMT[i], HOT); ++ hashArray[i] = GenerateHash(ppMT[i].GetValue(), HOT); + } + for (i = numElementsHot; i < numElements; i++) + { +- hashArray[i] = GenerateHash(ppMT[i], COLD); ++ hashArray[i] = GenerateHash(ppMT[i].GetValue(), COLD); + } + + // Sort the two arrays by hash values to create regions with the same hash values. +@@ -8410,7 +8412,7 @@ void ModuleCtorInfo::Save(DataImage *image, CorProfileData *profileData) + // make cctorInfoCold point to the first cold element + cctorInfoCold = cctorInfoHot + numElementsHot; + +- ppHotGCStaticsMTs = (totalBoxedStatics != 0) ? new FixupPointer<PTR_MethodTable>[totalBoxedStatics] : NULL; ++ ppHotGCStaticsMTs = (totalBoxedStatics != 0) ? new RelativeFixupPointer<PTR_MethodTable>[totalBoxedStatics] : NULL; + numHotGCStaticsMTs = totalBoxedStatics; + + DWORD iGCStaticMT = 0; +@@ -8426,7 +8428,7 @@ void ModuleCtorInfo::Save(DataImage *image, CorProfileData *profileData) + ppColdGCStaticsMTs = ppHotGCStaticsMTs + numHotGCStaticsMTs; + } + +- MethodTable* pMT = ppMT[i]; ++ MethodTable* pMT = ppMT[i].GetValue(); + ClassCtorInfoEntry* pEntry = &cctorInfoHot[i]; + + WORD numBoxedStatics = pMT->GetNumBoxedRegularStatics(); +@@ -8456,7 +8458,7 @@ void ModuleCtorInfo::Save(DataImage *image, CorProfileData *profileData) + == (iGCStaticMT - pEntry->firstBoxedStaticMTIndex) * sizeof(MethodTable*)); + + TypeHandle th = pField->GetFieldTypeHandleThrowing(); +- ppHotGCStaticsMTs[iGCStaticMT++].SetValue(th.GetMethodTable()); ++ ppHotGCStaticsMTs[iGCStaticMT++].SetValueMaybeNull(th.GetMethodTable()); + + numFoundBoxedStatics++; + } +@@ -8479,7 +8481,7 @@ void ModuleCtorInfo::Save(DataImage *image, CorProfileData *profileData) + + if (numElements > 0) + image->StoreStructure(ppMT, +- sizeof(MethodTable *) * numElements, ++ sizeof(RelativePointer<MethodTable *>) * numElements, + DataImage::ITEM_MODULE_CCTOR_INFO_HOT); + + if (numElements > numElementsHot) +@@ -8496,7 +8498,7 @@ void ModuleCtorInfo::Save(DataImage *image, CorProfileData *profileData) + if ( numHotGCStaticsMTs ) + { + // Save the mt templates +- image->StoreStructure( ppHotGCStaticsMTs, numHotGCStaticsMTs * sizeof(MethodTable*), ++ image->StoreStructure( ppHotGCStaticsMTs, numHotGCStaticsMTs * sizeof(RelativeFixupPointer<MethodTable*>), + DataImage::ITEM_GC_STATIC_HANDLES_HOT); + } + else +@@ -8507,7 +8509,7 @@ void ModuleCtorInfo::Save(DataImage *image, CorProfileData *profileData) + if ( numColdGCStaticsMTs ) + { + // Save the hot mt templates +- image->StoreStructure( ppColdGCStaticsMTs, numColdGCStaticsMTs * sizeof(MethodTable*), ++ image->StoreStructure( ppColdGCStaticsMTs, numColdGCStaticsMTs * sizeof(RelativeFixupPointer<MethodTable*>), + DataImage::ITEM_GC_STATIC_HANDLES_COLD); + } + else +@@ -8516,6 +8518,7 @@ void ModuleCtorInfo::Save(DataImage *image, CorProfileData *profileData) + } + } + ++#endif // !DACCESS_COMPILE + + bool Module::AreAllClassesFullyLoaded() + { +@@ -9658,7 +9661,7 @@ void ModuleCtorInfo::Fixup(DataImage *image) + + for (DWORD i=0; i<numElements; i++) + { +- image->FixupPointerField(ppMT, i * sizeof(ppMT[0])); ++ image->FixupRelativePointerField(ppMT, i * sizeof(ppMT[0])); + } + } + else +@@ -14064,7 +14067,7 @@ ModuleCtorInfo::EnumMemoryRegions(CLRDataEnumMemoryFlags flags) + + // This class is contained so do not enumerate 'this'. + DacEnumMemoryRegion(dac_cast<TADDR>(ppMT), numElements * +- sizeof(TADDR)); ++ sizeof(RelativePointer<MethodTable *>)); + DacEnumMemoryRegion(dac_cast<TADDR>(cctorInfoHot), numElementsHot * + sizeof(ClassCtorInfoEntry)); + DacEnumMemoryRegion(dac_cast<TADDR>(cctorInfoCold), +diff --git a/src/vm/ceeload.h b/src/vm/ceeload.h +index fa61089..e82f279 100644 +--- a/src/vm/ceeload.h ++++ b/src/vm/ceeload.h +@@ -620,7 +620,7 @@ struct ModuleCtorInfo + DWORD numElements; + DWORD numLastAllocated; + DWORD numElementsHot; +- DPTR(PTR_MethodTable) ppMT; // size is numElements ++ DPTR(RelativePointer<PTR_MethodTable>) ppMT; // size is numElements + PTR_ClassCtorInfoEntry cctorInfoHot; // size is numElementsHot + PTR_ClassCtorInfoEntry cctorInfoCold; // size is numElements-numElementsHot + +@@ -629,8 +629,8 @@ struct ModuleCtorInfo + DWORD numHotHashes; + DWORD numColdHashes; + +- ArrayDPTR(FixupPointer<PTR_MethodTable>) ppHotGCStaticsMTs; // hot table +- ArrayDPTR(FixupPointer<PTR_MethodTable>) ppColdGCStaticsMTs; // cold table ++ ArrayDPTR(RelativeFixupPointer<PTR_MethodTable>) ppHotGCStaticsMTs; // hot table ++ ArrayDPTR(RelativeFixupPointer<PTR_MethodTable>) ppColdGCStaticsMTs; // cold table + + DWORD numHotGCStaticsMTs; + DWORD numColdGCStaticsMTs; +@@ -666,7 +666,13 @@ struct ModuleCtorInfo + return hashVal; + }; + +- ArrayDPTR(FixupPointer<PTR_MethodTable>) GetGCStaticMTs(DWORD index); ++ ArrayDPTR(RelativeFixupPointer<PTR_MethodTable>) GetGCStaticMTs(DWORD index); ++ ++ PTR_MethodTable GetMT(DWORD i) ++ { ++ LIMITED_METHOD_DAC_CONTRACT; ++ return ppMT[i].GetValue(dac_cast<TADDR>(ppMT) + i * sizeof(RelativePointer<PTR_MethodTable>)); ++ } + + #ifdef FEATURE_PREJIT + +@@ -677,11 +683,11 @@ struct ModuleCtorInfo + class ClassCtorInfoEntryArraySort : public CQuickSort<DWORD> + { + private: +- PTR_MethodTable *m_pBase1; ++ DPTR(RelativePointer<PTR_MethodTable>) m_pBase1; + + public: + //Constructor +- ClassCtorInfoEntryArraySort(DWORD *base, PTR_MethodTable *base1, int count) ++ ClassCtorInfoEntryArraySort(DWORD *base, DPTR(RelativePointer<PTR_MethodTable>) base1, int count) + : CQuickSort<DWORD>(base, count) + { + WRAPPER_NO_CONTRACT; +@@ -702,6 +708,7 @@ struct ModuleCtorInfo + return 1; + } + ++#ifndef DACCESS_COMPILE + // Swap is overwriten so that we can sort both the MethodTable pointer + // array and the ClassCtorInfoEntry array in parrallel. + FORCEINLINE void Swap(SSIZE_T iFirst, SSIZE_T iSecond) +@@ -717,10 +724,11 @@ struct ModuleCtorInfo + m_pBase[iFirst] = m_pBase[iSecond]; + m_pBase[iSecond] = sTemp; + +- sTemp1 = m_pBase1[iFirst]; +- m_pBase1[iFirst] = m_pBase1[iSecond]; +- m_pBase1[iSecond] = sTemp1; ++ sTemp1 = m_pBase1[iFirst].GetValueMaybeNull(); ++ m_pBase1[iFirst].SetValueMaybeNull(m_pBase1[iSecond].GetValueMaybeNull()); ++ m_pBase1[iSecond].SetValueMaybeNull(sTemp1); + } ++#endif // !DACCESS_COMPILE + }; + #endif // FEATURE_PREJIT + }; +diff --git a/src/vm/dataimage.h b/src/vm/dataimage.h +index 5d48a71..0167ec5 100644 +--- a/src/vm/dataimage.h ++++ b/src/vm/dataimage.h +@@ -309,8 +309,58 @@ public: + void FixupPointerField(PVOID p, SSIZE_T offset); + void FixupRelativePointerField(PVOID p, SSIZE_T offset); + ++ template<typename T, typename PT> ++ void FixupPlainOrRelativePointerField(const T *base, const RelativePointer<PT> T::* pPointerFieldMember) ++ { ++ STANDARD_VM_CONTRACT; ++ SSIZE_T offset = (SSIZE_T) &(base->*pPointerFieldMember) - (SSIZE_T) base; ++ FixupRelativePointerField((PVOID)base, offset); ++ } ++ ++ template<typename T, typename C, typename PT> ++ void FixupPlainOrRelativePointerField(const T *base, const C T::* pFirstPointerFieldMember, const RelativePointer<PT> C::* pSecondPointerFieldMember) ++ { ++ STANDARD_VM_CONTRACT; ++ const RelativePointer<PT> *ptr = &(base->*pFirstPointerFieldMember.*pSecondPointerFieldMember); ++ SSIZE_T offset = (SSIZE_T) ptr - (SSIZE_T) base; ++ FixupRelativePointerField((PVOID)base, offset); ++ } ++ ++ template<typename T, typename PT> ++ void FixupPlainOrRelativePointerField(const T *base, const PlainPointer<PT> T::* pPointerFieldMember) ++ { ++ STANDARD_VM_CONTRACT; ++ SSIZE_T offset = (SSIZE_T) &(base->*pPointerFieldMember) - (SSIZE_T) base; ++ FixupPointerField((PVOID)base, offset); ++ } ++ ++ template<typename T, typename C, typename PT> ++ void FixupPlainOrRelativePointerField(const T *base, const C T::* pFirstPointerFieldMember, const PlainPointer<PT> C::* pSecondPointerFieldMember) ++ { ++ STANDARD_VM_CONTRACT; ++ const PlainPointer<PT> *ptr = &(base->*pFirstPointerFieldMember.*pSecondPointerFieldMember); ++ SSIZE_T offset = (SSIZE_T) ptr - (SSIZE_T) base; ++ FixupPointerField((PVOID)base, offset); ++ } ++ + void FixupField(PVOID p, SSIZE_T offset, PVOID pTarget, SSIZE_T targetOffset = 0, ZapRelocationType type = IMAGE_REL_BASED_PTR); + ++ template<typename T, typename PT> ++ void FixupPlainOrRelativeField(const T *base, const RelativePointer<PT> T::* pPointerFieldMember, PVOID pTarget, SSIZE_T targetOffset = 0) ++ { ++ STANDARD_VM_CONTRACT; ++ SSIZE_T offset = (SSIZE_T) &(base->*pPointerFieldMember) - (SSIZE_T) base; ++ FixupField((PVOID)base, offset, pTarget, targetOffset, IMAGE_REL_BASED_RELPTR); ++ } ++ ++ template<typename T, typename PT> ++ void FixupPlainOrRelativeField(const T *base, const PlainPointer<PT> T::* pPointerFieldMember, PVOID pTarget, SSIZE_T targetOffset = 0) ++ { ++ STANDARD_VM_CONTRACT; ++ SSIZE_T offset = (SSIZE_T) &(base->*pPointerFieldMember) - (SSIZE_T) base; ++ FixupField((PVOID)base, offset, pTarget, targetOffset, IMAGE_REL_BASED_PTR); ++ } ++ + void FixupFieldToNode(PVOID p, SSIZE_T offset, ZapNode * pTarget, SSIZE_T targetOffset = 0, ZapRelocationType type = IMAGE_REL_BASED_PTR); + + void FixupFieldToNode(PVOID p, SSIZE_T offset, ZapStoredStructure * pTarget, SSIZE_T targetOffset = 0, ZapRelocationType type = IMAGE_REL_BASED_PTR) +@@ -318,6 +368,34 @@ public: + return FixupFieldToNode(p, offset, (ZapNode *)pTarget, targetOffset, type); + } + ++ template<typename T, typename PT> ++ void FixupPlainOrRelativeFieldToNode(const T *base, const RelativePointer<PT> T::* pPointerFieldMember, ZapNode * pTarget, SSIZE_T targetOffset = 0) ++ { ++ STANDARD_VM_CONTRACT; ++ SSIZE_T offset = (SSIZE_T) &(base->*pPointerFieldMember) - (SSIZE_T) base; ++ FixupFieldToNode((PVOID)base, offset, pTarget, targetOffset, IMAGE_REL_BASED_RELPTR); ++ } ++ ++ template<typename T, typename PT> ++ void FixupPlainOrRelativeFieldToNode(const T *base, const RelativePointer<PT> T::* pPointerFieldMember, ZapStoredStructure * pTarget, SSIZE_T targetOffset = 0) ++ { ++ return FixupPlainOrRelativeFieldToNode(base, pPointerFieldMember, (ZapNode *)pTarget, targetOffset); ++ } ++ ++ template<typename T, typename PT> ++ void FixupPlainOrRelativeFieldToNode(const T *base, const PlainPointer<PT> T::* pPointerFieldMember, ZapNode * pTarget, SSIZE_T targetOffset = 0) ++ { ++ STANDARD_VM_CONTRACT; ++ SSIZE_T offset = (SSIZE_T) &(base->*pPointerFieldMember) - (SSIZE_T) base; ++ FixupFieldToNode((PVOID)base, offset, pTarget, targetOffset, IMAGE_REL_BASED_PTR); ++ } ++ ++ template<typename T, typename PT> ++ void FixupPlainOrRelativeFieldToNode(const T *base, const PlainPointer<PT> T::* pPointerFieldMember, ZapStoredStructure * pTarget, SSIZE_T targetOffset = 0) ++ { ++ return FixupPlainOrRelativeFieldToNode(base, pPointerFieldMember, (ZapNode *)pTarget, targetOffset); ++ } ++ + BOOL IsStored(const void *data) + { WRAPPER_NO_CONTRACT; return m_structures.LookupPtr(data) != NULL; } + +diff --git a/src/vm/methodtable.cpp b/src/vm/methodtable.cpp +index 598759a..e219bb7 100644 +--- a/src/vm/methodtable.cpp ++++ b/src/vm/methodtable.cpp +@@ -1014,7 +1014,7 @@ void MethodTable::SetInterfaceMap(WORD wNumInterfaces, InterfaceInfo_t* iMap) + m_wNumInterfaces = wNumInterfaces; + + CONSISTENCY_CHECK(IS_ALIGNED(iMap, sizeof(void*))); +- m_pInterfaceMap = iMap; ++ m_pInterfaceMap.SetValue(iMap); + } + + //========================================================================================== +@@ -1247,7 +1247,8 @@ void MethodTable::AddDynamicInterface(MethodTable *pItfMT) + *(((DWORD_PTR *)pNewItfMap) - 1) = NumDynAddedInterfaces + 1; + + // Switch the old interface map with the new one. +- VolatileStore(EnsureWritablePages(&m_pInterfaceMap), pNewItfMap); ++ EnsureWritablePages(&m_pInterfaceMap); ++ m_pInterfaceMap.SetValueVolatile(pNewItfMap); + + // Log the fact that we leaked the interface vtable map. + #ifdef _DEBUG +@@ -1288,7 +1289,7 @@ void MethodTable::SetupGenericsStaticsInfo(FieldDesc* pStaticFieldDescs) + pInfo->m_DynamicTypeID = (SIZE_T)-1; + } + +- pInfo->m_pFieldDescs = pStaticFieldDescs; ++ pInfo->m_pFieldDescs.SetValueMaybeNull(pStaticFieldDescs); + } + + #endif // !DACCESS_COMPILE +@@ -3148,7 +3149,7 @@ void MethodTable::AllocateRegularStaticBoxes() + OBJECTREF* pStaticSlots = (OBJECTREF*)(pStaticBase + pClassCtorInfoEntry->firstBoxedStaticOffset); + GCPROTECT_BEGININTERIOR(pStaticSlots); + +- ArrayDPTR(FixupPointer<PTR_MethodTable>) ppMTs = GetLoaderModule()->GetZapModuleCtorInfo()-> ++ ArrayDPTR(RelativeFixupPointer<PTR_MethodTable>) ppMTs = GetLoaderModule()->GetZapModuleCtorInfo()-> + GetGCStaticMTs(pClassCtorInfoEntry->firstBoxedStaticMTIndex); + + DWORD numBoxedStatics = pClassCtorInfoEntry->numBoxedStatics; +@@ -4123,7 +4124,7 @@ void ModuleCtorInfo::AddElement(MethodTable *pMethodTable) + { + _ASSERTE(numElements == numLastAllocated); + +- MethodTable ** ppOldMTEntries = ppMT; ++ RelativePointer<MethodTable *> *ppOldMTEntries = ppMT; + + #ifdef _PREFAST_ + #pragma warning(push) +@@ -4134,12 +4135,19 @@ void ModuleCtorInfo::AddElement(MethodTable *pMethodTable) + #pragma warning(pop) + #endif // _PREFAST_ + +- ppMT = new MethodTable* [numNewAllocated]; ++ ppMT = new RelativePointer<MethodTable *> [numNewAllocated]; + + _ASSERTE(ppMT); + +- memcpy(ppMT, ppOldMTEntries, sizeof(MethodTable *) * numLastAllocated); +- memset(ppMT + numLastAllocated, 0, sizeof(MethodTable *) * (numNewAllocated - numLastAllocated)); ++ for (unsigned index = 0; index < numLastAllocated; ++index) ++ { ++ ppMT[index].SetValueMaybeNull(ppOldMTEntries[index].GetValueMaybeNull()); ++ } ++ ++ for (unsigned index = numLastAllocated; index < numNewAllocated; ++index) ++ { ++ ppMT[index].SetValueMaybeNull(NULL); ++ } + + delete[] ppOldMTEntries; + +@@ -4151,7 +4159,7 @@ void ModuleCtorInfo::AddElement(MethodTable *pMethodTable) + // Note the use of two "parallel" arrays. We do this to keep the workingset smaller since we + // often search (in GetClassCtorInfoIfExists) for a methodtable pointer but never actually find it. + +- ppMT[numElements] = pMethodTable; ++ ppMT[numElements].SetValue(pMethodTable); + numElements++; + } + +@@ -4691,7 +4699,7 @@ void MethodTable::Fixup(DataImage *image) + if (IsCanonicalMethodTable()) + { + // Pointer to EEClass +- image->FixupPointerField(this, offsetof(MethodTable, m_pEEClass)); ++ image->FixupPlainOrRelativePointerField(this, &MethodTable::m_pEEClass); + } + else + { +@@ -4706,7 +4714,7 @@ void MethodTable::Fixup(DataImage *image) + if (image->CanHardBindToZapModule(pCanonMT->GetLoaderModule())) + { + // Pointer to canonical methodtable +- image->FixupField(this, offsetof(MethodTable, m_pCanonMT), pCanonMT, UNION_METHODTABLE); ++ image->FixupPlainOrRelativeField(this, &MethodTable::m_pCanonMT, pCanonMT, UNION_METHODTABLE); + } + else + { +@@ -4724,11 +4732,11 @@ void MethodTable::Fixup(DataImage *image) + + if (pImport != NULL) + { +- image->FixupFieldToNode(this, offsetof(MethodTable, m_pCanonMT), pImport, UNION_INDIRECTION); ++ image->FixupPlainOrRelativeFieldToNode(this, &MethodTable::m_pCanonMT, pImport, UNION_INDIRECTION); + } + } + +- image->FixupField(this, offsetof(MethodTable, m_pLoaderModule), pZapModule); ++ image->FixupField(this, offsetof(MethodTable, m_pLoaderModule), pZapModule, 0, IMAGE_REL_BASED_RELPTR); + + #ifdef _DEBUG + image->FixupPointerField(this, offsetof(MethodTable, debug_m_szClassName)); +@@ -4797,7 +4805,7 @@ void MethodTable::Fixup(DataImage *image) + + if (HasInterfaceMap()) + { +- image->FixupPointerField(this, offsetof(MethodTable, m_pMultipurposeSlot2)); ++ image->FixupPlainOrRelativePointerField(this, &MethodTable::m_pInterfaceMap); + + FixupExtraInterfaceInfo(image); + } +@@ -5033,7 +5041,7 @@ void MethodTable::Fixup(DataImage *image) + { + GenericsStaticsInfo *pInfo = GetGenericsStaticsInfo(); + +- image->FixupPointerField(this, (BYTE *)&pInfo->m_pFieldDescs - (BYTE *)this); ++ image->FixupRelativePointerField(this, (BYTE *)&pInfo->m_pFieldDescs - (BYTE *)this); + if (!isCanonical) + { + for (DWORD i = 0; i < GetClass()->GetNumStaticFields(); i++) +@@ -5950,9 +5958,9 @@ void MethodTable::DoRestoreTypeKey() + + // If we have an indirection cell then restore the m_pCanonMT and its module pointer + // +- if (union_getLowBits(m_pCanonMT) == UNION_INDIRECTION) ++ if (union_getLowBits(m_pCanonMT.GetValue()) == UNION_INDIRECTION) + { +- Module::RestoreMethodTablePointerRaw((MethodTable **)(union_getPointer(m_pCanonMT)), ++ Module::RestoreMethodTablePointerRaw((MethodTable **)(union_getPointer(m_pCanonMT.GetValue())), + GetLoaderModule(), CLASS_LOAD_UNRESTORED); + } + +@@ -7593,7 +7601,7 @@ BOOL MethodTable::SanityCheck() + // strings have component size2, all other non-arrays should have 0 + _ASSERTE((GetComponentSize() <= 2) || IsArray()); + +- if (m_pEEClass == NULL) ++ if (m_pEEClass.IsNull()) + { + if (IsAsyncPinType()) + { +@@ -7733,7 +7741,7 @@ ClassCtorInfoEntry* MethodTable::GetClassCtorInfoIfExists() + if (HasBoxedRegularStatics()) + { + ModuleCtorInfo *pModuleCtorInfo = GetZapModule()->GetZapModuleCtorInfo(); +- DPTR(PTR_MethodTable) ppMT = pModuleCtorInfo->ppMT; ++ DPTR(RelativePointer<PTR_MethodTable>) ppMT = pModuleCtorInfo->ppMT; + PTR_DWORD hotHashOffsets = pModuleCtorInfo->hotHashOffsets; + PTR_DWORD coldHashOffsets = pModuleCtorInfo->coldHashOffsets; + +@@ -7744,8 +7752,8 @@ ClassCtorInfoEntry* MethodTable::GetClassCtorInfoIfExists() + + for (DWORD i = hotHashOffsets[hash]; i != hotHashOffsets[hash + 1]; i++) + { +- _ASSERTE(ppMT[i]); +- if (dac_cast<TADDR>(ppMT[i]) == dac_cast<TADDR>(this)) ++ _ASSERTE(!ppMT[i].IsNull()); ++ if (dac_cast<TADDR>(pModuleCtorInfo->GetMT(i)) == dac_cast<TADDR>(this)) + { + return pModuleCtorInfo->cctorInfoHot + i; + } +@@ -7759,8 +7767,8 @@ ClassCtorInfoEntry* MethodTable::GetClassCtorInfoIfExists() + + for (DWORD i = coldHashOffsets[hash]; i != coldHashOffsets[hash + 1]; i++) + { +- _ASSERTE(ppMT[i]); +- if (dac_cast<TADDR>(ppMT[i]) == dac_cast<TADDR>(this)) ++ _ASSERTE(!ppMT[i].IsNull()); ++ if (dac_cast<TADDR>(pModuleCtorInfo->GetMT(i)) == dac_cast<TADDR>(this)) + { + return pModuleCtorInfo->cctorInfoCold + (i - pModuleCtorInfo->numElementsHot); + } +diff --git a/src/vm/methodtable.h b/src/vm/methodtable.h +index 93a9ae2..f8b34ae 100644 +--- a/src/vm/methodtable.h ++++ b/src/vm/methodtable.h +@@ -248,7 +248,7 @@ typedef DPTR(GenericsDictInfo) PTR_GenericsDictInfo; + struct GenericsStaticsInfo + { + // Pointer to field descs for statics +- PTR_FieldDesc m_pFieldDescs; ++ RelativePointer<PTR_FieldDesc> m_pFieldDescs; + + // Method table ID for statics + SIZE_T m_DynamicTypeID; +@@ -2210,12 +2210,12 @@ public: + inline void SetClass(EEClass *pClass) + { + LIMITED_METHOD_CONTRACT; +- m_pEEClass = pClass; ++ m_pEEClass.SetValue(pClass); + } + + inline void SetCanonicalMethodTable(MethodTable * pMT) + { +- m_pCanonMT = (TADDR)pMT | MethodTable::UNION_METHODTABLE; ++ m_pCanonMT.SetValue((TADDR)pMT | MethodTable::UNION_METHODTABLE); + } + #endif + +@@ -2640,7 +2640,7 @@ public: + { + WRAPPER_NO_CONTRACT; + _ASSERTE(HasGenericsStaticsInfo()); +- return GetGenericsStaticsInfo()->m_pFieldDescs; ++ return ReadPointerMaybeNull((GenericsStaticsInfo *)GetGenericsStaticsInfo(), &GenericsStaticsInfo::m_pFieldDescs); + } + + BOOL HasCrossModuleGenericStaticsInfo() +@@ -4059,7 +4059,7 @@ private: + // for enum_flag_HasIndirectParentMethodTable. + TADDR m_pParentMethodTable; + +- PTR_Module m_pLoaderModule; // LoaderModule. It is equal to the ZapModule in ngened images ++ RelativePointer<PTR_Module> m_pLoaderModule; // LoaderModule. It is equal to the ZapModule in ngened images + + PTR_MethodTableWriteableData m_pWriteableData; + +@@ -4073,8 +4073,13 @@ private: + static const TADDR UNION_MASK = 3; + + union { +- EEClass * m_pEEClass; +- TADDR m_pCanonMT; ++#if defined(PLATFORM_UNIX) && defined(_TARGET_ARM_) ++ RelativePointer<DPTR(EEClass)> m_pEEClass; ++ RelativePointer<TADDR> m_pCanonMT; ++#else ++ PlainPointer<DPTR(EEClass)> m_pEEClass; ++ PlainPointer<TADDR> m_pCanonMT; ++#endif + }; + + __forceinline static LowBits union_getLowBits(TADDR pCanonMT) +@@ -4103,7 +4108,11 @@ private: + public: + union + { +- InterfaceInfo_t * m_pInterfaceMap; ++#if defined(PLATFORM_UNIX) && defined(_TARGET_ARM_) ++ RelativePointer<PTR_InterfaceInfo> m_pInterfaceMap; ++#else ++ PlainPointer<PTR_InterfaceInfo> m_pInterfaceMap; ++#endif + TADDR m_pMultipurposeSlot2; + }; + +diff --git a/src/vm/methodtable.inl b/src/vm/methodtable.inl +index 9b72d24..eb1abb0 100644 +--- a/src/vm/methodtable.inl ++++ b/src/vm/methodtable.inl +@@ -23,24 +23,26 @@ inline PTR_EEClass MethodTable::GetClass_NoLogging() + { + LIMITED_METHOD_DAC_CONTRACT; + ++ TADDR addr = ReadPointer(this, &MethodTable::m_pCanonMT); ++ + #ifdef _DEBUG +- LowBits lowBits = union_getLowBits(m_pCanonMT); ++ LowBits lowBits = union_getLowBits(addr); + if (lowBits == UNION_EECLASS) + { +- return PTR_EEClass(m_pCanonMT); ++ return PTR_EEClass(addr); + } + else if (lowBits == UNION_METHODTABLE) + { + // pointer to canonical MethodTable. +- TADDR canonicalMethodTable = union_getPointer(m_pCanonMT); +- return PTR_EEClass(PTR_MethodTable(canonicalMethodTable)->m_pCanonMT); ++ TADDR canonicalMethodTable = union_getPointer(addr); ++ return PTR_EEClass(ReadPointer((MethodTable *) PTR_MethodTable(canonicalMethodTable), &MethodTable::m_pCanonMT)); + } + #ifdef FEATURE_PREJIT + else if (lowBits == UNION_INDIRECTION) + { + // pointer to indirection cell that points to canonical MethodTable +- TADDR canonicalMethodTable = *PTR_TADDR(union_getPointer(m_pCanonMT)); +- return PTR_EEClass(PTR_MethodTable(canonicalMethodTable)->m_pCanonMT); ++ TADDR canonicalMethodTable = *PTR_TADDR(union_getPointer(addr)); ++ return PTR_EEClass(ReadPointer((MethodTable *) PTR_MethodTable(canonicalMethodTable), &MethodTable::m_pCanonMT)); + } + #endif + #ifdef DACCESS_COMPILE +@@ -52,8 +54,6 @@ inline PTR_EEClass MethodTable::GetClass_NoLogging() + + #else + +- TADDR addr = m_pCanonMT; +- + if ((addr & 2) == 0) + { + // pointer to EEClass +@@ -65,12 +65,12 @@ inline PTR_EEClass MethodTable::GetClass_NoLogging() + { + // pointer to indirection cell that points to canonical MethodTable + TADDR canonicalMethodTable = *PTR_TADDR(addr - 3); +- return PTR_EEClass(PTR_MethodTable(canonicalMethodTable)->m_pCanonMT); ++ return PTR_EEClass(ReadPointer((MethodTable *) PTR_MethodTable(canonicalMethodTable), &MethodTable::m_pCanonMT)); + } + #endif + + // pointer to canonical MethodTable. +- return PTR_EEClass(PTR_MethodTable(addr - 2)->m_pCanonMT); ++ return PTR_EEClass(ReadPointer((MethodTable *) PTR_MethodTable(addr - 2), &MethodTable::m_pCanonMT)); + #endif + } + +@@ -113,25 +113,27 @@ inline BOOL MethodTable::IsClassPointerValid() + WRAPPER_NO_CONTRACT; + SUPPORTS_DAC; + +- LowBits lowBits = union_getLowBits(m_pCanonMT); ++ TADDR addr = ReadPointer(this, &MethodTable::m_pCanonMT); ++ ++ LowBits lowBits = union_getLowBits(addr); + if (lowBits == UNION_EECLASS) + { +- return (m_pEEClass != NULL); ++ return !m_pEEClass.IsNull(); + } + else if (lowBits == UNION_METHODTABLE) + { + // pointer to canonical MethodTable. +- TADDR canonicalMethodTable = union_getPointer(m_pCanonMT); +- return (PTR_MethodTable(canonicalMethodTable)->m_pEEClass != NULL); ++ TADDR canonicalMethodTable = union_getPointer(addr); ++ return !PTR_MethodTable(canonicalMethodTable)->m_pEEClass.IsNull(); + } + #ifdef FEATURE_PREJIT + else if (lowBits == UNION_INDIRECTION) + { + // pointer to indirection cell that points to canonical MethodTable +- TADDR canonicalMethodTable = *PTR_TADDR(union_getPointer(m_pCanonMT)); ++ TADDR canonicalMethodTable = *PTR_TADDR(union_getPointer(addr)); + if (CORCOMPILE_IS_POINTER_TAGGED(canonicalMethodTable)) + return FALSE; +- return (PTR_MethodTable(canonicalMethodTable)->m_pEEClass != NULL); ++ return !PTR_MethodTable(canonicalMethodTable)->m_pEEClass.IsNull(); + } + #endif + _ASSERTE(!"Malformed m_pEEClass in MethodTable"); +@@ -161,7 +163,7 @@ inline PTR_Module MethodTable::GetZapModule() + PTR_Module zapModule = NULL; + if (IsZapped()) + { +- zapModule = m_pLoaderModule; ++ zapModule = ReadPointer(this, &MethodTable::m_pLoaderModule); + } + + return zapModule; +@@ -171,7 +173,7 @@ inline PTR_Module MethodTable::GetZapModule() + inline PTR_Module MethodTable::GetLoaderModule() + { + LIMITED_METHOD_DAC_CONTRACT; +- return m_pLoaderModule; ++ return ReadPointer(this, &MethodTable::m_pLoaderModule); + } + + inline PTR_LoaderAllocator MethodTable::GetLoaderAllocator() +@@ -187,7 +189,7 @@ inline PTR_LoaderAllocator MethodTable::GetLoaderAllocator() + inline void MethodTable::SetLoaderModule(Module* pModule) + { + WRAPPER_NO_CONTRACT; +- m_pLoaderModule = pModule; ++ m_pLoaderModule.SetValue(pModule); + } + + inline void MethodTable::SetLoaderAllocator(LoaderAllocator* pAllocator) +@@ -1145,8 +1147,10 @@ inline PTR_MethodTable MethodTable::GetCanonicalMethodTable() + { + LIMITED_METHOD_DAC_CONTRACT; + ++ TADDR addr = ReadPointer(this, &MethodTable::m_pCanonMT); ++ + #ifdef _DEBUG +- LowBits lowBits = union_getLowBits(m_pCanonMT); ++ LowBits lowBits = union_getLowBits(addr); + if (lowBits == UNION_EECLASS) + { + return dac_cast<PTR_MethodTable>(this); +@@ -1154,18 +1158,17 @@ inline PTR_MethodTable MethodTable::GetCanonicalMethodTable() + else if (lowBits == UNION_METHODTABLE) + { + // pointer to canonical MethodTable. +- return PTR_MethodTable(union_getPointer(m_pCanonMT)); ++ return PTR_MethodTable(union_getPointer(addr)); + } + #ifdef FEATURE_PREJIT + else if (lowBits == UNION_INDIRECTION) + { +- return PTR_MethodTable(*PTR_TADDR(union_getPointer(m_pCanonMT))); ++ return PTR_MethodTable(*PTR_TADDR(union_getPointer(addr))); + } + #endif + _ASSERTE(!"Malformed m_pCanonMT in MethodTable"); + return NULL; + #else +- TADDR addr = m_pCanonMT; + + if ((addr & 2) == 0) + return dac_cast<PTR_MethodTable>(this); +@@ -1185,11 +1188,12 @@ inline TADDR MethodTable::GetCanonicalMethodTableFixup() + LIMITED_METHOD_DAC_CONTRACT; + + #ifdef FEATURE_PREJIT +- LowBits lowBits = union_getLowBits(m_pCanonMT); ++ TADDR addr = ReadPointer(this, &MethodTable::m_pCanonMT); ++ LowBits lowBits = union_getLowBits(addr); + if (lowBits == UNION_INDIRECTION) + { + // pointer to canonical MethodTable. +- return *PTR_TADDR(union_getPointer(m_pCanonMT)); ++ return *PTR_TADDR(union_getPointer(addr)); + } + else + #endif +@@ -1304,7 +1308,7 @@ inline BOOL MethodTable::IsCanonicalMethodTable() + { + LIMITED_METHOD_DAC_CONTRACT; + +- return (union_getLowBits(m_pCanonMT) == UNION_EECLASS); ++ return (union_getLowBits(ReadPointer(this, &MethodTable::m_pCanonMT)) == UNION_EECLASS); + } + + //========================================================================================== +@@ -1338,7 +1342,7 @@ inline PTR_InterfaceInfo MethodTable::GetInterfaceMap() + { + LIMITED_METHOD_DAC_CONTRACT; + +- return dac_cast<PTR_InterfaceInfo>(m_pMultipurposeSlot2); // m_pInterfaceMap ++ return ReadPointer(this, &MethodTable::m_pInterfaceMap); + } + + //========================================================================================== +-- +2.7.4 + |