summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/debug/daccess/nidump.cpp4
-rw-r--r--src/vm/ceeload.cpp26
-rw-r--r--src/vm/ceeload.h4
-rw-r--r--src/vm/class.cpp10
-rw-r--r--src/vm/generics.cpp2
-rw-r--r--src/vm/jithelpers.cpp8
-rw-r--r--src/vm/methodtable.cpp31
-rw-r--r--src/vm/methodtable.h42
-rw-r--r--src/vm/proftoeeinterfaceimpl.cpp2
9 files changed, 85 insertions, 44 deletions
diff --git a/src/debug/daccess/nidump.cpp b/src/debug/daccess/nidump.cpp
index eec4c43be6..0d948ddf6c 100644
--- a/src/debug/daccess/nidump.cpp
+++ b/src/debug/daccess/nidump.cpp
@@ -6012,7 +6012,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) );
_ASSERTE(!CORCOMPILE_IS_POINTER_TAGGED(PTR_TO_TADDR(parent)));
return parent;
}
@@ -6986,7 +6986,7 @@ NativeImageDumper::DumpMethodTable( PTR_MethodTable mt, const char * name,
- PTR_MethodTable parent = mt->m_pParentMethodTable;
+ PTR_MethodTable parent = ReadPointerMaybeNull((MethodTable *) mt, &MethodTable::m_pParentMethodTable);
if( parent == NULL )
{
DisplayWriteFieldPointer( m_pParentMethodTable, NULL, MethodTable,
diff --git a/src/vm/ceeload.cpp b/src/vm/ceeload.cpp
index ea93e5ccf4..4d7c754333 100644
--- a/src/vm/ceeload.cpp
+++ b/src/vm/ceeload.cpp
@@ -10263,6 +10263,32 @@ void Module::RestoreMethodTablePointer(RelativeFixupPointer<PTR_MethodTable> * p
}
}
+/*static*/
+void Module::RestoreMethodTablePointer(PlainPointer<PTR_MethodTable> * ppMT,
+ Module *pContainingModule,
+ ClassLoadLevel level)
+{
+ CONTRACTL
+ {
+ THROWS;
+ GC_TRIGGERS;
+ MODE_ANY;
+ }
+ CONTRACTL_END;
+
+ if (ppMT->IsNull())
+ return;
+
+ if (ppMT->IsTagged())
+ {
+ RestoreMethodTablePointerRaw(ppMT->GetValuePtr(), pContainingModule, level);
+ }
+ else
+ {
+ ClassLoader::EnsureLoaded(ppMT->GetValue(), level);
+ }
+}
+
#endif // !DACCESS_COMPILE
BOOL Module::IsZappedCode(PCODE code)
diff --git a/src/vm/ceeload.h b/src/vm/ceeload.h
index 15d7959433..4533597fba 100644
--- a/src/vm/ceeload.h
+++ b/src/vm/ceeload.h
@@ -2911,6 +2911,10 @@ public:
ClassLoadLevel level = CLASS_LOADED);
static void RestoreFieldDescPointer(RelativeFixupPointer<PTR_FieldDesc> * ppFD);
+ static void RestoreMethodTablePointer(PlainPointer<PTR_MethodTable> * ppMT,
+ Module *pContainingModule = NULL,
+ ClassLoadLevel level = CLASS_LOADED);
+
static void RestoreModulePointer(RelativeFixupPointer<PTR_Module> * ppModule, Module *pContainingModule);
static PTR_Module RestoreModulePointerIfLoaded(DPTR(RelativeFixupPointer<PTR_Module>) ppModule, Module *pContainingModule);
diff --git a/src/vm/class.cpp b/src/vm/class.cpp
index c1519a2bfe..f1332f3650 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->GetParentMethodTablePlainOrRelativePointerPtr()->IsIndirectPtrMaybeNull())
+ {
+ *EnsureWritablePages(pMT->GetParentMethodTablePlainOrRelativePointerPtr()->GetValuePtr()) = pNewParentMT;
+ }
+ else
+ {
+ EnsureWritablePages(pMT->GetParentMethodTablePlainOrRelativePointerPtr());
+ pMT->GetParentMethodTablePlainOrRelativePointerPtr()->SetValueMaybeNull(pNewParentMT);
+ }
pParentMT = pNewParentMT;
}
diff --git a/src/vm/generics.cpp b/src/vm/generics.cpp
index d1a511ffb7..1a182da718 100644
--- a/src/vm/generics.cpp
+++ b/src/vm/generics.cpp
@@ -364,7 +364,7 @@ ClassLoader::CreateTypeHandleForNonCanonicalGenericInstantiation(
pMT->ClearFlag(MethodTable::enum_flag_IsZapped);
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/jithelpers.cpp b/src/vm/jithelpers.cpp
index bfb2b34565..066672c5b1 100644
--- a/src/vm/jithelpers.cpp
+++ b/src/vm/jithelpers.cpp
@@ -2398,7 +2398,7 @@ HCIMPL2(Object*, JIT_ChkCastClass_Portable, MethodTable* pTargetMT, Object* pObj
if (pMT == pTargetMT)
return pObject;
- pMT = MethodTable::GetParentMethodTableOrIndirection(pMT);
+ pMT = MethodTable::GetParentMethodTable(pMT);
} while (pMT);
ENDFORBIDGC();
@@ -2418,14 +2418,14 @@ HCIMPL2(Object*, JIT_ChkCastClassSpecial_Portable, MethodTable* pTargetMT, Objec
PRECONDITION(pObject->GetMethodTable() != pTargetMT);
} CONTRACTL_END;
- PTR_VOID pMT = MethodTable::GetParentMethodTableOrIndirection(pObject->GetMethodTable());
+ PTR_VOID pMT = MethodTable::GetParentMethodTable(pObject->GetMethodTable());
while (pMT)
{
if (pMT == pTargetMT)
return pObject;
- pMT = MethodTable::GetParentMethodTableOrIndirection(pMT);
+ pMT = MethodTable::GetParentMethodTable(pMT);
}
ENDFORBIDGC();
@@ -2452,7 +2452,7 @@ HCIMPL2(Object*, JIT_IsInstanceOfClass_Portable, MethodTable* pTargetMT, Object*
if (pMT == pTargetMT)
return pObject;
- pMT = MethodTable::GetParentMethodTableOrIndirection(pMT);
+ pMT = MethodTable::GetParentMethodTable(pMT);
} while (pMT);
if (!pObject->GetMethodTable()->HasTypeEquivalence())
diff --git a/src/vm/methodtable.cpp b/src/vm/methodtable.cpp
index d60f565b08..cf24f19239 100644
--- a/src/vm/methodtable.cpp
+++ b/src/vm/methodtable.cpp
@@ -1790,7 +1790,7 @@ TypeHandle::CastResult MethodTable::CanCastToClassNoGC(MethodTable *pTargetMT)
if (pMT == pTargetMT)
return TypeHandle::CanCast;
- pMT = MethodTable::GetParentMethodTableOrIndirection(pMT);
+ pMT = MethodTable::GetParentMethodTable(pMT);
} while (pMT);
}
@@ -4781,7 +4781,17 @@ void MethodTable::Fixup(DataImage *image)
#endif // _DEBUG
MethodTable * pParentMT = GetParentMethodTable();
- _ASSERTE(!pNewMT->GetFlag(enum_flag_HasIndirectParent));
+ _ASSERTE(!pNewMT->m_pParentMethodTable.IsIndirectPtrMaybeNull());
+
+ ZapRelocationType relocType;
+ if (decltype(MethodTable::m_pParentMethodTable)::isRelative)
+ {
+ relocType = IMAGE_REL_BASED_RELPTR;
+ }
+ else
+ {
+ relocType = IMAGE_REL_BASED_PTR;
+ }
if (pParentMT != NULL)
{
@@ -4793,7 +4803,8 @@ void MethodTable::Fixup(DataImage *image)
{
if (image->CanHardBindToZapModule(pParentMT->GetLoaderModule()))
{
- image->FixupPointerField(this, offsetof(MethodTable, m_pParentMethodTable));
+ _ASSERTE(!m_pParentMethodTable.IsIndirectPtr());
+ image->FixupField(this, offsetof(MethodTable, m_pParentMethodTable), pParentMT, 0, relocType);
}
else
{
@@ -4829,8 +4840,7 @@ void MethodTable::Fixup(DataImage *image)
if (pImport != NULL)
{
- image->FixupFieldToNode(this, offsetof(MethodTable, m_pParentMethodTable), pImport, -(SSIZE_T)offsetof(MethodTable, m_pParentMethodTable));
- pNewMT->SetFlag(enum_flag_HasIndirectParent);
+ image->FixupFieldToNode(this, offsetof(MethodTable, m_pParentMethodTable), pImport, FIXUP_POINTER_INDIRECTION, relocType);
}
}
@@ -6087,7 +6097,7 @@ void MethodTable::Restore()
//
// Restore parent method table
//
- Module::RestoreMethodTablePointerRaw(GetParentMethodTablePtr(), GetLoaderModule(), CLASS_LOAD_APPROXPARENTS);
+ Module::RestoreMethodTablePointer(&m_pParentMethodTable, GetLoaderModule(), CLASS_LOAD_APPROXPARENTS);
//
// Restore interface classes
@@ -7845,13 +7855,8 @@ 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);
+ TADDR base = dac_cast<TADDR>(this) + offsetof(MethodTable, m_pParentMethodTable);
+ return !m_pParentMethodTable.IsTagged(base);
}
#endif
diff --git a/src/vm/methodtable.h b/src/vm/methodtable.h
index bf811aa409..770dda4031 100644
--- a/src/vm/methodtable.h
+++ b/src/vm/methodtable.h
@@ -2115,6 +2115,12 @@ public:
// THE METHOD TABLE PARENT (SUPERCLASS/BASE CLASS)
//
+#if defined(PLATFORM_UNIX) && defined(_TARGET_ARM_)
+ typedef RelativeFixupPointer<PTR_MethodTable> ParentMT_t;
+#else
+ typedef PlainPointer<PTR_MethodTable> ParentMT_t;
+#endif
+
BOOL HasApproxParent()
{
LIMITED_METHOD_DAC_CONTRACT;
@@ -2133,32 +2139,24 @@ 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);
}
- inline static PTR_VOID GetParentMethodTableOrIndirection(PTR_VOID pMT)
+ inline static PTR_VOID GetParentMethodTable(PTR_VOID pMT)
{
- WRAPPER_NO_CONTRACT;
- return PTR_VOID(*PTR_TADDR(dac_cast<TADDR>(pMT) + offsetof(MethodTable, m_pParentMethodTable)));
+ LIMITED_METHOD_DAC_CONTRACT;
+
+ PTR_MethodTable pMethodTable = dac_cast<PTR_MethodTable>(pMT);
+ return pMethodTable->GetParentMethodTable();
}
- inline MethodTable ** GetParentMethodTablePtr()
+#ifndef DACCESS_COMPILE
+ inline ParentMT_t * GetParentMethodTablePlainOrRelativePointerPtr()
{
- WRAPPER_NO_CONTRACT;
-
-#ifdef FEATURE_PREJIT
- return GetFlag(enum_flag_HasIndirectParent) ?
- (MethodTable **)(m_pParentMethodTable + offsetof(MethodTable, m_pParentMethodTable)) :(MethodTable **)&m_pParentMethodTable;
-#else
- return (MethodTable **)&m_pParentMethodTable;
-#endif
+ LIMITED_METHOD_CONTRACT;
+ return &m_pParentMethodTable;
}
+#endif // !DACCESS_COMPILE
// Is the parent method table pointer equal to the given argument?
BOOL ParentEquals(PTR_MethodTable pMT)
@@ -2177,8 +2175,8 @@ public:
void SetParentMethodTable (MethodTable *pParentMethodTable)
{
LIMITED_METHOD_CONTRACT;
- PRECONDITION(!GetFlag(enum_flag_HasIndirectParent));
- m_pParentMethodTable = (TADDR)pParentMethodTable;
+ PRECONDITION(!m_pParentMethodTable.IsIndirectPtrMaybeNull());
+ m_pParentMethodTable.SetValueMaybeNull(pParentMethodTable);
#ifdef _DEBUG
GetWriteableDataForWrite_NoLogging()->SetParentMethodTablePointerValid();
#endif
@@ -4073,7 +4071,7 @@ private:
// 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 cfd99adf27..7022ffbc94 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 (typeHandle.AsMethodTable()->GetParentMethodTablePlainOrRelativePointerPtr()->IsTagged())
{
return CORPROF_E_DATAINCOMPLETE;
}