From cb61d565def2fc2c303e7b7c567c6ea8a554175f Mon Sep 17 00:00:00 2001 From: Gleb Balykov Date: Wed, 21 Jun 2017 19:48:49 +0300 Subject: [PATCH] Remove relocations from SECTION_Readonly for fields not accessed from jit code on ARM Commit migrated from https://github.com/dotnet/coreclr/commit/b4786838985ca249cca04a7d0676ae57ee61ca2b --- src/coreclr/src/debug/daccess/nidump.cpp | 6 +-- src/coreclr/src/inc/fixuppointer.h | 28 ++++++++++-- src/coreclr/src/vm/ceeload.cpp | 31 +++++++------ src/coreclr/src/vm/ceeload.h | 26 +++++++---- src/coreclr/src/vm/dataimage.h | 78 ++++++++++++++++++++++++++++++++ src/coreclr/src/vm/methodtable.cpp | 54 ++++++++++++---------- src/coreclr/src/vm/methodtable.h | 25 ++++++---- src/coreclr/src/vm/methodtable.inl | 58 +++++++++++++----------- 8 files changed, 218 insertions(+), 88 deletions(-) diff --git a/src/coreclr/src/debug/daccess/nidump.cpp b/src/coreclr/src/debug/daccess/nidump.cpp index cd5ba83..67a19cf 100644 --- a/src/coreclr/src/debug/daccess/nidump.cpp +++ b/src/coreclr/src/debug/daccess/nidump.cpp @@ -3947,7 +3947,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 @@ -7259,7 +7259,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 ) @@ -7293,7 +7293,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/coreclr/src/inc/fixuppointer.h b/src/coreclr/src/inc/fixuppointer.h index 83ff20e..20eb9d8 100644 --- a/src/coreclr/src/inc/fixuppointer.h +++ b/src/coreclr/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/coreclr/src/vm/ceeload.cpp b/src/coreclr/src/vm/ceeload.cpp index 49068fc..857c67e 100644 --- a/src/coreclr/src/vm/ceeload.cpp +++ b/src/coreclr/src/vm/ceeload.cpp @@ -2883,7 +2883,7 @@ BOOL Module::IsPreV4Assembly() } -ArrayDPTR(FixupPointer) ModuleCtorInfo::GetGCStaticMTs(DWORD index) +ArrayDPTR(RelativeFixupPointer) ModuleCtorInfo::GetGCStaticMTs(DWORD index) { LIMITED_METHOD_CONTRACT; @@ -8252,6 +8252,8 @@ void Module::SaveTypeHandle(DataImage * image, #endif // _DEBUG } +#ifndef DACCESS_COMPILE + void ModuleCtorInfo::Save(DataImage *image, CorProfileData *profileData) { STANDARD_VM_CONTRACT; @@ -8273,7 +8275,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(); @@ -8287,8 +8289,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++; } @@ -8313,11 +8315,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. @@ -8380,7 +8382,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; @@ -8396,7 +8398,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(); @@ -8426,7 +8428,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++; } @@ -8449,7 +8451,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) @@ -8466,7 +8468,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 @@ -8477,7 +8479,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 @@ -8486,6 +8488,7 @@ void ModuleCtorInfo::Save(DataImage *image, CorProfileData *profileData) } } +#endif // !DACCESS_COMPILE bool Module::AreAllClassesFullyLoaded() { @@ -9622,7 +9625,7 @@ void ModuleCtorInfo::Fixup(DataImage *image) for (DWORD i=0; iFixupPointerField(ppMT, i * sizeof(ppMT[0])); + image->FixupRelativePointerField(ppMT, i * sizeof(ppMT[0])); } } else @@ -14018,7 +14021,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/coreclr/src/vm/ceeload.h b/src/coreclr/src/vm/ceeload.h index 0896c9b..15d7959 100644 --- a/src/coreclr/src/vm/ceeload.h +++ b/src/coreclr/src/vm/ceeload.h @@ -618,7 +618,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 @@ -627,8 +627,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; @@ -664,7 +664,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 @@ -675,11 +681,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; @@ -700,6 +706,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) @@ -715,10 +722,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/coreclr/src/vm/dataimage.h b/src/coreclr/src/vm/dataimage.h index 5d48a71..0167ec5 100644 --- a/src/coreclr/src/vm/dataimage.h +++ b/src/coreclr/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/coreclr/src/vm/methodtable.cpp b/src/coreclr/src/vm/methodtable.cpp index 66a6a2e..4a29684 100644 --- a/src/coreclr/src/vm/methodtable.cpp +++ b/src/coreclr/src/vm/methodtable.cpp @@ -1013,7 +1013,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); } //========================================================================================== @@ -1246,7 +1246,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 @@ -1287,7 +1288,7 @@ void MethodTable::SetupGenericsStaticsInfo(FieldDesc* pStaticFieldDescs) pInfo->m_DynamicTypeID = (SIZE_T)-1; } - pInfo->m_pFieldDescs = pStaticFieldDescs; + pInfo->m_pFieldDescs.SetValueMaybeNull(pStaticFieldDescs); } #endif // !DACCESS_COMPILE @@ -3147,7 +3148,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; @@ -4122,7 +4123,7 @@ void ModuleCtorInfo::AddElement(MethodTable *pMethodTable) { _ASSERTE(numElements == numLastAllocated); - MethodTable ** ppOldMTEntries = ppMT; + RelativePointer *ppOldMTEntries = ppMT; #ifdef _PREFAST_ #pragma warning(push) @@ -4133,12 +4134,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; @@ -4150,7 +4158,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++; } @@ -4694,7 +4702,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 { @@ -4709,7 +4717,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 { @@ -4727,11 +4735,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)); @@ -4800,7 +4808,7 @@ void MethodTable::Fixup(DataImage *image) if (HasInterfaceMap()) { - image->FixupPointerField(this, offsetof(MethodTable, m_pMultipurposeSlot2)); + image->FixupPlainOrRelativePointerField(this, &MethodTable::m_pInterfaceMap); FixupExtraInterfaceInfo(image); } @@ -5036,7 +5044,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++) @@ -5953,9 +5961,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); } @@ -7596,7 +7604,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()) { @@ -7736,7 +7744,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; @@ -7747,8 +7755,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; } @@ -7762,8 +7770,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/coreclr/src/vm/methodtable.h b/src/coreclr/src/vm/methodtable.h index d3eb0ce..fcc9779 100644 --- a/src/coreclr/src/vm/methodtable.h +++ b/src/coreclr/src/vm/methodtable.h @@ -247,7 +247,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; @@ -2209,12 +2209,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 @@ -2639,7 +2639,7 @@ public: { WRAPPER_NO_CONTRACT; _ASSERTE(HasGenericsStaticsInfo()); - return GetGenericsStaticsInfo()->m_pFieldDescs; + return ReadPointerMaybeNull((GenericsStaticsInfo *)GetGenericsStaticsInfo(), &GenericsStaticsInfo::m_pFieldDescs); } BOOL HasCrossModuleGenericStaticsInfo() @@ -4044,7 +4044,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; @@ -4058,8 +4058,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) @@ -4088,7 +4093,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/coreclr/src/vm/methodtable.inl b/src/coreclr/src/vm/methodtable.inl index 9b72d24..eb1abb0 100644 --- a/src/coreclr/src/vm/methodtable.inl +++ b/src/coreclr/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