Remove relocations from SECTION_Readonly for fields not accessed from jit code on ARM
authorGleb Balykov <g.balykov@samsung.com>
Wed, 21 Jun 2017 16:48:49 +0000 (19:48 +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/b4786838985ca249cca04a7d0676ae57ee61ca2b

src/coreclr/src/debug/daccess/nidump.cpp
src/coreclr/src/inc/fixuppointer.h
src/coreclr/src/vm/ceeload.cpp
src/coreclr/src/vm/ceeload.h
src/coreclr/src/vm/dataimage.h
src/coreclr/src/vm/methodtable.cpp
src/coreclr/src/vm/methodtable.h
src/coreclr/src/vm/methodtable.inl

index cd5ba83..67a19cf 100644 (file)
@@ -3947,7 +3947,7 @@ void NativeImageDumper::DumpModule( PTR_Module module )
     DisplayWriteFieldInt( numElementsHot, ctorInfo->numElementsHot,
                           ModuleCtorInfo, SLIM_MODULE_TBLS );
     DisplayWriteFieldAddress( ppMT, DPtrToPreferredAddr(ctorInfo->ppMT),
-                              ctorInfo->numElements * sizeof(MethodTable*),
+                              ctorInfo->numElements * sizeof(RelativePointer<MethodTable*>),
                               ModuleCtorInfo, SLIM_MODULE_TBLS );
     /* REVISIT_TODO Tue 03/21/2006
      * is cctorInfoHot and cctorInfoCold actually have anything interesting
@@ -7259,7 +7259,7 @@ NativeImageDumper::DumpMethodTable( PTR_MethodTable mt, const char * name,
     {
         PTR_InterfaceInfo ifMap = mt->GetInterfaceMap();
         m_display->StartArrayWithOffset( "InterfaceMap",
-                                         offsetof(MethodTable, m_pMultipurposeSlot2),
+                                         offsetof(MethodTable, m_pInterfaceMap),
                                          sizeof(void*),
                                          NULL );
         for( unsigned i = 0; i < mt->GetNumInterfaces(); ++i )
@@ -7293,7 +7293,7 @@ NativeImageDumper::DumpMethodTable( PTR_MethodTable mt, const char * name,
                                              DPtrToPreferredAddr(genStatics),
                                              sizeof(*genStatics) );
 
-        PTR_FieldDesc fieldDescs = genStatics->m_pFieldDescs;
+        PTR_FieldDesc fieldDescs = ReadPointerMaybeNull((GenericsStaticsInfo *) genStatics, &GenericsStaticsInfo::m_pFieldDescs);
         if( fieldDescs == NULL )
         {
             DisplayWriteFieldPointer( m_pFieldDescs, NULL, GenericsStaticsInfo,
index 83ff20e..20eb9d8 100644 (file)
@@ -141,6 +141,12 @@ public:
         LIMITED_METHOD_CONTRACT;
         SetValueMaybeNull((TADDR)this, addr);
     }
+
+    FORCEINLINE void SetValueVolatile(PTR_TYPE addr)
+    {
+        LIMITED_METHOD_CONTRACT;
+        SetValue(addr);
+    }
 #endif
 
 #ifndef DACCESS_COMPILE
@@ -264,6 +270,9 @@ public:
     RelativeFixupPointer<PTR_TYPE>& operator = (const RelativeFixupPointer<PTR_TYPE> &) =delete;
     RelativeFixupPointer<PTR_TYPE>& operator = (RelativeFixupPointer<PTR_TYPE> &&) =delete;
 
+    // Default constructor
+    RelativeFixupPointer<PTR_TYPE>() {}
+
     // Returns whether the encoded pointer is NULL.
     BOOL IsNull() const
     {
@@ -468,7 +477,6 @@ public:
     PTR_TYPE GetValue(TADDR base) const
     {
         LIMITED_METHOD_DAC_CONTRACT;
-        PRECONDITION(!IsNull());
         return dac_cast<PTR_TYPE>(m_ptr);
     }
 
@@ -480,6 +488,13 @@ public:
     }
 
     // Returns value of the encoded pointer. The pointer can be NULL.
+    PTR_TYPE GetValueMaybeNull() const
+    {
+        LIMITED_METHOD_DAC_CONTRACT;
+        return dac_cast<PTR_TYPE>(m_ptr);
+    }
+
+    // Returns value of the encoded pointer. The pointer can be NULL.
     PTR_TYPE GetValueMaybeNull(TADDR base) const
     {
         LIMITED_METHOD_DAC_CONTRACT;
@@ -493,6 +508,7 @@ public:
         return dac_cast<DPTR(PlainPointer<PTR_TYPE>)>(base)->GetValueMaybeNull(base);
     }
 
+#ifndef DACCESS_COMPILE
     void SetValue(PTR_TYPE addr)
     {
         LIMITED_METHOD_CONTRACT;
@@ -503,7 +519,6 @@ public:
     void SetValue(TADDR base, PTR_TYPE addr)
     {
         LIMITED_METHOD_CONTRACT;
-        PRECONDITION(addr != NULL);
         m_ptr = dac_cast<TADDR>(addr);
     }
 
@@ -521,7 +536,6 @@ public:
         m_ptr = dac_cast<TADDR>(addr);
     }
 
-#ifndef DACCESS_COMPILE
     // Set encoded value of the pointer. The value can be NULL.
     // Does not need explicit base and thus can be used in non-DAC builds only.
     FORCEINLINE void SetValueMaybeNull(PTR_TYPE addr)
@@ -529,7 +543,6 @@ public:
         LIMITED_METHOD_CONTRACT;
         return SetValueMaybeNull((TADDR)this, addr);
     }
-#endif
 
     // Static version of SetValueMaybeNull. It is meant to simplify access to arrays of pointers.
     FORCEINLINE static void SetValueMaybeNullAtPtr(TADDR base, PTR_TYPE addr)
@@ -538,6 +551,13 @@ public:
         dac_cast<DPTR(PlainPointer<PTR_TYPE>)>(base)->SetValueMaybeNull(base, addr);
     }
 
+    FORCEINLINE void SetValueVolatile(PTR_TYPE addr)
+    {
+        LIMITED_METHOD_CONTRACT;
+        VolatileStore((PTR_TYPE *)(&m_ptr), addr);
+    }
+#endif
+
 private:
     TADDR m_ptr;
 };
index 49068fc..857c67e 100644 (file)
@@ -2883,7 +2883,7 @@ BOOL Module::IsPreV4Assembly()
 }
 
 
-ArrayDPTR(FixupPointer<PTR_MethodTable>) ModuleCtorInfo::GetGCStaticMTs(DWORD index)
+ArrayDPTR(RelativeFixupPointer<PTR_MethodTable>) ModuleCtorInfo::GetGCStaticMTs(DWORD index)
 {
     LIMITED_METHOD_CONTRACT;
 
@@ -8252,6 +8252,8 @@ void Module::SaveTypeHandle(DataImage *  image,
 #endif // _DEBUG
 }
 
+#ifndef DACCESS_COMPILE
+
 void ModuleCtorInfo::Save(DataImage *image, CorProfileData *profileData)
 {
     STANDARD_VM_CONTRACT;
@@ -8273,7 +8275,7 @@ void ModuleCtorInfo::Save(DataImage *image, CorProfileData *profileData)
     // items numElementsHot...i-1 are cold
     for (i = 0; i < numElements; i++)
     {
-        MethodTable *ppMTTemp = ppMT[i];
+        MethodTable *ppMTTemp = ppMT[i].GetValue();
 
         // Count the number of boxed statics along the way
         totalBoxedStatics += ppMTTemp->GetNumBoxedRegularStatics();
@@ -8287,8 +8289,8 @@ void ModuleCtorInfo::Save(DataImage *image, CorProfileData *profileData)
         if (hot)
         {
             // swap ppMT[i] and ppMT[numElementsHot] to maintain the loop invariant
-            ppMT[i] = ppMT[numElementsHot];
-            ppMT[numElementsHot] = ppMTTemp;
+            ppMT[i].SetValue(ppMT[numElementsHot].GetValue());
+            ppMT[numElementsHot].SetValue(ppMTTemp);
 
             numElementsHot++;
         }
@@ -8313,11 +8315,11 @@ void ModuleCtorInfo::Save(DataImage *image, CorProfileData *profileData)
 
     for (i = 0; i < numElementsHot; i++)
     {
-        hashArray[i] = GenerateHash(ppMT[i], HOT);
+        hashArray[i] = GenerateHash(ppMT[i].GetValue(), HOT);
     }
     for (i = numElementsHot; i < numElements; i++)
     {
-        hashArray[i] = GenerateHash(ppMT[i], COLD);
+        hashArray[i] = GenerateHash(ppMT[i].GetValue(), COLD);
     }
 
     // Sort the two arrays by hash values to create regions with the same hash values.
@@ -8380,7 +8382,7 @@ void ModuleCtorInfo::Save(DataImage *image, CorProfileData *profileData)
     // make cctorInfoCold point to the first cold element
     cctorInfoCold   = cctorInfoHot + numElementsHot;
 
-    ppHotGCStaticsMTs   = (totalBoxedStatics != 0) ? new FixupPointer<PTR_MethodTable>[totalBoxedStatics] : NULL;
+    ppHotGCStaticsMTs   = (totalBoxedStatics != 0) ? new RelativeFixupPointer<PTR_MethodTable>[totalBoxedStatics] : NULL;
     numHotGCStaticsMTs  = totalBoxedStatics;
 
     DWORD iGCStaticMT = 0;
@@ -8396,7 +8398,7 @@ void ModuleCtorInfo::Save(DataImage *image, CorProfileData *profileData)
             ppColdGCStaticsMTs = ppHotGCStaticsMTs + numHotGCStaticsMTs;
         }
 
-        MethodTable* pMT = ppMT[i];
+        MethodTable* pMT = ppMT[i].GetValue();
         ClassCtorInfoEntry* pEntry = &cctorInfoHot[i];
 
         WORD numBoxedStatics = pMT->GetNumBoxedRegularStatics();
@@ -8426,7 +8428,7 @@ void ModuleCtorInfo::Save(DataImage *image, CorProfileData *profileData)
                     == (iGCStaticMT - pEntry->firstBoxedStaticMTIndex) * sizeof(MethodTable*));
 
                 TypeHandle th = pField->GetFieldTypeHandleThrowing();
-                ppHotGCStaticsMTs[iGCStaticMT++].SetValue(th.GetMethodTable());
+                ppHotGCStaticsMTs[iGCStaticMT++].SetValueMaybeNull(th.GetMethodTable());
 
                 numFoundBoxedStatics++;
             }
@@ -8449,7 +8451,7 @@ void ModuleCtorInfo::Save(DataImage *image, CorProfileData *profileData)
 
     if (numElements > 0)
         image->StoreStructure(ppMT,
-                                sizeof(MethodTable *) * numElements,
+                                sizeof(RelativePointer<MethodTable *>) * numElements,
                                 DataImage::ITEM_MODULE_CCTOR_INFO_HOT);
 
     if (numElements > numElementsHot)
@@ -8466,7 +8468,7 @@ void ModuleCtorInfo::Save(DataImage *image, CorProfileData *profileData)
     if ( numHotGCStaticsMTs )
     {
         // Save the mt templates
-        image->StoreStructure( ppHotGCStaticsMTs, numHotGCStaticsMTs * sizeof(MethodTable*),
+        image->StoreStructure( ppHotGCStaticsMTs, numHotGCStaticsMTs * sizeof(RelativeFixupPointer<MethodTable*>),
                                 DataImage::ITEM_GC_STATIC_HANDLES_HOT);
     }
     else
@@ -8477,7 +8479,7 @@ void ModuleCtorInfo::Save(DataImage *image, CorProfileData *profileData)
     if ( numColdGCStaticsMTs )
     {
         // Save the hot mt templates
-        image->StoreStructure( ppColdGCStaticsMTs, numColdGCStaticsMTs * sizeof(MethodTable*),
+        image->StoreStructure( ppColdGCStaticsMTs, numColdGCStaticsMTs * sizeof(RelativeFixupPointer<MethodTable*>),
                                 DataImage::ITEM_GC_STATIC_HANDLES_COLD);
     }
     else
@@ -8486,6 +8488,7 @@ void ModuleCtorInfo::Save(DataImage *image, CorProfileData *profileData)
     }
 }
 
+#endif // !DACCESS_COMPILE
 
 bool Module::AreAllClassesFullyLoaded()
 {
@@ -9622,7 +9625,7 @@ void ModuleCtorInfo::Fixup(DataImage *image)
 
         for (DWORD i=0; i<numElements; i++)
         {
-            image->FixupPointerField(ppMT, i * sizeof(ppMT[0]));
+            image->FixupRelativePointerField(ppMT, i * sizeof(ppMT[0]));
         }
     }
     else
@@ -14018,7 +14021,7 @@ ModuleCtorInfo::EnumMemoryRegions(CLRDataEnumMemoryFlags flags)
 
     // This class is contained so do not enumerate 'this'.
     DacEnumMemoryRegion(dac_cast<TADDR>(ppMT), numElements *
-                        sizeof(TADDR));
+                        sizeof(RelativePointer<MethodTable *>));
     DacEnumMemoryRegion(dac_cast<TADDR>(cctorInfoHot), numElementsHot *
                         sizeof(ClassCtorInfoEntry));
     DacEnumMemoryRegion(dac_cast<TADDR>(cctorInfoCold),
index 0896c9b..15d7959 100644 (file)
@@ -618,7 +618,7 @@ struct ModuleCtorInfo
     DWORD                   numElements;
     DWORD                   numLastAllocated;
     DWORD                   numElementsHot;
-    DPTR(PTR_MethodTable)   ppMT;           // size is numElements
+    DPTR(RelativePointer<PTR_MethodTable>) ppMT; // size is numElements
     PTR_ClassCtorInfoEntry  cctorInfoHot;   // size is numElementsHot
     PTR_ClassCtorInfoEntry  cctorInfoCold;  // size is numElements-numElementsHot
 
@@ -627,8 +627,8 @@ struct ModuleCtorInfo
     DWORD                   numHotHashes;
     DWORD                   numColdHashes;
 
-    ArrayDPTR(FixupPointer<PTR_MethodTable>) ppHotGCStaticsMTs;            // hot table
-    ArrayDPTR(FixupPointer<PTR_MethodTable>) ppColdGCStaticsMTs;           // cold table
+    ArrayDPTR(RelativeFixupPointer<PTR_MethodTable>) ppHotGCStaticsMTs;            // hot table
+    ArrayDPTR(RelativeFixupPointer<PTR_MethodTable>) ppColdGCStaticsMTs;           // cold table
 
     DWORD                   numHotGCStaticsMTs;
     DWORD                   numColdGCStaticsMTs;
@@ -664,7 +664,13 @@ struct ModuleCtorInfo
         return hashVal;
     };
 
-    ArrayDPTR(FixupPointer<PTR_MethodTable>) GetGCStaticMTs(DWORD index);
+    ArrayDPTR(RelativeFixupPointer<PTR_MethodTable>) GetGCStaticMTs(DWORD index);
+
+    PTR_MethodTable GetMT(DWORD i)
+    {
+        LIMITED_METHOD_DAC_CONTRACT;
+        return ppMT[i].GetValue(dac_cast<TADDR>(ppMT) + i * sizeof(RelativePointer<PTR_MethodTable>));
+    }
 
 #ifdef FEATURE_PREJIT
 
@@ -675,11 +681,11 @@ struct ModuleCtorInfo
     class ClassCtorInfoEntryArraySort : public CQuickSort<DWORD>
     {
     private:
-        PTR_MethodTable *m_pBase1;
+        DPTR(RelativePointer<PTR_MethodTable>) m_pBase1;
 
     public:
         //Constructor
-        ClassCtorInfoEntryArraySort(DWORD *base, PTR_MethodTable *base1, int count)
+        ClassCtorInfoEntryArraySort(DWORD *base, DPTR(RelativePointer<PTR_MethodTable>) base1, int count)
           : CQuickSort<DWORD>(base, count)
         {
             WRAPPER_NO_CONTRACT;
@@ -700,6 +706,7 @@ struct ModuleCtorInfo
                 return 1;
         }
         
+#ifndef DACCESS_COMPILE
         // Swap is overwriten so that we can sort both the MethodTable pointer
         // array and the ClassCtorInfoEntry array in parrallel.
         FORCEINLINE void Swap(SSIZE_T iFirst, SSIZE_T iSecond)
@@ -715,10 +722,11 @@ struct ModuleCtorInfo
             m_pBase[iFirst] = m_pBase[iSecond];
             m_pBase[iSecond] = sTemp;
 
-            sTemp1 = m_pBase1[iFirst];
-            m_pBase1[iFirst] = m_pBase1[iSecond];
-            m_pBase1[iSecond] = sTemp1;
+            sTemp1 = m_pBase1[iFirst].GetValueMaybeNull();
+            m_pBase1[iFirst].SetValueMaybeNull(m_pBase1[iSecond].GetValueMaybeNull());
+            m_pBase1[iSecond].SetValueMaybeNull(sTemp1);
         }
+#endif // !DACCESS_COMPILE
     };
 #endif // FEATURE_PREJIT
 };
index 5d48a71..0167ec5 100644 (file)
@@ -309,8 +309,58 @@ public:
     void FixupPointerField(PVOID p, SSIZE_T offset);
     void FixupRelativePointerField(PVOID p, SSIZE_T offset);
 
+    template<typename T, typename PT>
+    void FixupPlainOrRelativePointerField(const T *base, const RelativePointer<PT> T::* pPointerFieldMember)
+    {
+        STANDARD_VM_CONTRACT;
+        SSIZE_T offset = (SSIZE_T) &(base->*pPointerFieldMember) - (SSIZE_T) base;
+        FixupRelativePointerField((PVOID)base, offset);
+    }
+
+    template<typename T, typename C, typename PT>
+    void FixupPlainOrRelativePointerField(const T *base, const C T::* pFirstPointerFieldMember, const RelativePointer<PT> C::* pSecondPointerFieldMember)
+    {
+        STANDARD_VM_CONTRACT;
+        const RelativePointer<PT> *ptr = &(base->*pFirstPointerFieldMember.*pSecondPointerFieldMember);
+        SSIZE_T offset = (SSIZE_T) ptr - (SSIZE_T) base;
+        FixupRelativePointerField((PVOID)base, offset);
+    }
+
+    template<typename T, typename PT>
+    void FixupPlainOrRelativePointerField(const T *base, const PlainPointer<PT> T::* pPointerFieldMember)
+    {
+        STANDARD_VM_CONTRACT;
+        SSIZE_T offset = (SSIZE_T) &(base->*pPointerFieldMember) - (SSIZE_T) base;
+        FixupPointerField((PVOID)base, offset);
+    }
+
+    template<typename T, typename C, typename PT>
+    void FixupPlainOrRelativePointerField(const T *base, const C T::* pFirstPointerFieldMember, const PlainPointer<PT> C::* pSecondPointerFieldMember)
+    {
+        STANDARD_VM_CONTRACT;
+        const PlainPointer<PT> *ptr = &(base->*pFirstPointerFieldMember.*pSecondPointerFieldMember);
+        SSIZE_T offset = (SSIZE_T) ptr - (SSIZE_T) base;
+        FixupPointerField((PVOID)base, offset);
+    }
+
     void FixupField(PVOID p, SSIZE_T offset, PVOID pTarget, SSIZE_T targetOffset = 0, ZapRelocationType type = IMAGE_REL_BASED_PTR);
 
+    template<typename T, typename PT>
+    void FixupPlainOrRelativeField(const T *base, const RelativePointer<PT> T::* pPointerFieldMember, PVOID pTarget, SSIZE_T targetOffset = 0)
+    {
+        STANDARD_VM_CONTRACT;
+        SSIZE_T offset = (SSIZE_T) &(base->*pPointerFieldMember) - (SSIZE_T) base;
+        FixupField((PVOID)base, offset, pTarget, targetOffset, IMAGE_REL_BASED_RELPTR);
+    }
+
+    template<typename T, typename PT>
+    void FixupPlainOrRelativeField(const T *base, const PlainPointer<PT> T::* pPointerFieldMember, PVOID pTarget, SSIZE_T targetOffset = 0)
+    {
+        STANDARD_VM_CONTRACT;
+        SSIZE_T offset = (SSIZE_T) &(base->*pPointerFieldMember) - (SSIZE_T) base;
+        FixupField((PVOID)base, offset, pTarget, targetOffset, IMAGE_REL_BASED_PTR);
+    }
+
     void FixupFieldToNode(PVOID p, SSIZE_T offset, ZapNode * pTarget, SSIZE_T targetOffset = 0, ZapRelocationType type = IMAGE_REL_BASED_PTR);
 
     void FixupFieldToNode(PVOID p, SSIZE_T offset, ZapStoredStructure * pTarget, SSIZE_T targetOffset = 0, ZapRelocationType type = IMAGE_REL_BASED_PTR)
@@ -318,6 +368,34 @@ public:
         return FixupFieldToNode(p, offset, (ZapNode *)pTarget, targetOffset, type);
     }
 
+    template<typename T, typename PT>
+    void FixupPlainOrRelativeFieldToNode(const T *base, const RelativePointer<PT> T::* pPointerFieldMember, ZapNode * pTarget, SSIZE_T targetOffset = 0)
+    {
+        STANDARD_VM_CONTRACT;
+        SSIZE_T offset = (SSIZE_T) &(base->*pPointerFieldMember) - (SSIZE_T) base;
+        FixupFieldToNode((PVOID)base, offset, pTarget, targetOffset, IMAGE_REL_BASED_RELPTR);
+    }
+
+    template<typename T, typename PT>
+    void FixupPlainOrRelativeFieldToNode(const T *base, const RelativePointer<PT> T::* pPointerFieldMember, ZapStoredStructure * pTarget, SSIZE_T targetOffset = 0)
+    {
+        return FixupPlainOrRelativeFieldToNode(base, pPointerFieldMember, (ZapNode *)pTarget, targetOffset);
+    }
+
+    template<typename T, typename PT>
+    void FixupPlainOrRelativeFieldToNode(const T *base, const PlainPointer<PT> T::* pPointerFieldMember, ZapNode * pTarget, SSIZE_T targetOffset = 0)
+    {
+        STANDARD_VM_CONTRACT;
+        SSIZE_T offset = (SSIZE_T) &(base->*pPointerFieldMember) - (SSIZE_T) base;
+        FixupFieldToNode((PVOID)base, offset, pTarget, targetOffset, IMAGE_REL_BASED_PTR);
+    }
+
+    template<typename T, typename PT>
+    void FixupPlainOrRelativeFieldToNode(const T *base, const PlainPointer<PT> T::* pPointerFieldMember, ZapStoredStructure * pTarget, SSIZE_T targetOffset = 0)
+    {
+        return FixupPlainOrRelativeFieldToNode(base, pPointerFieldMember, (ZapNode *)pTarget, targetOffset);
+    }
+
     BOOL IsStored(const void *data)
       { WRAPPER_NO_CONTRACT; return m_structures.LookupPtr(data) != NULL; }
 
index 66a6a2e..4a29684 100644 (file)
@@ -1013,7 +1013,7 @@ void MethodTable::SetInterfaceMap(WORD wNumInterfaces, InterfaceInfo_t* iMap)
     m_wNumInterfaces = wNumInterfaces;
 
     CONSISTENCY_CHECK(IS_ALIGNED(iMap, sizeof(void*)));
-    m_pInterfaceMap = iMap;
+    m_pInterfaceMap.SetValue(iMap);
 }
 
 //==========================================================================================
@@ -1246,7 +1246,8 @@ void MethodTable::AddDynamicInterface(MethodTable *pItfMT)
     *(((DWORD_PTR *)pNewItfMap) - 1) = NumDynAddedInterfaces + 1;
 
     // Switch the old interface map with the new one.
-    VolatileStore(EnsureWritablePages(&m_pInterfaceMap), pNewItfMap);
+    EnsureWritablePages(&m_pInterfaceMap);
+    m_pInterfaceMap.SetValueVolatile(pNewItfMap);
 
     // Log the fact that we leaked the interface vtable map.
 #ifdef _DEBUG
@@ -1287,7 +1288,7 @@ void MethodTable::SetupGenericsStaticsInfo(FieldDesc* pStaticFieldDescs)
         pInfo->m_DynamicTypeID = (SIZE_T)-1;
     }
 
-    pInfo->m_pFieldDescs = pStaticFieldDescs;
+    pInfo->m_pFieldDescs.SetValueMaybeNull(pStaticFieldDescs);
 }
 
 #endif // !DACCESS_COMPILE
@@ -3147,7 +3148,7 @@ void MethodTable::AllocateRegularStaticBoxes()
         OBJECTREF* pStaticSlots = (OBJECTREF*)(pStaticBase + pClassCtorInfoEntry->firstBoxedStaticOffset);
         GCPROTECT_BEGININTERIOR(pStaticSlots);
 
-        ArrayDPTR(FixupPointer<PTR_MethodTable>) ppMTs = GetLoaderModule()->GetZapModuleCtorInfo()->
+        ArrayDPTR(RelativeFixupPointer<PTR_MethodTable>) ppMTs = GetLoaderModule()->GetZapModuleCtorInfo()->
             GetGCStaticMTs(pClassCtorInfoEntry->firstBoxedStaticMTIndex);
 
         DWORD numBoxedStatics = pClassCtorInfoEntry->numBoxedStatics;
@@ -4122,7 +4123,7 @@ void ModuleCtorInfo::AddElement(MethodTable *pMethodTable)
     {
         _ASSERTE(numElements == numLastAllocated);
 
-        MethodTable ** ppOldMTEntries = ppMT;
+        RelativePointer<MethodTable *> *ppOldMTEntries = ppMT;
 
 #ifdef _PREFAST_ 
 #pragma warning(push)
@@ -4133,12 +4134,19 @@ void ModuleCtorInfo::AddElement(MethodTable *pMethodTable)
 #pragma warning(pop)
 #endif // _PREFAST_
 
-        ppMT = new MethodTable* [numNewAllocated];
+        ppMT = new RelativePointer<MethodTable *> [numNewAllocated];
 
         _ASSERTE(ppMT);
 
-        memcpy(ppMT, ppOldMTEntries, sizeof(MethodTable *) * numLastAllocated);
-        memset(ppMT + numLastAllocated, 0, sizeof(MethodTable *) * (numNewAllocated - numLastAllocated));
+        for (unsigned index = 0; index < numLastAllocated; ++index)
+        {
+            ppMT[index].SetValueMaybeNull(ppOldMTEntries[index].GetValueMaybeNull());
+        }
+
+        for (unsigned index = numLastAllocated; index < numNewAllocated; ++index)
+        {
+            ppMT[index].SetValueMaybeNull(NULL);
+        }
 
         delete[] ppOldMTEntries;
 
@@ -4150,7 +4158,7 @@ void ModuleCtorInfo::AddElement(MethodTable *pMethodTable)
     // Note the use of two "parallel" arrays.  We do this to keep the workingset smaller since we
     // often search (in GetClassCtorInfoIfExists) for a methodtable pointer but never actually find it.
 
-    ppMT[numElements] = pMethodTable;
+    ppMT[numElements].SetValue(pMethodTable);
     numElements++;
 }
 
@@ -4694,7 +4702,7 @@ void MethodTable::Fixup(DataImage *image)
     if (IsCanonicalMethodTable())
     {
         // Pointer to EEClass
-        image->FixupPointerField(this, offsetof(MethodTable, m_pEEClass));
+        image->FixupPlainOrRelativePointerField(this, &MethodTable::m_pEEClass);
     }
     else
     {
@@ -4709,7 +4717,7 @@ void MethodTable::Fixup(DataImage *image)
             if (image->CanHardBindToZapModule(pCanonMT->GetLoaderModule()))
             {
                 // Pointer to canonical methodtable
-                image->FixupField(this, offsetof(MethodTable, m_pCanonMT), pCanonMT, UNION_METHODTABLE);
+                image->FixupPlainOrRelativeField(this, &MethodTable::m_pCanonMT, pCanonMT, UNION_METHODTABLE);
             }
             else
             {
@@ -4727,11 +4735,11 @@ void MethodTable::Fixup(DataImage *image)
 
         if (pImport != NULL)
         {
-            image->FixupFieldToNode(this, offsetof(MethodTable, m_pCanonMT), pImport, UNION_INDIRECTION);
+            image->FixupPlainOrRelativeFieldToNode(this, &MethodTable::m_pCanonMT, pImport, UNION_INDIRECTION);
         }
     }
 
-    image->FixupField(this, offsetof(MethodTable, m_pLoaderModule), pZapModule);
+    image->FixupField(this, offsetof(MethodTable, m_pLoaderModule), pZapModule, 0, IMAGE_REL_BASED_RELPTR);
 
 #ifdef _DEBUG
     image->FixupPointerField(this, offsetof(MethodTable, debug_m_szClassName));
@@ -4800,7 +4808,7 @@ void MethodTable::Fixup(DataImage *image)
 
     if (HasInterfaceMap())
     {
-        image->FixupPointerField(this, offsetof(MethodTable, m_pMultipurposeSlot2));
+        image->FixupPlainOrRelativePointerField(this, &MethodTable::m_pInterfaceMap);
 
         FixupExtraInterfaceInfo(image);
     }
@@ -5036,7 +5044,7 @@ void MethodTable::Fixup(DataImage *image)
     {
         GenericsStaticsInfo *pInfo = GetGenericsStaticsInfo();
 
-        image->FixupPointerField(this, (BYTE *)&pInfo->m_pFieldDescs - (BYTE *)this);
+        image->FixupRelativePointerField(this, (BYTE *)&pInfo->m_pFieldDescs - (BYTE *)this);
         if (!isCanonical)
         {
             for (DWORD i = 0; i < GetClass()->GetNumStaticFields(); i++)
@@ -5953,9 +5961,9 @@ void MethodTable::DoRestoreTypeKey()
 
     // If we have an indirection cell then restore the m_pCanonMT and its module pointer
     //
-    if (union_getLowBits(m_pCanonMT) == UNION_INDIRECTION)
+    if (union_getLowBits(m_pCanonMT.GetValue()) == UNION_INDIRECTION)
     {
-        Module::RestoreMethodTablePointerRaw((MethodTable **)(union_getPointer(m_pCanonMT)), 
+        Module::RestoreMethodTablePointerRaw((MethodTable **)(union_getPointer(m_pCanonMT.GetValue())),
             GetLoaderModule(), CLASS_LOAD_UNRESTORED);
     }
 
@@ -7596,7 +7604,7 @@ BOOL MethodTable::SanityCheck()
     // strings have component size2, all other non-arrays should have 0
     _ASSERTE((GetComponentSize() <= 2) || IsArray());
 
-    if (m_pEEClass == NULL)
+    if (m_pEEClass.IsNull())
     {
         if (IsAsyncPinType())
         {
@@ -7736,7 +7744,7 @@ ClassCtorInfoEntry* MethodTable::GetClassCtorInfoIfExists()
     if (HasBoxedRegularStatics())
     {
         ModuleCtorInfo *pModuleCtorInfo = GetZapModule()->GetZapModuleCtorInfo();
-        DPTR(PTR_MethodTable) ppMT = pModuleCtorInfo->ppMT;
+        DPTR(RelativePointer<PTR_MethodTable>) ppMT = pModuleCtorInfo->ppMT;
         PTR_DWORD hotHashOffsets = pModuleCtorInfo->hotHashOffsets;
         PTR_DWORD coldHashOffsets = pModuleCtorInfo->coldHashOffsets;
 
@@ -7747,8 +7755,8 @@ ClassCtorInfoEntry* MethodTable::GetClassCtorInfoIfExists()
 
             for (DWORD i = hotHashOffsets[hash]; i != hotHashOffsets[hash + 1]; i++)
             {
-                _ASSERTE(ppMT[i]);
-                if (dac_cast<TADDR>(ppMT[i]) == dac_cast<TADDR>(this))
+                _ASSERTE(!ppMT[i].IsNull());
+                if (dac_cast<TADDR>(pModuleCtorInfo->GetMT(i)) == dac_cast<TADDR>(this))
                 {
                     return pModuleCtorInfo->cctorInfoHot + i;
                 }
@@ -7762,8 +7770,8 @@ ClassCtorInfoEntry* MethodTable::GetClassCtorInfoIfExists()
 
             for (DWORD i = coldHashOffsets[hash]; i != coldHashOffsets[hash + 1]; i++)
             {
-                _ASSERTE(ppMT[i]);
-                if (dac_cast<TADDR>(ppMT[i]) == dac_cast<TADDR>(this))
+                _ASSERTE(!ppMT[i].IsNull());
+                if (dac_cast<TADDR>(pModuleCtorInfo->GetMT(i)) == dac_cast<TADDR>(this))
                 {
                     return pModuleCtorInfo->cctorInfoCold + (i - pModuleCtorInfo->numElementsHot);
                 }
index d3eb0ce..fcc9779 100644 (file)
@@ -247,7 +247,7 @@ typedef DPTR(GenericsDictInfo) PTR_GenericsDictInfo;
 struct GenericsStaticsInfo
 {
     // Pointer to field descs for statics
-    PTR_FieldDesc       m_pFieldDescs;
+    RelativePointer<PTR_FieldDesc> m_pFieldDescs;
 
     // Method table ID for statics
     SIZE_T              m_DynamicTypeID;
@@ -2209,12 +2209,12 @@ public:
     inline void SetClass(EEClass *pClass)
     {
         LIMITED_METHOD_CONTRACT;
-        m_pEEClass = pClass;
+        m_pEEClass.SetValue(pClass);
     }
 
     inline void SetCanonicalMethodTable(MethodTable * pMT)
     {
-        m_pCanonMT = (TADDR)pMT | MethodTable::UNION_METHODTABLE;
+        m_pCanonMT.SetValue((TADDR)pMT | MethodTable::UNION_METHODTABLE);
     }
 #endif
 
@@ -2639,7 +2639,7 @@ public:
     {
         WRAPPER_NO_CONTRACT;
         _ASSERTE(HasGenericsStaticsInfo());
-        return GetGenericsStaticsInfo()->m_pFieldDescs;
+        return ReadPointerMaybeNull((GenericsStaticsInfo *)GetGenericsStaticsInfo(), &GenericsStaticsInfo::m_pFieldDescs);
     }
 
     BOOL HasCrossModuleGenericStaticsInfo()
@@ -4044,7 +4044,7 @@ private:
     // for enum_flag_HasIndirectParentMethodTable.
     TADDR           m_pParentMethodTable;
 
-    PTR_Module      m_pLoaderModule;    // LoaderModule. It is equal to the ZapModule in ngened images
+    RelativePointer<PTR_Module> m_pLoaderModule;    // LoaderModule. It is equal to the ZapModule in ngened images
     
     PTR_MethodTableWriteableData m_pWriteableData;
     
@@ -4058,8 +4058,13 @@ private:
     static const TADDR UNION_MASK = 3; 
 
     union {
-        EEClass *   m_pEEClass;
-        TADDR       m_pCanonMT;
+#if defined(PLATFORM_UNIX) && defined(_TARGET_ARM_)
+        RelativePointer<DPTR(EEClass)> m_pEEClass;
+        RelativePointer<TADDR> m_pCanonMT;
+#else
+        PlainPointer<DPTR(EEClass)> m_pEEClass;
+        PlainPointer<TADDR> m_pCanonMT;
+#endif
     };
 
     __forceinline static LowBits union_getLowBits(TADDR pCanonMT)
@@ -4088,7 +4093,11 @@ private:
     public:
     union
     {
-        InterfaceInfo_t *   m_pInterfaceMap;
+#if defined(PLATFORM_UNIX) && defined(_TARGET_ARM_)
+        RelativePointer<PTR_InterfaceInfo>   m_pInterfaceMap;
+#else
+        PlainPointer<PTR_InterfaceInfo>   m_pInterfaceMap;
+#endif
         TADDR               m_pMultipurposeSlot2;
     };
 
index 9b72d24..eb1abb0 100644 (file)
@@ -23,24 +23,26 @@ inline PTR_EEClass MethodTable::GetClass_NoLogging()
 {
     LIMITED_METHOD_DAC_CONTRACT;
 
+    TADDR addr = ReadPointer(this, &MethodTable::m_pCanonMT);
+
 #ifdef _DEBUG 
-    LowBits lowBits = union_getLowBits(m_pCanonMT);
+    LowBits lowBits = union_getLowBits(addr);
     if (lowBits == UNION_EECLASS)
     {
-        return PTR_EEClass(m_pCanonMT);
+        return PTR_EEClass(addr);
     }
     else if (lowBits == UNION_METHODTABLE)
     {
         // pointer to canonical MethodTable.
-        TADDR canonicalMethodTable = union_getPointer(m_pCanonMT);
-        return PTR_EEClass(PTR_MethodTable(canonicalMethodTable)->m_pCanonMT);
+        TADDR canonicalMethodTable = union_getPointer(addr);
+        return PTR_EEClass(ReadPointer((MethodTable *) PTR_MethodTable(canonicalMethodTable), &MethodTable::m_pCanonMT));
     }
 #ifdef FEATURE_PREJIT
     else if (lowBits == UNION_INDIRECTION)
     {
         // pointer to indirection cell that points to canonical MethodTable
-        TADDR canonicalMethodTable = *PTR_TADDR(union_getPointer(m_pCanonMT));
-        return PTR_EEClass(PTR_MethodTable(canonicalMethodTable)->m_pCanonMT);
+        TADDR canonicalMethodTable = *PTR_TADDR(union_getPointer(addr));
+        return PTR_EEClass(ReadPointer((MethodTable *) PTR_MethodTable(canonicalMethodTable), &MethodTable::m_pCanonMT));
     }
 #endif
 #ifdef DACCESS_COMPILE
@@ -52,8 +54,6 @@ inline PTR_EEClass MethodTable::GetClass_NoLogging()
 
 #else
 
-    TADDR addr = m_pCanonMT;
-
     if ((addr & 2) == 0)
     {
         // pointer to EEClass
@@ -65,12 +65,12 @@ inline PTR_EEClass MethodTable::GetClass_NoLogging()
     {
         // pointer to indirection cell that points to canonical MethodTable
         TADDR canonicalMethodTable = *PTR_TADDR(addr - 3);
-        return PTR_EEClass(PTR_MethodTable(canonicalMethodTable)->m_pCanonMT);
+        return PTR_EEClass(ReadPointer((MethodTable *) PTR_MethodTable(canonicalMethodTable), &MethodTable::m_pCanonMT));
     }
 #endif
 
     // pointer to canonical MethodTable.
-    return PTR_EEClass(PTR_MethodTable(addr - 2)->m_pCanonMT);
+    return PTR_EEClass(ReadPointer((MethodTable *) PTR_MethodTable(addr - 2), &MethodTable::m_pCanonMT));
 #endif
 }
 
@@ -113,25 +113,27 @@ inline BOOL MethodTable::IsClassPointerValid()
     WRAPPER_NO_CONTRACT;
     SUPPORTS_DAC;
 
-    LowBits lowBits = union_getLowBits(m_pCanonMT);
+    TADDR addr = ReadPointer(this, &MethodTable::m_pCanonMT);
+
+    LowBits lowBits = union_getLowBits(addr);
     if (lowBits == UNION_EECLASS)
     {
-        return (m_pEEClass != NULL);
+        return !m_pEEClass.IsNull();
     }
     else if (lowBits == UNION_METHODTABLE)
     {
         // pointer to canonical MethodTable.
-        TADDR canonicalMethodTable = union_getPointer(m_pCanonMT);
-        return (PTR_MethodTable(canonicalMethodTable)->m_pEEClass != NULL);
+        TADDR canonicalMethodTable = union_getPointer(addr);
+        return !PTR_MethodTable(canonicalMethodTable)->m_pEEClass.IsNull();
     }
 #ifdef FEATURE_PREJIT
     else if (lowBits == UNION_INDIRECTION)
     {
         // pointer to indirection cell that points to canonical MethodTable
-        TADDR canonicalMethodTable = *PTR_TADDR(union_getPointer(m_pCanonMT));
+        TADDR canonicalMethodTable = *PTR_TADDR(union_getPointer(addr));
         if (CORCOMPILE_IS_POINTER_TAGGED(canonicalMethodTable))
             return FALSE;
-        return (PTR_MethodTable(canonicalMethodTable)->m_pEEClass != NULL);
+        return !PTR_MethodTable(canonicalMethodTable)->m_pEEClass.IsNull();
     }
 #endif
     _ASSERTE(!"Malformed m_pEEClass in MethodTable");
@@ -161,7 +163,7 @@ inline PTR_Module MethodTable::GetZapModule()
     PTR_Module zapModule = NULL;
     if (IsZapped())
     {
-        zapModule = m_pLoaderModule;
+        zapModule = ReadPointer(this, &MethodTable::m_pLoaderModule);
     }
 
     return zapModule;
@@ -171,7 +173,7 @@ inline PTR_Module MethodTable::GetZapModule()
 inline PTR_Module MethodTable::GetLoaderModule() 
 {
     LIMITED_METHOD_DAC_CONTRACT;
-    return m_pLoaderModule;
+    return ReadPointer(this, &MethodTable::m_pLoaderModule);
 }
 
 inline PTR_LoaderAllocator MethodTable::GetLoaderAllocator() 
@@ -187,7 +189,7 @@ inline PTR_LoaderAllocator MethodTable::GetLoaderAllocator()
 inline void MethodTable::SetLoaderModule(Module* pModule) 
 {
     WRAPPER_NO_CONTRACT;
-    m_pLoaderModule = pModule;
+    m_pLoaderModule.SetValue(pModule);
 }
 
 inline void MethodTable::SetLoaderAllocator(LoaderAllocator* pAllocator) 
@@ -1145,8 +1147,10 @@ inline PTR_MethodTable MethodTable::GetCanonicalMethodTable()
 {
     LIMITED_METHOD_DAC_CONTRACT;
 
+    TADDR addr = ReadPointer(this, &MethodTable::m_pCanonMT);
+
 #ifdef _DEBUG
-    LowBits lowBits = union_getLowBits(m_pCanonMT);
+    LowBits lowBits = union_getLowBits(addr);
     if (lowBits == UNION_EECLASS)
     {
         return dac_cast<PTR_MethodTable>(this);
@@ -1154,18 +1158,17 @@ inline PTR_MethodTable MethodTable::GetCanonicalMethodTable()
     else if (lowBits == UNION_METHODTABLE)
     {
         // pointer to canonical MethodTable.
-        return PTR_MethodTable(union_getPointer(m_pCanonMT));
+        return PTR_MethodTable(union_getPointer(addr));
     }
 #ifdef FEATURE_PREJIT
     else if (lowBits == UNION_INDIRECTION)
     {
-        return PTR_MethodTable(*PTR_TADDR(union_getPointer(m_pCanonMT)));
+        return PTR_MethodTable(*PTR_TADDR(union_getPointer(addr)));
     }
 #endif
     _ASSERTE(!"Malformed m_pCanonMT in MethodTable");
     return NULL;
 #else
-    TADDR addr = m_pCanonMT;
 
     if ((addr & 2) == 0)
         return dac_cast<PTR_MethodTable>(this);
@@ -1185,11 +1188,12 @@ inline TADDR MethodTable::GetCanonicalMethodTableFixup()
     LIMITED_METHOD_DAC_CONTRACT;
 
 #ifdef FEATURE_PREJIT
-    LowBits lowBits = union_getLowBits(m_pCanonMT);
+    TADDR addr = ReadPointer(this, &MethodTable::m_pCanonMT);
+    LowBits lowBits = union_getLowBits(addr);
     if (lowBits == UNION_INDIRECTION)
     {
         // pointer to canonical MethodTable.
-        return *PTR_TADDR(union_getPointer(m_pCanonMT));
+        return *PTR_TADDR(union_getPointer(addr));
     }
     else
 #endif
@@ -1304,7 +1308,7 @@ inline BOOL MethodTable::IsCanonicalMethodTable()
 {
     LIMITED_METHOD_DAC_CONTRACT;
 
-    return (union_getLowBits(m_pCanonMT) == UNION_EECLASS);
+    return (union_getLowBits(ReadPointer(this, &MethodTable::m_pCanonMT)) == UNION_EECLASS);
 }
 
 //==========================================================================================
@@ -1338,7 +1342,7 @@ inline PTR_InterfaceInfo MethodTable::GetInterfaceMap()
 {
     LIMITED_METHOD_DAC_CONTRACT;
 
-    return dac_cast<PTR_InterfaceInfo>(m_pMultipurposeSlot2); // m_pInterfaceMap
+    return ReadPointer(this, &MethodTable::m_pInterfaceMap);
 }
 
 //==========================================================================================