Remove relocations for MethodTable::m_pParentMethodTable for Linux ARM
authorGleb Balykov <g.balykov@samsung.com>
Fri, 23 Jun 2017 11:57:25 +0000 (14:57 +0300)
committerGleb Balykov <g.balykov@samsung.com>
Mon, 10 Jul 2017 13:37:05 +0000 (16:37 +0300)
Commit migrated from https://github.com/dotnet/coreclr/commit/cf1fb9e17fc8b6ee849edab5a696d0ec5c6eadd2

src/coreclr/src/debug/daccess/nidump.cpp
src/coreclr/src/vm/ceeload.cpp
src/coreclr/src/vm/ceeload.h
src/coreclr/src/vm/class.cpp
src/coreclr/src/vm/generics.cpp
src/coreclr/src/vm/jithelpers.cpp
src/coreclr/src/vm/methodtable.cpp
src/coreclr/src/vm/methodtable.h
src/coreclr/src/vm/proftoeeinterfaceimpl.cpp

index eec4c43..0d948dd 100644 (file)
@@ -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,
index ea93e5c..4d7c754 100644 (file)
@@ -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)
index 15d7959..4533597 100644 (file)
@@ -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);
index c1519a2..f1332f3 100644 (file)
@@ -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;
         }
index d1a511f..1a182da 100644 (file)
@@ -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);
index bfb2b34..066672c 100644 (file)
@@ -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())
index d60f565..cf24f19 100644 (file)
@@ -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
 
index bf811aa..770dda4 100644 (file)
@@ -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
     
index cfd99ad..7022ffb 100644 (file)
@@ -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;
     }