2 // Copyright (c) Microsoft. All rights reserved.
3 // Licensed under the MIT license. See LICENSE file in the project root for full license information.
6 #include "standardpch.h"
7 #include "icorjitinfo.h"
8 #include "jitdebugger.h"
11 ICorJitInfo* pICJI = nullptr;
13 ICorJitInfo* InitICorJitInfo(JitInstance* jitInstance)
15 MyICJI* icji = new MyICJI();
16 icji->jitInstance = jitInstance;
21 // Stuff on ICorStaticInfo
22 /**********************************************************************************/
26 /**********************************************************************************/
28 // return flags (defined above, CORINFO_FLG_PUBLIC ...)
29 DWORD MyICJI::getMethodAttribs(CORINFO_METHOD_HANDLE ftn /* IN */)
31 jitInstance->mc->cr->AddCall("getMethodAttribs");
32 return jitInstance->mc->repGetMethodAttribs(ftn);
35 // sets private JIT flags, which can be, retrieved using getAttrib.
36 void MyICJI::setMethodAttribs(CORINFO_METHOD_HANDLE ftn, /* IN */
37 CorInfoMethodRuntimeFlags attribs /* IN */)
39 jitInstance->mc->cr->AddCall("setMethodAttribs");
40 jitInstance->mc->cr->recSetMethodAttribs(ftn, attribs);
43 // Given a method descriptor ftnHnd, extract signature information into sigInfo
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 */
52 jitInstance->mc->cr->AddCall("getMethodSig");
53 jitInstance->mc->repGetMethodSig(ftn, sig, memberParent);
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 *********************************************************************/
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 */
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);
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
82 // The callerHnd must be the immediate caller (i.e. when we have a chain of inlined calls)
84 // The inlined method need not be verified
86 CorInfoInline MyICJI::canInline(CORINFO_METHOD_HANDLE callerHnd, /* IN */
87 CORINFO_METHOD_HANDLE calleeHnd, /* IN */
88 DWORD* pRestrictions /* OUT */
91 jitInstance->mc->cr->AddCall("canInline");
93 DWORD exceptionCode = 0;
94 CorInfoInline result = jitInstance->mc->repCanInline(callerHnd, calleeHnd, pRestrictions, &exceptionCode);
95 if (exceptionCode != 0)
96 ThrowException(exceptionCode);
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
103 void MyICJI::reportInliningDecision(CORINFO_METHOD_HANDLE inlinerHnd,
104 CORINFO_METHOD_HANDLE inlineeHnd,
105 CorInfoInline inlineResult,
108 jitInstance->mc->cr->AddCall("reportInliningDecision");
109 jitInstance->mc->cr->recReportInliningDecision(inlinerHnd, inlineeHnd, inlineResult, reason);
112 // Returns false if the call is across security boundaries thus we cannot tailcall
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 */
121 jitInstance->mc->cr->AddCall("canTailCall");
122 return jitInstance->mc->repCanTailCall(callerHnd, declaredCalleeHnd, exactCalleeHnd, fIsTailPrefix);
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,
131 CorInfoTailCall tailCallResult,
134 jitInstance->mc->cr->AddCall("reportTailCallDecision");
135 jitInstance->mc->cr->recReportTailCallDecision(callerHnd, calleeHnd, fIsTailPrefix, tailCallResult, reason);
138 // get individual exception handler
139 void MyICJI::getEHinfo(CORINFO_METHOD_HANDLE ftn, /* IN */
140 unsigned EHnumber, /* IN */
141 CORINFO_EH_CLAUSE* clause /* OUT */
144 jitInstance->mc->cr->AddCall("getEHinfo");
145 jitInstance->mc->repGetEHinfo(ftn, EHnumber, clause);
148 // return class it belongs to
149 CORINFO_CLASS_HANDLE MyICJI::getMethodClass(CORINFO_METHOD_HANDLE method)
151 jitInstance->mc->cr->AddCall("getMethodClass");
152 return jitInstance->mc->repGetMethodClass(method);
155 // return module it belongs to
156 CORINFO_MODULE_HANDLE MyICJI::getMethodModule(CORINFO_METHOD_HANDLE method)
158 jitInstance->mc->cr->AddCall("getMethodModule");
159 LogError("Hit unimplemented getMethodModule");
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 */
171 jitInstance->mc->cr->AddCall("getMethodVTableOffset");
172 jitInstance->mc->repGetMethodVTableOffset(method, offsetOfIndirection, offsetAfterIndirection);
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)
181 jitInstance->mc->cr->AddCall("resolveVirtualMethod");
182 CORINFO_METHOD_HANDLE result =
183 jitInstance->mc->repResolveVirtualMethod(virtualMethod, implementingClass, ownerType);
187 void MyICJI::expandRawHandleIntrinsic(
188 CORINFO_RESOLVED_TOKEN * pResolvedToken,
189 CORINFO_GENERICHANDLE_RESULT * pResult)
191 jitInstance->mc->cr->AddCall("expandRawHandleIntrinsic");
192 LogError("Hit unimplemented expandRawHandleIntrinsic");
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 */
201 jitInstance->mc->cr->AddCall("getIntrinsicID");
202 return jitInstance->mc->repGetIntrinsicID(method, pMustExpand);
205 // Is the given module the System.Numerics.Vectors module?
206 bool MyICJI::isInSIMDModule(CORINFO_CLASS_HANDLE classHnd)
208 jitInstance->mc->cr->AddCall("isInSIMDModule");
209 return jitInstance->mc->repIsInSIMDModule(classHnd) ? true : false;
212 // return the unmanaged calling convention for a PInvoke
213 CorInfoUnmanagedCallConv MyICJI::getUnmanagedCallConv(CORINFO_METHOD_HANDLE method)
215 jitInstance->mc->cr->AddCall("getUnmanagedCallConv");
216 return jitInstance->mc->repGetUnmanagedCallConv(method);
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)
223 jitInstance->mc->cr->AddCall("pInvokeMarshalingRequired");
224 return jitInstance->mc->repPInvokeMarshalingRequired(method, callSiteSig);
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)
232 jitInstance->mc->cr->AddCall("satisfiesMethodConstraints");
233 return jitInstance->mc->repSatisfiesMethodConstraints(parent, method);
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 */
246 jitInstance->mc->cr->AddCall("isCompatibleDelegate");
247 return jitInstance->mc->repIsCompatibleDelegate(objCls, methodParentCls, method, delegateCls, pfIsOpenDelegate);
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 */
255 jitInstance->mc->cr->AddCall("isInstantiationOfVerifiedGeneric");
256 return jitInstance->mc->repIsInstantiationOfVerifiedGeneric(method);
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 */
266 jitInstance->mc->cr->AddCall("initConstraintsForVerification");
267 jitInstance->mc->repInitConstraintsForVerification(method, pfHasCircularClassConstraints,
268 pfHasCircularMethodConstraint);
271 // Returns enum whether the method does not require verification
272 // Also see ICorModuleInfo::canSkipVerification
273 CorInfoCanSkipVerificationResult MyICJI::canSkipMethodVerification(CORINFO_METHOD_HANDLE ftnHandle)
275 jitInstance->mc->cr->AddCall("canSkipMethodVerification");
276 return jitInstance->mc->repCanSkipMethodVerification(ftnHandle, FALSE);
279 // load and restore the method
280 void MyICJI::methodMustBeLoadedBeforeCodeIsRun(CORINFO_METHOD_HANDLE method)
282 jitInstance->mc->cr->AddCall("methodMustBeLoadedBeforeCodeIsRun");
283 jitInstance->mc->cr->recMethodMustBeLoadedBeforeCodeIsRun(method);
286 CORINFO_METHOD_HANDLE MyICJI::mapMethodDeclToMethodImpl(CORINFO_METHOD_HANDLE method)
288 jitInstance->mc->cr->AddCall("mapMethodDeclToMethodImpl");
289 LogError("Hit unimplemented mapMethodDeclToMethodImpl");
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
300 jitInstance->mc->cr->AddCall("getGSCookie");
301 jitInstance->mc->repGetGSCookie(pCookieVal, ppCookieVal);
304 /**********************************************************************************/
308 /**********************************************************************************/
310 // Resolve metadata token into runtime method handles.
311 void MyICJI::resolveToken(/* IN, OUT */ CORINFO_RESOLVED_TOKEN* pResolvedToken)
313 DWORD exceptionCode = 0;
314 jitInstance->mc->cr->AddCall("resolveToken");
315 jitInstance->mc->repResolveToken(pResolvedToken, &exceptionCode);
316 if (exceptionCode != 0)
317 ThrowException(exceptionCode);
320 // Resolve metadata token into runtime method handles.
321 bool MyICJI::tryResolveToken(/* IN, OUT */ CORINFO_RESOLVED_TOKEN* pResolvedToken)
323 jitInstance->mc->cr->AddCall("tryResolveToken");
324 return jitInstance->mc->repTryResolveToken(pResolvedToken);
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 */
334 jitInstance->mc->cr->AddCall("findSig");
335 jitInstance->mc->repFindSig(module, sigTOK, context, sig);
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 */
347 jitInstance->mc->cr->AddCall("findCallSiteSig");
348 jitInstance->mc->repFindCallSiteSig(module, methTOK, context, sig);
351 CORINFO_CLASS_HANDLE MyICJI::getTokenTypeAsHandle(CORINFO_RESOLVED_TOKEN* pResolvedToken /* IN */)
353 jitInstance->mc->cr->AddCall("getTokenTypeAsHandle");
354 return jitInstance->mc->repGetTokenTypeAsHandle(pResolvedToken);
357 // Returns true if the module does not require verification
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.
366 // Returns enum whether the module does not require verification
367 // Also see ICorMethodInfo::canSkipMethodVerification();
368 CorInfoCanSkipVerificationResult MyICJI::canSkipVerification(CORINFO_MODULE_HANDLE module /* IN */
371 jitInstance->mc->cr->AddCall("canSkipVerification");
372 LogError("Hit unimplemented canSkipVerification");
374 return CORINFO_VERIFICATION_CANNOT_SKIP;
377 // Checks if the given metadata token is valid
378 BOOL MyICJI::isValidToken(CORINFO_MODULE_HANDLE module, /* IN */
379 unsigned metaTOK /* IN */
382 jitInstance->mc->cr->AddCall("isValidToken");
383 return jitInstance->mc->repIsValidToken(module, metaTOK);
386 // Checks if the given metadata token is valid StringRef
387 BOOL MyICJI::isValidStringRef(CORINFO_MODULE_HANDLE module, /* IN */
388 unsigned metaTOK /* IN */
391 jitInstance->mc->cr->AddCall("isValidStringRef");
392 return jitInstance->mc->repIsValidStringRef(module, metaTOK);
395 BOOL MyICJI::shouldEnforceCallvirtRestriction(CORINFO_MODULE_HANDLE scope)
397 jitInstance->mc->cr->AddCall("shouldEnforceCallvirtRestriction");
398 return jitInstance->mc->repShouldEnforceCallvirtRestriction(scope);
401 /**********************************************************************************/
405 /**********************************************************************************/
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)
411 jitInstance->mc->cr->AddCall("asCorInfoType");
412 return jitInstance->mc->repAsCorInfoType(cls);
416 const char* MyICJI::getClassName(CORINFO_CLASS_HANDLE cls)
418 jitInstance->mc->cr->AddCall("getClassName");
419 const char* result = jitInstance->mc->repGetClassName(cls);
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,
430 CORINFO_CLASS_HANDLE cls,
435 jitInstance->mc->cr->AddCall("appendClassName");
436 const WCHAR* result = jitInstance->mc->repAppendClassName(cls, fNamespace, fFullInst, fAssembly);
438 if (ppBuf != nullptr && result != nullptr)
440 nLen = (int)wcslen(result);
441 if (*pnBufLen > nLen)
443 wcscpy_s(*ppBuf, *pnBufLen, result);
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)
455 jitInstance->mc->cr->AddCall("isValueClass");
456 return jitInstance->mc->repIsValueClass(cls);
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)
463 jitInstance->mc->cr->AddCall("canInlineTypeCheckWithObjectVTable");
464 return jitInstance->mc->repCanInlineTypeCheckWithObjectVTable(cls);
467 // return flags (defined above, CORINFO_FLG_PUBLIC ...)
468 DWORD MyICJI::getClassAttribs(CORINFO_CLASS_HANDLE cls)
470 jitInstance->mc->cr->AddCall("getClassAttribs");
471 return jitInstance->mc->repGetClassAttribs(cls);
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)
482 jitInstance->mc->cr->AddCall("isStructRequiringStackAllocRetBuf");
483 return jitInstance->mc->repIsStructRequiringStackAllocRetBuf(cls);
486 CORINFO_MODULE_HANDLE MyICJI::getClassModule(CORINFO_CLASS_HANDLE cls)
488 jitInstance->mc->cr->AddCall("getClassModule");
489 LogError("Hit unimplemented getClassModule");
491 return (CORINFO_MODULE_HANDLE)0;
492 // jitInstance->mc->getClassModule(cls);
495 // Returns the assembly that contains the module "mod".
496 CORINFO_ASSEMBLY_HANDLE MyICJI::getModuleAssembly(CORINFO_MODULE_HANDLE mod)
498 jitInstance->mc->cr->AddCall("getModuleAssembly");
499 LogError("Hit unimplemented getModuleAssembly");
501 return (CORINFO_ASSEMBLY_HANDLE)0;
503 // return jitInstance->mc->getModuleAssembly(mod);
506 // Returns the name of the assembly "assem".
507 const char* MyICJI::getAssemblyName(CORINFO_ASSEMBLY_HANDLE assem)
509 jitInstance->mc->cr->AddCall("getAssemblyName");
510 LogError("Hit unimplemented getAssemblyName");
513 // return jitInstance->mc->getAssemblyName(assem);
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)
522 jitInstance->mc->cr->AddCall("LongLifetimeMalloc");
523 LogError("Hit unimplemented LongLifetimeMalloc");
528 void MyICJI::LongLifetimeFree(void* obj)
530 jitInstance->mc->cr->AddCall("LongLifetimeFree");
531 LogError("Hit unimplemented LongLifetimeFree");
535 size_t MyICJI::getClassModuleIdForStatics(CORINFO_CLASS_HANDLE cls,
536 CORINFO_MODULE_HANDLE* pModule,
537 void** ppIndirection)
539 jitInstance->mc->cr->AddCall("getClassModuleIdForStatics");
540 return jitInstance->mc->repGetClassModuleIdForStatics(cls, pModule, ppIndirection);
543 // return the number of bytes needed by an instance of the class
544 unsigned MyICJI::getClassSize(CORINFO_CLASS_HANDLE cls)
546 jitInstance->mc->cr->AddCall("getClassSize");
547 return jitInstance->mc->repGetClassSize(cls);
550 unsigned MyICJI::getClassAlignmentRequirement(CORINFO_CLASS_HANDLE cls, BOOL fDoubleAlignHint)
552 jitInstance->mc->cr->AddCall("getClassAlignmentRequirement");
553 return jitInstance->mc->repGetClassAlignmentRequirement(cls, fDoubleAlignHint);
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 */
569 jitInstance->mc->cr->AddCall("getClassGClayout");
570 return jitInstance->mc->repGetClassGClayout(cls, gcPtrs);
573 // returns the number of instance fields in a class
574 unsigned MyICJI::getClassNumInstanceFields(CORINFO_CLASS_HANDLE cls /* IN */
577 jitInstance->mc->cr->AddCall("getClassNumInstanceFields");
578 return jitInstance->mc->repGetClassNumInstanceFields(cls);
581 CORINFO_FIELD_HANDLE MyICJI::getFieldInClass(CORINFO_CLASS_HANDLE clsHnd, INT num)
583 jitInstance->mc->cr->AddCall("getFieldInClass");
584 return jitInstance->mc->repGetFieldInClass(clsHnd, num);
587 BOOL MyICJI::checkMethodModifier(CORINFO_METHOD_HANDLE hMethod, LPCSTR modifier, BOOL fOptional)
589 jitInstance->mc->cr->AddCall("checkMethodModifier");
590 BOOL result = jitInstance->mc->repCheckMethodModifier(hMethod, modifier, fOptional);
594 // returns the "NEW" helper optimized for "newCls."
595 CorInfoHelpFunc MyICJI::getNewHelper(CORINFO_RESOLVED_TOKEN* pResolvedToken, CORINFO_METHOD_HANDLE callerHandle)
597 jitInstance->mc->cr->AddCall("getNewHelper");
598 return jitInstance->mc->repGetNewHelper(pResolvedToken, callerHandle);
601 // returns the newArr (1-Dim array) helper optimized for "arrayCls."
602 CorInfoHelpFunc MyICJI::getNewArrHelper(CORINFO_CLASS_HANDLE arrayCls)
604 jitInstance->mc->cr->AddCall("getNewArrHelper");
605 return jitInstance->mc->repGetNewArrHelper(arrayCls);
608 // returns the optimized "IsInstanceOf" or "ChkCast" helper
609 CorInfoHelpFunc MyICJI::getCastingHelper(CORINFO_RESOLVED_TOKEN* pResolvedToken, bool fThrowing)
611 jitInstance->mc->cr->AddCall("getCastingHelper");
612 return jitInstance->mc->repGetCastingHelper(pResolvedToken, fThrowing);
615 // returns helper to trigger static constructor
616 CorInfoHelpFunc MyICJI::getSharedCCtorHelper(CORINFO_CLASS_HANDLE clsHnd)
618 jitInstance->mc->cr->AddCall("getSharedCCtorHelper");
619 return jitInstance->mc->repGetSharedCCtorHelper(clsHnd);
622 CorInfoHelpFunc MyICJI::getSecurityPrologHelper(CORINFO_METHOD_HANDLE ftn)
624 jitInstance->mc->cr->AddCall("getSecurityPrologHelper");
625 return jitInstance->mc->repGetSecurityPrologHelper(ftn);
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)
634 jitInstance->mc->cr->AddCall("getTypeForBox");
635 return jitInstance->mc->repGetTypeForBox(cls);
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)
643 jitInstance->mc->cr->AddCall("getBoxHelper");
644 return jitInstance->mc->repGetBoxHelper(cls);
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.
659 CorInfoHelpFunc MyICJI::getUnBoxHelper(CORINFO_CLASS_HANDLE cls)
661 jitInstance->mc->cr->AddCall("getUnBoxHelper");
662 CorInfoHelpFunc result = jitInstance->mc->repGetUnBoxHelper(cls);
666 bool MyICJI::getReadyToRunHelper(CORINFO_RESOLVED_TOKEN* pResolvedToken,
667 CORINFO_LOOKUP_KIND* pGenericLookupKind,
669 CORINFO_CONST_LOOKUP* pLookup)
671 jitInstance->mc->cr->AddCall("getReadyToRunHelper");
672 return jitInstance->mc->repGetReadyToRunHelper(pResolvedToken, pGenericLookupKind, id, pLookup);
675 void MyICJI::getReadyToRunDelegateCtorHelper(CORINFO_RESOLVED_TOKEN* pTargetMethod,
676 CORINFO_CLASS_HANDLE delegateType,
677 CORINFO_LOOKUP* pLookup)
679 jitInstance->mc->cr->AddCall("getReadyToRunDelegateCtorHelper");
680 jitInstance->mc->repGetReadyToRunDelegateCtorHelper(pTargetMethod, delegateType, pLookup);
683 const char* MyICJI::getHelperName(CorInfoHelpFunc funcNum)
685 jitInstance->mc->cr->AddCall("getHelperName");
686 return jitInstance->mc->repGetHelperName(funcNum);
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.
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
702 jitInstance->mc->cr->AddCall("initClass");
703 return jitInstance->mc->repInitClass(field, method, context, speculative);
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.
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)
718 jitInstance->mc->cr->AddCall("classMustBeLoadedBeforeCodeIsRun");
719 jitInstance->mc->cr->recClassMustBeLoadedBeforeCodeIsRun(cls);
722 // returns the class handle for the special builtin classes
723 CORINFO_CLASS_HANDLE MyICJI::getBuiltinClass(CorInfoClassId classId)
725 jitInstance->mc->cr->AddCall("getBuiltinClass");
726 return jitInstance->mc->repGetBuiltinClass(classId);
729 // "System.Int32" ==> CORINFO_TYPE_INT..
730 CorInfoType MyICJI::getTypeForPrimitiveValueClass(CORINFO_CLASS_HANDLE cls)
732 jitInstance->mc->cr->AddCall("getTypeForPrimitiveValueClass");
733 return jitInstance->mc->repGetTypeForPrimitiveValueClass(cls);
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
742 jitInstance->mc->cr->AddCall("canCast");
743 return jitInstance->mc->repCanCast(child, parent);
746 // TRUE if cls1 and cls2 are considered equivalent types.
747 BOOL MyICJI::areTypesEquivalent(CORINFO_CLASS_HANDLE cls1, CORINFO_CLASS_HANDLE cls2)
749 jitInstance->mc->cr->AddCall("areTypesEquivalent");
750 return jitInstance->mc->repAreTypesEquivalent(cls1, cls2);
753 // returns is the intersection of cls1 and cls2.
754 CORINFO_CLASS_HANDLE MyICJI::mergeClasses(CORINFO_CLASS_HANDLE cls1, CORINFO_CLASS_HANDLE cls2)
756 jitInstance->mc->cr->AddCall("mergeClasses");
757 return jitInstance->mc->repMergeClasses(cls1, cls2);
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)
765 jitInstance->mc->cr->AddCall("getParentType");
766 return jitInstance->mc->repGetParentType(cls);
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)
775 jitInstance->mc->cr->AddCall("getChildType");
776 return jitInstance->mc->repGetChildType(clsHnd, clsRet);
779 // Check constraints on type arguments of this class and parent classes
780 BOOL MyICJI::satisfiesClassConstraints(CORINFO_CLASS_HANDLE cls)
782 jitInstance->mc->cr->AddCall("satisfiesClassConstraints");
783 return jitInstance->mc->repSatisfiesClassConstraints(cls);
786 // Check if this is a single dimensional array type
787 BOOL MyICJI::isSDArray(CORINFO_CLASS_HANDLE cls)
789 jitInstance->mc->cr->AddCall("isSDArray");
790 return jitInstance->mc->repIsSDArray(cls);
793 // Get the numbmer of dimensions in an array
794 unsigned MyICJI::getArrayRank(CORINFO_CLASS_HANDLE cls)
796 jitInstance->mc->cr->AddCall("getArrayRank");
797 return jitInstance->mc->repGetArrayRank(cls);
800 // Get static field data for an array
801 void* MyICJI::getArrayInitializationData(CORINFO_FIELD_HANDLE field, DWORD size)
803 jitInstance->mc->cr->AddCall("getArrayInitializationData");
804 return jitInstance->mc->repGetArrayInitializationData(field, size);
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. */
815 jitInstance->mc->cr->AddCall("canAccessClass");
816 return jitInstance->mc->repCanAccessClass(pResolvedToken, callerHandle, pAccessHelper);
819 /**********************************************************************************/
823 /**********************************************************************************/
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 */
832 jitInstance->mc->cr->AddCall("getFieldName");
833 return jitInstance->mc->repGetFieldName(ftn, moduleName);
836 // return class it belongs to
837 CORINFO_CLASS_HANDLE MyICJI::getFieldClass(CORINFO_FIELD_HANDLE field)
839 jitInstance->mc->cr->AddCall("getFieldClass");
840 return jitInstance->mc->repGetFieldClass(field);
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).
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 */
854 jitInstance->mc->cr->AddCall("getFieldType");
855 return jitInstance->mc->repGetFieldType(field, structType, memberParent);
858 // return the data member's instance offset
859 unsigned MyICJI::getFieldOffset(CORINFO_FIELD_HANDLE field)
861 jitInstance->mc->cr->AddCall("getFieldOffset");
862 return jitInstance->mc->repGetFieldOffset(field);
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)
870 jitInstance->mc->cr->AddCall("isWriteBarrierHelperRequired");
871 bool result = jitInstance->mc->repIsWriteBarrierHelperRequired(field);
875 void MyICJI::getFieldInfo(CORINFO_RESOLVED_TOKEN* pResolvedToken,
876 CORINFO_METHOD_HANDLE callerHandle,
877 CORINFO_ACCESS_FLAGS flags,
878 CORINFO_FIELD_INFO* pResult)
880 jitInstance->mc->cr->AddCall("getFieldInfo");
881 jitInstance->mc->repGetFieldInfo(pResolvedToken, callerHandle, flags, pResult);
884 // Returns true iff "fldHnd" represents a static field.
885 bool MyICJI::isFieldStatic(CORINFO_FIELD_HANDLE fldHnd)
887 jitInstance->mc->cr->AddCall("isFieldStatic");
888 return jitInstance->mc->repIsFieldStatic(fldHnd);
891 /*********************************************************************************/
895 /*********************************************************************************/
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.
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
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
911 jitInstance->mc->cr->AddCall("getBoundaries");
912 jitInstance->mc->repGetBoundaries(ftn, cILOffsets, pILOffsets, implictBoundaries);
914 // The JIT will want to call freearray on the array we pass back, so move the data into a form that complies with
918 DWORD* realOffsets = (DWORD*)allocateArray(*cILOffsets * sizeof(ICorDebugInfo::BoundaryTypes));
919 memcpy(realOffsets, *pILOffsets, *cILOffsets * sizeof(ICorDebugInfo::BoundaryTypes));
920 *pILOffsets = realOffsets;
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.
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
939 jitInstance->mc->cr->AddCall("setBoundaries");
940 jitInstance->mc->cr->recSetBoundaries(ftn, cMap, pMap);
942 freeArray(pMap); // see note in recSetBoundaries... we own this array and own destroying it.
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.
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
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
961 jitInstance->mc->cr->AddCall("getVars");
962 jitInstance->mc->repGetVars(ftn, cVars, vars, extendOthers);
964 // The JIT will want to call freearray on the array we pass back, so move the data into a form that complies with
968 ICorDebugInfo::ILVarInfo* realOffsets =
969 (ICorDebugInfo::ILVarInfo*)allocateArray(*cVars * sizeof(ICorDebugInfo::ILVarInfo));
970 memcpy(realOffsets, *vars, *cVars * sizeof(ICorDebugInfo::ILVarInfo));
977 // Report back to the EE the location of every variable.
978 // note that the JIT might split lifetimes into different
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
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
992 /*-------------------------- Misc ---------------------------------------*/
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)
999 return jitInstance->allocateArray(cBytes);
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
1006 void MyICJI::freeArray(void* array)
1008 jitInstance->freeArray(array);
1011 /*********************************************************************************/
1015 /*********************************************************************************/
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 */
1022 jitInstance->mc->cr->AddCall("getArgNext");
1023 return jitInstance->mc->repGetArgNext(args);
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 */
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);
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 */
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);
1061 // Returns type of HFA for valuetype
1062 CorInfoType MyICJI::getHFAType(CORINFO_CLASS_HANDLE hClass)
1064 jitInstance->mc->cr->AddCall("getHFAType");
1065 CorInfoType value = jitInstance->mc->repGetHFAType(hClass);
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 *****************************************************************************/
1075 // Returns the HRESULT of the current exception
1076 HRESULT MyICJI::GetErrorHRESULT(struct _EXCEPTION_POINTERS* pExceptionPointers)
1078 jitInstance->mc->cr->AddCall("GetErrorHRESULT");
1079 LogError("Hit unimplemented GetErrorHRESULT");
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)
1089 jitInstance->mc->cr->AddCall("GetErrorMessage");
1090 LogError("Hit unimplemented GetErrorMessage");
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
1101 int MyICJI::FilterException(struct _EXCEPTION_POINTERS* pExceptionPointers)
1103 jitInstance->mc->cr->AddCall("FilterException");
1104 int result = jitInstance->mc->repFilterException(pExceptionPointers);
1108 // Cleans up internal EE tracking when an exception is caught.
1109 void MyICJI::HandleException(struct _EXCEPTION_POINTERS* pExceptionPointers)
1111 jitInstance->mc->cr->AddCall("HandleException");
1114 void MyICJI::ThrowExceptionForJitResult(HRESULT result)
1116 jitInstance->mc->cr->AddCall("ThrowExceptionForJitResult");
1117 LogError("Hit unimplemented ThrowExceptionForJitResult");
1121 // Throws an exception defined by the given throw helper.
1122 void MyICJI::ThrowExceptionForHelper(const CORINFO_HELPER_DESC* throwHelper)
1124 jitInstance->mc->cr->AddCall("ThrowExceptionForHelper");
1125 LogError("Hit unimplemented ThrowExceptionForHelper");
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 *****************************************************************************/
1136 // Return details about EE internal data structures
1137 void MyICJI::getEEInfo(CORINFO_EE_INFO* pEEInfoOut)
1139 jitInstance->mc->cr->AddCall("getEEInfo");
1140 jitInstance->mc->repGetEEInfo(pEEInfoOut);
1143 // Returns name of the JIT timer log
1144 LPCWSTR MyICJI::getJitTimeLogFilename()
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;
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"));
1159 /*********************************************************************************/
1161 // Diagnostic methods
1163 /*********************************************************************************/
1165 // this function is for debugging only. Returns method token.
1166 // Returns mdMethodDefNil for dynamic methods.
1167 mdMethodDef MyICJI::getMethodDefFromMethod(CORINFO_METHOD_HANDLE hMethod)
1169 jitInstance->mc->cr->AddCall("getMethodDefFromMethod");
1170 mdMethodDef result = jitInstance->mc->repGetMethodDefFromMethod(hMethod);
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 */
1181 jitInstance->mc->cr->AddCall("getMethodName");
1182 return jitInstance->mc->repGetMethodName(ftn, moduleName);
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 */
1191 jitInstance->mc->cr->AddCall("getMethodHash");
1192 return jitInstance->mc->repGetMethodHash(ftn);
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 */
1202 jitInstance->mc->cr->AddCall("findNameOfToken");
1203 return jitInstance->mc->repFindNameOfToken(module, metaTOK, szFQName, FQNameCapacity);
1206 bool MyICJI::getSystemVAmd64PassStructInRegisterDescriptor(
1207 /* IN */ CORINFO_CLASS_HANDLE structHnd,
1208 /* OUT */ SYSTEMV_AMD64_CORINFO_STRUCT_REG_PASSING_DESCRIPTOR* structPassInRegDescPtr)
1210 jitInstance->mc->cr->AddCall("getSystemVAmd64PassStructInRegisterDescriptor");
1211 return jitInstance->mc->repGetSystemVAmd64PassStructInRegisterDescriptor(structHnd, structPassInRegDescPtr);
1214 // Stuff on ICorDynamicInfo
1215 DWORD MyICJI::getThreadTLSIndex(void** ppIndirection)
1217 jitInstance->mc->cr->AddCall("getThreadTLSIndex");
1218 return jitInstance->mc->repGetThreadTLSIndex(ppIndirection);
1221 const void* MyICJI::getInlinedCallFrameVptr(void** ppIndirection)
1223 jitInstance->mc->cr->AddCall("getInlinedCallFrameVptr");
1224 return jitInstance->mc->repGetInlinedCallFrameVptr(ppIndirection);
1227 LONG* MyICJI::getAddrOfCaptureThreadGlobal(void** ppIndirection)
1229 jitInstance->mc->cr->AddCall("getAddrOfCaptureThreadGlobal");
1230 return jitInstance->mc->repGetAddrOfCaptureThreadGlobal(ppIndirection);
1233 // return the native entry point to an EE helper (see CorInfoHelpFunc)
1234 void* MyICJI::getHelperFtn(CorInfoHelpFunc ftnNum, void** ppIndirection)
1236 jitInstance->mc->cr->AddCall("getHelperFtn");
1237 return jitInstance->mc->repGetHelperFtn(ftnNum, ppIndirection);
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)
1247 jitInstance->mc->cr->AddCall("getFunctionEntryPoint");
1248 jitInstance->mc->repGetFunctionEntryPoint(ftn, pResult, accessFlags);
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)
1256 jitInstance->mc->cr->AddCall("getFunctionFixedEntryPoint");
1257 jitInstance->mc->repGetFunctionFixedEntryPoint(ftn, pResult);
1260 // get the synchronization handle that is passed to monXstatic function
1261 void* MyICJI::getMethodSync(CORINFO_METHOD_HANDLE ftn, void** ppIndirection)
1263 jitInstance->mc->cr->AddCall("getMethodSync");
1264 return jitInstance->mc->repGetMethodSync(ftn, ppIndirection);
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.)
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)
1275 jitInstance->mc->cr->AddCall("getLazyStringLiteralHelper");
1276 return jitInstance->mc->repGetLazyStringLiteralHelper(handle);
1279 CORINFO_MODULE_HANDLE MyICJI::embedModuleHandle(CORINFO_MODULE_HANDLE handle, void** ppIndirection)
1281 jitInstance->mc->cr->AddCall("embedModuleHandle");
1282 return jitInstance->mc->repEmbedModuleHandle(handle, ppIndirection);
1285 CORINFO_CLASS_HANDLE MyICJI::embedClassHandle(CORINFO_CLASS_HANDLE handle, void** ppIndirection)
1287 jitInstance->mc->cr->AddCall("embedClassHandle");
1288 return jitInstance->mc->repEmbedClassHandle(handle, ppIndirection);
1291 CORINFO_METHOD_HANDLE MyICJI::embedMethodHandle(CORINFO_METHOD_HANDLE handle, void** ppIndirection)
1293 jitInstance->mc->cr->AddCall("embedMethodHandle");
1294 return jitInstance->mc->repEmbedMethodHandle(handle, ppIndirection);
1297 CORINFO_FIELD_HANDLE MyICJI::embedFieldHandle(CORINFO_FIELD_HANDLE handle, void** ppIndirection)
1299 jitInstance->mc->cr->AddCall("embedFieldHandle");
1300 return jitInstance->mc->repEmbedFieldHandle(handle, ppIndirection);
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.
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)
1314 jitInstance->mc->cr->AddCall("embedGenericHandle");
1315 jitInstance->mc->repEmbedGenericHandle(pResolvedToken, fEmbedParent, pResult);
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)
1327 jitInstance->mc->cr->AddCall("getLocationOfThisType");
1328 return jitInstance->mc->repGetLocationOfThisType(context);
1331 // return the unmanaged target *if method has already been prelinked.*
1332 void* MyICJI::getPInvokeUnmanagedTarget(CORINFO_METHOD_HANDLE method, void** ppIndirection)
1334 jitInstance->mc->cr->AddCall("getPInvokeUnmanagedTarget");
1335 void* result = jitInstance->mc->repGetPInvokeUnmanagedTarget(method, ppIndirection);
1339 // return address of fixup area for late-bound PInvoke calls.
1340 void* MyICJI::getAddressOfPInvokeFixup(CORINFO_METHOD_HANDLE method, void** ppIndirection)
1342 jitInstance->mc->cr->AddCall("getAddressOfPInvokeFixup");
1343 return jitInstance->mc->repGetAddressOfPInvokeFixup(method, ppIndirection);
1346 // return address of fixup area for late-bound PInvoke calls.
1347 void MyICJI::getAddressOfPInvokeTarget(CORINFO_METHOD_HANDLE method, CORINFO_CONST_LOOKUP* pLookup)
1349 jitInstance->mc->cr->AddCall("getAddressOfPInvokeTarget");
1350 jitInstance->mc->repGetAddressOfPInvokeTarget(method, pLookup);
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)
1357 jitInstance->mc->cr->AddCall("GetCookieForPInvokeCalliSig");
1358 return jitInstance->mc->repGetCookieForPInvokeCalliSig(szMetaSig, ppIndirection);
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)
1365 jitInstance->mc->cr->AddCall("canGetCookieForPInvokeCalliSig");
1366 return jitInstance->mc->repCanGetCookieForPInvokeCalliSig(szMetaSig);
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)
1374 jitInstance->mc->cr->AddCall("getJustMyCodeHandle");
1375 return jitInstance->mc->repGetJustMyCodeHandle(method, ppIndirection);
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)
1383 jitInstance->mc->cr->AddCall("GetProfilingHandle");
1384 jitInstance->mc->repGetProfilingHandle(pbHookFunction, pProfilerHandle, pbIndirectedHandles);
1387 // Returns instructions on how to make the call. See code:CORINFO_CALL_INFO for possible return values.
1388 void MyICJI::getCallInfo(
1390 CORINFO_RESOLVED_TOKEN* pResolvedToken,
1393 CORINFO_RESOLVED_TOKEN* pConstrainedResolvedToken,
1396 CORINFO_METHOD_HANDLE callerHandle,
1399 CORINFO_CALLINFO_FLAGS flags,
1402 CORINFO_CALL_INFO* pResult)
1404 jitInstance->mc->cr->AddCall("getCallInfo");
1405 DWORD exceptionCode = 0;
1406 jitInstance->mc->repGetCallInfo(pResolvedToken, pConstrainedResolvedToken, callerHandle, flags, pResult,
1408 if (exceptionCode != 0)
1409 ThrowException(exceptionCode);
1412 BOOL MyICJI::canAccessFamily(CORINFO_METHOD_HANDLE hCaller, CORINFO_CLASS_HANDLE hInstanceType)
1415 jitInstance->mc->cr->AddCall("canAccessFamily");
1416 return jitInstance->mc->repCanAccessFamily(hCaller, hInstanceType);
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)
1422 jitInstance->mc->cr->AddCall("isRIDClassDomainID");
1423 LogError("Hit unimplemented isRIDClassDomainID");
1424 DebugBreakorAV(107);
1428 // returns the class's domain ID for accessing shared statics
1429 unsigned MyICJI::getClassDomainID(CORINFO_CLASS_HANDLE cls, void** ppIndirection)
1431 jitInstance->mc->cr->AddCall("getClassDomainID");
1432 return jitInstance->mc->repGetClassDomainID(cls, ppIndirection);
1435 // return the data's address (for static fields only)
1436 void* MyICJI::getFieldAddress(CORINFO_FIELD_HANDLE field, void** ppIndirection)
1438 jitInstance->mc->cr->AddCall("getFieldAddress");
1439 return jitInstance->mc->repGetFieldAddress(field, ppIndirection);
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)
1445 jitInstance->mc->cr->AddCall("getVarArgsHandle");
1446 return jitInstance->mc->repGetVarArgsHandle(pSig, ppIndirection);
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)
1453 jitInstance->mc->cr->AddCall("canGetVarArgsHandle");
1454 return jitInstance->mc->repCanGetVarArgsHandle(pSig);
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)
1460 jitInstance->mc->cr->AddCall("constructStringLiteral");
1461 return jitInstance->mc->repConstructStringLiteral(module, metaTok, ppValue);
1464 InfoAccessType MyICJI::emptyStringLiteral(void** ppValue)
1466 jitInstance->mc->cr->AddCall("emptyStringLiteral");
1467 return jitInstance->mc->repEmptyStringLiteral(ppValue);
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)
1475 jitInstance->mc->cr->AddCall("getFieldThreadLocalStoreID");
1476 return jitInstance->mc->repGetFieldThreadLocalStoreID(field, ppIndirection);
1479 // Sets another object to intercept calls to "self" and current method being compiled
1480 void MyICJI::setOverride(ICorDynamicInfo* pOverride, CORINFO_METHOD_HANDLE currentMethod)
1482 jitInstance->mc->cr->AddCall("setOverride");
1483 LogError("Hit unimplemented setOverride");
1484 DebugBreakorAV(115);
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)
1491 jitInstance->mc->cr->AddCall("addActiveDependency");
1492 LogError("Hit unimplemented addActiveDependency");
1493 DebugBreakorAV(116);
1496 CORINFO_METHOD_HANDLE MyICJI::GetDelegateCtor(CORINFO_METHOD_HANDLE methHnd,
1497 CORINFO_CLASS_HANDLE clsHnd,
1498 CORINFO_METHOD_HANDLE targetMethodHnd,
1499 DelegateCtorArgs* pCtorData)
1501 jitInstance->mc->cr->AddCall("GetDelegateCtor");
1502 return jitInstance->mc->repGetDelegateCtor(methHnd, clsHnd, targetMethodHnd, pCtorData);
1505 void MyICJI::MethodCompileComplete(CORINFO_METHOD_HANDLE methHnd)
1507 jitInstance->mc->cr->AddCall("MethodCompileComplete");
1508 LogError("Hit unimplemented MethodCompileComplete");
1509 DebugBreakorAV(118);
1512 // return a thunk that will copy the arguments for the given signature.
1513 void* MyICJI::getTailCallCopyArgsThunk(CORINFO_SIG_INFO* pSig, CorInfoHelperTailCallSpecialHandling flags)
1515 jitInstance->mc->cr->AddCall("getTailCallCopyArgsThunk");
1516 return jitInstance->mc->repGetTailCallCopyArgsThunk(pSig, flags);
1519 // Stuff directly on ICorJitInfo
1521 // Returns extended flags for a particular compilation instance.
1522 DWORD MyICJI::getJitFlags(CORJIT_FLAGS* jitFlags, DWORD sizeInBytes)
1524 jitInstance->mc->cr->AddCall("getJitFlags");
1525 return jitInstance->mc->repGetJitFlags(jitFlags, sizeInBytes);
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)
1533 return RunWithErrorTrap(function, param);
1536 // return memory manager that the JIT can use to allocate a regular memory
1537 IEEMemoryManager* MyICJI::getMemoryManager()
1539 return InitIEEMemoryManager(jitInstance);
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 */
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);
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);
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
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.
1576 void MyICJI::reserveUnwindInfo(BOOL isFunclet, /* IN */
1577 BOOL isColdCode, /* IN */
1578 ULONG unwindSize /* IN */
1581 jitInstance->mc->cr->AddCall("reserveUnwindInfo");
1582 jitInstance->mc->cr->recReserveUnwindInfo(isFunclet, isColdCode, unwindSize);
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.
1592 // pHotCode main method code buffer, always filled in
1593 // pColdCode cold code buffer, only filled in if this is cold code,
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)
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 */
1611 jitInstance->mc->cr->AddCall("allocUnwindInfo");
1612 jitInstance->mc->cr->recAllocUnwindInfo(pHotCode, pColdCode, startOffset, endOffset, unwindSize, pUnwindBlock,
1616 // Get a block of memory needed for the code manager information,
1617 // (the info for enumerating the GC pointers while crawling the
1619 // Note that allocMem must be called first
1620 void* MyICJI::allocGCInfo(size_t size /* IN */
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);
1630 // Only used on x64.
1631 void MyICJI::yieldExecution()
1633 jitInstance->mc->cr->AddCall("yieldExecution");
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 */
1642 jitInstance->mc->cr->AddCall("setEHcount");
1643 jitInstance->mc->cr->recSetEHcount(cEH);
1646 // Set the values for one particular exception handler block.
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 */
1655 jitInstance->mc->cr->AddCall("setEHinfo");
1656 jitInstance->mc->cr->recSetEHinfo(EHnumber, clause);
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)
1664 jitInstance->mc->cr->AddCall("logMsg");
1668 //jitInstance->mc->cr->recMessageLog(fmt, args);
1669 //DebugBreakorAV(0x99);
1671 jitInstance->mc->cr->recMessageLog(fmt, args);
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)
1679 jitInstance->mc->cr->AddCall("doAssert");
1680 char buff[16 * 1024];
1681 sprintf_s(buff, sizeof(buff), "%s (%d) - %s", szFile, iLine, szExpr);
1683 LogIssue(ISSUE_ASSERT, "%s", buff);
1684 jitInstance->mc->cr->recMessageLog(buff);
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)
1691 DbgBreakCheck(szFile, iLine, szExpr);
1694 DebugBreakorAV(0x7b);
1698 void MyICJI::reportFatalError(CorJitResult result)
1700 jitInstance->mc->cr->AddCall("reportFatalError");
1701 jitInstance->mc->cr->recReportFatalError(result);
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)
1709 jitInstance->mc->cr->AddCall("allocBBProfileBuffer");
1710 return jitInstance->mc->cr->repAllocBBProfileBuffer(count, profileBuffer);
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,
1720 jitInstance->mc->cr->AddCall("getBBProfileData");
1721 return jitInstance->mc->repGetBBProfileData(ftnHnd, count, profileBuffer, numRuns);
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 */
1733 jitInstance->mc->cr->AddCall("recordCallSite");
1734 jitInstance->mc->cr->repRecordCallSite(instrOffset, callSig, methodHandle);
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 */
1746 jitInstance->mc->cr->AddCall("recordRelocation");
1747 jitInstance->mc->cr->repRecordRelocation(location, target, fRelocType, slotNum, addlDelta);
1750 WORD MyICJI::getRelocTypeHint(void* target)
1752 jitInstance->mc->cr->AddCall("getRelocTypeHint");
1753 WORD result = jitInstance->mc->repGetRelocTypeHint(target);
1757 // A callback to identify the range of address known to point to
1758 // compiler-generated native entry points that call back into
1760 void MyICJI::getModuleNativeEntryPointRange(void** pStart, /* OUT */
1761 void** pEnd /* OUT */
1764 jitInstance->mc->cr->AddCall("getModuleNativeEntryPointRange");
1765 LogError("Hit unimplemented getModuleNativeEntryPointRange");
1766 DebugBreakorAV(128);
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.
1774 DWORD MyICJI::getExpectedTargetArchitecture()
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;
1785 return IMAGE_FILE_MACHINE_UNKNOWN;