summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRuben Ayrapetyan <ruben-ayrapetyan@users.noreply.github.com>2017-06-28 09:16:01 +0300
committerJan Kotas <jkotas@microsoft.com>2017-06-27 23:16:01 -0700
commit44f57065649af5f8bcbb7c71d827221a7bc1bf7a (patch)
treedaa511e0217853b725dec53e3ec676683ecd2224
parent7cc721ec6ec56c998d66f1d57e7341cf7141a8a3 (diff)
downloadcoreclr-44f57065649af5f8bcbb7c71d827221a7bc1bf7a.tar.gz
coreclr-44f57065649af5f8bcbb7c71d827221a7bc1bf7a.tar.bz2
coreclr-44f57065649af5f8bcbb7c71d827221a7bc1bf7a.zip
Partially remove relocations from Class section of NGEN-ed images (#11962)
* Remove relocations for ParamTypeDesc::m_TemplateMT. * Remove relocations for LayoutEEClass::m_LayoutInfo.m_pFieldMarshalers. * Prepare RelativeFixupPointer. * Remove relocations for FieldMarshaler::m_pFD and FieldMarshaler_*::m_*.
-rw-r--r--src/debug/daccess/nidump.cpp8
-rw-r--r--src/inc/fixuppointer.h31
-rw-r--r--src/vm/ceeload.cpp7
-rw-r--r--src/vm/ceeload.h3
-rw-r--r--src/vm/class.cpp8
-rw-r--r--src/vm/class.h15
-rw-r--r--src/vm/fieldmarshaler.cpp19
-rw-r--r--src/vm/fieldmarshaler.h197
-rw-r--r--src/vm/methodtablebuilder.cpp8
-rw-r--r--src/vm/typedesc.cpp22
-rw-r--r--src/vm/typedesc.h23
-rw-r--r--src/vm/typedesc.inl2
12 files changed, 269 insertions, 74 deletions
diff --git a/src/debug/daccess/nidump.cpp b/src/debug/daccess/nidump.cpp
index a878c7ce26..cd5ba83b23 100644
--- a/src/debug/daccess/nidump.cpp
+++ b/src/debug/daccess/nidump.cpp
@@ -4745,7 +4745,7 @@ void NativeImageDumper::TraverseTypeHashEntry(void *pContext, PTR_EETypeHashEntr
* all that much harm here (bloats m_discoveredMTs though,
* but not by a huge amount.
*/
- PTR_MethodTable mt(ptd->m_TemplateMT.GetValue());
+ PTR_MethodTable mt(ptd->GetTemplateMethodTableInternal());
if (isInRange(PTR_TO_TADDR(mt)))
{
m_discoveredMTs.AppendEx(mt);
@@ -6201,7 +6201,7 @@ void NativeImageDumper::TypeDescToString( PTR_TypeDesc td, SString& buf )
if( td->IsArray() )
{
//td->HasTypeParam() may also be true.
- PTR_MethodTable mt = ptd->m_TemplateMT.GetValue();
+ PTR_MethodTable mt = ptd->GetTemplateMethodTableInternal();
_ASSERTE( PTR_TO_TADDR(mt) );
if( CORCOMPILE_IS_POINTER_TAGGED(PTR_TO_TADDR(mt)) )
{
@@ -8451,7 +8451,7 @@ NativeImageDumper::DumpEEClassForMethodTable( PTR_MethodTable mt )
VERBOSE_TYPES );
DisplayWriteFieldInt( m_numCTMFields, eecli->m_numCTMFields,
EEClassLayoutInfo, VERBOSE_TYPES );
- PTR_FieldMarshaler fmArray( TO_TADDR(eecli->m_pFieldMarshalers) );
+ PTR_FieldMarshaler fmArray = eecli->GetFieldMarshalers();
DisplayWriteFieldAddress( m_pFieldMarshalers,
DPtrToPreferredAddr(fmArray),
eecli->m_numCTMFields
@@ -8793,7 +8793,7 @@ void NativeImageDumper::DumpTypeDesc( PTR_TypeDesc td )
{
PTR_ParamTypeDesc ptd(td);
DisplayStartVStructure( "ParamTypeDesc", TYPEDESCS );
- WriteFieldMethodTable( m_TemplateMT, ptd->m_TemplateMT.GetValue(),
+ WriteFieldMethodTable( m_TemplateMT, ptd->GetTemplateMethodTableInternal(),
ParamTypeDesc, TYPEDESCS );
WriteFieldTypeHandle( m_Arg, ptd->m_Arg,
ParamTypeDesc, TYPEDESCS );
diff --git a/src/inc/fixuppointer.h b/src/inc/fixuppointer.h
index 38ae348e1e..83ff20e04f 100644
--- a/src/inc/fixuppointer.h
+++ b/src/inc/fixuppointer.h
@@ -249,6 +249,15 @@ public:
static constexpr bool isRelative = true;
typedef PTR_TYPE type;
+#ifndef DACCESS_COMPILE
+ RelativeFixupPointer()
+ {
+ SetValueMaybeNull(NULL);
+ }
+#else // DACCESS_COMPILE
+ RelativeFixupPointer() =delete;
+#endif // DACCESS_COMPILE
+
// Implicit copy/move is not allowed
RelativeFixupPointer<PTR_TYPE>(const RelativeFixupPointer<PTR_TYPE> &) =delete;
RelativeFixupPointer<PTR_TYPE>(RelativeFixupPointer<PTR_TYPE> &&) =delete;
@@ -273,6 +282,15 @@ public:
return FALSE;
}
+#ifndef DACCESS_COMPILE
+ FORCEINLINE BOOL IsTagged() const
+ {
+ LIMITED_METHOD_CONTRACT;
+ TADDR base = (TADDR) this;
+ return IsTagged(base);
+ }
+#endif // !DACCESS_COMPILE
+
// Returns value of the encoded pointer. Assumes that the pointer is not NULL.
FORCEINLINE PTR_TYPE GetValue(TADDR base) const
{
@@ -343,7 +361,7 @@ public:
{
LIMITED_METHOD_CONTRACT;
PRECONDITION(addr != NULL);
- m_delta = (TADDR)addr - (TADDR)this;
+ m_delta = dac_cast<TADDR>(addr) - (TADDR)this;
}
// Set encoded value of the pointer. The value can be NULL.
@@ -353,7 +371,7 @@ public:
if (addr == NULL)
m_delta = NULL;
else
- m_delta = (TADDR)addr - (TADDR)base;
+ m_delta = dac_cast<TADDR>(addr) - (TADDR)base;
}
// Set encoded value of the pointer. The value can be NULL.
@@ -373,6 +391,15 @@ public:
return dac_cast<DPTR(PTR_TYPE)>(addr - FIXUP_POINTER_INDIRECTION);
}
+#ifndef DACCESS_COMPILE
+ PTR_TYPE * GetValuePtr() const
+ {
+ LIMITED_METHOD_CONTRACT;
+ TADDR base = (TADDR) this;
+ return GetValuePtr(base);
+ }
+#endif // !DACCESS_COMPILE
+
// Returns value of the encoded pointer. Assumes that the pointer is not NULL.
// Allows the value to be tagged.
FORCEINLINE TADDR GetValueMaybeTagged(TADDR base) const
diff --git a/src/vm/ceeload.cpp b/src/vm/ceeload.cpp
index 47810b7168..49068fcd36 100644
--- a/src/vm/ceeload.cpp
+++ b/src/vm/ceeload.cpp
@@ -10702,7 +10702,7 @@ void Module::RestoreMethodDescPointer(RelativeFixupPointer<PTR_MethodDesc> * ppM
}
/*static*/
-void Module::RestoreFieldDescPointer(FixupPointer<PTR_FieldDesc> * ppFD)
+void Module::RestoreFieldDescPointer(RelativeFixupPointer<PTR_FieldDesc> * ppFD)
{
CONTRACTL
{
@@ -10712,6 +10712,9 @@ void Module::RestoreFieldDescPointer(FixupPointer<PTR_FieldDesc> * ppFD)
}
CONTRACTL_END;
+ if (!ppFD->IsTagged())
+ return;
+
PTR_FieldDesc * ppValue = ppFD->GetValuePtr();
// Ensure that the compiler won't fetch the value twice
@@ -10723,7 +10726,7 @@ void Module::RestoreFieldDescPointer(FixupPointer<PTR_FieldDesc> * ppFD)
CONSISTENCY_CHECK((CORCOMPILE_UNTAG_TOKEN(fixup)>>32) == 0);
#endif
- Module * pContainingModule = ExecutionManager::FindZapModule(dac_cast<TADDR>(ppValue));
+ Module * pContainingModule = ExecutionManager::FindZapModule((TADDR)ppValue);
PREFIX_ASSUME(pContainingModule != NULL);
RVA fixupRva = (RVA) CORCOMPILE_UNTAG_TOKEN(fixup);
diff --git a/src/vm/ceeload.h b/src/vm/ceeload.h
index 7fa125dd84..0896c9b8ab 100644
--- a/src/vm/ceeload.h
+++ b/src/vm/ceeload.h
@@ -2901,8 +2901,7 @@ public:
static void RestoreMethodDescPointer(RelativeFixupPointer<PTR_MethodDesc> * ppMD,
Module *pContainingModule = NULL,
ClassLoadLevel level = CLASS_LOADED);
-
- static void RestoreFieldDescPointer(FixupPointer<PTR_FieldDesc> * ppFD);
+ static void RestoreFieldDescPointer(RelativeFixupPointer<PTR_FieldDesc> * ppFD);
static void RestoreModulePointer(RelativeFixupPointer<PTR_Module> * ppModule, Module *pContainingModule);
diff --git a/src/vm/class.cpp b/src/vm/class.cpp
index 0259b1e4fc..6697b23a9a 100644
--- a/src/vm/class.cpp
+++ b/src/vm/class.cpp
@@ -2818,13 +2818,13 @@ void EEClass::Save(DataImage *image, MethodTable *pMT)
if (pInfo->m_numCTMFields > 0)
{
- ZapStoredStructure * pNode = image->StoreStructure(pInfo->m_pFieldMarshalers,
+ ZapStoredStructure * pNode = image->StoreStructure(pInfo->GetFieldMarshalers(),
pInfo->m_numCTMFields * MAXFIELDMARSHALERSIZE,
DataImage::ITEM_FIELD_MARSHALERS);
for (UINT iField = 0; iField < pInfo->m_numCTMFields; iField++)
{
- FieldMarshaler *pFM = (FieldMarshaler*)((BYTE *)pInfo->m_pFieldMarshalers + iField * MAXFIELDMARSHALERSIZE);
+ FieldMarshaler *pFM = (FieldMarshaler*)((BYTE *)pInfo->GetFieldMarshalers() + iField * MAXFIELDMARSHALERSIZE);
pFM->Save(image);
if (iField > 0)
@@ -3029,11 +3029,11 @@ void EEClass::Fixup(DataImage *image, MethodTable *pMT)
if (HasLayout())
{
- image->FixupPointerField(this, offsetof(LayoutEEClass, m_LayoutInfo.m_pFieldMarshalers));
+ image->FixupRelativePointerField(this, offsetof(LayoutEEClass, m_LayoutInfo.m_pFieldMarshalers));
EEClassLayoutInfo *pInfo = &((LayoutEEClass*)this)->m_LayoutInfo;
- FieldMarshaler *pFM = pInfo->m_pFieldMarshalers;
+ FieldMarshaler *pFM = pInfo->GetFieldMarshalers();
FieldMarshaler *pFMEnd = (FieldMarshaler*) ((BYTE *)pFM + pInfo->m_numCTMFields*MAXFIELDMARSHALERSIZE);
while (pFM < pFMEnd)
{
diff --git a/src/vm/class.h b/src/vm/class.h
index d1f10d451f..60cab67707 100644
--- a/src/vm/class.h
+++ b/src/vm/class.h
@@ -109,6 +109,7 @@ class LoaderAllocator;
class ComCallWrapperTemplate;
typedef DPTR(DictionaryLayout) PTR_DictionaryLayout;
+typedef DPTR(FieldMarshaler) PTR_FieldMarshaler;
//---------------------------------------------------------------------------------
@@ -439,7 +440,7 @@ class EEClassLayoutInfo
// An array of FieldMarshaler data blocks, used to drive call-time
// marshaling of NStruct reference parameters. The number of elements
// equals m_numCTMFields.
- FieldMarshaler *m_pFieldMarshalers;
+ RelativePointer<PTR_FieldMarshaler> m_pFieldMarshalers;
public:
@@ -468,12 +469,20 @@ class EEClassLayoutInfo
return m_numCTMFields;
}
- FieldMarshaler *GetFieldMarshalers() const
+ PTR_FieldMarshaler GetFieldMarshalers() const
{
LIMITED_METHOD_CONTRACT;
- return m_pFieldMarshalers;
+ return ReadPointerMaybeNull(this, &EEClassLayoutInfo::m_pFieldMarshalers);
}
+#ifndef DACCESS_COMPILE
+ void SetFieldMarshalers(FieldMarshaler *pFieldMarshallers)
+ {
+ LIMITED_METHOD_CONTRACT;
+ m_pFieldMarshalers.SetValueMaybeNull(pFieldMarshallers);
+ }
+#endif // DACCESS_COMPILE
+
BOOL IsBlittable() const
{
LIMITED_METHOD_CONTRACT;
diff --git a/src/vm/fieldmarshaler.cpp b/src/vm/fieldmarshaler.cpp
index 0de71b592c..9415b948b5 100644
--- a/src/vm/fieldmarshaler.cpp
+++ b/src/vm/fieldmarshaler.cpp
@@ -1318,7 +1318,7 @@ VOID EEClassLayoutInfo::CollectLayoutFieldMetadataThrowing(
}
pEEClassLayoutInfoOut->m_numCTMFields = fHasNonTrivialParent ? pParentMT->GetLayoutInfo()->m_numCTMFields : 0;
- pEEClassLayoutInfoOut->m_pFieldMarshalers = NULL;
+ pEEClassLayoutInfoOut->SetFieldMarshalers(NULL);
pEEClassLayoutInfoOut->SetIsBlittable(TRUE);
if (fHasNonTrivialParent)
pEEClassLayoutInfoOut->SetIsBlittable(pParentMT->IsBlittable());
@@ -1599,7 +1599,7 @@ VOID EEClassLayoutInfo::CollectLayoutFieldMetadataThrowing(
if (pEEClassLayoutInfoOut->m_numCTMFields)
{
- pEEClassLayoutInfoOut->m_pFieldMarshalers = (FieldMarshaler*)(pamTracker->Track(pAllocator->GetLowFrequencyHeap()->AllocMem(S_SIZE_T(MAXFIELDMARSHALERSIZE) * S_SIZE_T(pEEClassLayoutInfoOut->m_numCTMFields))));
+ pEEClassLayoutInfoOut->SetFieldMarshalers((FieldMarshaler*)(pamTracker->Track(pAllocator->GetLowFrequencyHeap()->AllocMem(S_SIZE_T(MAXFIELDMARSHALERSIZE) * S_SIZE_T(pEEClassLayoutInfoOut->m_numCTMFields)))));
// Bring in the parent's fieldmarshalers
if (fHasNonTrivialParent)
@@ -1608,8 +1608,8 @@ VOID EEClassLayoutInfo::CollectLayoutFieldMetadataThrowing(
PREFAST_ASSUME(pParentLayoutInfo != NULL); // See if (fParentHasLayout) branch above
UINT numChildCTMFields = pEEClassLayoutInfoOut->m_numCTMFields - pParentLayoutInfo->m_numCTMFields;
- memcpyNoGCRefs( ((BYTE*)pEEClassLayoutInfoOut->m_pFieldMarshalers) + MAXFIELDMARSHALERSIZE*numChildCTMFields,
- pParentLayoutInfo->m_pFieldMarshalers,
+ memcpyNoGCRefs( ((BYTE*)pEEClassLayoutInfoOut->GetFieldMarshalers()) + MAXFIELDMARSHALERSIZE*numChildCTMFields,
+ pParentLayoutInfo->GetFieldMarshalers(),
MAXFIELDMARSHALERSIZE * (pParentLayoutInfo->m_numCTMFields) );
}
@@ -3726,7 +3726,7 @@ VOID FieldMarshaler_SafeArray::UpdateNativeImpl(OBJECTREF* pCLRValue, LPVOID pNa
pSafeArray = (LPSAFEARRAY*)pNativeValue;
VARTYPE vt = m_vt;
- MethodTable* pMT = m_pMT.GetValue();
+ MethodTable* pMT = m_pMT.GetValueMaybeNull();
GCPROTECT_BEGIN(pArray)
{
@@ -3771,7 +3771,7 @@ VOID FieldMarshaler_SafeArray::UpdateCLRImpl(const VOID *pNativeValue, OBJECTREF
}
VARTYPE vt = m_vt;
- MethodTable* pMT = m_pMT.GetValue();
+ MethodTable* pMT = m_pMT.GetValueMaybeNull();
// If we have an empty vartype, get it from the safearray vartype
if (vt == VT_EMPTY)
@@ -4868,3 +4868,10 @@ IMPLEMENT_FieldMarshaler_METHOD(void, Restore,
(),
,
())
+
+#ifndef DACCESS_COMPILE
+IMPLEMENT_FieldMarshaler_METHOD(VOID, CopyTo,
+ (VOID *pDest, SIZE_T destSize) const,
+ ,
+ (pDest, destSize))
+#endif // !DACCESS_COMPILE
diff --git a/src/vm/fieldmarshaler.h b/src/vm/fieldmarshaler.h
index 287da41a5b..f11c81b896 100644
--- a/src/vm/fieldmarshaler.h
+++ b/src/vm/fieldmarshaler.h
@@ -253,6 +253,28 @@ VOID FmtValueTypeUpdateCLR(LPVOID pProtectedManagedData, MethodTable *pMT, BYTE
} \
ELEMENT_SIZE_IMPL(NativeSize, AlignmentReq)
+#define COPY_TO_IMPL_BASE_STRUCT_ONLY() \
+ VOID CopyToImpl(VOID *pDest, SIZE_T destSize) \
+ { \
+ static_assert(sizeof(*this) == sizeof(FieldMarshaler), \
+ "Please, implement CopyToImpl for correct copy of field values"); \
+ \
+ FieldMarshaler::CopyToImpl(pDest, destSize); \
+ }
+
+#define START_COPY_TO_IMPL(CLASS_NAME) \
+ VOID CopyToImpl(VOID *pDest, SIZE_T destSize) const \
+ { \
+ FieldMarshaler::CopyToImpl(pDest, destSize); \
+ \
+ CLASS_NAME *pDestFieldMarshaller = (std::remove_const<std::remove_pointer<decltype(this)>::type>::type *) pDest; \
+ _ASSERTE(sizeof(*pDestFieldMarshaller) <= destSize); \
+
+#define END_COPY_TO_IMPL(CLASS_NAME) \
+ static_assert(std::is_same<CLASS_NAME *, decltype(pDestFieldMarshaller)>::value, \
+ "Structure's name is required"); \
+ }
+
//=======================================================================
//
@@ -278,6 +300,7 @@ public:
VOID ScalarUpdateCLR(const VOID *pNative, LPVOID pCLR) const;
VOID NestedValueClassUpdateNative(const VOID **ppProtectedCLR, SIZE_T startoffset, LPVOID pNative, OBJECTREF *ppCleanupWorkListOnStack) const;
VOID NestedValueClassUpdateCLR(const VOID *pNative, LPVOID *ppProtectedCLR, SIZE_T startoffset) const;
+ VOID CopyTo(VOID *pDest, SIZE_T destSize) const;
#ifdef FEATURE_PREJIT
void Save(DataImage *image);
void Fixup(DataImage *image);
@@ -351,10 +374,21 @@ public:
#endif // FEATURE_PREJIT
}
+ void CopyToImpl(VOID *pDest, SIZE_T destSize) const
+ {
+ FieldMarshaler *pDestFieldMarshaller = (FieldMarshaler *) pDest;
+
+ _ASSERTE(sizeof(*pDestFieldMarshaller) <= destSize);
+
+ pDestFieldMarshaller->SetFieldDesc(GetFieldDesc());
+ pDestFieldMarshaller->SetExternalOffset(GetExternalOffset());
+ pDestFieldMarshaller->SetNStructFieldType(GetNStructFieldType());
+ }
+
void SetFieldDesc(FieldDesc* pFD)
{
LIMITED_METHOD_CONTRACT;
- m_pFD.SetValue(pFD);
+ m_pFD.SetValueMaybeNull(pFD);
}
FieldDesc* GetFieldDesc() const
@@ -369,7 +403,7 @@ public:
}
CONTRACT_END;
- RETURN m_pFD.GetValue();
+ RETURN m_pFD.GetValueMaybeNull();
}
void SetExternalOffset(UINT32 dwExternalOffset)
@@ -394,7 +428,7 @@ protected:
#endif
}
- static inline void RestoreHelper(FixupPointer<PTR_MethodTable> *ppMT)
+ static inline void RestoreHelper(RelativeFixupPointer<PTR_MethodTable> *ppMT)
{
CONTRACTL
{
@@ -414,7 +448,7 @@ protected:
}
#ifdef _DEBUG
- static inline BOOL IsRestoredHelper(FixupPointer<PTR_MethodTable> pMT)
+ static inline BOOL IsRestoredHelper(const RelativeFixupPointer<PTR_MethodTable> &pMT)
{
WRAPPER_NO_CONTRACT;
@@ -428,7 +462,7 @@ protected:
#endif // _DEBUG
- FixupPointer<PTR_FieldDesc> m_pFD; // FieldDesc
+ RelativeFixupPointer<PTR_FieldDesc> m_pFD; // FieldDesc
UINT32 m_dwExternalOffset; // offset of field in the fixed portion
NStructFieldType m_nft;
};
@@ -449,6 +483,7 @@ public:
VOID DestroyNativeImpl(LPVOID pNativeValue) const;
ELEMENT_SIZE_IMPL(sizeof(BSTR), sizeof(BSTR))
+ COPY_TO_IMPL_BASE_STRUCT_ONLY()
};
//=======================================================================
@@ -462,6 +497,7 @@ public:
VOID DestroyNativeImpl(LPVOID pNativeValue) const;
ELEMENT_SIZE_IMPL(sizeof(HSTRING), sizeof(HSTRING))
+ COPY_TO_IMPL_BASE_STRUCT_ONLY()
};
//=======================================================================
@@ -473,7 +509,7 @@ public:
FieldMarshaler_Nullable(MethodTable* pMT)
{
- m_pNullableTypeMT.SetValue(pMT);
+ m_pNullableTypeMT.SetValueMaybeNull(pMT);
}
BOOL IsNullableMarshalerImpl() const
@@ -526,6 +562,12 @@ public:
FieldMarshaler::RestoreImpl();
}
+ START_COPY_TO_IMPL(FieldMarshaler_Nullable)
+ {
+ pDestFieldMarshaller->m_pNullableTypeMT.SetValueMaybeNull(GetMethodTable());
+ }
+ END_COPY_TO_IMPL(FieldMarshaler_Nullable)
+
#ifdef _DEBUG
BOOL IsRestored() const
{
@@ -550,7 +592,7 @@ public:
}
private:
- FixupPointer<PTR_MethodTable> m_pNullableTypeMT;
+ RelativeFixupPointer<PTR_MethodTable> m_pNullableTypeMT;
};
@@ -565,6 +607,7 @@ public:
VOID DestroyNativeImpl(LPVOID pNativeValue) const;
ELEMENT_SIZE_IMPL(sizeof(HSTRING), sizeof(HSTRING))
+ COPY_TO_IMPL_BASE_STRUCT_ONLY()
};
//=======================================================================
@@ -578,6 +621,7 @@ public:
VOID UpdateCLRImpl(const VOID * pNativeValue, OBJECTREF * ppProtectedCLRValue, OBJECTREF * ppProtectedOldCLRValue) const;
ELEMENT_SIZE_IMPL(sizeof(HRESULT), sizeof(HRESULT))
+ COPY_TO_IMPL_BASE_STRUCT_ONLY()
};
#endif // FEATURE_COMINTEROP
@@ -593,7 +637,7 @@ public:
FieldMarshaler_NestedLayoutClass(MethodTable *pMT)
{
WRAPPER_NO_CONTRACT;
- m_pNestedMethodTable.SetValue(pMT);
+ m_pNestedMethodTable.SetValueMaybeNull(pMT);
}
VOID UpdateNativeImpl(OBJECTREF* pCLRValue, LPVOID pNativeValue, OBJECTREF *ppCleanupWorkListOnStack) const;
@@ -629,6 +673,12 @@ public:
FieldMarshaler::RestoreImpl();
}
+ START_COPY_TO_IMPL(FieldMarshaler_NestedLayoutClass)
+ {
+ pDestFieldMarshaller->m_pNestedMethodTable.SetValueMaybeNull(GetMethodTable());
+ }
+ END_COPY_TO_IMPL(FieldMarshaler_NestedLayoutClass)
+
#ifdef _DEBUG
BOOL IsRestored() const
{
@@ -649,12 +699,12 @@ public:
}
CONTRACTL_END;
- return m_pNestedMethodTable.GetValue();
+ return m_pNestedMethodTable.GetValueMaybeNull();
}
private:
// MethodTable of nested FieldMarshaler.
- FixupPointer<PTR_MethodTable> m_pNestedMethodTable;
+ RelativeFixupPointer<PTR_MethodTable> m_pNestedMethodTable;
};
@@ -667,7 +717,7 @@ public:
FieldMarshaler_NestedValueClass(MethodTable *pMT)
{
WRAPPER_NO_CONTRACT;
- m_pNestedMethodTable.SetValue(pMT);
+ m_pNestedMethodTable.SetValueMaybeNull(pMT);
}
BOOL IsNestedValueClassMarshalerImpl() const
@@ -712,6 +762,12 @@ public:
FieldMarshaler::RestoreImpl();
}
+ START_COPY_TO_IMPL(FieldMarshaler_NestedValueClass)
+ {
+ pDestFieldMarshaller->m_pNestedMethodTable.SetValueMaybeNull(GetMethodTable());
+ }
+ END_COPY_TO_IMPL(FieldMarshaler_NestedValueClass)
+
#ifdef _DEBUG
BOOL IsRestored() const
{
@@ -738,13 +794,13 @@ public:
}
CONTRACTL_END;
- return m_pNestedMethodTable.GetValue();
+ return m_pNestedMethodTable.GetValueMaybeNull();
}
private:
// MethodTable of nested NStruct.
- FixupPointer<PTR_MethodTable> m_pNestedMethodTable;
+ RelativeFixupPointer<PTR_MethodTable> m_pNestedMethodTable;
};
@@ -760,6 +816,7 @@ public:
VOID DestroyNativeImpl(LPVOID pNativeValue) const;
ELEMENT_SIZE_IMPL(sizeof(LPWSTR), sizeof(LPWSTR))
+ COPY_TO_IMPL_BASE_STRUCT_ONLY()
};
//=======================================================================
@@ -774,6 +831,7 @@ public:
VOID DestroyNativeImpl(LPVOID pNativeValue) const;
ELEMENT_SIZE_IMPL(sizeof(LPSTR), sizeof(LPSTR))
+ COPY_TO_IMPL_BASE_STRUCT_ONLY()
};
//=======================================================================
@@ -806,6 +864,13 @@ public:
return m_ThrowOnUnmappableChar;
}
+ START_COPY_TO_IMPL(FieldMarshaler_StringAnsi)
+ {
+ pDestFieldMarshaller->m_BestFitMap = m_BestFitMap;
+ pDestFieldMarshaller->m_ThrowOnUnmappableChar = m_ThrowOnUnmappableChar;
+ }
+ END_COPY_TO_IMPL(FieldMarshaler_StringAnsi)
+
private:
bool m_BestFitMap:1;
bool m_ThrowOnUnmappableChar:1;
@@ -829,6 +894,12 @@ public:
m_numchar = numChar;
}
+ START_COPY_TO_IMPL(FieldMarshaler_FixedStringUni)
+ {
+ pDestFieldMarshaller->m_numchar = m_numchar;
+ }
+ END_COPY_TO_IMPL(FieldMarshaler_FixedStringUni)
+
private:
// # of characters for fixed strings
UINT32 m_numchar;
@@ -864,6 +935,14 @@ public:
return m_ThrowOnUnmappableChar;
}
+ START_COPY_TO_IMPL(FieldMarshaler_FixedStringAnsi)
+ {
+ pDestFieldMarshaller->m_numchar = m_numchar;
+ pDestFieldMarshaller->m_BestFitMap = m_BestFitMap;
+ pDestFieldMarshaller->m_ThrowOnUnmappableChar = m_ThrowOnUnmappableChar;
+ }
+ END_COPY_TO_IMPL(FieldMarshaler_FixedStringAnsi)
+
private:
// # of characters for fixed strings
UINT32 m_numchar;
@@ -901,6 +980,14 @@ public:
return m_ThrowOnUnmappableChar;
}
+ START_COPY_TO_IMPL(FieldMarshaler_FixedCharArrayAnsi)
+ {
+ pDestFieldMarshaller->m_numElems = m_numElems;
+ pDestFieldMarshaller->m_BestFitMap = m_BestFitMap;
+ pDestFieldMarshaller->m_ThrowOnUnmappableChar = m_ThrowOnUnmappableChar;
+ }
+ END_COPY_TO_IMPL(FieldMarshaler_FixedCharArrayAnsi)
+
private:
// # of elements for fixedchararray
UINT32 m_numElems;
@@ -980,6 +1067,16 @@ public:
FieldMarshaler::RestoreImpl();
}
+ START_COPY_TO_IMPL(FieldMarshaler_FixedArray)
+ {
+ pDestFieldMarshaller->m_arrayType.SetValueMaybeNull(m_arrayType.GetValueMaybeNull());
+ pDestFieldMarshaller->m_numElems = m_numElems;
+ pDestFieldMarshaller->m_vt = m_vt;
+ pDestFieldMarshaller->m_BestFitMap = m_BestFitMap;
+ pDestFieldMarshaller->m_ThrowOnUnmappableChar = m_ThrowOnUnmappableChar;
+ }
+ END_COPY_TO_IMPL(FieldMarshaler_FixedArray)
+
#ifdef _DEBUG
BOOL IsRestored() const
{
@@ -994,7 +1091,7 @@ public:
#endif
private:
- FixupPointer<TypeHandle> m_arrayType;
+ RelativeFixupPointer<TypeHandle> m_arrayType;
UINT32 m_numElems;
VARTYPE m_vt;
bool m_BestFitMap:1; // Note: deliberately use small bools to save on working set - this is the largest FieldMarshaler and dominates the cost of the FieldMarshaler array
@@ -1020,7 +1117,7 @@ public:
{
WRAPPER_NO_CONTRACT;
m_vt = vt;
- m_pMT.SetValue(pMT);
+ m_pMT.SetValueMaybeNull(pMT);
}
#ifdef FEATURE_PREJIT
@@ -1049,6 +1146,13 @@ public:
FieldMarshaler::RestoreImpl();
}
+ START_COPY_TO_IMPL(FieldMarshaler_SafeArray)
+ {
+ pDestFieldMarshaller->m_pMT.SetValueMaybeNull(m_pMT.GetValueMaybeNull());
+ pDestFieldMarshaller->m_vt = m_vt;
+ }
+ END_COPY_TO_IMPL(FieldMarshaler_SafeArray)
+
#ifdef _DEBUG
BOOL IsRestored() const
{
@@ -1079,7 +1183,7 @@ public:
}
private:
- FixupPointer<PTR_MethodTable> m_pMT;
+ RelativeFixupPointer<PTR_MethodTable> m_pMT;
VARTYPE m_vt;
};
#endif //FEATURE_CLASSIC_COMINTEROP
@@ -1094,7 +1198,7 @@ public:
FieldMarshaler_Delegate(MethodTable* pMT)
{
WRAPPER_NO_CONTRACT;
- m_pNestedMethodTable.SetValue(pMT);
+ m_pNestedMethodTable.SetValueMaybeNull(pMT);
}
VOID UpdateNativeImpl(OBJECTREF* pCLRValue, LPVOID pNativeValue, OBJECTREF *ppCleanupWorkListOnStack) const;
@@ -1128,6 +1232,12 @@ public:
FieldMarshaler::RestoreImpl();
}
+ START_COPY_TO_IMPL(FieldMarshaler_Delegate)
+ {
+ pDestFieldMarshaller->m_pNestedMethodTable.SetValueMaybeNull(m_pNestedMethodTable.GetValueMaybeNull());
+ }
+ END_COPY_TO_IMPL(FieldMarshaler_Delegate)
+
#ifdef _DEBUG
BOOL IsRestored() const
{
@@ -1148,10 +1258,10 @@ public:
}
CONTRACTL_END;
- return m_pNestedMethodTable.GetValue();
+ return m_pNestedMethodTable.GetValueMaybeNull();
}
- FixupPointer<PTR_MethodTable> m_pNestedMethodTable;
+ RelativeFixupPointer<PTR_MethodTable> m_pNestedMethodTable;
};
@@ -1168,6 +1278,7 @@ public:
VOID UpdateCLRImpl(const VOID *pNativeValue, OBJECTREF *ppProtectedCLRValue, OBJECTREF *ppProtectedOldCLRValue) const;
ELEMENT_SIZE_IMPL(sizeof(LPVOID), sizeof(LPVOID))
+ COPY_TO_IMPL_BASE_STRUCT_ONLY()
};
@@ -1184,6 +1295,7 @@ public:
VOID UpdateCLRImpl(const VOID *pNativeValue, OBJECTREF *ppProtectedCLRValue, OBJECTREF *ppProtectedOldCLRValue) const;
ELEMENT_SIZE_IMPL(sizeof(LPVOID), sizeof(LPVOID))
+ COPY_TO_IMPL_BASE_STRUCT_ONLY()
};
#ifdef FEATURE_COMINTEROP
@@ -1204,8 +1316,8 @@ public:
FieldMarshaler_Interface(MethodTable *pClassMT, MethodTable *pItfMT, DWORD dwFlags)
{
WRAPPER_NO_CONTRACT;
- m_pClassMT.SetValue(pClassMT);
- m_pItfMT.SetValue(pItfMT);
+ m_pClassMT.SetValueMaybeNull(pClassMT);
+ m_pItfMT.SetValueMaybeNull(pItfMT);
m_dwFlags = dwFlags;
}
@@ -1237,6 +1349,14 @@ public:
FieldMarshaler::RestoreImpl();
}
+ START_COPY_TO_IMPL(FieldMarshaler_Interface)
+ {
+ pDestFieldMarshaller->m_pClassMT.SetValueMaybeNull(m_pClassMT.GetValueMaybeNull());
+ pDestFieldMarshaller->m_pItfMT.SetValueMaybeNull(m_pItfMT.GetValueMaybeNull());
+ pDestFieldMarshaller->m_dwFlags = m_dwFlags;
+ }
+ END_COPY_TO_IMPL(FieldMarshaler_Interface)
+
#ifdef _DEBUG
BOOL IsRestored() const
{
@@ -1275,7 +1395,7 @@ public:
}
CONTRACTL_END;
- return m_pClassMT.GetValue();
+ return m_pClassMT.GetValueMaybeNull();
}
MethodTable *GetInterfaceMethodTable() const
@@ -1289,12 +1409,12 @@ public:
}
CONTRACTL_END;
- return m_pItfMT.GetValue();
+ return m_pItfMT.GetValueMaybeNull();
}
private:
- FixupPointer<PTR_MethodTable> m_pClassMT;
- FixupPointer<PTR_MethodTable> m_pItfMT;
+ RelativeFixupPointer<PTR_MethodTable> m_pClassMT;
+ RelativeFixupPointer<PTR_MethodTable> m_pItfMT;
DWORD m_dwFlags;
};
@@ -1328,6 +1448,7 @@ public:
VOID DestroyNativeImpl(LPVOID pNativeValue) const;
ELEMENT_SIZE_IMPL(sizeof(VARIANT), 8)
+ COPY_TO_IMPL_BASE_STRUCT_ONLY()
};
#endif // FEATURE_COMINTEROP
@@ -1352,7 +1473,13 @@ public:
VOID ScalarUpdateCLRImpl(const VOID *pNative, LPVOID pCLR) const;
SCALAR_MARSHALER_IMPL(1, 1)
-
+
+ START_COPY_TO_IMPL(FieldMarshaler_Illegal)
+ {
+ pDestFieldMarshaller->m_resIDWhy = m_resIDWhy;
+ }
+ END_COPY_TO_IMPL(FieldMarshaler_Illegal)
+
private:
UINT m_resIDWhy;
};
@@ -1369,6 +1496,7 @@ public:
UNUSED_METHOD_IMPL(VOID UpdateCLRImpl(const VOID *pNativeValue, OBJECTREF *ppProtectedCLRValue, OBJECTREF *ppProtectedOldCLRValue) const)
SCALAR_MARSHALER_IMPL(1, 1)
+ COPY_TO_IMPL_BASE_STRUCT_ONLY()
VOID ScalarUpdateNativeImpl(LPVOID pCLR, LPVOID pNative) const
{
@@ -1413,6 +1541,7 @@ public:
UNUSED_METHOD_IMPL(VOID UpdateCLRImpl(const VOID *pNativeValue, OBJECTREF *ppProtectedCLRValue, OBJECTREF *ppProtectedOldCLRValue) const)
SCALAR_MARSHALER_IMPL(2, 2)
+ COPY_TO_IMPL_BASE_STRUCT_ONLY()
VOID ScalarUpdateNativeImpl(LPVOID pCLR, LPVOID pNative) const
{
@@ -1456,6 +1585,7 @@ public:
UNUSED_METHOD_IMPL(VOID UpdateCLRImpl(const VOID *pNativeValue, OBJECTREF *ppProtectedCLRValue, OBJECTREF *ppProtectedOldCLRValue) const)
SCALAR_MARSHALER_IMPL(4, 4)
+ COPY_TO_IMPL_BASE_STRUCT_ONLY()
VOID ScalarUpdateNativeImpl(LPVOID pCLR, LPVOID pNative) const
{
@@ -1499,6 +1629,7 @@ public:
UNUSED_METHOD_IMPL(VOID UpdateCLRImpl(const VOID *pNativeValue, OBJECTREF *ppProtectedCLRValue, OBJECTREF *ppProtectedOldCLRValue) const)
SCALAR_MARSHALER_IMPL(8, 8)
+ COPY_TO_IMPL_BASE_STRUCT_ONLY()
VOID ScalarUpdateNativeImpl(LPVOID pCLR, LPVOID pNative) const
{
@@ -1599,6 +1730,13 @@ public:
return m_ThrowOnUnmappableChar;
}
+ START_COPY_TO_IMPL(FieldMarshaler_Ansi)
+ {
+ pDestFieldMarshaller->m_BestFitMap = m_BestFitMap;
+ pDestFieldMarshaller->m_ThrowOnUnmappableChar = m_ThrowOnUnmappableChar;
+ }
+ END_COPY_TO_IMPL(FieldMarshaler_Ansi)
+
private:
bool m_BestFitMap:1;
bool m_ThrowOnUnmappableChar:1;
@@ -1614,6 +1752,7 @@ public:
UNUSED_METHOD_IMPL(VOID UpdateCLRImpl(const VOID *pNativeValue, OBJECTREF *ppProtectedCLRValue, OBJECTREF *ppProtectedOldCLRValue) const)
SCALAR_MARSHALER_IMPL(sizeof(BOOL), sizeof(BOOL))
+ COPY_TO_IMPL_BASE_STRUCT_ONLY()
VOID ScalarUpdateNativeImpl(LPVOID pCLR, LPVOID pNative) const
{
@@ -1661,6 +1800,7 @@ public:
UNUSED_METHOD_IMPL(VOID UpdateCLRImpl(const VOID *pNativeValue, OBJECTREF *ppProtectedCLRValue, OBJECTREF *ppProtectedOldCLRValue) const)
SCALAR_MARSHALER_IMPL(sizeof(VARIANT_BOOL), sizeof(VARIANT_BOOL))
+ COPY_TO_IMPL_BASE_STRUCT_ONLY()
VOID ScalarUpdateNativeImpl(LPVOID pCLR, LPVOID pNative) const
{
@@ -1711,6 +1851,7 @@ public:
UNUSED_METHOD_IMPL(VOID UpdateCLRImpl(const VOID *pNativeValue, OBJECTREF *ppProtectedCLRValue, OBJECTREF *ppProtectedOldCLRValue) const)
SCALAR_MARSHALER_IMPL(1, 1)
+ COPY_TO_IMPL_BASE_STRUCT_ONLY()
VOID ScalarUpdateNativeImpl(LPVOID pCLR, LPVOID pNative) const
{
@@ -1752,6 +1893,7 @@ public:
UNUSED_METHOD_IMPL(VOID UpdateCLRImpl(const VOID *pNativeValue, OBJECTREF *ppProtectedCLRValue, OBJECTREF *ppProtectedOldCLRValue) const)
SCALAR_MARSHALER_IMPL(sizeof(DECIMAL), 8);
+ COPY_TO_IMPL_BASE_STRUCT_ONLY()
VOID ScalarUpdateNativeImpl(LPVOID pCLR, LPVOID pNative) const
{
@@ -1793,6 +1935,7 @@ public:
UNUSED_METHOD_IMPL(VOID UpdateCLRImpl(const VOID *pNativeValue, OBJECTREF *ppProtectedCLRValue, OBJECTREF *ppProtectedOldCLRValue) const)
SCALAR_MARSHALER_IMPL(sizeof(DATE), sizeof(DATE))
+ COPY_TO_IMPL_BASE_STRUCT_ONLY()
VOID ScalarUpdateNativeImpl(LPVOID pCLR, LPVOID pNative) const;
VOID ScalarUpdateCLRImpl(const VOID *pNative, LPVOID pCLR) const;
@@ -1811,6 +1954,7 @@ public:
UNUSED_METHOD_IMPL(VOID UpdateCLRImpl(const VOID *pNativeValue, OBJECTREF *ppProtectedCLRValue, OBJECTREF *ppProtectedOldCLRValue) const)
SCALAR_MARSHALER_IMPL(sizeof(CURRENCY), sizeof(CURRENCY))
+ COPY_TO_IMPL_BASE_STRUCT_ONLY()
VOID ScalarUpdateNativeImpl(LPVOID pCLR, LPVOID pNative) const;
VOID ScalarUpdateCLRImpl(const VOID *pNative, LPVOID pCLR) const;
@@ -1825,6 +1969,7 @@ public:
UNUSED_METHOD_IMPL(VOID UpdateCLRImpl(const VOID *pNativeValue, OBJECTREF *ppProtectedCLRValue, OBJECTREF *ppProtectedOldCLRValue) const)
SCALAR_MARSHALER_IMPL(sizeof(INT64), sizeof(INT64))
+ COPY_TO_IMPL_BASE_STRUCT_ONLY()
VOID ScalarUpdateNativeImpl(LPVOID pCLR, LPVOID pNative) const;
VOID ScalarUpdateCLRImpl(const VOID *pNative, LPVOID pCLR) const;
diff --git a/src/vm/methodtablebuilder.cpp b/src/vm/methodtablebuilder.cpp
index f5a256a14f..bd9dd24e2e 100644
--- a/src/vm/methodtablebuilder.cpp
+++ b/src/vm/methodtablebuilder.cpp
@@ -4142,11 +4142,11 @@ VOID MethodTableBuilder::InitializeFieldDescs(FieldDesc *pFieldDescList,
{
if (pwalk->m_MD == bmtMetaData->pFields[i])
{
-
pLayoutFieldInfo = pwalk;
- CopyMemory(pNextFieldMarshaler,
- &(pwalk->m_FieldMarshaler),
- MAXFIELDMARSHALERSIZE);
+
+ const FieldMarshaler *pSrcFieldMarshaler = (const FieldMarshaler *) &pwalk->m_FieldMarshaler;
+
+ pSrcFieldMarshaler->CopyTo(pNextFieldMarshaler, MAXFIELDMARSHALERSIZE);
pNextFieldMarshaler->SetFieldDesc(pFD);
pNextFieldMarshaler->SetExternalOffset(pwalk->m_offset);
diff --git a/src/vm/typedesc.cpp b/src/vm/typedesc.cpp
index 67180684de..7da1c84604 100644
--- a/src/vm/typedesc.cpp
+++ b/src/vm/typedesc.cpp
@@ -40,7 +40,7 @@ BOOL ParamTypeDesc::Verify() {
STATIC_CONTRACT_DEBUG_ONLY;
STATIC_CONTRACT_SUPPORTS_DAC;
- _ASSERTE(m_TemplateMT.IsNull() || m_TemplateMT.GetValue()->SanityCheck());
+ _ASSERTE(m_TemplateMT.IsNull() || GetTemplateMethodTableInternal()->SanityCheck());
_ASSERTE(!GetTypeParam().IsNull());
BAD_FORMAT_NOTHROW_ASSERT(GetTypeParam().IsTypeDesc() || !GetTypeParam().AsMethodTable()->IsArray());
BAD_FORMAT_NOTHROW_ASSERT(CorTypeInfo::IsModifier_NoThrow(GetInternalCorElementType()) ||
@@ -59,7 +59,7 @@ BOOL ArrayTypeDesc::Verify() {
STATIC_CONTRACT_SUPPORTS_DAC;
// m_TemplateMT == 0 may be null when building types involving TypeVarTypeDesc's
- BAD_FORMAT_NOTHROW_ASSERT(m_TemplateMT.IsNull() || m_TemplateMT.GetValue()->IsArray());
+ BAD_FORMAT_NOTHROW_ASSERT(m_TemplateMT.IsNull() || GetTemplateMethodTable()->IsArray());
BAD_FORMAT_NOTHROW_ASSERT(CorTypeInfo::IsArray_NoThrow(GetInternalCorElementType()));
ParamTypeDesc::Verify();
return(true);
@@ -844,7 +844,7 @@ OBJECTREF ParamTypeDesc::GetManagedClassObject()
if (OwnsTemplateMethodTable())
{
// Set the handle on template methodtable as well to make Object.GetType for arrays take the fast path
- EnsureWritablePages(m_TemplateMT.GetValue()->GetWriteableDataForWrite())->m_hExposedClassObject = m_hExposedClassObject;
+ EnsureWritablePages(GetTemplateMethodTableInternal()->GetWriteableDataForWrite())->m_hExposedClassObject = m_hExposedClassObject;
}
// Log the TypeVarTypeDesc access
@@ -1011,7 +1011,7 @@ void TypeDesc::DoFullyLoad(Generics::RecursionGraph *pVisited, ClassLoadLevel le
// Fully load the template method table
if (!pPTD->m_TemplateMT.IsNull())
{
- pPTD->m_TemplateMT.GetValue()->DoFullyLoad(&newVisited, level, pPending, &fBailed, pInstContext);
+ pPTD->GetTemplateMethodTableInternal()->DoFullyLoad(&newVisited, level, pPending, &fBailed, pInstContext);
}
}
@@ -1189,8 +1189,8 @@ void ParamTypeDesc::Save(DataImage *image)
if (OwnsTemplateMethodTable())
{
// This TypeDesc should be the only one saving this MT
- _ASSERTE(!image->IsStored(m_TemplateMT.GetValue()));
- Module::SaveMethodTable(image, m_TemplateMT.GetValue(), 0);
+ _ASSERTE(!image->IsStored(GetTemplateMethodTableInternal()));
+ Module::SaveMethodTable(image, GetTemplateMethodTableInternal(), 0);
}
}
@@ -1219,8 +1219,8 @@ void ParamTypeDesc::Fixup(DataImage *image)
// TypeDesc and the MT are "tightly-knit") In other words if one is present in
// an NGEN image then then other will be, and if one is "used" at runtime then
// the other will be too.
- image->FixupPointerField(this, offsetof(ParamTypeDesc, m_TemplateMT));
- m_TemplateMT.GetValue()->Fixup(image);
+ image->FixupMethodTablePointer(this, &m_TemplateMT);
+ GetTemplateMethodTableInternal()->Fixup(image);
}
else
{
@@ -1275,14 +1275,14 @@ BOOL ParamTypeDesc::ComputeNeedsRestore(DataImage *image, TypeHandleList *pVisit
{
if (OwnsTemplateMethodTable())
{
- if (m_TemplateMT.GetValue()->ComputeNeedsRestore(image, pVisited))
+ if (GetTemplateMethodTableInternal()->ComputeNeedsRestore(image, pVisited))
{
res = TRUE;
}
}
else
{
- if (!image->CanPrerestoreEagerBindToMethodTable(m_TemplateMT.GetValue(), pVisited))
+ if (!image->CanPrerestoreEagerBindToMethodTable(GetTemplateMethodTableInternal(), pVisited))
{
res = TRUE;
}
@@ -2419,7 +2419,7 @@ ParamTypeDesc::EnumMemoryRegions(CLRDataEnumMemoryFlags flags)
SUPPORTS_DAC;
DAC_ENUM_DTHIS();
- PTR_MethodTable pTemplateMT = m_TemplateMT.GetValue();
+ PTR_MethodTable pTemplateMT = GetTemplateMethodTableInternal();
if (pTemplateMT.IsValid())
{
pTemplateMT->EnumMemoryRegions(flags);
diff --git a/src/vm/typedesc.h b/src/vm/typedesc.h
index a8b1c2552e..3e8b0e618b 100644
--- a/src/vm/typedesc.h
+++ b/src/vm/typedesc.h
@@ -254,7 +254,7 @@ public:
LIMITED_METHOD_CONTRACT;
- m_TemplateMT.SetValue(pMT);
+ m_TemplateMT.SetValueMaybeNull(pMT);
// ParamTypeDescs start out life not fully loaded
m_typeAndFlags |= TypeDesc::enum_flag_IsNotFullyLoaded;
@@ -323,8 +323,13 @@ public:
friend class ArrayOpLinker;
#endif
protected:
+ PTR_MethodTable GetTemplateMethodTableInternal() {
+ WRAPPER_NO_CONTRACT;
+ return ReadPointerMaybeNull(this, &ParamTypeDesc::m_TemplateMT);
+ }
+
// the m_typeAndFlags field in TypeDesc tell what kind of parameterized type we have
- FixupPointer<PTR_MethodTable> m_TemplateMT; // The shared method table, some variants do not use this field (it is null)
+ RelativeFixupPointer<PTR_MethodTable> m_TemplateMT; // The shared method table, some variants do not use this field (it is null)
TypeHandle m_Arg; // The type that is being modified
LOADERHANDLE m_hExposedClassObject; // handle back to the internal reflection Type object
};
@@ -380,8 +385,8 @@ public:
WRAPPER_NO_CONTRACT;
_ASSERTE(!m_TemplateMT.IsNull());
- _ASSERTE(m_TemplateMT.GetValue()->IsArray());
- _ASSERTE(m_TemplateMT.GetValue()->ParentEquals(g_pArrayClass));
+ _ASSERTE(GetTemplateMethodTableInternal()->IsArray());
+ _ASSERTE(GetTemplateMethodTableInternal()->ParentEquals(g_pArrayClass));
return g_pArrayClass;
}
@@ -416,16 +421,16 @@ public:
void Fixup(DataImage *image);
#endif
- MethodTable * GetTemplateMethodTable() {
+ PTR_MethodTable GetTemplateMethodTable() {
WRAPPER_NO_CONTRACT;
- MethodTable * pTemplateMT = m_TemplateMT.GetValue();
- _ASSERTE(pTemplateMT->IsArray());
- return pTemplateMT;
+ PTR_MethodTable ptrTemplateMT = GetTemplateMethodTableInternal();
+ _ASSERTE(ptrTemplateMT->IsArray());
+ return ptrTemplateMT;
}
TADDR GetTemplateMethodTableMaybeTagged() {
WRAPPER_NO_CONTRACT;
- return m_TemplateMT.GetValueMaybeTagged();
+ return m_TemplateMT.GetValueMaybeTagged(dac_cast<TADDR>(this) + offsetof(ArrayTypeDesc, m_TemplateMT));
}
#ifdef FEATURE_COMINTEROP
diff --git a/src/vm/typedesc.inl b/src/vm/typedesc.inl
index 4d7416ebf8..312270edbb 100644
--- a/src/vm/typedesc.inl
+++ b/src/vm/typedesc.inl
@@ -31,7 +31,7 @@ inline PTR_MethodTable TypeDesc::GetMethodTable() {
if (GetInternalCorElementType() == ELEMENT_TYPE_VALUETYPE)
return dac_cast<PTR_MethodTable>(asParam->m_Arg.AsMethodTable());
else
- return(asParam->m_TemplateMT.GetValue());
+ return(asParam->GetTemplateMethodTableInternal());
}
inline TypeHandle TypeDesc::GetTypeParam() {