From 9440822ceb7b6e58b840cfa4f4118e6410375df5 Mon Sep 17 00:00:00 2001 From: Gleb Balykov 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), 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& operator = (const RelativeFixupPointer &) =delete; RelativeFixupPointer& operator = (RelativeFixupPointer &&) =delete; + // Default constructor + RelativeFixupPointer() {} + // 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(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(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)>(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(addr); } @@ -521,7 +536,6 @@ public: m_ptr = dac_cast(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)>(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) ModuleCtorInfo::GetGCStaticMTs(DWORD index) +ArrayDPTR(RelativeFixupPointer) 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[totalBoxedStatics] : NULL; + ppHotGCStaticsMTs = (totalBoxedStatics != 0) ? new RelativeFixupPointer[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) * 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), 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), 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; iFixupPointerField(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(ppMT), numElements * - sizeof(TADDR)); + sizeof(RelativePointer)); DacEnumMemoryRegion(dac_cast(cctorInfoHot), numElementsHot * sizeof(ClassCtorInfoEntry)); DacEnumMemoryRegion(dac_cast(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) 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) ppHotGCStaticsMTs; // hot table - ArrayDPTR(FixupPointer) ppColdGCStaticsMTs; // cold table + ArrayDPTR(RelativeFixupPointer) ppHotGCStaticsMTs; // hot table + ArrayDPTR(RelativeFixupPointer) ppColdGCStaticsMTs; // cold table DWORD numHotGCStaticsMTs; DWORD numColdGCStaticsMTs; @@ -666,7 +666,13 @@ struct ModuleCtorInfo return hashVal; }; - ArrayDPTR(FixupPointer) GetGCStaticMTs(DWORD index); + ArrayDPTR(RelativeFixupPointer) GetGCStaticMTs(DWORD index); + + PTR_MethodTable GetMT(DWORD i) + { + LIMITED_METHOD_DAC_CONTRACT; + return ppMT[i].GetValue(dac_cast(ppMT) + i * sizeof(RelativePointer)); + } #ifdef FEATURE_PREJIT @@ -677,11 +683,11 @@ struct ModuleCtorInfo class ClassCtorInfoEntryArraySort : public CQuickSort { private: - PTR_MethodTable *m_pBase1; + DPTR(RelativePointer) m_pBase1; public: //Constructor - ClassCtorInfoEntryArraySort(DWORD *base, PTR_MethodTable *base1, int count) + ClassCtorInfoEntryArraySort(DWORD *base, DPTR(RelativePointer) base1, int count) : CQuickSort(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 + void FixupPlainOrRelativePointerField(const T *base, const RelativePointer T::* pPointerFieldMember) + { + STANDARD_VM_CONTRACT; + SSIZE_T offset = (SSIZE_T) &(base->*pPointerFieldMember) - (SSIZE_T) base; + FixupRelativePointerField((PVOID)base, offset); + } + + template + void FixupPlainOrRelativePointerField(const T *base, const C T::* pFirstPointerFieldMember, const RelativePointer C::* pSecondPointerFieldMember) + { + STANDARD_VM_CONTRACT; + const RelativePointer *ptr = &(base->*pFirstPointerFieldMember.*pSecondPointerFieldMember); + SSIZE_T offset = (SSIZE_T) ptr - (SSIZE_T) base; + FixupRelativePointerField((PVOID)base, offset); + } + + template + void FixupPlainOrRelativePointerField(const T *base, const PlainPointer T::* pPointerFieldMember) + { + STANDARD_VM_CONTRACT; + SSIZE_T offset = (SSIZE_T) &(base->*pPointerFieldMember) - (SSIZE_T) base; + FixupPointerField((PVOID)base, offset); + } + + template + void FixupPlainOrRelativePointerField(const T *base, const C T::* pFirstPointerFieldMember, const PlainPointer C::* pSecondPointerFieldMember) + { + STANDARD_VM_CONTRACT; + const PlainPointer *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 + void FixupPlainOrRelativeField(const T *base, const RelativePointer 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 + void FixupPlainOrRelativeField(const T *base, const PlainPointer 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 + void FixupPlainOrRelativeFieldToNode(const T *base, const RelativePointer 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 + void FixupPlainOrRelativeFieldToNode(const T *base, const RelativePointer T::* pPointerFieldMember, ZapStoredStructure * pTarget, SSIZE_T targetOffset = 0) + { + return FixupPlainOrRelativeFieldToNode(base, pPointerFieldMember, (ZapNode *)pTarget, targetOffset); + } + + template + void FixupPlainOrRelativeFieldToNode(const T *base, const PlainPointer 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 + void FixupPlainOrRelativeFieldToNode(const T *base, const PlainPointer 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) ppMTs = GetLoaderModule()->GetZapModuleCtorInfo()-> + ArrayDPTR(RelativeFixupPointer) 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 *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 [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) 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(ppMT[i]) == dac_cast(this)) + _ASSERTE(!ppMT[i].IsNull()); + if (dac_cast(pModuleCtorInfo->GetMT(i)) == dac_cast(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(ppMT[i]) == dac_cast(this)) + _ASSERTE(!ppMT[i].IsNull()); + if (dac_cast(pModuleCtorInfo->GetMT(i)) == dac_cast(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 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 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 m_pEEClass; + RelativePointer m_pCanonMT; +#else + PlainPointer m_pEEClass; + PlainPointer 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 m_pInterfaceMap; +#else + PlainPointer 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(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(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(m_pMultipurposeSlot2); // m_pInterfaceMap + return ReadPointer(this, &MethodTable::m_pInterfaceMap); } //========================================================================================== -- 2.7.4