1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // See the LICENSE file in the project root for more information.
7 /*****************************************************************************\
9 * CorInfo.h - EE / Code generator interface *
11 *******************************************************************************
13 * This file exposes CLR runtime functionality. It can be used by compilers,
14 * both Just-in-time and ahead-of-time, to generate native code which
15 * executes in the runtime environment.
16 *******************************************************************************
18 //////////////////////////////////////////////////////////////////////////////////////////////////////////
20 // NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE
22 // The JIT/EE interface is versioned. By "interface", we mean mean any and all communication between the
23 // JIT and the EE. Any time a change is made to the interface, the JIT/EE interface version identifier
24 // must be updated. See code:JITEEVersionIdentifier for more information.
26 // NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE
28 //////////////////////////////////////////////////////////////////////////////////////////////////////////
32 The semantic contract between the EE and the JIT should be documented here It is incomplete, but as time goes
33 on, that hopefully will change
35 See file:../../doc/BookOfTheRuntime/JIT/JIT%20Design.doc for details on the JIT compiler. See
36 code:EEStartup#TableOfContents for information on the runtime as a whole.
38 -------------------------------------------------------------------------------
41 The tokens in IL stream needs to be resolved to EE handles (CORINFO_CLASS/METHOD/FIELD_HANDLE) that
42 the runtime operates with. ICorStaticInfo::resolveToken is the method that resolves the found in IL stream
43 to set of EE handles (CORINFO_RESOLVED_TOKEN). All other APIs take resolved token as input. This design
44 avoids redundant token resolutions.
46 The token validation is done as part of token resolution. The JIT is not required to do explicit upfront
49 -------------------------------------------------------------------------------
52 First of all class contruction comes in two flavors precise and 'beforeFieldInit'. In C# you get the former
53 if you declare an explicit class constructor method and the later if you declaratively initialize static
54 fields. Precise class construction guarentees that the .cctor is run precisely before the first access to any
55 method or field of the class. 'beforeFieldInit' semantics guarentees only that the .cctor will be run some
56 time before the first static field access (note that calling methods (static or insance) or accessing
57 instance fields does not cause .cctors to be run).
59 Next you need to know that there are two kinds of code generation that can happen in the JIT: appdomain
60 neutral and appdomain specialized. The difference between these two kinds of code is how statics are handled.
61 For appdomain specific code, the address of a particular static variable is embeded in the code. This makes
62 it usable only for one appdomain (since every appdomain gets a own copy of its statics). Appdomain neutral
63 code calls a helper that looks up static variables off of a thread local variable. Thus the same code can be
64 used by mulitple appdomains in the same process.
66 Generics also introduce a similar issue. Code for generic classes might be specialised for a particular set
67 of type arguments, or it could use helpers to access data that depends on type parameters and thus be shared
68 across several instantiations of the generic type.
72 * BeforeFieldInitCCtor - Unshared code. Cctors are only called when static fields are fetched. At the
73 time the method that touches the static field is JITed (or fixed up in the case of NGENed code), the
75 * BeforeFieldInitCCtor - Shared code. Since the same code is used for multiple classes, the act of JITing
76 the code can not be used as a hook. However, it is also the case that since the code is shared, it
77 can not wire in a particular address for the static and thus needs to use a helper that looks up the
78 correct address based on the thread ID. This helper does the .cctor check, and thus no additional
79 cctor logic is needed.
80 * PreciseCCtor - Unshared code. Any time a method is JITTed (or fixed up in the case of NGEN), a cctor
81 check for the class of the method being JITTed is done. In addition the JIT inserts explicit checks
82 before any static field accesses. Instance methods and fields do NOT have hooks because a .ctor
83 method must be called before the instance can be created.
84 * PreciseCctor - Shared code .cctor checks are placed in the prolog of every .ctor and static method. All
85 methods that access static fields have an explicit .cctor check before use. Again instance methods
86 don't have hooks because a .ctor would have to be called first.
88 Technically speaking, however the optimization of avoiding checks on instance methods is flawed. It requires
89 that a .ctor always preceed a call to an instance methods. This break down when
91 * A NULL is passed to an instance method.
92 * A .ctor does not call its superclasses .ctor. This allows an instance to be created without necessarily
93 calling all the .cctors of all the superclasses. A virtual call can then be made to a instance of a
94 superclass without necessarily calling the superclass's .cctor.
95 * The class is a value class (which exists without a .ctor being called)
97 Nevertheless, the cost of plugging these holes is considered to high and the benefit is low.
99 ----------------------------------------------------------------------
101 #ClassConstructionFlags
103 Thus the JIT's cctor responsibilities require it to check with the EE on every static field access using
104 initClass and before jitting any method to see if a .cctor check must be placed in the prolog.
106 * CORINFO_FLG_BEFOREFIELDINIT indicate the class has beforeFieldInit semantics. The jit does not strictly
107 need this information however, it is valuable in optimizing static field fetch helper calls. Helper
108 call for classes with BeforeFieldInit semantics can be hoisted before other side effects where
109 classes with precise .cctor semantics do not allow this optimization.
111 Inlining also complicates things. Because the class could have precise semantics it is also required that the
112 inlining of any constructor or static method must also do the initClass check. The inliner has the option of
113 inserting any required runtime check or simply not inlining the function.
115 -------------------------------------------------------------------------------
119 The first 4 options are mutially exclusive
121 * CORINFO_FLG_HELPER If the field has this set, then the JIT must call getFieldHelper and call the
122 returned helper with the object ref (for an instance field) and a fieldDesc. Note that this should be
123 able to handle ANY field so to get a JIT up quickly, it has the option of using helper calls for all
124 field access (and skip the complexity below). Note that for statics it is assumed that you will
125 alwasy ask for the ADDRESSS helper and to the fetch in the JIT.
127 * CORINFO_FLG_SHARED_HELPER This is currently only used for static fields. If this bit is set it means
128 that the field is feched by a helper call that takes a module identifier (see getModuleDomainID) and
129 a class identifier (see getClassDomainID) as arguments. The exact helper to call is determined by
130 getSharedStaticBaseHelper. The return value is of this function is the base of all statics in the
131 module. The offset from getFieldOffset must be added to this value to get the address of the field
132 itself. (see also CORINFO_FLG_STATIC_IN_HEAP).
135 * CORINFO_FLG_GENERICS_STATIC This is currently only used for static fields (of generic type). This
136 function is intended to be called with a Generic handle as a argument (from embedGenericHandle). The
137 exact helper to call is determined by getSharedStaticBaseHelper. The returned value is the base of
138 all statics in the class. The offset from getFieldOffset must be added to this value to get the
139 address of the (see also CORINFO_FLG_STATIC_IN_HEAP).
141 * CORINFO_FLG_TLS This indicate that the static field is a Windows style Thread Local Static. (We also
142 have managed thread local statics, which work through the HELPER. Support for this is considered
143 legacy, and going forward, the EE should
145 * <NONE> This is a normal static field. Its address in in memory is determined by getFieldAddress. (see
146 also CORINFO_FLG_STATIC_IN_HEAP).
149 This last field can modify any of the cases above except CORINFO_FLG_HELPER
151 CORINFO_FLG_STATIC_IN_HEAP This is currently only used for static fields of value classes. If the field has
152 this set then after computing what would normally be the field, what you actually get is a object pointer
153 (that must be reported to the GC) to a boxed version of the value. Thus the actual field address is computed
154 by addr = (*addr+sizeof(OBJECTREF))
158 * CORINFO_FLG_HELPER This is used if the class is MarshalByRef, which means that the object might be a
159 proxyt to the real object in some other appdomain or process. If the field has this set, then the JIT
160 must call getFieldHelper and call the returned helper with the object ref. If the helper returned is
161 helpers that are for structures the args are as follows
163 * CORINFO_HELP_GETFIELDSTRUCT - args are: retBuff, object, fieldDesc
164 * CORINFO_HELP_SETFIELDSTRUCT - args are object fieldDesc value
166 The other GET helpers take an object fieldDesc and return the value The other SET helpers take an object
169 Note that unlike static fields there is no helper to take the address of a field because in general there
170 is no address for proxies (LDFLDA is illegal on proxies).
172 CORINFO_FLG_EnC This is to support adding new field for edit and continue. This field also indicates that
173 a helper is needed to access this field. However this helper is always CORINFO_HELP_GETFIELDADDR, and
174 this helper always takes the object and field handle and returns the address of the field. It is the
175 JIT's responcibility to do the fetch or set.
177 -------------------------------------------------------------------------------
179 TODO: Talk about initializing strutures before use
182 *******************************************************************************
189 #include <specstrings.h>
191 //////////////////////////////////////////////////////////////////////////////////////////////////////////
193 // NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE
195 // #JITEEVersionIdentifier
197 // This GUID represents the version of the JIT/EE interface. Any time the interface between the JIT and
198 // the EE changes (by adding or removing methods to any interface shared between them), this GUID should
199 // be changed. This is the identifier verified by ICorJitCompiler::getVersionIdentifier().
201 // You can use "uuidgen.exe -s" to generate this value.
203 // **** NOTE TO INTEGRATORS:
205 // If there is a merge conflict here, because the version changed in two different places, you must
206 // create a **NEW** GUID, not simply choose one or the other!
208 // NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE
210 //////////////////////////////////////////////////////////////////////////////////////////////////////////
212 #if !defined(SELECTANY)
213 #if defined(__GNUC__)
214 #define SELECTANY extern __attribute__((weak))
216 #define SELECTANY extern __declspec(selectany)
220 SELECTANY const GUID JITEEVersionIdentifier = { /* d609bed1-7831-49fc-bd49-b6f054dd4d46 */
224 {0xbd, 0x49, 0xb6, 0xf0, 0x54, 0xdd, 0x4d, 0x46}
227 //////////////////////////////////////////////////////////////////////////////////////////////////////////
229 // END JITEEVersionIdentifier
231 //////////////////////////////////////////////////////////////////////////////////////////////////////////
233 // For System V on the CLR type system number of registers to pass in and return a struct is the same.
234 // The CLR type system allows only up to 2 eightbytes to be passed in registers. There is no SSEUP classification types.
235 #define CLR_SYSTEMV_MAX_EIGHTBYTES_COUNT_TO_PASS_IN_REGISTERS 2
236 #define CLR_SYSTEMV_MAX_EIGHTBYTES_COUNT_TO_RETURN_IN_REGISTERS 2
237 #define CLR_SYSTEMV_MAX_STRUCT_BYTES_TO_PASS_IN_REGISTERS 16
239 // System V struct passing
240 // The Classification types are described in the ABI spec at http://www.x86-64.org/documentation/abi.pdf
241 enum SystemVClassificationType : unsigned __int8
243 SystemVClassificationTypeUnknown = 0,
244 SystemVClassificationTypeStruct = 1,
245 SystemVClassificationTypeNoClass = 2,
246 SystemVClassificationTypeMemory = 3,
247 SystemVClassificationTypeInteger = 4,
248 SystemVClassificationTypeIntegerReference = 5,
249 SystemVClassificationTypeIntegerByRef = 6,
250 SystemVClassificationTypeSSE = 7,
251 // SystemVClassificationTypeSSEUp = Unused, // Not supported by the CLR.
252 // SystemVClassificationTypeX87 = Unused, // Not supported by the CLR.
253 // SystemVClassificationTypeX87Up = Unused, // Not supported by the CLR.
254 // SystemVClassificationTypeComplexX87 = Unused, // Not supported by the CLR.
256 // Internal flags - never returned outside of the classification implementation.
258 // This value represents a very special type with two eightbytes.
259 // First ByRef, second Integer (platform int).
260 // The VM has a special Elem type for this type - ELEMENT_TYPE_TYPEDBYREF.
261 // This is the classification counterpart for that element type. It is used to detect
262 // the special TypedReference type and specialize its classification.
263 // This type is represented as a struct with two fields. The classification needs to do
264 // special handling of it since the source/methadata type of the fieds is IntPtr.
265 // The VM changes the first to ByRef. The second is left as IntPtr (TYP_I_IMPL really). The classification needs to match this and
266 // special handling is warranted (similar thing is done in the getGCLayout function for this type).
267 SystemVClassificationTypeTypedReference = 8,
268 SystemVClassificationTypeMAX = 9,
271 // Represents classification information for a struct.
272 struct SYSTEMV_AMD64_CORINFO_STRUCT_REG_PASSING_DESCRIPTOR
274 SYSTEMV_AMD64_CORINFO_STRUCT_REG_PASSING_DESCRIPTOR()
279 bool passedInRegisters; // Whether the struct is passable/passed (this includes struct returning) in registers.
280 unsigned __int8 eightByteCount; // Number of eightbytes for this struct.
281 SystemVClassificationType eightByteClassifications[CLR_SYSTEMV_MAX_EIGHTBYTES_COUNT_TO_PASS_IN_REGISTERS]; // The eightbytes type classification.
282 unsigned __int8 eightByteSizes[CLR_SYSTEMV_MAX_EIGHTBYTES_COUNT_TO_PASS_IN_REGISTERS]; // The size of the eightbytes (an eightbyte could include padding. This represents the no padding size of the eightbyte).
283 unsigned __int8 eightByteOffsets[CLR_SYSTEMV_MAX_EIGHTBYTES_COUNT_TO_PASS_IN_REGISTERS]; // The start offset of the eightbytes (in bytes).
287 //------------------------------------------------------------------------
288 // CopyFrom: Copies a struct classification into this one.
291 // 'copyFrom' the struct classification to copy from.
293 void CopyFrom(const SYSTEMV_AMD64_CORINFO_STRUCT_REG_PASSING_DESCRIPTOR& copyFrom)
295 passedInRegisters = copyFrom.passedInRegisters;
296 eightByteCount = copyFrom.eightByteCount;
298 for (int i = 0; i < CLR_SYSTEMV_MAX_EIGHTBYTES_COUNT_TO_PASS_IN_REGISTERS; i++)
300 eightByteClassifications[i] = copyFrom.eightByteClassifications[i];
301 eightByteSizes[i] = copyFrom.eightByteSizes[i];
302 eightByteOffsets[i] = copyFrom.eightByteOffsets[i];
306 //------------------------------------------------------------------------
307 // IsIntegralSlot: Returns whether the eightbyte at slotIndex is of integral type.
310 // 'slotIndex' the slot number we are determining if it is of integral type.
313 // returns true if we the eightbyte at index slotIndex is of integral type.
316 bool IsIntegralSlot(unsigned slotIndex) const
318 return ((eightByteClassifications[slotIndex] == SystemVClassificationTypeInteger) ||
319 (eightByteClassifications[slotIndex] == SystemVClassificationTypeIntegerReference) ||
320 (eightByteClassifications[slotIndex] == SystemVClassificationTypeIntegerByRef));
323 //------------------------------------------------------------------------
324 // IsSseSlot: Returns whether the eightbyte at slotIndex is SSE type.
327 // 'slotIndex' the slot number we are determining if it is of SSE type.
330 // returns true if we the eightbyte at index slotIndex is of SSE type.
332 // Follows the rules of the AMD64 System V ABI specification at www.x86-64.org/documentation/abi.pdf.
333 // Please refer to it for definitions/examples.
335 bool IsSseSlot(unsigned slotIndex) const
337 return (eightByteClassifications[slotIndex] == SystemVClassificationTypeSSE);
343 passedInRegisters = false;
346 for (int i = 0; i < CLR_SYSTEMV_MAX_EIGHTBYTES_COUNT_TO_PASS_IN_REGISTERS; i++)
348 eightByteClassifications[i] = SystemVClassificationTypeUnknown;
349 eightByteSizes[i] = 0;
350 eightByteOffsets[i] = 0;
355 // CorInfoHelpFunc defines the set of helpers (accessed via the ICorDynamicInfo::getHelperFtn())
356 // These helpers can be called by native code which executes in the runtime.
357 // Compilers can emit calls to these helpers.
359 // The signatures of the helpers are below (see RuntimeHelperArgumentCheck)
363 CORINFO_HELP_UNDEF, // invalid value. This should never be used
365 /* Arithmetic helpers */
367 CORINFO_HELP_DIV, // For the ARM 32-bit integer divide uses a helper call :-(
376 CORINFO_HELP_LMUL_OVF,
377 CORINFO_HELP_ULMUL_OVF,
382 CORINFO_HELP_LNG2DBL, // Convert a signed int64 to a double
383 CORINFO_HELP_ULNG2DBL, // Convert a unsigned int64 to a double
384 CORINFO_HELP_DBL2INT,
385 CORINFO_HELP_DBL2INT_OVF,
386 CORINFO_HELP_DBL2LNG,
387 CORINFO_HELP_DBL2LNG_OVF,
388 CORINFO_HELP_DBL2UINT,
389 CORINFO_HELP_DBL2UINT_OVF,
390 CORINFO_HELP_DBL2ULNG,
391 CORINFO_HELP_DBL2ULNG_OVF,
394 CORINFO_HELP_FLTROUND,
395 CORINFO_HELP_DBLROUND,
397 /* Allocating a new object. Always use ICorClassInfo::getNewHelper() to decide
398 which is the right helper to use to allocate an object of a given type. */
400 CORINFO_HELP_NEW_CROSSCONTEXT, // cross context new object
401 CORINFO_HELP_NEWFAST,
402 CORINFO_HELP_NEWSFAST, // allocator for small, non-finalizer, non-array object
403 CORINFO_HELP_NEWSFAST_FINALIZE, // allocator for small, finalizable, non-array object
404 CORINFO_HELP_NEWSFAST_ALIGN8, // allocator for small, non-finalizer, non-array object, 8 byte aligned
405 CORINFO_HELP_NEWSFAST_ALIGN8_VC,// allocator for small, value class, 8 byte aligned
406 CORINFO_HELP_NEWSFAST_ALIGN8_FINALIZE, // allocator for small, finalizable, non-array object, 8 byte aligned
407 CORINFO_HELP_NEW_MDARR, // multi-dim array helper (with or without lower bounds - dimensions passed in as vararg)
408 CORINFO_HELP_NEW_MDARR_NONVARARG,// multi-dim array helper (with or without lower bounds - dimensions passed in as unmanaged array)
409 CORINFO_HELP_NEWARR_1_DIRECT, // helper for any one dimensional array creation
410 CORINFO_HELP_NEWARR_1_R2R_DIRECT, // wrapper for R2R direct call, which extracts method table from ArrayTypeDesc
411 CORINFO_HELP_NEWARR_1_OBJ, // optimized 1-D object arrays
412 CORINFO_HELP_NEWARR_1_VC, // optimized 1-D value class arrays
413 CORINFO_HELP_NEWARR_1_ALIGN8, // like VC, but aligns the array start
415 CORINFO_HELP_STRCNS, // create a new string literal
416 CORINFO_HELP_STRCNS_CURRENT_MODULE, // create a new string literal from the current module (used by NGen code)
420 CORINFO_HELP_INITCLASS, // Initialize class if not already initialized
421 CORINFO_HELP_INITINSTCLASS, // Initialize class for instantiated type
423 // Use ICorClassInfo::getCastingHelper to determine
424 // the right helper to use
426 CORINFO_HELP_ISINSTANCEOFINTERFACE, // Optimized helper for interfaces
427 CORINFO_HELP_ISINSTANCEOFARRAY, // Optimized helper for arrays
428 CORINFO_HELP_ISINSTANCEOFCLASS, // Optimized helper for classes
429 CORINFO_HELP_ISINSTANCEOFANY, // Slow helper for any type
431 CORINFO_HELP_CHKCASTINTERFACE,
432 CORINFO_HELP_CHKCASTARRAY,
433 CORINFO_HELP_CHKCASTCLASS,
434 CORINFO_HELP_CHKCASTANY,
435 CORINFO_HELP_CHKCASTCLASS_SPECIAL, // Optimized helper for classes. Assumes that the trivial cases
436 // has been taken care of by the inlined check
439 CORINFO_HELP_BOX_NULLABLE, // special form of boxing for Nullable<T>
441 CORINFO_HELP_UNBOX_NULLABLE, // special form of unboxing for Nullable<T>
442 CORINFO_HELP_GETREFANY, // Extract the byref from a TypedReference, checking that it is the expected type
444 CORINFO_HELP_ARRADDR_ST, // assign to element of object array with type-checking
445 CORINFO_HELP_LDELEMA_REF, // does a precise type comparision and returns address
449 CORINFO_HELP_THROW, // Throw an exception object
450 CORINFO_HELP_RETHROW, // Rethrow the currently active exception
451 CORINFO_HELP_USER_BREAKPOINT, // For a user program to break to the debugger
452 CORINFO_HELP_RNGCHKFAIL, // array bounds check failed
453 CORINFO_HELP_OVERFLOW, // throw an overflow exception
454 CORINFO_HELP_THROWDIVZERO, // throw a divide by zero exception
455 CORINFO_HELP_THROWNULLREF, // throw a null reference exception
457 CORINFO_HELP_INTERNALTHROW, // Support for really fast jit
458 CORINFO_HELP_VERIFICATION, // Throw a VerificationException
459 CORINFO_HELP_SEC_UNMGDCODE_EXCPT, // throw a security unmanaged code exception
460 CORINFO_HELP_FAIL_FAST, // Kill the process avoiding any exceptions or stack and data dependencies (use for GuardStack unsafe buffer checks)
462 CORINFO_HELP_METHOD_ACCESS_EXCEPTION,//Throw an access exception due to a failed member/class access check.
463 CORINFO_HELP_FIELD_ACCESS_EXCEPTION,
464 CORINFO_HELP_CLASS_ACCESS_EXCEPTION,
466 CORINFO_HELP_ENDCATCH, // call back into the EE at the end of a catch block
468 /* Synchronization */
470 CORINFO_HELP_MON_ENTER,
471 CORINFO_HELP_MON_EXIT,
472 CORINFO_HELP_MON_ENTER_STATIC,
473 CORINFO_HELP_MON_EXIT_STATIC,
475 CORINFO_HELP_GETCLASSFROMMETHODPARAM, // Given a generics method handle, returns a class handle
476 CORINFO_HELP_GETSYNCFROMCLASSHANDLE, // Given a generics class handle, returns the sync monitor
477 // in its ManagedClassObject
479 /* Security callout support */
481 CORINFO_HELP_SECURITY_PROLOG, // Required if CORINFO_FLG_SECURITYCHECK is set, or CORINFO_FLG_NOSECURITYWRAP is not set
482 CORINFO_HELP_SECURITY_PROLOG_FRAMED, // Slow version of CORINFO_HELP_SECURITY_PROLOG. Used for instrumentation.
484 CORINFO_HELP_METHOD_ACCESS_CHECK, // Callouts to runtime security access checks
485 CORINFO_HELP_FIELD_ACCESS_CHECK,
486 CORINFO_HELP_CLASS_ACCESS_CHECK,
488 CORINFO_HELP_DELEGATE_SECURITY_CHECK, // Callout to delegate security transparency check
490 /* Verification runtime callout support */
492 CORINFO_HELP_VERIFICATION_RUNTIME_CHECK, // Do a Demand for UnmanagedCode permission at runtime
496 CORINFO_HELP_STOP_FOR_GC, // Call GC (force a GC)
497 CORINFO_HELP_POLL_GC, // Ask GC if it wants to collect
499 CORINFO_HELP_STRESS_GC, // Force a GC, but then update the JITTED code to be a noop call
500 CORINFO_HELP_CHECK_OBJ, // confirm that ECX is a valid object pointer (debugging only)
502 /* GC Write barrier support */
504 CORINFO_HELP_ASSIGN_REF, // universal helpers with F_CALL_CONV calling convention
505 CORINFO_HELP_CHECKED_ASSIGN_REF,
506 CORINFO_HELP_ASSIGN_REF_ENSURE_NONHEAP, // Do the store, and ensure that the target was not in the heap.
508 CORINFO_HELP_ASSIGN_BYREF,
509 CORINFO_HELP_ASSIGN_STRUCT,
512 /* Accessing fields */
514 // For COM object support (using COM get/set routines to update object)
515 // and EnC and cross-context support
516 CORINFO_HELP_GETFIELD8,
517 CORINFO_HELP_SETFIELD8,
518 CORINFO_HELP_GETFIELD16,
519 CORINFO_HELP_SETFIELD16,
520 CORINFO_HELP_GETFIELD32,
521 CORINFO_HELP_SETFIELD32,
522 CORINFO_HELP_GETFIELD64,
523 CORINFO_HELP_SETFIELD64,
524 CORINFO_HELP_GETFIELDOBJ,
525 CORINFO_HELP_SETFIELDOBJ,
526 CORINFO_HELP_GETFIELDSTRUCT,
527 CORINFO_HELP_SETFIELDSTRUCT,
528 CORINFO_HELP_GETFIELDFLOAT,
529 CORINFO_HELP_SETFIELDFLOAT,
530 CORINFO_HELP_GETFIELDDOUBLE,
531 CORINFO_HELP_SETFIELDDOUBLE,
533 CORINFO_HELP_GETFIELDADDR,
535 CORINFO_HELP_GETSTATICFIELDADDR_CONTEXT, // Helper for context-static fields
536 CORINFO_HELP_GETSTATICFIELDADDR_TLS, // Helper for PE TLS fields
538 // There are a variety of specialized helpers for accessing static fields. The JIT should use
539 // ICorClassInfo::getSharedStaticsOrCCtorHelper to determine which helper to use
541 // Helpers for regular statics
542 CORINFO_HELP_GETGENERICS_GCSTATIC_BASE,
543 CORINFO_HELP_GETGENERICS_NONGCSTATIC_BASE,
544 CORINFO_HELP_GETSHARED_GCSTATIC_BASE,
545 CORINFO_HELP_GETSHARED_NONGCSTATIC_BASE,
546 CORINFO_HELP_GETSHARED_GCSTATIC_BASE_NOCTOR,
547 CORINFO_HELP_GETSHARED_NONGCSTATIC_BASE_NOCTOR,
548 CORINFO_HELP_GETSHARED_GCSTATIC_BASE_DYNAMICCLASS,
549 CORINFO_HELP_GETSHARED_NONGCSTATIC_BASE_DYNAMICCLASS,
550 // Helper to class initialize shared generic with dynamicclass, but not get static field address
551 CORINFO_HELP_CLASSINIT_SHARED_DYNAMICCLASS,
553 // Helpers for thread statics
554 CORINFO_HELP_GETGENERICS_GCTHREADSTATIC_BASE,
555 CORINFO_HELP_GETGENERICS_NONGCTHREADSTATIC_BASE,
556 CORINFO_HELP_GETSHARED_GCTHREADSTATIC_BASE,
557 CORINFO_HELP_GETSHARED_NONGCTHREADSTATIC_BASE,
558 CORINFO_HELP_GETSHARED_GCTHREADSTATIC_BASE_NOCTOR,
559 CORINFO_HELP_GETSHARED_NONGCTHREADSTATIC_BASE_NOCTOR,
560 CORINFO_HELP_GETSHARED_GCTHREADSTATIC_BASE_DYNAMICCLASS,
561 CORINFO_HELP_GETSHARED_NONGCTHREADSTATIC_BASE_DYNAMICCLASS,
565 CORINFO_HELP_DBG_IS_JUST_MY_CODE, // Check if this is "JustMyCode" and needs to be stepped through.
567 /* Profiling enter/leave probe addresses */
568 CORINFO_HELP_PROF_FCN_ENTER, // record the entry to a method (caller)
569 CORINFO_HELP_PROF_FCN_LEAVE, // record the completion of current method (caller)
570 CORINFO_HELP_PROF_FCN_TAILCALL, // record the completionof current method through tailcall (caller)
574 CORINFO_HELP_BBT_FCN_ENTER, // record the entry to a method for collecting Tuning data
576 CORINFO_HELP_PINVOKE_CALLI, // Indirect pinvoke call
577 CORINFO_HELP_TAILCALL, // Perform a tail call
579 CORINFO_HELP_GETCURRENTMANAGEDTHREADID,
581 CORINFO_HELP_INIT_PINVOKE_FRAME, // initialize an inlined PInvoke Frame for the JIT-compiler
583 CORINFO_HELP_MEMSET, // Init block of memory
584 CORINFO_HELP_MEMCPY, // Copy block of memory
586 CORINFO_HELP_RUNTIMEHANDLE_METHOD, // determine a type/field/method handle at run-time
587 CORINFO_HELP_RUNTIMEHANDLE_METHOD_LOG, // determine a type/field/method handle at run-time, with IBC logging
588 CORINFO_HELP_RUNTIMEHANDLE_CLASS, // determine a type/field/method handle at run-time
589 CORINFO_HELP_RUNTIMEHANDLE_CLASS_LOG, // determine a type/field/method handle at run-time, with IBC logging
591 CORINFO_HELP_TYPEHANDLE_TO_RUNTIMETYPE, // Convert from a TypeHandle (native structure pointer) to RuntimeType at run-time
592 CORINFO_HELP_TYPEHANDLE_TO_RUNTIMETYPE_MAYBENULL, // Convert from a TypeHandle (native structure pointer) to RuntimeType at run-time, the type may be null
593 CORINFO_HELP_METHODDESC_TO_STUBRUNTIMEMETHOD, // Convert from a MethodDesc (native structure pointer) to RuntimeMethodHandle at run-time
594 CORINFO_HELP_FIELDDESC_TO_STUBRUNTIMEFIELD, // Convert from a FieldDesc (native structure pointer) to RuntimeFieldHandle at run-time
595 CORINFO_HELP_TYPEHANDLE_TO_RUNTIMETYPEHANDLE, // Convert from a TypeHandle (native structure pointer) to RuntimeTypeHandle at run-time
596 CORINFO_HELP_TYPEHANDLE_TO_RUNTIMETYPEHANDLE_MAYBENULL, // Convert from a TypeHandle (native structure pointer) to RuntimeTypeHandle at run-time, handle might point to a null type
598 CORINFO_HELP_ARE_TYPES_EQUIVALENT, // Check whether two TypeHandles (native structure pointers) are equivalent
600 CORINFO_HELP_VIRTUAL_FUNC_PTR, // look up a virtual method at run-time
601 //CORINFO_HELP_VIRTUAL_FUNC_PTR_LOG, // look up a virtual method at run-time, with IBC logging
603 // Not a real helpers. Instead of taking handle arguments, these helpers point to a small stub that loads the handle argument and calls the static helper.
604 CORINFO_HELP_READYTORUN_NEW,
605 CORINFO_HELP_READYTORUN_NEWARR_1,
606 CORINFO_HELP_READYTORUN_ISINSTANCEOF,
607 CORINFO_HELP_READYTORUN_CHKCAST,
608 CORINFO_HELP_READYTORUN_STATIC_BASE,
609 CORINFO_HELP_READYTORUN_VIRTUAL_FUNC_PTR,
610 CORINFO_HELP_READYTORUN_GENERIC_HANDLE,
611 CORINFO_HELP_READYTORUN_DELEGATE_CTOR,
612 CORINFO_HELP_READYTORUN_GENERIC_STATIC_BASE,
614 CORINFO_HELP_EE_PRESTUB, // Not real JIT helper. Used in native images.
616 CORINFO_HELP_EE_PRECODE_FIXUP, // Not real JIT helper. Used for Precode fixup in native images.
617 CORINFO_HELP_EE_PINVOKE_FIXUP, // Not real JIT helper. Used for PInvoke target fixup in native images.
618 CORINFO_HELP_EE_VSD_FIXUP, // Not real JIT helper. Used for VSD cell fixup in native images.
619 CORINFO_HELP_EE_EXTERNAL_FIXUP, // Not real JIT helper. Used for to fixup external method thunks in native images.
620 CORINFO_HELP_EE_VTABLE_FIXUP, // Not real JIT helper. Used for inherited vtable slot fixup in native images.
622 CORINFO_HELP_EE_REMOTING_THUNK, // Not real JIT helper. Used for remoting precode in native images.
624 CORINFO_HELP_EE_PERSONALITY_ROUTINE,// Not real JIT helper. Used in native images.
625 CORINFO_HELP_EE_PERSONALITY_ROUTINE_FILTER_FUNCLET,// Not real JIT helper. Used in native images to detect filter funclets.
627 // ASSIGN_REF_EAX - CHECKED_ASSIGN_REF_EBP: NOGC_WRITE_BARRIERS JIT helper calls
629 // For unchecked versions EDX is required to point into GC heap.
631 // NOTE: these helpers are only used for x86.
632 CORINFO_HELP_ASSIGN_REF_EAX, // EAX holds GC ptr, do a 'mov [EDX], EAX' and inform GC
633 CORINFO_HELP_ASSIGN_REF_EBX, // EBX holds GC ptr, do a 'mov [EDX], EBX' and inform GC
634 CORINFO_HELP_ASSIGN_REF_ECX, // ECX holds GC ptr, do a 'mov [EDX], ECX' and inform GC
635 CORINFO_HELP_ASSIGN_REF_ESI, // ESI holds GC ptr, do a 'mov [EDX], ESI' and inform GC
636 CORINFO_HELP_ASSIGN_REF_EDI, // EDI holds GC ptr, do a 'mov [EDX], EDI' and inform GC
637 CORINFO_HELP_ASSIGN_REF_EBP, // EBP holds GC ptr, do a 'mov [EDX], EBP' and inform GC
639 CORINFO_HELP_CHECKED_ASSIGN_REF_EAX, // These are the same as ASSIGN_REF above ...
640 CORINFO_HELP_CHECKED_ASSIGN_REF_EBX, // ... but also check if EDX points into heap.
641 CORINFO_HELP_CHECKED_ASSIGN_REF_ECX,
642 CORINFO_HELP_CHECKED_ASSIGN_REF_ESI,
643 CORINFO_HELP_CHECKED_ASSIGN_REF_EDI,
644 CORINFO_HELP_CHECKED_ASSIGN_REF_EBP,
646 CORINFO_HELP_LOOP_CLONE_CHOICE_ADDR, // Return the reference to a counter to decide to take cloned path in debug stress.
647 CORINFO_HELP_DEBUG_LOG_LOOP_CLONING, // Print a message that a loop cloning optimization has occurred in debug mode.
649 CORINFO_HELP_THROW_ARGUMENTEXCEPTION, // throw ArgumentException
650 CORINFO_HELP_THROW_ARGUMENTOUTOFRANGEEXCEPTION, // throw ArgumentOutOfRangeException
651 CORINFO_HELP_THROW_NOT_IMPLEMENTED, // throw NotImplementedException
652 CORINFO_HELP_THROW_PLATFORM_NOT_SUPPORTED, // throw PlatformNotSupportedException
653 CORINFO_HELP_THROW_TYPE_NOT_SUPPORTED, // throw TypeNotSupportedException
655 CORINFO_HELP_JIT_PINVOKE_BEGIN, // Transition to preemptive mode before a P/Invoke, frame is the first argument
656 CORINFO_HELP_JIT_PINVOKE_END, // Transition to cooperative mode after a P/Invoke, frame is the first argument
658 CORINFO_HELP_JIT_REVERSE_PINVOKE_ENTER, // Transition to cooperative mode in reverse P/Invoke prolog, frame is the first argument
659 CORINFO_HELP_JIT_REVERSE_PINVOKE_EXIT, // Transition to preemptive mode in reverse P/Invoke epilog, frame is the first argument
661 CORINFO_HELP_GVMLOOKUP_FOR_SLOT, // Resolve a generic virtual method target from this pointer and runtime method handle
666 #define CORINFO_HELP_READYTORUN_ATYPICAL_CALLSITE 0x40000000
668 //This describes the signature for a helper method.
671 CORINFO_HELP_SIG_UNDEF,
672 CORINFO_HELP_SIG_NO_ALIGN_STUB,
673 CORINFO_HELP_SIG_NO_UNWIND_STUB,
674 CORINFO_HELP_SIG_REG_ONLY,
675 CORINFO_HELP_SIG_4_STACK,
676 CORINFO_HELP_SIG_8_STACK,
677 CORINFO_HELP_SIG_12_STACK,
678 CORINFO_HELP_SIG_16_STACK,
679 CORINFO_HELP_SIG_8_VA, //2 arguments plus varargs
681 CORINFO_HELP_SIG_EBPCALL, //special calling convention that uses EDX and
684 CORINFO_HELP_SIG_CANNOT_USE_ALIGN_STUB,
686 CORINFO_HELP_SIG_COUNT
689 // The enumeration is returned in 'getSig','getType', getArgType methods
692 CORINFO_TYPE_UNDEF = 0x0,
693 CORINFO_TYPE_VOID = 0x1,
694 CORINFO_TYPE_BOOL = 0x2,
695 CORINFO_TYPE_CHAR = 0x3,
696 CORINFO_TYPE_BYTE = 0x4,
697 CORINFO_TYPE_UBYTE = 0x5,
698 CORINFO_TYPE_SHORT = 0x6,
699 CORINFO_TYPE_USHORT = 0x7,
700 CORINFO_TYPE_INT = 0x8,
701 CORINFO_TYPE_UINT = 0x9,
702 CORINFO_TYPE_LONG = 0xa,
703 CORINFO_TYPE_ULONG = 0xb,
704 CORINFO_TYPE_NATIVEINT = 0xc,
705 CORINFO_TYPE_NATIVEUINT = 0xd,
706 CORINFO_TYPE_FLOAT = 0xe,
707 CORINFO_TYPE_DOUBLE = 0xf,
708 CORINFO_TYPE_STRING = 0x10, // Not used, should remove
709 CORINFO_TYPE_PTR = 0x11,
710 CORINFO_TYPE_BYREF = 0x12,
711 CORINFO_TYPE_VALUECLASS = 0x13,
712 CORINFO_TYPE_CLASS = 0x14,
713 CORINFO_TYPE_REFANY = 0x15,
715 // CORINFO_TYPE_VAR is for a generic type variable.
716 // Generic type variables only appear when the JIT is doing
717 // verification (not NOT compilation) of generic code
718 // for the EE, in which case we're running
719 // the JIT in "import only" mode.
721 CORINFO_TYPE_VAR = 0x16,
722 CORINFO_TYPE_COUNT, // number of jit types
725 enum CorInfoTypeWithMod
727 CORINFO_TYPE_MASK = 0x3F, // lower 6 bits are type mask
728 CORINFO_TYPE_MOD_PINNED = 0x40, // can be applied to CLASS, or BYREF to indiate pinned
731 inline CorInfoType strip(CorInfoTypeWithMod val) {
732 return CorInfoType(val & CORINFO_TYPE_MASK);
735 // The enumeration is returned in 'getSig'
739 // These correspond to CorCallingConvention
741 CORINFO_CALLCONV_DEFAULT = 0x0,
742 CORINFO_CALLCONV_C = 0x1,
743 CORINFO_CALLCONV_STDCALL = 0x2,
744 CORINFO_CALLCONV_THISCALL = 0x3,
745 CORINFO_CALLCONV_FASTCALL = 0x4,
746 CORINFO_CALLCONV_VARARG = 0x5,
747 CORINFO_CALLCONV_FIELD = 0x6,
748 CORINFO_CALLCONV_LOCAL_SIG = 0x7,
749 CORINFO_CALLCONV_PROPERTY = 0x8,
750 CORINFO_CALLCONV_NATIVEVARARG = 0xb, // used ONLY for IL stub PInvoke vararg calls
752 CORINFO_CALLCONV_MASK = 0x0f, // Calling convention is bottom 4 bits
753 CORINFO_CALLCONV_GENERIC = 0x10,
754 CORINFO_CALLCONV_HASTHIS = 0x20,
755 CORINFO_CALLCONV_EXPLICITTHIS=0x40,
756 CORINFO_CALLCONV_PARAMTYPE = 0x80, // Passed last. Same as CORINFO_GENERICS_CTXT_FROM_PARAMTYPEARG
760 inline bool IsCallerPop(CorInfoCallConv callConv)
762 unsigned int umask = CORINFO_CALLCONV_STDCALL
763 | CORINFO_CALLCONV_THISCALL
764 | CORINFO_CALLCONV_FASTCALL;
766 return !(callConv & umask);
768 #endif // UNIX_X86_ABI
770 enum CorInfoUnmanagedCallConv
772 // These correspond to CorUnmanagedCallingConvention
774 CORINFO_UNMANAGED_CALLCONV_UNKNOWN,
775 CORINFO_UNMANAGED_CALLCONV_C,
776 CORINFO_UNMANAGED_CALLCONV_STDCALL,
777 CORINFO_UNMANAGED_CALLCONV_THISCALL,
778 CORINFO_UNMANAGED_CALLCONV_FASTCALL
781 // These are returned from getMethodOptions
784 CORINFO_OPT_INIT_LOCALS = 0x00000010, // zero initialize all variables
786 CORINFO_GENERICS_CTXT_FROM_THIS = 0x00000020, // is this shared generic code that access the generic context from the this pointer? If so, then if the method has SEH then the 'this' pointer must always be reported and kept alive.
787 CORINFO_GENERICS_CTXT_FROM_METHODDESC = 0x00000040, // is this shared generic code that access the generic context from the ParamTypeArg(that is a MethodDesc)? If so, then if the method has SEH then the 'ParamTypeArg' must always be reported and kept alive. Same as CORINFO_CALLCONV_PARAMTYPE
788 CORINFO_GENERICS_CTXT_FROM_METHODTABLE = 0x00000080, // is this shared generic code that access the generic context from the ParamTypeArg(that is a MethodTable)? If so, then if the method has SEH then the 'ParamTypeArg' must always be reported and kept alive. Same as CORINFO_CALLCONV_PARAMTYPE
789 CORINFO_GENERICS_CTXT_MASK = (CORINFO_GENERICS_CTXT_FROM_THIS |
790 CORINFO_GENERICS_CTXT_FROM_METHODDESC |
791 CORINFO_GENERICS_CTXT_FROM_METHODTABLE),
792 CORINFO_GENERICS_CTXT_KEEP_ALIVE = 0x00000100, // Keep the generics context alive throughout the method even if there is no explicit use, and report its location to the CLR
797 // what type of code region we are in
799 enum CorInfoRegionKind
808 // these are the attribute flags for fields and methods (getMethodAttribs)
811 // CORINFO_FLG_UNUSED = 0x00000001,
812 // CORINFO_FLG_UNUSED = 0x00000002,
813 CORINFO_FLG_PROTECTED = 0x00000004,
814 CORINFO_FLG_STATIC = 0x00000008,
815 CORINFO_FLG_FINAL = 0x00000010,
816 CORINFO_FLG_SYNCH = 0x00000020,
817 CORINFO_FLG_VIRTUAL = 0x00000040,
818 // CORINFO_FLG_UNUSED = 0x00000080,
819 CORINFO_FLG_NATIVE = 0x00000100,
820 CORINFO_FLG_INTRINSIC_TYPE = 0x00000200, // This type is marked by [Intrinsic]
821 CORINFO_FLG_ABSTRACT = 0x00000400,
823 CORINFO_FLG_EnC = 0x00000800, // member was added by Edit'n'Continue
825 // These are internal flags that can only be on methods
826 CORINFO_FLG_FORCEINLINE = 0x00010000, // The method should be inlined if possible.
827 CORINFO_FLG_SHAREDINST = 0x00020000, // the code for this method is shared between different generic instantiations (also set on classes/types)
828 CORINFO_FLG_DELEGATE_INVOKE = 0x00040000, // "Delegate
829 CORINFO_FLG_PINVOKE = 0x00080000, // Is a P/Invoke call
830 CORINFO_FLG_SECURITYCHECK = 0x00100000, // Is one of the security routines that does a stackwalk (e.g. Assert, Demand)
831 CORINFO_FLG_NOGCCHECK = 0x00200000, // This method is FCALL that has no GC check. Don't put alone in loops
832 CORINFO_FLG_INTRINSIC = 0x00400000, // This method MAY have an intrinsic ID
833 CORINFO_FLG_CONSTRUCTOR = 0x00800000, // This method is an instance or type initializer
834 CORINFO_FLG_AGGRESSIVE_OPT = 0x01000000, // The method may contain hot code and should be aggressively optimized if possible
835 CORINFO_FLG_DISABLE_TIER0_FOR_LOOPS = 0x02000000, // Indicates that tier 0 JIT should not be used for a method that contains a loop
836 CORINFO_FLG_NOSECURITYWRAP = 0x04000000, // The method requires no security checks
837 CORINFO_FLG_DONT_INLINE = 0x10000000, // The method should not be inlined
838 CORINFO_FLG_DONT_INLINE_CALLER = 0x20000000, // The method should not be inlined, nor should its callers. It cannot be tail called.
839 CORINFO_FLG_JIT_INTRINSIC = 0x40000000, // Method is a potential jit intrinsic; verify identity by name check
841 // These are internal flags that can only be on Classes
842 CORINFO_FLG_VALUECLASS = 0x00010000, // is the class a value class
843 // This flag is define din the Methods section, but is also valid on classes.
844 // CORINFO_FLG_SHAREDINST = 0x00020000, // This class is satisfies TypeHandle::IsCanonicalSubtype
845 CORINFO_FLG_VAROBJSIZE = 0x00040000, // the object size varies depending of constructor args
846 CORINFO_FLG_ARRAY = 0x00080000, // class is an array class (initialized differently)
847 CORINFO_FLG_OVERLAPPING_FIELDS = 0x00100000, // struct or class has fields that overlap (aka union)
848 CORINFO_FLG_INTERFACE = 0x00200000, // it is an interface
849 CORINFO_FLG_CONTEXTFUL = 0x00400000, // is this a contextful class?
850 CORINFO_FLG_CUSTOMLAYOUT = 0x00800000, // does this struct have custom layout?
851 CORINFO_FLG_CONTAINS_GC_PTR = 0x01000000, // does the class contain a gc ptr ?
852 CORINFO_FLG_DELEGATE = 0x02000000, // is this a subclass of delegate or multicast delegate ?
853 CORINFO_FLG_MARSHAL_BYREF = 0x04000000, // is this a subclass of MarshalByRef ?
854 CORINFO_FLG_CONTAINS_STACK_PTR = 0x08000000, // This class has a stack pointer inside it
855 CORINFO_FLG_VARIANCE = 0x10000000, // MethodTable::HasVariance (sealed does *not* mean uncast-able)
856 CORINFO_FLG_BEFOREFIELDINIT = 0x20000000, // Additional flexibility for when to run .cctor (see code:#ClassConstructionFlags)
857 CORINFO_FLG_GENERIC_TYPE_VARIABLE = 0x40000000, // This is really a handle for a variable type
858 CORINFO_FLG_UNSAFE_VALUECLASS = 0x80000000, // Unsafe (C++'s /GS) value type
861 // Flags computed by a runtime compiler
862 enum CorInfoMethodRuntimeFlags
864 CORINFO_FLG_BAD_INLINEE = 0x00000001, // The method is not suitable for inlining
865 CORINFO_FLG_VERIFIABLE = 0x00000002, // The method has verifiable code
866 CORINFO_FLG_UNVERIFIABLE = 0x00000004, // The method has unverifiable code
867 CORINFO_FLG_SWITCHED_TO_MIN_OPT = 0x00000008, // The JIT decided to switch to MinOpt for this method, when it was not requested
868 CORINFO_FLG_SWITCHED_TO_OPTIMIZED = 0x00000010, // The JIT decided to switch to tier 1 for this method, when a different tier was requested
872 enum CORINFO_ACCESS_FLAGS
874 CORINFO_ACCESS_ANY = 0x0000, // Normal access
875 CORINFO_ACCESS_THIS = 0x0001, // Accessed via the this reference
876 CORINFO_ACCESS_UNWRAP = 0x0002, // Accessed via an unwrap reference
878 CORINFO_ACCESS_NONNULL = 0x0004, // Instance is guaranteed non-null
880 CORINFO_ACCESS_LDFTN = 0x0010, // Accessed via ldftn
882 // Field access flags
883 CORINFO_ACCESS_GET = 0x0100, // Field get (ldfld)
884 CORINFO_ACCESS_SET = 0x0200, // Field set (stfld)
885 CORINFO_ACCESS_ADDRESS = 0x0400, // Field address (ldflda)
886 CORINFO_ACCESS_INIT_ARRAY = 0x0800, // Field use for InitializeArray
887 CORINFO_ACCESS_ATYPICAL_CALLSITE = 0x4000, // Atypical callsite that cannot be disassembled by delay loading helper
888 CORINFO_ACCESS_INLINECHECK= 0x8000, // Return fieldFlags and fieldAccessor only. Used by JIT64 during inlining.
891 // These are the flags set on an CORINFO_EH_CLAUSE
892 enum CORINFO_EH_CLAUSE_FLAGS
894 CORINFO_EH_CLAUSE_NONE = 0,
895 CORINFO_EH_CLAUSE_FILTER = 0x0001, // If this bit is on, then this EH entry is for a filter
896 CORINFO_EH_CLAUSE_FINALLY = 0x0002, // This clause is a finally clause
897 CORINFO_EH_CLAUSE_FAULT = 0x0004, // This clause is a fault clause
898 CORINFO_EH_CLAUSE_DUPLICATE = 0x0008, // Duplicated clause. This clause was duplicated to a funclet which was pulled out of line
899 CORINFO_EH_CLAUSE_SAMETRY = 0x0010, // This clause covers same try block as the previous one. (Used by CoreRT ABI.)
902 // This enumeration is passed to InternalThrow
903 enum CorInfoException
905 CORINFO_NullReferenceException,
906 CORINFO_DivideByZeroException,
907 CORINFO_InvalidCastException,
908 CORINFO_IndexOutOfRangeException,
909 CORINFO_OverflowException,
910 CORINFO_SynchronizationLockException,
911 CORINFO_ArrayTypeMismatchException,
912 CORINFO_RankException,
913 CORINFO_ArgumentNullException,
914 CORINFO_ArgumentException,
915 CORINFO_Exception_Count,
919 // This enumeration is returned by getIntrinsicID. Methods corresponding to
920 // these values will have "well-known" specified behavior. Calls to these
921 // methods could be replaced with inlined code corresponding to the
922 // specified behavior (without having to examine the IL beforehand).
924 enum CorInfoIntrinsics
926 CORINFO_INTRINSIC_Sin,
927 CORINFO_INTRINSIC_Cos,
928 CORINFO_INTRINSIC_Cbrt,
929 CORINFO_INTRINSIC_Sqrt,
930 CORINFO_INTRINSIC_Abs,
931 CORINFO_INTRINSIC_Round,
932 CORINFO_INTRINSIC_Cosh,
933 CORINFO_INTRINSIC_Sinh,
934 CORINFO_INTRINSIC_Tan,
935 CORINFO_INTRINSIC_Tanh,
936 CORINFO_INTRINSIC_Asin,
937 CORINFO_INTRINSIC_Asinh,
938 CORINFO_INTRINSIC_Acos,
939 CORINFO_INTRINSIC_Acosh,
940 CORINFO_INTRINSIC_Atan,
941 CORINFO_INTRINSIC_Atan2,
942 CORINFO_INTRINSIC_Atanh,
943 CORINFO_INTRINSIC_Log10,
944 CORINFO_INTRINSIC_Pow,
945 CORINFO_INTRINSIC_Exp,
946 CORINFO_INTRINSIC_Ceiling,
947 CORINFO_INTRINSIC_Floor,
948 CORINFO_INTRINSIC_GetChar, // fetch character out of string
949 CORINFO_INTRINSIC_Array_GetDimLength, // Get number of elements in a given dimension of an array
950 CORINFO_INTRINSIC_Array_Get, // Get the value of an element in an array
951 CORINFO_INTRINSIC_Array_Address, // Get the address of an element in an array
952 CORINFO_INTRINSIC_Array_Set, // Set the value of an element in an array
953 CORINFO_INTRINSIC_StringGetChar, // fetch character out of string
954 CORINFO_INTRINSIC_StringLength, // get the length
955 CORINFO_INTRINSIC_InitializeArray, // initialize an array from static data
956 CORINFO_INTRINSIC_GetTypeFromHandle,
957 CORINFO_INTRINSIC_RTH_GetValueInternal,
958 CORINFO_INTRINSIC_TypeEQ,
959 CORINFO_INTRINSIC_TypeNEQ,
960 CORINFO_INTRINSIC_Object_GetType,
961 CORINFO_INTRINSIC_StubHelpers_GetStubContext,
962 CORINFO_INTRINSIC_StubHelpers_GetStubContextAddr,
963 CORINFO_INTRINSIC_StubHelpers_GetNDirectTarget,
964 CORINFO_INTRINSIC_InterlockedAdd32,
965 CORINFO_INTRINSIC_InterlockedAdd64,
966 CORINFO_INTRINSIC_InterlockedXAdd32,
967 CORINFO_INTRINSIC_InterlockedXAdd64,
968 CORINFO_INTRINSIC_InterlockedXchg32,
969 CORINFO_INTRINSIC_InterlockedXchg64,
970 CORINFO_INTRINSIC_InterlockedCmpXchg32,
971 CORINFO_INTRINSIC_InterlockedCmpXchg64,
972 CORINFO_INTRINSIC_MemoryBarrier,
973 CORINFO_INTRINSIC_GetCurrentManagedThread,
974 CORINFO_INTRINSIC_GetManagedThreadId,
975 CORINFO_INTRINSIC_ByReference_Ctor,
976 CORINFO_INTRINSIC_ByReference_Value,
977 CORINFO_INTRINSIC_Span_GetItem,
978 CORINFO_INTRINSIC_ReadOnlySpan_GetItem,
979 CORINFO_INTRINSIC_GetRawHandle,
981 CORINFO_INTRINSIC_Count,
982 CORINFO_INTRINSIC_Illegal = -1, // Not a true intrinsic,
985 // Can a value be accessed directly from JITed code.
988 IAT_VALUE, // The info value is directly available
989 IAT_PVALUE, // The value needs to be accessed via an indirection
990 IAT_PPVALUE, // The value needs to be accessed via a double indirection
991 IAT_RELPVALUE // The value needs to be accessed via a relative indirection
996 TYPE_GC_NONE, // no embedded objectrefs
997 TYPE_GC_REF, // Is an object ref
998 TYPE_GC_BYREF, // Is an interior pointer - promote it but don't scan it
999 TYPE_GC_OTHER // requires type-specific treatment
1004 CLASSID_SYSTEM_OBJECT,
1005 CLASSID_TYPED_BYREF,
1006 CLASSID_TYPE_HANDLE,
1007 CLASSID_FIELD_HANDLE,
1008 CLASSID_METHOD_HANDLE,
1010 CLASSID_ARGUMENT_HANDLE,
1011 CLASSID_RUNTIME_TYPE,
1016 INLINE_PASS = 0, // Inlining OK
1018 // failures are negative
1019 INLINE_FAIL = -1, // Inlining not OK for this case only
1020 INLINE_NEVER = -2, // This method should never be inlined, regardless of context
1023 enum CorInfoInlineRestrictions
1025 INLINE_RESPECT_BOUNDARY = 0x00000001, // You can inline if there are no calls from the method being inlined
1026 INLINE_NO_CALLEE_LDSTR = 0x00000002, // You can inline only if you guarantee that if inlinee does an ldstr
1027 // inlinee's module will never see that string (by any means).
1028 // This is due to how we implement the NoStringInterningAttribute
1029 // (by reusing the fixup table).
1030 INLINE_SAME_THIS = 0x00000004, // You can inline only if the callee is on the same this reference as caller
1033 enum CorInfoInlineTypeCheck
1035 CORINFO_INLINE_TYPECHECK_NONE = 0x00000000, // It's not okay to compare type's vtable with a native type handle
1036 CORINFO_INLINE_TYPECHECK_PASS = 0x00000001, // It's okay to compare type's vtable with a native type handle
1037 CORINFO_INLINE_TYPECHECK_USE_HELPER = 0x00000002, // Use a specialized helper to compare type's vtable with native type handle
1040 enum CorInfoInlineTypeCheckSource
1042 CORINFO_INLINE_TYPECHECK_SOURCE_VTABLE = 0x00000000, // Type handle comes from the vtable
1043 CORINFO_INLINE_TYPECHECK_SOURCE_TOKEN = 0x00000001, // Type handle comes from an ldtoken
1046 // If you add more values here, keep it in sync with TailCallTypeMap in ..\vm\ClrEtwAll.man
1047 // and the string enum in CEEInfo::reportTailCallDecision in ..\vm\JITInterface.cpp
1048 enum CorInfoTailCall
1050 TAILCALL_OPTIMIZED = 0, // Optimized tail call (epilog + jmp)
1051 TAILCALL_RECURSIVE = 1, // Optimized into a loop (only when a method tail calls itself)
1052 TAILCALL_HELPER = 2, // Helper assisted tail call (call to JIT_TailCall)
1054 // failures are negative
1055 TAILCALL_FAIL = -1, // Couldn't do a tail call
1058 enum CorInfoCanSkipVerificationResult
1060 CORINFO_VERIFICATION_CANNOT_SKIP = 0, // Cannot skip verification during jit time.
1061 CORINFO_VERIFICATION_CAN_SKIP = 1, // Can skip verification during jit time.
1062 CORINFO_VERIFICATION_RUNTIME_CHECK = 2, // Cannot skip verification during jit time,
1063 // but need to insert a callout to the VM to ask during runtime
1064 // whether to raise a verification or not (if the method is unverifiable).
1065 CORINFO_VERIFICATION_DONT_JIT = 3, // Cannot skip verification during jit time,
1066 // but do not jit the method if is is unverifiable.
1069 enum CorInfoInitClassResult
1071 CORINFO_INITCLASS_NOT_REQUIRED = 0x00, // No class initialization required, but the class is not actually initialized yet
1072 // (e.g. we are guaranteed to run the static constructor in method prolog)
1073 CORINFO_INITCLASS_INITIALIZED = 0x01, // Class initialized
1074 CORINFO_INITCLASS_SPECULATIVE = 0x02, // Class may be initialized speculatively
1075 CORINFO_INITCLASS_USE_HELPER = 0x04, // The JIT must insert class initialization helper call.
1076 CORINFO_INITCLASS_DONT_INLINE = 0x08, // The JIT should not inline the method requesting the class initialization. The class
1077 // initialization requires helper class now, but will not require initialization
1078 // if the method is compiled standalone. Or the method cannot be inlined due to some
1079 // requirement around class initialization such as shared generics.
1082 // Reason codes for making indirect calls
1083 #define INDIRECT_CALL_REASONS() \
1084 INDIRECT_CALL_REASON_FUNC(CORINFO_INDIRECT_CALL_UNKNOWN) \
1085 INDIRECT_CALL_REASON_FUNC(CORINFO_INDIRECT_CALL_EXOTIC) \
1086 INDIRECT_CALL_REASON_FUNC(CORINFO_INDIRECT_CALL_PINVOKE) \
1087 INDIRECT_CALL_REASON_FUNC(CORINFO_INDIRECT_CALL_GENERIC) \
1088 INDIRECT_CALL_REASON_FUNC(CORINFO_INDIRECT_CALL_NO_CODE) \
1089 INDIRECT_CALL_REASON_FUNC(CORINFO_INDIRECT_CALL_FIXUPS) \
1090 INDIRECT_CALL_REASON_FUNC(CORINFO_INDIRECT_CALL_STUB) \
1091 INDIRECT_CALL_REASON_FUNC(CORINFO_INDIRECT_CALL_REMOTING) \
1092 INDIRECT_CALL_REASON_FUNC(CORINFO_INDIRECT_CALL_CER) \
1093 INDIRECT_CALL_REASON_FUNC(CORINFO_INDIRECT_CALL_RESTORE_METHOD) \
1094 INDIRECT_CALL_REASON_FUNC(CORINFO_INDIRECT_CALL_RESTORE_FIRST_CALL) \
1095 INDIRECT_CALL_REASON_FUNC(CORINFO_INDIRECT_CALL_RESTORE_VALUE_TYPE) \
1096 INDIRECT_CALL_REASON_FUNC(CORINFO_INDIRECT_CALL_RESTORE) \
1097 INDIRECT_CALL_REASON_FUNC(CORINFO_INDIRECT_CALL_CANT_PATCH) \
1098 INDIRECT_CALL_REASON_FUNC(CORINFO_INDIRECT_CALL_PROFILING) \
1099 INDIRECT_CALL_REASON_FUNC(CORINFO_INDIRECT_CALL_OTHER_LOADER_MODULE) \
1101 enum CorInfoIndirectCallReason
1103 #undef INDIRECT_CALL_REASON_FUNC
1104 #define INDIRECT_CALL_REASON_FUNC(x) x,
1105 INDIRECT_CALL_REASONS()
1107 #undef INDIRECT_CALL_REASON_FUNC
1109 CORINFO_INDIRECT_CALL_COUNT
1112 // This is for use when the JIT is compiling an instantiation
1113 // of generic code. The JIT needs to know if the generic code itself
1114 // (which can be verified once and for all independently of the
1115 // instantiations) passed verification.
1116 enum CorInfoInstantiationVerification
1118 // The method is NOT a concrete instantiation (eg. List<int>.Add()) of a method
1119 // in a generic class or a generic method. It is either the typical instantiation
1120 // (eg. List<T>.Add()) or entirely non-generic.
1121 INSTVER_NOT_INSTANTIATION = 0,
1123 // The method is an instantiation of a method in a generic class or a generic method,
1124 // and the generic class was successfully verified
1125 INSTVER_GENERIC_PASSED_VERIFICATION = 1,
1127 // The method is an instantiation of a method in a generic class or a generic method,
1128 // and the generic class failed verification
1129 INSTVER_GENERIC_FAILED_VERIFICATION = 2,
1132 // When using CORINFO_HELPER_TAILCALL, the JIT needs to pass certain special
1133 // calling convention/argument passing/handling details to the helper
1134 enum CorInfoHelperTailCallSpecialHandling
1136 CORINFO_TAILCALL_NORMAL = 0x00000000,
1137 CORINFO_TAILCALL_STUB_DISPATCH_ARG = 0x00000001,
1141 inline bool dontInline(CorInfoInline val) {
1145 // Cookie types consumed by the code generator (these are opaque values
1146 // not inspected by the code generator):
1148 typedef struct CORINFO_ASSEMBLY_STRUCT_* CORINFO_ASSEMBLY_HANDLE;
1149 typedef struct CORINFO_MODULE_STRUCT_* CORINFO_MODULE_HANDLE;
1150 typedef struct CORINFO_DEPENDENCY_STRUCT_* CORINFO_DEPENDENCY_HANDLE;
1151 typedef struct CORINFO_CLASS_STRUCT_* CORINFO_CLASS_HANDLE;
1152 typedef struct CORINFO_METHOD_STRUCT_* CORINFO_METHOD_HANDLE;
1153 typedef struct CORINFO_FIELD_STRUCT_* CORINFO_FIELD_HANDLE;
1154 typedef struct CORINFO_ARG_LIST_STRUCT_* CORINFO_ARG_LIST_HANDLE; // represents a list of argument types
1155 typedef struct CORINFO_JUST_MY_CODE_HANDLE_*CORINFO_JUST_MY_CODE_HANDLE;
1156 typedef struct CORINFO_PROFILING_STRUCT_* CORINFO_PROFILING_HANDLE; // a handle guaranteed to be unique per process
1157 typedef struct CORINFO_GENERIC_STRUCT_* CORINFO_GENERIC_HANDLE; // a generic handle (could be any of the above)
1159 // what is actually passed on the varargs call
1160 typedef struct CORINFO_VarArgInfo * CORINFO_VARARGS_HANDLE;
1162 // Generic tokens are resolved with respect to a context, which is usually the method
1163 // being compiled. The CORINFO_CONTEXT_HANDLE indicates which exact instantiation
1164 // (or the open instantiation) is being referred to.
1165 // CORINFO_CONTEXT_HANDLE is more tightly scoped than CORINFO_MODULE_HANDLE. For cases
1166 // where the exact instantiation does not matter, CORINFO_MODULE_HANDLE is used.
1167 typedef CORINFO_METHOD_HANDLE CORINFO_CONTEXT_HANDLE;
1169 typedef struct CORINFO_DEPENDENCY_STRUCT_
1171 CORINFO_MODULE_HANDLE moduleFrom;
1172 CORINFO_MODULE_HANDLE moduleTo;
1173 } CORINFO_DEPENDENCY;
1175 // Bit-twiddling of contexts assumes word-alignment of method handles and type handles
1176 // If this ever changes, some other encoding will be needed
1177 enum CorInfoContextFlags
1179 CORINFO_CONTEXTFLAGS_METHOD = 0x00, // CORINFO_CONTEXT_HANDLE is really a CORINFO_METHOD_HANDLE
1180 CORINFO_CONTEXTFLAGS_CLASS = 0x01, // CORINFO_CONTEXT_HANDLE is really a CORINFO_CLASS_HANDLE
1181 CORINFO_CONTEXTFLAGS_MASK = 0x01
1184 #define MAKE_CLASSCONTEXT(c) (CORINFO_CONTEXT_HANDLE((size_t) (c) | CORINFO_CONTEXTFLAGS_CLASS))
1185 #define MAKE_METHODCONTEXT(m) (CORINFO_CONTEXT_HANDLE((size_t) (m) | CORINFO_CONTEXTFLAGS_METHOD))
1187 enum CorInfoSigInfoFlags
1189 CORINFO_SIGFLAG_IS_LOCAL_SIG = 0x01,
1190 CORINFO_SIGFLAG_IL_STUB = 0x02,
1193 struct CORINFO_SIG_INST
1195 unsigned classInstCount;
1196 CORINFO_CLASS_HANDLE * classInst; // (representative, not exact) instantiation for class type variables in signature
1197 unsigned methInstCount;
1198 CORINFO_CLASS_HANDLE * methInst; // (representative, not exact) instantiation for method type variables in signature
1201 struct CORINFO_SIG_INFO
1203 CorInfoCallConv callConv;
1204 CORINFO_CLASS_HANDLE retTypeClass; // if the return type is a value class, this is its handle (enums are normalized)
1205 CORINFO_CLASS_HANDLE retTypeSigClass;// returns the value class as it is in the sig (enums are not converted to primitives)
1206 CorInfoType retType : 8;
1207 unsigned flags : 8; // used by IL stubs code
1208 unsigned numArgs : 16;
1209 struct CORINFO_SIG_INST sigInst; // information about how type variables are being instantiated in generic code
1210 CORINFO_ARG_LIST_HANDLE args;
1211 PCCOR_SIGNATURE pSig;
1213 CORINFO_MODULE_HANDLE scope; // passed to getArgClass
1216 CorInfoCallConv getCallConv() { return CorInfoCallConv((callConv & CORINFO_CALLCONV_MASK)); }
1217 bool hasThis() { return ((callConv & CORINFO_CALLCONV_HASTHIS) != 0); }
1218 bool hasExplicitThis() { return ((callConv & CORINFO_CALLCONV_EXPLICITTHIS) != 0); }
1219 unsigned totalILArgs() { return (numArgs + hasThis()); }
1220 bool isVarArg() { return ((getCallConv() == CORINFO_CALLCONV_VARARG) || (getCallConv() == CORINFO_CALLCONV_NATIVEVARARG)); }
1221 bool hasTypeArg() { return ((callConv & CORINFO_CALLCONV_PARAMTYPE) != 0); }
1224 struct CORINFO_METHOD_INFO
1226 CORINFO_METHOD_HANDLE ftn;
1227 CORINFO_MODULE_HANDLE scope;
1229 unsigned ILCodeSize;
1232 CorInfoOptions options;
1233 CorInfoRegionKind regionKind;
1234 CORINFO_SIG_INFO args;
1235 CORINFO_SIG_INFO locals;
1238 //----------------------------------------------------------------------------
1239 // Looking up handles and addresses.
1241 // When the JIT requests a handle, the EE may direct the JIT that it must
1242 // access the handle in a variety of ways. These are packed as
1243 // CORINFO_CONST_LOOKUP
1244 // or CORINFO_LOOKUP (contains either a CORINFO_CONST_LOOKUP or a CORINFO_RUNTIME_LOOKUP)
1246 // Constant Lookups v. Runtime Lookups (i.e. when will Runtime Lookups be generated?)
1247 // -----------------------------------------------------------------------------------
1249 // CORINFO_LOOKUP_KIND is part of the result type of embedGenericHandle,
1250 // getVirtualCallInfo and any other functions that may require a
1251 // runtime lookup when compiling shared generic code.
1253 // CORINFO_LOOKUP_KIND indicates whether a particular token in the instruction stream can be:
1254 // (a) Mapped to a handle (type, field or method) at compile-time (!needsRuntimeLookup)
1255 // (b) Must be looked up at run-time, and if so which runtime lookup technique should be used (see below)
1257 // If the JIT or EE does not support code sharing for generic code, then
1258 // all CORINFO_LOOKUP results will be "constant lookups", i.e.
1259 // the needsRuntimeLookup of CORINFO_LOOKUP.lookupKind.needsRuntimeLookup
1265 // Constant Lookups are either:
1266 // IAT_VALUE: immediate (relocatable) values,
1267 // IAT_PVALUE: immediate values access via an indirection through an immediate (relocatable) address
1268 // IAT_RELPVALUE: immediate values access via a relative indirection through an immediate offset
1269 // IAT_PPVALUE: immediate values access via a double indirection through an immediate (relocatable) address
1274 // CORINFO_LOOKUP_KIND is part of the result type of embedGenericHandle,
1275 // getVirtualCallInfo and any other functions that may require a
1276 // runtime lookup when compiling shared generic code.
1278 // CORINFO_LOOKUP_KIND indicates whether a particular token in the instruction stream can be:
1279 // (a) Mapped to a handle (type, field or method) at compile-time (!needsRuntimeLookup)
1280 // (b) Must be looked up at run-time using the class dictionary
1281 // stored in the vtable of the this pointer (needsRuntimeLookup && THISOBJ)
1282 // (c) Must be looked up at run-time using the method dictionary
1283 // stored in the method descriptor parameter passed to a generic
1284 // method (needsRuntimeLookup && METHODPARAM)
1285 // (d) Must be looked up at run-time using the class dictionary stored
1286 // in the vtable parameter passed to a method in a generic
1287 // struct (needsRuntimeLookup && CLASSPARAM)
1289 struct CORINFO_CONST_LOOKUP
1291 // If the handle is obtained at compile-time, then this handle is the "exact" handle (class, method, or field)
1292 // Otherwise, it's a representative...
1294 // IAT_VALUE --> "handle" stores the real handle or "addr " stores the computed address
1295 // IAT_PVALUE --> "addr" stores a pointer to a location which will hold the real handle
1296 // IAT_RELPVALUE --> "addr" stores a relative pointer to a location which will hold the real handle
1297 // IAT_PPVALUE --> "addr" stores a double indirection to a location which will hold the real handle
1299 InfoAccessType accessType;
1302 CORINFO_GENERIC_HANDLE handle;
1307 enum CORINFO_RUNTIME_LOOKUP_KIND
1309 CORINFO_LOOKUP_THISOBJ,
1310 CORINFO_LOOKUP_METHODPARAM,
1311 CORINFO_LOOKUP_CLASSPARAM,
1314 struct CORINFO_LOOKUP_KIND
1316 bool needsRuntimeLookup;
1317 CORINFO_RUNTIME_LOOKUP_KIND runtimeLookupKind;
1319 // The 'runtimeLookupFlags' and 'runtimeLookupArgs' fields
1320 // are just for internal VM / ZAP communication, not to be used by the JIT.
1321 WORD runtimeLookupFlags;
1322 void * runtimeLookupArgs;
1326 // CORINFO_RUNTIME_LOOKUP indicates the details of the runtime lookup
1327 // operation to be performed.
1329 // CORINFO_MAXINDIRECTIONS is the maximum number of
1330 // indirections used by runtime lookups.
1331 // This accounts for up to 2 indirections to get at a dictionary followed by a possible spill slot
1333 #define CORINFO_MAXINDIRECTIONS 4
1334 #define CORINFO_USEHELPER ((WORD) 0xffff)
1336 struct CORINFO_RUNTIME_LOOKUP
1338 // This is signature you must pass back to the runtime lookup helper
1341 // Here is the helper you must call. It is one of CORINFO_HELP_RUNTIMEHANDLE_* helpers.
1342 CorInfoHelpFunc helper;
1344 // Number of indirections to get there
1345 // CORINFO_USEHELPER = don't know how to get it, so use helper function at run-time instead
1346 // 0 = use the this pointer itself (e.g. token is C<!0> inside code in sealed class C)
1347 // or method desc itself (e.g. token is method void M::mymeth<!!0>() inside code in M::mymeth)
1348 // Otherwise, follow each byte-offset stored in the "offsets[]" array (may be negative)
1351 // If set, test for null and branch to helper if null
1354 // If set, test the lowest bit and dereference if set (see code:FixupPointer)
1357 SIZE_T offsets[CORINFO_MAXINDIRECTIONS];
1359 // If set, first offset is indirect.
1360 // 0 means that value stored at first offset (offsets[0]) from pointer is next pointer, to which the next offset
1361 // (offsets[1]) is added and so on.
1362 // 1 means that value stored at first offset (offsets[0]) from pointer is offset1, and the next pointer is
1363 // stored at pointer+offsets[0]+offset1.
1364 bool indirectFirstOffset;
1366 // If set, second offset is indirect.
1367 // 0 means that value stored at second offset (offsets[1]) from pointer is next pointer, to which the next offset
1368 // (offsets[2]) is added and so on.
1369 // 1 means that value stored at second offset (offsets[1]) from pointer is offset2, and the next pointer is
1370 // stored at pointer+offsets[1]+offset2.
1371 bool indirectSecondOffset;
1374 // Result of calling embedGenericHandle
1375 struct CORINFO_LOOKUP
1377 CORINFO_LOOKUP_KIND lookupKind;
1381 // If kind.needsRuntimeLookup then this indicates how to do the lookup
1382 CORINFO_RUNTIME_LOOKUP runtimeLookup;
1384 // If the handle is obtained at compile-time, then this handle is the "exact" handle (class, method, or field)
1385 // Otherwise, it's a representative... If accessType is
1386 // IAT_VALUE --> "handle" stores the real handle or "addr " stores the computed address
1387 // IAT_PVALUE --> "addr" stores a pointer to a location which will hold the real handle
1388 // IAT_RELPVALUE --> "addr" stores a relative pointer to a location which will hold the real handle
1389 // IAT_PPVALUE --> "addr" stores a double indirection to a location which will hold the real handle
1390 CORINFO_CONST_LOOKUP constLookup;
1394 enum CorInfoGenericHandleType
1396 CORINFO_HANDLETYPE_UNKNOWN,
1397 CORINFO_HANDLETYPE_CLASS,
1398 CORINFO_HANDLETYPE_METHOD,
1399 CORINFO_HANDLETYPE_FIELD
1402 //----------------------------------------------------------------------------
1403 // Embedding type, method and field handles (for "ldtoken" or to pass back to helpers)
1405 // Result of calling embedGenericHandle
1406 struct CORINFO_GENERICHANDLE_RESULT
1408 CORINFO_LOOKUP lookup;
1410 // compileTimeHandle is guaranteed to be either NULL or a handle that is usable during compile time.
1411 // It must not be embedded in the code because it might not be valid at run-time.
1412 CORINFO_GENERIC_HANDLE compileTimeHandle;
1414 // Type of the result
1415 CorInfoGenericHandleType handleType;
1418 #define CORINFO_ACCESS_ALLOWED_MAX_ARGS 4
1420 enum CorInfoAccessAllowedHelperArgType
1422 CORINFO_HELPER_ARG_TYPE_Invalid = 0,
1423 CORINFO_HELPER_ARG_TYPE_Field = 1,
1424 CORINFO_HELPER_ARG_TYPE_Method = 2,
1425 CORINFO_HELPER_ARG_TYPE_Class = 3,
1426 CORINFO_HELPER_ARG_TYPE_Module = 4,
1427 CORINFO_HELPER_ARG_TYPE_Const = 5,
1429 struct CORINFO_HELPER_ARG
1433 CORINFO_FIELD_HANDLE fieldHandle;
1434 CORINFO_METHOD_HANDLE methodHandle;
1435 CORINFO_CLASS_HANDLE classHandle;
1436 CORINFO_MODULE_HANDLE moduleHandle;
1439 CorInfoAccessAllowedHelperArgType argType;
1441 void Set(CORINFO_METHOD_HANDLE handle)
1443 argType = CORINFO_HELPER_ARG_TYPE_Method;
1444 methodHandle = handle;
1447 void Set(CORINFO_FIELD_HANDLE handle)
1449 argType = CORINFO_HELPER_ARG_TYPE_Field;
1450 fieldHandle = handle;
1453 void Set(CORINFO_CLASS_HANDLE handle)
1455 argType = CORINFO_HELPER_ARG_TYPE_Class;
1456 classHandle = handle;
1459 void Set(size_t value)
1461 argType = CORINFO_HELPER_ARG_TYPE_Const;
1466 struct CORINFO_HELPER_DESC
1468 CorInfoHelpFunc helperNum;
1470 CORINFO_HELPER_ARG args[CORINFO_ACCESS_ALLOWED_MAX_ARGS];
1473 //----------------------------------------------------------------------------
1474 // getCallInfo and CORINFO_CALL_INFO: The EE instructs the JIT about how to make a call
1480 // Indicates that the JIT can use getFunctionEntryPoint to make a call,
1481 // i.e. there is nothing abnormal about the call. The JITs know what to do if they get this.
1482 // Except in the case of constraint calls (see below), [targetMethodHandle] will hold
1483 // the CORINFO_METHOD_HANDLE that a call to findMethod would
1485 // This flag may be combined with nullInstanceCheck=TRUE for uses of callvirt on methods that can
1486 // be resolved at compile-time (non-virtual, final or sealed).
1488 // CORINFO_CALL_CODE_POINTER (shared generic code only) :
1489 // Indicates that the JIT should do an indirect call to the entrypoint given by address, which may be specified
1490 // as a runtime lookup by CORINFO_CALL_INFO::codePointerLookup.
1491 // [targetMethodHandle] will not hold a valid value.
1492 // This flag may be combined with nullInstanceCheck=TRUE for uses of callvirt on methods whose target method can
1493 // be resolved at compile-time but whose instantiation can be resolved only through runtime lookup.
1495 // CORINFO_VIRTUALCALL_STUB (interface calls) :
1496 // Indicates that the EE supports "stub dispatch" and request the JIT to make a
1497 // "stub dispatch" call (an indirect call through CORINFO_CALL_INFO::stubLookup,
1498 // similar to CORINFO_CALL_CODE_POINTER).
1499 // "Stub dispatch" is a specialized calling sequence (that may require use of NOPs)
1500 // which allow the runtime to determine the call-site after the call has been dispatched.
1501 // If the call is too complex for the JIT (e.g. because
1502 // fetching the dispatch stub requires a runtime lookup, i.e. lookupKind.needsRuntimeLookup
1503 // is set) then the JIT is allowed to implement the call as if it were CORINFO_VIRTUALCALL_LDVIRTFTN
1504 // [targetMethodHandle] will hold the CORINFO_METHOD_HANDLE that a call to findMethod would
1506 // This flag is always accompanied by nullInstanceCheck=TRUE.
1508 // CORINFO_VIRTUALCALL_LDVIRTFTN (virtual generic methods) :
1509 // Indicates that the EE provides no way to implement the call directly and
1510 // that the JIT should use a LDVIRTFTN sequence (as implemented by CORINFO_HELP_VIRTUAL_FUNC_PTR)
1511 // followed by an indirect call.
1512 // [targetMethodHandle] will hold the CORINFO_METHOD_HANDLE that a call to findMethod would
1514 // This flag is always accompanied by nullInstanceCheck=TRUE though typically the null check will
1515 // be implicit in the access through the instance pointer.
1517 // CORINFO_VIRTUALCALL_VTABLE (regular virtual methods) :
1518 // Indicates that the EE supports vtable dispatch and that the JIT should use getVTableOffset etc.
1519 // to implement the call.
1520 // [targetMethodHandle] will hold the CORINFO_METHOD_HANDLE that a call to findMethod would
1522 // This flag is always accompanied by nullInstanceCheck=TRUE though typically the null check will
1523 // be implicit in the access through the instance pointer.
1525 // thisTransform and constraint calls
1526 // ----------------------------------
1528 // For evertyhing besides "constrained." calls "thisTransform" is set to
1529 // CORINFO_NO_THIS_TRANSFORM.
1531 // For "constrained." calls the EE attempts to resolve the call at compile
1532 // time to a more specific method, or (shared generic code only) to a runtime lookup
1533 // for a code pointer for the more specific method.
1535 // In order to permit this, the "this" pointer supplied for a "constrained." call
1536 // is a byref to an arbitrary type (see the IL spec). The "thisTransform" field
1537 // will indicate how the JIT must transform the "this" pointer in order
1538 // to be able to call the resolved method:
1540 // CORINFO_NO_THIS_TRANSFORM --> Leave it as a byref to an unboxed value type
1541 // CORINFO_BOX_THIS --> Box it to produce an object
1542 // CORINFO_DEREF_THIS --> Deref the byref to get an object reference
1544 // In addition, the "kind" field will be set as follows for constraint calls:
1546 // CORINFO_CALL --> the call was resolved at compile time, and
1547 // can be compiled like a normal call.
1548 // CORINFO_CALL_CODE_POINTER --> the call was resolved, but the target address will be
1549 // computed at runtime. Only returned for shared generic code.
1550 // CORINFO_VIRTUALCALL_STUB,
1551 // CORINFO_VIRTUALCALL_LDVIRTFTN,
1552 // CORINFO_VIRTUALCALL_VTABLE --> usual values indicating that a virtual call must be made
1554 enum CORINFO_CALL_KIND
1557 CORINFO_CALL_CODE_POINTER,
1558 CORINFO_VIRTUALCALL_STUB,
1559 CORINFO_VIRTUALCALL_LDVIRTFTN,
1560 CORINFO_VIRTUALCALL_VTABLE
1563 // Indicates that the CORINFO_VIRTUALCALL_VTABLE lookup needn't do a chunk indirection
1564 #define CORINFO_VIRTUALCALL_NO_CHUNK 0xFFFFFFFF
1566 enum CORINFO_THIS_TRANSFORM
1568 CORINFO_NO_THIS_TRANSFORM,
1573 enum CORINFO_CALLINFO_FLAGS
1575 CORINFO_CALLINFO_NONE = 0x0000,
1576 CORINFO_CALLINFO_ALLOWINSTPARAM = 0x0001, // Can the compiler generate code to pass an instantiation parameters? Simple compilers should not use this flag
1577 CORINFO_CALLINFO_CALLVIRT = 0x0002, // Is it a virtual call?
1578 CORINFO_CALLINFO_KINDONLY = 0x0004, // This is set to only query the kind of call to perform, without getting any other information
1579 CORINFO_CALLINFO_VERIFICATION = 0x0008, // Gets extra verification information.
1580 CORINFO_CALLINFO_SECURITYCHECKS = 0x0010, // Perform security checks.
1581 CORINFO_CALLINFO_LDFTN = 0x0020, // Resolving target of LDFTN
1582 CORINFO_CALLINFO_ATYPICAL_CALLSITE = 0x0040, // Atypical callsite that cannot be disassembled by delay loading helper
1585 enum CorInfoIsAccessAllowedResult
1587 CORINFO_ACCESS_ALLOWED = 0, // Call allowed
1588 CORINFO_ACCESS_ILLEGAL = 1, // Call not allowed
1589 CORINFO_ACCESS_RUNTIME_CHECK = 2, // Ask at runtime whether to allow the call or not
1593 // This enum is used for JIT to tell EE where this token comes from.
1594 // E.g. Depending on different opcodes, we might allow/disallow certain types of tokens or
1595 // return different types of handles (e.g. boxed vs. regular entrypoints)
1596 enum CorInfoTokenKind
1598 CORINFO_TOKENKIND_Class = 0x01,
1599 CORINFO_TOKENKIND_Method = 0x02,
1600 CORINFO_TOKENKIND_Field = 0x04,
1601 CORINFO_TOKENKIND_Mask = 0x07,
1603 // token comes from CEE_LDTOKEN
1604 CORINFO_TOKENKIND_Ldtoken = 0x10 | CORINFO_TOKENKIND_Class | CORINFO_TOKENKIND_Method | CORINFO_TOKENKIND_Field,
1606 // token comes from CEE_CASTCLASS or CEE_ISINST
1607 CORINFO_TOKENKIND_Casting = 0x20 | CORINFO_TOKENKIND_Class,
1609 // token comes from CEE_NEWARR
1610 CORINFO_TOKENKIND_Newarr = 0x40 | CORINFO_TOKENKIND_Class,
1612 // token comes from CEE_BOX
1613 CORINFO_TOKENKIND_Box = 0x80 | CORINFO_TOKENKIND_Class,
1615 // token comes from CEE_CONSTRAINED
1616 CORINFO_TOKENKIND_Constrained = 0x100 | CORINFO_TOKENKIND_Class,
1618 // token comes from CEE_NEWOBJ
1619 CORINFO_TOKENKIND_NewObj = 0x200 | CORINFO_TOKENKIND_Method,
1621 // token comes from CEE_LDVIRTFTN
1622 CORINFO_TOKENKIND_Ldvirtftn = 0x400 | CORINFO_TOKENKIND_Method,
1625 struct CORINFO_RESOLVED_TOKEN
1628 // [In] arguments of resolveToken
1630 CORINFO_CONTEXT_HANDLE tokenContext; //Context for resolution of generic arguments
1631 CORINFO_MODULE_HANDLE tokenScope;
1632 mdToken token; //The source token
1633 CorInfoTokenKind tokenType;
1636 // [Out] arguments of resolveToken.
1637 // - Type handle is always non-NULL.
1638 // - At most one of method and field handles is non-NULL (according to the token type).
1639 // - Method handle is an instantiating stub only for generic methods. Type handle
1640 // is required to provide the full context for methods in generic types.
1642 CORINFO_CLASS_HANDLE hClass;
1643 CORINFO_METHOD_HANDLE hMethod;
1644 CORINFO_FIELD_HANDLE hField;
1647 // [Out] TypeSpec and MethodSpec signatures for generics. NULL otherwise.
1649 PCCOR_SIGNATURE pTypeSpec;
1651 PCCOR_SIGNATURE pMethodSpec;
1655 struct CORINFO_CALL_INFO
1657 CORINFO_METHOD_HANDLE hMethod; //target method handle
1658 unsigned methodFlags; //flags for the target method
1660 unsigned classFlags; //flags for CORINFO_RESOLVED_TOKEN::hClass
1662 CORINFO_SIG_INFO sig;
1664 //Verification information
1665 unsigned verMethodFlags; // flags for CORINFO_RESOLVED_TOKEN::hMethod
1666 CORINFO_SIG_INFO verSig;
1667 //All of the regular method data is the same... hMethod might not be the same as CORINFO_RESOLVED_TOKEN::hMethod
1671 // - CORINFO_ACCESS_ALLOWED - The access is allowed.
1672 // - CORINFO_ACCESS_ILLEGAL - This access cannot be allowed (i.e. it is public calling private). The
1673 // JIT may either insert the callsiteCalloutHelper into the code (as per a verification error) or
1674 // call throwExceptionFromHelper on the callsiteCalloutHelper. In this case callsiteCalloutHelper
1675 // is guaranteed not to return.
1676 // - CORINFO_ACCESS_RUNTIME_CHECK - The jit must insert the callsiteCalloutHelper at the call site.
1677 // the helper may return
1678 CorInfoIsAccessAllowedResult accessAllowed;
1679 CORINFO_HELPER_DESC callsiteCalloutHelper;
1681 // See above section on constraintCalls to understand when these are set to unusual values.
1682 CORINFO_THIS_TRANSFORM thisTransform;
1684 CORINFO_CALL_KIND kind;
1685 BOOL nullInstanceCheck;
1687 // Context for inlining and hidden arg
1688 CORINFO_CONTEXT_HANDLE contextHandle;
1689 BOOL exactContextNeedsRuntimeLookup; // Set if contextHandle is approx handle. Runtime lookup is required to get the exact handle.
1691 // If kind.CORINFO_VIRTUALCALL_STUB then stubLookup will be set.
1692 // If kind.CORINFO_CALL_CODE_POINTER then entryPointLookup will be set.
1695 CORINFO_LOOKUP stubLookup;
1697 CORINFO_LOOKUP codePointerLookup;
1700 CORINFO_CONST_LOOKUP instParamLookup; // Used by Ready-to-Run
1702 BOOL secureDelegateInvoke;
1705 //----------------------------------------------------------------------------
1706 // getFieldInfo and CORINFO_FIELD_INFO: The EE instructs the JIT about how to access a field
1708 enum CORINFO_FIELD_ACCESSOR
1710 CORINFO_FIELD_INSTANCE, // regular instance field at given offset from this-ptr
1711 CORINFO_FIELD_INSTANCE_WITH_BASE, // instance field with base offset (used by Ready-to-Run)
1712 CORINFO_FIELD_INSTANCE_HELPER, // instance field accessed using helper (arguments are this, FieldDesc * and the value)
1713 CORINFO_FIELD_INSTANCE_ADDR_HELPER, // instance field accessed using address-of helper (arguments are this and FieldDesc *)
1715 CORINFO_FIELD_STATIC_ADDRESS, // field at given address
1716 CORINFO_FIELD_STATIC_RVA_ADDRESS, // RVA field at given address
1717 CORINFO_FIELD_STATIC_SHARED_STATIC_HELPER, // static field accessed using the "shared static" helper (arguments are ModuleID + ClassID)
1718 CORINFO_FIELD_STATIC_GENERICS_STATIC_HELPER, // static field access using the "generic static" helper (argument is MethodTable *)
1719 CORINFO_FIELD_STATIC_ADDR_HELPER, // static field accessed using address-of helper (argument is FieldDesc *)
1720 CORINFO_FIELD_STATIC_TLS, // unmanaged TLS access
1721 CORINFO_FIELD_STATIC_READYTORUN_HELPER, // static field access using a runtime lookup helper
1723 CORINFO_FIELD_INTRINSIC_ZERO, // intrinsic zero (IntPtr.Zero, UIntPtr.Zero)
1724 CORINFO_FIELD_INTRINSIC_EMPTY_STRING, // intrinsic emptry string (String.Empty)
1725 CORINFO_FIELD_INTRINSIC_ISLITTLEENDIAN, // intrinsic BitConverter.IsLittleEndian
1728 // Set of flags returned in CORINFO_FIELD_INFO::fieldFlags
1729 enum CORINFO_FIELD_FLAGS
1731 CORINFO_FLG_FIELD_STATIC = 0x00000001,
1732 CORINFO_FLG_FIELD_UNMANAGED = 0x00000002, // RVA field
1733 CORINFO_FLG_FIELD_FINAL = 0x00000004,
1734 CORINFO_FLG_FIELD_STATIC_IN_HEAP = 0x00000008, // See code:#StaticFields. This static field is in the GC heap as a boxed object
1735 CORINFO_FLG_FIELD_SAFESTATIC_BYREF_RETURN = 0x00000010, // Field can be returned safely (has GC heap lifetime)
1736 CORINFO_FLG_FIELD_INITCLASS = 0x00000020, // initClass has to be called before accessing the field
1737 CORINFO_FLG_FIELD_PROTECTED = 0x00000040,
1740 struct CORINFO_FIELD_INFO
1742 CORINFO_FIELD_ACCESSOR fieldAccessor;
1743 unsigned fieldFlags;
1745 // Helper to use if the field access requires it
1746 CorInfoHelpFunc helper;
1748 // Field offset if there is one
1751 CorInfoType fieldType;
1752 CORINFO_CLASS_HANDLE structType; //possibly null
1754 //See CORINFO_CALL_INFO.accessAllowed
1755 CorInfoIsAccessAllowedResult accessAllowed;
1756 CORINFO_HELPER_DESC accessCalloutHelper;
1758 CORINFO_CONST_LOOKUP fieldLookup; // Used by Ready-to-Run
1761 //----------------------------------------------------------------------------
1762 // Exception handling
1764 struct CORINFO_EH_CLAUSE
1766 CORINFO_EH_CLAUSE_FLAGS Flags;
1769 DWORD HandlerOffset;
1770 DWORD HandlerLength;
1773 DWORD ClassToken; // use for type-based exception handlers
1774 DWORD FilterOffset; // use for filter-based exception handlers (COR_ILEXCEPTION_FILTER is set)
1788 DWORD dwExtendedFeatures;
1791 enum CORINFO_RUNTIME_ABI
1793 CORINFO_DESKTOP_ABI = 0x100,
1794 CORINFO_CORECLR_ABI = 0x200,
1795 CORINFO_CORERT_ABI = 0x300,
1798 // For some highly optimized paths, the JIT must generate code that directly
1799 // manipulates internal EE data structures. The getEEInfo() helper returns
1800 // this structure containing the needed offsets and values.
1801 struct CORINFO_EE_INFO
1803 // Information about the InlinedCallFrame structure layout
1804 struct InlinedCallFrameInfo
1806 // Size of the Frame structure
1809 unsigned offsetOfGSCookie;
1810 unsigned offsetOfFrameVptr;
1811 unsigned offsetOfFrameLink;
1812 unsigned offsetOfCallSiteSP;
1813 unsigned offsetOfCalleeSavedFP;
1814 unsigned offsetOfCallTarget;
1815 unsigned offsetOfReturnAddress;
1817 inlinedCallFrameInfo;
1819 // Offsets into the Thread structure
1820 unsigned offsetOfThreadFrame; // offset of the current Frame
1821 unsigned offsetOfGCState; // offset of the preemptive/cooperative state of the Thread
1824 unsigned offsetOfDelegateInstance;
1825 unsigned offsetOfDelegateFirstTarget;
1827 // Secure delegate offsets
1828 unsigned offsetOfSecureDelegateIndirectCell;
1831 unsigned offsetOfTransparentProxyRP;
1832 unsigned offsetOfRealProxyServer;
1835 unsigned offsetOfObjArrayData;
1837 // Reverse PInvoke offsets
1838 unsigned sizeOfReversePInvokeFrame;
1843 // Null object offset
1844 size_t maxUncheckedOffsetForNullObject;
1846 // Target ABI. Combined with target architecture and OS to determine
1847 // GC, EH, and unwind styles.
1848 CORINFO_RUNTIME_ABI targetAbi;
1856 // This is used to indicate that a finally has been called
1857 // "locally" by the try block
1858 enum { LCL_FINALLY_MARK = 0xFC }; // FC = "Finally Call"
1860 /**********************************************************************************
1861 * The following is the internal structure of an object that the compiler knows about
1862 * when it generates code
1863 **********************************************************************************/
1865 #include <pshpack4.h>
1867 typedef void* CORINFO_MethodPtr; // a generic method pointer
1869 struct CORINFO_Object
1871 CORINFO_MethodPtr *methTable; // the vtable for the object
1874 struct CORINFO_String : public CORINFO_Object
1877 wchar_t chars[1]; // actually of variable size
1880 struct CORINFO_Array : public CORINFO_Object
1888 /* Multi-dimensional arrays have the lengths and bounds here */
1889 unsigned dimLength[length];
1890 unsigned dimBound[length];
1895 __int8 i1Elems[1]; // actually of variable size
1896 unsigned __int8 u1Elems[1];
1898 unsigned __int16 u2Elems[1];
1900 unsigned __int32 u4Elems[1];
1905 #include <pshpack4.h>
1906 struct CORINFO_Array8 : public CORINFO_Object
1917 unsigned __int64 u8Elems[1];
1921 #include <poppack.h>
1923 struct CORINFO_RefArray : public CORINFO_Object
1931 /* Multi-dimensional arrays have the lengths and bounds here */
1932 unsigned dimLength[length];
1933 unsigned dimBound[length];
1936 CORINFO_Object* refElems[1]; // actually of variable size;
1939 struct CORINFO_RefAny
1942 CORINFO_CLASS_HANDLE type;
1945 // The jit assumes the CORINFO_VARARGS_HANDLE is a pointer to a subclass of this
1946 struct CORINFO_VarArgInfo
1948 unsigned argBytes; // number of bytes the arguments take up.
1949 // (The CORINFO_VARARGS_HANDLE counts as an arg)
1952 #include <poppack.h>
1954 #define SIZEOF__CORINFO_Object TARGET_POINTER_SIZE /* methTable */
1956 #define OFFSETOF__CORINFO_Array__length SIZEOF__CORINFO_Object
1957 #ifdef _TARGET_64BIT_
1958 #define OFFSETOF__CORINFO_Array__data (OFFSETOF__CORINFO_Array__length + sizeof(unsigned __int32) /* length */ + sizeof(unsigned __int32) /* alignpad */)
1960 #define OFFSETOF__CORINFO_Array__data (OFFSETOF__CORINFO_Array__length + sizeof(unsigned __int32) /* length */)
1963 #define OFFSETOF__CORINFO_TypedReference__dataPtr 0
1964 #define OFFSETOF__CORINFO_TypedReference__type (OFFSETOF__CORINFO_TypedReference__dataPtr + TARGET_POINTER_SIZE /* dataPtr */)
1966 #define OFFSETOF__CORINFO_String__stringLen SIZEOF__CORINFO_Object
1967 #define OFFSETOF__CORINFO_String__chars (OFFSETOF__CORINFO_String__stringLen + sizeof(unsigned __int32) /* stringLen */)
1969 enum CorInfoSecurityRuntimeChecks
1971 CORINFO_ACCESS_SECURITY_NONE = 0,
1972 CORINFO_ACCESS_SECURITY_TRANSPARENCY = 0x0001 // check that transparency rules are enforced between the caller and callee
1976 /* data to optimize delegate construction */
1977 struct DelegateCtorArgs
1985 // use offsetof to get the offset of the fields above
1986 #include <stddef.h> // offsetof
1988 // Guard-stack cookie for preventing against stack buffer overruns
1989 typedef SIZE_T GSCookie;
1991 #include "cordebuginfo.h"
1993 /**********************************************************************************/
1994 // Some compilers cannot arbitrarily allow the handler nesting level to grow
1995 // arbitrarily during Edit'n'Continue.
1996 // This is the maximum nesting level that a compiler needs to support for EnC
1998 const int MAX_EnC_HANDLER_NESTING_LEVEL = 6;
2000 // Results from type comparison queries
2001 enum class TypeCompareState
2003 MustNot = -1, // types are not equal
2004 May = 0, // types may be equal (must test at runtime)
2005 Must = 1, // type are equal
2009 // This interface is logically split into sections for each class of information
2010 // (ICorMethodInfo, ICorModuleInfo, etc.). This split used to exist physically as well
2011 // using virtual inheritance, but was eliminated to improve efficiency of the JIT-EE
2014 class ICorStaticInfo
2017 /**********************************************************************************/
2021 /**********************************************************************************/
2023 // return flags (defined above, CORINFO_FLG_PUBLIC ...)
2024 virtual DWORD getMethodAttribs (
2025 CORINFO_METHOD_HANDLE ftn /* IN */
2028 // sets private JIT flags, which can be, retrieved using getAttrib.
2029 virtual void setMethodAttribs (
2030 CORINFO_METHOD_HANDLE ftn, /* IN */
2031 CorInfoMethodRuntimeFlags attribs /* IN */
2034 // Given a method descriptor ftnHnd, extract signature information into sigInfo
2036 // 'memberParent' is typically only set when verifying. It should be the
2037 // result of calling getMemberParent.
2038 virtual void getMethodSig (
2039 CORINFO_METHOD_HANDLE ftn, /* IN */
2040 CORINFO_SIG_INFO *sig, /* OUT */
2041 CORINFO_CLASS_HANDLE memberParent = NULL /* IN */
2044 /*********************************************************************
2045 * Note the following methods can only be used on functions known
2046 * to be IL. This includes the method being compiled and any method
2047 * that 'getMethodInfo' returns true for
2048 *********************************************************************/
2050 // return information about a method private to the implementation
2051 // returns false if method is not IL, or is otherwise unavailable.
2052 // This method is used to fetch data needed to inline functions
2053 virtual bool getMethodInfo (
2054 CORINFO_METHOD_HANDLE ftn, /* IN */
2055 CORINFO_METHOD_INFO* info /* OUT */
2058 // Decides if you have any limitations for inlining. If everything's OK, it will return
2059 // INLINE_PASS and will fill out pRestrictions with a mask of restrictions the caller of this
2060 // function must respect. If caller passes pRestrictions = NULL, if there are any restrictions
2061 // INLINE_FAIL will be returned
2063 // The callerHnd must be the immediate caller (i.e. when we have a chain of inlined calls)
2065 // The inlined method need not be verified
2067 virtual CorInfoInline canInline (
2068 CORINFO_METHOD_HANDLE callerHnd, /* IN */
2069 CORINFO_METHOD_HANDLE calleeHnd, /* IN */
2070 DWORD* pRestrictions /* OUT */
2073 // Reports whether or not a method can be inlined, and why. canInline is responsible for reporting all
2074 // inlining results when it returns INLINE_FAIL and INLINE_NEVER. All other results are reported by the
2076 virtual void reportInliningDecision (CORINFO_METHOD_HANDLE inlinerHnd,
2077 CORINFO_METHOD_HANDLE inlineeHnd,
2078 CorInfoInline inlineResult,
2079 const char * reason) = 0;
2082 // Returns false if the call is across security boundaries thus we cannot tailcall
2084 // The callerHnd must be the immediate caller (i.e. when we have a chain of inlined calls)
2085 virtual bool canTailCall (
2086 CORINFO_METHOD_HANDLE callerHnd, /* IN */
2087 CORINFO_METHOD_HANDLE declaredCalleeHnd, /* IN */
2088 CORINFO_METHOD_HANDLE exactCalleeHnd, /* IN */
2089 bool fIsTailPrefix /* IN */
2092 // Reports whether or not a method can be tail called, and why.
2093 // canTailCall is responsible for reporting all results when it returns
2094 // false. All other results are reported by the JIT.
2095 virtual void reportTailCallDecision (CORINFO_METHOD_HANDLE callerHnd,
2096 CORINFO_METHOD_HANDLE calleeHnd,
2098 CorInfoTailCall tailCallResult,
2099 const char * reason) = 0;
2101 // get individual exception handler
2102 virtual void getEHinfo(
2103 CORINFO_METHOD_HANDLE ftn, /* IN */
2104 unsigned EHnumber, /* IN */
2105 CORINFO_EH_CLAUSE* clause /* OUT */
2108 // return class it belongs to
2109 virtual CORINFO_CLASS_HANDLE getMethodClass (
2110 CORINFO_METHOD_HANDLE method
2113 // return module it belongs to
2114 virtual CORINFO_MODULE_HANDLE getMethodModule (
2115 CORINFO_METHOD_HANDLE method
2118 // This function returns the offset of the specified method in the
2119 // vtable of it's owning class or interface.
2120 virtual void getMethodVTableOffset (
2121 CORINFO_METHOD_HANDLE method, /* IN */
2122 unsigned* offsetOfIndirection, /* OUT */
2123 unsigned* offsetAfterIndirection, /* OUT */
2124 bool* isRelative /* OUT */
2127 // Find the virtual method in implementingClass that overrides virtualMethod,
2128 // or the method in implementingClass that implements the interface method
2129 // represented by virtualMethod.
2131 // Return null if devirtualization is not possible. Owner type is optional
2132 // and provides additional context for shared interface devirtualization.
2133 virtual CORINFO_METHOD_HANDLE resolveVirtualMethod(
2134 CORINFO_METHOD_HANDLE virtualMethod, /* IN */
2135 CORINFO_CLASS_HANDLE implementingClass, /* IN */
2136 CORINFO_CONTEXT_HANDLE ownerType = NULL /* IN */
2139 // Get the unboxed entry point for a method, if possible.
2140 virtual CORINFO_METHOD_HANDLE getUnboxedEntry(
2141 CORINFO_METHOD_HANDLE ftn,
2142 bool* requiresInstMethodTableArg = NULL /* OUT */
2145 // Given T, return the type of the default EqualityComparer<T>.
2146 // Returns null if the type can't be determined exactly.
2147 virtual CORINFO_CLASS_HANDLE getDefaultEqualityComparerClass(
2148 CORINFO_CLASS_HANDLE elemType
2151 // Given resolved token that corresponds to an intrinsic classified as
2152 // a CORINFO_INTRINSIC_GetRawHandle intrinsic, fetch the handle associated
2153 // with the token. If this is not possible at compile-time (because the current method's
2154 // code is shared and the token contains generic parameters) then indicate
2155 // how the handle should be looked up at runtime.
2156 virtual void expandRawHandleIntrinsic(
2157 CORINFO_RESOLVED_TOKEN * pResolvedToken,
2158 CORINFO_GENERICHANDLE_RESULT * pResult) = 0;
2160 // If a method's attributes have (getMethodAttribs) CORINFO_FLG_INTRINSIC set,
2161 // getIntrinsicID() returns the intrinsic ID.
2162 // *pMustExpand tells whether or not JIT must expand the intrinsic.
2163 virtual CorInfoIntrinsics getIntrinsicID(
2164 CORINFO_METHOD_HANDLE method,
2165 bool* pMustExpand = NULL /* OUT */
2168 // Is the given module the System.Numerics.Vectors module?
2169 // This defaults to false.
2170 virtual bool isInSIMDModule(
2171 CORINFO_CLASS_HANDLE classHnd
2174 // return the unmanaged calling convention for a PInvoke
2175 virtual CorInfoUnmanagedCallConv getUnmanagedCallConv(
2176 CORINFO_METHOD_HANDLE method
2179 // return if any marshaling is required for PInvoke methods. Note that
2180 // method == 0 => calli. The call site sig is only needed for the varargs or calli case
2181 virtual BOOL pInvokeMarshalingRequired(
2182 CORINFO_METHOD_HANDLE method,
2183 CORINFO_SIG_INFO* callSiteSig
2186 // Check constraints on method type arguments (only).
2187 // The parent class should be checked separately using satisfiesClassConstraints(parent).
2188 virtual BOOL satisfiesMethodConstraints(
2189 CORINFO_CLASS_HANDLE parent, // the exact parent of the method
2190 CORINFO_METHOD_HANDLE method
2193 // Given a delegate target class, a target method parent class, a target method,
2194 // a delegate class, check if the method signature is compatible with the Invoke method of the delegate
2195 // (under the typical instantiation of any free type variables in the memberref signatures).
2196 virtual BOOL isCompatibleDelegate(
2197 CORINFO_CLASS_HANDLE objCls, /* type of the delegate target, if any */
2198 CORINFO_CLASS_HANDLE methodParentCls, /* exact parent of the target method, if any */
2199 CORINFO_METHOD_HANDLE method, /* (representative) target method, if any */
2200 CORINFO_CLASS_HANDLE delegateCls, /* exact type of the delegate */
2201 BOOL *pfIsOpenDelegate /* is the delegate open */
2204 // Indicates if the method is an instance of the generic
2205 // method that passes (or has passed) verification
2206 virtual CorInfoInstantiationVerification isInstantiationOfVerifiedGeneric (
2207 CORINFO_METHOD_HANDLE method /* IN */
2210 // Loads the constraints on a typical method definition, detecting cycles;
2211 // for use in verification.
2212 virtual void initConstraintsForVerification(
2213 CORINFO_METHOD_HANDLE method, /* IN */
2214 BOOL *pfHasCircularClassConstraints, /* OUT */
2215 BOOL *pfHasCircularMethodConstraint /* OUT */
2218 // Returns enum whether the method does not require verification
2219 // Also see ICorModuleInfo::canSkipVerification
2220 virtual CorInfoCanSkipVerificationResult canSkipMethodVerification (
2221 CORINFO_METHOD_HANDLE ftnHandle
2224 // load and restore the method
2225 virtual void methodMustBeLoadedBeforeCodeIsRun(
2226 CORINFO_METHOD_HANDLE method
2229 virtual CORINFO_METHOD_HANDLE mapMethodDeclToMethodImpl(
2230 CORINFO_METHOD_HANDLE method
2233 // Returns the global cookie for the /GS unsafe buffer checks
2234 // The cookie might be a constant value (JIT), or a handle to memory location (Ngen)
2235 virtual void getGSCookie(
2236 GSCookie * pCookieVal, // OUT
2237 GSCookie ** ppCookieVal // OUT
2240 /**********************************************************************************/
2244 /**********************************************************************************/
2246 // Resolve metadata token into runtime method handles. This function may not
2247 // return normally (e.g. it may throw) if it encounters invalid metadata or other
2248 // failures during token resolution.
2249 virtual void resolveToken(/* IN, OUT */ CORINFO_RESOLVED_TOKEN * pResolvedToken) = 0;
2251 // Attempt to resolve a metadata token into a runtime method handle. Returns true
2252 // if resolution succeeded and false otherwise (e.g. if it encounters invalid metadata
2253 // during token reoslution). This method should be used instead of `resolveToken` in
2254 // situations that need to be resilient to invalid metadata.
2255 virtual bool tryResolveToken(/* IN, OUT */ CORINFO_RESOLVED_TOKEN * pResolvedToken) = 0;
2257 // Signature information about the call sig
2258 virtual void findSig (
2259 CORINFO_MODULE_HANDLE module, /* IN */
2260 unsigned sigTOK, /* IN */
2261 CORINFO_CONTEXT_HANDLE context, /* IN */
2262 CORINFO_SIG_INFO *sig /* OUT */
2265 // for Varargs, the signature at the call site may differ from
2266 // the signature at the definition. Thus we need a way of
2267 // fetching the call site information
2268 virtual void findCallSiteSig (
2269 CORINFO_MODULE_HANDLE module, /* IN */
2270 unsigned methTOK, /* IN */
2271 CORINFO_CONTEXT_HANDLE context, /* IN */
2272 CORINFO_SIG_INFO *sig /* OUT */
2275 virtual CORINFO_CLASS_HANDLE getTokenTypeAsHandle (
2276 CORINFO_RESOLVED_TOKEN * pResolvedToken /* IN */) = 0;
2278 // Returns true if the module does not require verification
2280 // If fQuickCheckOnlyWithoutCommit=TRUE, the function only checks that the
2281 // module does not currently require verification in the current AppDomain.
2282 // This decision could change in the future, and so should not be cached.
2283 // If it is cached, it should only be used as a hint.
2284 // This is only used by ngen for calculating certain hints.
2287 // Returns enum whether the module does not require verification
2288 // Also see ICorMethodInfo::canSkipMethodVerification();
2289 virtual CorInfoCanSkipVerificationResult canSkipVerification (
2290 CORINFO_MODULE_HANDLE module /* IN */
2293 // Checks if the given metadata token is valid
2294 virtual BOOL isValidToken (
2295 CORINFO_MODULE_HANDLE module, /* IN */
2296 unsigned metaTOK /* IN */
2299 // Checks if the given metadata token is valid StringRef
2300 virtual BOOL isValidStringRef (
2301 CORINFO_MODULE_HANDLE module, /* IN */
2302 unsigned metaTOK /* IN */
2305 virtual BOOL shouldEnforceCallvirtRestriction(
2306 CORINFO_MODULE_HANDLE scope
2309 /**********************************************************************************/
2313 /**********************************************************************************/
2315 // If the value class 'cls' is isomorphic to a primitive type it will
2316 // return that type, otherwise it will return CORINFO_TYPE_VALUECLASS
2317 virtual CorInfoType asCorInfoType (
2318 CORINFO_CLASS_HANDLE cls
2322 virtual const char* getClassName (
2323 CORINFO_CLASS_HANDLE cls
2326 // Return class name as in metadata, or nullptr if there is none.
2327 // Suitable for non-debugging use.
2328 virtual const char* getClassNameFromMetadata (
2329 CORINFO_CLASS_HANDLE cls,
2330 const char **namespaceName /* OUT */
2333 // Return the type argument of the instantiated generic class,
2334 // which is specified by the index
2335 virtual CORINFO_CLASS_HANDLE getTypeInstantiationArgument(
2336 CORINFO_CLASS_HANDLE cls,
2341 // Append a (possibly truncated) representation of the type cls to the preallocated buffer ppBuf of length pnBufLen
2342 // If fNamespace=TRUE, include the namespace/enclosing classes
2343 // If fFullInst=TRUE (regardless of fNamespace and fAssembly), include namespace and assembly for any type parameters
2344 // If fAssembly=TRUE, suffix with a comma and the full assembly qualification
2345 // return size of representation
2346 virtual int appendClassName(
2347 __deref_inout_ecount(*pnBufLen) WCHAR** ppBuf,
2349 CORINFO_CLASS_HANDLE cls,
2355 // Quick check whether the type is a value class. Returns the same value as getClassAttribs(cls) & CORINFO_FLG_VALUECLASS, except faster.
2356 virtual BOOL isValueClass(CORINFO_CLASS_HANDLE cls) = 0;
2358 // Decides how the JIT should do the optimization to inline the check for
2359 // GetTypeFromHandle(handle) == obj.GetType() (for CORINFO_INLINE_TYPECHECK_SOURCE_VTABLE)
2360 // GetTypeFromHandle(X) == GetTypeFromHandle(Y) (for CORINFO_INLINE_TYPECHECK_SOURCE_TOKEN)
2361 virtual CorInfoInlineTypeCheck canInlineTypeCheck(CORINFO_CLASS_HANDLE cls, CorInfoInlineTypeCheckSource source) = 0;
2363 // If this method returns true, JIT will do optimization to inline the check for
2364 // GetTypeFromHandle(handle) == obj.GetType()
2365 virtual BOOL canInlineTypeCheckWithObjectVTable(CORINFO_CLASS_HANDLE cls) = 0;
2367 // return flags (defined above, CORINFO_FLG_PUBLIC ...)
2368 virtual DWORD getClassAttribs (
2369 CORINFO_CLASS_HANDLE cls
2372 // Returns "TRUE" iff "cls" is a struct type such that return buffers used for returning a value
2373 // of this type must be stack-allocated. This will generally be true only if the struct
2374 // contains GC pointers, and does not exceed some size limit. Maintaining this as an invariant allows
2375 // an optimization: the JIT may assume that return buffer pointers for return types for which this predicate
2376 // returns TRUE are always stack allocated, and thus, that stores to the GC-pointer fields of such return
2377 // buffers do not require GC write barriers.
2378 virtual BOOL isStructRequiringStackAllocRetBuf(CORINFO_CLASS_HANDLE cls) = 0;
2380 virtual CORINFO_MODULE_HANDLE getClassModule (
2381 CORINFO_CLASS_HANDLE cls
2384 // Returns the assembly that contains the module "mod".
2385 virtual CORINFO_ASSEMBLY_HANDLE getModuleAssembly (
2386 CORINFO_MODULE_HANDLE mod
2389 // Returns the name of the assembly "assem".
2390 virtual const char* getAssemblyName (
2391 CORINFO_ASSEMBLY_HANDLE assem
2394 // Allocate and delete process-lifetime objects. Should only be
2395 // referred to from static fields, lest a leak occur.
2396 // Note that "LongLifetimeFree" does not execute destructors, if "obj"
2397 // is an array of a struct type with a destructor.
2398 virtual void* LongLifetimeMalloc(size_t sz) = 0;
2399 virtual void LongLifetimeFree(void* obj) = 0;
2401 virtual size_t getClassModuleIdForStatics (
2402 CORINFO_CLASS_HANDLE cls,
2403 CORINFO_MODULE_HANDLE *pModule,
2404 void **ppIndirection
2407 // return the number of bytes needed by an instance of the class
2408 virtual unsigned getClassSize (
2409 CORINFO_CLASS_HANDLE cls
2412 // return the number of bytes needed by an instance of the class allocated on the heap
2413 virtual unsigned getHeapClassSize(
2414 CORINFO_CLASS_HANDLE cls
2417 virtual BOOL canAllocateOnStack(
2418 CORINFO_CLASS_HANDLE cls
2421 virtual unsigned getClassAlignmentRequirement (
2422 CORINFO_CLASS_HANDLE cls,
2423 BOOL fDoubleAlignHint = FALSE
2426 // This is only called for Value classes. It returns a boolean array
2427 // in representing of 'cls' from a GC perspective. The class is
2428 // assumed to be an array of machine words
2429 // (of length // getClassSize(cls) / TARGET_POINTER_SIZE),
2430 // 'gcPtrs' is a pointer to an array of BYTEs of this length.
2431 // getClassGClayout fills in this array so that gcPtrs[i] is set
2432 // to one of the CorInfoGCType values which is the GC type of
2433 // the i-th machine word of an object of type 'cls'
2434 // returns the number of GC pointers in the array
2435 virtual unsigned getClassGClayout (
2436 CORINFO_CLASS_HANDLE cls, /* IN */
2437 BYTE *gcPtrs /* OUT */
2440 // returns the number of instance fields in a class
2441 virtual unsigned getClassNumInstanceFields (
2442 CORINFO_CLASS_HANDLE cls /* IN */
2445 virtual CORINFO_FIELD_HANDLE getFieldInClass(
2446 CORINFO_CLASS_HANDLE clsHnd,
2450 virtual BOOL checkMethodModifier(
2451 CORINFO_METHOD_HANDLE hMethod,
2456 // returns the "NEW" helper optimized for "newCls."
2457 virtual CorInfoHelpFunc getNewHelper(
2458 CORINFO_RESOLVED_TOKEN * pResolvedToken,
2459 CORINFO_METHOD_HANDLE callerHandle,
2460 bool * pHasSideEffects = NULL /* OUT */
2463 // returns the newArr (1-Dim array) helper optimized for "arrayCls."
2464 virtual CorInfoHelpFunc getNewArrHelper(
2465 CORINFO_CLASS_HANDLE arrayCls
2468 // returns the optimized "IsInstanceOf" or "ChkCast" helper
2469 virtual CorInfoHelpFunc getCastingHelper(
2470 CORINFO_RESOLVED_TOKEN * pResolvedToken,
2474 // returns helper to trigger static constructor
2475 virtual CorInfoHelpFunc getSharedCCtorHelper(
2476 CORINFO_CLASS_HANDLE clsHnd
2479 virtual CorInfoHelpFunc getSecurityPrologHelper(
2480 CORINFO_METHOD_HANDLE ftn
2483 // This is not pretty. Boxing nullable<T> actually returns
2484 // a boxed<T> not a boxed Nullable<T>. This call allows the verifier
2485 // to call back to the EE on the 'box' instruction and get the transformed
2486 // type to use for verification.
2487 virtual CORINFO_CLASS_HANDLE getTypeForBox(
2488 CORINFO_CLASS_HANDLE cls
2491 // returns the correct box helper for a particular class. Note
2492 // that if this returns CORINFO_HELP_BOX, the JIT can assume
2493 // 'standard' boxing (allocate object and copy), and optimize
2494 virtual CorInfoHelpFunc getBoxHelper(
2495 CORINFO_CLASS_HANDLE cls
2498 // returns the unbox helper. If 'helperCopies' points to a true
2499 // value it means the JIT is requesting a helper that unboxes the
2500 // value into a particular location and thus has the signature
2501 // void unboxHelper(void* dest, CORINFO_CLASS_HANDLE cls, Object* obj)
2502 // Otherwise (it is null or points at a FALSE value) it is requesting
2503 // a helper that returns a pointer to the unboxed data
2504 // void* unboxHelper(CORINFO_CLASS_HANDLE cls, Object* obj)
2505 // The EE has the option of NOT returning the copy style helper
2506 // (But must be able to always honor the non-copy style helper)
2507 // The EE set 'helperCopies' on return to indicate what kind of
2508 // helper has been created.
2510 virtual CorInfoHelpFunc getUnBoxHelper(
2511 CORINFO_CLASS_HANDLE cls
2514 virtual bool getReadyToRunHelper(
2515 CORINFO_RESOLVED_TOKEN * pResolvedToken,
2516 CORINFO_LOOKUP_KIND * pGenericLookupKind,
2518 CORINFO_CONST_LOOKUP * pLookup
2521 virtual void getReadyToRunDelegateCtorHelper(
2522 CORINFO_RESOLVED_TOKEN * pTargetMethod,
2523 CORINFO_CLASS_HANDLE delegateType,
2524 CORINFO_LOOKUP * pLookup
2527 virtual const char* getHelperName(
2531 // This function tries to initialize the class (run the class constructor).
2532 // this function returns whether the JIT must insert helper calls before
2533 // accessing static field or method.
2535 // See code:ICorClassInfo#ClassConstruction.
2536 virtual CorInfoInitClassResult initClass(
2537 CORINFO_FIELD_HANDLE field, // Non-NULL - inquire about cctor trigger before static field access
2538 // NULL - inquire about cctor trigger in method prolog
2539 CORINFO_METHOD_HANDLE method, // Method referencing the field or prolog
2540 CORINFO_CONTEXT_HANDLE context, // Exact context of method
2541 BOOL speculative = FALSE // TRUE means don't actually run it
2544 // This used to be called "loadClass". This records the fact
2545 // that the class must be loaded (including restored if necessary) before we execute the
2546 // code that we are currently generating. When jitting code
2547 // the function loads the class immediately. When zapping code
2548 // the zapper will if necessary use the call to record the fact that we have
2549 // to do a fixup/restore before running the method currently being generated.
2551 // This is typically used to ensure value types are loaded before zapped
2552 // code that manipulates them is executed, so that the GC can access information
2553 // about those value types.
2554 virtual void classMustBeLoadedBeforeCodeIsRun(
2555 CORINFO_CLASS_HANDLE cls
2558 // returns the class handle for the special builtin classes
2559 virtual CORINFO_CLASS_HANDLE getBuiltinClass (
2560 CorInfoClassId classId
2563 // "System.Int32" ==> CORINFO_TYPE_INT..
2564 virtual CorInfoType getTypeForPrimitiveValueClass(
2565 CORINFO_CLASS_HANDLE cls
2568 // "System.Int32" ==> CORINFO_TYPE_INT..
2569 // "System.UInt32" ==> CORINFO_TYPE_UINT..
2570 virtual CorInfoType getTypeForPrimitiveNumericClass(
2571 CORINFO_CLASS_HANDLE cls
2574 // TRUE if child is a subtype of parent
2575 // if parent is an interface, then does child implement / extend parent
2576 virtual BOOL canCast(
2577 CORINFO_CLASS_HANDLE child, // subtype (extends parent)
2578 CORINFO_CLASS_HANDLE parent // base type
2581 // TRUE if cls1 and cls2 are considered equivalent types.
2582 virtual BOOL areTypesEquivalent(
2583 CORINFO_CLASS_HANDLE cls1,
2584 CORINFO_CLASS_HANDLE cls2
2587 // See if a cast from fromClass to toClass will succeed, fail, or needs
2588 // to be resolved at runtime.
2589 virtual TypeCompareState compareTypesForCast(
2590 CORINFO_CLASS_HANDLE fromClass,
2591 CORINFO_CLASS_HANDLE toClass
2594 // See if types represented by cls1 and cls2 compare equal, not
2595 // equal, or the comparison needs to be resolved at runtime.
2596 virtual TypeCompareState compareTypesForEquality(
2597 CORINFO_CLASS_HANDLE cls1,
2598 CORINFO_CLASS_HANDLE cls2
2601 // Returns the intersection of cls1 and cls2.
2602 virtual CORINFO_CLASS_HANDLE mergeClasses(
2603 CORINFO_CLASS_HANDLE cls1,
2604 CORINFO_CLASS_HANDLE cls2
2607 // Returns true if cls2 is known to be a more specific type
2608 // than cls1 (a subtype or more restrictive shared type)
2609 // for purposes of jit type tracking. This is a hint to the
2610 // jit for optimization; it does not have correctness
2612 virtual BOOL isMoreSpecificType(
2613 CORINFO_CLASS_HANDLE cls1,
2614 CORINFO_CLASS_HANDLE cls2
2617 // Given a class handle, returns the Parent type.
2618 // For COMObjectType, it returns Class Handle of System.Object.
2619 // Returns 0 if System.Object is passed in.
2620 virtual CORINFO_CLASS_HANDLE getParentType (
2621 CORINFO_CLASS_HANDLE cls
2624 // Returns the CorInfoType of the "child type". If the child type is
2625 // not a primitive type, *clsRet will be set.
2626 // Given an Array of Type Foo, returns Foo.
2627 // Given BYREF Foo, returns Foo
2628 virtual CorInfoType getChildType (
2629 CORINFO_CLASS_HANDLE clsHnd,
2630 CORINFO_CLASS_HANDLE *clsRet
2633 // Check constraints on type arguments of this class and parent classes
2634 virtual BOOL satisfiesClassConstraints(
2635 CORINFO_CLASS_HANDLE cls
2638 // Check if this is a single dimensional array type
2639 virtual BOOL isSDArray(
2640 CORINFO_CLASS_HANDLE cls
2643 // Get the numbmer of dimensions in an array
2644 virtual unsigned getArrayRank(
2645 CORINFO_CLASS_HANDLE cls
2648 // Get static field data for an array
2649 virtual void * getArrayInitializationData(
2650 CORINFO_FIELD_HANDLE field,
2654 // Check Visibility rules.
2655 virtual CorInfoIsAccessAllowedResult canAccessClass(
2656 CORINFO_RESOLVED_TOKEN * pResolvedToken,
2657 CORINFO_METHOD_HANDLE callerHandle,
2658 CORINFO_HELPER_DESC *pAccessHelper /* If canAccessMethod returns something other
2659 than ALLOWED, then this is filled in. */
2662 /**********************************************************************************/
2666 /**********************************************************************************/
2668 // this function is for debugging only. It returns the field name
2669 // and if 'moduleName' is non-null, it sets it to something that will
2670 // says which method (a class name, or a module name)
2671 virtual const char* getFieldName (
2672 CORINFO_FIELD_HANDLE ftn, /* IN */
2673 const char **moduleName /* OUT */
2676 // return class it belongs to
2677 virtual CORINFO_CLASS_HANDLE getFieldClass (
2678 CORINFO_FIELD_HANDLE field
2681 // Return the field's type, if it is CORINFO_TYPE_VALUECLASS 'structType' is set
2682 // the field's value class (if 'structType' == 0, then don't bother
2683 // the structure info).
2685 // 'memberParent' is typically only set when verifying. It should be the
2686 // result of calling getMemberParent.
2687 virtual CorInfoType getFieldType(
2688 CORINFO_FIELD_HANDLE field,
2689 CORINFO_CLASS_HANDLE *structType = NULL,
2690 CORINFO_CLASS_HANDLE memberParent = NULL /* IN */
2693 // return the data member's instance offset
2694 virtual unsigned getFieldOffset(
2695 CORINFO_FIELD_HANDLE field
2698 // TODO: jit64 should be switched to the same plan as the i386 jits - use
2699 // getClassGClayout to figure out the need for writebarrier helper, and inline the copying.
2700 // The interpretted value class copy is slow. Once this happens, USE_WRITE_BARRIER_HELPERS
2701 virtual bool isWriteBarrierHelperRequired(
2702 CORINFO_FIELD_HANDLE field) = 0;
2704 virtual void getFieldInfo (CORINFO_RESOLVED_TOKEN * pResolvedToken,
2705 CORINFO_METHOD_HANDLE callerHandle,
2706 CORINFO_ACCESS_FLAGS flags,
2707 CORINFO_FIELD_INFO *pResult
2710 // Returns true iff "fldHnd" represents a static field.
2711 virtual bool isFieldStatic(CORINFO_FIELD_HANDLE fldHnd) = 0;
2713 /*********************************************************************************/
2717 /*********************************************************************************/
2719 // Query the EE to find out where interesting break points
2720 // in the code are. The native compiler will ensure that these places
2721 // have a corresponding break point in native code.
2723 // Note that unless CORJIT_FLAG_DEBUG_CODE is specified, this function will
2724 // be used only as a hint and the native compiler should not change its
2726 virtual void getBoundaries(
2727 CORINFO_METHOD_HANDLE ftn, // [IN] method of interest
2728 unsigned int *cILOffsets, // [OUT] size of pILOffsets
2729 DWORD **pILOffsets, // [OUT] IL offsets of interest
2730 // jit MUST free with freeArray!
2731 ICorDebugInfo::BoundaryTypes *implictBoundaries // [OUT] tell jit, all boundries of this type
2734 // Report back the mapping from IL to native code,
2735 // this map should include all boundaries that 'getBoundaries'
2736 // reported as interesting to the debugger.
2738 // Note that debugger (and profiler) is assuming that all of the
2739 // offsets form a contiguous block of memory, and that the
2740 // OffsetMapping is sorted in order of increasing native offset.
2741 virtual void setBoundaries(
2742 CORINFO_METHOD_HANDLE ftn, // [IN] method of interest
2743 ULONG32 cMap, // [IN] size of pMap
2744 ICorDebugInfo::OffsetMapping *pMap // [IN] map including all points of interest.
2745 // jit allocated with allocateArray, EE frees
2748 // Query the EE to find out the scope of local varables.
2749 // normally the JIT would trash variables after last use, but
2750 // under debugging, the JIT needs to keep them live over their
2751 // entire scope so that they can be inspected.
2753 // Note that unless CORJIT_FLAG_DEBUG_CODE is specified, this function will
2754 // be used only as a hint and the native compiler should not change its
2756 virtual void getVars(
2757 CORINFO_METHOD_HANDLE ftn, // [IN] method of interest
2758 ULONG32 *cVars, // [OUT] size of 'vars'
2759 ICorDebugInfo::ILVarInfo **vars, // [OUT] scopes of variables of interest
2760 // jit MUST free with freeArray!
2761 bool *extendOthers // [OUT] it TRUE, then assume the scope
2762 // of unmentioned vars is entire method
2765 // Report back to the EE the location of every variable.
2766 // note that the JIT might split lifetimes into different
2769 virtual void setVars(
2770 CORINFO_METHOD_HANDLE ftn, // [IN] method of interest
2771 ULONG32 cVars, // [IN] size of 'vars'
2772 ICorDebugInfo::NativeVarInfo *vars // [IN] map telling where local vars are stored at what points
2773 // jit allocated with allocateArray, EE frees
2776 /*-------------------------- Misc ---------------------------------------*/
2778 // Used to allocate memory that needs to handed to the EE.
2779 // For eg, use this to allocated memory for reporting debug info,
2780 // which will be handed to the EE by setVars() and setBoundaries()
2781 virtual void * allocateArray(
2785 // JitCompiler will free arrays passed by the EE using this
2786 // For eg, The EE returns memory in getVars() and getBoundaries()
2787 // to the JitCompiler, which the JitCompiler should release using
2789 virtual void freeArray(
2793 /*********************************************************************************/
2797 /*********************************************************************************/
2799 // advance the pointer to the argument list.
2800 // a ptr of 0, is special and always means the first argument
2801 virtual CORINFO_ARG_LIST_HANDLE getArgNext (
2802 CORINFO_ARG_LIST_HANDLE args /* IN */
2805 // Get the type of a particular argument
2806 // CORINFO_TYPE_UNDEF is returned when there are no more arguments
2807 // If the type returned is a primitive type (or an enum) *vcTypeRet set to NULL
2808 // otherwise it is set to the TypeHandle associted with the type
2809 // Enumerations will always look their underlying type (probably should fix this)
2810 // Otherwise vcTypeRet is the type as would be seen by the IL,
2811 // The return value is the type that is used for calling convention purposes
2812 // (Thus if the EE wants a value class to be passed like an int, then it will
2813 // return CORINFO_TYPE_INT
2814 virtual CorInfoTypeWithMod getArgType (
2815 CORINFO_SIG_INFO* sig, /* IN */
2816 CORINFO_ARG_LIST_HANDLE args, /* IN */
2817 CORINFO_CLASS_HANDLE *vcTypeRet /* OUT */
2820 // If the Arg is a CORINFO_TYPE_CLASS fetch the class handle associated with it
2821 virtual CORINFO_CLASS_HANDLE getArgClass (
2822 CORINFO_SIG_INFO* sig, /* IN */
2823 CORINFO_ARG_LIST_HANDLE args /* IN */
2826 // Returns type of HFA for valuetype
2827 virtual CorInfoType getHFAType (
2828 CORINFO_CLASS_HANDLE hClass
2831 /*****************************************************************************
2832 * ICorErrorInfo contains methods to deal with SEH exceptions being thrown
2833 * from the corinfo interface. These methods may be called when an exception
2834 * with code EXCEPTION_COMPLUS is caught.
2835 *****************************************************************************/
2837 // Returns the HRESULT of the current exception
2838 virtual HRESULT GetErrorHRESULT(
2839 struct _EXCEPTION_POINTERS *pExceptionPointers
2842 // Fetches the message of the current exception
2843 // Returns the size of the message (including terminating null). This can be
2844 // greater than bufferLength if the buffer is insufficient.
2845 virtual ULONG GetErrorMessage(
2846 __inout_ecount(bufferLength) LPWSTR buffer,
2850 // returns EXCEPTION_EXECUTE_HANDLER if it is OK for the compile to handle the
2851 // exception, abort some work (like the inlining) and continue compilation
2852 // returns EXCEPTION_CONTINUE_SEARCH if exception must always be handled by the EE
2853 // things like ThreadStoppedException ...
2854 // returns EXCEPTION_CONTINUE_EXECUTION if exception is fixed up by the EE
2856 virtual int FilterException(
2857 struct _EXCEPTION_POINTERS *pExceptionPointers
2860 // Cleans up internal EE tracking when an exception is caught.
2861 virtual void HandleException(
2862 struct _EXCEPTION_POINTERS *pExceptionPointers
2865 virtual void ThrowExceptionForJitResult(
2866 HRESULT result) = 0;
2868 //Throws an exception defined by the given throw helper.
2869 virtual void ThrowExceptionForHelper(
2870 const CORINFO_HELPER_DESC * throwHelper) = 0;
2872 // Runs the given function under an error trap. This allows the JIT to make calls
2873 // to interface functions that may throw exceptions without needing to be aware of
2874 // the EH ABI, exception types, etc. Returns true if the given function completed
2875 // successfully and false otherwise.
2876 virtual bool runWithErrorTrap(
2877 void (*function)(void*), // The function to run
2878 void* parameter // The context parameter that will be passed to the function and the handler
2881 /*****************************************************************************
2882 * ICorStaticInfo contains EE interface methods which return values that are
2883 * constant from invocation to invocation. Thus they may be embedded in
2884 * persisted information like statically generated code. (This is of course
2885 * assuming that all code versions are identical each time.)
2886 *****************************************************************************/
2888 // Return details about EE internal data structures
2889 virtual void getEEInfo(
2890 CORINFO_EE_INFO *pEEInfoOut
2893 // Returns name of the JIT timer log
2894 virtual LPCWSTR getJitTimeLogFilename() = 0;
2896 /*********************************************************************************/
2898 // Diagnostic methods
2900 /*********************************************************************************/
2902 // this function is for debugging only. Returns method token.
2903 // Returns mdMethodDefNil for dynamic methods.
2904 virtual mdMethodDef getMethodDefFromMethod(
2905 CORINFO_METHOD_HANDLE hMethod
2908 // this function is for debugging only. It returns the method name
2909 // and if 'moduleName' is non-null, it sets it to something that will
2910 // says which method (a class name, or a module name)
2911 virtual const char* getMethodName (
2912 CORINFO_METHOD_HANDLE ftn, /* IN */
2913 const char **moduleName /* OUT */
2916 // Return method name as in metadata, or nullptr if there is none,
2917 // and optionally return the class, enclosing class, and namespace names
2919 // Suitable for non-debugging use.
2920 virtual const char* getMethodNameFromMetadata(
2921 CORINFO_METHOD_HANDLE ftn, /* IN */
2922 const char **className, /* OUT */
2923 const char **namespaceName, /* OUT */
2924 const char **enclosingClassName /* OUT */
2927 // this function is for debugging only. It returns a value that
2928 // is will always be the same for a given method. It is used
2929 // to implement the 'jitRange' functionality
2930 virtual unsigned getMethodHash (
2931 CORINFO_METHOD_HANDLE ftn /* IN */
2934 // this function is for debugging only.
2935 virtual size_t findNameOfToken (
2936 CORINFO_MODULE_HANDLE module, /* IN */
2937 mdToken metaTOK, /* IN */
2938 __out_ecount (FQNameCapacity) char * szFQName, /* OUT */
2939 size_t FQNameCapacity /* IN */
2942 // returns whether the struct is enregisterable. Only valid on a System V VM. Returns true on success, false on failure.
2943 virtual bool getSystemVAmd64PassStructInRegisterDescriptor(
2944 /* IN */ CORINFO_CLASS_HANDLE structHnd,
2945 /* OUT */ SYSTEMV_AMD64_CORINFO_STRUCT_REG_PASSING_DESCRIPTOR* structPassInRegDescPtr
2950 /*****************************************************************************
2951 * ICorDynamicInfo contains EE interface methods which return values that may
2952 * change from invocation to invocation. They cannot be embedded in persisted
2953 * data; they must be requeried each time the EE is run.
2954 *****************************************************************************/
2956 class ICorDynamicInfo : public ICorStaticInfo
2961 // These methods return values to the JIT which are not constant
2962 // from session to session.
2964 // These methods take an extra parameter : void **ppIndirection.
2965 // If a JIT supports generation of prejit code (install-o-jit), it
2966 // must pass a non-null value for this parameter, and check the
2967 // resulting value. If *ppIndirection is NULL, code should be
2968 // generated normally. If non-null, then the value of
2969 // *ppIndirection is an address in the cookie table, and the code
2970 // generator needs to generate an indirection through the table to
2971 // get the resulting value. In this case, the return result of the
2972 // function must NOT be directly embedded in the generated code.
2974 // Note that if a JIT does not support prejit code generation, it
2975 // may ignore the extra parameter & pass the default of NULL - the
2976 // prejit ICorDynamicInfo implementation will see this & generate
2977 // an error if the jitter is used in a prejit scenario.
2980 // Return details about EE internal data structures
2982 virtual DWORD getThreadTLSIndex(
2983 void **ppIndirection = NULL
2986 virtual const void * getInlinedCallFrameVptr(
2987 void **ppIndirection = NULL
2990 virtual LONG * getAddrOfCaptureThreadGlobal(
2991 void **ppIndirection = NULL
2994 // return the native entry point to an EE helper (see CorInfoHelpFunc)
2995 virtual void* getHelperFtn (
2996 CorInfoHelpFunc ftnNum,
2997 void **ppIndirection = NULL
3000 // return a callable address of the function (native code). This function
3001 // may return a different value (depending on whether the method has
3002 // been JITed or not.
3003 virtual void getFunctionEntryPoint(
3004 CORINFO_METHOD_HANDLE ftn, /* IN */
3005 CORINFO_CONST_LOOKUP * pResult, /* OUT */
3006 CORINFO_ACCESS_FLAGS accessFlags = CORINFO_ACCESS_ANY) = 0;
3008 // return a directly callable address. This can be used similarly to the
3009 // value returned by getFunctionEntryPoint() except that it is
3010 // guaranteed to be multi callable entrypoint.
3011 virtual void getFunctionFixedEntryPoint(
3012 CORINFO_METHOD_HANDLE ftn,
3013 CORINFO_CONST_LOOKUP * pResult) = 0;
3015 // get the synchronization handle that is passed to monXstatic function
3016 virtual void* getMethodSync(
3017 CORINFO_METHOD_HANDLE ftn,
3018 void **ppIndirection = NULL
3021 // get slow lazy string literal helper to use (CORINFO_HELP_STRCNS*).
3022 // Returns CORINFO_HELP_UNDEF if lazy string literal helper cannot be used.
3023 virtual CorInfoHelpFunc getLazyStringLiteralHelper(
3024 CORINFO_MODULE_HANDLE handle
3027 virtual CORINFO_MODULE_HANDLE embedModuleHandle(
3028 CORINFO_MODULE_HANDLE handle,
3029 void **ppIndirection = NULL
3032 virtual CORINFO_CLASS_HANDLE embedClassHandle(
3033 CORINFO_CLASS_HANDLE handle,
3034 void **ppIndirection = NULL
3037 virtual CORINFO_METHOD_HANDLE embedMethodHandle(
3038 CORINFO_METHOD_HANDLE handle,
3039 void **ppIndirection = NULL
3042 virtual CORINFO_FIELD_HANDLE embedFieldHandle(
3043 CORINFO_FIELD_HANDLE handle,
3044 void **ppIndirection = NULL
3047 // Given a module scope (module), a method handle (context) and
3048 // a metadata token (metaTOK), fetch the handle
3049 // (type, field or method) associated with the token.
3050 // If this is not possible at compile-time (because the current method's
3051 // code is shared and the token contains generic parameters)
3052 // then indicate how the handle should be looked up at run-time.
3054 virtual void embedGenericHandle(
3055 CORINFO_RESOLVED_TOKEN * pResolvedToken,
3056 BOOL fEmbedParent, // TRUE - embeds parent type handle of the field/method handle
3057 CORINFO_GENERICHANDLE_RESULT * pResult) = 0;
3059 // Return information used to locate the exact enclosing type of the current method.
3060 // Used only to invoke .cctor method from code shared across generic instantiations
3061 // !needsRuntimeLookup statically known (enclosing type of method itself)
3062 // needsRuntimeLookup:
3063 // CORINFO_LOOKUP_THISOBJ use vtable pointer of 'this' param
3064 // CORINFO_LOOKUP_CLASSPARAM use vtable hidden param
3065 // CORINFO_LOOKUP_METHODPARAM use enclosing type of method-desc hidden param
3066 virtual CORINFO_LOOKUP_KIND getLocationOfThisType(
3067 CORINFO_METHOD_HANDLE context
3070 // NOTE: the two methods below--getPInvokeUnmanagedTarget and getAddressOfPInvokeFixup--are
3071 // deprecated. New code should instead use getAddressOfPInvokeTarget, which subsumes the
3072 // functionality of these methods.
3074 // return the unmanaged target *if method has already been prelinked.*
3075 virtual void* getPInvokeUnmanagedTarget(
3076 CORINFO_METHOD_HANDLE method,
3077 void **ppIndirection = NULL
3080 // return address of fixup area for late-bound PInvoke calls.
3081 virtual void* getAddressOfPInvokeFixup(
3082 CORINFO_METHOD_HANDLE method,
3083 void **ppIndirection = NULL
3086 // return the address of the PInvoke target. May be a fixup area in the
3087 // case of late-bound PInvoke calls.
3088 virtual void getAddressOfPInvokeTarget(
3089 CORINFO_METHOD_HANDLE method,
3090 CORINFO_CONST_LOOKUP *pLookup
3093 // Generate a cookie based on the signature that would needs to be passed
3094 // to CORINFO_HELP_PINVOKE_CALLI
3095 virtual LPVOID GetCookieForPInvokeCalliSig(
3096 CORINFO_SIG_INFO* szMetaSig,
3097 void ** ppIndirection = NULL
3100 // returns true if a VM cookie can be generated for it (might be false due to cross-module
3101 // inlining, in which case the inlining should be aborted)
3102 virtual bool canGetCookieForPInvokeCalliSig(
3103 CORINFO_SIG_INFO* szMetaSig
3106 // Gets a handle that is checked to see if the current method is
3107 // included in "JustMyCode"
3108 virtual CORINFO_JUST_MY_CODE_HANDLE getJustMyCodeHandle(
3109 CORINFO_METHOD_HANDLE method,
3110 CORINFO_JUST_MY_CODE_HANDLE**ppIndirection = NULL
3113 // Gets a method handle that can be used to correlate profiling data.
3114 // This is the IP of a native method, or the address of the descriptor struct
3115 // for IL. Always guaranteed to be unique per process, and not to move. */
3116 virtual void GetProfilingHandle(
3117 BOOL *pbHookFunction,
3118 void **pProfilerHandle,
3119 BOOL *pbIndirectedHandles
3122 // Returns instructions on how to make the call. See code:CORINFO_CALL_INFO for possible return values.
3123 virtual void getCallInfo(
3125 CORINFO_RESOLVED_TOKEN * pResolvedToken,
3128 CORINFO_RESOLVED_TOKEN * pConstrainedResolvedToken,
3131 CORINFO_METHOD_HANDLE callerHandle,
3134 CORINFO_CALLINFO_FLAGS flags,
3137 CORINFO_CALL_INFO *pResult
3140 virtual BOOL canAccessFamily(CORINFO_METHOD_HANDLE hCaller,
3141 CORINFO_CLASS_HANDLE hInstanceType) = 0;
3143 // Returns TRUE if the Class Domain ID is the RID of the class (currently true for every class
3144 // except reflection emitted classes and generics)
3145 virtual BOOL isRIDClassDomainID(CORINFO_CLASS_HANDLE cls) = 0;
3147 // returns the class's domain ID for accessing shared statics
3148 virtual unsigned getClassDomainID (
3149 CORINFO_CLASS_HANDLE cls,
3150 void **ppIndirection = NULL
3154 // return the data's address (for static fields only)
3155 virtual void* getFieldAddress(
3156 CORINFO_FIELD_HANDLE field,
3157 void **ppIndirection = NULL
3160 // If pIsSpeculative is NULL, return the class handle for the value of ref-class typed
3161 // static readonly fields, if there is a unique location for the static and the class
3162 // is already initialized.
3164 // If pIsSpeculative is not NULL, fetch the class handle for the value of all ref-class
3165 // typed static fields, if there is a unique location for the static and the field is
3168 // Set *pIsSpeculative true if this type may change over time (field is not readonly or
3169 // is readonly but class has not yet finished initialization). Set *pIsSpeculative false
3170 // if this type will not change.
3171 virtual CORINFO_CLASS_HANDLE getStaticFieldCurrentClass(
3172 CORINFO_FIELD_HANDLE field,
3173 bool *pIsSpeculative = NULL
3176 // registers a vararg sig & returns a VM cookie for it (which can contain other stuff)
3177 virtual CORINFO_VARARGS_HANDLE getVarArgsHandle(
3178 CORINFO_SIG_INFO *pSig,
3179 void **ppIndirection = NULL
3182 // returns true if a VM cookie can be generated for it (might be false due to cross-module
3183 // inlining, in which case the inlining should be aborted)
3184 virtual bool canGetVarArgsHandle(
3185 CORINFO_SIG_INFO *pSig
3188 // Allocate a string literal on the heap and return a handle to it
3189 virtual InfoAccessType constructStringLiteral(
3190 CORINFO_MODULE_HANDLE module,
3195 virtual InfoAccessType emptyStringLiteral(
3199 // (static fields only) given that 'field' refers to thread local store,
3200 // return the ID (TLS index), which is used to find the begining of the
3201 // TLS data area for the particular DLL 'field' is associated with.
3202 virtual DWORD getFieldThreadLocalStoreID (
3203 CORINFO_FIELD_HANDLE field,
3204 void **ppIndirection = NULL
3207 // Sets another object to intercept calls to "self" and current method being compiled
3208 virtual void setOverride(
3209 ICorDynamicInfo *pOverride,
3210 CORINFO_METHOD_HANDLE currentMethod
3213 // Adds an active dependency from the context method's module to the given module
3214 // This is internal callback for the EE. JIT should not call it directly.
3215 virtual void addActiveDependency(
3216 CORINFO_MODULE_HANDLE moduleFrom,
3217 CORINFO_MODULE_HANDLE moduleTo
3220 virtual CORINFO_METHOD_HANDLE GetDelegateCtor(
3221 CORINFO_METHOD_HANDLE methHnd,
3222 CORINFO_CLASS_HANDLE clsHnd,
3223 CORINFO_METHOD_HANDLE targetMethodHnd,
3224 DelegateCtorArgs * pCtorData
3227 virtual void MethodCompileComplete(
3228 CORINFO_METHOD_HANDLE methHnd
3231 // return a thunk that will copy the arguments for the given signature.
3232 virtual void* getTailCallCopyArgsThunk (
3233 CORINFO_SIG_INFO *pSig,
3234 CorInfoHelperTailCallSpecialHandling flags
3237 // Optionally, convert calli to regular method call. This is for PInvoke argument marshalling.
3238 virtual bool convertPInvokeCalliToCall(
3239 CORINFO_RESOLVED_TOKEN * pResolvedToken,
3244 /**********************************************************************************/
3246 // It would be nicer to use existing IMAGE_REL_XXX constants instead of defining our own here...
3247 #define IMAGE_REL_BASED_REL32 0x10
3248 #define IMAGE_REL_BASED_THUMB_BRANCH24 0x13
3250 // The identifier for ARM32-specific PC-relative address
3251 // computation corresponds to the following instruction
3253 // l0: movw rX, #imm_lo // 4 byte
3254 // l4: movt rX, #imm_hi // 4 byte
3255 // l8: add rX, pc <- after this instruction rX = relocTarget
3257 // Program counter at l8 is address of l8 + 4
3258 // Address of relocated movw/movt is l0
3259 // So, imm should be calculated as the following:
3260 // imm = relocTarget - (l8 + 4) = relocTarget - (l0 + 8 + 4) = relocTarget - (l_0 + 12)
3261 // So, the value of offset correction is 12
3263 #define IMAGE_REL_BASED_REL_THUMB_MOV32_PCREL 0x14
3265 #endif // _COR_INFO_H_