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