1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
|
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
//
// Hash table associated with each module that records for all types defined in that module the mapping
// between type name and token (or TypeHandle).
//
#ifndef __CLASS_HASH_INCLUDED
#define __CLASS_HASH_INCLUDED
#include "ngenhash.h"
// The type of each entry in the hash.
typedef DPTR(struct EEClassHashEntry) PTR_EEClassHashEntry;
class EEClassHashTable;
typedef struct EEClassHashEntry
{
friend class EEClassHashTable;
#ifdef DACCESS_COMPILE
friend class NativeImageDumper;
#endif
#ifdef BINDER
friend class MdilModule;
#endif
#ifdef _DEBUG
PTR_CUTF8 DebugKey[2]; // Name of the type
#endif // _DEBUG
// Accessors for encloser (pointer to hash entry of enclosing type when this entry describes a nested
// type). You need to use the accessors since the reference is not encoded as a simple pointer anymore.
PTR_EEClassHashEntry GetEncloser();
void SetEncloser(EEClassHashEntry *pEncloser) DAC_EMPTY();
// Bit masks for flags in the data field. <NICE>Ideally we'd abstract this encoding but that's too much
// code churn right now.</NICE>
#define EECLASSHASH_TYPEHANDLE_DISCR ((ULONG_PTR)(UINT)0x00000001)
#define EECLASSHASH_MDEXPORT_DISCR ((ULONG_PTR)(UINT)0x80000000)
#define EECLASSHASH_ALREADYSEEN ((ULONG_PTR)(UINT)0x40000000)
// Accessors for the data field (TypeHandle or a token with EECLASSHASH_TYPEHANDLE_DISCR set and possibly
// some of the other flag bits above). The type handle is also encoded as a non-regular pointer, so use
// this accessor.
PTR_VOID GetData();
void SetData(PTR_VOID data) DAC_EMPTY();
private:
PTR_VOID m_Data; // Either the token (if EECLASSHASH_TYPEHANDLE_DISCR), or the type handle encoded
// as a relative pointer
NgenHashEntryRef<EEClassHashTable, EEClassHashEntry, 4> m_pEncloser; // If this entry is a for a nested
// class, this field stores a
// reference to the enclosing type
// (which must be in this same
// hash). The NgenHashEntryRef<>
// is required to abstract some
// complex logic required while
// ngen'ing such references.
} EEClassHashEntry_t;
// The hash type itself. All common logic is provided by the NgenHashTable templated base class. See
// NgenHash.h for details.
typedef DPTR(class EEClassHashTable) PTR_EEClassHashTable;
class EEClassHashTable : public NgenHashTable<EEClassHashTable, EEClassHashEntry, 4>
{
#ifdef DACCESS_COMPILE
friend class NativeImageDumper;
#endif
public:
// The LookupContext type we export to track GetValue/FindNextNestedClass enumerations is simply a rename
// of the base classes' hash value enumerator.
typedef NgenHashTable<EEClassHashTable, EEClassHashEntry, 4>::LookupContext LookupContext;
static EEClassHashTable *Create(Module *pModule, DWORD dwNumBuckets, BOOL bCaseInsensitive, AllocMemTracker *pamTracker);
//NOTICE: look at InsertValue() in ClassLoader, that may be the function you want to use. Use this only
// when you are sure you want to insert the value in 'this' table. This function does not deal
// with case (as often the class loader has to)
#ifndef BINDER
EEClassHashEntry_t *InsertValue(LPCUTF8 pszNamespace, LPCUTF8 pszClassName, PTR_VOID Data, EEClassHashEntry_t *pEncloser, AllocMemTracker *pamTracker);
EEClassHashEntry_t *InsertValueIfNotFound(LPCUTF8 pszNamespace, LPCUTF8 pszClassName, PTR_VOID *pData, EEClassHashEntry_t *pEncloser, BOOL IsNested, BOOL *pbFound, AllocMemTracker *pamTracker);
EEClassHashEntry_t *InsertValueUsingPreallocatedEntry(EEClassHashEntry_t *pStorageForNewEntry, LPCUTF8 pszNamespace, LPCUTF8 pszClassName, PTR_VOID Data, EEClassHashEntry_t *pEncloser);
EEClassHashEntry_t *GetValue(LPCUTF8 pszNamespace, LPCUTF8 pszClassName, PTR_VOID *pData, BOOL IsNested, LookupContext *pContext);
EEClassHashEntry_t *GetValue(LPCUTF8 pszFullyQualifiedName, PTR_VOID *pData, BOOL IsNested, LookupContext *pContext);
EEClassHashEntry_t *GetValue(NameHandle* pName, PTR_VOID *pData, BOOL IsNested, LookupContext *pContext);
EEClassHashEntry_t *AllocNewEntry(AllocMemTracker *pamTracker);
EEClassHashTable *MakeCaseInsensitiveTable(Module *pModule, AllocMemTracker *pamTracker);
EEClassHashEntry_t *FindItem(LPCUTF8 pszNamespace, LPCUTF8 pszClassName, BOOL IsNested, LookupContext *pContext);
EEClassHashEntry_t *FindNextNestedClass(NameHandle* pName, PTR_VOID *pData, LookupContext *pContext);
EEClassHashEntry_t *FindNextNestedClass(LPCUTF8 pszNamespace, LPCUTF8 pszClassName, PTR_VOID *pData, LookupContext *pContext);
EEClassHashEntry_t *FindNextNestedClass(LPCUTF8 pszFullyQualifiedName, PTR_VOID *pData, LookupContext *pContext);
#endif // BINDER
BOOL CompareKeys(PTR_EEClassHashEntry pEntry, LPCUTF8 * pKey2);
static DWORD Hash(LPCUTF8 pszNamespace, LPCUTF8 pszClassName);
class ConstructKeyCallback
{
public:
virtual void UseKeys(__in_ecount(2) LPUTF8 *Key) = 0;
};
static PTR_VOID CompressClassDef(mdToken cl /* either a TypeDef or ExportedType*/);
#ifndef BINDER
bool UncompressModuleAndClassDef(PTR_VOID Data, Loader::LoadFlag loadFlag,
Module **ppModule, mdTypeDef *pCL,
mdExportedType *pmdFoundExportedType);
VOID UncompressModuleAndNonExportClassDef(PTR_VOID Data, Module **ppModule,
mdTypeDef *pCL);
static mdToken UncompressModuleAndClassDef(PTR_VOID Data);
#endif // !BINDER
#ifdef DACCESS_COMPILE
void EnumMemoryRegions(CLRDataEnumMemoryFlags flags);
void EnumMemoryRegionsForEntry(EEClassHashEntry_t *pEntry, CLRDataEnumMemoryFlags flags);
#endif
#if defined(FEATURE_PREJIT) && !defined(DACCESS_COMPILE)
void Save(DataImage *pImage, CorProfileData *pProfileData);
void Fixup(DataImage *pImage);
private:
friend class NgenHashTable<EEClassHashTable, EEClassHashEntry, 4>;
void PrepareExportedTypesForSaving(DataImage *image);
bool ShouldSave(DataImage *pImage, EEClassHashEntry_t *pEntry);
bool IsHotEntry(EEClassHashEntry_t *pEntry, CorProfileData *pProfileData);
bool SaveEntry(DataImage *pImage, CorProfileData *pProfileData, EEClassHashEntry_t *pOldEntry, EEClassHashEntry_t *pNewEntry, EntryMappingTable *pMap);
void FixupEntry(DataImage *pImage, EEClassHashEntry_t *pEntry, void *pFixupBase, DWORD cbFixupOffset);
#endif // FEATURE_PREJIT && !DACCESS_COMPILE
private:
#ifndef DACCESS_COMPILE
EEClassHashTable(Module *pModule, LoaderHeap *pHeap, DWORD cInitialBuckets) :
NgenHashTable<EEClassHashTable, EEClassHashEntry, 4>(pModule, pHeap, cInitialBuckets) {}
#endif
VOID ConstructKeyFromData(PTR_EEClassHashEntry pEntry, ConstructKeyCallback * pCallback);
BOOL m_bCaseInsensitive; // Default is true FALSE unless we call MakeCaseInsensitiveTable
};
#endif // !__CLASS_HASH_INCLUDED
|