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
5extern ICorJitHost* g_jitHost;
6
7class CILJit : public ICorJitCompiler
8{
9 CorJitResult __stdcall compileMethod(ICorJitInfo* comp, /* IN */
10 CORINFO_METHOD_INFO* methodInfo, /* IN */
11 unsigned flags, /* IN */
12 BYTE** nativeEntry, /* OUT */
13 ULONG* nativeSizeOfCode /* OUT */
14 );
15
16 void clearCache(void);
17 BOOL isCacheCleanupRequired(void);
18
19 void ProcessShutdownWork(ICorStaticInfo* statInfo);
20
21 void getVersionIdentifier(GUID* versionIdentifier /* OUT */
22 );
23
24 unsigned getMaxIntrinsicSIMDVectorLength(CORJIT_FLAGS cpuCompileFlags);
25
26 void setRealJit(ICorJitCompiler* realJitCompiler);
27};
28
29/*****************************************************************************
30 *
31 * Functions to get various handles
32 */
33
34FORCEINLINE
35void Compiler::eeGetCallInfo(CORINFO_RESOLVED_TOKEN* pResolvedToken,
36 CORINFO_RESOLVED_TOKEN* pConstrainedToken,
37 CORINFO_CALLINFO_FLAGS flags,
38 CORINFO_CALL_INFO* pResult)
39{
40 info.compCompHnd->getCallInfo(pResolvedToken, pConstrainedToken, info.compMethodHnd, flags, pResult);
41}
42
43FORCEINLINE
44void Compiler::eeGetFieldInfo(CORINFO_RESOLVED_TOKEN* pResolvedToken,
45 CORINFO_ACCESS_FLAGS accessFlags,
46 CORINFO_FIELD_INFO* pResult)
47{
48 info.compCompHnd->getFieldInfo(pResolvedToken, info.compMethodHnd, accessFlags, pResult);
49}
50
51/*****************************************************************************
52 *
53 * VOS info, method sigs, etc
54 */
55
56FORCEINLINE
57BOOL Compiler::eeIsValueClass(CORINFO_CLASS_HANDLE clsHnd)
58{
59 return info.compCompHnd->isValueClass(clsHnd);
60}
61
62FORCEINLINE
63void Compiler::eeGetSig(unsigned sigTok,
64 CORINFO_MODULE_HANDLE scope,
65 CORINFO_CONTEXT_HANDLE context,
66 CORINFO_SIG_INFO* retSig)
67{
68 info.compCompHnd->findSig(scope, sigTok, context, retSig);
69
70 assert(!varTypeIsComposite(JITtype2varType(retSig->retType)) || retSig->retTypeClass != nullptr);
71}
72
73FORCEINLINE
74void Compiler::eeGetMethodSig(CORINFO_METHOD_HANDLE methHnd, CORINFO_SIG_INFO* sigRet, CORINFO_CLASS_HANDLE owner)
75{
76 info.compCompHnd->getMethodSig(methHnd, sigRet, owner);
77
78 assert(!varTypeIsComposite(JITtype2varType(sigRet->retType)) || sigRet->retTypeClass != nullptr);
79}
80
81/**********************************************************************
82 * For varargs we need the number of arguments at the call site
83 */
84
85FORCEINLINE
86void Compiler::eeGetCallSiteSig(unsigned sigTok,
87 CORINFO_MODULE_HANDLE scope,
88 CORINFO_CONTEXT_HANDLE context,
89 CORINFO_SIG_INFO* sigRet)
90{
91 info.compCompHnd->findCallSiteSig(scope, sigTok, context, sigRet);
92
93 assert(!varTypeIsComposite(JITtype2varType(sigRet->retType)) || sigRet->retTypeClass != nullptr);
94}
95
96/*****************************************************************************/
97inline var_types Compiler::eeGetArgType(CORINFO_ARG_LIST_HANDLE list, CORINFO_SIG_INFO* sig)
98{
99 CORINFO_CLASS_HANDLE argClass;
100 return (JITtype2varType(strip(info.compCompHnd->getArgType(sig, list, &argClass))));
101}
102
103/*****************************************************************************/
104inline var_types Compiler::eeGetArgType(CORINFO_ARG_LIST_HANDLE list, CORINFO_SIG_INFO* sig, bool* isPinned)
105{
106 CORINFO_CLASS_HANDLE argClass;
107 CorInfoTypeWithMod type = info.compCompHnd->getArgType(sig, list, &argClass);
108 *isPinned = ((type & ~CORINFO_TYPE_MASK) != 0);
109 return JITtype2varType(strip(type));
110}
111
112/*****************************************************************************
113 *
114 * Native Direct Optimizations
115 */
116
117inline CORINFO_EE_INFO* Compiler::eeGetEEInfo()
118{
119 if (!eeInfoInitialized)
120 {
121 info.compCompHnd->getEEInfo(&eeInfo);
122 eeInfoInitialized = true;
123 }
124
125 return &eeInfo;
126}
127
128/*****************************************************************************
129 *
130 * Convert the type returned from the VM to a var_type.
131 */
132
133inline var_types JITtype2varType(CorInfoType type)
134{
135
136 static const unsigned char varTypeMap[CORINFO_TYPE_COUNT] = {
137 // see the definition of enum CorInfoType in file inc/corinfo.h
138 TYP_UNDEF, // CORINFO_TYPE_UNDEF = 0x0,
139 TYP_VOID, // CORINFO_TYPE_VOID = 0x1,
140 TYP_BOOL, // CORINFO_TYPE_BOOL = 0x2,
141 TYP_USHORT, // CORINFO_TYPE_CHAR = 0x3,
142 TYP_BYTE, // CORINFO_TYPE_BYTE = 0x4,
143 TYP_UBYTE, // CORINFO_TYPE_UBYTE = 0x5,
144 TYP_SHORT, // CORINFO_TYPE_SHORT = 0x6,
145 TYP_USHORT, // CORINFO_TYPE_USHORT = 0x7,
146 TYP_INT, // CORINFO_TYPE_INT = 0x8,
147 TYP_INT, // CORINFO_TYPE_UINT = 0x9,
148 TYP_LONG, // CORINFO_TYPE_LONG = 0xa,
149 TYP_LONG, // CORINFO_TYPE_ULONG = 0xb,
150 TYP_I_IMPL, // CORINFO_TYPE_NATIVEINT = 0xc,
151 TYP_I_IMPL, // CORINFO_TYPE_NATIVEUINT = 0xd,
152 TYP_FLOAT, // CORINFO_TYPE_FLOAT = 0xe,
153 TYP_DOUBLE, // CORINFO_TYPE_DOUBLE = 0xf,
154 TYP_REF, // CORINFO_TYPE_STRING = 0x10, // Not used, should remove
155 TYP_I_IMPL, // CORINFO_TYPE_PTR = 0x11,
156 TYP_BYREF, // CORINFO_TYPE_BYREF = 0x12,
157 TYP_STRUCT, // CORINFO_TYPE_VALUECLASS = 0x13,
158 TYP_REF, // CORINFO_TYPE_CLASS = 0x14,
159 TYP_STRUCT, // CORINFO_TYPE_REFANY = 0x15,
160
161 // Generic type variables only appear when we're doing
162 // verification of generic code, in which case we're running
163 // in "import only" mode. Annoyingly the "import only"
164 // mode of the JIT actually does a fair bit of compilation,
165 // so we have to trick the compiler into thinking it's compiling
166 // a real instantiation. We do that by just pretending we're
167 // compiling the "object" instantiation of the code, i.e. by
168 // turing all generic type variables refs, except for a few
169 // choice places to do with verification, where we use
170 // verification types and CLASS_HANDLEs to track the difference.
171
172 TYP_REF, // CORINFO_TYPE_VAR = 0x16,
173 };
174
175 // spot check to make certain enumerations have not changed
176
177 assert(varTypeMap[CORINFO_TYPE_CLASS] == TYP_REF);
178 assert(varTypeMap[CORINFO_TYPE_BYREF] == TYP_BYREF);
179 assert(varTypeMap[CORINFO_TYPE_PTR] == TYP_I_IMPL);
180 assert(varTypeMap[CORINFO_TYPE_INT] == TYP_INT);
181 assert(varTypeMap[CORINFO_TYPE_UINT] == TYP_INT);
182 assert(varTypeMap[CORINFO_TYPE_DOUBLE] == TYP_DOUBLE);
183 assert(varTypeMap[CORINFO_TYPE_VOID] == TYP_VOID);
184 assert(varTypeMap[CORINFO_TYPE_VALUECLASS] == TYP_STRUCT);
185 assert(varTypeMap[CORINFO_TYPE_REFANY] == TYP_STRUCT);
186
187 assert(type < CORINFO_TYPE_COUNT);
188 assert(varTypeMap[type] != TYP_UNDEF);
189
190 return ((var_types)varTypeMap[type]);
191};
192
193inline CORINFO_CALLINFO_FLAGS combine(CORINFO_CALLINFO_FLAGS flag1, CORINFO_CALLINFO_FLAGS flag2)
194{
195 return (CORINFO_CALLINFO_FLAGS)(flag1 | flag2);
196}
197inline CORINFO_CALLINFO_FLAGS Compiler::addVerifyFlag(CORINFO_CALLINFO_FLAGS flags)
198{
199 if (tiVerificationNeeded)
200 {
201 flags = combine(flags, CORINFO_CALLINFO_VERIFICATION);
202 }
203 return flags;
204}
205