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
24class ILStubHashBlobBase
25{
26public:
27 size_t m_cbSizeOfBlob; // this is size of entire object!!
28};
29
30class ILStubHashBlob : public ILStubHashBlobBase
31{
32public:
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//
41class ILStubCache : private CClosedHashBase
42{
43private:
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
57public:
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
104private:
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
152private:
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
169typedef DPTR(struct StubMethodHashEntry) PTR_StubMethodHashEntry;
170typedef 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
178private:
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
191typedef DPTR(class StubMethodHashTable) PTR_StubMethodHashTable;
192class 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
202public:
203 static StubMethodHashTable *Create(LoaderAllocator *pAllocator, Module *pModule, DWORD dwNumBuckets, AllocMemTracker *pamTracker);
204
205private:
206 void operator delete(void *p);
207
208public:
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