Remove relocations for InterfaceInfo_t::m_pMethodTable for Linux ARM
authorGleb Balykov <g.balykov@samsung.com>
Thu, 22 Jun 2017 17:24:54 +0000 (20:24 +0300)
committerGleb Balykov <g.balykov@samsung.com>
Mon, 10 Jul 2017 13:37:05 +0000 (16:37 +0300)
src/vm/array.cpp
src/vm/methodtable.cpp
src/vm/methodtable.h

index d679294..3f5a8aa 100644 (file)
@@ -509,8 +509,11 @@ MethodTable* Module::CreateArrayMethodTable(TypeHandle elemTypeHnd, CorElementTy
 #endif // !defined(_WIN64) && (DATA_ALIGNMENT > 4)
     pMT->SetBaseSize(baseSize);
     // Because of array method table persisting, we need to copy the map
-    memcpy(pMTHead + imapOffset, pParentClass->GetInterfaceMap(),
-           pParentClass->GetNumInterfaces() * sizeof(InterfaceInfo_t));
+    for (unsigned index = 0; index < pParentClass->GetNumInterfaces(); ++index)
+    {
+      InterfaceInfo_t *pIntInfo = (InterfaceInfo_t *) (pMTHead + imapOffset + index * sizeof(InterfaceInfo_t));
+      pIntInfo->SetMethodTable((pParentClass->GetInterfaceMap() + index)->GetMethodTable());
+    }
     pMT->SetInterfaceMap(pParentClass->GetNumInterfaces(), (InterfaceInfo_t *)(pMTHead + imapOffset));
 
     // Copy down flags for these interfaces as well. This is simplified a bit since we know that System.Array
index 4a29684..567f2b6 100644 (file)
@@ -1236,7 +1236,12 @@ void MethodTable::AddDynamicInterface(MethodTable *pItfMT)
     if (TotalNumInterfaces > 0) {
         InterfaceInfo_t *pInterfaceMap = GetInterfaceMap();
         PREFIX_ASSUME(pInterfaceMap != NULL);
-        memcpy(pNewItfMap, pInterfaceMap, TotalNumInterfaces * sizeof(InterfaceInfo_t));
+
+        for (unsigned index = 0; index < TotalNumInterfaces; ++index)
+        {
+          InterfaceInfo_t *pIntInfo = (InterfaceInfo_t *) (pNewItfMap + index);
+          pIntInfo->SetMethodTable((pInterfaceMap + index)->GetMethodTable());
+        }
     }
 
     // Add the new interface at the end of the map.
@@ -4284,16 +4289,32 @@ void MethodTable::Save(DataImage *image, DWORD profilingFlags)
         // Dynamic interface maps have an additional DWORD_PTR preceding the InterfaceInfo_t array
         if (HasDynamicInterfaceMap())
         {
-            ZapStoredStructure * pInterfaceMapNode = image->StoreInternedStructure(((DWORD_PTR *)GetInterfaceMap()) - 1, 
-                                                                                   GetInterfaceMapSize(), 
-                                                                                   DataImage::ITEM_INTERFACE_MAP);
-                                                                                   
+            ZapStoredStructure * pInterfaceMapNode;
+            if (decltype(InterfaceInfo_t::m_pMethodTable)::isRelative)
+            {
+                pInterfaceMapNode = image->StoreStructure(((DWORD_PTR *)GetInterfaceMap()) - 1,
+                                                          GetInterfaceMapSize(),
+                                                          DataImage::ITEM_INTERFACE_MAP);
+            }
+            else
+            {
+                pInterfaceMapNode = image->StoreInternedStructure(((DWORD_PTR *)GetInterfaceMap()) - 1,
+                                                                  GetInterfaceMapSize(),
+                                                                  DataImage::ITEM_INTERFACE_MAP);
+            }
             image->BindPointer(GetInterfaceMap(), pInterfaceMapNode, sizeof(DWORD_PTR));
         }
         else
 #endif // FEATURE_COMINTEROP
         {
-            image->StoreInternedStructure(GetInterfaceMap(), GetInterfaceMapSize(), DataImage::ITEM_INTERFACE_MAP);
+            if (decltype(InterfaceInfo_t::m_pMethodTable)::isRelative)
+            {
+                image->StoreStructure(GetInterfaceMap(), GetInterfaceMapSize(), DataImage::ITEM_INTERFACE_MAP);
+            }
+            else
+            {
+                image->StoreInternedStructure(GetInterfaceMap(), GetInterfaceMapSize(), DataImage::ITEM_INTERFACE_MAP);
+            }
         }
 
         SaveExtraInterfaceInfo(image);
index fcc9779..92a61f4 100644 (file)
@@ -110,25 +110,40 @@ struct InterfaceInfo_t
     friend class NativeImageDumper;
 #endif
 
-    FixupPointer<PTR_MethodTable> m_pMethodTable;        // Method table of the interface
+    // Method table of the interface
+#if defined(PLATFORM_UNIX) && defined(_TARGET_ARM_)
+    RelativeFixupPointer<PTR_MethodTable> m_pMethodTable;
+#else
+    FixupPointer<PTR_MethodTable> m_pMethodTable;
+#endif
 
 public:
     FORCEINLINE PTR_MethodTable GetMethodTable()
     {
         LIMITED_METHOD_CONTRACT;
-        return m_pMethodTable.GetValue();
+        return ReadPointerMaybeNull(this, &InterfaceInfo_t::m_pMethodTable);
     }
 
 #ifndef DACCESS_COMPILE
     void SetMethodTable(MethodTable * pMT)
     {
         LIMITED_METHOD_CONTRACT;
-        m_pMethodTable.SetValue(pMT);
+        m_pMethodTable.SetValueMaybeNull(pMT);
     }
 
     // Get approximate method table. This is used by the type loader before the type is fully loaded.
     PTR_MethodTable GetApproxMethodTable(Module * pContainingModule);
-#endif
+#endif // !DACCESS_COMPILE
+
+#ifndef DACCESS_COMPILE
+    InterfaceInfo_t(InterfaceInfo_t &right)
+    {
+        m_pMethodTable.SetValueMaybeNull(right.m_pMethodTable.GetValueMaybeNull());
+    }
+#else // !DACCESS_COMPILE
+private:
+    InterfaceInfo_t(InterfaceInfo_t &right);
+#endif // !DACCESS_COMPILE
 };  // struct InterfaceInfo_t
 
 typedef DPTR(InterfaceInfo_t) PTR_InterfaceInfo;