diff options
author | gbalykov <g.balykov@samsung.com> | 2018-02-22 20:47:46 +0300 |
---|---|---|
committer | Jan Kotas <jkotas@microsoft.com> | 2018-02-22 09:47:46 -0800 |
commit | 34247df6ccb1bcc54363807f047e67c8d43c03cb (patch) | |
tree | f74c65cf73c5e677046cc17e6c9ea6d9f839421c /src/vm | |
parent | 9e7ec667bd2871970b127fda856b0c6cf3eb2060 (diff) | |
download | coreclr-34247df6ccb1bcc54363807f047e67c8d43c03cb.tar.gz coreclr-34247df6ccb1bcc54363807f047e67c8d43c03cb.tar.bz2 coreclr-34247df6ccb1bcc54363807f047e67c8d43c03cb.zip |
Remove relocations for MethodTable::m_pParentMethodTable for Linux ARM (#15915)
Diffstat (limited to 'src/vm')
-rw-r--r-- | src/vm/class.cpp | 10 | ||||
-rw-r--r-- | src/vm/generics.cpp | 1 | ||||
-rw-r--r-- | src/vm/methodtable.cpp | 35 | ||||
-rw-r--r-- | src/vm/methodtable.h | 69 | ||||
-rw-r--r-- | src/vm/proftoeeinterfaceimpl.cpp | 2 |
5 files changed, 89 insertions, 28 deletions
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; } |