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