From: Gleb Balykov Date: Fri, 23 Jun 2017 11:57:25 +0000 (+0300) Subject: Remove relocations for MethodTable::m_pParentMethodTable for Linux ARM X-Git-Tag: submit/tizen/20210909.063632~11030^2~6513^2~386^2~4 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=9cab21f8262799f056d5cbe1a35d02300f6c435f;p=platform%2Fupstream%2Fdotnet%2Fruntime.git Remove relocations for MethodTable::m_pParentMethodTable for Linux ARM Commit migrated from https://github.com/dotnet/coreclr/commit/cf1fb9e17fc8b6ee849edab5a696d0ec5c6eadd2 --- diff --git a/src/coreclr/src/debug/daccess/nidump.cpp b/src/coreclr/src/debug/daccess/nidump.cpp index eec4c43..0d948dd 100644 --- a/src/coreclr/src/debug/daccess/nidump.cpp +++ b/src/coreclr/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/coreclr/src/vm/ceeload.cpp b/src/coreclr/src/vm/ceeload.cpp index ea93e5c..4d7c754 100644 --- a/src/coreclr/src/vm/ceeload.cpp +++ b/src/coreclr/src/vm/ceeload.cpp @@ -10263,6 +10263,32 @@ void Module::RestoreMethodTablePointer(RelativeFixupPointer * p } } +/*static*/ +void Module::RestoreMethodTablePointer(PlainPointer * 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/coreclr/src/vm/ceeload.h b/src/coreclr/src/vm/ceeload.h index 15d7959..4533597 100644 --- a/src/coreclr/src/vm/ceeload.h +++ b/src/coreclr/src/vm/ceeload.h @@ -2911,6 +2911,10 @@ public: ClassLoadLevel level = CLASS_LOADED); static void RestoreFieldDescPointer(RelativeFixupPointer * ppFD); + static void RestoreMethodTablePointer(PlainPointer * ppMT, + Module *pContainingModule = NULL, + ClassLoadLevel level = CLASS_LOADED); + static void RestoreModulePointer(RelativeFixupPointer * ppModule, Module *pContainingModule); static PTR_Module RestoreModulePointerIfLoaded(DPTR(RelativeFixupPointer) ppModule, Module *pContainingModule); diff --git a/src/coreclr/src/vm/class.cpp b/src/coreclr/src/vm/class.cpp index c1519a2..f1332f3 100644 --- a/src/coreclr/src/vm/class.cpp +++ b/src/coreclr/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/coreclr/src/vm/generics.cpp b/src/coreclr/src/vm/generics.cpp index d1a511f..1a182da 100644 --- a/src/coreclr/src/vm/generics.cpp +++ b/src/coreclr/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/coreclr/src/vm/jithelpers.cpp b/src/coreclr/src/vm/jithelpers.cpp index bfb2b34..066672c 100644 --- a/src/coreclr/src/vm/jithelpers.cpp +++ b/src/coreclr/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/coreclr/src/vm/methodtable.cpp b/src/coreclr/src/vm/methodtable.cpp index d60f565..cf24f19 100644 --- a/src/coreclr/src/vm/methodtable.cpp +++ b/src/coreclr/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(this) + offsetof(MethodTable, m_pParentMethodTable); + return !m_pParentMethodTable.IsTagged(base); } #endif diff --git a/src/coreclr/src/vm/methodtable.h b/src/coreclr/src/vm/methodtable.h index bf811aa..770dda4 100644 --- a/src/coreclr/src/vm/methodtable.h +++ b/src/coreclr/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 ParentMT_t; +#else + typedef PlainPointer 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(pMT) + offsetof(MethodTable, m_pParentMethodTable))); + LIMITED_METHOD_DAC_CONTRACT; + + PTR_MethodTable pMethodTable = dac_cast(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 m_pLoaderModule; // LoaderModule. It is equal to the ZapModule in ngened images diff --git a/src/coreclr/src/vm/proftoeeinterfaceimpl.cpp b/src/coreclr/src/vm/proftoeeinterfaceimpl.cpp index cfd99ad..7022ffb 100644 --- a/src/coreclr/src/vm/proftoeeinterfaceimpl.cpp +++ b/src/coreclr/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; }