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 #ifndef _ICorJitInfoImpl
7 #define _ICorJitInfoImpl
9 // ICorJitInfoImpl: declare for implementation all the members of the ICorJitInfo interface (which are
10 // specified as pure virtual methods). This is done once, here, and all implementations share it,
11 // to avoid duplicated declarations. This file is #include'd within all the ICorJitInfo implementation
14 // NOTE: this file is in exactly the same order, with exactly the same whitespace, as the ICorJitInfo
15 // interface declaration (with the "virtual" and "= 0" syntax removed). This is to make it easy to compare
16 // against the interface declaration.
19 /**********************************************************************************/
23 /**********************************************************************************/
25 // return flags (defined above, CORINFO_FLG_PUBLIC ...)
26 DWORD getMethodAttribs(CORINFO_METHOD_HANDLE ftn /* IN */
29 // sets private JIT flags, which can be, retrieved using getAttrib.
30 void setMethodAttribs(CORINFO_METHOD_HANDLE ftn, /* IN */
31 CorInfoMethodRuntimeFlags attribs /* IN */
34 // Given a method descriptor ftnHnd, extract signature information into sigInfo
36 // 'memberParent' is typically only set when verifying. It should be the
37 // result of calling getMemberParent.
38 void getMethodSig(CORINFO_METHOD_HANDLE ftn, /* IN */
39 CORINFO_SIG_INFO* sig, /* OUT */
40 CORINFO_CLASS_HANDLE memberParent = NULL /* IN */
43 /*********************************************************************
44 * Note the following methods can only be used on functions known
45 * to be IL. This includes the method being compiled and any method
46 * that 'getMethodInfo' returns true for
47 *********************************************************************/
49 // return information about a method private to the implementation
50 // returns false if method is not IL, or is otherwise unavailable.
51 // This method is used to fetch data needed to inline functions
52 bool getMethodInfo(CORINFO_METHOD_HANDLE ftn, /* IN */
53 CORINFO_METHOD_INFO* info /* OUT */
56 // Decides if you have any limitations for inlining. If everything's OK, it will return
57 // INLINE_PASS and will fill out pRestrictions with a mask of restrictions the caller of this
58 // function must respect. If caller passes pRestrictions = NULL, if there are any restrictions
59 // INLINE_FAIL will be returned
61 // The callerHnd must be the immediate caller (i.e. when we have a chain of inlined calls)
63 // The inlined method need not be verified
65 CorInfoInline canInline(CORINFO_METHOD_HANDLE callerHnd, /* IN */
66 CORINFO_METHOD_HANDLE calleeHnd, /* IN */
67 DWORD* pRestrictions /* OUT */
70 // Reports whether or not a method can be inlined, and why. canInline is responsible for reporting all
71 // inlining results when it returns INLINE_FAIL and INLINE_NEVER. All other results are reported by the
73 void reportInliningDecision(CORINFO_METHOD_HANDLE inlinerHnd,
74 CORINFO_METHOD_HANDLE inlineeHnd,
75 CorInfoInline inlineResult,
78 // Returns false if the call is across security boundaries thus we cannot tailcall
80 // The callerHnd must be the immediate caller (i.e. when we have a chain of inlined calls)
81 bool canTailCall(CORINFO_METHOD_HANDLE callerHnd, /* IN */
82 CORINFO_METHOD_HANDLE declaredCalleeHnd, /* IN */
83 CORINFO_METHOD_HANDLE exactCalleeHnd, /* IN */
84 bool fIsTailPrefix /* IN */
87 // Reports whether or not a method can be tail called, and why.
88 // canTailCall is responsible for reporting all results when it returns
89 // false. All other results are reported by the JIT.
90 void reportTailCallDecision(CORINFO_METHOD_HANDLE callerHnd,
91 CORINFO_METHOD_HANDLE calleeHnd,
93 CorInfoTailCall tailCallResult,
96 // get individual exception handler
97 void getEHinfo(CORINFO_METHOD_HANDLE ftn, /* IN */
98 unsigned EHnumber, /* IN */
99 CORINFO_EH_CLAUSE* clause /* OUT */
102 // return class it belongs to
103 CORINFO_CLASS_HANDLE getMethodClass(CORINFO_METHOD_HANDLE method);
105 // return module it belongs to
106 CORINFO_MODULE_HANDLE getMethodModule(CORINFO_METHOD_HANDLE method);
108 // This function returns the offset of the specified method in the
109 // vtable of it's owning class or interface.
110 void getMethodVTableOffset(CORINFO_METHOD_HANDLE method, /* IN */
111 unsigned* offsetOfIndirection, /* OUT */
112 unsigned* offsetAfterIndirection,/* OUT */
113 bool* isRelative /* OUT */
116 // Find the virtual method in implementingClass that overrides virtualMethod.
117 // Return null if devirtualization is not possible.
118 CORINFO_METHOD_HANDLE resolveVirtualMethod(CORINFO_METHOD_HANDLE virtualMethod,
119 CORINFO_CLASS_HANDLE implementingClass,
120 CORINFO_CONTEXT_HANDLE ownerType);
122 void expandRawHandleIntrinsic(
123 CORINFO_RESOLVED_TOKEN * pResolvedToken,
124 CORINFO_GENERICHANDLE_RESULT * pResult);
126 // If a method's attributes have (getMethodAttribs) CORINFO_FLG_INTRINSIC set,
127 // getIntrinsicID() returns the intrinsic ID.
128 // *pMustExpand tells whether or not JIT must expand the intrinsic.
129 CorInfoIntrinsics getIntrinsicID(CORINFO_METHOD_HANDLE method, bool* pMustExpand = NULL /* OUT */
132 // Is the given module the System.Numerics.Vectors module?
133 // This defaults to false.
134 bool isInSIMDModule(CORINFO_CLASS_HANDLE classHnd); /* { return false; } */
136 // return the unmanaged calling convention for a PInvoke
137 CorInfoUnmanagedCallConv getUnmanagedCallConv(CORINFO_METHOD_HANDLE method);
139 // return if any marshaling is required for PInvoke methods. Note that
140 // method == 0 => calli. The call site sig is only needed for the varargs or calli case
141 BOOL pInvokeMarshalingRequired(CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* callSiteSig);
143 // Check constraints on method type arguments (only).
144 // The parent class should be checked separately using satisfiesClassConstraints(parent).
145 BOOL satisfiesMethodConstraints(CORINFO_CLASS_HANDLE parent, // the exact parent of the method
146 CORINFO_METHOD_HANDLE method);
148 // Given a delegate target class, a target method parent class, a target method,
149 // a delegate class, check if the method signature is compatible with the Invoke method of the delegate
150 // (under the typical instantiation of any free type variables in the memberref signatures).
151 BOOL isCompatibleDelegate(CORINFO_CLASS_HANDLE objCls, /* type of the delegate target, if any */
152 CORINFO_CLASS_HANDLE methodParentCls, /* exact parent of the target method, if any */
153 CORINFO_METHOD_HANDLE method, /* (representative) target method, if any */
154 CORINFO_CLASS_HANDLE delegateCls, /* exact type of the delegate */
155 BOOL* pfIsOpenDelegate /* is the delegate open */
158 // Indicates if the method is an instance of the generic
159 // method that passes (or has passed) verification
160 CorInfoInstantiationVerification isInstantiationOfVerifiedGeneric(CORINFO_METHOD_HANDLE method /* IN */
163 // Loads the constraints on a typical method definition, detecting cycles;
164 // for use in verification.
165 void initConstraintsForVerification(CORINFO_METHOD_HANDLE method, /* IN */
166 BOOL* pfHasCircularClassConstraints, /* OUT */
167 BOOL* pfHasCircularMethodConstraint /* OUT */
170 // Returns enum whether the method does not require verification
171 // Also see ICorModuleInfo::canSkipVerification
172 CorInfoCanSkipVerificationResult canSkipMethodVerification(CORINFO_METHOD_HANDLE ftnHandle);
174 // load and restore the method
175 void methodMustBeLoadedBeforeCodeIsRun(CORINFO_METHOD_HANDLE method);
177 CORINFO_METHOD_HANDLE mapMethodDeclToMethodImpl(CORINFO_METHOD_HANDLE method);
179 // Returns the global cookie for the /GS unsafe buffer checks
180 // The cookie might be a constant value (JIT), or a handle to memory location (Ngen)
181 void getGSCookie(GSCookie* pCookieVal, // OUT
182 GSCookie** ppCookieVal // OUT
185 /**********************************************************************************/
189 /**********************************************************************************/
191 // Resolve metadata token into runtime method handles. This function may not
192 // return normally (e.g. it may throw) if it encounters invalid metadata or other
193 // failures during token resolution.
194 void resolveToken(/* IN, OUT */ CORINFO_RESOLVED_TOKEN* pResolvedToken);
196 // Attempt to resolve a metadata token into a runtime method handle. Returns true
197 // if resolution succeeded and false otherwise (e.g. if it encounters invalid metadata
198 // during token reoslution). This method should be used instead of `resolveToken` in
199 // situations that need to be resilient to invalid metadata.
200 bool tryResolveToken(/* IN, OUT */ CORINFO_RESOLVED_TOKEN* pResolvedToken);
202 // Signature information about the call sig
203 void findSig(CORINFO_MODULE_HANDLE module, /* IN */
204 unsigned sigTOK, /* IN */
205 CORINFO_CONTEXT_HANDLE context, /* IN */
206 CORINFO_SIG_INFO* sig /* OUT */
209 // for Varargs, the signature at the call site may differ from
210 // the signature at the definition. Thus we need a way of
211 // fetching the call site information
212 void findCallSiteSig(CORINFO_MODULE_HANDLE module, /* IN */
213 unsigned methTOK, /* IN */
214 CORINFO_CONTEXT_HANDLE context, /* IN */
215 CORINFO_SIG_INFO* sig /* OUT */
218 CORINFO_CLASS_HANDLE getTokenTypeAsHandle(CORINFO_RESOLVED_TOKEN* pResolvedToken /* IN */);
220 // Returns true if the module does not require verification
222 // If fQuickCheckOnlyWithoutCommit=TRUE, the function only checks that the
223 // module does not currently require verification in the current AppDomain.
224 // This decision could change in the future, and so should not be cached.
225 // If it is cached, it should only be used as a hint.
226 // This is only used by ngen for calculating certain hints.
229 // Returns enum whether the module does not require verification
230 // Also see ICorMethodInfo::canSkipMethodVerification();
231 CorInfoCanSkipVerificationResult canSkipVerification(CORINFO_MODULE_HANDLE module /* IN */
234 // Checks if the given metadata token is valid
235 BOOL isValidToken(CORINFO_MODULE_HANDLE module, /* IN */
236 unsigned metaTOK /* IN */
239 // Checks if the given metadata token is valid StringRef
240 BOOL isValidStringRef(CORINFO_MODULE_HANDLE module, /* IN */
241 unsigned metaTOK /* IN */
244 BOOL shouldEnforceCallvirtRestriction(CORINFO_MODULE_HANDLE scope);
246 /**********************************************************************************/
250 /**********************************************************************************/
252 // If the value class 'cls' is isomorphic to a primitive type it will
253 // return that type, otherwise it will return CORINFO_TYPE_VALUECLASS
254 CorInfoType asCorInfoType(CORINFO_CLASS_HANDLE cls);
257 const char* getClassName(CORINFO_CLASS_HANDLE cls);
259 // Append a (possibly truncated) representation of the type cls to the preallocated buffer ppBuf of length pnBufLen
260 // If fNamespace=TRUE, include the namespace/enclosing classes
261 // If fFullInst=TRUE (regardless of fNamespace and fAssembly), include namespace and assembly for any type parameters
262 // If fAssembly=TRUE, suffix with a comma and the full assembly qualification
263 // return size of representation
264 int appendClassName(__deref_inout_ecount(*pnBufLen) WCHAR** ppBuf,
266 CORINFO_CLASS_HANDLE cls,
271 // Quick check whether the type is a value class. Returns the same value as getClassAttribs(cls) &
272 // CORINFO_FLG_VALUECLASS, except faster.
273 BOOL isValueClass(CORINFO_CLASS_HANDLE cls);
275 // If this method returns true, JIT will do optimization to inline the check for
276 // GetTypeFromHandle(handle) == obj.GetType()
277 BOOL canInlineTypeCheckWithObjectVTable(CORINFO_CLASS_HANDLE cls);
279 // return flags (defined above, CORINFO_FLG_PUBLIC ...)
280 DWORD getClassAttribs(CORINFO_CLASS_HANDLE cls);
282 // Returns "TRUE" iff "cls" is a struct type such that return buffers used for returning a value
283 // of this type must be stack-allocated. This will generally be true only if the struct
284 // contains GC pointers, and does not exceed some size limit. Maintaining this as an invariant allows
285 // an optimization: the JIT may assume that return buffer pointers for return types for which this predicate
286 // returns TRUE are always stack allocated, and thus, that stores to the GC-pointer fields of such return
287 // buffers do not require GC write barriers.
288 BOOL isStructRequiringStackAllocRetBuf(CORINFO_CLASS_HANDLE cls);
290 CORINFO_MODULE_HANDLE getClassModule(CORINFO_CLASS_HANDLE cls);
292 // Returns the assembly that contains the module "mod".
293 CORINFO_ASSEMBLY_HANDLE getModuleAssembly(CORINFO_MODULE_HANDLE mod);
295 // Returns the name of the assembly "assem".
296 const char* getAssemblyName(CORINFO_ASSEMBLY_HANDLE assem);
298 // Allocate and delete process-lifetime objects. Should only be
299 // referred to from static fields, lest a leak occur.
300 // Note that "LongLifetimeFree" does not execute destructors, if "obj"
301 // is an array of a struct type with a destructor.
302 void* LongLifetimeMalloc(size_t sz);
303 void LongLifetimeFree(void* obj);
305 size_t getClassModuleIdForStatics(CORINFO_CLASS_HANDLE cls, CORINFO_MODULE_HANDLE* pModule, void** ppIndirection);
307 // return the number of bytes needed by an instance of the class
308 unsigned getClassSize(CORINFO_CLASS_HANDLE cls);
310 unsigned getClassAlignmentRequirement(CORINFO_CLASS_HANDLE cls, BOOL fDoubleAlignHint = FALSE);
312 // This is only called for Value classes. It returns a boolean array
313 // in representing of 'cls' from a GC perspective. The class is
314 // assumed to be an array of machine words
315 // (of length // getClassSize(cls) / sizeof(void*)),
316 // 'gcPtrs' is a pointer to an array of BYTEs of this length.
317 // getClassGClayout fills in this array so that gcPtrs[i] is set
318 // to one of the CorInfoGCType values which is the GC type of
319 // the i-th machine word of an object of type 'cls'
320 // returns the number of GC pointers in the array
321 unsigned getClassGClayout(CORINFO_CLASS_HANDLE cls, /* IN */
322 BYTE* gcPtrs /* OUT */
325 // returns the number of instance fields in a class
326 unsigned getClassNumInstanceFields(CORINFO_CLASS_HANDLE cls /* IN */
329 CORINFO_FIELD_HANDLE getFieldInClass(CORINFO_CLASS_HANDLE clsHnd, INT num);
331 BOOL checkMethodModifier(CORINFO_METHOD_HANDLE hMethod, LPCSTR modifier, BOOL fOptional);
333 // returns the "NEW" helper optimized for "newCls."
334 CorInfoHelpFunc getNewHelper(CORINFO_RESOLVED_TOKEN* pResolvedToken, CORINFO_METHOD_HANDLE callerHandle);
336 // returns the newArr (1-Dim array) helper optimized for "arrayCls."
337 CorInfoHelpFunc getNewArrHelper(CORINFO_CLASS_HANDLE arrayCls);
339 // returns the optimized "IsInstanceOf" or "ChkCast" helper
340 CorInfoHelpFunc getCastingHelper(CORINFO_RESOLVED_TOKEN* pResolvedToken, bool fThrowing);
342 // returns helper to trigger static constructor
343 CorInfoHelpFunc getSharedCCtorHelper(CORINFO_CLASS_HANDLE clsHnd);
345 CorInfoHelpFunc getSecurityPrologHelper(CORINFO_METHOD_HANDLE ftn);
347 // This is not pretty. Boxing nullable<T> actually returns
348 // a boxed<T> not a boxed Nullable<T>. This call allows the verifier
349 // to call back to the EE on the 'box' instruction and get the transformed
350 // type to use for verification.
351 CORINFO_CLASS_HANDLE getTypeForBox(CORINFO_CLASS_HANDLE cls);
353 // returns the correct box helper for a particular class. Note
354 // that if this returns CORINFO_HELP_BOX, the JIT can assume
355 // 'standard' boxing (allocate object and copy), and optimize
356 CorInfoHelpFunc getBoxHelper(CORINFO_CLASS_HANDLE cls);
358 // returns the unbox helper. If 'helperCopies' points to a true
359 // value it means the JIT is requesting a helper that unboxes the
360 // value into a particular location and thus has the signature
361 // void unboxHelper(void* dest, CORINFO_CLASS_HANDLE cls, Object* obj)
362 // Otherwise (it is null or points at a FALSE value) it is requesting
363 // a helper that returns a pointer to the unboxed data
364 // void* unboxHelper(CORINFO_CLASS_HANDLE cls, Object* obj)
365 // The EE has the option of NOT returning the copy style helper
366 // (But must be able to always honor the non-copy style helper)
367 // The EE set 'helperCopies' on return to indicate what kind of
368 // helper has been created.
370 CorInfoHelpFunc getUnBoxHelper(CORINFO_CLASS_HANDLE cls);
372 bool getReadyToRunHelper(CORINFO_RESOLVED_TOKEN* pResolvedToken,
373 CORINFO_LOOKUP_KIND* pGenericLookupKind,
375 CORINFO_CONST_LOOKUP* pLookup);
377 void getReadyToRunDelegateCtorHelper(CORINFO_RESOLVED_TOKEN* pTargetMethod,
378 CORINFO_CLASS_HANDLE delegateType,
379 CORINFO_LOOKUP* pLookup);
381 const char* getHelperName(CorInfoHelpFunc);
383 // This function tries to initialize the class (run the class constructor).
384 // this function returns whether the JIT must insert helper calls before
385 // accessing static field or method.
387 // See code:ICorClassInfo#ClassConstruction.
388 CorInfoInitClassResult initClass(CORINFO_FIELD_HANDLE field, // Non-NULL - inquire about cctor trigger before static
389 // field access NULL - inquire about cctor trigger in
391 CORINFO_METHOD_HANDLE method, // Method referencing the field or prolog
392 CORINFO_CONTEXT_HANDLE context, // Exact context of method
393 BOOL speculative = FALSE // TRUE means don't actually run it
396 // This used to be called "loadClass". This records the fact
397 // that the class must be loaded (including restored if necessary) before we execute the
398 // code that we are currently generating. When jitting code
399 // the function loads the class immediately. When zapping code
400 // the zapper will if necessary use the call to record the fact that we have
401 // to do a fixup/restore before running the method currently being generated.
403 // This is typically used to ensure value types are loaded before zapped
404 // code that manipulates them is executed, so that the GC can access information
405 // about those value types.
406 void classMustBeLoadedBeforeCodeIsRun(CORINFO_CLASS_HANDLE cls);
408 // returns the class handle for the special builtin classes
409 CORINFO_CLASS_HANDLE getBuiltinClass(CorInfoClassId classId);
411 // "System.Int32" ==> CORINFO_TYPE_INT..
412 CorInfoType getTypeForPrimitiveValueClass(CORINFO_CLASS_HANDLE cls);
414 // TRUE if child is a subtype of parent
415 // if parent is an interface, then does child implement / extend parent
416 BOOL canCast(CORINFO_CLASS_HANDLE child, // subtype (extends parent)
417 CORINFO_CLASS_HANDLE parent // base type
420 // TRUE if cls1 and cls2 are considered equivalent types.
421 BOOL areTypesEquivalent(CORINFO_CLASS_HANDLE cls1, CORINFO_CLASS_HANDLE cls2);
423 // returns is the intersection of cls1 and cls2.
424 CORINFO_CLASS_HANDLE mergeClasses(CORINFO_CLASS_HANDLE cls1, CORINFO_CLASS_HANDLE cls2);
426 // Given a class handle, returns the Parent type.
427 // For COMObjectType, it returns Class Handle of System.Object.
428 // Returns 0 if System.Object is passed in.
429 CORINFO_CLASS_HANDLE getParentType(CORINFO_CLASS_HANDLE cls);
431 // Returns the CorInfoType of the "child type". If the child type is
432 // not a primitive type, *clsRet will be set.
433 // Given an Array of Type Foo, returns Foo.
434 // Given BYREF Foo, returns Foo
435 CorInfoType getChildType(CORINFO_CLASS_HANDLE clsHnd, CORINFO_CLASS_HANDLE* clsRet);
437 // Check constraints on type arguments of this class and parent classes
438 BOOL satisfiesClassConstraints(CORINFO_CLASS_HANDLE cls);
440 // Check if this is a single dimensional array type
441 BOOL isSDArray(CORINFO_CLASS_HANDLE cls);
443 // Get the numbmer of dimensions in an array
444 unsigned getArrayRank(CORINFO_CLASS_HANDLE cls);
446 // Get static field data for an array
447 void* getArrayInitializationData(CORINFO_FIELD_HANDLE field, DWORD size);
449 // Check Visibility rules.
450 CorInfoIsAccessAllowedResult canAccessClass(CORINFO_RESOLVED_TOKEN* pResolvedToken,
451 CORINFO_METHOD_HANDLE callerHandle,
452 CORINFO_HELPER_DESC* pAccessHelper /* If canAccessMethod returns something
453 other than ALLOWED, then this is
457 /**********************************************************************************/
461 /**********************************************************************************/
463 // this function is for debugging only. It returns the field name
464 // and if 'moduleName' is non-null, it sets it to something that will
465 // says which method (a class name, or a module name)
466 const char* getFieldName(CORINFO_FIELD_HANDLE ftn, /* IN */
467 const char** moduleName /* OUT */
470 // return class it belongs to
471 CORINFO_CLASS_HANDLE getFieldClass(CORINFO_FIELD_HANDLE field);
473 // Return the field's type, if it is CORINFO_TYPE_VALUECLASS 'structType' is set
474 // the field's value class (if 'structType' == 0, then don't bother
475 // the structure info).
477 // 'memberParent' is typically only set when verifying. It should be the
478 // result of calling getMemberParent.
479 CorInfoType getFieldType(CORINFO_FIELD_HANDLE field,
480 CORINFO_CLASS_HANDLE* structType,
481 CORINFO_CLASS_HANDLE memberParent = NULL /* IN */
484 // return the data member's instance offset
485 unsigned getFieldOffset(CORINFO_FIELD_HANDLE field);
487 // TODO: jit64 should be switched to the same plan as the i386 jits - use
488 // getClassGClayout to figure out the need for writebarrier helper, and inline the copying.
489 // The interpretted value class copy is slow. Once this happens, USE_WRITE_BARRIER_HELPERS
490 bool isWriteBarrierHelperRequired(CORINFO_FIELD_HANDLE field);
492 void getFieldInfo(CORINFO_RESOLVED_TOKEN* pResolvedToken,
493 CORINFO_METHOD_HANDLE callerHandle,
494 CORINFO_ACCESS_FLAGS flags,
495 CORINFO_FIELD_INFO* pResult);
497 // Returns true iff "fldHnd" represents a static field.
498 bool isFieldStatic(CORINFO_FIELD_HANDLE fldHnd);
500 /*********************************************************************************/
504 /*********************************************************************************/
506 // Query the EE to find out where interesting break points
507 // in the code are. The native compiler will ensure that these places
508 // have a corresponding break point in native code.
510 // Note that unless CORJIT_FLAG_DEBUG_CODE is specified, this function will
511 // be used only as a hint and the native compiler should not change its
513 void getBoundaries(CORINFO_METHOD_HANDLE ftn, // [IN] method of interest
514 unsigned int* cILOffsets, // [OUT] size of pILOffsets
515 DWORD** pILOffsets, // [OUT] IL offsets of interest
516 // jit MUST free with freeArray!
517 ICorDebugInfo::BoundaryTypes* implictBoundaries // [OUT] tell jit, all boundries of this type
520 // Report back the mapping from IL to native code,
521 // this map should include all boundaries that 'getBoundaries'
522 // reported as interesting to the debugger.
524 // Note that debugger (and profiler) is assuming that all of the
525 // offsets form a contiguous block of memory, and that the
526 // OffsetMapping is sorted in order of increasing native offset.
527 void setBoundaries(CORINFO_METHOD_HANDLE ftn, // [IN] method of interest
528 ULONG32 cMap, // [IN] size of pMap
529 ICorDebugInfo::OffsetMapping* pMap // [IN] map including all points of interest.
530 // jit allocated with allocateArray, EE frees
533 // Query the EE to find out the scope of local varables.
534 // normally the JIT would trash variables after last use, but
535 // under debugging, the JIT needs to keep them live over their
536 // entire scope so that they can be inspected.
538 // Note that unless CORJIT_FLAG_DEBUG_CODE is specified, this function will
539 // be used only as a hint and the native compiler should not change its
541 void getVars(CORINFO_METHOD_HANDLE ftn, // [IN] method of interest
542 ULONG32* cVars, // [OUT] size of 'vars'
543 ICorDebugInfo::ILVarInfo** vars, // [OUT] scopes of variables of interest
544 // jit MUST free with freeArray!
545 bool* extendOthers // [OUT] it TRUE, then assume the scope
546 // of unmentioned vars is entire method
549 // Report back to the EE the location of every variable.
550 // note that the JIT might split lifetimes into different
553 void setVars(CORINFO_METHOD_HANDLE ftn, // [IN] method of interest
554 ULONG32 cVars, // [IN] size of 'vars'
555 ICorDebugInfo::NativeVarInfo* vars // [IN] map telling where local vars are stored at what points
556 // jit allocated with allocateArray, EE frees
559 /*-------------------------- Misc ---------------------------------------*/
561 // Used to allocate memory that needs to handed to the EE.
562 // For eg, use this to allocated memory for reporting debug info,
563 // which will be handed to the EE by setVars() and setBoundaries()
564 void* allocateArray(ULONG cBytes);
566 // JitCompiler will free arrays passed by the EE using this
567 // For eg, The EE returns memory in getVars() and getBoundaries()
568 // to the JitCompiler, which the JitCompiler should release using
570 void freeArray(void* array);
572 /*********************************************************************************/
576 /*********************************************************************************/
578 // advance the pointer to the argument list.
579 // a ptr of 0, is special and always means the first argument
580 CORINFO_ARG_LIST_HANDLE getArgNext(CORINFO_ARG_LIST_HANDLE args /* IN */
583 // Get the type of a particular argument
584 // CORINFO_TYPE_UNDEF is returned when there are no more arguments
585 // If the type returned is a primitive type (or an enum) *vcTypeRet set to NULL
586 // otherwise it is set to the TypeHandle associted with the type
587 // Enumerations will always look their underlying type (probably should fix this)
588 // Otherwise vcTypeRet is the type as would be seen by the IL,
589 // The return value is the type that is used for calling convention purposes
590 // (Thus if the EE wants a value class to be passed like an int, then it will
591 // return CORINFO_TYPE_INT
592 CorInfoTypeWithMod getArgType(CORINFO_SIG_INFO* sig, /* IN */
593 CORINFO_ARG_LIST_HANDLE args, /* IN */
594 CORINFO_CLASS_HANDLE* vcTypeRet /* OUT */
597 // If the Arg is a CORINFO_TYPE_CLASS fetch the class handle associated with it
598 CORINFO_CLASS_HANDLE getArgClass(CORINFO_SIG_INFO* sig, /* IN */
599 CORINFO_ARG_LIST_HANDLE args /* IN */
602 // Returns type of HFA for valuetype
603 CorInfoType getHFAType(CORINFO_CLASS_HANDLE hClass);
605 /*****************************************************************************
606 * ICorErrorInfo contains methods to deal with SEH exceptions being thrown
607 * from the corinfo interface. These methods may be called when an exception
608 * with code EXCEPTION_COMPLUS is caught.
609 *****************************************************************************/
611 // Returns the HRESULT of the current exception
612 HRESULT GetErrorHRESULT(struct _EXCEPTION_POINTERS* pExceptionPointers);
614 // Fetches the message of the current exception
615 // Returns the size of the message (including terminating null). This can be
616 // greater than bufferLength if the buffer is insufficient.
617 ULONG GetErrorMessage(__inout_ecount(bufferLength) LPWSTR buffer, ULONG bufferLength);
619 // returns EXCEPTION_EXECUTE_HANDLER if it is OK for the compile to handle the
620 // exception, abort some work (like the inlining) and continue compilation
621 // returns EXCEPTION_CONTINUE_SEARCH if exception must always be handled by the EE
622 // things like ThreadStoppedException ...
623 // returns EXCEPTION_CONTINUE_EXECUTION if exception is fixed up by the EE
625 int FilterException(struct _EXCEPTION_POINTERS* pExceptionPointers);
627 // Cleans up internal EE tracking when an exception is caught.
628 void HandleException(struct _EXCEPTION_POINTERS* pExceptionPointers);
630 void ThrowExceptionForJitResult(HRESULT result);
632 // Throws an exception defined by the given throw helper.
633 void ThrowExceptionForHelper(const CORINFO_HELPER_DESC* throwHelper);
635 // Runs the given function under an error trap. This allows the JIT to make calls
636 // to interface functions that may throw exceptions without needing to be aware of
637 // the EH ABI, exception types, etc. Returns true if the given function completed
638 // successfully and false otherwise.
639 bool runWithErrorTrap(void (*function)(void*), // The function to run
640 void* parameter // The context parameter that will be passed to the function and the handler
643 /*****************************************************************************
644 * ICorStaticInfo contains EE interface methods which return values that are
645 * constant from invocation to invocation. Thus they may be embedded in
646 * persisted information like statically generated code. (This is of course
647 * assuming that all code versions are identical each time.)
648 *****************************************************************************/
650 // Return details about EE internal data structures
651 void getEEInfo(CORINFO_EE_INFO* pEEInfoOut);
653 // Returns name of the JIT timer log
654 LPCWSTR getJitTimeLogFilename();
656 /*********************************************************************************/
658 // Diagnostic methods
660 /*********************************************************************************/
662 // this function is for debugging only. Returns method token.
663 // Returns mdMethodDefNil for dynamic methods.
664 mdMethodDef getMethodDefFromMethod(CORINFO_METHOD_HANDLE hMethod);
666 // this function is for debugging only. It returns the method name
667 // and if 'moduleName' is non-null, it sets it to something that will
668 // says which method (a class name, or a module name)
669 const char* getMethodName(CORINFO_METHOD_HANDLE ftn, /* IN */
670 const char** moduleName /* OUT */
673 // Return method name as in metadata, or nullptr if there is none,
674 // and optionally return the class name as in metadata.
675 // Suitable for non-debugging use.
676 const char* getMethodNameFromMetadata(CORINFO_METHOD_HANDLE ftn, /* IN */
677 const char** className, /* OUT */
678 const char** namespaceName /* OUT */
681 // this function is for debugging only. It returns a value that
682 // is will always be the same for a given method. It is used
683 // to implement the 'jitRange' functionality
684 unsigned getMethodHash(CORINFO_METHOD_HANDLE ftn /* IN */
687 // this function is for debugging only.
688 size_t findNameOfToken(CORINFO_MODULE_HANDLE module, /* IN */
689 mdToken metaTOK, /* IN */
690 __out_ecount(FQNameCapacity) char* szFQName, /* OUT */
691 size_t FQNameCapacity /* IN */
694 // returns whether the struct is enregisterable. Only valid on a System V VM. Returns true on success, false on failure.
695 bool getSystemVAmd64PassStructInRegisterDescriptor(
696 /* IN */ CORINFO_CLASS_HANDLE structHnd,
697 /* OUT */ SYSTEMV_AMD64_CORINFO_STRUCT_REG_PASSING_DESCRIPTOR* structPassInRegDescPtr);
699 /*****************************************************************************
700 * ICorDynamicInfo contains EE interface methods which return values that may
701 * change from invocation to invocation. They cannot be embedded in persisted
702 * data; they must be requeried each time the EE is run.
703 *****************************************************************************/
706 // These methods return values to the JIT which are not constant
707 // from session to session.
709 // These methods take an extra parameter : void **ppIndirection.
710 // If a JIT supports generation of prejit code (install-o-jit), it
711 // must pass a non-null value for this parameter, and check the
712 // resulting value. If *ppIndirection is NULL, code should be
713 // generated normally. If non-null, then the value of
714 // *ppIndirection is an address in the cookie table, and the code
715 // generator needs to generate an indirection through the table to
716 // get the resulting value. In this case, the return result of the
717 // function must NOT be directly embedded in the generated code.
719 // Note that if a JIT does not support prejit code generation, it
720 // may ignore the extra parameter & pass the default of NULL - the
721 // prejit ICorDynamicInfo implementation will see this & generate
722 // an error if the jitter is used in a prejit scenario.
725 // Return details about EE internal data structures
727 DWORD getThreadTLSIndex(void** ppIndirection = NULL);
729 const void* getInlinedCallFrameVptr(void** ppIndirection = NULL);
731 LONG* getAddrOfCaptureThreadGlobal(void** ppIndirection = NULL);
733 // return the native entry point to an EE helper (see CorInfoHelpFunc)
734 void* getHelperFtn(CorInfoHelpFunc ftnNum, void** ppIndirection = NULL);
736 // return a callable address of the function (native code). This function
737 // may return a different value (depending on whether the method has
738 // been JITed or not.
739 void getFunctionEntryPoint(CORINFO_METHOD_HANDLE ftn, /* IN */
740 CORINFO_CONST_LOOKUP* pResult, /* OUT */
741 CORINFO_ACCESS_FLAGS accessFlags = CORINFO_ACCESS_ANY);
743 // return a directly callable address. This can be used similarly to the
744 // value returned by getFunctionEntryPoint() except that it is
745 // guaranteed to be multi callable entrypoint.
746 void getFunctionFixedEntryPoint(CORINFO_METHOD_HANDLE ftn, CORINFO_CONST_LOOKUP* pResult);
748 // get the synchronization handle that is passed to monXstatic function
749 void* getMethodSync(CORINFO_METHOD_HANDLE ftn, void** ppIndirection = NULL);
751 // get slow lazy string literal helper to use (CORINFO_HELP_STRCNS*).
752 // Returns CORINFO_HELP_UNDEF if lazy string literal helper cannot be used.
753 CorInfoHelpFunc getLazyStringLiteralHelper(CORINFO_MODULE_HANDLE handle);
755 CORINFO_MODULE_HANDLE embedModuleHandle(CORINFO_MODULE_HANDLE handle, void** ppIndirection = NULL);
757 CORINFO_CLASS_HANDLE embedClassHandle(CORINFO_CLASS_HANDLE handle, void** ppIndirection = NULL);
759 CORINFO_METHOD_HANDLE embedMethodHandle(CORINFO_METHOD_HANDLE handle, void** ppIndirection = NULL);
761 CORINFO_FIELD_HANDLE embedFieldHandle(CORINFO_FIELD_HANDLE handle, void** ppIndirection = NULL);
763 // Given a module scope (module), a method handle (context) and
764 // a metadata token (metaTOK), fetch the handle
765 // (type, field or method) associated with the token.
766 // If this is not possible at compile-time (because the current method's
767 // code is shared and the token contains generic parameters)
768 // then indicate how the handle should be looked up at run-time.
770 void embedGenericHandle(CORINFO_RESOLVED_TOKEN* pResolvedToken,
771 BOOL fEmbedParent, // TRUE - embeds parent type handle of the field/method handle
772 CORINFO_GENERICHANDLE_RESULT* pResult);
774 // Return information used to locate the exact enclosing type of the current method.
775 // Used only to invoke .cctor method from code shared across generic instantiations
776 // !needsRuntimeLookup statically known (enclosing type of method itself)
777 // needsRuntimeLookup:
778 // CORINFO_LOOKUP_THISOBJ use vtable pointer of 'this' param
779 // CORINFO_LOOKUP_CLASSPARAM use vtable hidden param
780 // CORINFO_LOOKUP_METHODPARAM use enclosing type of method-desc hidden param
781 CORINFO_LOOKUP_KIND getLocationOfThisType(CORINFO_METHOD_HANDLE context);
783 // NOTE: the two methods below--getPInvokeUnmanagedTarget and getAddressOfPInvokeFixup--are
784 // deprecated. New code should instead use getAddressOfPInvokeTarget, which subsumes the
785 // functionality of these methods.
787 // return the unmanaged target *if method has already been prelinked.*
788 void* getPInvokeUnmanagedTarget(CORINFO_METHOD_HANDLE method, void** ppIndirection = NULL);
790 // return address of fixup area for late-bound PInvoke calls.
791 void* getAddressOfPInvokeFixup(CORINFO_METHOD_HANDLE method, void** ppIndirection = NULL);
793 // return the address of the PInvoke target. May be a fixup area in the
794 // case of late-bound PInvoke calls.
795 void getAddressOfPInvokeTarget(CORINFO_METHOD_HANDLE method, CORINFO_CONST_LOOKUP* pLookup);
797 // Generate a cookie based on the signature that would needs to be passed
798 // to CORINFO_HELP_PINVOKE_CALLI
799 LPVOID GetCookieForPInvokeCalliSig(CORINFO_SIG_INFO* szMetaSig, void** ppIndirection = NULL);
801 // returns true if a VM cookie can be generated for it (might be false due to cross-module
802 // inlining, in which case the inlining should be aborted)
803 bool canGetCookieForPInvokeCalliSig(CORINFO_SIG_INFO* szMetaSig);
805 // Gets a handle that is checked to see if the current method is
806 // included in "JustMyCode"
807 CORINFO_JUST_MY_CODE_HANDLE getJustMyCodeHandle(CORINFO_METHOD_HANDLE method,
808 CORINFO_JUST_MY_CODE_HANDLE** ppIndirection = NULL);
810 // Gets a method handle that can be used to correlate profiling data.
811 // This is the IP of a native method, or the address of the descriptor struct
812 // for IL. Always guaranteed to be unique per process, and not to move. */
813 void GetProfilingHandle(BOOL* pbHookFunction, void** pProfilerHandle, BOOL* pbIndirectedHandles);
815 // Returns instructions on how to make the call. See code:CORINFO_CALL_INFO for possible return values.
818 CORINFO_RESOLVED_TOKEN* pResolvedToken,
821 CORINFO_RESOLVED_TOKEN* pConstrainedResolvedToken,
824 CORINFO_METHOD_HANDLE callerHandle,
827 CORINFO_CALLINFO_FLAGS flags,
830 CORINFO_CALL_INFO* pResult);
832 BOOL canAccessFamily(CORINFO_METHOD_HANDLE hCaller, CORINFO_CLASS_HANDLE hInstanceType);
834 // Returns TRUE if the Class Domain ID is the RID of the class (currently true for every class
835 // except reflection emitted classes and generics)
836 BOOL isRIDClassDomainID(CORINFO_CLASS_HANDLE cls);
838 // returns the class's domain ID for accessing shared statics
839 unsigned getClassDomainID(CORINFO_CLASS_HANDLE cls, void** ppIndirection = NULL);
841 // return the data's address (for static fields only)
842 void* getFieldAddress(CORINFO_FIELD_HANDLE field, void** ppIndirection = NULL);
844 // registers a vararg sig & returns a VM cookie for it (which can contain other stuff)
845 CORINFO_VARARGS_HANDLE getVarArgsHandle(CORINFO_SIG_INFO* pSig, void** ppIndirection = NULL);
847 // returns true if a VM cookie can be generated for it (might be false due to cross-module
848 // inlining, in which case the inlining should be aborted)
849 bool canGetVarArgsHandle(CORINFO_SIG_INFO* pSig);
851 // Allocate a string literal on the heap and return a handle to it
852 InfoAccessType constructStringLiteral(CORINFO_MODULE_HANDLE module, mdToken metaTok, void** ppValue);
854 InfoAccessType emptyStringLiteral(void** ppValue);
856 // (static fields only) given that 'field' refers to thread local store,
857 // return the ID (TLS index), which is used to find the begining of the
858 // TLS data area for the particular DLL 'field' is associated with.
859 DWORD getFieldThreadLocalStoreID(CORINFO_FIELD_HANDLE field, void** ppIndirection = NULL);
861 // Sets another object to intercept calls to "self" and current method being compiled
862 void setOverride(ICorDynamicInfo* pOverride, CORINFO_METHOD_HANDLE currentMethod);
864 // Adds an active dependency from the context method's module to the given module
865 // This is internal callback for the EE. JIT should not call it directly.
866 void addActiveDependency(CORINFO_MODULE_HANDLE moduleFrom, CORINFO_MODULE_HANDLE moduleTo);
868 CORINFO_METHOD_HANDLE GetDelegateCtor(CORINFO_METHOD_HANDLE methHnd,
869 CORINFO_CLASS_HANDLE clsHnd,
870 CORINFO_METHOD_HANDLE targetMethodHnd,
871 DelegateCtorArgs* pCtorData);
873 void MethodCompileComplete(CORINFO_METHOD_HANDLE methHnd);
875 // return a thunk that will copy the arguments for the given signature.
876 void* getTailCallCopyArgsThunk(CORINFO_SIG_INFO* pSig, CorInfoHelperTailCallSpecialHandling flags);
878 // return memory manager that the JIT can use to allocate a regular memory
879 IEEMemoryManager* getMemoryManager();
881 // get a block of memory for the code, readonly data, and read-write data
882 void allocMem(ULONG hotCodeSize, /* IN */
883 ULONG coldCodeSize, /* IN */
884 ULONG roDataSize, /* IN */
885 ULONG xcptnsCount, /* IN */
886 CorJitAllocMemFlag flag, /* IN */
887 void** hotCodeBlock, /* OUT */
888 void** coldCodeBlock, /* OUT */
889 void** roDataBlock /* OUT */
892 // Reserve memory for the method/funclet's unwind information.
893 // Note that this must be called before allocMem. It should be
894 // called once for the main method, once for every funclet, and
895 // once for every block of cold code for which allocUnwindInfo
898 // This is necessary because jitted code must allocate all the
899 // memory needed for the unwindInfo at the allocMem call.
900 // For prejitted code we split up the unwinding information into
901 // separate sections .rdata and .pdata.
903 void reserveUnwindInfo(BOOL isFunclet, /* IN */
904 BOOL isColdCode, /* IN */
905 ULONG unwindSize /* IN */
908 // Allocate and initialize the .rdata and .pdata for this method or
909 // funclet, and get the block of memory needed for the machine-specific
910 // unwind information (the info for crawling the stack frame).
911 // Note that allocMem must be called first.
915 // pHotCode main method code buffer, always filled in
916 // pColdCode cold code buffer, only filled in if this is cold code,
918 // startOffset start of code block, relative to appropriate code buffer
919 // (e.g. pColdCode if cold, pHotCode if hot).
920 // endOffset end of code block, relative to appropriate code buffer
921 // unwindSize size of unwind info pointed to by pUnwindBlock
922 // pUnwindBlock pointer to unwind info
923 // funcKind type of funclet (main method code, handler, filter)
925 void allocUnwindInfo(BYTE* pHotCode, /* IN */
926 BYTE* pColdCode, /* IN */
927 ULONG startOffset, /* IN */
928 ULONG endOffset, /* IN */
929 ULONG unwindSize, /* IN */
930 BYTE* pUnwindBlock, /* IN */
931 CorJitFuncKind funcKind /* IN */
934 // Get a block of memory needed for the code manager information,
935 // (the info for enumerating the GC pointers while crawling the
937 // Note that allocMem must be called first
938 void* allocGCInfo(size_t size /* IN */
941 void yieldExecution();
943 // Indicate how many exception handler blocks are to be returned.
944 // This is guaranteed to be called before any 'setEHinfo' call.
945 // Note that allocMem must be called before this method can be called.
946 void setEHcount(unsigned cEH /* IN */
949 // Set the values for one particular exception handler block.
951 // Handler regions should be lexically contiguous.
952 // This is because FinallyIsUnwinding() uses lexicality to
953 // determine if a "finally" clause is executing.
954 void setEHinfo(unsigned EHnumber, /* IN */
955 const CORINFO_EH_CLAUSE* clause /* IN */
958 // Level -> fatalError, Level 2 -> Error, Level 3 -> Warning
959 // Level 4 means happens 10 times in a run, level 5 means 100, level 6 means 1000 ...
960 // returns non-zero if the logging succeeded
961 BOOL logMsg(unsigned level, const char* fmt, va_list args);
963 // do an assert. will return true if the code should retry (DebugBreak)
964 // returns false, if the assert should be igored.
965 int doAssert(const char* szFile, int iLine, const char* szExpr);
967 void reportFatalError(CorJitResult result);
970 struct ProfileBuffer // Also defined here: code:CORBBTPROF_BLOCK_DATA
973 ULONG ExecutionCount;
977 // allocate a basic block profile buffer where execution counts will be stored
978 // for jitted basic blocks.
979 HRESULT allocBBProfileBuffer(ULONG count, // The number of basic blocks that we have
980 ProfileBuffer** profileBuffer);
982 // get profile information to be used for optimizing the current method. The format
983 // of the buffer is the same as the format the JIT passes to allocBBProfileBuffer.
984 HRESULT getBBProfileData(CORINFO_METHOD_HANDLE ftnHnd,
985 ULONG* count, // The number of basic blocks that we have
986 ProfileBuffer** profileBuffer,
989 // Associates a native call site, identified by its offset in the native code stream, with
990 // the signature information and method handle the JIT used to lay out the call site. If
991 // the call site has no signature information (e.g. a helper call) or has no method handle
992 // (e.g. a CALLI P/Invoke), then null should be passed instead.
993 void recordCallSite(ULONG instrOffset, /* IN */
994 CORINFO_SIG_INFO* callSig, /* IN */
995 CORINFO_METHOD_HANDLE methodHandle /* IN */
998 // A relocation is recorded if we are pre-jitting.
999 // A jump thunk may be inserted if we are jitting
1000 void recordRelocation(void* location, /* IN */
1001 void* target, /* IN */
1002 WORD fRelocType, /* IN */
1003 WORD slotNum, /* IN */
1004 INT32 addlDelta /* IN */
1007 WORD getRelocTypeHint(void* target);
1009 // A callback to identify the range of address known to point to
1010 // compiler-generated native entry points that call back into
1012 void getModuleNativeEntryPointRange(void** pStart, /* OUT */
1013 void** pEnd /* OUT */
1016 // For what machine does the VM expect the JIT to generate code? The VM
1017 // returns one of the IMAGE_FILE_MACHINE_* values. Note that if the VM
1018 // is cross-compiling (such as the case for crossgen), it will return a
1019 // different value than if it was compiling for the host architecture.
1021 DWORD getExpectedTargetArchitecture();
1023 // Fetches extended flags for a particular compilation instance. Returns
1024 // the number of bytes written to the provided buffer.
1025 DWORD getJitFlags(CORJIT_FLAGS* flags, /* IN: Points to a buffer that will hold the extended flags. */
1026 DWORD sizeInBytes /* IN: The size of the buffer. Note that this is effectively a
1027 version number for the CORJIT_FLAGS value. */
1030 #endif // _ICorJitInfoImpl