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 | // File: REJIT.H |
7 | // |
8 | |
9 | // |
10 | // REJIT.H defines the class and structures used to store info about rejitted |
11 | // methods. See comment at top of rejit.cpp for more information on how |
12 | // rejit works. |
13 | // |
14 | // =========================================================================== |
15 | #ifndef _REJIT_H_ |
16 | #define _REJIT_H_ |
17 | |
18 | #include "common.h" |
19 | #include "contractimpl.h" |
20 | #include "shash.h" |
21 | #include "corprof.h" |
22 | #include "codeversion.h" |
23 | |
24 | class ReJitManager; |
25 | class MethodDesc; |
26 | class ClrDataAccess; |
27 | |
28 | #ifdef FEATURE_REJIT |
29 | |
30 | //--------------------------------------------------------------------------------------- |
31 | // The CLR's implementation of ICorProfilerFunctionControl, which is passed |
32 | // to the profiler. The profiler calls methods on this to specify the IL and |
33 | // codegen flags for a given rejit request. |
34 | // |
35 | class ProfilerFunctionControl : public ICorProfilerFunctionControl |
36 | { |
37 | public: |
38 | ProfilerFunctionControl(LoaderHeap * pHeap); |
39 | virtual ~ProfilerFunctionControl(); |
40 | |
41 | // IUnknown functions |
42 | virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID id, void** pInterface); |
43 | virtual ULONG STDMETHODCALLTYPE AddRef(); |
44 | virtual ULONG STDMETHODCALLTYPE Release(); |
45 | |
46 | // ICorProfilerFunctionControl functions |
47 | virtual HRESULT STDMETHODCALLTYPE SetCodegenFlags(DWORD flags); |
48 | virtual HRESULT STDMETHODCALLTYPE SetILFunctionBody(ULONG , LPCBYTE ); |
49 | virtual HRESULT STDMETHODCALLTYPE SetILInstrumentedCodeMap(ULONG cILMapEntries, COR_IL_MAP * rgILMapEntries); |
50 | |
51 | // Accessors |
52 | DWORD GetCodegenFlags(); |
53 | LPBYTE GetIL(); |
54 | ULONG GetInstrumentedMapEntryCount(); |
55 | COR_IL_MAP* GetInstrumentedMapEntries(); |
56 | |
57 | |
58 | protected: |
59 | Volatile<LONG> m_refCount; |
60 | LoaderHeap * m_pHeap; |
61 | DWORD m_dwCodegenFlags; |
62 | ULONG m_cbIL; |
63 | |
64 | // This pointer will get copied into SharedReJitInfo::m_pbIL and owned there. |
65 | LPBYTE m_pbIL; |
66 | ULONG m_cInstrumentedMapEntries; |
67 | COR_IL_MAP * m_rgInstrumentedMapEntries; |
68 | }; |
69 | |
70 | #endif // FEATURE_REJIT |
71 | |
72 | |
73 | |
74 | //--------------------------------------------------------------------------------------- |
75 | // The big honcho. One of these per AppDomain, plus one for the |
76 | // SharedDomain. Contains the hash table of ReJitInfo structures to manage |
77 | // every rejit and revert request for its owning domain. |
78 | // |
79 | class ReJitManager |
80 | { |
81 | friend class ClrDataAccess; |
82 | friend class DacDbiInterfaceImpl; |
83 | |
84 | private: |
85 | |
86 | #ifdef FEATURE_REJIT |
87 | |
88 | // One global crst (for the entire CLR instance) to synchronize |
89 | // cross-ReJitManager operations, such as batch calls to RequestRejit and |
90 | // RequestRevert (which modify multiple ReJitManager instances). |
91 | static CrstStatic s_csGlobalRequest; |
92 | |
93 | #endif //FEATURE_REJIT |
94 | |
95 | public: |
96 | |
97 | static void InitStatic(); |
98 | |
99 | static BOOL IsReJITEnabled(); |
100 | |
101 | static HRESULT RequestReJIT( |
102 | ULONG cFunctions, |
103 | ModuleID rgModuleIDs[], |
104 | mdMethodDef rgMethodDefs[]); |
105 | |
106 | static HRESULT RequestRevert( |
107 | ULONG cFunctions, |
108 | ModuleID rgModuleIDs[], |
109 | mdMethodDef rgMethodDefs[], |
110 | HRESULT rgHrStatuses[]); |
111 | |
112 | static HRESULT ConfigureILCodeVersion(ILCodeVersion ilCodeVersion); |
113 | static CORJIT_FLAGS JitFlagsFromProfCodegenFlags(DWORD dwCodegenFlags); |
114 | |
115 | static ReJITID GetReJitId(PTR_MethodDesc pMD, PCODE pCodeStart); |
116 | static ReJITID GetReJitIdNoLock(PTR_MethodDesc pMD, PCODE pCodeStart); |
117 | static HRESULT GetReJITIDs(PTR_MethodDesc pMD, ULONG cReJitIds, ULONG * pcReJitIds, ReJITID reJitIds[]); |
118 | |
119 | #ifdef FEATURE_REJIT |
120 | |
121 | #ifndef DACCESS_COMPILE |
122 | static void ReportReJITError(CodeVersionManager::CodePublishError* pErrorRecord); |
123 | static void ReportReJITError(Module* pModule, mdMethodDef methodDef, MethodDesc* pMD, HRESULT hrStatus); |
124 | #endif |
125 | |
126 | private: |
127 | |
128 | static HRESULT UpdateActiveILVersions( |
129 | ULONG cFunctions, |
130 | ModuleID rgModuleIDs[], |
131 | mdMethodDef rgMethodDefs[], |
132 | HRESULT rgHrStatuses[], |
133 | BOOL fIsRevert); |
134 | |
135 | struct CodeActivationBatch |
136 | { |
137 | CodeActivationBatch(CodeVersionManager * pCodeVersionManager) : |
138 | m_pCodeVersionManager(pCodeVersionManager) |
139 | {} |
140 | CodeVersionManager* m_pCodeVersionManager; |
141 | CDynArray<ILCodeVersion> m_methodsToActivate; |
142 | }; |
143 | |
144 | class CodeActivationBatchTraits : public DefaultSHashTraits<CodeActivationBatch *> |
145 | { |
146 | public: |
147 | typedef DefaultSHashTraits<CodeActivationBatch *> PARENT; |
148 | typedef PARENT::element_t element_t; |
149 | typedef PARENT::count_t count_t; |
150 | typedef CodeVersionManager * key_t; |
151 | static key_t GetKey(const element_t &e) { return e->m_pCodeVersionManager; } |
152 | static BOOL Equals(key_t k1, key_t k2) { return (k1 == k2); } |
153 | static count_t Hash(key_t k) { return (count_t)k; } |
154 | static bool IsNull(const element_t &e) { return (e == NULL); } |
155 | }; |
156 | |
157 | static HRESULT BindILVersion( |
158 | CodeVersionManager* pCodeVersionManager, |
159 | PTR_Module pModule, |
160 | mdMethodDef methodDef, |
161 | ILCodeVersion *pILCodeVersion); |
162 | |
163 | #endif // FEATURE_REJIT |
164 | |
165 | }; |
166 | |
167 | #include "rejit.inl" |
168 | |
169 | #endif // _REJIT_H_ |
170 | |