From fbde4535e72a88b02c20bb9d24b9b9215fe50adf Mon Sep 17 00:00:00 2001 From: Gleb Balykov Date: Thu, 22 Jun 2017 20:24:54 +0300 Subject: [PATCH] Remove relocations for InterfaceInfo_t::m_pMethodTable for Linux ARM Commit migrated from https://github.com/dotnet/coreclr/commit/e085f07a5fa0aff778ff7562a33a88513b79b3b7 --- src/coreclr/src/vm/array.cpp | 7 +++++-- src/coreclr/src/vm/methodtable.cpp | 33 +++++++++++++++++++++++++++------ src/coreclr/src/vm/methodtable.h | 23 +++++++++++++++++++---- 3 files changed, 51 insertions(+), 12 deletions(-) diff --git a/src/coreclr/src/vm/array.cpp b/src/coreclr/src/vm/array.cpp index d679294..3f5a8aa 100644 --- a/src/coreclr/src/vm/array.cpp +++ b/src/coreclr/src/vm/array.cpp @@ -509,8 +509,11 @@ MethodTable* Module::CreateArrayMethodTable(TypeHandle elemTypeHnd, CorElementTy #endif // !defined(_WIN64) && (DATA_ALIGNMENT > 4) pMT->SetBaseSize(baseSize); // Because of array method table persisting, we need to copy the map - memcpy(pMTHead + imapOffset, pParentClass->GetInterfaceMap(), - pParentClass->GetNumInterfaces() * sizeof(InterfaceInfo_t)); + for (unsigned index = 0; index < pParentClass->GetNumInterfaces(); ++index) + { + InterfaceInfo_t *pIntInfo = (InterfaceInfo_t *) (pMTHead + imapOffset + index * sizeof(InterfaceInfo_t)); + pIntInfo->SetMethodTable((pParentClass->GetInterfaceMap() + index)->GetMethodTable()); + } pMT->SetInterfaceMap(pParentClass->GetNumInterfaces(), (InterfaceInfo_t *)(pMTHead + imapOffset)); // Copy down flags for these interfaces as well. This is simplified a bit since we know that System.Array diff --git a/src/coreclr/src/vm/methodtable.cpp b/src/coreclr/src/vm/methodtable.cpp index 4a29684..567f2b6 100644 --- a/src/coreclr/src/vm/methodtable.cpp +++ b/src/coreclr/src/vm/methodtable.cpp @@ -1236,7 +1236,12 @@ void MethodTable::AddDynamicInterface(MethodTable *pItfMT) if (TotalNumInterfaces > 0) { InterfaceInfo_t *pInterfaceMap = GetInterfaceMap(); PREFIX_ASSUME(pInterfaceMap != NULL); - memcpy(pNewItfMap, pInterfaceMap, TotalNumInterfaces * sizeof(InterfaceInfo_t)); + + for (unsigned index = 0; index < TotalNumInterfaces; ++index) + { + InterfaceInfo_t *pIntInfo = (InterfaceInfo_t *) (pNewItfMap + index); + pIntInfo->SetMethodTable((pInterfaceMap + index)->GetMethodTable()); + } } // Add the new interface at the end of the map. @@ -4284,16 +4289,32 @@ void MethodTable::Save(DataImage *image, DWORD profilingFlags) // Dynamic interface maps have an additional DWORD_PTR preceding the InterfaceInfo_t array if (HasDynamicInterfaceMap()) { - ZapStoredStructure * pInterfaceMapNode = image->StoreInternedStructure(((DWORD_PTR *)GetInterfaceMap()) - 1, - GetInterfaceMapSize(), - DataImage::ITEM_INTERFACE_MAP); - + ZapStoredStructure * pInterfaceMapNode; + if (decltype(InterfaceInfo_t::m_pMethodTable)::isRelative) + { + pInterfaceMapNode = image->StoreStructure(((DWORD_PTR *)GetInterfaceMap()) - 1, + GetInterfaceMapSize(), + DataImage::ITEM_INTERFACE_MAP); + } + else + { + pInterfaceMapNode = image->StoreInternedStructure(((DWORD_PTR *)GetInterfaceMap()) - 1, + GetInterfaceMapSize(), + DataImage::ITEM_INTERFACE_MAP); + } image->BindPointer(GetInterfaceMap(), pInterfaceMapNode, sizeof(DWORD_PTR)); } else #endif // FEATURE_COMINTEROP { - image->StoreInternedStructure(GetInterfaceMap(), GetInterfaceMapSize(), DataImage::ITEM_INTERFACE_MAP); + if (decltype(InterfaceInfo_t::m_pMethodTable)::isRelative) + { + image->StoreStructure(GetInterfaceMap(), GetInterfaceMapSize(), DataImage::ITEM_INTERFACE_MAP); + } + else + { + image->StoreInternedStructure(GetInterfaceMap(), GetInterfaceMapSize(), DataImage::ITEM_INTERFACE_MAP); + } } SaveExtraInterfaceInfo(image); diff --git a/src/coreclr/src/vm/methodtable.h b/src/coreclr/src/vm/methodtable.h index fcc9779..92a61f4 100644 --- a/src/coreclr/src/vm/methodtable.h +++ b/src/coreclr/src/vm/methodtable.h @@ -110,25 +110,40 @@ struct InterfaceInfo_t friend class NativeImageDumper; #endif - FixupPointer m_pMethodTable; // Method table of the interface + // Method table of the interface +#if defined(PLATFORM_UNIX) && defined(_TARGET_ARM_) + RelativeFixupPointer m_pMethodTable; +#else + FixupPointer m_pMethodTable; +#endif public: FORCEINLINE PTR_MethodTable GetMethodTable() { LIMITED_METHOD_CONTRACT; - return m_pMethodTable.GetValue(); + return ReadPointerMaybeNull(this, &InterfaceInfo_t::m_pMethodTable); } #ifndef DACCESS_COMPILE void SetMethodTable(MethodTable * pMT) { LIMITED_METHOD_CONTRACT; - m_pMethodTable.SetValue(pMT); + m_pMethodTable.SetValueMaybeNull(pMT); } // Get approximate method table. This is used by the type loader before the type is fully loaded. PTR_MethodTable GetApproxMethodTable(Module * pContainingModule); -#endif +#endif // !DACCESS_COMPILE + +#ifndef DACCESS_COMPILE + InterfaceInfo_t(InterfaceInfo_t &right) + { + m_pMethodTable.SetValueMaybeNull(right.m_pMethodTable.GetValueMaybeNull()); + } +#else // !DACCESS_COMPILE +private: + InterfaceInfo_t(InterfaceInfo_t &right); +#endif // !DACCESS_COMPILE }; // struct InterfaceInfo_t typedef DPTR(InterfaceInfo_t) PTR_InterfaceInfo; -- 2.7.4