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
24class ReJitManager;
25class MethodDesc;
26class 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//
35class ProfilerFunctionControl : public ICorProfilerFunctionControl
36{
37public:
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 cbNewILMethodHeader, LPCBYTE pbNewILMethodHeader);
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
58protected:
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//
79class ReJitManager
80{
81 friend class ClrDataAccess;
82 friend class DacDbiInterfaceImpl;
83
84private:
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
95public:
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
126private:
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