diff options
Diffstat (limited to 'packaging/0030-Remove-relocations-for-MethodTable-m_pParentMethodTa.patch')
-rw-r--r-- | packaging/0030-Remove-relocations-for-MethodTable-m_pParentMethodTa.patch | 563 |
1 files changed, 563 insertions, 0 deletions
diff --git a/packaging/0030-Remove-relocations-for-MethodTable-m_pParentMethodTa.patch b/packaging/0030-Remove-relocations-for-MethodTable-m_pParentMethodTa.patch new file mode 100644 index 0000000000..9dae3204ee --- /dev/null +++ b/packaging/0030-Remove-relocations-for-MethodTable-m_pParentMethodTa.patch @@ -0,0 +1,563 @@ +From 52707bd377553ce6c42b1baa0b924dc7413e93ea Mon Sep 17 00:00:00 2001 +From: gbalykov <g.balykov@samsung.com> +Date: Thu, 22 Feb 2018 20:47:46 +0300 +Subject: [PATCH 30/32] Remove relocations for + MethodTable::m_pParentMethodTable for Linux ARM (#15915) + +--- + src/debug/daccess/nidump.cpp | 4 +- + src/inc/fixuppointer.h | 208 +++++++++++++++++++++++++++++++++++++++ + src/vm/class.cpp | 10 +- + src/vm/generics.cpp | 1 + + src/vm/methodtable.cpp | 35 ++++--- + src/vm/methodtable.h | 69 ++++++++++--- + src/vm/proftoeeinterfaceimpl.cpp | 2 +- + 7 files changed, 299 insertions(+), 30 deletions(-) + +diff --git a/src/debug/daccess/nidump.cpp b/src/debug/daccess/nidump.cpp +index 2732c9e..ef4725f 100644 +--- a/src/debug/daccess/nidump.cpp ++++ b/src/debug/daccess/nidump.cpp +@@ -6053,7 +6053,7 @@ PTR_MethodTable NativeImageDumper::GetParent( PTR_MethodTable mt ) + /* REVISIT_TODO Thu 12/01/2005 + * Handle fixups + */ +- PTR_MethodTable parent( mt->m_pParentMethodTable ); ++ PTR_MethodTable parent( ReadPointerMaybeNull((MethodTable*) mt, &MethodTable::m_pParentMethodTable, mt->GetFlagHasIndirectParent()) ); + _ASSERTE(!CORCOMPILE_IS_POINTER_TAGGED(PTR_TO_TADDR(parent))); + return parent; + } +@@ -7027,7 +7027,7 @@ NativeImageDumper::DumpMethodTable( PTR_MethodTable mt, const char * name, + + + +- PTR_MethodTable parent = mt->m_pParentMethodTable; ++ PTR_MethodTable parent = ReadPointerMaybeNull((MethodTable*) mt, &MethodTable::m_pParentMethodTable, mt->GetFlagHasIndirectParent()); + if( parent == NULL ) + { + DisplayWriteFieldPointer( m_pParentMethodTable, NULL, MethodTable, +diff --git a/src/inc/fixuppointer.h b/src/inc/fixuppointer.h +index a711418..5a897e4 100644 +--- a/src/inc/fixuppointer.h ++++ b/src/inc/fixuppointer.h +@@ -319,6 +319,14 @@ public: + return FALSE; + } + ++ // Returns whether the indirection cell contain fixup that has not been converted to real pointer yet. ++ // Ignores isIndirect and offset values. ++ FORCEINLINE BOOL IsTaggedIndirect(TADDR base, bool isIndirect, intptr_t offset) const ++ { ++ LIMITED_METHOD_DAC_CONTRACT; ++ return IsTagged(base); ++ } ++ + #ifndef DACCESS_COMPILE + // Returns whether the indirection cell contain fixup that has not been converted to real pointer yet. + // Does not need explicit base and thus can be used in non-DAC builds only. +@@ -358,6 +366,14 @@ public: + return dac_cast<DPTR(RelativeFixupPointer<PTR_TYPE>)>(base)->GetValue(base); + } + ++ // Static version of GetValue. It is meant to simplify access to arrays of pointers. ++ // Ignores isIndirect and offset values. ++ FORCEINLINE static PTR_TYPE GetValueAtPtrIndirect(TADDR base, bool isIndirect, intptr_t offset) ++ { ++ LIMITED_METHOD_DAC_CONTRACT; ++ return GetValueAtPtr(base); ++ } ++ + // Returns value of the encoded pointer. The pointer can be NULL. + PTR_TYPE GetValueMaybeNull(TADDR base) const + { +@@ -393,6 +409,14 @@ public: + return dac_cast<DPTR(RelativeFixupPointer<PTR_TYPE>)>(base)->GetValueMaybeNull(base); + } + ++ // Static version of GetValueMaybeNull. It is meant to simplify access to arrays of pointers. ++ // Ignores isIndirect and offset values. ++ FORCEINLINE static PTR_TYPE GetValueMaybeNullAtPtrIndirect(TADDR base, bool isIndirect, intptr_t offset) ++ { ++ LIMITED_METHOD_DAC_CONTRACT; ++ return GetValueMaybeNullAtPtr(base); ++ } ++ + #ifndef DACCESS_COMPILE + // Set encoded value of the pointer. Assumes that the value is not NULL. + FORCEINLINE void SetValue(PTR_TYPE addr) +@@ -429,6 +453,14 @@ public: + _ASSERTE((addr & FIXUP_POINTER_INDIRECTION) != 0); + return (PTR_TYPE *)(addr - FIXUP_POINTER_INDIRECTION); + } ++ ++ // Returns the pointer to the indirection cell. ++ // Ignores isIndirect and offset values. ++ PTR_TYPE * GetValuePtrIndirect(bool isIndirect, intptr_t offset) const ++ { ++ LIMITED_METHOD_CONTRACT; ++ return GetValuePtr(); ++ } + #endif // !DACCESS_COMPILE + + // Returns value of the encoded pointer. Assumes that the pointer is not NULL. +@@ -462,6 +494,14 @@ public: + LIMITED_METHOD_CONTRACT; + return IsIndirectPtr((TADDR)this); + } ++ ++ // Returns whether pointer is indirect. Assumes that the value is not NULL. ++ // Ignores isIndirect and offset values. ++ bool IsIndirectPtrIndirect(bool isIndirect, intptr_t offset) const ++ { ++ LIMITED_METHOD_DAC_CONTRACT; ++ return IsIndirectPtr(); ++ } + #endif + + // Returns whether pointer is indirect. The value can be NULL. +@@ -483,6 +523,14 @@ public: + LIMITED_METHOD_CONTRACT; + return IsIndirectPtrMaybeNull((TADDR)this); + } ++ ++ // Returns whether pointer is indirect. The value can be NULL. ++ // Ignores isIndirect and offset values. ++ bool IsIndirectPtrMaybeNullIndirect(bool isIndirect, intptr_t offset) const ++ { ++ LIMITED_METHOD_DAC_CONTRACT; ++ return IsIndirectPtrMaybeNull(); ++ } + #endif + + private: +@@ -765,6 +813,130 @@ private: + INT32 m_delta; + }; + ++//---------------------------------------------------------------------------- ++// IndirectPointer is pointer with optional indirection, similar to FixupPointer and RelativeFixupPointer. ++// ++// In comparison to FixupPointer, IndirectPointer's indirection is handled from outside by isIndirect flag. ++// In comparison to RelativeFixupPointer, IndirectPointer's offset is a constant, ++// while RelativeFixupPointer's offset is an address. ++// ++// IndirectPointer can contain NULL only if it is not indirect. ++// ++template<typename PTR_TYPE> ++class IndirectPointer ++{ ++public: ++ ++ static constexpr bool isRelative = false; ++ typedef PTR_TYPE type; ++ ++ // Returns whether the encoded pointer is NULL. ++ BOOL IsNull() const ++ { ++ LIMITED_METHOD_DAC_CONTRACT; ++ return m_addr == (TADDR)NULL; ++ } ++ ++ // Returns whether the indirection cell contain fixup that has not been converted to real pointer yet. ++ // Uses isIndirect to identify, whether pointer is indirect or not. If it is, uses offset. ++ FORCEINLINE BOOL IsTaggedIndirect(TADDR base, bool isIndirect, intptr_t offset) const ++ { ++ LIMITED_METHOD_DAC_CONTRACT; ++ TADDR addr = m_addr; ++ if (isIndirect) ++ { ++ _ASSERTE(!IsNull()); ++ return (*PTR_TADDR(addr + offset) & 1) != 0; ++ } ++ return FALSE; ++ } ++ ++ // Returns value of the encoded pointer. ++ // Uses isIndirect to identify, whether pointer is indirect or not. If it is, uses offset. ++ FORCEINLINE PTR_TYPE GetValueIndirect(bool isIndirect, intptr_t offset) const ++ { ++ LIMITED_METHOD_DAC_CONTRACT; ++ TADDR addr = m_addr; ++ if (isIndirect) ++ { ++ _ASSERTE(!IsNull()); ++ addr = *PTR_TADDR(addr + offset); ++ } ++ return dac_cast<PTR_TYPE>(addr); ++ } ++ ++#ifndef DACCESS_COMPILE ++ // Returns the pointer to the indirection cell. ++ // Uses isIndirect to identify, whether pointer is indirect or not. If it is, uses offset. ++ PTR_TYPE * GetValuePtrIndirect(bool isIndirect, intptr_t offset) const ++ { ++ LIMITED_METHOD_CONTRACT; ++ TADDR addr = m_addr; ++ if (isIndirect) ++ { ++ _ASSERTE(!IsNull()); ++ return (PTR_TYPE *)(addr + offset); ++ } ++ return (PTR_TYPE *)&m_addr; ++ } ++#endif // !DACCESS_COMPILE ++ ++ // Static version of GetValue. It is meant to simplify access to arrays of pointers. ++ // Uses isIndirect to identify, whether pointer is indirect or not. If it is, uses offset. ++ FORCEINLINE static PTR_TYPE GetValueAtPtrIndirect(TADDR base, bool isIndirect, intptr_t offset) ++ { ++ LIMITED_METHOD_DAC_CONTRACT; ++ return dac_cast<DPTR(IndirectPointer<PTR_TYPE>)>(base)->GetValueIndirect(isIndirect, offset); ++ } ++ ++ // Static version of GetValueMaybeNull. It is meant to simplify access to arrays of pointers. ++ // Uses isIndirect to identify, whether pointer is indirect or not. If it is, uses offset. ++ FORCEINLINE static PTR_TYPE GetValueMaybeNullAtPtrIndirect(TADDR base, bool isIndirect, intptr_t offset) ++ { ++ LIMITED_METHOD_DAC_CONTRACT; ++ return GetValueAtPtrIndirect(base, isIndirect, offset); ++ } ++ ++#ifndef DACCESS_COMPILE ++ // Returns whether pointer is indirect. Assumes that the value is not NULL. ++ // Uses isIndirect to identify, whether pointer is indirect or not. If it is, uses offset. ++ bool IsIndirectPtrIndirect(bool isIndirect, intptr_t offset) const ++ { ++ LIMITED_METHOD_CONTRACT; ++ if (isIndirect) ++ _ASSERTE(!IsNull()); ++ return isIndirect; ++ } ++ ++ // Returns whether pointer is indirect. The value can be NULL. ++ // Uses isIndirect to identify, whether pointer is indirect or not. If it is, uses offset. ++ bool IsIndirectPtrMaybeNullIndirect(bool isIndirect, intptr_t offset) const ++ { ++ LIMITED_METHOD_CONTRACT; ++ return IsIndirectPtrIndirect(isIndirect, offset); ++ } ++#endif // !DACCESS_COMPILE ++ ++#ifndef DACCESS_COMPILE ++ // Set encoded value of the pointer. Assumes that the value is not NULL. ++ void SetValue(PTR_TYPE addr) ++ { ++ LIMITED_METHOD_CONTRACT; ++ m_addr = dac_cast<TADDR>(addr); ++ } ++ ++ // Set encoded value of the pointer. The value can be NULL. ++ void SetValueMaybeNull(PTR_TYPE addr) ++ { ++ LIMITED_METHOD_CONTRACT; ++ SetValue(addr); ++ } ++#endif // !DACCESS_COMPILE ++ ++private: ++ TADDR m_addr; ++}; ++ + template<bool isMaybeNull, typename T, typename PT> + typename PT::type + ReadPointer(const T *base, const PT T::* pPointerFieldMember) +@@ -783,6 +955,24 @@ ReadPointer(const T *base, const PT T::* pPointerFieldMember) + } + } + ++template<bool isMaybeNull, typename T, typename PT> ++typename PT::type ++ReadPointer(const T *base, const PT T::* pPointerFieldMember, bool isIndirect) ++{ ++ LIMITED_METHOD_DAC_CONTRACT; ++ ++ uintptr_t offset = (uintptr_t) &(base->*pPointerFieldMember) - (uintptr_t) base; ++ ++ if (isMaybeNull) ++ { ++ return PT::GetValueMaybeNullAtPtrIndirect(dac_cast<TADDR>(base) + offset, isIndirect, offset); ++ } ++ else ++ { ++ return PT::GetValueAtPtrIndirect(dac_cast<TADDR>(base) + offset, isIndirect, offset); ++ } ++} ++ + template<typename T, typename PT> + typename PT::type + ReadPointerMaybeNull(const T *base, const PT T::* pPointerFieldMember) +@@ -794,6 +984,15 @@ ReadPointerMaybeNull(const T *base, const PT T::* pPointerFieldMember) + + template<typename T, typename PT> + typename PT::type ++ReadPointerMaybeNull(const T *base, const PT T::* pPointerFieldMember, bool isIndirect) ++{ ++ LIMITED_METHOD_DAC_CONTRACT; ++ ++ return ReadPointer<true>(base, pPointerFieldMember, isIndirect); ++} ++ ++template<typename T, typename PT> ++typename PT::type + ReadPointer(const T *base, const PT T::* pPointerFieldMember) + { + LIMITED_METHOD_DAC_CONTRACT; +@@ -801,6 +1000,15 @@ ReadPointer(const T *base, const PT T::* pPointerFieldMember) + return ReadPointer<false>(base, pPointerFieldMember); + } + ++template<typename T, typename PT> ++typename PT::type ++ReadPointer(const T *base, const PT T::* pPointerFieldMember, bool isIndirect) ++{ ++ LIMITED_METHOD_DAC_CONTRACT; ++ ++ return ReadPointer<false>(base, pPointerFieldMember, isIndirect); ++} ++ + template<bool isMaybeNull, typename T, typename C, typename PT> + typename PT::type + ReadPointer(const T *base, const C T::* pFirstPointerFieldMember, const PT C::* pSecondPointerFieldMember) +diff --git a/src/vm/class.cpp b/src/vm/class.cpp +index c1519a2..7b2885b 100644 +--- a/src/vm/class.cpp ++++ b/src/vm/class.cpp +@@ -889,7 +889,15 @@ ClassLoader::LoadExactParentAndInterfacesTransitively(MethodTable *pMT) + LOG((LF_CLASSLOADER, LL_INFO1000, "GENERICS: Replaced approximate parent %s with exact parent %s from token %x\n", pParentMT->GetDebugClassName(), pNewParentMT->GetDebugClassName(), crExtends)); + + // SetParentMethodTable is not used here since we want to update the indirection cell in the NGen case +- *EnsureWritablePages(pMT->GetParentMethodTablePtr()) = pNewParentMT; ++ if (pMT->IsParentMethodTableIndirectPointerMaybeNull()) ++ { ++ *EnsureWritablePages(pMT->GetParentMethodTableValuePtr()) = pNewParentMT; ++ } ++ else ++ { ++ EnsureWritablePages(pMT->GetParentMethodTablePointerPtr()); ++ pMT->GetParentMethodTablePointerPtr()->SetValueMaybeNull(pNewParentMT); ++ } + + pParentMT = pNewParentMT; + } +diff --git a/src/vm/generics.cpp b/src/vm/generics.cpp +index b110184..61a1de5 100644 +--- a/src/vm/generics.cpp ++++ b/src/vm/generics.cpp +@@ -365,6 +365,7 @@ ClassLoader::CreateTypeHandleForNonCanonicalGenericInstantiation( + pMT->ClearFlag(MethodTable::enum_flag_IsPreRestored); + + pMT->ClearFlag(MethodTable::enum_flag_HasIndirectParent); ++ pMT->m_pParentMethodTable.SetValueMaybeNull(NULL); + + // Non non-virtual slots + pMT->ClearFlag(MethodTable::enum_flag_HasSingleNonVirtualSlot); +diff --git a/src/vm/methodtable.cpp b/src/vm/methodtable.cpp +index 75db911..b097406 100644 +--- a/src/vm/methodtable.cpp ++++ b/src/vm/methodtable.cpp +@@ -4778,7 +4778,17 @@ void MethodTable::Fixup(DataImage *image) + #endif // _DEBUG + + MethodTable * pParentMT = GetParentMethodTable(); +- _ASSERTE(!pNewMT->GetFlag(enum_flag_HasIndirectParent)); ++ _ASSERTE(!pNewMT->IsParentMethodTableIndirectPointerMaybeNull()); ++ ++ ZapRelocationType relocType; ++ if (decltype(MethodTable::m_pParentMethodTable)::isRelative) ++ { ++ relocType = IMAGE_REL_BASED_RELPTR; ++ } ++ else ++ { ++ relocType = IMAGE_REL_BASED_PTR; ++ } + + if (pParentMT != NULL) + { +@@ -4790,7 +4800,8 @@ void MethodTable::Fixup(DataImage *image) + { + if (image->CanHardBindToZapModule(pParentMT->GetLoaderModule())) + { +- image->FixupPointerField(this, offsetof(MethodTable, m_pParentMethodTable)); ++ _ASSERTE(!IsParentMethodTableIndirectPointer()); ++ image->FixupField(this, offsetof(MethodTable, m_pParentMethodTable), pParentMT, 0, relocType); + } + else + { +@@ -4826,7 +4837,7 @@ void MethodTable::Fixup(DataImage *image) + + if (pImport != NULL) + { +- image->FixupFieldToNode(this, offsetof(MethodTable, m_pParentMethodTable), pImport, -(SSIZE_T)offsetof(MethodTable, m_pParentMethodTable)); ++ image->FixupFieldToNode(this, offsetof(MethodTable, m_pParentMethodTable), pImport, -PARENT_MT_FIXUP_OFFSET, relocType); + pNewMT->SetFlag(enum_flag_HasIndirectParent); + } + } +@@ -6091,7 +6102,15 @@ void MethodTable::Restore() + // + // Restore parent method table + // +- Module::RestoreMethodTablePointerRaw(GetParentMethodTablePtr(), GetLoaderModule(), CLASS_LOAD_APPROXPARENTS); ++ if (IsParentMethodTableIndirectPointerMaybeNull()) ++ { ++ Module::RestoreMethodTablePointerRaw(GetParentMethodTableValuePtr(), GetLoaderModule(), CLASS_LOAD_APPROXPARENTS); ++ } ++ else ++ { ++ ClassLoader::EnsureLoaded(ReadPointer(this, &MethodTable::m_pParentMethodTable, GetFlagHasIndirectParent()), ++ CLASS_LOAD_APPROXPARENTS); ++ } + + // + // Restore interface classes +@@ -7849,13 +7868,7 @@ BOOL MethodTable::IsParentMethodTablePointerValid() + if (!GetWriteableData_NoLogging()->IsParentMethodTablePointerValid()) + return FALSE; + +- if (!GetFlag(enum_flag_HasIndirectParent)) +- { +- return TRUE; +- } +- TADDR pMT; +- pMT = *PTR_TADDR(m_pParentMethodTable + offsetof(MethodTable, m_pParentMethodTable)); +- return !CORCOMPILE_IS_POINTER_TAGGED(pMT); ++ return !IsParentMethodTableTagged(dac_cast<PTR_MethodTable>(this)); + } + #endif + +diff --git a/src/vm/methodtable.h b/src/vm/methodtable.h +index 8c15d2e..c2c2564 100644 +--- a/src/vm/methodtable.h ++++ b/src/vm/methodtable.h +@@ -2127,6 +2127,14 @@ public: + // THE METHOD TABLE PARENT (SUPERCLASS/BASE CLASS) + // + ++#if defined(PLATFORM_UNIX) && defined(_TARGET_ARM_) ++#define PARENT_MT_FIXUP_OFFSET (-FIXUP_POINTER_INDIRECTION) ++ typedef RelativeFixupPointer<PTR_MethodTable> ParentMT_t; ++#else ++#define PARENT_MT_FIXUP_OFFSET ((SSIZE_T)offsetof(MethodTable, m_pParentMethodTable)) ++ typedef IndirectPointer<PTR_MethodTable> ParentMT_t; ++#endif ++ + BOOL HasApproxParent() + { + LIMITED_METHOD_DAC_CONTRACT; +@@ -2145,33 +2153,63 @@ public: + LIMITED_METHOD_DAC_CONTRACT; + + PRECONDITION(IsParentMethodTablePointerValid()); +- +- TADDR pMT = m_pParentMethodTable; +-#ifdef FEATURE_PREJIT +- if (GetFlag(enum_flag_HasIndirectParent)) +- pMT = *PTR_TADDR(m_pParentMethodTable + offsetof(MethodTable, m_pParentMethodTable)); +-#endif +- return PTR_MethodTable(pMT); ++ return ReadPointerMaybeNull(this, &MethodTable::m_pParentMethodTable, GetFlagHasIndirectParent()); + } + + inline static PTR_VOID GetParentMethodTableOrIndirection(PTR_VOID pMT) + { + WRAPPER_NO_CONTRACT; ++#if defined(PLATFORM_UNIX) && defined(_TARGET_ARM_) ++ PTR_MethodTable pMethodTable = dac_cast<PTR_MethodTable>(pMT); ++ PTR_MethodTable pParentMT = ReadPointerMaybeNull((MethodTable*) pMethodTable, &MethodTable::m_pParentMethodTable); ++ return dac_cast<PTR_VOID>(pParentMT); ++#else + return PTR_VOID(*PTR_TADDR(dac_cast<TADDR>(pMT) + offsetof(MethodTable, m_pParentMethodTable))); ++#endif + } + +- inline MethodTable ** GetParentMethodTablePtr() ++ inline static bool IsParentMethodTableTagged(PTR_MethodTable pMT) + { +- WRAPPER_NO_CONTRACT; ++ LIMITED_METHOD_CONTRACT; ++ TADDR base = dac_cast<TADDR>(pMT) + offsetof(MethodTable, m_pParentMethodTable); ++ return pMT->m_pParentMethodTable.IsTaggedIndirect(base, pMT->GetFlagHasIndirectParent(), PARENT_MT_FIXUP_OFFSET); ++ } + ++ bool GetFlagHasIndirectParent() ++ { + #ifdef FEATURE_PREJIT +- return GetFlag(enum_flag_HasIndirectParent) ? +- (MethodTable **)(m_pParentMethodTable + offsetof(MethodTable, m_pParentMethodTable)) :(MethodTable **)&m_pParentMethodTable; ++ return GetFlag(enum_flag_HasIndirectParent); + #else +- return (MethodTable **)&m_pParentMethodTable; ++ return FALSE; + #endif + } + ++#ifndef DACCESS_COMPILE ++ inline ParentMT_t * GetParentMethodTablePointerPtr() ++ { ++ LIMITED_METHOD_CONTRACT; ++ return &m_pParentMethodTable; ++ } ++ ++ inline bool IsParentMethodTableIndirectPointerMaybeNull() ++ { ++ LIMITED_METHOD_CONTRACT; ++ return m_pParentMethodTable.IsIndirectPtrMaybeNullIndirect(GetFlagHasIndirectParent(), PARENT_MT_FIXUP_OFFSET); ++ } ++ ++ inline bool IsParentMethodTableIndirectPointer() ++ { ++ LIMITED_METHOD_CONTRACT; ++ return m_pParentMethodTable.IsIndirectPtrIndirect(GetFlagHasIndirectParent(), PARENT_MT_FIXUP_OFFSET); ++ } ++ ++ inline MethodTable ** GetParentMethodTableValuePtr() ++ { ++ LIMITED_METHOD_CONTRACT; ++ return m_pParentMethodTable.GetValuePtrIndirect(GetFlagHasIndirectParent(), PARENT_MT_FIXUP_OFFSET); ++ } ++#endif // !DACCESS_COMPILE ++ + // Is the parent method table pointer equal to the given argument? + BOOL ParentEquals(PTR_MethodTable pMT) + { +@@ -2189,8 +2227,8 @@ public: + void SetParentMethodTable (MethodTable *pParentMethodTable) + { + LIMITED_METHOD_CONTRACT; +- PRECONDITION(!GetFlag(enum_flag_HasIndirectParent)); +- m_pParentMethodTable = (TADDR)pParentMethodTable; ++ PRECONDITION(!IsParentMethodTableIndirectPointerMaybeNull()); ++ m_pParentMethodTable.SetValueMaybeNull(pParentMethodTable); + #ifdef _DEBUG + GetWriteableDataForWrite_NoLogging()->SetParentMethodTablePointerValid(); + #endif +@@ -4095,11 +4133,12 @@ private: + LPCUTF8 debug_m_szClassName; + #endif //_DEBUG + ++ // On Linux ARM is a RelativeFixupPointer. Otherwise, + // Parent PTR_MethodTable if enum_flag_HasIndirectParent is not set. Pointer to indirection cell + // if enum_flag_enum_flag_HasIndirectParent is set. The indirection is offset by offsetof(MethodTable, m_pParentMethodTable). + // It allows casting helpers to go through parent chain natually. Casting helper do not need need the explicit check + // for enum_flag_HasIndirectParentMethodTable. +- TADDR m_pParentMethodTable; ++ ParentMT_t m_pParentMethodTable; + + RelativePointer<PTR_Module> m_pLoaderModule; // LoaderModule. It is equal to the ZapModule in ngened images + +diff --git a/src/vm/proftoeeinterfaceimpl.cpp b/src/vm/proftoeeinterfaceimpl.cpp +index cfd99ad..972a0eb 100644 +--- a/src/vm/proftoeeinterfaceimpl.cpp ++++ b/src/vm/proftoeeinterfaceimpl.cpp +@@ -6832,7 +6832,7 @@ HRESULT ProfToEEInterfaceImpl::GetClassLayout(ClassID classID, + // running into - attempting to get the class layout for all types at module load time. + // If we don't detect this the runtime will AV during the field iteration below. Feel + // free to eliminate this check when a more complete solution is available. +- if (CORCOMPILE_IS_POINTER_TAGGED(*(typeHandle.AsMethodTable()->GetParentMethodTablePtr()))) ++ if (MethodTable::IsParentMethodTableTagged(typeHandle.AsMethodTable())) + { + return CORPROF_E_DATAINCOMPLETE; + } +-- +2.7.4 + |