d88e35299aab897e646e836088475e20189e2235
[platform/upstream/dotnet/runtime.git] / src / coreclr / src / ToolBox / superpmi / superpmi / icorjitinfo.cpp
1 //
2 // Copyright (c) Microsoft. All rights reserved.
3 // Licensed under the MIT license. See LICENSE file in the project root for full license information.
4 //
5
6 #include "standardpch.h"
7 #include "icorjitinfo.h"
8 #include "jitdebugger.h"
9 #include "spmiutil.h"
10
11 ICorJitInfo* pICJI = nullptr;
12
13 ICorJitInfo* InitICorJitInfo(JitInstance* jitInstance)
14 {
15     MyICJI* icji      = new MyICJI();
16     icji->jitInstance = jitInstance;
17     pICJI             = icji;
18     return icji;
19 }
20
21 // Stuff on ICorStaticInfo
22 /**********************************************************************************/
23 //
24 // ICorMethodInfo
25 //
26 /**********************************************************************************/
27
28 // return flags (defined above, CORINFO_FLG_PUBLIC ...)
29 DWORD MyICJI::getMethodAttribs(CORINFO_METHOD_HANDLE ftn /* IN */)
30 {
31     jitInstance->mc->cr->AddCall("getMethodAttribs");
32     return jitInstance->mc->repGetMethodAttribs(ftn);
33 }
34
35 // sets private JIT flags, which can be, retrieved using getAttrib.
36 void MyICJI::setMethodAttribs(CORINFO_METHOD_HANDLE     ftn, /* IN */
37                               CorInfoMethodRuntimeFlags attribs /* IN */)
38 {
39     jitInstance->mc->cr->AddCall("setMethodAttribs");
40     jitInstance->mc->cr->recSetMethodAttribs(ftn, attribs);
41 }
42
43 // Given a method descriptor ftnHnd, extract signature information into sigInfo
44 //
45 // 'memberParent' is typically only set when verifying.  It should be the
46 // result of calling getMemberParent.
47 void MyICJI::getMethodSig(CORINFO_METHOD_HANDLE ftn,         /* IN  */
48                           CORINFO_SIG_INFO*     sig,         /* OUT */
49                           CORINFO_CLASS_HANDLE  memberParent /* IN */
50                           )
51 {
52     jitInstance->mc->cr->AddCall("getMethodSig");
53     jitInstance->mc->repGetMethodSig(ftn, sig, memberParent);
54 }
55
56 /*********************************************************************
57 * Note the following methods can only be used on functions known
58 * to be IL.  This includes the method being compiled and any method
59 * that 'getMethodInfo' returns true for
60 *********************************************************************/
61
62 // return information about a method private to the implementation
63 //      returns false if method is not IL, or is otherwise unavailable.
64 //      This method is used to fetch data needed to inline functions
65 bool MyICJI::getMethodInfo(CORINFO_METHOD_HANDLE ftn, /* IN  */
66                            CORINFO_METHOD_INFO*  info /* OUT */
67                            )
68 {
69     jitInstance->mc->cr->AddCall("getMethodInfo");
70     DWORD exceptionCode = 0;
71     bool  value         = jitInstance->mc->repGetMethodInfo(ftn, info, &exceptionCode);
72     if (exceptionCode != 0)
73         ThrowException(exceptionCode);
74     return value;
75 }
76
77 // Decides if you have any limitations for inlining. If everything's OK, it will return
78 // INLINE_PASS and will fill out pRestrictions with a mask of restrictions the caller of this
79 // function must respect. If caller passes pRestrictions = nullptr, if there are any restrictions
80 // INLINE_FAIL will be returned
81 //
82 // The callerHnd must be the immediate caller (i.e. when we have a chain of inlined calls)
83 //
84 // The inlined method need not be verified
85
86 CorInfoInline MyICJI::canInline(CORINFO_METHOD_HANDLE callerHnd,    /* IN  */
87                                 CORINFO_METHOD_HANDLE calleeHnd,    /* IN  */
88                                 DWORD*                pRestrictions /* OUT */
89                                 )
90 {
91     jitInstance->mc->cr->AddCall("canInline");
92
93     DWORD         exceptionCode = 0;
94     CorInfoInline result        = jitInstance->mc->repCanInline(callerHnd, calleeHnd, pRestrictions, &exceptionCode);
95     if (exceptionCode != 0)
96         ThrowException(exceptionCode);
97     return result;
98 }
99
100 // Reports whether or not a method can be inlined, and why.  canInline is responsible for reporting all
101 // inlining results when it returns INLINE_FAIL and INLINE_NEVER.  All other results are reported by the
102 // JIT.
103 void MyICJI::reportInliningDecision(CORINFO_METHOD_HANDLE inlinerHnd,
104                                     CORINFO_METHOD_HANDLE inlineeHnd,
105                                     CorInfoInline         inlineResult,
106                                     const char*           reason)
107 {
108     jitInstance->mc->cr->AddCall("reportInliningDecision");
109     jitInstance->mc->cr->recReportInliningDecision(inlinerHnd, inlineeHnd, inlineResult, reason);
110 }
111
112 // Returns false if the call is across security boundaries thus we cannot tailcall
113 //
114 // The callerHnd must be the immediate caller (i.e. when we have a chain of inlined calls)
115 bool MyICJI::canTailCall(CORINFO_METHOD_HANDLE callerHnd,         /* IN */
116                          CORINFO_METHOD_HANDLE declaredCalleeHnd, /* IN */
117                          CORINFO_METHOD_HANDLE exactCalleeHnd,    /* IN */
118                          bool                  fIsTailPrefix      /* IN */
119                          )
120 {
121     jitInstance->mc->cr->AddCall("canTailCall");
122     return jitInstance->mc->repCanTailCall(callerHnd, declaredCalleeHnd, exactCalleeHnd, fIsTailPrefix);
123 }
124
125 // Reports whether or not a method can be tail called, and why.
126 // canTailCall is responsible for reporting all results when it returns
127 // false.  All other results are reported by the JIT.
128 void MyICJI::reportTailCallDecision(CORINFO_METHOD_HANDLE callerHnd,
129                                     CORINFO_METHOD_HANDLE calleeHnd,
130                                     bool                  fIsTailPrefix,
131                                     CorInfoTailCall       tailCallResult,
132                                     const char*           reason)
133 {
134     jitInstance->mc->cr->AddCall("reportTailCallDecision");
135     jitInstance->mc->cr->recReportTailCallDecision(callerHnd, calleeHnd, fIsTailPrefix, tailCallResult, reason);
136 }
137
138 // get individual exception handler
139 void MyICJI::getEHinfo(CORINFO_METHOD_HANDLE ftn,      /* IN  */
140                        unsigned              EHnumber, /* IN */
141                        CORINFO_EH_CLAUSE*    clause    /* OUT */
142                        )
143 {
144     jitInstance->mc->cr->AddCall("getEHinfo");
145     jitInstance->mc->repGetEHinfo(ftn, EHnumber, clause);
146 }
147
148 // return class it belongs to
149 CORINFO_CLASS_HANDLE MyICJI::getMethodClass(CORINFO_METHOD_HANDLE method)
150 {
151     jitInstance->mc->cr->AddCall("getMethodClass");
152     return jitInstance->mc->repGetMethodClass(method);
153 }
154
155 // return module it belongs to
156 CORINFO_MODULE_HANDLE MyICJI::getMethodModule(CORINFO_METHOD_HANDLE method)
157 {
158     jitInstance->mc->cr->AddCall("getMethodModule");
159     LogError("Hit unimplemented getMethodModule");
160     DebugBreakorAV(7);
161     return 0;
162 }
163
164 // This function returns the offset of the specified method in the
165 // vtable of it's owning class or interface.
166 void MyICJI::getMethodVTableOffset(CORINFO_METHOD_HANDLE method,                /* IN */
167                                    unsigned*             offsetOfIndirection,   /* OUT */
168                                    unsigned*             offsetAfterIndirection /* OUT */
169                                    )
170 {
171     jitInstance->mc->cr->AddCall("getMethodVTableOffset");
172     jitInstance->mc->repGetMethodVTableOffset(method, offsetOfIndirection, offsetAfterIndirection);
173 }
174
175 // Find the virtual method in implementingClass that overrides virtualMethod.
176 // Return null if devirtualization is not possible.
177 CORINFO_METHOD_HANDLE MyICJI::resolveVirtualMethod(CORINFO_METHOD_HANDLE  virtualMethod,
178                                                    CORINFO_CLASS_HANDLE   implementingClass,
179                                                    CORINFO_CONTEXT_HANDLE ownerType)
180 {
181     jitInstance->mc->cr->AddCall("resolveVirtualMethod");
182     CORINFO_METHOD_HANDLE result =
183         jitInstance->mc->repResolveVirtualMethod(virtualMethod, implementingClass, ownerType);
184     return result;
185 }
186
187 void MyICJI::expandRawHandleIntrinsic(
188     CORINFO_RESOLVED_TOKEN *        pResolvedToken,
189     CORINFO_GENERICHANDLE_RESULT *  pResult)
190 {
191     jitInstance->mc->cr->AddCall("expandRawHandleIntrinsic");
192     LogError("Hit unimplemented expandRawHandleIntrinsic");
193     DebugBreakorAV(129);
194 }
195
196 // If a method's attributes have (getMethodAttribs) CORINFO_FLG_INTRINSIC set,
197 // getIntrinsicID() returns the intrinsic ID.
198 CorInfoIntrinsics MyICJI::getIntrinsicID(CORINFO_METHOD_HANDLE method, bool* pMustExpand /* OUT */
199                                          )
200 {
201     jitInstance->mc->cr->AddCall("getIntrinsicID");
202     return jitInstance->mc->repGetIntrinsicID(method, pMustExpand);
203 }
204
205 // Is the given module the System.Numerics.Vectors module?
206 bool MyICJI::isInSIMDModule(CORINFO_CLASS_HANDLE classHnd)
207 {
208     jitInstance->mc->cr->AddCall("isInSIMDModule");
209     return jitInstance->mc->repIsInSIMDModule(classHnd) ? true : false;
210 }
211
212 // return the unmanaged calling convention for a PInvoke
213 CorInfoUnmanagedCallConv MyICJI::getUnmanagedCallConv(CORINFO_METHOD_HANDLE method)
214 {
215     jitInstance->mc->cr->AddCall("getUnmanagedCallConv");
216     return jitInstance->mc->repGetUnmanagedCallConv(method);
217 }
218
219 // return if any marshaling is required for PInvoke methods.  Note that
220 // method == 0 => calli.  The call site sig is only needed for the varargs or calli case
221 BOOL MyICJI::pInvokeMarshalingRequired(CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* callSiteSig)
222 {
223     jitInstance->mc->cr->AddCall("pInvokeMarshalingRequired");
224     return jitInstance->mc->repPInvokeMarshalingRequired(method, callSiteSig);
225 }
226
227 // Check constraints on method type arguments (only).
228 // The parent class should be checked separately using satisfiesClassConstraints(parent).
229 BOOL MyICJI::satisfiesMethodConstraints(CORINFO_CLASS_HANDLE  parent, // the exact parent of the method
230                                         CORINFO_METHOD_HANDLE method)
231 {
232     jitInstance->mc->cr->AddCall("satisfiesMethodConstraints");
233     return jitInstance->mc->repSatisfiesMethodConstraints(parent, method);
234 }
235
236 // Given a delegate target class, a target method parent class,  a  target method,
237 // a delegate class, check if the method signature is compatible with the Invoke method of the delegate
238 // (under the typical instantiation of any free type variables in the memberref signatures).
239 BOOL MyICJI::isCompatibleDelegate(CORINFO_CLASS_HANDLE  objCls,          /* type of the delegate target, if any */
240                                   CORINFO_CLASS_HANDLE  methodParentCls, /* exact parent of the target method, if any */
241                                   CORINFO_METHOD_HANDLE method,          /* (representative) target method, if any */
242                                   CORINFO_CLASS_HANDLE  delegateCls,     /* exact type of the delegate */
243                                   BOOL*                 pfIsOpenDelegate /* is the delegate open */
244                                   )
245 {
246     jitInstance->mc->cr->AddCall("isCompatibleDelegate");
247     return jitInstance->mc->repIsCompatibleDelegate(objCls, methodParentCls, method, delegateCls, pfIsOpenDelegate);
248 }
249
250 // Indicates if the method is an instance of the generic
251 // method that passes (or has passed) verification
252 CorInfoInstantiationVerification MyICJI::isInstantiationOfVerifiedGeneric(CORINFO_METHOD_HANDLE method /* IN  */
253                                                                           )
254 {
255     jitInstance->mc->cr->AddCall("isInstantiationOfVerifiedGeneric");
256     return jitInstance->mc->repIsInstantiationOfVerifiedGeneric(method);
257 }
258
259 // Loads the constraints on a typical method definition, detecting cycles;
260 // for use in verification.
261 void MyICJI::initConstraintsForVerification(CORINFO_METHOD_HANDLE method,                        /* IN */
262                                             BOOL*                 pfHasCircularClassConstraints, /* OUT */
263                                             BOOL*                 pfHasCircularMethodConstraint  /* OUT */
264                                             )
265 {
266     jitInstance->mc->cr->AddCall("initConstraintsForVerification");
267     jitInstance->mc->repInitConstraintsForVerification(method, pfHasCircularClassConstraints,
268                                                        pfHasCircularMethodConstraint);
269 }
270
271 // Returns enum whether the method does not require verification
272 // Also see ICorModuleInfo::canSkipVerification
273 CorInfoCanSkipVerificationResult MyICJI::canSkipMethodVerification(CORINFO_METHOD_HANDLE ftnHandle)
274 {
275     jitInstance->mc->cr->AddCall("canSkipMethodVerification");
276     return jitInstance->mc->repCanSkipMethodVerification(ftnHandle, FALSE);
277 }
278
279 // load and restore the method
280 void MyICJI::methodMustBeLoadedBeforeCodeIsRun(CORINFO_METHOD_HANDLE method)
281 {
282     jitInstance->mc->cr->AddCall("methodMustBeLoadedBeforeCodeIsRun");
283     jitInstance->mc->cr->recMethodMustBeLoadedBeforeCodeIsRun(method);
284 }
285
286 CORINFO_METHOD_HANDLE MyICJI::mapMethodDeclToMethodImpl(CORINFO_METHOD_HANDLE method)
287 {
288     jitInstance->mc->cr->AddCall("mapMethodDeclToMethodImpl");
289     LogError("Hit unimplemented mapMethodDeclToMethodImpl");
290     DebugBreakorAV(17);
291     return 0;
292 }
293
294 // Returns the global cookie for the /GS unsafe buffer checks
295 // The cookie might be a constant value (JIT), or a handle to memory location (Ngen)
296 void MyICJI::getGSCookie(GSCookie*  pCookieVal, // OUT
297                          GSCookie** ppCookieVal // OUT
298                          )
299 {
300     jitInstance->mc->cr->AddCall("getGSCookie");
301     jitInstance->mc->repGetGSCookie(pCookieVal, ppCookieVal);
302 }
303
304 /**********************************************************************************/
305 //
306 // ICorModuleInfo
307 //
308 /**********************************************************************************/
309
310 // Resolve metadata token into runtime method handles.
311 void MyICJI::resolveToken(/* IN, OUT */ CORINFO_RESOLVED_TOKEN* pResolvedToken)
312 {
313     DWORD exceptionCode = 0;
314     jitInstance->mc->cr->AddCall("resolveToken");
315     jitInstance->mc->repResolveToken(pResolvedToken, &exceptionCode);
316     if (exceptionCode != 0)
317         ThrowException(exceptionCode);
318 }
319
320 // Resolve metadata token into runtime method handles.
321 bool MyICJI::tryResolveToken(/* IN, OUT */ CORINFO_RESOLVED_TOKEN* pResolvedToken)
322 {
323     jitInstance->mc->cr->AddCall("tryResolveToken");
324     return jitInstance->mc->repTryResolveToken(pResolvedToken);
325 }
326
327 // Signature information about the call sig
328 void MyICJI::findSig(CORINFO_MODULE_HANDLE  module,  /* IN */
329                      unsigned               sigTOK,  /* IN */
330                      CORINFO_CONTEXT_HANDLE context, /* IN */
331                      CORINFO_SIG_INFO*      sig      /* OUT */
332                      )
333 {
334     jitInstance->mc->cr->AddCall("findSig");
335     jitInstance->mc->repFindSig(module, sigTOK, context, sig);
336 }
337
338 // for Varargs, the signature at the call site may differ from
339 // the signature at the definition.  Thus we need a way of
340 // fetching the call site information
341 void MyICJI::findCallSiteSig(CORINFO_MODULE_HANDLE  module,  /* IN */
342                              unsigned               methTOK, /* IN */
343                              CORINFO_CONTEXT_HANDLE context, /* IN */
344                              CORINFO_SIG_INFO*      sig      /* OUT */
345                              )
346 {
347     jitInstance->mc->cr->AddCall("findCallSiteSig");
348     jitInstance->mc->repFindCallSiteSig(module, methTOK, context, sig);
349 }
350
351 CORINFO_CLASS_HANDLE MyICJI::getTokenTypeAsHandle(CORINFO_RESOLVED_TOKEN* pResolvedToken /* IN  */)
352 {
353     jitInstance->mc->cr->AddCall("getTokenTypeAsHandle");
354     return jitInstance->mc->repGetTokenTypeAsHandle(pResolvedToken);
355 }
356
357 // Returns true if the module does not require verification
358 //
359 // If fQuickCheckOnlyWithoutCommit=TRUE, the function only checks that the
360 // module does not currently require verification in the current AppDomain.
361 // This decision could change in the future, and so should not be cached.
362 // If it is cached, it should only be used as a hint.
363 // This is only used by ngen for calculating certain hints.
364 //
365
366 // Returns enum whether the module does not require verification
367 // Also see ICorMethodInfo::canSkipMethodVerification();
368 CorInfoCanSkipVerificationResult MyICJI::canSkipVerification(CORINFO_MODULE_HANDLE module /* IN  */
369                                                              )
370 {
371     jitInstance->mc->cr->AddCall("canSkipVerification");
372     LogError("Hit unimplemented canSkipVerification");
373     DebugBreakorAV(22);
374     return CORINFO_VERIFICATION_CANNOT_SKIP;
375 }
376
377 // Checks if the given metadata token is valid
378 BOOL MyICJI::isValidToken(CORINFO_MODULE_HANDLE module, /* IN  */
379                           unsigned              metaTOK /* IN  */
380                           )
381 {
382     jitInstance->mc->cr->AddCall("isValidToken");
383     return jitInstance->mc->repIsValidToken(module, metaTOK);
384 }
385
386 // Checks if the given metadata token is valid StringRef
387 BOOL MyICJI::isValidStringRef(CORINFO_MODULE_HANDLE module, /* IN  */
388                               unsigned              metaTOK /* IN  */
389                               )
390 {
391     jitInstance->mc->cr->AddCall("isValidStringRef");
392     return jitInstance->mc->repIsValidStringRef(module, metaTOK);
393 }
394
395 BOOL MyICJI::shouldEnforceCallvirtRestriction(CORINFO_MODULE_HANDLE scope)
396 {
397     jitInstance->mc->cr->AddCall("shouldEnforceCallvirtRestriction");
398     return jitInstance->mc->repShouldEnforceCallvirtRestriction(scope);
399 }
400
401 /**********************************************************************************/
402 //
403 // ICorClassInfo
404 //
405 /**********************************************************************************/
406
407 // If the value class 'cls' is isomorphic to a primitive type it will
408 // return that type, otherwise it will return CORINFO_TYPE_VALUECLASS
409 CorInfoType MyICJI::asCorInfoType(CORINFO_CLASS_HANDLE cls)
410 {
411     jitInstance->mc->cr->AddCall("asCorInfoType");
412     return jitInstance->mc->repAsCorInfoType(cls);
413 }
414
415 // for completeness
416 const char* MyICJI::getClassName(CORINFO_CLASS_HANDLE cls)
417 {
418     jitInstance->mc->cr->AddCall("getClassName");
419     const char* result = jitInstance->mc->repGetClassName(cls);
420     return result;
421 }
422
423 // Append a (possibly truncated) representation of the type cls to the preallocated buffer ppBuf of length pnBufLen
424 // If fNamespace=TRUE, include the namespace/enclosing classes
425 // If fFullInst=TRUE (regardless of fNamespace and fAssembly), include namespace and assembly for any type parameters
426 // If fAssembly=TRUE, suffix with a comma and the full assembly qualification
427 // return size of representation
428 int MyICJI::appendClassName(__deref_inout_ecount(*pnBufLen) WCHAR** ppBuf,
429                             int*                                    pnBufLen,
430                             CORINFO_CLASS_HANDLE                    cls,
431                             BOOL                                    fNamespace,
432                             BOOL                                    fFullInst,
433                             BOOL                                    fAssembly)
434 {
435     jitInstance->mc->cr->AddCall("appendClassName");
436     const WCHAR* result = jitInstance->mc->repAppendClassName(cls, fNamespace, fFullInst, fAssembly);
437     int          nLen   = 0;
438     if (ppBuf != nullptr && result != nullptr)
439     {
440         nLen = (int)wcslen(result);
441         if (*pnBufLen > nLen)
442         {
443             wcscpy_s(*ppBuf, *pnBufLen, result);
444             (*ppBuf) += nLen;
445             (*pnBufLen) -= nLen;
446         }
447     }
448     return nLen;
449 }
450
451 // Quick check whether the type is a value class. Returns the same value as getClassAttribs(cls) &
452 // CORINFO_FLG_VALUECLASS, except faster.
453 BOOL MyICJI::isValueClass(CORINFO_CLASS_HANDLE cls)
454 {
455     jitInstance->mc->cr->AddCall("isValueClass");
456     return jitInstance->mc->repIsValueClass(cls);
457 }
458
459 // If this method returns true, JIT will do optimization to inline the check for
460 //     GetTypeFromHandle(handle) == obj.GetType()
461 BOOL MyICJI::canInlineTypeCheckWithObjectVTable(CORINFO_CLASS_HANDLE cls)
462 {
463     jitInstance->mc->cr->AddCall("canInlineTypeCheckWithObjectVTable");
464     return jitInstance->mc->repCanInlineTypeCheckWithObjectVTable(cls);
465 }
466
467 // return flags (defined above, CORINFO_FLG_PUBLIC ...)
468 DWORD MyICJI::getClassAttribs(CORINFO_CLASS_HANDLE cls)
469 {
470     jitInstance->mc->cr->AddCall("getClassAttribs");
471     return jitInstance->mc->repGetClassAttribs(cls);
472 }
473
474 // Returns "TRUE" iff "cls" is a struct type such that return buffers used for returning a value
475 // of this type must be stack-allocated.  This will generally be true only if the struct
476 // contains GC pointers, and does not exceed some size limit.  Maintaining this as an invariant allows
477 // an optimization: the JIT may assume that return buffer pointers for return types for which this predicate
478 // returns TRUE are always stack allocated, and thus, that stores to the GC-pointer fields of such return
479 // buffers do not require GC write barriers.
480 BOOL MyICJI::isStructRequiringStackAllocRetBuf(CORINFO_CLASS_HANDLE cls)
481 {
482     jitInstance->mc->cr->AddCall("isStructRequiringStackAllocRetBuf");
483     return jitInstance->mc->repIsStructRequiringStackAllocRetBuf(cls);
484 }
485
486 CORINFO_MODULE_HANDLE MyICJI::getClassModule(CORINFO_CLASS_HANDLE cls)
487 {
488     jitInstance->mc->cr->AddCall("getClassModule");
489     LogError("Hit unimplemented getClassModule");
490     DebugBreakorAV(28);
491     return (CORINFO_MODULE_HANDLE)0;
492     // jitInstance->mc->getClassModule(cls);
493 }
494
495 // Returns the assembly that contains the module "mod".
496 CORINFO_ASSEMBLY_HANDLE MyICJI::getModuleAssembly(CORINFO_MODULE_HANDLE mod)
497 {
498     jitInstance->mc->cr->AddCall("getModuleAssembly");
499     LogError("Hit unimplemented getModuleAssembly");
500     DebugBreakorAV(28);
501     return (CORINFO_ASSEMBLY_HANDLE)0;
502
503     //  return jitInstance->mc->getModuleAssembly(mod);
504 }
505
506 // Returns the name of the assembly "assem".
507 const char* MyICJI::getAssemblyName(CORINFO_ASSEMBLY_HANDLE assem)
508 {
509     jitInstance->mc->cr->AddCall("getAssemblyName");
510     LogError("Hit unimplemented getAssemblyName");
511     DebugBreakorAV(28);
512     return nullptr;
513     //  return jitInstance->mc->getAssemblyName(assem);
514 }
515
516 // Allocate and delete process-lifetime objects.  Should only be
517 // referred to from static fields, lest a leak occur.
518 // Note that "LongLifetimeFree" does not execute destructors, if "obj"
519 // is an array of a struct type with a destructor.
520 void* MyICJI::LongLifetimeMalloc(size_t sz)
521 {
522     jitInstance->mc->cr->AddCall("LongLifetimeMalloc");
523     LogError("Hit unimplemented LongLifetimeMalloc");
524     DebugBreakorAV(32);
525     return 0;
526 }
527
528 void MyICJI::LongLifetimeFree(void* obj)
529 {
530     jitInstance->mc->cr->AddCall("LongLifetimeFree");
531     LogError("Hit unimplemented LongLifetimeFree");
532     DebugBreakorAV(33);
533 }
534
535 size_t MyICJI::getClassModuleIdForStatics(CORINFO_CLASS_HANDLE   cls,
536                                           CORINFO_MODULE_HANDLE* pModule,
537                                           void**                 ppIndirection)
538 {
539     jitInstance->mc->cr->AddCall("getClassModuleIdForStatics");
540     return jitInstance->mc->repGetClassModuleIdForStatics(cls, pModule, ppIndirection);
541 }
542
543 // return the number of bytes needed by an instance of the class
544 unsigned MyICJI::getClassSize(CORINFO_CLASS_HANDLE cls)
545 {
546     jitInstance->mc->cr->AddCall("getClassSize");
547     return jitInstance->mc->repGetClassSize(cls);
548 }
549
550 unsigned MyICJI::getClassAlignmentRequirement(CORINFO_CLASS_HANDLE cls, BOOL fDoubleAlignHint)
551 {
552     jitInstance->mc->cr->AddCall("getClassAlignmentRequirement");
553     return jitInstance->mc->repGetClassAlignmentRequirement(cls, fDoubleAlignHint);
554 }
555
556 // This is only called for Value classes.  It returns a boolean array
557 // in representing of 'cls' from a GC perspective.  The class is
558 // assumed to be an array of machine words
559 // (of length // getClassSize(cls) / sizeof(void*)),
560 // 'gcPtrs' is a pointer to an array of BYTEs of this length.
561 // getClassGClayout fills in this array so that gcPtrs[i] is set
562 // to one of the CorInfoGCType values which is the GC type of
563 // the i-th machine word of an object of type 'cls'
564 // returns the number of GC pointers in the array
565 unsigned MyICJI::getClassGClayout(CORINFO_CLASS_HANDLE cls,   /* IN */
566                                   BYTE*                gcPtrs /* OUT */
567                                   )
568 {
569     jitInstance->mc->cr->AddCall("getClassGClayout");
570     return jitInstance->mc->repGetClassGClayout(cls, gcPtrs);
571 }
572
573 // returns the number of instance fields in a class
574 unsigned MyICJI::getClassNumInstanceFields(CORINFO_CLASS_HANDLE cls /* IN */
575                                            )
576 {
577     jitInstance->mc->cr->AddCall("getClassNumInstanceFields");
578     return jitInstance->mc->repGetClassNumInstanceFields(cls);
579 }
580
581 CORINFO_FIELD_HANDLE MyICJI::getFieldInClass(CORINFO_CLASS_HANDLE clsHnd, INT num)
582 {
583     jitInstance->mc->cr->AddCall("getFieldInClass");
584     return jitInstance->mc->repGetFieldInClass(clsHnd, num);
585 }
586
587 BOOL MyICJI::checkMethodModifier(CORINFO_METHOD_HANDLE hMethod, LPCSTR modifier, BOOL fOptional)
588 {
589     jitInstance->mc->cr->AddCall("checkMethodModifier");
590     BOOL result = jitInstance->mc->repCheckMethodModifier(hMethod, modifier, fOptional);
591     return result;
592 }
593
594 // returns the "NEW" helper optimized for "newCls."
595 CorInfoHelpFunc MyICJI::getNewHelper(CORINFO_RESOLVED_TOKEN* pResolvedToken, CORINFO_METHOD_HANDLE callerHandle)
596 {
597     jitInstance->mc->cr->AddCall("getNewHelper");
598     return jitInstance->mc->repGetNewHelper(pResolvedToken, callerHandle);
599 }
600
601 // returns the newArr (1-Dim array) helper optimized for "arrayCls."
602 CorInfoHelpFunc MyICJI::getNewArrHelper(CORINFO_CLASS_HANDLE arrayCls)
603 {
604     jitInstance->mc->cr->AddCall("getNewArrHelper");
605     return jitInstance->mc->repGetNewArrHelper(arrayCls);
606 }
607
608 // returns the optimized "IsInstanceOf" or "ChkCast" helper
609 CorInfoHelpFunc MyICJI::getCastingHelper(CORINFO_RESOLVED_TOKEN* pResolvedToken, bool fThrowing)
610 {
611     jitInstance->mc->cr->AddCall("getCastingHelper");
612     return jitInstance->mc->repGetCastingHelper(pResolvedToken, fThrowing);
613 }
614
615 // returns helper to trigger static constructor
616 CorInfoHelpFunc MyICJI::getSharedCCtorHelper(CORINFO_CLASS_HANDLE clsHnd)
617 {
618     jitInstance->mc->cr->AddCall("getSharedCCtorHelper");
619     return jitInstance->mc->repGetSharedCCtorHelper(clsHnd);
620 }
621
622 CorInfoHelpFunc MyICJI::getSecurityPrologHelper(CORINFO_METHOD_HANDLE ftn)
623 {
624     jitInstance->mc->cr->AddCall("getSecurityPrologHelper");
625     return jitInstance->mc->repGetSecurityPrologHelper(ftn);
626 }
627
628 // This is not pretty.  Boxing nullable<T> actually returns
629 // a boxed<T> not a boxed Nullable<T>.  This call allows the verifier
630 // to call back to the EE on the 'box' instruction and get the transformed
631 // type to use for verification.
632 CORINFO_CLASS_HANDLE MyICJI::getTypeForBox(CORINFO_CLASS_HANDLE cls)
633 {
634     jitInstance->mc->cr->AddCall("getTypeForBox");
635     return jitInstance->mc->repGetTypeForBox(cls);
636 }
637
638 // returns the correct box helper for a particular class.  Note
639 // that if this returns CORINFO_HELP_BOX, the JIT can assume
640 // 'standard' boxing (allocate object and copy), and optimize
641 CorInfoHelpFunc MyICJI::getBoxHelper(CORINFO_CLASS_HANDLE cls)
642 {
643     jitInstance->mc->cr->AddCall("getBoxHelper");
644     return jitInstance->mc->repGetBoxHelper(cls);
645 }
646
647 // returns the unbox helper.  If 'helperCopies' points to a true
648 // value it means the JIT is requesting a helper that unboxes the
649 // value into a particular location and thus has the signature
650 //     void unboxHelper(void* dest, CORINFO_CLASS_HANDLE cls, Object* obj)
651 // Otherwise (it is null or points at a FALSE value) it is requesting
652 // a helper that returns a pointer to the unboxed data
653 //     void* unboxHelper(CORINFO_CLASS_HANDLE cls, Object* obj)
654 // The EE has the option of NOT returning the copy style helper
655 // (But must be able to always honor the non-copy style helper)
656 // The EE set 'helperCopies' on return to indicate what kind of
657 // helper has been created.
658
659 CorInfoHelpFunc MyICJI::getUnBoxHelper(CORINFO_CLASS_HANDLE cls)
660 {
661     jitInstance->mc->cr->AddCall("getUnBoxHelper");
662     CorInfoHelpFunc result = jitInstance->mc->repGetUnBoxHelper(cls);
663     return result;
664 }
665
666 bool MyICJI::getReadyToRunHelper(CORINFO_RESOLVED_TOKEN* pResolvedToken,
667                                  CORINFO_LOOKUP_KIND*    pGenericLookupKind,
668                                  CorInfoHelpFunc         id,
669                                  CORINFO_CONST_LOOKUP*   pLookup)
670 {
671     jitInstance->mc->cr->AddCall("getReadyToRunHelper");
672     return jitInstance->mc->repGetReadyToRunHelper(pResolvedToken, pGenericLookupKind, id, pLookup);
673 }
674
675 void MyICJI::getReadyToRunDelegateCtorHelper(CORINFO_RESOLVED_TOKEN* pTargetMethod,
676                                              CORINFO_CLASS_HANDLE    delegateType,
677                                              CORINFO_LOOKUP*         pLookup)
678 {
679     jitInstance->mc->cr->AddCall("getReadyToRunDelegateCtorHelper");
680     jitInstance->mc->repGetReadyToRunDelegateCtorHelper(pTargetMethod, delegateType, pLookup);
681 }
682
683 const char* MyICJI::getHelperName(CorInfoHelpFunc funcNum)
684 {
685     jitInstance->mc->cr->AddCall("getHelperName");
686     return jitInstance->mc->repGetHelperName(funcNum);
687 }
688
689 // This function tries to initialize the class (run the class constructor).
690 // this function returns whether the JIT must insert helper calls before
691 // accessing static field or method.
692 //
693 // See code:ICorClassInfo#ClassConstruction.
694 CorInfoInitClassResult MyICJI::initClass(CORINFO_FIELD_HANDLE field, // Non-nullptr - inquire about cctor trigger before
695                                                                      // static field access nullptr - inquire about
696                                                                      // cctor trigger in method prolog
697                                          CORINFO_METHOD_HANDLE  method,     // Method referencing the field or prolog
698                                          CORINFO_CONTEXT_HANDLE context,    // Exact context of method
699                                          BOOL                   speculative // TRUE means don't actually run it
700                                          )
701 {
702     jitInstance->mc->cr->AddCall("initClass");
703     return jitInstance->mc->repInitClass(field, method, context, speculative);
704 }
705
706 // This used to be called "loadClass".  This records the fact
707 // that the class must be loaded (including restored if necessary) before we execute the
708 // code that we are currently generating.  When jitting code
709 // the function loads the class immediately.  When zapping code
710 // the zapper will if necessary use the call to record the fact that we have
711 // to do a fixup/restore before running the method currently being generated.
712 //
713 // This is typically used to ensure value types are loaded before zapped
714 // code that manipulates them is executed, so that the GC can access information
715 // about those value types.
716 void MyICJI::classMustBeLoadedBeforeCodeIsRun(CORINFO_CLASS_HANDLE cls)
717 {
718     jitInstance->mc->cr->AddCall("classMustBeLoadedBeforeCodeIsRun");
719     jitInstance->mc->cr->recClassMustBeLoadedBeforeCodeIsRun(cls);
720 }
721
722 // returns the class handle for the special builtin classes
723 CORINFO_CLASS_HANDLE MyICJI::getBuiltinClass(CorInfoClassId classId)
724 {
725     jitInstance->mc->cr->AddCall("getBuiltinClass");
726     return jitInstance->mc->repGetBuiltinClass(classId);
727 }
728
729 // "System.Int32" ==> CORINFO_TYPE_INT..
730 CorInfoType MyICJI::getTypeForPrimitiveValueClass(CORINFO_CLASS_HANDLE cls)
731 {
732     jitInstance->mc->cr->AddCall("getTypeForPrimitiveValueClass");
733     return jitInstance->mc->repGetTypeForPrimitiveValueClass(cls);
734 }
735
736 // TRUE if child is a subtype of parent
737 // if parent is an interface, then does child implement / extend parent
738 BOOL MyICJI::canCast(CORINFO_CLASS_HANDLE child, // subtype (extends parent)
739                      CORINFO_CLASS_HANDLE parent // base type
740                      )
741 {
742     jitInstance->mc->cr->AddCall("canCast");
743     return jitInstance->mc->repCanCast(child, parent);
744 }
745
746 // TRUE if cls1 and cls2 are considered equivalent types.
747 BOOL MyICJI::areTypesEquivalent(CORINFO_CLASS_HANDLE cls1, CORINFO_CLASS_HANDLE cls2)
748 {
749     jitInstance->mc->cr->AddCall("areTypesEquivalent");
750     return jitInstance->mc->repAreTypesEquivalent(cls1, cls2);
751 }
752
753 // returns is the intersection of cls1 and cls2.
754 CORINFO_CLASS_HANDLE MyICJI::mergeClasses(CORINFO_CLASS_HANDLE cls1, CORINFO_CLASS_HANDLE cls2)
755 {
756     jitInstance->mc->cr->AddCall("mergeClasses");
757     return jitInstance->mc->repMergeClasses(cls1, cls2);
758 }
759
760 // Given a class handle, returns the Parent type.
761 // For COMObjectType, it returns Class Handle of System.Object.
762 // Returns 0 if System.Object is passed in.
763 CORINFO_CLASS_HANDLE MyICJI::getParentType(CORINFO_CLASS_HANDLE cls)
764 {
765     jitInstance->mc->cr->AddCall("getParentType");
766     return jitInstance->mc->repGetParentType(cls);
767 }
768
769 // Returns the CorInfoType of the "child type". If the child type is
770 // not a primitive type, *clsRet will be set.
771 // Given an Array of Type Foo, returns Foo.
772 // Given BYREF Foo, returns Foo
773 CorInfoType MyICJI::getChildType(CORINFO_CLASS_HANDLE clsHnd, CORINFO_CLASS_HANDLE* clsRet)
774 {
775     jitInstance->mc->cr->AddCall("getChildType");
776     return jitInstance->mc->repGetChildType(clsHnd, clsRet);
777 }
778
779 // Check constraints on type arguments of this class and parent classes
780 BOOL MyICJI::satisfiesClassConstraints(CORINFO_CLASS_HANDLE cls)
781 {
782     jitInstance->mc->cr->AddCall("satisfiesClassConstraints");
783     return jitInstance->mc->repSatisfiesClassConstraints(cls);
784 }
785
786 // Check if this is a single dimensional array type
787 BOOL MyICJI::isSDArray(CORINFO_CLASS_HANDLE cls)
788 {
789     jitInstance->mc->cr->AddCall("isSDArray");
790     return jitInstance->mc->repIsSDArray(cls);
791 }
792
793 // Get the numbmer of dimensions in an array
794 unsigned MyICJI::getArrayRank(CORINFO_CLASS_HANDLE cls)
795 {
796     jitInstance->mc->cr->AddCall("getArrayRank");
797     return jitInstance->mc->repGetArrayRank(cls);
798 }
799
800 // Get static field data for an array
801 void* MyICJI::getArrayInitializationData(CORINFO_FIELD_HANDLE field, DWORD size)
802 {
803     jitInstance->mc->cr->AddCall("getArrayInitializationData");
804     return jitInstance->mc->repGetArrayInitializationData(field, size);
805 }
806
807 // Check Visibility rules.
808 CorInfoIsAccessAllowedResult MyICJI::canAccessClass(CORINFO_RESOLVED_TOKEN* pResolvedToken,
809                                                     CORINFO_METHOD_HANDLE   callerHandle,
810                                                     CORINFO_HELPER_DESC*    pAccessHelper /* If canAccessMethod returns
811                                                                                              something other    than ALLOWED,
812                                                                                              then this is filled in. */
813                                                     )
814 {
815     jitInstance->mc->cr->AddCall("canAccessClass");
816     return jitInstance->mc->repCanAccessClass(pResolvedToken, callerHandle, pAccessHelper);
817 }
818
819 /**********************************************************************************/
820 //
821 // ICorFieldInfo
822 //
823 /**********************************************************************************/
824
825 // this function is for debugging only.  It returns the field name
826 // and if 'moduleName' is non-null, it sets it to something that will
827 // says which method (a class name, or a module name)
828 const char* MyICJI::getFieldName(CORINFO_FIELD_HANDLE ftn,       /* IN */
829                                  const char**         moduleName /* OUT */
830                                  )
831 {
832     jitInstance->mc->cr->AddCall("getFieldName");
833     return jitInstance->mc->repGetFieldName(ftn, moduleName);
834 }
835
836 // return class it belongs to
837 CORINFO_CLASS_HANDLE MyICJI::getFieldClass(CORINFO_FIELD_HANDLE field)
838 {
839     jitInstance->mc->cr->AddCall("getFieldClass");
840     return jitInstance->mc->repGetFieldClass(field);
841 }
842
843 // Return the field's type, if it is CORINFO_TYPE_VALUECLASS 'structType' is set
844 // the field's value class (if 'structType' == 0, then don't bother
845 // the structure info).
846 //
847 // 'memberParent' is typically only set when verifying.  It should be the
848 // result of calling getMemberParent.
849 CorInfoType MyICJI::getFieldType(CORINFO_FIELD_HANDLE  field,
850                                  CORINFO_CLASS_HANDLE* structType,
851                                  CORINFO_CLASS_HANDLE  memberParent /* IN */
852                                  )
853 {
854     jitInstance->mc->cr->AddCall("getFieldType");
855     return jitInstance->mc->repGetFieldType(field, structType, memberParent);
856 }
857
858 // return the data member's instance offset
859 unsigned MyICJI::getFieldOffset(CORINFO_FIELD_HANDLE field)
860 {
861     jitInstance->mc->cr->AddCall("getFieldOffset");
862     return jitInstance->mc->repGetFieldOffset(field);
863 }
864
865 // TODO: jit64 should be switched to the same plan as the i386 jits - use
866 // getClassGClayout to figure out the need for writebarrier helper, and inline the copying.
867 // The interpretted value class copy is slow. Once this happens, USE_WRITE_BARRIER_HELPERS
868 bool MyICJI::isWriteBarrierHelperRequired(CORINFO_FIELD_HANDLE field)
869 {
870     jitInstance->mc->cr->AddCall("isWriteBarrierHelperRequired");
871     bool result = jitInstance->mc->repIsWriteBarrierHelperRequired(field);
872     return result;
873 }
874
875 void MyICJI::getFieldInfo(CORINFO_RESOLVED_TOKEN* pResolvedToken,
876                           CORINFO_METHOD_HANDLE   callerHandle,
877                           CORINFO_ACCESS_FLAGS    flags,
878                           CORINFO_FIELD_INFO*     pResult)
879 {
880     jitInstance->mc->cr->AddCall("getFieldInfo");
881     jitInstance->mc->repGetFieldInfo(pResolvedToken, callerHandle, flags, pResult);
882 }
883
884 // Returns true iff "fldHnd" represents a static field.
885 bool MyICJI::isFieldStatic(CORINFO_FIELD_HANDLE fldHnd)
886 {
887     jitInstance->mc->cr->AddCall("isFieldStatic");
888     return jitInstance->mc->repIsFieldStatic(fldHnd);
889 }
890
891 /*********************************************************************************/
892 //
893 // ICorDebugInfo
894 //
895 /*********************************************************************************/
896
897 // Query the EE to find out where interesting break points
898 // in the code are.  The native compiler will ensure that these places
899 // have a corresponding break point in native code.
900 //
901 // Note that unless CORJIT_FLAG_DEBUG_CODE is specified, this function will
902 // be used only as a hint and the native compiler should not change its
903 // code generation.
904 void MyICJI::getBoundaries(CORINFO_METHOD_HANDLE ftn,                      // [IN] method of interest
905                            unsigned int*         cILOffsets,               // [OUT] size of pILOffsets
906                            DWORD**               pILOffsets,               // [OUT] IL offsets of interest
907                                                                            //       jit MUST free with freeArray!
908                            ICorDebugInfo::BoundaryTypes* implictBoundaries // [OUT] tell jit, all boundries of this type
909                            )
910 {
911     jitInstance->mc->cr->AddCall("getBoundaries");
912     jitInstance->mc->repGetBoundaries(ftn, cILOffsets, pILOffsets, implictBoundaries);
913
914     // The JIT will want to call freearray on the array we pass back, so move the data into a form that complies with
915     // this
916     if (*cILOffsets > 0)
917     {
918         DWORD* realOffsets = (DWORD*)allocateArray(*cILOffsets * sizeof(ICorDebugInfo::BoundaryTypes));
919         memcpy(realOffsets, *pILOffsets, *cILOffsets * sizeof(ICorDebugInfo::BoundaryTypes));
920         *pILOffsets = realOffsets;
921     }
922     else
923         *pILOffsets = 0;
924 }
925
926 // Report back the mapping from IL to native code,
927 // this map should include all boundaries that 'getBoundaries'
928 // reported as interesting to the debugger.
929
930 // Note that debugger (and profiler) is assuming that all of the
931 // offsets form a contiguous block of memory, and that the
932 // OffsetMapping is sorted in order of increasing native offset.
933 void MyICJI::setBoundaries(CORINFO_METHOD_HANDLE         ftn,  // [IN] method of interest
934                            ULONG32                       cMap, // [IN] size of pMap
935                            ICorDebugInfo::OffsetMapping* pMap  // [IN] map including all points of interest.
936                                                                //      jit allocated with allocateArray, EE frees
937                            )
938 {
939     jitInstance->mc->cr->AddCall("setBoundaries");
940     jitInstance->mc->cr->recSetBoundaries(ftn, cMap, pMap);
941
942     freeArray(pMap); // see note in recSetBoundaries... we own this array and own destroying it.
943 }
944
945 // Query the EE to find out the scope of local varables.
946 // normally the JIT would trash variables after last use, but
947 // under debugging, the JIT needs to keep them live over their
948 // entire scope so that they can be inspected.
949 //
950 // Note that unless CORJIT_FLAG_DEBUG_CODE is specified, this function will
951 // be used only as a hint and the native compiler should not change its
952 // code generation.
953 void MyICJI::getVars(CORINFO_METHOD_HANDLE      ftn,   // [IN]  method of interest
954                      ULONG32*                   cVars, // [OUT] size of 'vars'
955                      ICorDebugInfo::ILVarInfo** vars,  // [OUT] scopes of variables of interest
956                                                        //       jit MUST free with freeArray!
957                      bool* extendOthers                // [OUT] it TRUE, then assume the scope
958                                                        //       of unmentioned vars is entire method
959                      )
960 {
961     jitInstance->mc->cr->AddCall("getVars");
962     jitInstance->mc->repGetVars(ftn, cVars, vars, extendOthers);
963
964     // The JIT will want to call freearray on the array we pass back, so move the data into a form that complies with
965     // this
966     if (*cVars > 0)
967     {
968         ICorDebugInfo::ILVarInfo* realOffsets =
969             (ICorDebugInfo::ILVarInfo*)allocateArray(*cVars * sizeof(ICorDebugInfo::ILVarInfo));
970         memcpy(realOffsets, *vars, *cVars * sizeof(ICorDebugInfo::ILVarInfo));
971         *vars = realOffsets;
972     }
973     else
974         *vars = nullptr;
975 }
976
977 // Report back to the EE the location of every variable.
978 // note that the JIT might split lifetimes into different
979 // locations etc.
980
981 void MyICJI::setVars(CORINFO_METHOD_HANDLE         ftn,   // [IN] method of interest
982                      ULONG32                       cVars, // [IN] size of 'vars'
983                      ICorDebugInfo::NativeVarInfo* vars   // [IN] map telling where local vars are stored at what points
984                                                         //      jit allocated with allocateArray, EE frees
985                      )
986 {
987     jitInstance->mc->cr->AddCall("setVars");
988     jitInstance->mc->cr->recSetVars(ftn, cVars, vars);
989     freeArray(vars); // See note in recSetVars... we own destroying this array
990 }
991
992 /*-------------------------- Misc ---------------------------------------*/
993
994 // Used to allocate memory that needs to handed to the EE.
995 // For eg, use this to allocated memory for reporting debug info,
996 // which will be handed to the EE by setVars() and setBoundaries()
997 void* MyICJI::allocateArray(ULONG cBytes)
998 {
999     return jitInstance->allocateArray(cBytes);
1000 }
1001
1002 // JitCompiler will free arrays passed by the EE using this
1003 // For eg, The EE returns memory in getVars() and getBoundaries()
1004 // to the JitCompiler, which the JitCompiler should release using
1005 // freeArray()
1006 void MyICJI::freeArray(void* array)
1007 {
1008     jitInstance->freeArray(array);
1009 }
1010
1011 /*********************************************************************************/
1012 //
1013 // ICorArgInfo
1014 //
1015 /*********************************************************************************/
1016
1017 // advance the pointer to the argument list.
1018 // a ptr of 0, is special and always means the first argument
1019 CORINFO_ARG_LIST_HANDLE MyICJI::getArgNext(CORINFO_ARG_LIST_HANDLE args /* IN */
1020                                            )
1021 {
1022     jitInstance->mc->cr->AddCall("getArgNext");
1023     return jitInstance->mc->repGetArgNext(args);
1024 }
1025
1026 // Get the type of a particular argument
1027 // CORINFO_TYPE_UNDEF is returned when there are no more arguments
1028 // If the type returned is a primitive type (or an enum) *vcTypeRet set to nullptr
1029 // otherwise it is set to the TypeHandle associted with the type
1030 // Enumerations will always look their underlying type (probably should fix this)
1031 // Otherwise vcTypeRet is the type as would be seen by the IL,
1032 // The return value is the type that is used for calling convention purposes
1033 // (Thus if the EE wants a value class to be passed like an int, then it will
1034 // return CORINFO_TYPE_INT
1035 CorInfoTypeWithMod MyICJI::getArgType(CORINFO_SIG_INFO*       sig,      /* IN */
1036                                       CORINFO_ARG_LIST_HANDLE args,     /* IN */
1037                                       CORINFO_CLASS_HANDLE*   vcTypeRet /* OUT */
1038                                       )
1039 {
1040     DWORD exceptionCode = 0;
1041     jitInstance->mc->cr->AddCall("getArgType");
1042     CorInfoTypeWithMod value = jitInstance->mc->repGetArgType(sig, args, vcTypeRet, &exceptionCode);
1043     if (exceptionCode != 0)
1044         ThrowException(exceptionCode);
1045     return value;
1046 }
1047
1048 // If the Arg is a CORINFO_TYPE_CLASS fetch the class handle associated with it
1049 CORINFO_CLASS_HANDLE MyICJI::getArgClass(CORINFO_SIG_INFO*       sig, /* IN */
1050                                          CORINFO_ARG_LIST_HANDLE args /* IN */
1051                                          )
1052 {
1053     DWORD exceptionCode = 0;
1054     jitInstance->mc->cr->AddCall("getArgClass");
1055     CORINFO_CLASS_HANDLE value = jitInstance->mc->repGetArgClass(sig, args, &exceptionCode);
1056     if (exceptionCode != 0)
1057         ThrowException(exceptionCode);
1058     return value;
1059 }
1060
1061 // Returns type of HFA for valuetype
1062 CorInfoType MyICJI::getHFAType(CORINFO_CLASS_HANDLE hClass)
1063 {
1064     jitInstance->mc->cr->AddCall("getHFAType");
1065     CorInfoType value = jitInstance->mc->repGetHFAType(hClass);
1066     return value;
1067 }
1068
1069 /*****************************************************************************
1070 * ICorErrorInfo contains methods to deal with SEH exceptions being thrown
1071 * from the corinfo interface.  These methods may be called when an exception
1072 * with code EXCEPTION_COMPLUS is caught.
1073 *****************************************************************************/
1074
1075 // Returns the HRESULT of the current exception
1076 HRESULT MyICJI::GetErrorHRESULT(struct _EXCEPTION_POINTERS* pExceptionPointers)
1077 {
1078     jitInstance->mc->cr->AddCall("GetErrorHRESULT");
1079     LogError("Hit unimplemented GetErrorHRESULT");
1080     DebugBreakorAV(76);
1081     return 0;
1082 }
1083
1084 // Fetches the message of the current exception
1085 // Returns the size of the message (including terminating null). This can be
1086 // greater than bufferLength if the buffer is insufficient.
1087 ULONG MyICJI::GetErrorMessage(__inout_ecount(bufferLength) LPWSTR buffer, ULONG bufferLength)
1088 {
1089     jitInstance->mc->cr->AddCall("GetErrorMessage");
1090     LogError("Hit unimplemented GetErrorMessage");
1091     DebugBreakorAV(77);
1092     return 0;
1093 }
1094
1095 // returns EXCEPTION_EXECUTE_HANDLER if it is OK for the compile to handle the
1096 //                        exception, abort some work (like the inlining) and continue compilation
1097 // returns EXCEPTION_CONTINUE_SEARCH if exception must always be handled by the EE
1098 //                    things like ThreadStoppedException ...
1099 // returns EXCEPTION_CONTINUE_EXECUTION if exception is fixed up by the EE
1100
1101 int MyICJI::FilterException(struct _EXCEPTION_POINTERS* pExceptionPointers)
1102 {
1103     jitInstance->mc->cr->AddCall("FilterException");
1104     int result = jitInstance->mc->repFilterException(pExceptionPointers);
1105     return result;
1106 }
1107
1108 // Cleans up internal EE tracking when an exception is caught.
1109 void MyICJI::HandleException(struct _EXCEPTION_POINTERS* pExceptionPointers)
1110 {
1111     jitInstance->mc->cr->AddCall("HandleException");
1112 }
1113
1114 void MyICJI::ThrowExceptionForJitResult(HRESULT result)
1115 {
1116     jitInstance->mc->cr->AddCall("ThrowExceptionForJitResult");
1117     LogError("Hit unimplemented ThrowExceptionForJitResult");
1118     DebugBreakorAV(80);
1119 }
1120
1121 // Throws an exception defined by the given throw helper.
1122 void MyICJI::ThrowExceptionForHelper(const CORINFO_HELPER_DESC* throwHelper)
1123 {
1124     jitInstance->mc->cr->AddCall("ThrowExceptionForHelper");
1125     LogError("Hit unimplemented ThrowExceptionForHelper");
1126     DebugBreakorAV(81);
1127 }
1128
1129 /*****************************************************************************
1130  * ICorStaticInfo contains EE interface methods which return values that are
1131  * constant from invocation to invocation.  Thus they may be embedded in
1132  * persisted information like statically generated code. (This is of course
1133  * assuming that all code versions are identical each time.)
1134  *****************************************************************************/
1135
1136 // Return details about EE internal data structures
1137 void MyICJI::getEEInfo(CORINFO_EE_INFO* pEEInfoOut)
1138 {
1139     jitInstance->mc->cr->AddCall("getEEInfo");
1140     jitInstance->mc->repGetEEInfo(pEEInfoOut);
1141 }
1142
1143 // Returns name of the JIT timer log
1144 LPCWSTR MyICJI::getJitTimeLogFilename()
1145 {
1146     jitInstance->mc->cr->AddCall("getJitTimeLogFilename");
1147     // we have the ability to replay this, but we treat it in this case as EE context
1148     //  return jitInstance->eec->jitTimeLogFilename;
1149
1150     // We want to be able to set COMPLUS_JitTimeLogFile when replaying, to collect JIT
1151     // statistics. So, just do a getenv() call. This isn't quite as thorough as
1152     // the normal CLR config value functions (which also check the registry), and we've
1153     // also hard-coded the variable name here instead of using:
1154     //      CLRConfig::GetConfigValue(CLRConfig::INTERNAL_JitTimeLogFile);
1155     // like in the VM, but it works for our purposes.
1156     return GetEnvironmentVariableWithDefaultW(W("COMPlus_JitTimeLogFile"));
1157 }
1158
1159 /*********************************************************************************/
1160 //
1161 // Diagnostic methods
1162 //
1163 /*********************************************************************************/
1164
1165 // this function is for debugging only. Returns method token.
1166 // Returns mdMethodDefNil for dynamic methods.
1167 mdMethodDef MyICJI::getMethodDefFromMethod(CORINFO_METHOD_HANDLE hMethod)
1168 {
1169     jitInstance->mc->cr->AddCall("getMethodDefFromMethod");
1170     mdMethodDef result = jitInstance->mc->repGetMethodDefFromMethod(hMethod);
1171     return result;
1172 }
1173
1174 // this function is for debugging only.  It returns the method name
1175 // and if 'moduleName' is non-null, it sets it to something that will
1176 // says which method (a class name, or a module name)
1177 const char* MyICJI::getMethodName(CORINFO_METHOD_HANDLE ftn,       /* IN */
1178                                   const char**          moduleName /* OUT */
1179                                   )
1180 {
1181     jitInstance->mc->cr->AddCall("getMethodName");
1182     return jitInstance->mc->repGetMethodName(ftn, moduleName);
1183 }
1184
1185 // this function is for debugging only.  It returns a value that
1186 // is will always be the same for a given method.  It is used
1187 // to implement the 'jitRange' functionality
1188 unsigned MyICJI::getMethodHash(CORINFO_METHOD_HANDLE ftn /* IN */
1189                                )
1190 {
1191     jitInstance->mc->cr->AddCall("getMethodHash");
1192     return jitInstance->mc->repGetMethodHash(ftn);
1193 }
1194
1195 // this function is for debugging only.
1196 size_t MyICJI::findNameOfToken(CORINFO_MODULE_HANDLE              module,        /* IN  */
1197                                mdToken                            metaTOK,       /* IN  */
1198                                __out_ecount(FQNameCapacity) char* szFQName,      /* OUT */
1199                                size_t                             FQNameCapacity /* IN */
1200                                )
1201 {
1202     jitInstance->mc->cr->AddCall("findNameOfToken");
1203     return jitInstance->mc->repFindNameOfToken(module, metaTOK, szFQName, FQNameCapacity);
1204 }
1205
1206 bool MyICJI::getSystemVAmd64PassStructInRegisterDescriptor(
1207     /* IN */ CORINFO_CLASS_HANDLE                                  structHnd,
1208     /* OUT */ SYSTEMV_AMD64_CORINFO_STRUCT_REG_PASSING_DESCRIPTOR* structPassInRegDescPtr)
1209 {
1210     jitInstance->mc->cr->AddCall("getSystemVAmd64PassStructInRegisterDescriptor");
1211     return jitInstance->mc->repGetSystemVAmd64PassStructInRegisterDescriptor(structHnd, structPassInRegDescPtr);
1212 }
1213
1214 // Stuff on ICorDynamicInfo
1215 DWORD MyICJI::getThreadTLSIndex(void** ppIndirection)
1216 {
1217     jitInstance->mc->cr->AddCall("getThreadTLSIndex");
1218     return jitInstance->mc->repGetThreadTLSIndex(ppIndirection);
1219 }
1220
1221 const void* MyICJI::getInlinedCallFrameVptr(void** ppIndirection)
1222 {
1223     jitInstance->mc->cr->AddCall("getInlinedCallFrameVptr");
1224     return jitInstance->mc->repGetInlinedCallFrameVptr(ppIndirection);
1225 }
1226
1227 LONG* MyICJI::getAddrOfCaptureThreadGlobal(void** ppIndirection)
1228 {
1229     jitInstance->mc->cr->AddCall("getAddrOfCaptureThreadGlobal");
1230     return jitInstance->mc->repGetAddrOfCaptureThreadGlobal(ppIndirection);
1231 }
1232
1233 // return the native entry point to an EE helper (see CorInfoHelpFunc)
1234 void* MyICJI::getHelperFtn(CorInfoHelpFunc ftnNum, void** ppIndirection)
1235 {
1236     jitInstance->mc->cr->AddCall("getHelperFtn");
1237     return jitInstance->mc->repGetHelperFtn(ftnNum, ppIndirection);
1238 }
1239
1240 // return a callable address of the function (native code). This function
1241 // may return a different value (depending on whether the method has
1242 // been JITed or not.
1243 void MyICJI::getFunctionEntryPoint(CORINFO_METHOD_HANDLE ftn,     /* IN  */
1244                                    CORINFO_CONST_LOOKUP* pResult, /* OUT */
1245                                    CORINFO_ACCESS_FLAGS  accessFlags)
1246 {
1247     jitInstance->mc->cr->AddCall("getFunctionEntryPoint");
1248     jitInstance->mc->repGetFunctionEntryPoint(ftn, pResult, accessFlags);
1249 }
1250
1251 // return a directly callable address. This can be used similarly to the
1252 // value returned by getFunctionEntryPoint() except that it is
1253 // guaranteed to be multi callable entrypoint.
1254 void MyICJI::getFunctionFixedEntryPoint(CORINFO_METHOD_HANDLE ftn, CORINFO_CONST_LOOKUP* pResult)
1255 {
1256     jitInstance->mc->cr->AddCall("getFunctionFixedEntryPoint");
1257     jitInstance->mc->repGetFunctionFixedEntryPoint(ftn, pResult);
1258 }
1259
1260 // get the synchronization handle that is passed to monXstatic function
1261 void* MyICJI::getMethodSync(CORINFO_METHOD_HANDLE ftn, void** ppIndirection)
1262 {
1263     jitInstance->mc->cr->AddCall("getMethodSync");
1264     return jitInstance->mc->repGetMethodSync(ftn, ppIndirection);
1265 }
1266
1267 // These entry points must be called if a handle is being embedded in
1268 // the code to be passed to a JIT helper function. (as opposed to just
1269 // being passed back into the ICorInfo interface.)
1270
1271 // get slow lazy string literal helper to use (CORINFO_HELP_STRCNS*).
1272 // Returns CORINFO_HELP_UNDEF if lazy string literal helper cannot be used.
1273 CorInfoHelpFunc MyICJI::getLazyStringLiteralHelper(CORINFO_MODULE_HANDLE handle)
1274 {
1275     jitInstance->mc->cr->AddCall("getLazyStringLiteralHelper");
1276     return jitInstance->mc->repGetLazyStringLiteralHelper(handle);
1277 }
1278
1279 CORINFO_MODULE_HANDLE MyICJI::embedModuleHandle(CORINFO_MODULE_HANDLE handle, void** ppIndirection)
1280 {
1281     jitInstance->mc->cr->AddCall("embedModuleHandle");
1282     return jitInstance->mc->repEmbedModuleHandle(handle, ppIndirection);
1283 }
1284
1285 CORINFO_CLASS_HANDLE MyICJI::embedClassHandle(CORINFO_CLASS_HANDLE handle, void** ppIndirection)
1286 {
1287     jitInstance->mc->cr->AddCall("embedClassHandle");
1288     return jitInstance->mc->repEmbedClassHandle(handle, ppIndirection);
1289 }
1290
1291 CORINFO_METHOD_HANDLE MyICJI::embedMethodHandle(CORINFO_METHOD_HANDLE handle, void** ppIndirection)
1292 {
1293     jitInstance->mc->cr->AddCall("embedMethodHandle");
1294     return jitInstance->mc->repEmbedMethodHandle(handle, ppIndirection);
1295 }
1296
1297 CORINFO_FIELD_HANDLE MyICJI::embedFieldHandle(CORINFO_FIELD_HANDLE handle, void** ppIndirection)
1298 {
1299     jitInstance->mc->cr->AddCall("embedFieldHandle");
1300     return jitInstance->mc->repEmbedFieldHandle(handle, ppIndirection);
1301 }
1302
1303 // Given a module scope (module), a method handle (context) and
1304 // a metadata token (metaTOK), fetch the handle
1305 // (type, field or method) associated with the token.
1306 // If this is not possible at compile-time (because the current method's
1307 // code is shared and the token contains generic parameters)
1308 // then indicate how the handle should be looked up at run-time.
1309 //
1310 void MyICJI::embedGenericHandle(CORINFO_RESOLVED_TOKEN* pResolvedToken,
1311                                 BOOL fEmbedParent, // TRUE - embeds parent type handle of the field/method handle
1312                                 CORINFO_GENERICHANDLE_RESULT* pResult)
1313 {
1314     jitInstance->mc->cr->AddCall("embedGenericHandle");
1315     jitInstance->mc->repEmbedGenericHandle(pResolvedToken, fEmbedParent, pResult);
1316 }
1317
1318 // Return information used to locate the exact enclosing type of the current method.
1319 // Used only to invoke .cctor method from code shared across generic instantiations
1320 //   !needsRuntimeLookup       statically known (enclosing type of method itself)
1321 //   needsRuntimeLookup:
1322 //      CORINFO_LOOKUP_THISOBJ     use vtable pointer of 'this' param
1323 //      CORINFO_LOOKUP_CLASSPARAM  use vtable hidden param
1324 //      CORINFO_LOOKUP_METHODPARAM use enclosing type of method-desc hidden param
1325 CORINFO_LOOKUP_KIND MyICJI::getLocationOfThisType(CORINFO_METHOD_HANDLE context)
1326 {
1327     jitInstance->mc->cr->AddCall("getLocationOfThisType");
1328     return jitInstance->mc->repGetLocationOfThisType(context);
1329 }
1330
1331 // return the unmanaged target *if method has already been prelinked.*
1332 void* MyICJI::getPInvokeUnmanagedTarget(CORINFO_METHOD_HANDLE method, void** ppIndirection)
1333 {
1334     jitInstance->mc->cr->AddCall("getPInvokeUnmanagedTarget");
1335     void* result = jitInstance->mc->repGetPInvokeUnmanagedTarget(method, ppIndirection);
1336     return result;
1337 }
1338
1339 // return address of fixup area for late-bound PInvoke calls.
1340 void* MyICJI::getAddressOfPInvokeFixup(CORINFO_METHOD_HANDLE method, void** ppIndirection)
1341 {
1342     jitInstance->mc->cr->AddCall("getAddressOfPInvokeFixup");
1343     return jitInstance->mc->repGetAddressOfPInvokeFixup(method, ppIndirection);
1344 }
1345
1346 // return address of fixup area for late-bound PInvoke calls.
1347 void MyICJI::getAddressOfPInvokeTarget(CORINFO_METHOD_HANDLE method, CORINFO_CONST_LOOKUP* pLookup)
1348 {
1349     jitInstance->mc->cr->AddCall("getAddressOfPInvokeTarget");
1350     jitInstance->mc->repGetAddressOfPInvokeTarget(method, pLookup);
1351 }
1352
1353 // Generate a cookie based on the signature that would needs to be passed
1354 // to CORINFO_HELP_PINVOKE_CALLI
1355 LPVOID MyICJI::GetCookieForPInvokeCalliSig(CORINFO_SIG_INFO* szMetaSig, void** ppIndirection)
1356 {
1357     jitInstance->mc->cr->AddCall("GetCookieForPInvokeCalliSig");
1358     return jitInstance->mc->repGetCookieForPInvokeCalliSig(szMetaSig, ppIndirection);
1359 }
1360
1361 // returns true if a VM cookie can be generated for it (might be false due to cross-module
1362 // inlining, in which case the inlining should be aborted)
1363 bool MyICJI::canGetCookieForPInvokeCalliSig(CORINFO_SIG_INFO* szMetaSig)
1364 {
1365     jitInstance->mc->cr->AddCall("canGetCookieForPInvokeCalliSig");
1366     return jitInstance->mc->repCanGetCookieForPInvokeCalliSig(szMetaSig);
1367 }
1368
1369 // Gets a handle that is checked to see if the current method is
1370 // included in "JustMyCode"
1371 CORINFO_JUST_MY_CODE_HANDLE MyICJI::getJustMyCodeHandle(CORINFO_METHOD_HANDLE         method,
1372                                                         CORINFO_JUST_MY_CODE_HANDLE** ppIndirection)
1373 {
1374     jitInstance->mc->cr->AddCall("getJustMyCodeHandle");
1375     return jitInstance->mc->repGetJustMyCodeHandle(method, ppIndirection);
1376 }
1377
1378 // Gets a method handle that can be used to correlate profiling data.
1379 // This is the IP of a native method, or the address of the descriptor struct
1380 // for IL.  Always guaranteed to be unique per process, and not to move. */
1381 void MyICJI::GetProfilingHandle(BOOL* pbHookFunction, void** pProfilerHandle, BOOL* pbIndirectedHandles)
1382 {
1383     jitInstance->mc->cr->AddCall("GetProfilingHandle");
1384     jitInstance->mc->repGetProfilingHandle(pbHookFunction, pProfilerHandle, pbIndirectedHandles);
1385 }
1386
1387 // Returns instructions on how to make the call. See code:CORINFO_CALL_INFO for possible return values.
1388 void MyICJI::getCallInfo(
1389     // Token info
1390     CORINFO_RESOLVED_TOKEN* pResolvedToken,
1391
1392     // Generics info
1393     CORINFO_RESOLVED_TOKEN* pConstrainedResolvedToken,
1394
1395     // Security info
1396     CORINFO_METHOD_HANDLE callerHandle,
1397
1398     // Jit info
1399     CORINFO_CALLINFO_FLAGS flags,
1400
1401     // out params
1402     CORINFO_CALL_INFO* pResult)
1403 {
1404     jitInstance->mc->cr->AddCall("getCallInfo");
1405     DWORD exceptionCode = 0;
1406     jitInstance->mc->repGetCallInfo(pResolvedToken, pConstrainedResolvedToken, callerHandle, flags, pResult,
1407                                     &exceptionCode);
1408     if (exceptionCode != 0)
1409         ThrowException(exceptionCode);
1410 }
1411
1412 BOOL MyICJI::canAccessFamily(CORINFO_METHOD_HANDLE hCaller, CORINFO_CLASS_HANDLE hInstanceType)
1413
1414 {
1415     jitInstance->mc->cr->AddCall("canAccessFamily");
1416     return jitInstance->mc->repCanAccessFamily(hCaller, hInstanceType);
1417 }
1418 // Returns TRUE if the Class Domain ID is the RID of the class (currently true for every class
1419 // except reflection emitted classes and generics)
1420 BOOL MyICJI::isRIDClassDomainID(CORINFO_CLASS_HANDLE cls)
1421 {
1422     jitInstance->mc->cr->AddCall("isRIDClassDomainID");
1423     LogError("Hit unimplemented isRIDClassDomainID");
1424     DebugBreakorAV(107);
1425     return false;
1426 }
1427
1428 // returns the class's domain ID for accessing shared statics
1429 unsigned MyICJI::getClassDomainID(CORINFO_CLASS_HANDLE cls, void** ppIndirection)
1430 {
1431     jitInstance->mc->cr->AddCall("getClassDomainID");
1432     return jitInstance->mc->repGetClassDomainID(cls, ppIndirection);
1433 }
1434
1435 // return the data's address (for static fields only)
1436 void* MyICJI::getFieldAddress(CORINFO_FIELD_HANDLE field, void** ppIndirection)
1437 {
1438     jitInstance->mc->cr->AddCall("getFieldAddress");
1439     return jitInstance->mc->repGetFieldAddress(field, ppIndirection);
1440 }
1441
1442 // registers a vararg sig & returns a VM cookie for it (which can contain other stuff)
1443 CORINFO_VARARGS_HANDLE MyICJI::getVarArgsHandle(CORINFO_SIG_INFO* pSig, void** ppIndirection)
1444 {
1445     jitInstance->mc->cr->AddCall("getVarArgsHandle");
1446     return jitInstance->mc->repGetVarArgsHandle(pSig, ppIndirection);
1447 }
1448
1449 // returns true if a VM cookie can be generated for it (might be false due to cross-module
1450 // inlining, in which case the inlining should be aborted)
1451 bool MyICJI::canGetVarArgsHandle(CORINFO_SIG_INFO* pSig)
1452 {
1453     jitInstance->mc->cr->AddCall("canGetVarArgsHandle");
1454     return jitInstance->mc->repCanGetVarArgsHandle(pSig);
1455 }
1456
1457 // Allocate a string literal on the heap and return a handle to it
1458 InfoAccessType MyICJI::constructStringLiteral(CORINFO_MODULE_HANDLE module, mdToken metaTok, void** ppValue)
1459 {
1460     jitInstance->mc->cr->AddCall("constructStringLiteral");
1461     return jitInstance->mc->repConstructStringLiteral(module, metaTok, ppValue);
1462 }
1463
1464 InfoAccessType MyICJI::emptyStringLiteral(void** ppValue)
1465 {
1466     jitInstance->mc->cr->AddCall("emptyStringLiteral");
1467     return jitInstance->mc->repEmptyStringLiteral(ppValue);
1468 }
1469
1470 // (static fields only) given that 'field' refers to thread local store,
1471 // return the ID (TLS index), which is used to find the begining of the
1472 // TLS data area for the particular DLL 'field' is associated with.
1473 DWORD MyICJI::getFieldThreadLocalStoreID(CORINFO_FIELD_HANDLE field, void** ppIndirection)
1474 {
1475     jitInstance->mc->cr->AddCall("getFieldThreadLocalStoreID");
1476     return jitInstance->mc->repGetFieldThreadLocalStoreID(field, ppIndirection);
1477 }
1478
1479 // Sets another object to intercept calls to "self" and current method being compiled
1480 void MyICJI::setOverride(ICorDynamicInfo* pOverride, CORINFO_METHOD_HANDLE currentMethod)
1481 {
1482     jitInstance->mc->cr->AddCall("setOverride");
1483     LogError("Hit unimplemented setOverride");
1484     DebugBreakorAV(115);
1485 }
1486
1487 // Adds an active dependency from the context method's module to the given module
1488 // This is internal callback for the EE. JIT should not call it directly.
1489 void MyICJI::addActiveDependency(CORINFO_MODULE_HANDLE moduleFrom, CORINFO_MODULE_HANDLE moduleTo)
1490 {
1491     jitInstance->mc->cr->AddCall("addActiveDependency");
1492     LogError("Hit unimplemented addActiveDependency");
1493     DebugBreakorAV(116);
1494 }
1495
1496 CORINFO_METHOD_HANDLE MyICJI::GetDelegateCtor(CORINFO_METHOD_HANDLE methHnd,
1497                                               CORINFO_CLASS_HANDLE  clsHnd,
1498                                               CORINFO_METHOD_HANDLE targetMethodHnd,
1499                                               DelegateCtorArgs*     pCtorData)
1500 {
1501     jitInstance->mc->cr->AddCall("GetDelegateCtor");
1502     return jitInstance->mc->repGetDelegateCtor(methHnd, clsHnd, targetMethodHnd, pCtorData);
1503 }
1504
1505 void MyICJI::MethodCompileComplete(CORINFO_METHOD_HANDLE methHnd)
1506 {
1507     jitInstance->mc->cr->AddCall("MethodCompileComplete");
1508     LogError("Hit unimplemented MethodCompileComplete");
1509     DebugBreakorAV(118);
1510 }
1511
1512 // return a thunk that will copy the arguments for the given signature.
1513 void* MyICJI::getTailCallCopyArgsThunk(CORINFO_SIG_INFO* pSig, CorInfoHelperTailCallSpecialHandling flags)
1514 {
1515     jitInstance->mc->cr->AddCall("getTailCallCopyArgsThunk");
1516     return jitInstance->mc->repGetTailCallCopyArgsThunk(pSig, flags);
1517 }
1518
1519 // Stuff directly on ICorJitInfo
1520
1521 // Returns extended flags for a particular compilation instance.
1522 DWORD MyICJI::getJitFlags(CORJIT_FLAGS* jitFlags, DWORD sizeInBytes)
1523 {
1524     jitInstance->mc->cr->AddCall("getJitFlags");
1525     return jitInstance->mc->repGetJitFlags(jitFlags, sizeInBytes);
1526 }
1527
1528 // Runs the given function with the given parameter under an error trap
1529 // and returns true if the function completes successfully. We fake this
1530 // up a bit for SuperPMI and simply catch all exceptions.
1531 bool MyICJI::runWithErrorTrap(void (*function)(void*), void* param)
1532 {
1533     return RunWithErrorTrap(function, param);
1534 }
1535
1536 // return memory manager that the JIT can use to allocate a regular memory
1537 IEEMemoryManager* MyICJI::getMemoryManager()
1538 {
1539     return InitIEEMemoryManager(jitInstance);
1540 }
1541
1542 // get a block of memory for the code, readonly data, and read-write data
1543 void MyICJI::allocMem(ULONG              hotCodeSize,   /* IN */
1544                       ULONG              coldCodeSize,  /* IN */
1545                       ULONG              roDataSize,    /* IN */
1546                       ULONG              xcptnsCount,   /* IN */
1547                       CorJitAllocMemFlag flag,          /* IN */
1548                       void**             hotCodeBlock,  /* OUT */
1549                       void**             coldCodeBlock, /* OUT */
1550                       void**             roDataBlock    /* OUT */
1551                       )
1552 {
1553     jitInstance->mc->cr->AddCall("allocMem");
1554     // TODO-Cleanup: investigate if we need to check roDataBlock as well. Could hot block size be ever 0?
1555     *hotCodeBlock = HeapAlloc(jitInstance->mc->cr->getCodeHeap(), 0, hotCodeSize);
1556     if (coldCodeSize > 0)
1557         *coldCodeBlock = HeapAlloc(jitInstance->mc->cr->getCodeHeap(), 0, coldCodeSize);
1558     else
1559         *coldCodeBlock = nullptr;
1560     *roDataBlock       = HeapAlloc(jitInstance->mc->cr->getCodeHeap(), 0, roDataSize);
1561     jitInstance->mc->cr->recAllocMem(hotCodeSize, coldCodeSize, roDataSize, xcptnsCount, flag, hotCodeBlock,
1562                                      coldCodeBlock, roDataBlock);
1563 }
1564
1565 // Reserve memory for the method/funclet's unwind information.
1566 // Note that this must be called before allocMem. It should be
1567 // called once for the main method, once for every funclet, and
1568 // once for every block of cold code for which allocUnwindInfo
1569 // will be called.
1570 //
1571 // This is necessary because jitted code must allocate all the
1572 // memory needed for the unwindInfo at the allocMem call.
1573 // For prejitted code we split up the unwinding information into
1574 // separate sections .rdata and .pdata.
1575 //
1576 void MyICJI::reserveUnwindInfo(BOOL  isFunclet,  /* IN */
1577                                BOOL  isColdCode, /* IN */
1578                                ULONG unwindSize  /* IN */
1579                                )
1580 {
1581     jitInstance->mc->cr->AddCall("reserveUnwindInfo");
1582     jitInstance->mc->cr->recReserveUnwindInfo(isFunclet, isColdCode, unwindSize);
1583 }
1584
1585 // Allocate and initialize the .rdata and .pdata for this method or
1586 // funclet, and get the block of memory needed for the machine-specific
1587 // unwind information (the info for crawling the stack frame).
1588 // Note that allocMem must be called first.
1589 //
1590 // Parameters:
1591 //
1592 //    pHotCode        main method code buffer, always filled in
1593 //    pColdCode       cold code buffer, only filled in if this is cold code,
1594 //                      null otherwise
1595 //    startOffset     start of code block, relative to appropriate code buffer
1596 //                      (e.g. pColdCode if cold, pHotCode if hot).
1597 //    endOffset       end of code block, relative to appropriate code buffer
1598 //    unwindSize      size of unwind info pointed to by pUnwindBlock
1599 //    pUnwindBlock    pointer to unwind info
1600 //    funcKind        type of funclet (main method code, handler, filter)
1601 //
1602 void MyICJI::allocUnwindInfo(BYTE*          pHotCode,     /* IN */
1603                              BYTE*          pColdCode,    /* IN */
1604                              ULONG          startOffset,  /* IN */
1605                              ULONG          endOffset,    /* IN */
1606                              ULONG          unwindSize,   /* IN */
1607                              BYTE*          pUnwindBlock, /* IN */
1608                              CorJitFuncKind funcKind      /* IN */
1609                              )
1610 {
1611     jitInstance->mc->cr->AddCall("allocUnwindInfo");
1612     jitInstance->mc->cr->recAllocUnwindInfo(pHotCode, pColdCode, startOffset, endOffset, unwindSize, pUnwindBlock,
1613                                             funcKind);
1614 }
1615
1616 // Get a block of memory needed for the code manager information,
1617 // (the info for enumerating the GC pointers while crawling the
1618 // stack frame).
1619 // Note that allocMem must be called first
1620 void* MyICJI::allocGCInfo(size_t size /* IN */
1621                           )
1622 {
1623     jitInstance->mc->cr->AddCall("allocGCInfo");
1624     void* temp = (unsigned char*)HeapAlloc(jitInstance->mc->cr->getCodeHeap(), 0, size);
1625     jitInstance->mc->cr->recAllocGCInfo(size, temp);
1626
1627     return temp;
1628 }
1629
1630 // Only used on x64.
1631 void MyICJI::yieldExecution()
1632 {
1633     jitInstance->mc->cr->AddCall("yieldExecution");
1634 }
1635
1636 // Indicate how many exception handler blocks are to be returned.
1637 // This is guaranteed to be called before any 'setEHinfo' call.
1638 // Note that allocMem must be called before this method can be called.
1639 void MyICJI::setEHcount(unsigned cEH /* IN */
1640                         )
1641 {
1642     jitInstance->mc->cr->AddCall("setEHcount");
1643     jitInstance->mc->cr->recSetEHcount(cEH);
1644 }
1645
1646 // Set the values for one particular exception handler block.
1647 //
1648 // Handler regions should be lexically contiguous.
1649 // This is because FinallyIsUnwinding() uses lexicality to
1650 // determine if a "finally" clause is executing.
1651 void MyICJI::setEHinfo(unsigned                 EHnumber, /* IN  */
1652                        const CORINFO_EH_CLAUSE* clause    /* IN */
1653                        )
1654 {
1655     jitInstance->mc->cr->AddCall("setEHinfo");
1656     jitInstance->mc->cr->recSetEHinfo(EHnumber, clause);
1657 }
1658
1659 // Level 1 -> fatalError, Level 2 -> Error, Level 3 -> Warning
1660 // Level 4 means happens 10 times in a run, level 5 means 100, level 6 means 1000 ...
1661 // returns non-zero if the logging succeeded
1662 BOOL MyICJI::logMsg(unsigned level, const char* fmt, va_list args)
1663 {
1664     jitInstance->mc->cr->AddCall("logMsg");
1665
1666     //  if(level<=2)
1667     //  {
1668      //jitInstance->mc->cr->recMessageLog(fmt, args);
1669      //DebugBreakorAV(0x99);
1670     //}
1671     jitInstance->mc->cr->recMessageLog(fmt, args);
1672     return 0;
1673 }
1674
1675 // do an assert.  will return true if the code should retry (DebugBreak)
1676 // returns false, if the assert should be igored.
1677 int MyICJI::doAssert(const char* szFile, int iLine, const char* szExpr)
1678 {
1679     jitInstance->mc->cr->AddCall("doAssert");
1680     char buff[16 * 1024];
1681     sprintf_s(buff, sizeof(buff), "%s (%d) - %s", szFile, iLine, szExpr);
1682
1683     LogIssue(ISSUE_ASSERT, "%s", buff);
1684     jitInstance->mc->cr->recMessageLog(buff);
1685
1686     // Under "/boa", ask the user if they want to attach a debugger. If they do, the debugger will be attached,
1687     // then we'll call DebugBreakorAV(), which will issue a __debugbreak() and actually cause
1688     // us to stop in the debugger.
1689     if (breakOnDebugBreakorAV)
1690     {
1691         DbgBreakCheck(szFile, iLine, szExpr);
1692     }
1693
1694     DebugBreakorAV(0x7b);
1695     return 0;
1696 }
1697
1698 void MyICJI::reportFatalError(CorJitResult result)
1699 {
1700     jitInstance->mc->cr->AddCall("reportFatalError");
1701     jitInstance->mc->cr->recReportFatalError(result);
1702 }
1703
1704 // allocate a basic block profile buffer where execution counts will be stored
1705 // for jitted basic blocks.
1706 HRESULT MyICJI::allocBBProfileBuffer(ULONG           count, // The number of basic blocks that we have
1707                                      ProfileBuffer** profileBuffer)
1708 {
1709     jitInstance->mc->cr->AddCall("allocBBProfileBuffer");
1710     return jitInstance->mc->cr->repAllocBBProfileBuffer(count, profileBuffer);
1711 }
1712
1713 // get profile information to be used for optimizing the current method.  The format
1714 // of the buffer is the same as the format the JIT passes to allocBBProfileBuffer.
1715 HRESULT MyICJI::getBBProfileData(CORINFO_METHOD_HANDLE ftnHnd,
1716                                  ULONG*                count, // The number of basic blocks that we have
1717                                  ProfileBuffer**       profileBuffer,
1718                                  ULONG*                numRuns)
1719 {
1720     jitInstance->mc->cr->AddCall("getBBProfileData");
1721     return jitInstance->mc->repGetBBProfileData(ftnHnd, count, profileBuffer, numRuns);
1722 }
1723
1724 // Associates a native call site, identified by its offset in the native code stream, with
1725 // the signature information and method handle the JIT used to lay out the call site. If
1726 // the call site has no signature information (e.g. a helper call) or has no method handle
1727 // (e.g. a CALLI P/Invoke), then null should be passed instead.
1728 void MyICJI::recordCallSite(ULONG                 instrOffset, /* IN */
1729                             CORINFO_SIG_INFO*     callSig,     /* IN */
1730                             CORINFO_METHOD_HANDLE methodHandle /* IN */
1731                             )
1732 {
1733     jitInstance->mc->cr->AddCall("recordCallSite");
1734     jitInstance->mc->cr->repRecordCallSite(instrOffset, callSig, methodHandle);
1735 }
1736
1737 // A relocation is recorded if we are pre-jitting.
1738 // A jump thunk may be inserted if we are jitting
1739 void MyICJI::recordRelocation(void* location,   /* IN  */
1740                               void* target,     /* IN  */
1741                               WORD  fRelocType, /* IN  */
1742                               WORD  slotNum,    /* IN  */
1743                               INT32 addlDelta   /* IN  */
1744                               )
1745 {
1746     jitInstance->mc->cr->AddCall("recordRelocation");
1747     jitInstance->mc->cr->repRecordRelocation(location, target, fRelocType, slotNum, addlDelta);
1748 }
1749
1750 WORD MyICJI::getRelocTypeHint(void* target)
1751 {
1752     jitInstance->mc->cr->AddCall("getRelocTypeHint");
1753     WORD result = jitInstance->mc->repGetRelocTypeHint(target);
1754     return result;
1755 }
1756
1757 // A callback to identify the range of address known to point to
1758 // compiler-generated native entry points that call back into
1759 // MSIL.
1760 void MyICJI::getModuleNativeEntryPointRange(void** pStart, /* OUT */
1761                                             void** pEnd    /* OUT */
1762                                             )
1763 {
1764     jitInstance->mc->cr->AddCall("getModuleNativeEntryPointRange");
1765     LogError("Hit unimplemented getModuleNativeEntryPointRange");
1766     DebugBreakorAV(128);
1767 }
1768
1769 // For what machine does the VM expect the JIT to generate code? The VM
1770 // returns one of the IMAGE_FILE_MACHINE_* values. Note that if the VM
1771 // is cross-compiling (such as the case for crossgen), it will return a
1772 // different value than if it was compiling for the host architecture.
1773 //
1774 DWORD MyICJI::getExpectedTargetArchitecture()
1775 {
1776 #if defined(_TARGET_X86_)
1777     return IMAGE_FILE_MACHINE_I386;
1778 #elif defined(_TARGET_AMD64_)
1779     return IMAGE_FILE_MACHINE_AMD64;
1780 #elif defined(_TARGET_ARM_)
1781     return IMAGE_FILE_MACHINE_ARMNT;
1782 #elif defined(_TARGET_ARM64_)
1783     return IMAGE_FILE_MACHINE_ARM64;
1784 #else
1785     return IMAGE_FILE_MACHINE_UNKNOWN;
1786 #endif
1787 }