summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/debug/daccess/nidump.cpp26
-rw-r--r--src/vm/class.cpp14
-rw-r--r--src/vm/class.h67
-rw-r--r--src/vm/class.inl2
-rw-r--r--src/vm/classhash.cpp57
-rw-r--r--src/vm/comcallablewrapper.cpp2
-rw-r--r--src/vm/comdelegate.cpp38
-rw-r--r--src/vm/comsynchronizable.cpp2
-rw-r--r--src/vm/instmethhash.cpp8
-rw-r--r--src/vm/jitinterface.cpp4
-rw-r--r--src/vm/methodtablebuilder.cpp14
-rw-r--r--src/vm/ngenhash.h114
-rw-r--r--src/vm/ngenhash.inl189
-rw-r--r--src/vm/stubhelpers.cpp4
-rw-r--r--src/vm/typedesc.cpp18
-rw-r--r--src/vm/typedesc.h7
-rw-r--r--src/vm/typehash.cpp39
-rw-r--r--src/vm/typehash.h16
18 files changed, 397 insertions, 224 deletions
diff --git a/src/debug/daccess/nidump.cpp b/src/debug/daccess/nidump.cpp
index 81874a26ca..a878c7ce26 100644
--- a/src/debug/daccess/nidump.cpp
+++ b/src/debug/daccess/nidump.cpp
@@ -4470,14 +4470,14 @@ void NativeImageDumper::TraverseNgenHash(DPTR(HASH_CLASS) pTable,
}
DisplayWriteFieldPointer(m_pModule,
- DPtrToPreferredAddr(pTable->m_pModule),
+ DPtrToPreferredAddr(pTable->GetModule()),
HASH_CLASS, MODULE);
// Dump warm (volatile) entries.
DisplayWriteFieldUInt(m_cWarmEntries, pTable->m_cWarmEntries, HASH_CLASS, MODULE);
DisplayWriteFieldUInt(m_cWarmBuckets, pTable->m_cWarmBuckets, HASH_CLASS, MODULE);
DisplayWriteFieldAddress(m_pWarmBuckets,
- DPtrToPreferredAddr(pTable->m_pWarmBuckets),
+ DPtrToPreferredAddr(pTable->GetWarmBuckets()),
sizeof(HASH_ENTRY_CLASS*) * pTable->m_cWarmBuckets,
HASH_CLASS, MODULE);
@@ -4513,11 +4513,11 @@ void NativeImageDumper::TraverseNgenPersistedEntries(DPTR(HASH_CLASS) pTable,
DisplayWriteFieldUInt(m_cEntries, pEntries->m_cEntries, typename HASH_CLASS::PersistedEntries, MODULE);
DisplayWriteFieldUInt(m_cBuckets, pEntries->m_cBuckets, typename HASH_CLASS::PersistedEntries, MODULE);
DisplayWriteFieldAddress(m_pBuckets,
- DPtrToPreferredAddr(pEntries->m_pBuckets),
- pEntries->m_cBuckets ? pEntries->m_pBuckets->GetSize(pEntries->m_cBuckets) : 0,
+ DPtrToPreferredAddr(pTable->GetPersistedBuckets(pEntries)),
+ pEntries->m_cBuckets ? pTable->GetPersistedBuckets(pEntries)->GetSize(pEntries->m_cBuckets) : 0,
typename HASH_CLASS::PersistedEntries, MODULE);
DisplayWriteFieldAddress(m_pEntries,
- DPtrToPreferredAddr(pEntries->m_pEntries),
+ DPtrToPreferredAddr(pTable->GetPersistedEntries(pEntries)),
sizeof(typename HASH_CLASS::PersistedEntry) * pEntries->m_cEntries,
typename HASH_CLASS::PersistedEntries, MODULE);
@@ -4529,7 +4529,7 @@ void NativeImageDumper::TraverseNgenPersistedEntries(DPTR(HASH_CLASS) pTable,
{
// Get index of the first entry and the count of entries in the bucket.
DWORD dwEntryId, cEntries;
- pEntries->m_pBuckets->GetBucket(i, &dwEntryId, &cEntries);
+ pTable->GetPersistedBuckets(pEntries)->GetBucket(i, &dwEntryId, &cEntries);
// Loop over entries.
while (cEntries && (CHECK_OPT(SLIM_MODULE_TBLS)
@@ -4537,7 +4537,7 @@ void NativeImageDumper::TraverseNgenPersistedEntries(DPTR(HASH_CLASS) pTable,
|| CHECK_OPT(METHODTABLES)))
{
// Lookup entry in the array via the index we have.
- typename HASH_CLASS::PTR_PersistedEntry pEntry(PTR_TO_TADDR(pEntries->m_pEntries) +
+ typename HASH_CLASS::PTR_PersistedEntry pEntry(PTR_TO_TADDR(pTable->GetPersistedEntries(pEntries)) +
(dwEntryId * sizeof(typename HASH_CLASS::PersistedEntry)));
IF_OPT(SLIM_MODULE_TBLS)
@@ -8255,7 +8255,7 @@ NativeImageDumper::DumpEEClassForMethodTable( PTR_MethodTable mt )
EEClass, EECLASSES );
#endif
- WriteFieldMethodTable( m_pMethodTable, clazz->m_pMethodTable, EEClass,
+ WriteFieldMethodTable( m_pMethodTable, clazz->GetMethodTable(), EEClass,
EECLASSES );
WriteFieldCorElementType( m_NormType, (CorElementType)clazz->m_NormType,
@@ -8516,7 +8516,7 @@ NativeImageDumper::DumpEEClassForMethodTable( PTR_MethodTable mt )
DelegateEEClass, EECLASSES );
WriteFieldMethodDesc( m_pInvokeMethod,
- delegateClass->m_pInvokeMethod,
+ delegateClass->GetInvokeMethod(),
DelegateEEClass, EECLASSES );
DumpFieldStub( m_pMultiCastInvokeStub,
delegateClass->m_pMultiCastInvokeStub,
@@ -8543,10 +8543,10 @@ NativeImageDumper::DumpEEClassForMethodTable( PTR_MethodTable mt )
}
WriteFieldMethodDesc( m_pBeginInvokeMethod,
- delegateClass->m_pBeginInvokeMethod,
+ delegateClass->GetBeginInvokeMethod(),
DelegateEEClass, EECLASSES );
WriteFieldMethodDesc( m_pEndInvokeMethod,
- delegateClass->m_pEndInvokeMethod,
+ delegateClass->GetEndInvokeMethod(),
DelegateEEClass, EECLASSES );
DisplayWriteFieldPointer( m_pMarshalStub, delegateClass->m_pMarshalStub,
DelegateEEClass, EECLASSES );
@@ -8675,7 +8675,7 @@ NativeImageDumper::DumpEEClassForMethodTable( PTR_MethodTable mt )
}
}
}
- PTR_BYTE varianceInfo = TO_TADDR(pClassOptional->m_pVarianceInfo);
+ PTR_BYTE varianceInfo = pClassOptional->GetVarianceInfo();
if( varianceInfo == NULL )
{
DisplayWriteFieldPointer( m_pVarianceInfo, NULL,
@@ -8832,7 +8832,7 @@ void NativeImageDumper::DumpTypeDesc( PTR_TypeDesc td )
PTR_TypeVarTypeDesc tvtd(td);
DisplayStartVStructure( "TypeVarTypeDesc", TYPEDESCS );
DisplayWriteFieldPointer( m_pModule,
- DPtrToPreferredAddr(tvtd->m_pModule),
+ DPtrToPreferredAddr(tvtd->GetModule()),
TypeVarTypeDesc, TYPEDESCS );
DisplayWriteFieldUInt( m_typeOrMethodDef,
tvtd->m_typeOrMethodDef,
diff --git a/src/vm/class.cpp b/src/vm/class.cpp
index 21720909cb..0259b1e4fc 100644
--- a/src/vm/class.cpp
+++ b/src/vm/class.cpp
@@ -2884,7 +2884,7 @@ void EEClass::Save(DataImage *image, MethodTable *pMT)
{
// make sure we don't store a GUID_NULL guid in the NGEN image
// instead we'll compute the GUID at runtime, and throw, if appropriate
- m_pGuidInfo = NULL;
+ m_pGuidInfo.SetValueMaybeNull(NULL);
}
}
}
@@ -2961,14 +2961,14 @@ void EEClass::Fixup(DataImage *image, MethodTable *pMT)
}
if (HasOptionalFields())
- image->FixupPointerField(GetOptionalFields(), offsetof(EEClassOptionalFields, m_pVarianceInfo));
+ image->FixupRelativePointerField(GetOptionalFields(), offsetof(EEClassOptionalFields, m_pVarianceInfo));
//
// We pass in the method table, because some classes (e.g. remoting proxy)
// have fake method tables set up in them & we want to restore the regular
// one.
//
- image->FixupField(this, offsetof(EEClass, m_pMethodTable), pMT);
+ image->FixupField(this, offsetof(EEClass, m_pMethodTable), pMT, 0, IMAGE_REL_BASED_RelativePointer);
//
// Fixup MethodDescChunk and MethodDescs
@@ -3043,9 +3043,9 @@ void EEClass::Fixup(DataImage *image, MethodTable *pMT)
}
else if (IsDelegate())
{
- image->FixupPointerField(this, offsetof(DelegateEEClass, m_pInvokeMethod));
- image->FixupPointerField(this, offsetof(DelegateEEClass, m_pBeginInvokeMethod));
- image->FixupPointerField(this, offsetof(DelegateEEClass, m_pEndInvokeMethod));
+ image->FixupRelativePointerField(this, offsetof(DelegateEEClass, m_pInvokeMethod));
+ image->FixupRelativePointerField(this, offsetof(DelegateEEClass, m_pBeginInvokeMethod));
+ image->FixupRelativePointerField(this, offsetof(DelegateEEClass, m_pEndInvokeMethod));
image->ZeroPointerField(this, offsetof(DelegateEEClass, m_pUMThunkMarshInfo));
image->ZeroPointerField(this, offsetof(DelegateEEClass, m_pStaticCallStub));
@@ -3078,7 +3078,7 @@ void EEClass::Fixup(DataImage *image, MethodTable *pMT)
//
if (IsInterface() && GetGuidInfo() != NULL)
- image->FixupPointerField(this, offsetof(EEClass, m_pGuidInfo));
+ image->FixupRelativePointerField(this, offsetof(EEClass, m_pGuidInfo));
else
image->ZeroPointerField(this, offsetof(EEClass, m_pGuidInfo));
diff --git a/src/vm/class.h b/src/vm/class.h
index 90bebde4a6..cb4750811b 100644
--- a/src/vm/class.h
+++ b/src/vm/class.h
@@ -676,7 +676,7 @@ class EEClassOptionalFields
// Variance info for each type parameter (gpNonVariant, gpCovariant, or gpContravariant)
// If NULL, this type has no type parameters that are co/contravariant
- BYTE* m_pVarianceInfo;
+ RelativePointer<PTR_BYTE> m_pVarianceInfo;
//
// COM RELATED FIELDS.
@@ -714,6 +714,13 @@ class EEClassOptionalFields
// Set default values for optional fields.
inline void Init();
+
+ PTR_BYTE GetVarianceInfo()
+ {
+ LIMITED_METHOD_DAC_CONTRACT;
+
+ return ReadPointerMaybeNull(this, &EEClassOptionalFields::m_pVarianceInfo);
+ }
};
typedef DPTR(EEClassOptionalFields) PTR_EEClassOptionalFields;
@@ -971,12 +978,12 @@ public:
// will return the method table pointer corresponding to the "canonical"
// instantiation, as defined in typehandle.h.
//
- inline MethodTable* GetMethodTable()
+ inline PTR_MethodTable GetMethodTable()
{
LIMITED_METHOD_CONTRACT;
SUPPORTS_DAC;
- return m_pMethodTable;
+ return ReadPointerMaybeNull(this, &EEClass::m_pMethodTable);
}
// DO NOT ADD ANY ASSERTS TO THIS METHOD.
@@ -993,14 +1000,14 @@ public:
CANNOT_HAVE_CONTRACT;
SUPPORTS_DAC;
- return m_pMethodTable;
+ return ReadPointerMaybeNull(this, &EEClass::m_pMethodTable);
}
-#ifndef DACCESS_COMPILE
+#ifndef DACCESS_COMPILE
inline void SetMethodTable(MethodTable* pMT)
{
LIMITED_METHOD_CONTRACT;
- m_pMethodTable = pMT;
+ m_pMethodTable.SetValueMaybeNull(pMT);
}
#endif // !DACCESS_COMPILE
@@ -1655,14 +1662,15 @@ public:
inline PTR_GuidInfo GetGuidInfo()
{
LIMITED_METHOD_DAC_CONTRACT;
- return m_pGuidInfo;
+
+ return ReadPointerMaybeNull(this, &EEClass::m_pGuidInfo);
}
inline void SetGuidInfo(GuidInfo* pGuidInfo)
{
WRAPPER_NO_CONTRACT;
#ifndef DACCESS_COMPILE
- *EnsureWritablePages(&m_pGuidInfo) = pGuidInfo;
+ EnsureWritablePages(&m_pGuidInfo)->SetValueMaybeNull(pGuidInfo);
#endif // DACCESS_COMPILE
}
@@ -1824,6 +1832,7 @@ public:
GetOptionalFields()->m_pDictLayout = pLayout;
}
+#ifndef DACCESS_COMPILE
static CorGenericParamAttr GetVarianceOfTypeParameter(BYTE * pbVarianceInfo, DWORD i)
{
LIMITED_METHOD_CONTRACT;
@@ -1842,15 +1851,16 @@ public:
BYTE* GetVarianceInfo()
{
LIMITED_METHOD_CONTRACT;
- return HasOptionalFields() ? GetOptionalFields()->m_pVarianceInfo : NULL;
+ return HasOptionalFields() ? GetOptionalFields()->GetVarianceInfo() : NULL;
}
void SetVarianceInfo(BYTE *pVarianceInfo)
{
LIMITED_METHOD_CONTRACT;
_ASSERTE(HasOptionalFields());
- GetOptionalFields()->m_pVarianceInfo = pVarianceInfo;
+ GetOptionalFields()->m_pVarianceInfo.SetValueMaybeNull(pVarianceInfo);
}
+#endif // !DACCESS_COMPILE
// Check that a signature blob uses type parameters correctly
// in accordance with the variance annotations specified by this class
@@ -2090,7 +2100,7 @@ public:
// C_ASSERTs in Jitinterface.cpp need this to be public to check the offset.
// Put it first so the offset rarely changes, which just reduces the number of times we have to fiddle
// with the offset.
- PTR_GuidInfo m_pGuidInfo; // The cached guid inforation for interfaces.
+ RelativePointer<PTR_GuidInfo> m_pGuidInfo; // The cached guid information for interfaces.
#ifdef _DEBUG
public:
@@ -2104,7 +2114,7 @@ private:
RelativePointer<PTR_EEClassOptionalFields> m_rpOptionalFields;
// TODO: Remove this field. It is only used by SOS and object validation for stress.
- PTR_MethodTable m_pMethodTable;
+ RelativePointer<PTR_MethodTable> m_pMethodTable;
RelativePointer<PTR_FieldDesc> m_pFieldDescList;
RelativePointer<PTR_MethodDescChunk> m_pChunks;
@@ -2300,15 +2310,15 @@ struct ComPlusCallInfo;
class DelegateEEClass : public EEClass
{
public:
- PTR_Stub m_pStaticCallStub;
- PTR_Stub m_pInstRetBuffCallStub;
- PTR_MethodDesc m_pInvokeMethod;
- PTR_Stub m_pMultiCastInvokeStub;
- PTR_Stub m_pSecureDelegateInvokeStub;
- UMThunkMarshInfo* m_pUMThunkMarshInfo;
- PTR_MethodDesc m_pBeginInvokeMethod;
- PTR_MethodDesc m_pEndInvokeMethod;
- Volatile<PCODE> m_pMarshalStub;
+ PTR_Stub m_pStaticCallStub;
+ PTR_Stub m_pInstRetBuffCallStub;
+ RelativePointer<PTR_MethodDesc> m_pInvokeMethod;
+ PTR_Stub m_pMultiCastInvokeStub;
+ PTR_Stub m_pSecureDelegateInvokeStub;
+ UMThunkMarshInfo* m_pUMThunkMarshInfo;
+ RelativePointer<PTR_MethodDesc> m_pBeginInvokeMethod;
+ RelativePointer<PTR_MethodDesc> m_pEndInvokeMethod;
+ Volatile<PCODE> m_pMarshalStub;
#ifdef FEATURE_COMINTEROP
ComPlusCallInfo *m_pComPlusCallInfo;
@@ -2321,6 +2331,21 @@ public:
MethodDesc* m_pForwardStubMD; // marshaling stub for calls to unmanaged code
MethodDesc* m_pReverseStubMD; // marshaling stub for calls from unmanaged code
+ PTR_MethodDesc GetInvokeMethod()
+ {
+ return ReadPointer(this, &DelegateEEClass::m_pInvokeMethod);
+ }
+
+ PTR_MethodDesc GetBeginInvokeMethod()
+ {
+ return ReadPointer(this, &DelegateEEClass::m_pBeginInvokeMethod);
+ }
+
+ PTR_MethodDesc GetEndInvokeMethod()
+ {
+ return ReadPointer(this, &DelegateEEClass::m_pEndInvokeMethod);
+ }
+
#ifndef DACCESS_COMPILE
DelegateEEClass() : EEClass(sizeof(DelegateEEClass))
{
diff --git a/src/vm/class.inl b/src/vm/class.inl
index bc86e84101..78e05cdd14 100644
--- a/src/vm/class.inl
+++ b/src/vm/class.inl
@@ -39,7 +39,7 @@ inline void EEClassOptionalFields::Init()
{
LIMITED_METHOD_CONTRACT;
m_pDictLayout = NULL;
- m_pVarianceInfo = NULL;
+ m_pVarianceInfo.SetValueMaybeNull(NULL);
#ifdef FEATURE_COMINTEROP
m_pSparseVTableMap = NULL;
m_pCoClassForIntf = TypeHandle();
diff --git a/src/vm/classhash.cpp b/src/vm/classhash.cpp
index 2ffc612d66..31c7e84906 100644
--- a/src/vm/classhash.cpp
+++ b/src/vm/classhash.cpp
@@ -145,7 +145,7 @@ VOID EEClassHashTable::UncompressModuleAndNonExportClassDef(HashDatum Data, Modu
_ASSERTE(!(dwData & EECLASSHASH_MDEXPORT_DISCR));
*pCL = ((dwData >> 1) & 0x00ffffff) | mdtTypeDef;
- *ppModule = m_pModule;
+ *ppModule = GetModule();
}
bool EEClassHashTable::UncompressModuleAndClassDef(HashDatum Data, Loader::LoadFlag loadFlag,
@@ -172,8 +172,7 @@ bool EEClassHashTable::UncompressModuleAndClassDef(HashDatum Data, Loader::LoadF
if(dwData & EECLASSHASH_MDEXPORT_DISCR) {
*pmdFoundExportedType = ((dwData >> 1) & 0x00ffffff) | mdtExportedType;
- *ppModule = m_pModule->GetAssembly()->
- FindModuleByExportedType(*pmdFoundExportedType, loadFlag, mdTypeDefNil, pCL);
+ *ppModule = GetModule()->GetAssembly()->FindModuleByExportedType(*pmdFoundExportedType, loadFlag, mdTypeDefNil, pCL);
}
else {
UncompressModuleAndNonExportClassDef(Data, ppModule, pCL);
@@ -232,7 +231,7 @@ VOID EEClassHashTable::ConstructKeyFromData(PTR_EEClassHashEntry pEntry, // IN
// in this case, the lifetime of Key is bounded by the lifetime of cqb, which will free the memory
// it allocated on destruction.
- _ASSERTE(m_pModule);
+ _ASSERTE(!m_pModule.IsNull());
LPSTR pszName = NULL;
LPSTR pszNameSpace = NULL;
IMDInternalImport *pInternalImport = NULL;
@@ -259,7 +258,7 @@ VOID EEClassHashTable::ConstructKeyFromData(PTR_EEClassHashEntry pEntry, // IN
mdToken mdtUncompressed = UncompressModuleAndClassDef(Data);
if (TypeFromToken(mdtUncompressed) == mdtExportedType)
{
- IfFailThrow(m_pModule->GetClassLoader()->GetAssembly()->GetManifestImport()->GetExportedTypeProps(
+ IfFailThrow(GetModule()->GetClassLoader()->GetAssembly()->GetManifestImport()->GetExportedTypeProps(
mdtUncompressed,
(LPCSTR *)&pszNameSpace,
(LPCSTR *)&pszName,
@@ -355,7 +354,7 @@ EEClassHashEntry_t *EEClassHashTable::InsertValue(LPCUTF8 pszNamespace, LPCUTF8
_ASSERTE(pszNamespace != NULL);
_ASSERTE(pszClassName != NULL);
- _ASSERTE(m_pModule);
+ _ASSERTE(!m_pModule.IsNull());
EEClassHashEntry *pEntry = BaseAllocateEntry(pamTracker);
@@ -433,10 +432,9 @@ EEClassHashEntry_t *EEClassHashTable::InsertValueIfNotFound(LPCUTF8 pszNamespace
}
CONTRACTL_END;
- _ASSERTE(m_pModule);
+ _ASSERTE(!m_pModule.IsNull());
_ASSERTE(pszNamespace != NULL);
_ASSERTE(pszClassName != NULL);
- _ASSERTE(m_pModule);
EEClassHashEntry_t * pNewEntry = FindItem(pszNamespace, pszClassName, IsNested, NULL);
@@ -479,7 +477,7 @@ EEClassHashEntry_t *EEClassHashTable::FindItem(LPCUTF8 pszNamespace, LPCUTF8 psz
}
CONTRACTL_END;
- _ASSERTE(m_pModule);
+ _ASSERTE(!m_pModule.IsNull());
_ASSERTE(pszNamespace != NULL);
_ASSERTE(pszClassName != NULL);
@@ -533,7 +531,7 @@ EEClassHashEntry_t *EEClassHashTable::FindNextNestedClass(NameHandle* pName, PTR
}
CONTRACTL_END;
- _ASSERTE(m_pModule);
+ _ASSERTE(!m_pModule.IsNull());
_ASSERTE(pName);
if (pName->GetNameSpace())
@@ -564,7 +562,7 @@ EEClassHashEntry_t *EEClassHashTable::FindNextNestedClass(LPCUTF8 pszNamespace,
}
CONTRACTL_END;
- _ASSERTE(m_pModule);
+ _ASSERTE(!m_pModule.IsNull());
PTR_EEClassHashEntry pSearch = BaseFindNextEntryByHash(pContext);
@@ -597,7 +595,7 @@ EEClassHashEntry_t *EEClassHashTable::FindNextNestedClass(LPCUTF8 pszFullyQualif
}
CONTRACTL_END;
- _ASSERTE(m_pModule);
+ _ASSERTE(!m_pModule.IsNull());
CQuickBytes szNamespace;
@@ -639,7 +637,7 @@ EEClassHashEntry_t * EEClassHashTable::GetValue(LPCUTF8 pszFullyQualifiedName, P
}
CONTRACTL_END;
- _ASSERTE(m_pModule);
+ _ASSERTE(!m_pModule.IsNull());
CQuickBytes szNamespace;
@@ -685,7 +683,7 @@ EEClassHashEntry_t * EEClassHashTable::GetValue(LPCUTF8 pszNamespace, LPCUTF8 ps
CONTRACTL_END;
- _ASSERTE(m_pModule);
+ _ASSERTE(!m_pModule.IsNull());
EEClassHashEntry_t *pItem = FindItem(pszNamespace, pszClassName, IsNested, pContext);
if (pItem)
*pData = pItem->GetData();
@@ -709,7 +707,7 @@ EEClassHashEntry_t * EEClassHashTable::GetValue(NameHandle* pName, PTR_VOID *pDa
_ASSERTE(pName);
- _ASSERTE(m_pModule);
+ _ASSERTE(!m_pModule.IsNull());
if(pName->GetNameSpace() == NULL) {
return GetValue(pName->GetName(), pData, IsNested, pContext);
}
@@ -753,7 +751,7 @@ BOOL EEClassHashTable::CompareKeys(PTR_EEClassHashEntry pEntry, LPCUTF8 * pKey2)
CONTRACTL_END;
- _ASSERTE(m_pModule);
+ _ASSERTE(!m_pModule.IsNull());
_ASSERTE (pEntry);
_ASSERTE (pKey2);
@@ -778,7 +776,7 @@ void EEClassHashTable::Save(DataImage *image, CorProfileData *profileData)
STANDARD_VM_CONTRACT;
// See comment on PrepareExportedTypesForSaving for what's going on here.
- if (m_pModule->IsManifest())
+ if (GetModule()->IsManifest())
PrepareExportedTypesForSaving(image);
// The base class handles most of the saving logic (it controls the layout of the hash memory). It will
@@ -876,11 +874,11 @@ void EEClassHashTable::PrepareExportedTypesForSaving(DataImage *image)
THROWS;
GC_TRIGGERS;
PRECONDITION(GetAppDomain()->IsCompilationDomain());
- PRECONDITION(m_pModule->IsManifest());
+ PRECONDITION(GetModule()->IsManifest());
}
CONTRACTL_END
- IMDInternalImport *pImport = m_pModule->GetMDImport();
+ IMDInternalImport *pImport = GetModule()->GetMDImport();
HENUMInternalHolder phEnum(pImport);
phEnum.EnumInit(mdtExportedType, mdTokenNil);
@@ -900,7 +898,7 @@ void EEClassHashTable::PrepareExportedTypesForSaving(DataImage *image)
&typeDef,
&dwFlags)))
{
- THROW_BAD_FORMAT(BFA_NOFIND_EXPORTED_TYPE, m_pModule);
+ THROW_BAD_FORMAT(BFA_NOFIND_EXPORTED_TYPE, GetModule());
continue;
}
@@ -936,16 +934,19 @@ void EEClassHashTable::PrepareExportedTypesForSaving(DataImage *image)
// "CompareNestedEntryWithExportedType" will check if "pEntry->pEncloser" is a type of "mdImpl",
// as well as walking up the enclosing chain.
_ASSERTE (TypeFromToken(mdImpl) == mdtExportedType);
- while ((!m_pModule->GetClassLoader()->CompareNestedEntryWithExportedType(pImport,
- mdImpl,
- this,
- pEntry->GetEncloser())) &&
- (pEntry = FindNextNestedClass(pszNameSpace, pszName, &data, &sContext)) != NULL);
+ while ((!GetModule()->GetClassLoader()->CompareNestedEntryWithExportedType(pImport,
+ mdImpl,
+ this,
+ pEntry->GetEncloser()))
+ && (pEntry = FindNextNestedClass(pszNameSpace, pszName, &data, &sContext)) != NULL)
+ {
+ ;
+ }
}
}
if (!pEntry) {
- THROW_BAD_FORMAT(BFA_NOFIND_EXPORTED_TYPE, m_pModule);
+ THROW_BAD_FORMAT(BFA_NOFIND_EXPORTED_TYPE, GetModule());
continue;
}
@@ -1057,8 +1058,8 @@ EEClassHashTable *EEClassHashTable::MakeCaseInsensitiveTable(Module *pModule, Al
- _ASSERTE(m_pModule);
- _ASSERTE (pModule == m_pModule);
+ _ASSERTE(!m_pModule.IsNull());
+ _ASSERTE(pModule == GetModule());
// Allocate the table and verify that we actually got one.
EEClassHashTable * pCaseInsTable = EEClassHashTable::Create(pModule,
diff --git a/src/vm/comcallablewrapper.cpp b/src/vm/comcallablewrapper.cpp
index 156db505f7..af8b7b4946 100644
--- a/src/vm/comcallablewrapper.cpp
+++ b/src/vm/comcallablewrapper.cpp
@@ -4997,7 +4997,7 @@ void ComMethodTable::LayOutDelegateMethodTable()
// Some space for a CALL xx xx xx xx stub is reserved before the beginning of the MethodDesc
ComCallMethodDescHolder NewMDHolder = (ComCallMethodDesc *) (pMethodDescMemory + COMMETHOD_PREPAD);
- MethodDesc* pInvokeMD = ((DelegateEEClass *)(pDelegateMT->GetClass()))->m_pInvokeMethod;
+ MethodDesc* pInvokeMD = ((DelegateEEClass *)(pDelegateMT->GetClass()))->GetInvokeMethod();
if (pInvokeMD->IsSharedByGenericInstantiations())
{
diff --git a/src/vm/comdelegate.cpp b/src/vm/comdelegate.cpp
index b55e798453..cee0d8c08a 100644
--- a/src/vm/comdelegate.cpp
+++ b/src/vm/comdelegate.cpp
@@ -582,7 +582,7 @@ ComPlusCallInfo * COMDelegate::PopulateComPlusCallInfo(MethodTable * pDelMT)
// We need a LoaderHeap that lives at least as long as the DelegateEEClass, but ideally no longer
LoaderHeap *DelegateEEClass::GetStubHeap()
{
- return m_pInvokeMethod->GetLoaderAllocator()->GetStubHeap();
+ return GetInvokeMethod()->GetLoaderAllocator()->GetStubHeap();
}
@@ -601,7 +601,7 @@ Stub* COMDelegate::SetupShuffleThunk(MethodTable * pDelMT, MethodDesc *pTargetMe
DelegateEEClass * pClass = (DelegateEEClass *)pDelMT->GetClass();
- MethodDesc *pMD = pClass->m_pInvokeMethod;
+ MethodDesc *pMD = pClass->GetInvokeMethod();
StackSArray<ShuffleEntry> rShuffleEntryArray;
GenerateShuffleArray(pMD, pTargetMeth, &rShuffleEntryArray);
@@ -2375,7 +2375,7 @@ PCODE COMDelegate::GetInvokeMethodStub(EEImplMethodDesc* pMD)
MethodTable * pDelMT = pMD->GetMethodTable();
DelegateEEClass* pClass = (DelegateEEClass*) pDelMT->GetClass();
- if (pMD == pClass->m_pInvokeMethod)
+ if (pMD == pClass->GetInvokeMethod())
{
// Validate the invoke method, which at the moment just means checking the calling convention
@@ -2391,7 +2391,7 @@ PCODE COMDelegate::GetInvokeMethodStub(EEImplMethodDesc* pMD)
// and not an invalid-delegate-layout condition.
//
// If the call was indeed for async delegate invocation, we will just throw an exception.
- if ((pMD == pClass->m_pBeginInvokeMethod) || (pMD == pClass->m_pEndInvokeMethod))
+ if ((pMD == pClass->GetBeginInvokeMethod()) || (pMD == pClass->GetEndInvokeMethod()))
{
COMPlusThrow(kPlatformNotSupportedException);
}
@@ -2515,7 +2515,7 @@ DELEGATEREF COMDelegate::CreateSecureDelegate(DELEGATEREF delegate, MethodDesc*
CONTRACTL_END;
MethodTable *pDelegateType = delegate->GetMethodTable();
- MethodDesc *pMD = ((DelegateEEClass*)(pDelegateType->GetClass()))->m_pInvokeMethod;
+ MethodDesc *pMD = ((DelegateEEClass*)(pDelegateType->GetClass()))->GetInvokeMethod();
// allocate the object
struct _gc {
DELEGATEREF refSecDel;
@@ -2615,7 +2615,7 @@ FCIMPL1(MethodDesc*, COMDelegate::GetInvokeMethod, Object* refThisIn)
OBJECTREF refThis = ObjectToOBJECTREF(refThisIn);
MethodTable * pDelMT = refThis->GetMethodTable();
- MethodDesc* pMD = ((DelegateEEClass*)(pDelMT->GetClass()))->m_pInvokeMethod;
+ MethodDesc* pMD = ((DelegateEEClass*)(pDelMT->GetClass()))->GetInvokeMethod();
_ASSERTE(pMD);
return pMD;
}
@@ -2633,7 +2633,7 @@ FCIMPL1(PCODE, COMDelegate::GetMulticastInvoke, Object* refThisIn)
Stub *pStub = delegateEEClass->m_pMultiCastInvokeStub;
if (pStub == NULL)
{
- MethodDesc* pMD = delegateEEClass->m_pInvokeMethod;
+ MethodDesc* pMD = delegateEEClass->GetInvokeMethod();
HELPER_METHOD_FRAME_BEGIN_RET_0();
@@ -2757,7 +2757,7 @@ FCIMPL1(PCODE, COMDelegate::GetMulticastInvoke, Object* refThisIn)
Stub *pStub = delegateEEClass->m_pMultiCastInvokeStub;
if (pStub == NULL)
{
- MethodDesc* pMD = delegateEEClass->m_pInvokeMethod;
+ MethodDesc* pMD = delegateEEClass->GetInvokeMethod();
HELPER_METHOD_FRAME_BEGIN_RET_0();
@@ -3091,7 +3091,7 @@ MethodDesc* COMDelegate::FindDelegateInvokeMethod(MethodTable *pMT)
_ASSERTE(pMT->IsDelegate());
- MethodDesc * pMD = ((DelegateEEClass*)pMT->GetClass())->m_pInvokeMethod;
+ MethodDesc * pMD = ((DelegateEEClass*)pMT->GetClass())->GetInvokeMethod();
if (pMD == NULL)
COMPlusThrowNonLocalized(kMissingMethodException, W("Invoke"));
return pMD;
@@ -3104,7 +3104,7 @@ BOOL COMDelegate::IsDelegateInvokeMethod(MethodDesc *pMD)
MethodTable *pMT = pMD->GetMethodTable();
_ASSERTE(pMT->IsDelegate());
- return (pMD == ((DelegateEEClass *)pMT->GetClass())->m_pInvokeMethod);
+ return (pMD == ((DelegateEEClass *)pMT->GetClass())->GetInvokeMethod());
}
BOOL COMDelegate::IsMethodDescCompatible(TypeHandle thFirstArg,
@@ -3657,7 +3657,7 @@ BOOL COMDelegate::ValidateCtor(TypeHandle instHnd,
DelegateEEClass *pdlgEEClass = (DelegateEEClass*)dlgtHnd.AsMethodTable()->GetClass();
PREFIX_ASSUME(pdlgEEClass != NULL);
- MethodDesc *pDlgtInvoke = pdlgEEClass->m_pInvokeMethod;
+ MethodDesc *pDlgtInvoke = pdlgEEClass->GetInvokeMethod();
if (pDlgtInvoke == NULL)
return FALSE;
return IsMethodDescCompatible(instHnd, ftnParentHnd, pFtn, dlgtHnd, pDlgtInvoke, DBF_RelaxedSignature, pfIsOpenDelegate);
@@ -3672,18 +3672,18 @@ BOOL COMDelegate::ValidateBeginInvoke(DelegateEEClass* pClass)
MODE_ANY;
PRECONDITION(CheckPointer(pClass));
- PRECONDITION(CheckPointer(pClass->m_pBeginInvokeMethod));
+ PRECONDITION(CheckPointer(pClass->GetBeginInvokeMethod()));
// insert fault. Can the binder throw an OOM?
}
CONTRACTL_END;
- if (pClass->m_pInvokeMethod == NULL)
+ if (pClass->GetInvokeMethod() == NULL)
return FALSE;
// We check the signatures under the typical instantiation of the possibly generic class
- MetaSig beginInvokeSig(pClass->m_pBeginInvokeMethod->LoadTypicalMethodDefinition());
- MetaSig invokeSig(pClass->m_pInvokeMethod->LoadTypicalMethodDefinition());
+ MetaSig beginInvokeSig(pClass->GetBeginInvokeMethod()->LoadTypicalMethodDefinition());
+ MetaSig invokeSig(pClass->GetInvokeMethod()->LoadTypicalMethodDefinition());
if (beginInvokeSig.GetCallingConventionInfo() != (IMAGE_CEE_CS_CALLCONV_HASTHIS | IMAGE_CEE_CS_CALLCONV_DEFAULT))
return FALSE;
@@ -3724,18 +3724,18 @@ BOOL COMDelegate::ValidateEndInvoke(DelegateEEClass* pClass)
MODE_ANY;
PRECONDITION(CheckPointer(pClass));
- PRECONDITION(CheckPointer(pClass->m_pEndInvokeMethod));
+ PRECONDITION(CheckPointer(pClass->GetEndInvokeMethod()));
// insert fault. Can the binder throw an OOM?
}
CONTRACTL_END;
- if (pClass->m_pInvokeMethod == NULL)
+ if (pClass->GetInvokeMethod() == NULL)
return FALSE;
// We check the signatures under the typical instantiation of the possibly generic class
- MetaSig endInvokeSig(pClass->m_pEndInvokeMethod->LoadTypicalMethodDefinition());
- MetaSig invokeSig(pClass->m_pInvokeMethod->LoadTypicalMethodDefinition());
+ MetaSig endInvokeSig(pClass->GetEndInvokeMethod()->LoadTypicalMethodDefinition());
+ MetaSig invokeSig(pClass->GetInvokeMethod()->LoadTypicalMethodDefinition());
if (endInvokeSig.GetCallingConventionInfo() != (IMAGE_CEE_CS_CALLCONV_HASTHIS | IMAGE_CEE_CS_CALLCONV_DEFAULT))
return FALSE;
diff --git a/src/vm/comsynchronizable.cpp b/src/vm/comsynchronizable.cpp
index 08b5281a42..01ba49651b 100644
--- a/src/vm/comsynchronizable.cpp
+++ b/src/vm/comsynchronizable.cpp
@@ -235,7 +235,7 @@ void ThreadNative::KickOffThread_Worker(LPVOID ptr)
delete args->share;
args->share = 0;
- MethodDesc *pMeth = ((DelegateEEClass*)( gc.orDelegate->GetMethodTable()->GetClass() ))->m_pInvokeMethod;
+ MethodDesc *pMeth = ((DelegateEEClass*)( gc.orDelegate->GetMethodTable()->GetClass() ))->GetInvokeMethod();
_ASSERTE(pMeth);
MethodDescCallSite invokeMethod(pMeth, &gc.orDelegate);
diff --git a/src/vm/instmethhash.cpp b/src/vm/instmethhash.cpp
index 250a6d5247..560e9554be 100644
--- a/src/vm/instmethhash.cpp
+++ b/src/vm/instmethhash.cpp
@@ -86,8 +86,8 @@ PTR_LoaderAllocator InstMethodHashTable::GetLoaderAllocator()
}
else
{
- _ASSERTE(m_pModule != NULL);
- return m_pModule->GetLoaderAllocator();
+ _ASSERTE(!m_pModule.IsNull());
+ return GetModule()->GetLoaderAllocator();
}
}
@@ -188,7 +188,7 @@ MethodDesc* InstMethodHashTable::FindMethodDesc(TypeHandle declaringType,
RelativeFixupPointer<PTR_MethodTable> * ppMT = pMD->GetMethodTablePtr();
TADDR pMT = ppMT->GetValueMaybeTagged((TADDR)ppMT);
- if (!ZapSig::CompareTaggedPointerToTypeHandle(m_pModule, pMT, declaringType))
+ if (!ZapSig::CompareTaggedPointerToTypeHandle(GetModule(), pMT, declaringType))
{
continue; // Next iteration of the for loop
}
@@ -208,7 +208,7 @@ MethodDesc* InstMethodHashTable::FindMethodDesc(TypeHandle declaringType,
// asserts on encoded fixups.
TADDR candidateArg = ((FixupPointer<TADDR> *)candidateInst.GetRawArgs())[i].GetValue();
- if (!ZapSig::CompareTaggedPointerToTypeHandle(m_pModule, candidateArg, inst[i]))
+ if (!ZapSig::CompareTaggedPointerToTypeHandle(GetModule(), candidateArg, inst[i]))
{
match = false;
break;
diff --git a/src/vm/jitinterface.cpp b/src/vm/jitinterface.cpp
index 23f8b7f836..8a41c89aa8 100644
--- a/src/vm/jitinterface.cpp
+++ b/src/vm/jitinterface.cpp
@@ -5230,7 +5230,7 @@ void CEEInfo::getCallInfo(
// 2) Delegate.Invoke() - since a Delegate is a sealed class as per ECMA spec
// 3) JIT intrinsics - since they have pre-defined behavior
devirt = pTargetMD->GetMethodTable()->IsValueType() ||
- (pTargetMD->GetMethodTable()->IsDelegate() && ((DelegateEEClass*)(pTargetMD->GetMethodTable()->GetClass()))->m_pInvokeMethod == pMD) ||
+ (pTargetMD->GetMethodTable()->IsDelegate() && ((DelegateEEClass*)(pTargetMD->GetMethodTable()->GetClass()))->GetInvokeMethod() == pMD) ||
(pTargetMD->IsFCall() && ECall::GetIntrinsicID(pTargetMD) != CORINFO_INTRINSIC_Illegal);
callVirtCrossingVersionBubble = true;
@@ -6567,7 +6567,7 @@ DWORD CEEInfo::getMethodAttribsInternal (CORINFO_METHOD_HANDLE ftn)
result |= CORINFO_FLG_FORCEINLINE;
}
- if (pMT->IsDelegate() && ((DelegateEEClass*)(pMT->GetClass()))->m_pInvokeMethod == pMD)
+ if (pMT->IsDelegate() && ((DelegateEEClass*)(pMT->GetClass()))->GetInvokeMethod() == pMD)
{
// This is now used to emit efficient invoke code for any delegate invoke,
// including multicast.
diff --git a/src/vm/methodtablebuilder.cpp b/src/vm/methodtablebuilder.cpp
index 1b3d775e59..f5a256a14f 100644
--- a/src/vm/methodtablebuilder.cpp
+++ b/src/vm/methodtablebuilder.cpp
@@ -5948,18 +5948,18 @@ MethodTableBuilder::InitMethodDesc(
if (strcmp(pMethodName, "Invoke") == 0)
{
- BAD_FORMAT_NOTHROW_ASSERT(NULL == ((DelegateEEClass*)GetHalfBakedClass())->m_pInvokeMethod);
- ((DelegateEEClass*)GetHalfBakedClass())->m_pInvokeMethod = pNewMD;
+ BAD_FORMAT_NOTHROW_ASSERT(((DelegateEEClass*)GetHalfBakedClass())->m_pInvokeMethod.IsNull());
+ ((DelegateEEClass*)GetHalfBakedClass())->m_pInvokeMethod.SetValue(pNewMD);
}
else if (strcmp(pMethodName, "BeginInvoke") == 0)
{
- BAD_FORMAT_NOTHROW_ASSERT(NULL == ((DelegateEEClass*)GetHalfBakedClass())->m_pBeginInvokeMethod);
- ((DelegateEEClass*)GetHalfBakedClass())->m_pBeginInvokeMethod = pNewMD;
+ BAD_FORMAT_NOTHROW_ASSERT(((DelegateEEClass*)GetHalfBakedClass())->m_pBeginInvokeMethod.IsNull());
+ ((DelegateEEClass*)GetHalfBakedClass())->m_pBeginInvokeMethod.SetValue(pNewMD);
}
else if (strcmp(pMethodName, "EndInvoke") == 0)
{
- BAD_FORMAT_NOTHROW_ASSERT(NULL == ((DelegateEEClass*)GetHalfBakedClass())->m_pEndInvokeMethod);
- ((DelegateEEClass*)GetHalfBakedClass())->m_pEndInvokeMethod = pNewMD;
+ BAD_FORMAT_NOTHROW_ASSERT(((DelegateEEClass*)GetHalfBakedClass())->m_pEndInvokeMethod.IsNull());
+ ((DelegateEEClass*)GetHalfBakedClass())->m_pEndInvokeMethod.SetValue(pNewMD);
}
else
{
@@ -10124,7 +10124,7 @@ MethodTableBuilder::SetupMethodTable2(
GetMemTracker());
pMT->SetClass(pClass);
- pClass->m_pMethodTable = pMT;
+ pClass->m_pMethodTable.SetValue(pMT);
m_pHalfBakedMT = pMT;
#ifdef _DEBUG
diff --git a/src/vm/ngenhash.h b/src/vm/ngenhash.h
index 667a55e8f1..c59eb8e627 100644
--- a/src/vm/ngenhash.h
+++ b/src/vm/ngenhash.h
@@ -203,7 +203,7 @@ protected:
private:
friend class NgenHashTable<NGEN_HASH_ARGS>;
- NgenHashTable<NGEN_HASH_ARGS> *m_pTable; // Pointer back to the table being enumerated.
+ DPTR(NgenHashTable<NGEN_HASH_ARGS>) m_pTable; // Pointer back to the table being enumerated.
TADDR m_pEntry; // The entry the caller is currently looking at (or
// NULL to begin with). This is a VolatileEntry* or
// PersistedEntry* (depending on m_eType below) and
@@ -303,8 +303,13 @@ protected:
void BaseEnumMemoryRegions(CLRDataEnumMemoryFlags flags);
#endif // DACCESS_COMPILE
+ PTR_Module GetModule()
+ {
+ return ReadPointerMaybeNull(this, &NgenHashTable<NGEN_HASH_ARGS>::m_pModule);
+ }
+
// Owning module set at hash creation time (possibly NULL if this hash instance is not to be ngen'd).
- PTR_Module m_pModule;
+ RelativePointer<PTR_Module> m_pModule;
private:
// Internal implementation details. Nothing of interest to sub-classers for here on.
@@ -385,13 +390,13 @@ private:
// because this logic is replicated for Hot and Cold entries so we can factor some common code.
struct PersistedEntries
{
- APTR_PersistedEntry m_pEntries; // Pointer to a contiguous block of PersistedEntry structures
- // (NULL if zero entries)
- PTR_PersistedBucketList m_pBuckets; // Pointer to abstracted bucket list mapping above entries
- // into a hash (NULL if zero buckets, which is iff zero
- // entries)
- DWORD m_cEntries; // Count of entries in the above block
- DWORD m_cBuckets; // Count of buckets in the above bucket list
+ RelativePointer<APTR_PersistedEntry> m_pEntries; // Pointer to a contiguous block of PersistedEntry structures
+ // (NULL if zero entries)
+ RelativePointer<PTR_PersistedBucketList> m_pBuckets; // Pointer to abstracted bucket list mapping above entries
+ // into a hash (NULL if zero buckets, which is iff zero
+ // entries)
+ DWORD m_cEntries; // Count of entries in the above block
+ DWORD m_cBuckets; // Count of buckets in the above bucket list
};
#endif // FEATURE_PREJIT
@@ -439,13 +444,98 @@ private:
DWORD NextLargestPrime(DWORD dwNumber);
#endif // !DACCESS_COMPILE
+ DPTR(PTR_VolatileEntry) GetWarmBuckets()
+ {
+ SUPPORTS_DAC;
+
+ return ReadPointer(this, &NgenHashTable<NGEN_HASH_ARGS>::m_pWarmBuckets);
+ }
+
+#ifdef FEATURE_PREJIT
+ APTR_PersistedEntry GetPersistedHotEntries()
+ {
+ SUPPORTS_DAC;
+
+ return ReadPointerMaybeNull(this,
+ &NgenHashTable<NGEN_HASH_ARGS>::m_sHotEntries,
+ &decltype(NgenHashTable<NGEN_HASH_ARGS>::m_sHotEntries)::m_pEntries);
+ }
+
+ PTR_PersistedBucketList GetPersistedHotBuckets()
+ {
+ SUPPORTS_DAC;
+
+ return ReadPointerMaybeNull(this,
+ &NgenHashTable<NGEN_HASH_ARGS>::m_sHotEntries,
+ &decltype(NgenHashTable<NGEN_HASH_ARGS>::m_sHotEntries)::m_pBuckets);
+ }
+
+ APTR_PersistedEntry GetPersistedColdEntries()
+ {
+ SUPPORTS_DAC;
+
+ return ReadPointerMaybeNull(this,
+ &NgenHashTable<NGEN_HASH_ARGS>::m_sColdEntries,
+ &decltype(NgenHashTable<NGEN_HASH_ARGS>::m_sColdEntries)::m_pEntries);
+ }
+
+ PTR_PersistedBucketList GetPersistedColdBuckets()
+ {
+ SUPPORTS_DAC;
+
+ return ReadPointerMaybeNull(this,
+ &NgenHashTable<NGEN_HASH_ARGS>::m_sColdEntries,
+ &decltype(NgenHashTable<NGEN_HASH_ARGS>::m_sColdEntries)::m_pBuckets);
+ }
+
+#ifdef DACCESS_COMPILE
+ APTR_PersistedEntry GetPersistedEntries(DPTR(PersistedEntries) pEntries)
+ {
+ SUPPORTS_DAC;
+
+ TADDR hotEntriesAddr = dac_cast<TADDR>(this) + offsetof(NgenHashTable<NGEN_HASH_ARGS>, m_sHotEntries);
+ TADDR coldEntriesAddr = dac_cast<TADDR>(this) + offsetof(NgenHashTable<NGEN_HASH_ARGS>, m_sColdEntries);
+
+ if (hotEntriesAddr == dac_cast<TADDR>(pEntries))
+ {
+ return GetPersistedHotEntries();
+ }
+ else
+ {
+ _ASSERTE(hotEntriesAddr == dac_cast<TADDR>(pEntries));
+
+ return GetPersistedColdEntries();
+ }
+ }
+
+ PTR_PersistedBucketList GetPersistedBuckets(DPTR(PersistedEntries) pEntries)
+ {
+ SUPPORTS_DAC;
+
+ TADDR hotEntriesAddr = dac_cast<TADDR>(this) + offsetof(NgenHashTable<NGEN_HASH_ARGS>, m_sHotEntries);
+ TADDR coldEntriesAddr = dac_cast<TADDR>(this) + offsetof(NgenHashTable<NGEN_HASH_ARGS>, m_sColdEntries);
+
+ if (hotEntriesAddr == dac_cast<TADDR>(pEntries))
+ {
+ return GetPersistedHotBuckets();
+ }
+ else
+ {
+ _ASSERTE(hotEntriesAddr == dac_cast<TADDR>(pEntries));
+
+ return GetPersistedColdBuckets();
+ }
+ }
+#endif // DACCESS_COMPILE
+#endif // FEATURE_PREJIT
+
// Loader heap provided at construction time. May be NULL (in which case m_pModule must *not* be NULL).
LoaderHeap *m_pHeap;
// Fields related to the runtime (volatile or warm) part of the hash.
- DPTR(PTR_VolatileEntry) m_pWarmBuckets; // Pointer to a simple bucket list (array of VolatileEntry pointers)
- DWORD m_cWarmBuckets; // Count of buckets in the above array (always non-zero)
- DWORD m_cWarmEntries; // Count of elements in the warm section of the hash
+ RelativePointer<DPTR(PTR_VolatileEntry)> m_pWarmBuckets; // Pointer to a simple bucket list (array of VolatileEntry pointers)
+ DWORD m_cWarmBuckets; // Count of buckets in the above array (always non-zero)
+ DWORD m_cWarmEntries; // Count of elements in the warm section of the hash
#ifdef FEATURE_PREJIT
PersistedEntries m_sHotEntries; // Hot persisted hash entries (if any)
diff --git a/src/vm/ngenhash.inl b/src/vm/ngenhash.inl
index 070b1daeb5..6e5534578e 100644
--- a/src/vm/ngenhash.inl
+++ b/src/vm/ngenhash.inl
@@ -48,14 +48,14 @@ NgenHashTable<NGEN_HASH_ARGS>::NgenHashTable(Module *pModule, LoaderHeap *pHeap,
// At least one of module or heap must have been specified or we won't know how to allocate entries and
// buckets.
_ASSERTE(pModule || pHeap);
- m_pModule = pModule;
+ m_pModule.SetValueMaybeNull(pModule);
m_pHeap = pHeap;
S_SIZE_T cbBuckets = S_SIZE_T(sizeof(VolatileEntry*)) * S_SIZE_T(cInitialBuckets);
m_cWarmEntries = 0;
m_cWarmBuckets = cInitialBuckets;
- m_pWarmBuckets = (PTR_VolatileEntry*)(void*)GetHeap()->AllocMem(cbBuckets);
+ m_pWarmBuckets.SetValue((PTR_VolatileEntry*)(void*)GetHeap()->AllocMem(cbBuckets));
// Note: Memory allocated on loader heap is zero filled
// memset(m_pWarmBuckets, 0, sizeof(VolatileEntry*) * cInitialBuckets);
@@ -83,7 +83,7 @@ VALUE *NgenHashTable<NGEN_HASH_ARGS>::BaseAllocateEntry(AllocMemTracker *pamTrac
// Faults are forbidden in BaseInsertEntry. Make the table writeable now that the faults are still allowed.
EnsureWritablePages(this);
- EnsureWritablePages(this->m_pWarmBuckets, m_cWarmBuckets * sizeof(PTR_VolatileEntry));
+ EnsureWritablePages(this->GetWarmBuckets(), m_cWarmBuckets * sizeof(PTR_VolatileEntry));
TaggedMemAllocPtr pMemory = GetHeap()->AllocMem(S_SIZE_T(sizeof(VolatileEntry)));
@@ -119,8 +119,8 @@ LoaderHeap *NgenHashTable<NGEN_HASH_ARGS>::GetHeap()
// If not specified then we fall back to the owning module's heap (a module must have been specified in
// this case).
- _ASSERTE(m_pModule != NULL);
- return m_pModule->GetAssembly()->GetLowFrequencyHeap();
+ _ASSERTE(!m_pModule.IsNull());
+ return GetModule()->GetAssembly()->GetLowFrequencyHeap();
}
// Insert an entry previously allocated via BaseAllocateEntry (you cannot allocated entries in any other
@@ -154,13 +154,13 @@ void NgenHashTable<NGEN_HASH_ARGS>::BaseInsertEntry(NgenHashValue iHash, VALUE *
DWORD dwBucket = iHash % m_cWarmBuckets;
// Prepare to link the new entry at the head of the bucket chain.
- pVolatileEntry->m_pNextEntry = m_pWarmBuckets[dwBucket];
+ pVolatileEntry->m_pNextEntry = (GetWarmBuckets())[dwBucket];
// Make sure that all writes to the entry are visible before publishing the entry.
MemoryBarrier();
// Publish the entry by pointing the bucket at it.
- m_pWarmBuckets[dwBucket] = pVolatileEntry;
+ (GetWarmBuckets())[dwBucket] = pVolatileEntry;
m_cWarmEntries++;
@@ -205,7 +205,7 @@ void NgenHashTable<NGEN_HASH_ARGS>::GrowTable()
// again.
for (DWORD i = 0; i < m_cWarmBuckets; i++)
{
- PTR_VolatileEntry pEntry = m_pWarmBuckets[i];
+ PTR_VolatileEntry pEntry = (GetWarmBuckets())[i];
// Try to lock out readers from scanning this bucket. This is obviously a race which may fail.
// However, note that it's OK if somebody is already in the list - it's OK if we mess with the bucket
@@ -213,7 +213,7 @@ void NgenHashTable<NGEN_HASH_ARGS>::GrowTable()
// comparison even if it wanders aimlessly amongst entries while we are rearranging things. If a
// lookup finds a match under those circumstances, great. If not, they will have to acquire the lock &
// try again anyway.
- m_pWarmBuckets[i] = NULL;
+ (GetWarmBuckets())[i] = NULL;
while (pEntry != NULL)
{
@@ -229,7 +229,7 @@ void NgenHashTable<NGEN_HASH_ARGS>::GrowTable()
// Make sure that all writes are visible before publishing the new array.
MemoryBarrier();
- m_pWarmBuckets = pNewBuckets;
+ m_pWarmBuckets.SetValue(pNewBuckets);
// The new number of buckets has to be published last (prior to this readers may miscalculate a bucket
// index, but the result will always be in range and they'll simply walk the wrong chain and get a miss,
@@ -697,7 +697,7 @@ void NgenHashTable<NGEN_HASH_ARGS>::BaseSave(DataImage *pImage, CorProfileData *
// Persisted hashes had better have supplied an owning module at creation time (otherwise we won't know
// how to find a loader heap for further allocations at runtime: we don't know how to serialize a loader
// heap pointer).
- _ASSERTE(m_pModule != NULL);
+ _ASSERTE(!m_pModule.IsNull());
// We can only save once during ngen so the hot and cold sections of the hash cannot have been populated
// yet.
@@ -732,7 +732,7 @@ void NgenHashTable<NGEN_HASH_ARGS>::BaseSave(DataImage *pImage, CorProfileData *
for (i = 0; i < m_cWarmBuckets; i++)
{
// Iterate through the chain of warm entries for this bucket.
- VolatileEntry *pOldEntry = m_pWarmBuckets[i];
+ VolatileEntry *pOldEntry = (GetWarmBuckets())[i];
while (pOldEntry)
{
// Is the current entry being saved into the image?
@@ -842,18 +842,18 @@ void NgenHashTable<NGEN_HASH_ARGS>::BaseSave(DataImage *pImage, CorProfileData *
{
m_sHotEntries.m_cEntries = cHotEntries;
m_sHotEntries.m_cBuckets = cHotBuckets;
- m_sHotEntries.m_pEntries = new PersistedEntry[cHotEntries];
- m_sHotEntries.m_pBuckets = PersistedBucketList::CreateList(cHotBuckets, cHotEntries, cMaxHotChain);
- memset(m_sHotEntries.m_pEntries, 0, cHotEntries * sizeof(PersistedEntry)); // NGen determinism
+ m_sHotEntries.m_pEntries.SetValue(new PersistedEntry[cHotEntries]);
+ m_sHotEntries.m_pBuckets.SetValue(PersistedBucketList::CreateList(cHotBuckets, cHotEntries, cMaxHotChain));
+ memset(GetPersistedHotEntries(), 0, cHotEntries * sizeof(PersistedEntry)); // NGen determinism
}
if (cColdEntries)
{
m_sColdEntries.m_cEntries = cColdEntries;
m_sColdEntries.m_cBuckets = cColdBuckets;
- m_sColdEntries.m_pEntries = new PersistedEntry[cColdEntries];
- m_sColdEntries.m_pBuckets = PersistedBucketList::CreateList(cColdBuckets, cColdEntries, cMaxColdChain);
- memset(m_sColdEntries.m_pEntries, 0, cColdEntries * sizeof(PersistedEntry)); // NGen determinism
+ m_sColdEntries.m_pEntries.SetValue(new PersistedEntry[cColdEntries]);
+ m_sColdEntries.m_pBuckets.SetValue(PersistedBucketList::CreateList(cColdBuckets, cColdEntries, cMaxColdChain));
+ memset(GetPersistedColdEntries(), 0, cColdEntries * sizeof(PersistedEntry)); // NGen determinism
}
//
@@ -871,7 +871,7 @@ void NgenHashTable<NGEN_HASH_ARGS>::BaseSave(DataImage *pImage, CorProfileData *
DWORD dwNextId = 0; // This represents the index of the next entry to start a bucket chain
for (i = 0; i < cHotBuckets; i++)
{
- m_sHotEntries.m_pBuckets->SetBucket(i, dwNextId, pHotBucketSizes[i]);
+ m_sHotEntries.m_pBuckets.GetValue()->SetBucket(i, dwNextId, pHotBucketSizes[i]);
dwNextId += pHotBucketSizes[i];
}
_ASSERTE(dwNextId == m_sHotEntries.m_cEntries);
@@ -879,7 +879,7 @@ void NgenHashTable<NGEN_HASH_ARGS>::BaseSave(DataImage *pImage, CorProfileData *
dwNextId = 0; // Reset index for the cold entries (remember they have their own table of entries)
for (i = 0; i < cColdBuckets; i++)
{
- m_sColdEntries.m_pBuckets->SetBucket(i, dwNextId, pColdBucketSizes[i]);
+ m_sColdEntries.m_pBuckets.GetValue()->SetBucket(i, dwNextId, pColdBucketSizes[i]);
dwNextId += pColdBucketSizes[i];
}
_ASSERTE(dwNextId == m_sColdEntries.m_cEntries);
@@ -897,15 +897,16 @@ void NgenHashTable<NGEN_HASH_ARGS>::BaseSave(DataImage *pImage, CorProfileData *
typename EntryMappingTable::Entry *pMapEntry = &sEntryMap.m_pEntries[i];
// Entry block depends on whether this entry is hot or cold.
- PersistedEntries *pEntries = pMapEntry->m_fHot ? &m_sHotEntries : &m_sColdEntries;
+ APTR_PersistedEntry pPersistedEntries = pMapEntry->m_fHot ? GetPersistedHotEntries() : GetPersistedColdEntries();
+ PTR_PersistedBucketList pPersistedBucketsList = pMapEntry->m_fHot ? GetPersistedHotBuckets() : GetPersistedColdBuckets();
// We already know the new bucket this entry will go into. Retrieve the index of the first entry in
// that bucket chain.
- DWORD dwBaseChainIndex = pEntries->m_pBuckets->GetInitialEntry(pMapEntry->m_dwNewBucket);
+ DWORD dwBaseChainIndex = pPersistedBucketsList->GetInitialEntry(pMapEntry->m_dwNewBucket);
// This entry will be located at some offset from the index above (we calculated this ordinal in phase
// 2).
- PersistedEntry *pNewEntry = &pEntries->m_pEntries[dwBaseChainIndex + pMapEntry->m_dwChainOrdinal];
+ PersistedEntry *pNewEntry = &pPersistedEntries[dwBaseChainIndex + pMapEntry->m_dwChainOrdinal];
// Record the address of the embedded sub-class hash entry in the map entry (sub-classes will use this
// info to map old entry addresses to their new locations).
@@ -931,7 +932,11 @@ void NgenHashTable<NGEN_HASH_ARGS>::BaseSave(DataImage *pImage, CorProfileData *
bool fAllEntriesImmutable = true;
for (i = 0; i < sEntryMap.m_cEntries; i++)
- if (!DOWNCALL(SaveEntry)(pImage, pProfileData, sEntryMap.m_pEntries[i].m_pOldEntry, sEntryMap.m_pEntries[i].m_pNewEntry, &sEntryMap))
+ if (!DOWNCALL(SaveEntry)(pImage,
+ pProfileData,
+ sEntryMap.m_pEntries[i].m_pOldEntry,
+ sEntryMap.m_pEntries[i].m_pNewEntry,
+ &sEntryMap))
fAllEntriesImmutable = false;
// We're mostly done. Now just some cleanup and the actual DataImage storage operations.
@@ -943,24 +948,24 @@ void NgenHashTable<NGEN_HASH_ARGS>::BaseSave(DataImage *pImage, CorProfileData *
// If there are any hot entries store the entry array and bucket list.
if (cHotEntries)
{
- pImage->StoreStructure(m_sHotEntries.m_pEntries,
+ pImage->StoreStructure(GetPersistedHotEntries(),
static_cast<ULONG>(sizeof(PersistedEntry) * cHotEntries),
fAllEntriesImmutable ? DataImage::ITEM_NGEN_HASH_ENTRIES_RO_HOT : DataImage::ITEM_NGEN_HASH_ENTRIES_HOT);
- pImage->StoreStructure(m_sHotEntries.m_pBuckets,
- static_cast<ULONG>(m_sHotEntries.m_pBuckets->GetSize(m_sHotEntries.m_cBuckets)),
+ pImage->StoreStructure(GetPersistedHotBuckets(),
+ static_cast<ULONG>(m_sHotEntries.m_pBuckets.GetValue()->GetSize(m_sHotEntries.m_cBuckets)),
DataImage::ITEM_NGEN_HASH_BUCKETLIST_HOT);
}
// If there are any cold entries store the entry array and bucket list.
if (cColdEntries)
{
- pImage->StoreStructure(m_sColdEntries.m_pEntries,
+ pImage->StoreStructure(GetPersistedColdEntries(),
static_cast<ULONG>(sizeof(PersistedEntry) * cColdEntries),
fAllEntriesImmutable ? DataImage::ITEM_NGEN_HASH_ENTRIES_RO_COLD : DataImage::ITEM_NGEN_HASH_ENTRIES_COLD);
- pImage->StoreStructure(m_sColdEntries.m_pBuckets,
- static_cast<ULONG>(m_sColdEntries.m_pBuckets->GetSize(m_sColdEntries.m_cBuckets)),
+ pImage->StoreStructure(GetPersistedColdBuckets(),
+ static_cast<ULONG>(GetPersistedColdBuckets()->GetSize(m_sColdEntries.m_cBuckets)),
DataImage::ITEM_NGEN_HASH_BUCKETLIST_COLD);
}
@@ -987,7 +992,7 @@ void NgenHashTable<NGEN_HASH_ARGS>::BaseSave(DataImage *pImage, CorProfileData *
DWORD cNewWarmBuckets = min(m_cInitialBuckets, 11);
// Create the ngen version of the warm buckets.
- pImage->StoreStructure(m_pWarmBuckets,
+ pImage->StoreStructure(GetWarmBuckets(),
cNewWarmBuckets * sizeof(VolatileEntry*),
DataImage::ITEM_NGEN_HASH_HOT);
@@ -997,7 +1002,7 @@ void NgenHashTable<NGEN_HASH_ARGS>::BaseSave(DataImage *pImage, CorProfileData *
pNewTable->m_cWarmBuckets = cNewWarmBuckets;
// Zero-out the ngen version of the warm buckets.
- VolatileEntry *pNewBuckets = (VolatileEntry*)pImage->GetImagePointer(m_pWarmBuckets);
+ VolatileEntry *pNewBuckets = (VolatileEntry*)pImage->GetImagePointer(GetWarmBuckets());
memset(pNewBuckets, 0, cNewWarmBuckets * sizeof(VolatileEntry*));
}
@@ -1011,7 +1016,7 @@ void NgenHashTable<NGEN_HASH_ARGS>::BaseFixup(DataImage *pImage)
DWORD i;
// Fixup the module pointer.
- pImage->FixupPointerField(this, offsetof(NgenHashTable<NGEN_HASH_ARGS>, m_pModule));
+ pImage->FixupRelativePointerField(this, offsetof(NgenHashTable<NGEN_HASH_ARGS>, m_pModule));
// Throw away the heap pointer, we can't serialize it into the image. We'll rely on the loader heap
// associated with the module above at runtime.
@@ -1023,29 +1028,27 @@ void NgenHashTable<NGEN_HASH_ARGS>::BaseFixup(DataImage *pImage)
// be relative to the base of this array.
for (i = 0; i < m_sHotEntries.m_cEntries; i++)
- DOWNCALL(FixupEntry)(pImage, &m_sHotEntries.m_pEntries[i].m_sValue, m_sHotEntries.m_pEntries, i * sizeof(PersistedEntry));
+ DOWNCALL(FixupEntry)(pImage,
+ &(GetPersistedHotEntries())[i].m_sValue,
+ GetPersistedHotEntries(),
+ i * sizeof(PersistedEntry));
for (i = 0; i < m_sColdEntries.m_cEntries; i++)
- DOWNCALL(FixupEntry)(pImage, &m_sColdEntries.m_pEntries[i].m_sValue, m_sColdEntries.m_pEntries, i * sizeof(PersistedEntry));
+ DOWNCALL(FixupEntry)(pImage,
+ &(GetPersistedColdEntries())[i].m_sValue,
+ GetPersistedColdEntries(),
+ i * sizeof(PersistedEntry));
// Fixup the warm (empty) bucket list.
- pImage->FixupPointerField(this, offsetof(NgenHashTable<NGEN_HASH_ARGS>, m_pWarmBuckets));
+ pImage->FixupRelativePointerField(this, offsetof(NgenHashTable<NGEN_HASH_ARGS>, m_pWarmBuckets));
// Fixup the hot entry array and bucket list.
- pImage->FixupPointerField(this,
- offsetof(NgenHashTable<NGEN_HASH_ARGS>, m_sHotEntries) +
- offsetof(PersistedEntries, m_pEntries));
- pImage->FixupPointerField(this,
- offsetof(NgenHashTable<NGEN_HASH_ARGS>, m_sHotEntries) +
- offsetof(PersistedEntries, m_pBuckets));
+ pImage->FixupRelativePointerField(this, offsetof(NgenHashTable<NGEN_HASH_ARGS>, m_sHotEntries) + offsetof(PersistedEntries, m_pEntries));
+ pImage->FixupRelativePointerField(this, offsetof(NgenHashTable<NGEN_HASH_ARGS>, m_sHotEntries) + offsetof(PersistedEntries, m_pBuckets));
// Fixup the cold entry array and bucket list.
- pImage->FixupPointerField(this,
- offsetof(NgenHashTable<NGEN_HASH_ARGS>, m_sColdEntries) +
- offsetof(PersistedEntries, m_pEntries));
- pImage->FixupPointerField(this,
- offsetof(NgenHashTable<NGEN_HASH_ARGS>, m_sColdEntries) +
- offsetof(PersistedEntries, m_pBuckets));
+ pImage->FixupRelativePointerField(this, offsetof(NgenHashTable<NGEN_HASH_ARGS>, m_sColdEntries) + offsetof(PersistedEntries, m_pEntries));
+ pImage->FixupRelativePointerField(this, offsetof(NgenHashTable<NGEN_HASH_ARGS>, m_sColdEntries) + offsetof(PersistedEntries, m_pBuckets));
}
#endif // !DACCESS_COMPILE
#endif // FEATURE_PREJIT
@@ -1064,14 +1067,14 @@ void NgenHashTable<NGEN_HASH_ARGS>::BaseEnumMemoryRegions(CLRDataEnumMemoryFlags
DacEnumMemoryRegion(dac_cast<TADDR>(this), sizeof(FINAL_CLASS));
// Save the warm bucket list.
- DacEnumMemoryRegion(dac_cast<TADDR>(m_pWarmBuckets), m_cWarmBuckets * sizeof(VolatileEntry*));
+ DacEnumMemoryRegion(dac_cast<TADDR>(GetWarmBuckets()), m_cWarmBuckets * sizeof(VolatileEntry*));
// Save all the warm entries.
- if (m_pWarmBuckets.IsValid())
+ if (GetWarmBuckets().IsValid())
{
for (DWORD i = 0; i < m_cWarmBuckets; i++)
{
- PTR_VolatileEntry pEntry = m_pWarmBuckets[i];
+ PTR_VolatileEntry pEntry = (GetWarmBuckets())[i];
while (pEntry.IsValid())
{
pEntry.EnumMem();
@@ -1088,25 +1091,35 @@ void NgenHashTable<NGEN_HASH_ARGS>::BaseEnumMemoryRegions(CLRDataEnumMemoryFlags
// Save hot buckets and entries.
if (m_sHotEntries.m_cEntries > 0)
{
- DacEnumMemoryRegion(dac_cast<TADDR>(m_sHotEntries.m_pEntries), m_sHotEntries.m_cEntries * sizeof(PersistedEntry));
- DacEnumMemoryRegion(dac_cast<TADDR>(m_sHotEntries.m_pBuckets), m_sHotEntries.m_pBuckets->GetSize(m_sHotEntries.m_cBuckets));
+ DacEnumMemoryRegion(dac_cast<TADDR>(GetPersistedHotEntries()),
+ m_sHotEntries.m_cEntries * sizeof(PersistedEntry));
+ DacEnumMemoryRegion(dac_cast<TADDR>(GetPersistedHotBuckets()),
+ GetPersistedHotBuckets()->GetSize(m_sHotEntries.m_cBuckets));
for (DWORD i = 0; i < m_sHotEntries.m_cEntries; i++)
- DOWNCALL(EnumMemoryRegionsForEntry)(VALUE_FROM_PERSISTED_ENTRY(dac_cast<PTR_PersistedEntry>(&m_sHotEntries.m_pEntries[i])), flags);
+ {
+ PTR_PersistedEntry pEntry = dac_cast<PTR_PersistedEntry>(&(GetPersistedHotEntries())[i]);
+ DOWNCALL(EnumMemoryRegionsForEntry)(VALUE_FROM_PERSISTED_ENTRY(pEntry), flags);
+ }
}
// Save cold buckets and entries.
if (m_sColdEntries.m_cEntries > 0)
{
- DacEnumMemoryRegion(dac_cast<TADDR>(m_sColdEntries.m_pEntries), m_sColdEntries.m_cEntries * sizeof(PersistedEntry));
- DacEnumMemoryRegion(dac_cast<TADDR>(m_sColdEntries.m_pBuckets), m_sColdEntries.m_pBuckets->GetSize(m_sColdEntries.m_cBuckets));
+ DacEnumMemoryRegion(dac_cast<TADDR>(GetPersistedColdEntries()),
+ m_sColdEntries.m_cEntries * sizeof(PersistedEntry));
+ DacEnumMemoryRegion(dac_cast<TADDR>(GetPersistedColdBuckets()),
+ GetPersistedColdBuckets()->GetSize(m_sColdEntries.m_cBuckets));
for (DWORD i = 0; i < m_sColdEntries.m_cEntries; i++)
- DOWNCALL(EnumMemoryRegionsForEntry)(VALUE_FROM_PERSISTED_ENTRY(dac_cast<PTR_PersistedEntry>(&m_sColdEntries.m_pEntries[i])), flags);
+ {
+ PTR_PersistedEntry pEntry = dac_cast<PTR_PersistedEntry>(&(GetPersistedColdEntries())[i]);
+ DOWNCALL(EnumMemoryRegionsForEntry)(VALUE_FROM_PERSISTED_ENTRY(pEntry), flags);
+ }
}
#endif // FEATURE_PREJIT
// Save the module if present.
- if (m_pModule.IsValid())
- m_pModule->EnumMemoryRegions(flags, true);
+ if (GetModule().IsValid())
+ GetModule()->EnumMemoryRegions(flags, true);
}
#endif // DACCESS_COMPILE
@@ -1136,13 +1149,31 @@ DPTR(VALUE) NgenHashTable<NGEN_HASH_ARGS>::FindPersistedEntryByHash(PersistedEnt
// Since there is at least one entry there must be at least one bucket.
_ASSERTE(pEntries->m_cBuckets > 0);
+ DWORD eType = (pEntries == &m_sHotEntries ? Hot : Cold);
+
// Get the first entry and count of entries for the bucket which contains all entries with the given hash
// code.
DWORD dwEntryIndex, cEntriesLeft;
- pEntries->m_pBuckets->GetBucket(iHash % pEntries->m_cBuckets, &dwEntryIndex, &cEntriesLeft);
+ if (eType == Hot)
+ {
+ GetPersistedHotBuckets()->GetBucket(iHash % pEntries->m_cBuckets, &dwEntryIndex, &cEntriesLeft);
+ }
+ else
+ {
+ GetPersistedColdBuckets()->GetBucket(iHash % pEntries->m_cBuckets, &dwEntryIndex, &cEntriesLeft);
+ }
// Determine the address of the first entry in the chain by indexing into the entry array.
- PTR_PersistedEntry pEntry = dac_cast<PTR_PersistedEntry>(&pEntries->m_pEntries[dwEntryIndex]);
+ PTR_PersistedEntry pEntry;
+
+ if (eType == Hot)
+ {
+ pEntry = dac_cast<PTR_PersistedEntry>(&(GetPersistedHotEntries())[dwEntryIndex]);
+ }
+ else
+ {
+ pEntry = dac_cast<PTR_PersistedEntry>(&(GetPersistedColdEntries())[dwEntryIndex]);
+ }
// Iterate while we've still got entries left to check in this chain.
while (cEntriesLeft--)
@@ -1154,7 +1185,7 @@ DPTR(VALUE) NgenHashTable<NGEN_HASH_ARGS>::FindPersistedEntryByHash(PersistedEnt
// Record our current search state into the provided context so that a subsequent call to
// BaseFindNextEntryByHash can pick up the search where it left off.
pContext->m_pEntry = dac_cast<TADDR>(pEntry);
- pContext->m_eType = pEntries == &m_sHotEntries ? Hot : Cold;
+ pContext->m_eType = eType;
pContext->m_cRemainingEntries = cEntriesLeft;
// Return the address of the sub-classes' embedded entry structure.
@@ -1223,7 +1254,7 @@ DPTR(VALUE) NgenHashTable<NGEN_HASH_ARGS>::FindVolatileEntryByHash(NgenHashValue
_ASSERTE(m_cWarmBuckets > 0);
// Point at the first entry in the bucket chain which would contain any entries with the given hash code.
- PTR_VolatileEntry pEntry = m_pWarmBuckets[iHash % m_cWarmBuckets];
+ PTR_VolatileEntry pEntry = (GetWarmBuckets())[iHash % m_cWarmBuckets];
// Walk the bucket chain one entry at a time.
while (pEntry)
@@ -1257,7 +1288,7 @@ void NgenHashTable<NGEN_HASH_ARGS>::BaseInitIterator(BaseIterator *pIterator)
{
LIMITED_METHOD_DAC_CONTRACT;
- pIterator->m_pTable = this;
+ pIterator->m_pTable = dac_cast<DPTR(NgenHashTable<NGEN_HASH_ARGS>)>(this);
pIterator->m_pEntry = NULL;
#ifdef FEATURE_PREJIT
pIterator->m_eType = Hot;
@@ -1299,7 +1330,7 @@ DPTR(VALUE) NgenHashTable<NGEN_HASH_ARGS>::BaseIterator::Next()
if (m_pEntry == NULL)
{
// This is our first lookup in the hot section, return the first entry in the hot array.
- m_pEntry = dac_cast<TADDR>(m_pTable->m_sHotEntries.m_pEntries);
+ m_pEntry = dac_cast<TADDR>(m_pTable->GetPersistedHotEntries());
}
else
{
@@ -1329,7 +1360,7 @@ DPTR(VALUE) NgenHashTable<NGEN_HASH_ARGS>::BaseIterator::Next()
{
// This is our first lookup in the warm section for a particular bucket, return the first
// entry in that bucket.
- m_pEntry = dac_cast<TADDR>(m_pTable->m_pWarmBuckets[m_dwBucket]);
+ m_pEntry = dac_cast<TADDR>((m_pTable->GetWarmBuckets())[m_dwBucket]);
}
else
{
@@ -1370,7 +1401,7 @@ DPTR(VALUE) NgenHashTable<NGEN_HASH_ARGS>::BaseIterator::Next()
if (m_pEntry == NULL)
{
// This is our first lookup in the cold section, return the first entry in the cold array.
- m_pEntry = dac_cast<TADDR>(m_pTable->m_sColdEntries.m_pEntries);
+ m_pEntry = dac_cast<TADDR>(m_pTable->GetPersistedColdEntries());
}
else
{
@@ -1463,17 +1494,17 @@ void NgenHashEntryRef<NGEN_HASH_ARGS>::Fixup(DataImage *pImage, NgenHashTable<NG
BYTE *pLocationBase;
DWORD cbLocationOffset;
- if (pLocation >= (BYTE*)pTable->m_sHotEntries.m_pEntries &&
- pLocation < (BYTE*)(pTable->m_sHotEntries.m_pEntries + pTable->m_sHotEntries.m_cEntries))
+ if (pLocation >= (BYTE*)pTable->GetPersistedHotEntries() &&
+ pLocation < (BYTE*)(pTable->GetPersistedHotEntries() + pTable->m_sHotEntries.m_cEntries))
{
// The field is in a hot entry.
- pLocationBase = (BYTE*)pTable->m_sHotEntries.m_pEntries;
+ pLocationBase = (BYTE*)pTable->GetPersistedHotEntries();
}
- else if (pLocation >= (BYTE*)pTable->m_sColdEntries.m_pEntries &&
- pLocation < (BYTE*)(pTable->m_sColdEntries.m_pEntries + pTable->m_sColdEntries.m_cEntries))
+ else if (pLocation >= (BYTE*)pTable->GetPersistedColdEntries() &&
+ pLocation < (BYTE*)(pTable->GetPersistedColdEntries() + pTable->m_sColdEntries.m_cEntries))
{
// The field is in a cold entry.
- pLocationBase = (BYTE*)pTable->m_sColdEntries.m_pEntries;
+ pLocationBase = (BYTE*)pTable->GetPersistedColdEntries();
}
else
{
@@ -1490,17 +1521,17 @@ void NgenHashEntryRef<NGEN_HASH_ARGS>::Fixup(DataImage *pImage, NgenHashTable<NG
BYTE *pTargetBase;
DWORD cbTargetOffset;
- if (pTarget >= (BYTE*)pTable->m_sHotEntries.m_pEntries &&
- pTarget < (BYTE*)(pTable->m_sHotEntries.m_pEntries + pTable->m_sHotEntries.m_cEntries))
+ if (pTarget >= (BYTE*)pTable->GetPersistedHotEntries() &&
+ pTarget < (BYTE*)(pTable->GetPersistedHotEntries() + pTable->m_sHotEntries.m_cEntries))
{
// The target is a hot entry.
- pTargetBase = (BYTE*)pTable->m_sHotEntries.m_pEntries;
+ pTargetBase = (BYTE*)pTable->GetPersistedHotEntries();
}
- else if (pTarget >= (BYTE*)pTable->m_sColdEntries.m_pEntries &&
- pTarget < (BYTE*)(pTable->m_sColdEntries.m_pEntries + pTable->m_sColdEntries.m_cEntries))
+ else if (pTarget >= (BYTE*)pTable->GetPersistedColdEntries() &&
+ pTarget < (BYTE*)(pTable->GetPersistedColdEntries() + pTable->m_sColdEntries.m_cEntries))
{
// The target is a cold entry.
- pTargetBase = (BYTE*)pTable->m_sColdEntries.m_pEntries;
+ pTargetBase = (BYTE*)pTable->GetPersistedColdEntries();
}
else
{
diff --git a/src/vm/stubhelpers.cpp b/src/vm/stubhelpers.cpp
index a1f7abbb38..837d88f65a 100644
--- a/src/vm/stubhelpers.cpp
+++ b/src/vm/stubhelpers.cpp
@@ -96,7 +96,7 @@ MethodDesc *StubHelpers::ResolveInteropMethod(Object *pThisUNSAFE, MethodDesc *p
MethodTable *pMT = pThisUNSAFE->GetMethodTable();
_ASSERTE(pMT->IsDelegate());
- return ((DelegateEEClass *)pMT->GetClass())->m_pInvokeMethod;
+ return ((DelegateEEClass *)pMT->GetClass())->GetInvokeMethod();
}
return pMD;
}
@@ -1551,7 +1551,7 @@ FCIMPL3(SIZE_T, StubHelpers::ProfilerBeginTransitionCallback, SIZE_T pSecretPara
_ASSERTE(pMT->IsDelegate());
EEClass * pClass = pMT->GetClass();
- pRealMD = ((DelegateEEClass*)pClass)->m_pInvokeMethod;
+ pRealMD = ((DelegateEEClass*)pClass)->GetInvokeMethod();
_ASSERTE(pRealMD);
}
}
diff --git a/src/vm/typedesc.cpp b/src/vm/typedesc.cpp
index 06170cb2c1..67180684de 100644
--- a/src/vm/typedesc.cpp
+++ b/src/vm/typedesc.cpp
@@ -1373,7 +1373,7 @@ void TypeVarTypeDesc::Fixup(DataImage *image)
STANDARD_VM_CONTRACT;
LOG((LF_ZAP, LL_INFO10000, " TypeVarTypeDesc::Fixup %x (%p)\n", GetToken(), this));
- image->FixupPointerField(this, offsetof(TypeVarTypeDesc, m_pModule));
+ image->FixupRelativePointerField(this, offsetof(TypeVarTypeDesc, m_pModule));
image->ZeroField(this, offsetof(TypeVarTypeDesc, m_hExposedClassObject), sizeof(m_hExposedClassObject));
// We don't persist the constraints: instead, load them back on demand
@@ -1394,10 +1394,10 @@ MethodDesc * TypeVarTypeDesc::LoadOwnerMethod()
}
CONTRACTL_END;
- MethodDesc *pMD = m_pModule->LookupMethodDef(m_typeOrMethodDef);
+ MethodDesc *pMD = GetModule()->LookupMethodDef(m_typeOrMethodDef);
if (pMD == NULL)
{
- pMD = MemberLoader::GetMethodDescFromMethodDef(m_pModule, m_typeOrMethodDef, FALSE);
+ pMD = MemberLoader::GetMethodDescFromMethodDef(GetModule(), m_typeOrMethodDef, FALSE);
}
return pMD;
}
@@ -1414,10 +1414,10 @@ TypeHandle TypeVarTypeDesc::LoadOwnerType()
}
CONTRACTL_END;
- TypeHandle genericType = m_pModule->LookupTypeDef(m_typeOrMethodDef);
+ TypeHandle genericType = GetModule()->LookupTypeDef(m_typeOrMethodDef);
if (genericType.IsNull())
{
- genericType = ClassLoader::LoadTypeDefThrowing(m_pModule, m_typeOrMethodDef,
+ genericType = ClassLoader::LoadTypeDefThrowing(GetModule(), m_typeOrMethodDef,
ClassLoader::ThrowIfNotFound,
ClassLoader::PermitUninstDefOrRef);
}
@@ -1506,7 +1506,7 @@ void TypeVarTypeDesc::LoadConstraints(ClassLoadLevel level /* = CLASS_LOADED */)
numConstraints = pInternalImport->EnumGetCount(&hEnum);
if (numConstraints != 0)
{
- LoaderAllocator* pAllocator=m_pModule->GetLoaderAllocator();
+ LoaderAllocator* pAllocator = GetModule()->GetLoaderAllocator();
// If there is a single class constraint we put in in element 0 of the array
AllocMemHolder<TypeHandle> constraints
(pAllocator->GetLowFrequencyHeap()->AllocMem(S_SIZE_T(numConstraints) * S_SIZE_T(sizeof(TypeHandle))));
@@ -2434,9 +2434,11 @@ TypeVarTypeDesc::EnumMemoryRegions(CLRDataEnumMemoryFlags flags)
SUPPORTS_DAC;
DAC_ENUM_DTHIS();
- if (m_pModule.IsValid())
+ PTR_TypeVarTypeDesc ptrThis(this);
+
+ if (GetModule().IsValid())
{
- m_pModule->EnumMemoryRegions(flags, true);
+ GetModule()->EnumMemoryRegions(flags, true);
}
if (m_numConstraints != (DWORD)-1)
diff --git a/src/vm/typedesc.h b/src/vm/typedesc.h
index 4bc4978543..a8b1c2552e 100644
--- a/src/vm/typedesc.h
+++ b/src/vm/typedesc.h
@@ -462,7 +462,7 @@ public:
}
CONTRACTL_END;
- m_pModule = pModule;
+ m_pModule.SetValue(pModule);
m_typeOrMethodDef = typeOrMethodDef;
m_token = token;
m_index = index;
@@ -479,7 +479,8 @@ public:
{
LIMITED_METHOD_CONTRACT;
SUPPORTS_DAC;
- return m_pModule;
+
+ return ReadPointer(this, &TypeVarTypeDesc::m_pModule);
}
unsigned int GetIndex()
@@ -567,7 +568,7 @@ protected:
BOOL ConstrainedAsObjRefHelper();
// Module containing the generic definition, also the loader module for this type desc
- PTR_Module m_pModule;
+ RelativePointer<PTR_Module> m_pModule;
// Declaring type or method
mdToken m_typeOrMethodDef;
diff --git a/src/vm/typehash.cpp b/src/vm/typehash.cpp
index b3de777016..0d53a15a00 100644
--- a/src/vm/typehash.cpp
+++ b/src/vm/typehash.cpp
@@ -67,8 +67,8 @@ LoaderAllocator *EETypeHashTable::GetLoaderAllocator()
}
else
{
- _ASSERTE(m_pModule != NULL);
- return m_pModule->GetLoaderAllocator();
+ _ASSERTE(!m_pModule.IsNull());
+ return GetModule()->GetLoaderAllocator();
}
}
@@ -417,7 +417,7 @@ EETypeHashEntry_t *EETypeHashTable::FindItem(TypeKey* pKey)
if (CORCOMPILE_IS_POINTER_TAGGED(fixup))
{
Module *pDefiningModule;
- PCCOR_SIGNATURE pSig = m_pModule->GetEncodedSigIfLoaded(CORCOMPILE_UNTAG_TOKEN(fixup), &pDefiningModule);
+ PCCOR_SIGNATURE pSig = GetModule()->GetEncodedSigIfLoaded(CORCOMPILE_UNTAG_TOKEN(fixup), &pDefiningModule);
if (pDefiningModule == NULL)
break;
@@ -487,7 +487,8 @@ BOOL EETypeHashTable::CompareInstantiatedType(TypeHandle t, Module *pModule, mdT
if (CORCOMPILE_IS_POINTER_TAGGED(fixup))
{
Module *pDefiningModule;
- PCCOR_SIGNATURE pSig = m_pModule->GetEncodedSigIfLoaded(CORCOMPILE_UNTAG_TOKEN(fixup), &pDefiningModule);
+
+ PCCOR_SIGNATURE pSig = GetModule()->GetEncodedSigIfLoaded(CORCOMPILE_UNTAG_TOKEN(fixup), &pDefiningModule);
// First check that the modules for the generic type defs match
if (dac_cast<TADDR>(pDefiningModule) !=
@@ -536,7 +537,7 @@ BOOL EETypeHashTable::CompareInstantiatedType(TypeHandle t, Module *pModule, mdT
DACCOP_IGNORE(CastOfMarshalledType, "Dual mode DAC problem, but since the size is the same, the cast is safe");
TADDR candidateArg = ((FixupPointer<TADDR> *)candidateInst.GetRawArgs())[i].GetValue();
- if (!ZapSig::CompareTaggedPointerToTypeHandle(m_pModule, candidateArg, inst[i]))
+ if (!ZapSig::CompareTaggedPointerToTypeHandle(GetModule(), candidateArg, inst[i]))
{
return FALSE;
}
@@ -578,7 +579,7 @@ BOOL EETypeHashTable::CompareFnPtrType(TypeHandle t, BYTE callConv, DWORD numArg
for (DWORD i = 0; i <= numArgs; i++)
{
TADDR candidateArg = retAndArgTypes2[i].AsTAddr();
- if (!ZapSig::CompareTaggedPointerToTypeHandle(m_pModule, candidateArg, retAndArgTypes[i]))
+ if (!ZapSig::CompareTaggedPointerToTypeHandle(GetModule(), candidateArg, retAndArgTypes[i]))
{
return FALSE;
}
@@ -647,7 +648,7 @@ VOID EETypeHashTable::InsertValue(TypeHandle data)
PRECONDITION(!data.IsEncodedFixup());
PRECONDITION(!data.IsGenericTypeDefinition()); // Generic type defs live in typedef table (availableClasses)
PRECONDITION(data.HasInstantiation() || data.HasTypeParam() || data.IsFnPtrType()); // It's an instantiated type or an array/ptr/byref type
- PRECONDITION(!m_pModule || m_pModule->IsTenured()); // Destruct won't destruct m_pAvailableParamTypes for non-tenured modules - so make sure no one tries to insert one before the Module has been tenured
+ PRECONDITION(m_pModule.IsNull() || GetModule()->IsTenured()); // Destruct won't destruct m_pAvailableParamTypes for non-tenured modules - so make sure no one tries to insert one before the Module has been tenured
}
CONTRACTL_END
@@ -673,7 +674,7 @@ void EETypeHashTable::Save(DataImage *image, Module *module, CorProfileData *pro
CONTRACTL
{
STANDARD_VM_CHECK;
- PRECONDITION(image->GetModule() == m_pModule);
+ PRECONDITION(image->GetModule() == GetModule());
}
CONTRACTL_END;
@@ -715,7 +716,7 @@ void EETypeHashTable::Save(DataImage *image, Module *module, CorProfileData *pro
{
if (flags & (1<<ReadTypeHashTable))
{
- TypeHandle th = m_pModule->LoadIBCTypeHelper(pBlobSigEntry);
+ TypeHandle th = GetModule()->LoadIBCTypeHelper(pBlobSigEntry);
#if defined(_DEBUG) && !defined(DACCESS_COMPILE)
g_pConfig->DebugCheckAndForceIBCFailure(EEConfig::CallSite_8);
#endif
@@ -798,14 +799,14 @@ void EETypeHashTable::FixupEntry(DataImage *pImage, EETypeHashEntry_t *pEntry, v
if (pType.IsTypeDesc())
{
pImage->FixupField(pFixupBase, cbFixupOffset + offsetof(EETypeHashEntry_t, m_data),
- pType.AsTypeDesc(), 2);
+ pType.AsTypeDesc(), 2, IMAGE_REL_BASED_RelativePointer);
pType.AsTypeDesc()->Fixup(pImage);
}
else
{
pImage->FixupField(pFixupBase, cbFixupOffset + offsetof(EETypeHashEntry_t, m_data),
- pType.AsMethodTable());
+ pType.AsMethodTable(), 0, IMAGE_REL_BASED_RelativePointer);
pType.AsMethodTable()->Fixup(pImage);
}
@@ -838,17 +839,20 @@ TypeHandle EETypeHashEntry::GetTypeHandle()
LIMITED_METHOD_DAC_CONTRACT;
// Remove any hot entry indicator bit that may have been set as the result of Ngen saving.
- return TypeHandle::FromTAddr(m_data & ~0x1);
+ TADDR data = dac_cast<TADDR>(GetData());
+ return TypeHandle::FromTAddr(data & ~0x1);
}
+#ifndef DACCESS_COMPILE
void EETypeHashEntry::SetTypeHandle(TypeHandle handle)
{
LIMITED_METHOD_DAC_CONTRACT;
// We plan to steal the low-order bit of the handle for ngen purposes.
_ASSERTE((handle.AsTAddr() & 0x1) == 0);
- m_data = handle.AsTAddr();
+ m_data.SetValueMaybeNull(handle.AsPtr());
}
+#endif // !DACCESS_COMPILE
#ifdef FEATURE_PREJIT
bool EETypeHashEntry::IsHot()
@@ -856,16 +860,21 @@ bool EETypeHashEntry::IsHot()
LIMITED_METHOD_CONTRACT;
// Low order bit of data field indicates a hot entry.
- return (m_data & 1) != 0;
+ TADDR data = dac_cast<TADDR>(GetData());
+ return (data & 1) != 0;
}
+#ifndef DACCESS_COMPILE
void EETypeHashEntry::MarkAsHot()
{
LIMITED_METHOD_CONTRACT;
// Low order bit of data field indicates a hot entry.
- m_data |= 0x1;
+ TADDR data = dac_cast<TADDR>(GetData());
+ data |= 0x1;
+ m_data.SetValueMaybeNull(dac_cast<PTR_VOID>(data));
}
+#endif // !DACCESS_COMPILE
#endif // FEATURE_PREJIT
#ifdef _MSC_VER
diff --git a/src/vm/typehash.h b/src/vm/typehash.h
index ce1f90bbc2..c9b01d5d5f 100644
--- a/src/vm/typehash.h
+++ b/src/vm/typehash.h
@@ -42,13 +42,27 @@ typedef struct EETypeHashEntry
void MarkAsHot();
#endif // FEATURE_PREJIT
+#ifndef DACCESS_COMPILE
+ EETypeHashEntry& operator=(const EETypeHashEntry& src)
+ {
+ m_data.SetValueMaybeNull(src.m_data.GetValueMaybeNull());
+
+ return *this;
+ }
+#endif // !DACCESS_COMPILE
+
+ PTR_VOID GetData()
+ {
+ return ReadPointerMaybeNull(this, &EETypeHashEntry::m_data);
+ }
+
private:
friend class EETypeHashTable;
#ifdef DACCESS_COMPILE
friend class NativeImageDumper;
#endif
- TADDR m_data;
+ RelativePointer<PTR_VOID> m_data;
} EETypeHashEntry_t;