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 | // File: ILStubCache.h |
6 | // |
7 | |
8 | // |
9 | |
10 | |
11 | #ifdef _MSC_VER |
12 | #pragma once |
13 | #endif // _MSC_VER |
14 | #ifndef _ILSTUBCACHE_H |
15 | #define _ILSTUBCACHE_H |
16 | |
17 | |
18 | #include "vars.hpp" |
19 | #include "util.hpp" |
20 | #include "crst.h" |
21 | #include "ngenhash.h" |
22 | #include "stubgen.h" |
23 | |
24 | class ILStubHashBlobBase |
25 | { |
26 | public: |
27 | size_t m_cbSizeOfBlob; // this is size of entire object!! |
28 | }; |
29 | |
30 | class ILStubHashBlob : public ILStubHashBlobBase |
31 | { |
32 | public: |
33 | BYTE m_rgbBlobData[1]; |
34 | }; |
35 | |
36 | |
37 | // |
38 | // This class caches MethodDesc's for dynamically generated IL stubs, it is not |
39 | // persisted in NGEN images. |
40 | // |
41 | class ILStubCache : private CClosedHashBase |
42 | { |
43 | private: |
44 | //--------------------------------------------------------- |
45 | // Hash entry for CClosedHashBase. |
46 | //--------------------------------------------------------- |
47 | struct ILCHASHENTRY |
48 | { |
49 | // Values: |
50 | // NULL = free |
51 | // -1 = deleted |
52 | // other = used |
53 | MethodDesc* m_pMethodDesc; |
54 | ILStubHashBlob* m_pBlob; |
55 | }; |
56 | |
57 | public: |
58 | |
59 | //--------------------------------------------------------- |
60 | // Constructor |
61 | //--------------------------------------------------------- |
62 | ILStubCache(LoaderHeap* heap = NULL); |
63 | |
64 | //--------------------------------------------------------- |
65 | // Destructor |
66 | //--------------------------------------------------------- |
67 | virtual ~ILStubCache(); |
68 | |
69 | void Init(LoaderHeap* pHeap); |
70 | |
71 | MethodDesc* GetStubMethodDesc( |
72 | MethodDesc *pTargetMD, |
73 | ILStubHashBlob* pParams, |
74 | DWORD dwStubFlags, // bitmask of NDirectStubFlags |
75 | Module* pSigModule, |
76 | PCCOR_SIGNATURE pSig, |
77 | DWORD cbSig, |
78 | AllocMemTracker* pamTracker, |
79 | bool& bILStubCreator, |
80 | MethodDesc* pLastMD); |
81 | |
82 | void DeleteEntry(void *pParams); |
83 | |
84 | void AddMethodDescChunkWithLockTaken(MethodDesc *pMD); |
85 | |
86 | static MethodDesc* CreateAndLinkNewILStubMethodDesc( |
87 | LoaderAllocator* pAllocator, |
88 | MethodTable* pMT, |
89 | DWORD dwStubFlags, // bitmask of NDirectStubFlags |
90 | Module* pSigModule, |
91 | PCCOR_SIGNATURE pSig, |
92 | DWORD cbSig, |
93 | SigTypeContext *pTypeContext, |
94 | ILStubLinker* pStubLinker); |
95 | |
96 | MethodTable * GetStubMethodTable() |
97 | { |
98 | LIMITED_METHOD_CONTRACT; |
99 | return m_pStubMT; |
100 | } |
101 | |
102 | MethodTable* GetOrCreateStubMethodTable(Module* pLoaderModule); |
103 | |
104 | private: |
105 | |
106 | static MethodDesc* CreateNewMethodDesc( |
107 | LoaderHeap* pCreationHeap, |
108 | MethodTable* pMT, |
109 | DWORD dwStubFlags, // bitmask of NDirectStubFlags |
110 | Module* pSigModule, |
111 | PCCOR_SIGNATURE pSig, |
112 | DWORD cbSig, |
113 | SigTypeContext *pTypeContext, |
114 | AllocMemTracker* pamTracker); |
115 | |
116 | // *** OVERRIDES FOR CClosedHashBase ***/ |
117 | |
118 | //***************************************************************************** |
119 | // Hash is called with a pointer to an element in the table. You must override |
120 | // this method and provide a hash algorithm for your element type. |
121 | //***************************************************************************** |
122 | virtual unsigned int Hash( // The key value. |
123 | void const* pData); // Raw data to hash. |
124 | |
125 | //***************************************************************************** |
126 | // Compare is used in the typical memcmp way, 0 is eqaulity, -1/1 indicate |
127 | // direction of miscompare. In this system everything is always equal or not. |
128 | //***************************************************************************** |
129 | virtual unsigned int Compare( // 0, -1, or 1. |
130 | void const* pData, // Raw key data on lookup. |
131 | BYTE* pElement); // The element to compare data against. |
132 | |
133 | //***************************************************************************** |
134 | // Return true if the element is free to be used. |
135 | //***************************************************************************** |
136 | virtual ELEMENTSTATUS Status( // The status of the entry. |
137 | BYTE* pElement); // The element to check. |
138 | |
139 | //***************************************************************************** |
140 | // Sets the status of the given element. |
141 | //***************************************************************************** |
142 | virtual void SetStatus( |
143 | BYTE* pElement, // The element to set status for. |
144 | ELEMENTSTATUS eStatus); // New status. |
145 | |
146 | //***************************************************************************** |
147 | // Returns the internal key value for an element. |
148 | //***************************************************************************** |
149 | virtual void* GetKey( // The data to hash on. |
150 | BYTE* pElement); // The element to return data ptr for. |
151 | |
152 | private: |
153 | Crst m_crst; |
154 | LoaderHeap* m_heap; |
155 | MethodTable* m_pStubMT; |
156 | }; |
157 | |
158 | |
159 | #ifdef FEATURE_PREJIT |
160 | //======================================================================================== |
161 | // |
162 | // This hash table is used by interop to lookup NGENed marshaling stubs for methods |
163 | // in cases where the MethodDesc cannot point to the stub directly. |
164 | // |
165 | // Keys are arbitrary MethodDesc's, values are IL stub MethodDescs. |
166 | // |
167 | //======================================================================================== |
168 | |
169 | typedef DPTR(struct StubMethodHashEntry) PTR_StubMethodHashEntry; |
170 | typedef struct StubMethodHashEntry |
171 | { |
172 | PTR_MethodDesc GetMethod(); |
173 | PTR_MethodDesc GetStubMethod(); |
174 | #ifndef DACCESS_COMPILE |
175 | void SetMethodAndStub(MethodDesc *pMD, MethodDesc *pStubMD); |
176 | #endif // !DACCESS_COMPILE |
177 | |
178 | private: |
179 | friend class StubMethodHashTable; |
180 | #ifdef DACCESS_COMPILE |
181 | friend class NativeImageDumper; |
182 | #endif |
183 | |
184 | PTR_MethodDesc pMD; |
185 | PTR_MethodDesc pStubMD; |
186 | |
187 | } StubMethodHashEntry_t; |
188 | |
189 | |
190 | // The hash table itself |
191 | typedef DPTR(class StubMethodHashTable) PTR_StubMethodHashTable; |
192 | class StubMethodHashTable : public NgenHashTable<StubMethodHashTable, StubMethodHashEntry, 2> |
193 | { |
194 | #ifndef DACCESS_COMPILE |
195 | StubMethodHashTable(); |
196 | |
197 | StubMethodHashTable(Module *pModule, LoaderHeap *pHeap, DWORD cInitialBuckets) : |
198 | NgenHashTable<StubMethodHashTable, StubMethodHashEntry, 2>(pModule, pHeap, cInitialBuckets) {} |
199 | |
200 | ~StubMethodHashTable(); |
201 | #endif |
202 | public: |
203 | static StubMethodHashTable *Create(LoaderAllocator *pAllocator, Module *pModule, DWORD dwNumBuckets, AllocMemTracker *pamTracker); |
204 | |
205 | private: |
206 | void operator delete(void *p); |
207 | |
208 | public: |
209 | // Looks up a stub MethodDesc in the hash table, returns NULL if not found |
210 | MethodDesc *FindMethodDesc(MethodDesc *pMD); |
211 | |
212 | #ifndef DACCESS_COMPILE |
213 | // Inserts a method-stub pair into the hash table |
214 | VOID InsertMethodDesc(MethodDesc *pMD, MethodDesc *pStubMD); |
215 | |
216 | void Save(DataImage *image, CorProfileData *profileData); |
217 | void Fixup(DataImage *image); |
218 | |
219 | bool ShouldSave(DataImage *pImage, StubMethodHashEntry_t *pEntry); |
220 | |
221 | bool IsHotEntry(StubMethodHashEntry_t *pEntry, CorProfileData *pProfileData) |
222 | { LIMITED_METHOD_CONTRACT; return true; } |
223 | |
224 | bool SaveEntry(DataImage *pImage, CorProfileData *pProfileData, StubMethodHashEntry_t *pOldEntry, StubMethodHashEntry_t *pNewEntry, EntryMappingTable *pMap) |
225 | { LIMITED_METHOD_CONTRACT; return false; } |
226 | |
227 | void FixupEntry(DataImage *pImage, StubMethodHashEntry_t *pEntry, void *pFixupBase, DWORD cbFixupOffset); |
228 | #endif // !DACCESS_COMPILE |
229 | |
230 | #ifdef DACCESS_COMPILE |
231 | void EnumMemoryRegions(CLRDataEnumMemoryFlags flags); |
232 | void EnumMemoryRegionsForEntry(StubMethodHashEntry_t *pEntry, CLRDataEnumMemoryFlags flags); |
233 | #endif |
234 | }; |
235 | #endif // FEATURE_PREJIT |
236 | |
237 | #endif //_ILSTUBCACHE_H |
238 | |