summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorgbalykov <g.balykov@samsung.com>2018-02-22 20:47:46 +0300
committerJan Kotas <jkotas@microsoft.com>2018-02-22 09:47:46 -0800
commit34247df6ccb1bcc54363807f047e67c8d43c03cb (patch)
treef74c65cf73c5e677046cc17e6c9ea6d9f839421c
parent9e7ec667bd2871970b127fda856b0c6cf3eb2060 (diff)
downloadcoreclr-34247df6ccb1bcc54363807f047e67c8d43c03cb.tar.gz
coreclr-34247df6ccb1bcc54363807f047e67c8d43c03cb.tar.bz2
coreclr-34247df6ccb1bcc54363807f047e67c8d43c03cb.zip
Remove relocations for MethodTable::m_pParentMethodTable for Linux ARM (#15915)
-rw-r--r--src/debug/daccess/nidump.cpp4
-rw-r--r--src/inc/fixuppointer.h208
-rw-r--r--src/vm/class.cpp10
-rw-r--r--src/vm/generics.cpp1
-rw-r--r--src/vm/methodtable.cpp35
-rw-r--r--src/vm/methodtable.h69
-rw-r--r--src/vm/proftoeeinterfaceimpl.cpp2
7 files changed, 299 insertions, 30 deletions
diff --git a/src/debug/daccess/nidump.cpp b/src/debug/daccess/nidump.cpp
index 274b1e7ddf..45320dca7f 100644
--- a/src/debug/daccess/nidump.cpp
+++ b/src/debug/daccess/nidump.cpp
@@ -5987,7 +5987,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;
}
@@ -6961,7 +6961,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 a711418bd4..5a897e44ea 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 d0b07f0896..cd2bbbae47 100644
--- a/src/vm/class.cpp
+++ b/src/vm/class.cpp
@@ -883,7 +883,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 83bcd86f84..4ff877ed43 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 e8f9dccdc3..710a81abf4 100644
--- a/src/vm/methodtable.cpp
+++ b/src/vm/methodtable.cpp
@@ -4816,7 +4816,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)
{
@@ -4828,7 +4838,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
{
@@ -4864,7 +4875,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);
}
}
@@ -6128,7 +6139,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
@@ -8183,13 +8202,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 0073a18dde..29d36d1dce 100644
--- a/src/vm/methodtable.h
+++ b/src/vm/methodtable.h
@@ -2177,6 +2177,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;
@@ -2195,33 +2203,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)
{
@@ -2239,8 +2277,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
@@ -4139,11 +4177,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 5daf127387..04330a26e0 100644
--- a/src/vm/proftoeeinterfaceimpl.cpp
+++ b/src/vm/proftoeeinterfaceimpl.cpp
@@ -7091,7 +7091,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;
}