diff options
-rw-r--r-- | src/debug/daccess/nidump.cpp | 4 | ||||
-rw-r--r-- | src/vm/ceeload.cpp | 26 | ||||
-rw-r--r-- | src/vm/ceeload.h | 4 | ||||
-rw-r--r-- | src/vm/class.cpp | 10 | ||||
-rw-r--r-- | src/vm/generics.cpp | 2 | ||||
-rw-r--r-- | src/vm/jithelpers.cpp | 8 | ||||
-rw-r--r-- | src/vm/methodtable.cpp | 31 | ||||
-rw-r--r-- | src/vm/methodtable.h | 42 | ||||
-rw-r--r-- | src/vm/proftoeeinterfaceimpl.cpp | 2 |
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; } |