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.
4
5//
6
7/*****************************************************************************\
8* *
9* CorInfo.h - EE / Code generator interface *
10* *
11*******************************************************************************
12*
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*******************************************************************************
17
18//////////////////////////////////////////////////////////////////////////////////////////////////////////
19//
20// NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE
21//
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.
25//
26// NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE
27//
28//////////////////////////////////////////////////////////////////////////////////////////////////////////
29
30#EEJitContractDetails
31
32The semantic contract between the EE and the JIT should be documented here It is incomplete, but as time goes
33on, that hopefully will change
34
35See file:../../doc/BookOfTheRuntime/JIT/JIT%20Design.doc for details on the JIT compiler. See
36code:EEStartup#TableOfContents for information on the runtime as a whole.
37
38-------------------------------------------------------------------------------
39#Tokens
40
41The tokens in IL stream needs to be resolved to EE handles (CORINFO_CLASS/METHOD/FIELD_HANDLE) that
42the runtime operates with. ICorStaticInfo::resolveToken is the method that resolves the found in IL stream
43to set of EE handles (CORINFO_RESOLVED_TOKEN). All other APIs take resolved token as input. This design
44avoids redundant token resolutions.
45
46The token validation is done as part of token resolution. The JIT is not required to do explicit upfront
47token validation.
48
49-------------------------------------------------------------------------------
50#ClassConstruction
51
52First of all class contruction comes in two flavors precise and 'beforeFieldInit'. In C# you get the former
53if you declare an explicit class constructor method and the later if you declaratively initialize static
54fields. Precise class construction guarentees that the .cctor is run precisely before the first access to any
55method or field of the class. 'beforeFieldInit' semantics guarentees only that the .cctor will be run some
56time before the first static field access (note that calling methods (static or insance) or accessing
57instance fields does not cause .cctors to be run).
58
59Next you need to know that there are two kinds of code generation that can happen in the JIT: appdomain
60neutral and appdomain specialized. The difference between these two kinds of code is how statics are handled.
61For appdomain specific code, the address of a particular static variable is embeded in the code. This makes
62it usable only for one appdomain (since every appdomain gets a own copy of its statics). Appdomain neutral
63code calls a helper that looks up static variables off of a thread local variable. Thus the same code can be
64used by mulitple appdomains in the same process.
65
66Generics also introduce a similar issue. Code for generic classes might be specialised for a particular set
67of type arguments, or it could use helpers to access data that depends on type parameters and thus be shared
68across several instantiations of the generic type.
69
70Thus there four cases
71
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
74 .cctor is called.
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.
87
88Technically speaking, however the optimization of avoiding checks on instance methods is flawed. It requires
89that a .ctor always preceed a call to an instance methods. This break down when
90
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)
96
97Nevertheless, the cost of plugging these holes is considered to high and the benefit is low.
98
99----------------------------------------------------------------------
100
101#ClassConstructionFlags
102
103Thus the JIT's cctor responsibilities require it to check with the EE on every static field access using
104initClass and before jitting any method to see if a .cctor check must be placed in the prolog.
105
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.
110
111Inlining also complicates things. Because the class could have precise semantics it is also required that the
112inlining of any constructor or static method must also do the initClass check. The inliner has the option of
113inserting any required runtime check or simply not inlining the function.
114
115-------------------------------------------------------------------------------
116
117#StaticFields
118
119The first 4 options are mutially exclusive
120
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.
126
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).
133
134
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).
140
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
144
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).
147
148
149This last field can modify any of the cases above except CORINFO_FLG_HELPER
150
151CORINFO_FLG_STATIC_IN_HEAP This is currently only used for static fields of value classes. If the field has
152this 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
154by addr = (*addr+sizeof(OBJECTREF))
155
156Instance fields
157
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
162
163 * CORINFO_HELP_GETFIELDSTRUCT - args are: retBuff, object, fieldDesc
164 * CORINFO_HELP_SETFIELDSTRUCT - args are object fieldDesc value
165
166The other GET helpers take an object fieldDesc and return the value The other SET helpers take an object
167fieldDesc and value
168
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).
171
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.
176
177-------------------------------------------------------------------------------
178
179TODO: Talk about initializing strutures before use
180
181
182*******************************************************************************
183*/
184
185#ifndef _COR_INFO_H_
186#define _COR_INFO_H_
187
188#include <corhdr.h>
189#include <specstrings.h>
190
191//////////////////////////////////////////////////////////////////////////////////////////////////////////
192//
193// NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE
194//
195// #JITEEVersionIdentifier
196//
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().
200//
201// You can use "uuidgen.exe -s" to generate this value.
202//
203// **** NOTE TO INTEGRATORS:
204//
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!
207//
208// NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE
209//
210//////////////////////////////////////////////////////////////////////////////////////////////////////////
211
212#if !defined(SELECTANY)
213 #define SELECTANY extern __declspec(selectany)
214#endif
215
216SELECTANY const GUID JITEEVersionIdentifier = { /* 8903fe7b-a82a-4e2e-b691-f58430b485d1 */
217 0x8903fe7b,
218 0xa82a,
219 0x4e2e,
220 {0xb6, 0x91, 0xf5, 0x84, 0x30, 0xb4, 0x85, 0xd1}
221};
222
223//////////////////////////////////////////////////////////////////////////////////////////////////////////
224//
225// END JITEEVersionIdentifier
226//
227//////////////////////////////////////////////////////////////////////////////////////////////////////////
228
229// For System V on the CLR type system number of registers to pass in and return a struct is the same.
230// The CLR type system allows only up to 2 eightbytes to be passed in registers. There is no SSEUP classification types.
231#define CLR_SYSTEMV_MAX_EIGHTBYTES_COUNT_TO_PASS_IN_REGISTERS 2
232#define CLR_SYSTEMV_MAX_EIGHTBYTES_COUNT_TO_RETURN_IN_REGISTERS 2
233#define CLR_SYSTEMV_MAX_STRUCT_BYTES_TO_PASS_IN_REGISTERS 16
234
235// System V struct passing
236// The Classification types are described in the ABI spec at http://www.x86-64.org/documentation/abi.pdf
237enum SystemVClassificationType : unsigned __int8
238{
239 SystemVClassificationTypeUnknown = 0,
240 SystemVClassificationTypeStruct = 1,
241 SystemVClassificationTypeNoClass = 2,
242 SystemVClassificationTypeMemory = 3,
243 SystemVClassificationTypeInteger = 4,
244 SystemVClassificationTypeIntegerReference = 5,
245 SystemVClassificationTypeIntegerByRef = 6,
246 SystemVClassificationTypeSSE = 7,
247 // SystemVClassificationTypeSSEUp = Unused, // Not supported by the CLR.
248 // SystemVClassificationTypeX87 = Unused, // Not supported by the CLR.
249 // SystemVClassificationTypeX87Up = Unused, // Not supported by the CLR.
250 // SystemVClassificationTypeComplexX87 = Unused, // Not supported by the CLR.
251
252 // Internal flags - never returned outside of the classification implementation.
253
254 // This value represents a very special type with two eightbytes.
255 // First ByRef, second Integer (platform int).
256 // The VM has a special Elem type for this type - ELEMENT_TYPE_TYPEDBYREF.
257 // This is the classification counterpart for that element type. It is used to detect
258 // the special TypedReference type and specialize its classification.
259 // This type is represented as a struct with two fields. The classification needs to do
260 // special handling of it since the source/methadata type of the fieds is IntPtr.
261 // The VM changes the first to ByRef. The second is left as IntPtr (TYP_I_IMPL really). The classification needs to match this and
262 // special handling is warranted (similar thing is done in the getGCLayout function for this type).
263 SystemVClassificationTypeTypedReference = 8,
264 SystemVClassificationTypeMAX = 9,
265};
266
267// Represents classification information for a struct.
268struct SYSTEMV_AMD64_CORINFO_STRUCT_REG_PASSING_DESCRIPTOR
269{
270 SYSTEMV_AMD64_CORINFO_STRUCT_REG_PASSING_DESCRIPTOR()
271 {
272 Initialize();
273 }
274
275 bool passedInRegisters; // Whether the struct is passable/passed (this includes struct returning) in registers.
276 unsigned __int8 eightByteCount; // Number of eightbytes for this struct.
277 SystemVClassificationType eightByteClassifications[CLR_SYSTEMV_MAX_EIGHTBYTES_COUNT_TO_PASS_IN_REGISTERS]; // The eightbytes type classification.
278 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).
279 unsigned __int8 eightByteOffsets[CLR_SYSTEMV_MAX_EIGHTBYTES_COUNT_TO_PASS_IN_REGISTERS]; // The start offset of the eightbytes (in bytes).
280
281 // Members
282
283 //------------------------------------------------------------------------
284 // CopyFrom: Copies a struct classification into this one.
285 //
286 // Arguments:
287 // 'copyFrom' the struct classification to copy from.
288 //
289 void CopyFrom(const SYSTEMV_AMD64_CORINFO_STRUCT_REG_PASSING_DESCRIPTOR& copyFrom)
290 {
291 passedInRegisters = copyFrom.passedInRegisters;
292 eightByteCount = copyFrom.eightByteCount;
293
294 for (int i = 0; i < CLR_SYSTEMV_MAX_EIGHTBYTES_COUNT_TO_PASS_IN_REGISTERS; i++)
295 {
296 eightByteClassifications[i] = copyFrom.eightByteClassifications[i];
297 eightByteSizes[i] = copyFrom.eightByteSizes[i];
298 eightByteOffsets[i] = copyFrom.eightByteOffsets[i];
299 }
300 }
301
302 //------------------------------------------------------------------------
303 // IsIntegralSlot: Returns whether the eightbyte at slotIndex is of integral type.
304 //
305 // Arguments:
306 // 'slotIndex' the slot number we are determining if it is of integral type.
307 //
308 // Return value:
309 // returns true if we the eightbyte at index slotIndex is of integral type.
310 //
311
312 bool IsIntegralSlot(unsigned slotIndex) const
313 {
314 return ((eightByteClassifications[slotIndex] == SystemVClassificationTypeInteger) ||
315 (eightByteClassifications[slotIndex] == SystemVClassificationTypeIntegerReference) ||
316 (eightByteClassifications[slotIndex] == SystemVClassificationTypeIntegerByRef));
317 }
318
319 //------------------------------------------------------------------------
320 // IsSseSlot: Returns whether the eightbyte at slotIndex is SSE type.
321 //
322 // Arguments:
323 // 'slotIndex' the slot number we are determining if it is of SSE type.
324 //
325 // Return value:
326 // returns true if we the eightbyte at index slotIndex is of SSE type.
327 //
328 // Follows the rules of the AMD64 System V ABI specification at www.x86-64.org/documentation/abi.pdf.
329 // Please reffer to it for definitions/examples.
330 //
331 bool IsSseSlot(unsigned slotIndex) const
332 {
333 return (eightByteClassifications[slotIndex] == SystemVClassificationTypeSSE);
334 }
335
336private:
337 void Initialize()
338 {
339 passedInRegisters = false;
340 eightByteCount = 0;
341
342 for (int i = 0; i < CLR_SYSTEMV_MAX_EIGHTBYTES_COUNT_TO_PASS_IN_REGISTERS; i++)
343 {
344 eightByteClassifications[i] = SystemVClassificationTypeUnknown;
345 eightByteSizes[i] = 0;
346 eightByteOffsets[i] = 0;
347 }
348 }
349};
350
351// CorInfoHelpFunc defines the set of helpers (accessed via the ICorDynamicInfo::getHelperFtn())
352// These helpers can be called by native code which executes in the runtime.
353// Compilers can emit calls to these helpers.
354//
355// The signatures of the helpers are below (see RuntimeHelperArgumentCheck)
356
357enum CorInfoHelpFunc
358{
359 CORINFO_HELP_UNDEF, // invalid value. This should never be used
360
361 /* Arithmetic helpers */
362
363 CORINFO_HELP_DIV, // For the ARM 32-bit integer divide uses a helper call :-(
364 CORINFO_HELP_MOD,
365 CORINFO_HELP_UDIV,
366 CORINFO_HELP_UMOD,
367
368 CORINFO_HELP_LLSH,
369 CORINFO_HELP_LRSH,
370 CORINFO_HELP_LRSZ,
371 CORINFO_HELP_LMUL,
372 CORINFO_HELP_LMUL_OVF,
373 CORINFO_HELP_ULMUL_OVF,
374 CORINFO_HELP_LDIV,
375 CORINFO_HELP_LMOD,
376 CORINFO_HELP_ULDIV,
377 CORINFO_HELP_ULMOD,
378 CORINFO_HELP_LNG2DBL, // Convert a signed int64 to a double
379 CORINFO_HELP_ULNG2DBL, // Convert a unsigned int64 to a double
380 CORINFO_HELP_DBL2INT,
381 CORINFO_HELP_DBL2INT_OVF,
382 CORINFO_HELP_DBL2LNG,
383 CORINFO_HELP_DBL2LNG_OVF,
384 CORINFO_HELP_DBL2UINT,
385 CORINFO_HELP_DBL2UINT_OVF,
386 CORINFO_HELP_DBL2ULNG,
387 CORINFO_HELP_DBL2ULNG_OVF,
388 CORINFO_HELP_FLTREM,
389 CORINFO_HELP_DBLREM,
390 CORINFO_HELP_FLTROUND,
391 CORINFO_HELP_DBLROUND,
392
393 /* Allocating a new object. Always use ICorClassInfo::getNewHelper() to decide
394 which is the right helper to use to allocate an object of a given type. */
395
396 CORINFO_HELP_NEW_CROSSCONTEXT, // cross context new object
397 CORINFO_HELP_NEWFAST,
398 CORINFO_HELP_NEWSFAST, // allocator for small, non-finalizer, non-array object
399 CORINFO_HELP_NEWSFAST_FINALIZE, // allocator for small, finalizable, non-array object
400 CORINFO_HELP_NEWSFAST_ALIGN8, // allocator for small, non-finalizer, non-array object, 8 byte aligned
401 CORINFO_HELP_NEWSFAST_ALIGN8_VC,// allocator for small, value class, 8 byte aligned
402 CORINFO_HELP_NEWSFAST_ALIGN8_FINALIZE, // allocator for small, finalizable, non-array object, 8 byte aligned
403 CORINFO_HELP_NEW_MDARR, // multi-dim array helper (with or without lower bounds - dimensions passed in as vararg)
404 CORINFO_HELP_NEW_MDARR_NONVARARG,// multi-dim array helper (with or without lower bounds - dimensions passed in as unmanaged array)
405 CORINFO_HELP_NEWARR_1_DIRECT, // helper for any one dimensional array creation
406 CORINFO_HELP_NEWARR_1_R2R_DIRECT, // wrapper for R2R direct call, which extracts method table from ArrayTypeDesc
407 CORINFO_HELP_NEWARR_1_OBJ, // optimized 1-D object arrays
408 CORINFO_HELP_NEWARR_1_VC, // optimized 1-D value class arrays
409 CORINFO_HELP_NEWARR_1_ALIGN8, // like VC, but aligns the array start
410
411 CORINFO_HELP_STRCNS, // create a new string literal
412 CORINFO_HELP_STRCNS_CURRENT_MODULE, // create a new string literal from the current module (used by NGen code)
413
414 /* Object model */
415
416 CORINFO_HELP_INITCLASS, // Initialize class if not already initialized
417 CORINFO_HELP_INITINSTCLASS, // Initialize class for instantiated type
418
419 // Use ICorClassInfo::getCastingHelper to determine
420 // the right helper to use
421
422 CORINFO_HELP_ISINSTANCEOFINTERFACE, // Optimized helper for interfaces
423 CORINFO_HELP_ISINSTANCEOFARRAY, // Optimized helper for arrays
424 CORINFO_HELP_ISINSTANCEOFCLASS, // Optimized helper for classes
425 CORINFO_HELP_ISINSTANCEOFANY, // Slow helper for any type
426
427 CORINFO_HELP_CHKCASTINTERFACE,
428 CORINFO_HELP_CHKCASTARRAY,
429 CORINFO_HELP_CHKCASTCLASS,
430 CORINFO_HELP_CHKCASTANY,
431 CORINFO_HELP_CHKCASTCLASS_SPECIAL, // Optimized helper for classes. Assumes that the trivial cases
432 // has been taken care of by the inlined check
433
434 CORINFO_HELP_BOX,
435 CORINFO_HELP_BOX_NULLABLE, // special form of boxing for Nullable<T>
436 CORINFO_HELP_UNBOX,
437 CORINFO_HELP_UNBOX_NULLABLE, // special form of unboxing for Nullable<T>
438 CORINFO_HELP_GETREFANY, // Extract the byref from a TypedReference, checking that it is the expected type
439
440 CORINFO_HELP_ARRADDR_ST, // assign to element of object array with type-checking
441 CORINFO_HELP_LDELEMA_REF, // does a precise type comparision and returns address
442
443 /* Exceptions */
444
445 CORINFO_HELP_THROW, // Throw an exception object
446 CORINFO_HELP_RETHROW, // Rethrow the currently active exception
447 CORINFO_HELP_USER_BREAKPOINT, // For a user program to break to the debugger
448 CORINFO_HELP_RNGCHKFAIL, // array bounds check failed
449 CORINFO_HELP_OVERFLOW, // throw an overflow exception
450 CORINFO_HELP_THROWDIVZERO, // throw a divide by zero exception
451 CORINFO_HELP_THROWNULLREF, // throw a null reference exception
452
453 CORINFO_HELP_INTERNALTHROW, // Support for really fast jit
454 CORINFO_HELP_VERIFICATION, // Throw a VerificationException
455 CORINFO_HELP_SEC_UNMGDCODE_EXCPT, // throw a security unmanaged code exception
456 CORINFO_HELP_FAIL_FAST, // Kill the process avoiding any exceptions or stack and data dependencies (use for GuardStack unsafe buffer checks)
457
458 CORINFO_HELP_METHOD_ACCESS_EXCEPTION,//Throw an access exception due to a failed member/class access check.
459 CORINFO_HELP_FIELD_ACCESS_EXCEPTION,
460 CORINFO_HELP_CLASS_ACCESS_EXCEPTION,
461
462 CORINFO_HELP_ENDCATCH, // call back into the EE at the end of a catch block
463
464 /* Synchronization */
465
466 CORINFO_HELP_MON_ENTER,
467 CORINFO_HELP_MON_EXIT,
468 CORINFO_HELP_MON_ENTER_STATIC,
469 CORINFO_HELP_MON_EXIT_STATIC,
470
471 CORINFO_HELP_GETCLASSFROMMETHODPARAM, // Given a generics method handle, returns a class handle
472 CORINFO_HELP_GETSYNCFROMCLASSHANDLE, // Given a generics class handle, returns the sync monitor
473 // in its ManagedClassObject
474
475 /* Security callout support */
476
477 CORINFO_HELP_SECURITY_PROLOG, // Required if CORINFO_FLG_SECURITYCHECK is set, or CORINFO_FLG_NOSECURITYWRAP is not set
478 CORINFO_HELP_SECURITY_PROLOG_FRAMED, // Slow version of CORINFO_HELP_SECURITY_PROLOG. Used for instrumentation.
479
480 CORINFO_HELP_METHOD_ACCESS_CHECK, // Callouts to runtime security access checks
481 CORINFO_HELP_FIELD_ACCESS_CHECK,
482 CORINFO_HELP_CLASS_ACCESS_CHECK,
483
484 CORINFO_HELP_DELEGATE_SECURITY_CHECK, // Callout to delegate security transparency check
485
486 /* Verification runtime callout support */
487
488 CORINFO_HELP_VERIFICATION_RUNTIME_CHECK, // Do a Demand for UnmanagedCode permission at runtime
489
490 /* GC support */
491
492 CORINFO_HELP_STOP_FOR_GC, // Call GC (force a GC)
493 CORINFO_HELP_POLL_GC, // Ask GC if it wants to collect
494
495 CORINFO_HELP_STRESS_GC, // Force a GC, but then update the JITTED code to be a noop call
496 CORINFO_HELP_CHECK_OBJ, // confirm that ECX is a valid object pointer (debugging only)
497
498 /* GC Write barrier support */
499
500 CORINFO_HELP_ASSIGN_REF, // universal helpers with F_CALL_CONV calling convention
501 CORINFO_HELP_CHECKED_ASSIGN_REF,
502 CORINFO_HELP_ASSIGN_REF_ENSURE_NONHEAP, // Do the store, and ensure that the target was not in the heap.
503
504 CORINFO_HELP_ASSIGN_BYREF,
505 CORINFO_HELP_ASSIGN_STRUCT,
506
507
508 /* Accessing fields */
509
510 // For COM object support (using COM get/set routines to update object)
511 // and EnC and cross-context support
512 CORINFO_HELP_GETFIELD8,
513 CORINFO_HELP_SETFIELD8,
514 CORINFO_HELP_GETFIELD16,
515 CORINFO_HELP_SETFIELD16,
516 CORINFO_HELP_GETFIELD32,
517 CORINFO_HELP_SETFIELD32,
518 CORINFO_HELP_GETFIELD64,
519 CORINFO_HELP_SETFIELD64,
520 CORINFO_HELP_GETFIELDOBJ,
521 CORINFO_HELP_SETFIELDOBJ,
522 CORINFO_HELP_GETFIELDSTRUCT,
523 CORINFO_HELP_SETFIELDSTRUCT,
524 CORINFO_HELP_GETFIELDFLOAT,
525 CORINFO_HELP_SETFIELDFLOAT,
526 CORINFO_HELP_GETFIELDDOUBLE,
527 CORINFO_HELP_SETFIELDDOUBLE,
528
529 CORINFO_HELP_GETFIELDADDR,
530
531 CORINFO_HELP_GETSTATICFIELDADDR_CONTEXT, // Helper for context-static fields
532 CORINFO_HELP_GETSTATICFIELDADDR_TLS, // Helper for PE TLS fields
533
534 // There are a variety of specialized helpers for accessing static fields. The JIT should use
535 // ICorClassInfo::getSharedStaticsOrCCtorHelper to determine which helper to use
536
537 // Helpers for regular statics
538 CORINFO_HELP_GETGENERICS_GCSTATIC_BASE,
539 CORINFO_HELP_GETGENERICS_NONGCSTATIC_BASE,
540 CORINFO_HELP_GETSHARED_GCSTATIC_BASE,
541 CORINFO_HELP_GETSHARED_NONGCSTATIC_BASE,
542 CORINFO_HELP_GETSHARED_GCSTATIC_BASE_NOCTOR,
543 CORINFO_HELP_GETSHARED_NONGCSTATIC_BASE_NOCTOR,
544 CORINFO_HELP_GETSHARED_GCSTATIC_BASE_DYNAMICCLASS,
545 CORINFO_HELP_GETSHARED_NONGCSTATIC_BASE_DYNAMICCLASS,
546 // Helper to class initialize shared generic with dynamicclass, but not get static field address
547 CORINFO_HELP_CLASSINIT_SHARED_DYNAMICCLASS,
548
549 // Helpers for thread statics
550 CORINFO_HELP_GETGENERICS_GCTHREADSTATIC_BASE,
551 CORINFO_HELP_GETGENERICS_NONGCTHREADSTATIC_BASE,
552 CORINFO_HELP_GETSHARED_GCTHREADSTATIC_BASE,
553 CORINFO_HELP_GETSHARED_NONGCTHREADSTATIC_BASE,
554 CORINFO_HELP_GETSHARED_GCTHREADSTATIC_BASE_NOCTOR,
555 CORINFO_HELP_GETSHARED_NONGCTHREADSTATIC_BASE_NOCTOR,
556 CORINFO_HELP_GETSHARED_GCTHREADSTATIC_BASE_DYNAMICCLASS,
557 CORINFO_HELP_GETSHARED_NONGCTHREADSTATIC_BASE_DYNAMICCLASS,
558
559 /* Debugger */
560
561 CORINFO_HELP_DBG_IS_JUST_MY_CODE, // Check if this is "JustMyCode" and needs to be stepped through.
562
563 /* Profiling enter/leave probe addresses */
564 CORINFO_HELP_PROF_FCN_ENTER, // record the entry to a method (caller)
565 CORINFO_HELP_PROF_FCN_LEAVE, // record the completion of current method (caller)
566 CORINFO_HELP_PROF_FCN_TAILCALL, // record the completionof current method through tailcall (caller)
567
568 /* Miscellaneous */
569
570 CORINFO_HELP_BBT_FCN_ENTER, // record the entry to a method for collecting Tuning data
571
572 CORINFO_HELP_PINVOKE_CALLI, // Indirect pinvoke call
573 CORINFO_HELP_TAILCALL, // Perform a tail call
574
575 CORINFO_HELP_GETCURRENTMANAGEDTHREADID,
576
577 CORINFO_HELP_INIT_PINVOKE_FRAME, // initialize an inlined PInvoke Frame for the JIT-compiler
578
579 CORINFO_HELP_MEMSET, // Init block of memory
580 CORINFO_HELP_MEMCPY, // Copy block of memory
581
582 CORINFO_HELP_RUNTIMEHANDLE_METHOD, // determine a type/field/method handle at run-time
583 CORINFO_HELP_RUNTIMEHANDLE_METHOD_LOG, // determine a type/field/method handle at run-time, with IBC logging
584 CORINFO_HELP_RUNTIMEHANDLE_CLASS, // determine a type/field/method handle at run-time
585 CORINFO_HELP_RUNTIMEHANDLE_CLASS_LOG, // determine a type/field/method handle at run-time, with IBC logging
586
587 CORINFO_HELP_TYPEHANDLE_TO_RUNTIMETYPE, // Convert from a TypeHandle (native structure pointer) to RuntimeType at run-time
588 CORINFO_HELP_TYPEHANDLE_TO_RUNTIMETYPE_MAYBENULL, // Convert from a TypeHandle (native structure pointer) to RuntimeType at run-time, the type may be null
589 CORINFO_HELP_METHODDESC_TO_STUBRUNTIMEMETHOD, // Convert from a MethodDesc (native structure pointer) to RuntimeMethodHandle at run-time
590 CORINFO_HELP_FIELDDESC_TO_STUBRUNTIMEFIELD, // Convert from a FieldDesc (native structure pointer) to RuntimeFieldHandle at run-time
591 CORINFO_HELP_TYPEHANDLE_TO_RUNTIMETYPEHANDLE, // Convert from a TypeHandle (native structure pointer) to RuntimeTypeHandle at run-time
592 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
593
594 CORINFO_HELP_ARE_TYPES_EQUIVALENT, // Check whether two TypeHandles (native structure pointers) are equivalent
595
596 CORINFO_HELP_VIRTUAL_FUNC_PTR, // look up a virtual method at run-time
597 //CORINFO_HELP_VIRTUAL_FUNC_PTR_LOG, // look up a virtual method at run-time, with IBC logging
598
599 // 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.
600 CORINFO_HELP_READYTORUN_NEW,
601 CORINFO_HELP_READYTORUN_NEWARR_1,
602 CORINFO_HELP_READYTORUN_ISINSTANCEOF,
603 CORINFO_HELP_READYTORUN_CHKCAST,
604 CORINFO_HELP_READYTORUN_STATIC_BASE,
605 CORINFO_HELP_READYTORUN_VIRTUAL_FUNC_PTR,
606 CORINFO_HELP_READYTORUN_GENERIC_HANDLE,
607 CORINFO_HELP_READYTORUN_DELEGATE_CTOR,
608 CORINFO_HELP_READYTORUN_GENERIC_STATIC_BASE,
609
610 CORINFO_HELP_EE_PRESTUB, // Not real JIT helper. Used in native images.
611
612 CORINFO_HELP_EE_PRECODE_FIXUP, // Not real JIT helper. Used for Precode fixup in native images.
613 CORINFO_HELP_EE_PINVOKE_FIXUP, // Not real JIT helper. Used for PInvoke target fixup in native images.
614 CORINFO_HELP_EE_VSD_FIXUP, // Not real JIT helper. Used for VSD cell fixup in native images.
615 CORINFO_HELP_EE_EXTERNAL_FIXUP, // Not real JIT helper. Used for to fixup external method thunks in native images.
616 CORINFO_HELP_EE_VTABLE_FIXUP, // Not real JIT helper. Used for inherited vtable slot fixup in native images.
617
618 CORINFO_HELP_EE_REMOTING_THUNK, // Not real JIT helper. Used for remoting precode in native images.
619
620 CORINFO_HELP_EE_PERSONALITY_ROUTINE,// Not real JIT helper. Used in native images.
621 CORINFO_HELP_EE_PERSONALITY_ROUTINE_FILTER_FUNCLET,// Not real JIT helper. Used in native images to detect filter funclets.
622
623 // ASSIGN_REF_EAX - CHECKED_ASSIGN_REF_EBP: NOGC_WRITE_BARRIERS JIT helper calls
624 //
625 // For unchecked versions EDX is required to point into GC heap.
626 //
627 // NOTE: these helpers are only used for x86.
628 CORINFO_HELP_ASSIGN_REF_EAX, // EAX holds GC ptr, do a 'mov [EDX], EAX' and inform GC
629 CORINFO_HELP_ASSIGN_REF_EBX, // EBX holds GC ptr, do a 'mov [EDX], EBX' and inform GC
630 CORINFO_HELP_ASSIGN_REF_ECX, // ECX holds GC ptr, do a 'mov [EDX], ECX' and inform GC
631 CORINFO_HELP_ASSIGN_REF_ESI, // ESI holds GC ptr, do a 'mov [EDX], ESI' and inform GC
632 CORINFO_HELP_ASSIGN_REF_EDI, // EDI holds GC ptr, do a 'mov [EDX], EDI' and inform GC
633 CORINFO_HELP_ASSIGN_REF_EBP, // EBP holds GC ptr, do a 'mov [EDX], EBP' and inform GC
634
635 CORINFO_HELP_CHECKED_ASSIGN_REF_EAX, // These are the same as ASSIGN_REF above ...
636 CORINFO_HELP_CHECKED_ASSIGN_REF_EBX, // ... but also check if EDX points into heap.
637 CORINFO_HELP_CHECKED_ASSIGN_REF_ECX,
638 CORINFO_HELP_CHECKED_ASSIGN_REF_ESI,
639 CORINFO_HELP_CHECKED_ASSIGN_REF_EDI,
640 CORINFO_HELP_CHECKED_ASSIGN_REF_EBP,
641
642 CORINFO_HELP_LOOP_CLONE_CHOICE_ADDR, // Return the reference to a counter to decide to take cloned path in debug stress.
643 CORINFO_HELP_DEBUG_LOG_LOOP_CLONING, // Print a message that a loop cloning optimization has occurred in debug mode.
644
645 CORINFO_HELP_THROW_ARGUMENTEXCEPTION, // throw ArgumentException
646 CORINFO_HELP_THROW_ARGUMENTOUTOFRANGEEXCEPTION, // throw ArgumentOutOfRangeException
647 CORINFO_HELP_THROW_NOT_IMPLEMENTED, // throw NotImplementedException
648 CORINFO_HELP_THROW_PLATFORM_NOT_SUPPORTED, // throw PlatformNotSupportedException
649 CORINFO_HELP_THROW_TYPE_NOT_SUPPORTED, // throw TypeNotSupportedException
650
651 CORINFO_HELP_JIT_PINVOKE_BEGIN, // Transition to preemptive mode before a P/Invoke, frame is the first argument
652 CORINFO_HELP_JIT_PINVOKE_END, // Transition to cooperative mode after a P/Invoke, frame is the first argument
653
654 CORINFO_HELP_JIT_REVERSE_PINVOKE_ENTER, // Transition to cooperative mode in reverse P/Invoke prolog, frame is the first argument
655 CORINFO_HELP_JIT_REVERSE_PINVOKE_EXIT, // Transition to preemptive mode in reverse P/Invoke epilog, frame is the first argument
656
657 CORINFO_HELP_GVMLOOKUP_FOR_SLOT, // Resolve a generic virtual method target from this pointer and runtime method handle
658
659 CORINFO_HELP_COUNT,
660};
661
662#define CORINFO_HELP_READYTORUN_ATYPICAL_CALLSITE 0x40000000
663
664//This describes the signature for a helper method.
665enum CorInfoHelpSig
666{
667 CORINFO_HELP_SIG_UNDEF,
668 CORINFO_HELP_SIG_NO_ALIGN_STUB,
669 CORINFO_HELP_SIG_NO_UNWIND_STUB,
670 CORINFO_HELP_SIG_REG_ONLY,
671 CORINFO_HELP_SIG_4_STACK,
672 CORINFO_HELP_SIG_8_STACK,
673 CORINFO_HELP_SIG_12_STACK,
674 CORINFO_HELP_SIG_16_STACK,
675 CORINFO_HELP_SIG_8_VA, //2 arguments plus varargs
676
677 CORINFO_HELP_SIG_EBPCALL, //special calling convention that uses EDX and
678 //EBP as arguments
679
680 CORINFO_HELP_SIG_CANNOT_USE_ALIGN_STUB,
681
682 CORINFO_HELP_SIG_COUNT
683};
684
685// The enumeration is returned in 'getSig','getType', getArgType methods
686enum CorInfoType
687{
688 CORINFO_TYPE_UNDEF = 0x0,
689 CORINFO_TYPE_VOID = 0x1,
690 CORINFO_TYPE_BOOL = 0x2,
691 CORINFO_TYPE_CHAR = 0x3,
692 CORINFO_TYPE_BYTE = 0x4,
693 CORINFO_TYPE_UBYTE = 0x5,
694 CORINFO_TYPE_SHORT = 0x6,
695 CORINFO_TYPE_USHORT = 0x7,
696 CORINFO_TYPE_INT = 0x8,
697 CORINFO_TYPE_UINT = 0x9,
698 CORINFO_TYPE_LONG = 0xa,
699 CORINFO_TYPE_ULONG = 0xb,
700 CORINFO_TYPE_NATIVEINT = 0xc,
701 CORINFO_TYPE_NATIVEUINT = 0xd,
702 CORINFO_TYPE_FLOAT = 0xe,
703 CORINFO_TYPE_DOUBLE = 0xf,
704 CORINFO_TYPE_STRING = 0x10, // Not used, should remove
705 CORINFO_TYPE_PTR = 0x11,
706 CORINFO_TYPE_BYREF = 0x12,
707 CORINFO_TYPE_VALUECLASS = 0x13,
708 CORINFO_TYPE_CLASS = 0x14,
709 CORINFO_TYPE_REFANY = 0x15,
710
711 // CORINFO_TYPE_VAR is for a generic type variable.
712 // Generic type variables only appear when the JIT is doing
713 // verification (not NOT compilation) of generic code
714 // for the EE, in which case we're running
715 // the JIT in "import only" mode.
716
717 CORINFO_TYPE_VAR = 0x16,
718 CORINFO_TYPE_COUNT, // number of jit types
719};
720
721enum CorInfoTypeWithMod
722{
723 CORINFO_TYPE_MASK = 0x3F, // lower 6 bits are type mask
724 CORINFO_TYPE_MOD_PINNED = 0x40, // can be applied to CLASS, or BYREF to indiate pinned
725};
726
727inline CorInfoType strip(CorInfoTypeWithMod val) {
728 return CorInfoType(val & CORINFO_TYPE_MASK);
729}
730
731// The enumeration is returned in 'getSig'
732
733enum CorInfoCallConv
734{
735 // These correspond to CorCallingConvention
736
737 CORINFO_CALLCONV_DEFAULT = 0x0,
738 CORINFO_CALLCONV_C = 0x1,
739 CORINFO_CALLCONV_STDCALL = 0x2,
740 CORINFO_CALLCONV_THISCALL = 0x3,
741 CORINFO_CALLCONV_FASTCALL = 0x4,
742 CORINFO_CALLCONV_VARARG = 0x5,
743 CORINFO_CALLCONV_FIELD = 0x6,
744 CORINFO_CALLCONV_LOCAL_SIG = 0x7,
745 CORINFO_CALLCONV_PROPERTY = 0x8,
746 CORINFO_CALLCONV_NATIVEVARARG = 0xb, // used ONLY for IL stub PInvoke vararg calls
747
748 CORINFO_CALLCONV_MASK = 0x0f, // Calling convention is bottom 4 bits
749 CORINFO_CALLCONV_GENERIC = 0x10,
750 CORINFO_CALLCONV_HASTHIS = 0x20,
751 CORINFO_CALLCONV_EXPLICITTHIS=0x40,
752 CORINFO_CALLCONV_PARAMTYPE = 0x80, // Passed last. Same as CORINFO_GENERICS_CTXT_FROM_PARAMTYPEARG
753};
754
755#ifdef UNIX_X86_ABI
756inline bool IsCallerPop(CorInfoCallConv callConv)
757{
758 unsigned int umask = CORINFO_CALLCONV_STDCALL
759 | CORINFO_CALLCONV_THISCALL
760 | CORINFO_CALLCONV_FASTCALL;
761
762 return !(callConv & umask);
763}
764#endif // UNIX_X86_ABI
765
766enum CorInfoUnmanagedCallConv
767{
768 // These correspond to CorUnmanagedCallingConvention
769
770 CORINFO_UNMANAGED_CALLCONV_UNKNOWN,
771 CORINFO_UNMANAGED_CALLCONV_C,
772 CORINFO_UNMANAGED_CALLCONV_STDCALL,
773 CORINFO_UNMANAGED_CALLCONV_THISCALL,
774 CORINFO_UNMANAGED_CALLCONV_FASTCALL
775};
776
777// These are returned from getMethodOptions
778enum CorInfoOptions
779{
780 CORINFO_OPT_INIT_LOCALS = 0x00000010, // zero initialize all variables
781
782 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.
783 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
784 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
785 CORINFO_GENERICS_CTXT_MASK = (CORINFO_GENERICS_CTXT_FROM_THIS |
786 CORINFO_GENERICS_CTXT_FROM_METHODDESC |
787 CORINFO_GENERICS_CTXT_FROM_METHODTABLE),
788 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
789
790};
791
792//
793// what type of code region we are in
794//
795enum CorInfoRegionKind
796{
797 CORINFO_REGION_NONE,
798 CORINFO_REGION_HOT,
799 CORINFO_REGION_COLD,
800 CORINFO_REGION_JIT,
801};
802
803
804// these are the attribute flags for fields and methods (getMethodAttribs)
805enum CorInfoFlag
806{
807// CORINFO_FLG_UNUSED = 0x00000001,
808// CORINFO_FLG_UNUSED = 0x00000002,
809 CORINFO_FLG_PROTECTED = 0x00000004,
810 CORINFO_FLG_STATIC = 0x00000008,
811 CORINFO_FLG_FINAL = 0x00000010,
812 CORINFO_FLG_SYNCH = 0x00000020,
813 CORINFO_FLG_VIRTUAL = 0x00000040,
814// CORINFO_FLG_UNUSED = 0x00000080,
815 CORINFO_FLG_NATIVE = 0x00000100,
816 CORINFO_FLG_INTRINSIC_TYPE = 0x00000200, // This type is marked by [Intrinsic]
817 CORINFO_FLG_ABSTRACT = 0x00000400,
818
819 CORINFO_FLG_EnC = 0x00000800, // member was added by Edit'n'Continue
820
821 // These are internal flags that can only be on methods
822 CORINFO_FLG_FORCEINLINE = 0x00010000, // The method should be inlined if possible.
823 CORINFO_FLG_SHAREDINST = 0x00020000, // the code for this method is shared between different generic instantiations (also set on classes/types)
824 CORINFO_FLG_DELEGATE_INVOKE = 0x00040000, // "Delegate
825 CORINFO_FLG_PINVOKE = 0x00080000, // Is a P/Invoke call
826 CORINFO_FLG_SECURITYCHECK = 0x00100000, // Is one of the security routines that does a stackwalk (e.g. Assert, Demand)
827 CORINFO_FLG_NOGCCHECK = 0x00200000, // This method is FCALL that has no GC check. Don't put alone in loops
828 CORINFO_FLG_INTRINSIC = 0x00400000, // This method MAY have an intrinsic ID
829 CORINFO_FLG_CONSTRUCTOR = 0x00800000, // This method is an instance or type initializer
830 CORINFO_FLG_AGGRESSIVE_OPT = 0x01000000, // The method may contain hot code and should be aggressively optimized if possible
831// CORINFO_FLG_UNUSED = 0x02000000,
832 CORINFO_FLG_NOSECURITYWRAP = 0x04000000, // The method requires no security checks
833 CORINFO_FLG_DONT_INLINE = 0x10000000, // The method should not be inlined
834 CORINFO_FLG_DONT_INLINE_CALLER = 0x20000000, // The method should not be inlined, nor should its callers. It cannot be tail called.
835 CORINFO_FLG_JIT_INTRINSIC = 0x40000000, // Method is a potential jit intrinsic; verify identity by name check
836
837 // These are internal flags that can only be on Classes
838 CORINFO_FLG_VALUECLASS = 0x00010000, // is the class a value class
839// This flag is define din the Methods section, but is also valid on classes.
840// CORINFO_FLG_SHAREDINST = 0x00020000, // This class is satisfies TypeHandle::IsCanonicalSubtype
841 CORINFO_FLG_VAROBJSIZE = 0x00040000, // the object size varies depending of constructor args
842 CORINFO_FLG_ARRAY = 0x00080000, // class is an array class (initialized differently)
843 CORINFO_FLG_OVERLAPPING_FIELDS = 0x00100000, // struct or class has fields that overlap (aka union)
844 CORINFO_FLG_INTERFACE = 0x00200000, // it is an interface
845 CORINFO_FLG_CONTEXTFUL = 0x00400000, // is this a contextful class?
846 CORINFO_FLG_CUSTOMLAYOUT = 0x00800000, // does this struct have custom layout?
847 CORINFO_FLG_CONTAINS_GC_PTR = 0x01000000, // does the class contain a gc ptr ?
848 CORINFO_FLG_DELEGATE = 0x02000000, // is this a subclass of delegate or multicast delegate ?
849 CORINFO_FLG_MARSHAL_BYREF = 0x04000000, // is this a subclass of MarshalByRef ?
850 CORINFO_FLG_CONTAINS_STACK_PTR = 0x08000000, // This class has a stack pointer inside it
851 CORINFO_FLG_VARIANCE = 0x10000000, // MethodTable::HasVariance (sealed does *not* mean uncast-able)
852 CORINFO_FLG_BEFOREFIELDINIT = 0x20000000, // Additional flexibility for when to run .cctor (see code:#ClassConstructionFlags)
853 CORINFO_FLG_GENERIC_TYPE_VARIABLE = 0x40000000, // This is really a handle for a variable type
854 CORINFO_FLG_UNSAFE_VALUECLASS = 0x80000000, // Unsafe (C++'s /GS) value type
855};
856
857// Flags computed by a runtime compiler
858enum CorInfoMethodRuntimeFlags
859{
860 CORINFO_FLG_BAD_INLINEE = 0x00000001, // The method is not suitable for inlining
861 CORINFO_FLG_VERIFIABLE = 0x00000002, // The method has verifiable code
862 CORINFO_FLG_UNVERIFIABLE = 0x00000004, // The method has unverifiable code
863};
864
865
866enum CORINFO_ACCESS_FLAGS
867{
868 CORINFO_ACCESS_ANY = 0x0000, // Normal access
869 CORINFO_ACCESS_THIS = 0x0001, // Accessed via the this reference
870 CORINFO_ACCESS_UNWRAP = 0x0002, // Accessed via an unwrap reference
871
872 CORINFO_ACCESS_NONNULL = 0x0004, // Instance is guaranteed non-null
873
874 CORINFO_ACCESS_LDFTN = 0x0010, // Accessed via ldftn
875
876 // Field access flags
877 CORINFO_ACCESS_GET = 0x0100, // Field get (ldfld)
878 CORINFO_ACCESS_SET = 0x0200, // Field set (stfld)
879 CORINFO_ACCESS_ADDRESS = 0x0400, // Field address (ldflda)
880 CORINFO_ACCESS_INIT_ARRAY = 0x0800, // Field use for InitializeArray
881 CORINFO_ACCESS_ATYPICAL_CALLSITE = 0x4000, // Atypical callsite that cannot be disassembled by delay loading helper
882 CORINFO_ACCESS_INLINECHECK= 0x8000, // Return fieldFlags and fieldAccessor only. Used by JIT64 during inlining.
883};
884
885// These are the flags set on an CORINFO_EH_CLAUSE
886enum CORINFO_EH_CLAUSE_FLAGS
887{
888 CORINFO_EH_CLAUSE_NONE = 0,
889 CORINFO_EH_CLAUSE_FILTER = 0x0001, // If this bit is on, then this EH entry is for a filter
890 CORINFO_EH_CLAUSE_FINALLY = 0x0002, // This clause is a finally clause
891 CORINFO_EH_CLAUSE_FAULT = 0x0004, // This clause is a fault clause
892 CORINFO_EH_CLAUSE_DUPLICATE = 0x0008, // Duplicated clause. This clause was duplicated to a funclet which was pulled out of line
893 CORINFO_EH_CLAUSE_SAMETRY = 0x0010, // This clause covers same try block as the previous one. (Used by CoreRT ABI.)
894};
895
896// This enumeration is passed to InternalThrow
897enum CorInfoException
898{
899 CORINFO_NullReferenceException,
900 CORINFO_DivideByZeroException,
901 CORINFO_InvalidCastException,
902 CORINFO_IndexOutOfRangeException,
903 CORINFO_OverflowException,
904 CORINFO_SynchronizationLockException,
905 CORINFO_ArrayTypeMismatchException,
906 CORINFO_RankException,
907 CORINFO_ArgumentNullException,
908 CORINFO_ArgumentException,
909 CORINFO_Exception_Count,
910};
911
912
913// This enumeration is returned by getIntrinsicID. Methods corresponding to
914// these values will have "well-known" specified behavior. Calls to these
915// methods could be replaced with inlined code corresponding to the
916// specified behavior (without having to examine the IL beforehand).
917
918enum CorInfoIntrinsics
919{
920 CORINFO_INTRINSIC_Sin,
921 CORINFO_INTRINSIC_Cos,
922 CORINFO_INTRINSIC_Cbrt,
923 CORINFO_INTRINSIC_Sqrt,
924 CORINFO_INTRINSIC_Abs,
925 CORINFO_INTRINSIC_Round,
926 CORINFO_INTRINSIC_Cosh,
927 CORINFO_INTRINSIC_Sinh,
928 CORINFO_INTRINSIC_Tan,
929 CORINFO_INTRINSIC_Tanh,
930 CORINFO_INTRINSIC_Asin,
931 CORINFO_INTRINSIC_Asinh,
932 CORINFO_INTRINSIC_Acos,
933 CORINFO_INTRINSIC_Acosh,
934 CORINFO_INTRINSIC_Atan,
935 CORINFO_INTRINSIC_Atan2,
936 CORINFO_INTRINSIC_Atanh,
937 CORINFO_INTRINSIC_Log10,
938 CORINFO_INTRINSIC_Pow,
939 CORINFO_INTRINSIC_Exp,
940 CORINFO_INTRINSIC_Ceiling,
941 CORINFO_INTRINSIC_Floor,
942 CORINFO_INTRINSIC_GetChar, // fetch character out of string
943 CORINFO_INTRINSIC_Array_GetDimLength, // Get number of elements in a given dimension of an array
944 CORINFO_INTRINSIC_Array_Get, // Get the value of an element in an array
945 CORINFO_INTRINSIC_Array_Address, // Get the address of an element in an array
946 CORINFO_INTRINSIC_Array_Set, // Set the value of an element in an array
947 CORINFO_INTRINSIC_StringGetChar, // fetch character out of string
948 CORINFO_INTRINSIC_StringLength, // get the length
949 CORINFO_INTRINSIC_InitializeArray, // initialize an array from static data
950 CORINFO_INTRINSIC_GetTypeFromHandle,
951 CORINFO_INTRINSIC_RTH_GetValueInternal,
952 CORINFO_INTRINSIC_TypeEQ,
953 CORINFO_INTRINSIC_TypeNEQ,
954 CORINFO_INTRINSIC_Object_GetType,
955 CORINFO_INTRINSIC_StubHelpers_GetStubContext,
956 CORINFO_INTRINSIC_StubHelpers_GetStubContextAddr,
957 CORINFO_INTRINSIC_StubHelpers_GetNDirectTarget,
958 CORINFO_INTRINSIC_InterlockedAdd32,
959 CORINFO_INTRINSIC_InterlockedAdd64,
960 CORINFO_INTRINSIC_InterlockedXAdd32,
961 CORINFO_INTRINSIC_InterlockedXAdd64,
962 CORINFO_INTRINSIC_InterlockedXchg32,
963 CORINFO_INTRINSIC_InterlockedXchg64,
964 CORINFO_INTRINSIC_InterlockedCmpXchg32,
965 CORINFO_INTRINSIC_InterlockedCmpXchg64,
966 CORINFO_INTRINSIC_MemoryBarrier,
967 CORINFO_INTRINSIC_GetCurrentManagedThread,
968 CORINFO_INTRINSIC_GetManagedThreadId,
969 CORINFO_INTRINSIC_ByReference_Ctor,
970 CORINFO_INTRINSIC_ByReference_Value,
971 CORINFO_INTRINSIC_Span_GetItem,
972 CORINFO_INTRINSIC_ReadOnlySpan_GetItem,
973 CORINFO_INTRINSIC_GetRawHandle,
974
975 CORINFO_INTRINSIC_Count,
976 CORINFO_INTRINSIC_Illegal = -1, // Not a true intrinsic,
977};
978
979// Can a value be accessed directly from JITed code.
980enum InfoAccessType
981{
982 IAT_VALUE, // The info value is directly available
983 IAT_PVALUE, // The value needs to be accessed via an indirection
984 IAT_PPVALUE, // The value needs to be accessed via a double indirection
985 IAT_RELPVALUE // The value needs to be accessed via a relative indirection
986};
987
988enum CorInfoGCType
989{
990 TYPE_GC_NONE, // no embedded objectrefs
991 TYPE_GC_REF, // Is an object ref
992 TYPE_GC_BYREF, // Is an interior pointer - promote it but don't scan it
993 TYPE_GC_OTHER // requires type-specific treatment
994};
995
996enum CorInfoClassId
997{
998 CLASSID_SYSTEM_OBJECT,
999 CLASSID_TYPED_BYREF,
1000 CLASSID_TYPE_HANDLE,
1001 CLASSID_FIELD_HANDLE,
1002 CLASSID_METHOD_HANDLE,
1003 CLASSID_STRING,
1004 CLASSID_ARGUMENT_HANDLE,
1005 CLASSID_RUNTIME_TYPE,
1006};
1007
1008enum CorInfoInline
1009{
1010 INLINE_PASS = 0, // Inlining OK
1011
1012 // failures are negative
1013 INLINE_FAIL = -1, // Inlining not OK for this case only
1014 INLINE_NEVER = -2, // This method should never be inlined, regardless of context
1015};
1016
1017enum CorInfoInlineRestrictions
1018{
1019 INLINE_RESPECT_BOUNDARY = 0x00000001, // You can inline if there are no calls from the method being inlined
1020 INLINE_NO_CALLEE_LDSTR = 0x00000002, // You can inline only if you guarantee that if inlinee does an ldstr
1021 // inlinee's module will never see that string (by any means).
1022 // This is due to how we implement the NoStringInterningAttribute
1023 // (by reusing the fixup table).
1024 INLINE_SAME_THIS = 0x00000004, // You can inline only if the callee is on the same this reference as caller
1025};
1026
1027enum CorInfoInlineTypeCheck
1028{
1029 CORINFO_INLINE_TYPECHECK_NONE = 0x00000000, // It's not okay to compare type's vtable with a native type handle
1030 CORINFO_INLINE_TYPECHECK_PASS = 0x00000001, // It's okay to compare type's vtable with a native type handle
1031 CORINFO_INLINE_TYPECHECK_USE_HELPER = 0x00000002, // Use a specialized helper to compare type's vtable with native type handle
1032};
1033
1034enum CorInfoInlineTypeCheckSource
1035{
1036 CORINFO_INLINE_TYPECHECK_SOURCE_VTABLE = 0x00000000, // Type handle comes from the vtable
1037 CORINFO_INLINE_TYPECHECK_SOURCE_TOKEN = 0x00000001, // Type handle comes from an ldtoken
1038};
1039
1040// If you add more values here, keep it in sync with TailCallTypeMap in ..\vm\ClrEtwAll.man
1041// and the string enum in CEEInfo::reportTailCallDecision in ..\vm\JITInterface.cpp
1042enum CorInfoTailCall
1043{
1044 TAILCALL_OPTIMIZED = 0, // Optimized tail call (epilog + jmp)
1045 TAILCALL_RECURSIVE = 1, // Optimized into a loop (only when a method tail calls itself)
1046 TAILCALL_HELPER = 2, // Helper assisted tail call (call to JIT_TailCall)
1047
1048 // failures are negative
1049 TAILCALL_FAIL = -1, // Couldn't do a tail call
1050};
1051
1052enum CorInfoCanSkipVerificationResult
1053{
1054 CORINFO_VERIFICATION_CANNOT_SKIP = 0, // Cannot skip verification during jit time.
1055 CORINFO_VERIFICATION_CAN_SKIP = 1, // Can skip verification during jit time.
1056 CORINFO_VERIFICATION_RUNTIME_CHECK = 2, // Cannot skip verification during jit time,
1057 // but need to insert a callout to the VM to ask during runtime
1058 // whether to raise a verification or not (if the method is unverifiable).
1059 CORINFO_VERIFICATION_DONT_JIT = 3, // Cannot skip verification during jit time,
1060 // but do not jit the method if is is unverifiable.
1061};
1062
1063enum CorInfoInitClassResult
1064{
1065 CORINFO_INITCLASS_NOT_REQUIRED = 0x00, // No class initialization required, but the class is not actually initialized yet
1066 // (e.g. we are guaranteed to run the static constructor in method prolog)
1067 CORINFO_INITCLASS_INITIALIZED = 0x01, // Class initialized
1068 CORINFO_INITCLASS_SPECULATIVE = 0x02, // Class may be initialized speculatively
1069 CORINFO_INITCLASS_USE_HELPER = 0x04, // The JIT must insert class initialization helper call.
1070 CORINFO_INITCLASS_DONT_INLINE = 0x08, // The JIT should not inline the method requesting the class initialization. The class
1071 // initialization requires helper class now, but will not require initialization
1072 // if the method is compiled standalone. Or the method cannot be inlined due to some
1073 // requirement around class initialization such as shared generics.
1074};
1075
1076// Reason codes for making indirect calls
1077#define INDIRECT_CALL_REASONS() \
1078 INDIRECT_CALL_REASON_FUNC(CORINFO_INDIRECT_CALL_UNKNOWN) \
1079 INDIRECT_CALL_REASON_FUNC(CORINFO_INDIRECT_CALL_EXOTIC) \
1080 INDIRECT_CALL_REASON_FUNC(CORINFO_INDIRECT_CALL_PINVOKE) \
1081 INDIRECT_CALL_REASON_FUNC(CORINFO_INDIRECT_CALL_GENERIC) \
1082 INDIRECT_CALL_REASON_FUNC(CORINFO_INDIRECT_CALL_NO_CODE) \
1083 INDIRECT_CALL_REASON_FUNC(CORINFO_INDIRECT_CALL_FIXUPS) \
1084 INDIRECT_CALL_REASON_FUNC(CORINFO_INDIRECT_CALL_STUB) \
1085 INDIRECT_CALL_REASON_FUNC(CORINFO_INDIRECT_CALL_REMOTING) \
1086 INDIRECT_CALL_REASON_FUNC(CORINFO_INDIRECT_CALL_CER) \
1087 INDIRECT_CALL_REASON_FUNC(CORINFO_INDIRECT_CALL_RESTORE_METHOD) \
1088 INDIRECT_CALL_REASON_FUNC(CORINFO_INDIRECT_CALL_RESTORE_FIRST_CALL) \
1089 INDIRECT_CALL_REASON_FUNC(CORINFO_INDIRECT_CALL_RESTORE_VALUE_TYPE) \
1090 INDIRECT_CALL_REASON_FUNC(CORINFO_INDIRECT_CALL_RESTORE) \
1091 INDIRECT_CALL_REASON_FUNC(CORINFO_INDIRECT_CALL_CANT_PATCH) \
1092 INDIRECT_CALL_REASON_FUNC(CORINFO_INDIRECT_CALL_PROFILING) \
1093 INDIRECT_CALL_REASON_FUNC(CORINFO_INDIRECT_CALL_OTHER_LOADER_MODULE) \
1094
1095enum CorInfoIndirectCallReason
1096{
1097 #undef INDIRECT_CALL_REASON_FUNC
1098 #define INDIRECT_CALL_REASON_FUNC(x) x,
1099 INDIRECT_CALL_REASONS()
1100
1101 #undef INDIRECT_CALL_REASON_FUNC
1102
1103 CORINFO_INDIRECT_CALL_COUNT
1104};
1105
1106// This is for use when the JIT is compiling an instantiation
1107// of generic code. The JIT needs to know if the generic code itself
1108// (which can be verified once and for all independently of the
1109// instantiations) passed verification.
1110enum CorInfoInstantiationVerification
1111{
1112 // The method is NOT a concrete instantiation (eg. List<int>.Add()) of a method
1113 // in a generic class or a generic method. It is either the typical instantiation
1114 // (eg. List<T>.Add()) or entirely non-generic.
1115 INSTVER_NOT_INSTANTIATION = 0,
1116
1117 // The method is an instantiation of a method in a generic class or a generic method,
1118 // and the generic class was successfully verified
1119 INSTVER_GENERIC_PASSED_VERIFICATION = 1,
1120
1121 // The method is an instantiation of a method in a generic class or a generic method,
1122 // and the generic class failed verification
1123 INSTVER_GENERIC_FAILED_VERIFICATION = 2,
1124};
1125
1126// When using CORINFO_HELPER_TAILCALL, the JIT needs to pass certain special
1127// calling convention/argument passing/handling details to the helper
1128enum CorInfoHelperTailCallSpecialHandling
1129{
1130 CORINFO_TAILCALL_NORMAL = 0x00000000,
1131 CORINFO_TAILCALL_STUB_DISPATCH_ARG = 0x00000001,
1132};
1133
1134
1135inline bool dontInline(CorInfoInline val) {
1136 return(val < 0);
1137}
1138
1139// Cookie types consumed by the code generator (these are opaque values
1140// not inspected by the code generator):
1141
1142typedef struct CORINFO_ASSEMBLY_STRUCT_* CORINFO_ASSEMBLY_HANDLE;
1143typedef struct CORINFO_MODULE_STRUCT_* CORINFO_MODULE_HANDLE;
1144typedef struct CORINFO_DEPENDENCY_STRUCT_* CORINFO_DEPENDENCY_HANDLE;
1145typedef struct CORINFO_CLASS_STRUCT_* CORINFO_CLASS_HANDLE;
1146typedef struct CORINFO_METHOD_STRUCT_* CORINFO_METHOD_HANDLE;
1147typedef struct CORINFO_FIELD_STRUCT_* CORINFO_FIELD_HANDLE;
1148typedef struct CORINFO_ARG_LIST_STRUCT_* CORINFO_ARG_LIST_HANDLE; // represents a list of argument types
1149typedef struct CORINFO_JUST_MY_CODE_HANDLE_*CORINFO_JUST_MY_CODE_HANDLE;
1150typedef struct CORINFO_PROFILING_STRUCT_* CORINFO_PROFILING_HANDLE; // a handle guaranteed to be unique per process
1151typedef struct CORINFO_GENERIC_STRUCT_* CORINFO_GENERIC_HANDLE; // a generic handle (could be any of the above)
1152
1153// what is actually passed on the varargs call
1154typedef struct CORINFO_VarArgInfo * CORINFO_VARARGS_HANDLE;
1155
1156// Generic tokens are resolved with respect to a context, which is usually the method
1157// being compiled. The CORINFO_CONTEXT_HANDLE indicates which exact instantiation
1158// (or the open instantiation) is being referred to.
1159// CORINFO_CONTEXT_HANDLE is more tightly scoped than CORINFO_MODULE_HANDLE. For cases
1160// where the exact instantiation does not matter, CORINFO_MODULE_HANDLE is used.
1161typedef CORINFO_METHOD_HANDLE CORINFO_CONTEXT_HANDLE;
1162
1163typedef struct CORINFO_DEPENDENCY_STRUCT_
1164{
1165 CORINFO_MODULE_HANDLE moduleFrom;
1166 CORINFO_MODULE_HANDLE moduleTo;
1167} CORINFO_DEPENDENCY;
1168
1169// Bit-twiddling of contexts assumes word-alignment of method handles and type handles
1170// If this ever changes, some other encoding will be needed
1171enum CorInfoContextFlags
1172{
1173 CORINFO_CONTEXTFLAGS_METHOD = 0x00, // CORINFO_CONTEXT_HANDLE is really a CORINFO_METHOD_HANDLE
1174 CORINFO_CONTEXTFLAGS_CLASS = 0x01, // CORINFO_CONTEXT_HANDLE is really a CORINFO_CLASS_HANDLE
1175 CORINFO_CONTEXTFLAGS_MASK = 0x01
1176};
1177
1178#define MAKE_CLASSCONTEXT(c) (CORINFO_CONTEXT_HANDLE((size_t) (c) | CORINFO_CONTEXTFLAGS_CLASS))
1179#define MAKE_METHODCONTEXT(m) (CORINFO_CONTEXT_HANDLE((size_t) (m) | CORINFO_CONTEXTFLAGS_METHOD))
1180
1181enum CorInfoSigInfoFlags
1182{
1183 CORINFO_SIGFLAG_IS_LOCAL_SIG = 0x01,
1184 CORINFO_SIGFLAG_IL_STUB = 0x02,
1185};
1186
1187struct CORINFO_SIG_INST
1188{
1189 unsigned classInstCount;
1190 CORINFO_CLASS_HANDLE * classInst; // (representative, not exact) instantiation for class type variables in signature
1191 unsigned methInstCount;
1192 CORINFO_CLASS_HANDLE * methInst; // (representative, not exact) instantiation for method type variables in signature
1193};
1194
1195struct CORINFO_SIG_INFO
1196{
1197 CorInfoCallConv callConv;
1198 CORINFO_CLASS_HANDLE retTypeClass; // if the return type is a value class, this is its handle (enums are normalized)
1199 CORINFO_CLASS_HANDLE retTypeSigClass;// returns the value class as it is in the sig (enums are not converted to primitives)
1200 CorInfoType retType : 8;
1201 unsigned flags : 8; // used by IL stubs code
1202 unsigned numArgs : 16;
1203 struct CORINFO_SIG_INST sigInst; // information about how type variables are being instantiated in generic code
1204 CORINFO_ARG_LIST_HANDLE args;
1205 PCCOR_SIGNATURE pSig;
1206 unsigned cbSig;
1207 CORINFO_MODULE_HANDLE scope; // passed to getArgClass
1208 mdToken token;
1209
1210 CorInfoCallConv getCallConv() { return CorInfoCallConv((callConv & CORINFO_CALLCONV_MASK)); }
1211 bool hasThis() { return ((callConv & CORINFO_CALLCONV_HASTHIS) != 0); }
1212 bool hasExplicitThis() { return ((callConv & CORINFO_CALLCONV_EXPLICITTHIS) != 0); }
1213 unsigned totalILArgs() { return (numArgs + hasThis()); }
1214 bool isVarArg() { return ((getCallConv() == CORINFO_CALLCONV_VARARG) || (getCallConv() == CORINFO_CALLCONV_NATIVEVARARG)); }
1215 bool hasTypeArg() { return ((callConv & CORINFO_CALLCONV_PARAMTYPE) != 0); }
1216};
1217
1218struct CORINFO_METHOD_INFO
1219{
1220 CORINFO_METHOD_HANDLE ftn;
1221 CORINFO_MODULE_HANDLE scope;
1222 BYTE * ILCode;
1223 unsigned ILCodeSize;
1224 unsigned maxStack;
1225 unsigned EHcount;
1226 CorInfoOptions options;
1227 CorInfoRegionKind regionKind;
1228 CORINFO_SIG_INFO args;
1229 CORINFO_SIG_INFO locals;
1230};
1231
1232//----------------------------------------------------------------------------
1233// Looking up handles and addresses.
1234//
1235// When the JIT requests a handle, the EE may direct the JIT that it must
1236// access the handle in a variety of ways. These are packed as
1237// CORINFO_CONST_LOOKUP
1238// or CORINFO_LOOKUP (contains either a CORINFO_CONST_LOOKUP or a CORINFO_RUNTIME_LOOKUP)
1239//
1240// Constant Lookups v. Runtime Lookups (i.e. when will Runtime Lookups be generated?)
1241// -----------------------------------------------------------------------------------
1242//
1243// CORINFO_LOOKUP_KIND is part of the result type of embedGenericHandle,
1244// getVirtualCallInfo and any other functions that may require a
1245// runtime lookup when compiling shared generic code.
1246//
1247// CORINFO_LOOKUP_KIND indicates whether a particular token in the instruction stream can be:
1248// (a) Mapped to a handle (type, field or method) at compile-time (!needsRuntimeLookup)
1249// (b) Must be looked up at run-time, and if so which runtime lookup technique should be used (see below)
1250//
1251// If the JIT or EE does not support code sharing for generic code, then
1252// all CORINFO_LOOKUP results will be "constant lookups", i.e.
1253// the needsRuntimeLookup of CORINFO_LOOKUP.lookupKind.needsRuntimeLookup
1254// will be false.
1255//
1256// Constant Lookups
1257// ----------------
1258//
1259// Constant Lookups are either:
1260// IAT_VALUE: immediate (relocatable) values,
1261// IAT_PVALUE: immediate values access via an indirection through an immediate (relocatable) address
1262// IAT_RELPVALUE: immediate values access via a relative indirection through an immediate offset
1263// IAT_PPVALUE: immediate values access via a double indirection through an immediate (relocatable) address
1264//
1265// Runtime Lookups
1266// ---------------
1267//
1268// CORINFO_LOOKUP_KIND is part of the result type of embedGenericHandle,
1269// getVirtualCallInfo and any other functions that may require a
1270// runtime lookup when compiling shared generic code.
1271//
1272// CORINFO_LOOKUP_KIND indicates whether a particular token in the instruction stream can be:
1273// (a) Mapped to a handle (type, field or method) at compile-time (!needsRuntimeLookup)
1274// (b) Must be looked up at run-time using the class dictionary
1275// stored in the vtable of the this pointer (needsRuntimeLookup && THISOBJ)
1276// (c) Must be looked up at run-time using the method dictionary
1277// stored in the method descriptor parameter passed to a generic
1278// method (needsRuntimeLookup && METHODPARAM)
1279// (d) Must be looked up at run-time using the class dictionary stored
1280// in the vtable parameter passed to a method in a generic
1281// struct (needsRuntimeLookup && CLASSPARAM)
1282
1283struct CORINFO_CONST_LOOKUP
1284{
1285 // If the handle is obtained at compile-time, then this handle is the "exact" handle (class, method, or field)
1286 // Otherwise, it's a representative...
1287 // If accessType is
1288 // IAT_VALUE --> "handle" stores the real handle or "addr " stores the computed address
1289 // IAT_PVALUE --> "addr" stores a pointer to a location which will hold the real handle
1290 // IAT_RELPVALUE --> "addr" stores a relative pointer to a location which will hold the real handle
1291 // IAT_PPVALUE --> "addr" stores a double indirection to a location which will hold the real handle
1292
1293 InfoAccessType accessType;
1294 union
1295 {
1296 CORINFO_GENERIC_HANDLE handle;
1297 void * addr;
1298 };
1299};
1300
1301enum CORINFO_RUNTIME_LOOKUP_KIND
1302{
1303 CORINFO_LOOKUP_THISOBJ,
1304 CORINFO_LOOKUP_METHODPARAM,
1305 CORINFO_LOOKUP_CLASSPARAM,
1306};
1307
1308struct CORINFO_LOOKUP_KIND
1309{
1310 bool needsRuntimeLookup;
1311 CORINFO_RUNTIME_LOOKUP_KIND runtimeLookupKind;
1312
1313 // The 'runtimeLookupFlags' and 'runtimeLookupArgs' fields
1314 // are just for internal VM / ZAP communication, not to be used by the JIT.
1315 WORD runtimeLookupFlags;
1316 void * runtimeLookupArgs;
1317} ;
1318
1319
1320// CORINFO_RUNTIME_LOOKUP indicates the details of the runtime lookup
1321// operation to be performed.
1322//
1323// CORINFO_MAXINDIRECTIONS is the maximum number of
1324// indirections used by runtime lookups.
1325// This accounts for up to 2 indirections to get at a dictionary followed by a possible spill slot
1326//
1327#define CORINFO_MAXINDIRECTIONS 4
1328#define CORINFO_USEHELPER ((WORD) 0xffff)
1329
1330struct CORINFO_RUNTIME_LOOKUP
1331{
1332 // This is signature you must pass back to the runtime lookup helper
1333 LPVOID signature;
1334
1335 // Here is the helper you must call. It is one of CORINFO_HELP_RUNTIMEHANDLE_* helpers.
1336 CorInfoHelpFunc helper;
1337
1338 // Number of indirections to get there
1339 // CORINFO_USEHELPER = don't know how to get it, so use helper function at run-time instead
1340 // 0 = use the this pointer itself (e.g. token is C<!0> inside code in sealed class C)
1341 // or method desc itself (e.g. token is method void M::mymeth<!!0>() inside code in M::mymeth)
1342 // Otherwise, follow each byte-offset stored in the "offsets[]" array (may be negative)
1343 WORD indirections;
1344
1345 // If set, test for null and branch to helper if null
1346 bool testForNull;
1347
1348 // If set, test the lowest bit and dereference if set (see code:FixupPointer)
1349 bool testForFixup;
1350
1351 SIZE_T offsets[CORINFO_MAXINDIRECTIONS];
1352
1353 // If set, first offset is indirect.
1354 // 0 means that value stored at first offset (offsets[0]) from pointer is next pointer, to which the next offset
1355 // (offsets[1]) is added and so on.
1356 // 1 means that value stored at first offset (offsets[0]) from pointer is offset1, and the next pointer is
1357 // stored at pointer+offsets[0]+offset1.
1358 bool indirectFirstOffset;
1359
1360 // If set, second offset is indirect.
1361 // 0 means that value stored at second offset (offsets[1]) from pointer is next pointer, to which the next offset
1362 // (offsets[2]) is added and so on.
1363 // 1 means that value stored at second offset (offsets[1]) from pointer is offset2, and the next pointer is
1364 // stored at pointer+offsets[1]+offset2.
1365 bool indirectSecondOffset;
1366} ;
1367
1368// Result of calling embedGenericHandle
1369struct CORINFO_LOOKUP
1370{
1371 CORINFO_LOOKUP_KIND lookupKind;
1372
1373 union
1374 {
1375 // If kind.needsRuntimeLookup then this indicates how to do the lookup
1376 CORINFO_RUNTIME_LOOKUP runtimeLookup;
1377
1378 // If the handle is obtained at compile-time, then this handle is the "exact" handle (class, method, or field)
1379 // Otherwise, it's a representative... If accessType is
1380 // IAT_VALUE --> "handle" stores the real handle or "addr " stores the computed address
1381 // IAT_PVALUE --> "addr" stores a pointer to a location which will hold the real handle
1382 // IAT_RELPVALUE --> "addr" stores a relative pointer to a location which will hold the real handle
1383 // IAT_PPVALUE --> "addr" stores a double indirection to a location which will hold the real handle
1384 CORINFO_CONST_LOOKUP constLookup;
1385 };
1386};
1387
1388enum CorInfoGenericHandleType
1389{
1390 CORINFO_HANDLETYPE_UNKNOWN,
1391 CORINFO_HANDLETYPE_CLASS,
1392 CORINFO_HANDLETYPE_METHOD,
1393 CORINFO_HANDLETYPE_FIELD
1394};
1395
1396//----------------------------------------------------------------------------
1397// Embedding type, method and field handles (for "ldtoken" or to pass back to helpers)
1398
1399// Result of calling embedGenericHandle
1400struct CORINFO_GENERICHANDLE_RESULT
1401{
1402 CORINFO_LOOKUP lookup;
1403
1404 // compileTimeHandle is guaranteed to be either NULL or a handle that is usable during compile time.
1405 // It must not be embedded in the code because it might not be valid at run-time.
1406 CORINFO_GENERIC_HANDLE compileTimeHandle;
1407
1408 // Type of the result
1409 CorInfoGenericHandleType handleType;
1410};
1411
1412#define CORINFO_ACCESS_ALLOWED_MAX_ARGS 4
1413
1414enum CorInfoAccessAllowedHelperArgType
1415{
1416 CORINFO_HELPER_ARG_TYPE_Invalid = 0,
1417 CORINFO_HELPER_ARG_TYPE_Field = 1,
1418 CORINFO_HELPER_ARG_TYPE_Method = 2,
1419 CORINFO_HELPER_ARG_TYPE_Class = 3,
1420 CORINFO_HELPER_ARG_TYPE_Module = 4,
1421 CORINFO_HELPER_ARG_TYPE_Const = 5,
1422};
1423struct CORINFO_HELPER_ARG
1424{
1425 union
1426 {
1427 CORINFO_FIELD_HANDLE fieldHandle;
1428 CORINFO_METHOD_HANDLE methodHandle;
1429 CORINFO_CLASS_HANDLE classHandle;
1430 CORINFO_MODULE_HANDLE moduleHandle;
1431 size_t constant;
1432 };
1433 CorInfoAccessAllowedHelperArgType argType;
1434
1435 void Set(CORINFO_METHOD_HANDLE handle)
1436 {
1437 argType = CORINFO_HELPER_ARG_TYPE_Method;
1438 methodHandle = handle;
1439 }
1440
1441 void Set(CORINFO_FIELD_HANDLE handle)
1442 {
1443 argType = CORINFO_HELPER_ARG_TYPE_Field;
1444 fieldHandle = handle;
1445 }
1446
1447 void Set(CORINFO_CLASS_HANDLE handle)
1448 {
1449 argType = CORINFO_HELPER_ARG_TYPE_Class;
1450 classHandle = handle;
1451 }
1452
1453 void Set(size_t value)
1454 {
1455 argType = CORINFO_HELPER_ARG_TYPE_Const;
1456 constant = value;
1457 }
1458};
1459
1460struct CORINFO_HELPER_DESC
1461{
1462 CorInfoHelpFunc helperNum;
1463 unsigned numArgs;
1464 CORINFO_HELPER_ARG args[CORINFO_ACCESS_ALLOWED_MAX_ARGS];
1465};
1466
1467//----------------------------------------------------------------------------
1468// getCallInfo and CORINFO_CALL_INFO: The EE instructs the JIT about how to make a call
1469//
1470// callKind
1471// --------
1472//
1473// CORINFO_CALL :
1474// Indicates that the JIT can use getFunctionEntryPoint to make a call,
1475// i.e. there is nothing abnormal about the call. The JITs know what to do if they get this.
1476// Except in the case of constraint calls (see below), [targetMethodHandle] will hold
1477// the CORINFO_METHOD_HANDLE that a call to findMethod would
1478// have returned.
1479// This flag may be combined with nullInstanceCheck=TRUE for uses of callvirt on methods that can
1480// be resolved at compile-time (non-virtual, final or sealed).
1481//
1482// CORINFO_CALL_CODE_POINTER (shared generic code only) :
1483// Indicates that the JIT should do an indirect call to the entrypoint given by address, which may be specified
1484// as a runtime lookup by CORINFO_CALL_INFO::codePointerLookup.
1485// [targetMethodHandle] will not hold a valid value.
1486// This flag may be combined with nullInstanceCheck=TRUE for uses of callvirt on methods whose target method can
1487// be resolved at compile-time but whose instantiation can be resolved only through runtime lookup.
1488//
1489// CORINFO_VIRTUALCALL_STUB (interface calls) :
1490// Indicates that the EE supports "stub dispatch" and request the JIT to make a
1491// "stub dispatch" call (an indirect call through CORINFO_CALL_INFO::stubLookup,
1492// similar to CORINFO_CALL_CODE_POINTER).
1493// "Stub dispatch" is a specialized calling sequence (that may require use of NOPs)
1494// which allow the runtime to determine the call-site after the call has been dispatched.
1495// If the call is too complex for the JIT (e.g. because
1496// fetching the dispatch stub requires a runtime lookup, i.e. lookupKind.needsRuntimeLookup
1497// is set) then the JIT is allowed to implement the call as if it were CORINFO_VIRTUALCALL_LDVIRTFTN
1498// [targetMethodHandle] will hold the CORINFO_METHOD_HANDLE that a call to findMethod would
1499// have returned.
1500// This flag is always accompanied by nullInstanceCheck=TRUE.
1501//
1502// CORINFO_VIRTUALCALL_LDVIRTFTN (virtual generic methods) :
1503// Indicates that the EE provides no way to implement the call directly and
1504// that the JIT should use a LDVIRTFTN sequence (as implemented by CORINFO_HELP_VIRTUAL_FUNC_PTR)
1505// followed by an indirect call.
1506// [targetMethodHandle] will hold the CORINFO_METHOD_HANDLE that a call to findMethod would
1507// have returned.
1508// This flag is always accompanied by nullInstanceCheck=TRUE though typically the null check will
1509// be implicit in the access through the instance pointer.
1510//
1511// CORINFO_VIRTUALCALL_VTABLE (regular virtual methods) :
1512// Indicates that the EE supports vtable dispatch and that the JIT should use getVTableOffset etc.
1513// to implement the call.
1514// [targetMethodHandle] will hold the CORINFO_METHOD_HANDLE that a call to findMethod would
1515// have returned.
1516// This flag is always accompanied by nullInstanceCheck=TRUE though typically the null check will
1517// be implicit in the access through the instance pointer.
1518//
1519// thisTransform and constraint calls
1520// ----------------------------------
1521//
1522// For evertyhing besides "constrained." calls "thisTransform" is set to
1523// CORINFO_NO_THIS_TRANSFORM.
1524//
1525// For "constrained." calls the EE attempts to resolve the call at compile
1526// time to a more specific method, or (shared generic code only) to a runtime lookup
1527// for a code pointer for the more specific method.
1528//
1529// In order to permit this, the "this" pointer supplied for a "constrained." call
1530// is a byref to an arbitrary type (see the IL spec). The "thisTransform" field
1531// will indicate how the JIT must transform the "this" pointer in order
1532// to be able to call the resolved method:
1533//
1534// CORINFO_NO_THIS_TRANSFORM --> Leave it as a byref to an unboxed value type
1535// CORINFO_BOX_THIS --> Box it to produce an object
1536// CORINFO_DEREF_THIS --> Deref the byref to get an object reference
1537//
1538// In addition, the "kind" field will be set as follows for constraint calls:
1539
1540// CORINFO_CALL --> the call was resolved at compile time, and
1541// can be compiled like a normal call.
1542// CORINFO_CALL_CODE_POINTER --> the call was resolved, but the target address will be
1543// computed at runtime. Only returned for shared generic code.
1544// CORINFO_VIRTUALCALL_STUB,
1545// CORINFO_VIRTUALCALL_LDVIRTFTN,
1546// CORINFO_VIRTUALCALL_VTABLE --> usual values indicating that a virtual call must be made
1547
1548enum CORINFO_CALL_KIND
1549{
1550 CORINFO_CALL,
1551 CORINFO_CALL_CODE_POINTER,
1552 CORINFO_VIRTUALCALL_STUB,
1553 CORINFO_VIRTUALCALL_LDVIRTFTN,
1554 CORINFO_VIRTUALCALL_VTABLE
1555};
1556
1557// Indicates that the CORINFO_VIRTUALCALL_VTABLE lookup needn't do a chunk indirection
1558#define CORINFO_VIRTUALCALL_NO_CHUNK 0xFFFFFFFF
1559
1560enum CORINFO_THIS_TRANSFORM
1561{
1562 CORINFO_NO_THIS_TRANSFORM,
1563 CORINFO_BOX_THIS,
1564 CORINFO_DEREF_THIS
1565};
1566
1567enum CORINFO_CALLINFO_FLAGS
1568{
1569 CORINFO_CALLINFO_NONE = 0x0000,
1570 CORINFO_CALLINFO_ALLOWINSTPARAM = 0x0001, // Can the compiler generate code to pass an instantiation parameters? Simple compilers should not use this flag
1571 CORINFO_CALLINFO_CALLVIRT = 0x0002, // Is it a virtual call?
1572 CORINFO_CALLINFO_KINDONLY = 0x0004, // This is set to only query the kind of call to perform, without getting any other information
1573 CORINFO_CALLINFO_VERIFICATION = 0x0008, // Gets extra verification information.
1574 CORINFO_CALLINFO_SECURITYCHECKS = 0x0010, // Perform security checks.
1575 CORINFO_CALLINFO_LDFTN = 0x0020, // Resolving target of LDFTN
1576 CORINFO_CALLINFO_ATYPICAL_CALLSITE = 0x0040, // Atypical callsite that cannot be disassembled by delay loading helper
1577};
1578
1579enum CorInfoIsAccessAllowedResult
1580{
1581 CORINFO_ACCESS_ALLOWED = 0, // Call allowed
1582 CORINFO_ACCESS_ILLEGAL = 1, // Call not allowed
1583 CORINFO_ACCESS_RUNTIME_CHECK = 2, // Ask at runtime whether to allow the call or not
1584};
1585
1586
1587// This enum is used for JIT to tell EE where this token comes from.
1588// E.g. Depending on different opcodes, we might allow/disallow certain types of tokens or
1589// return different types of handles (e.g. boxed vs. regular entrypoints)
1590enum CorInfoTokenKind
1591{
1592 CORINFO_TOKENKIND_Class = 0x01,
1593 CORINFO_TOKENKIND_Method = 0x02,
1594 CORINFO_TOKENKIND_Field = 0x04,
1595 CORINFO_TOKENKIND_Mask = 0x07,
1596
1597 // token comes from CEE_LDTOKEN
1598 CORINFO_TOKENKIND_Ldtoken = 0x10 | CORINFO_TOKENKIND_Class | CORINFO_TOKENKIND_Method | CORINFO_TOKENKIND_Field,
1599
1600 // token comes from CEE_CASTCLASS or CEE_ISINST
1601 CORINFO_TOKENKIND_Casting = 0x20 | CORINFO_TOKENKIND_Class,
1602
1603 // token comes from CEE_NEWARR
1604 CORINFO_TOKENKIND_Newarr = 0x40 | CORINFO_TOKENKIND_Class,
1605
1606 // token comes from CEE_BOX
1607 CORINFO_TOKENKIND_Box = 0x80 | CORINFO_TOKENKIND_Class,
1608
1609 // token comes from CEE_CONSTRAINED
1610 CORINFO_TOKENKIND_Constrained = 0x100 | CORINFO_TOKENKIND_Class,
1611
1612 // token comes from CEE_NEWOBJ
1613 CORINFO_TOKENKIND_NewObj = 0x200 | CORINFO_TOKENKIND_Method,
1614
1615 // token comes from CEE_LDVIRTFTN
1616 CORINFO_TOKENKIND_Ldvirtftn = 0x400 | CORINFO_TOKENKIND_Method,
1617};
1618
1619struct CORINFO_RESOLVED_TOKEN
1620{
1621 //
1622 // [In] arguments of resolveToken
1623 //
1624 CORINFO_CONTEXT_HANDLE tokenContext; //Context for resolution of generic arguments
1625 CORINFO_MODULE_HANDLE tokenScope;
1626 mdToken token; //The source token
1627 CorInfoTokenKind tokenType;
1628
1629 //
1630 // [Out] arguments of resolveToken.
1631 // - Type handle is always non-NULL.
1632 // - At most one of method and field handles is non-NULL (according to the token type).
1633 // - Method handle is an instantiating stub only for generic methods. Type handle
1634 // is required to provide the full context for methods in generic types.
1635 //
1636 CORINFO_CLASS_HANDLE hClass;
1637 CORINFO_METHOD_HANDLE hMethod;
1638 CORINFO_FIELD_HANDLE hField;
1639
1640 //
1641 // [Out] TypeSpec and MethodSpec signatures for generics. NULL otherwise.
1642 //
1643 PCCOR_SIGNATURE pTypeSpec;
1644 ULONG cbTypeSpec;
1645 PCCOR_SIGNATURE pMethodSpec;
1646 ULONG cbMethodSpec;
1647};
1648
1649struct CORINFO_CALL_INFO
1650{
1651 CORINFO_METHOD_HANDLE hMethod; //target method handle
1652 unsigned methodFlags; //flags for the target method
1653
1654 unsigned classFlags; //flags for CORINFO_RESOLVED_TOKEN::hClass
1655
1656 CORINFO_SIG_INFO sig;
1657
1658 //Verification information
1659 unsigned verMethodFlags; // flags for CORINFO_RESOLVED_TOKEN::hMethod
1660 CORINFO_SIG_INFO verSig;
1661 //All of the regular method data is the same... hMethod might not be the same as CORINFO_RESOLVED_TOKEN::hMethod
1662
1663
1664 //If set to:
1665 // - CORINFO_ACCESS_ALLOWED - The access is allowed.
1666 // - CORINFO_ACCESS_ILLEGAL - This access cannot be allowed (i.e. it is public calling private). The
1667 // JIT may either insert the callsiteCalloutHelper into the code (as per a verification error) or
1668 // call throwExceptionFromHelper on the callsiteCalloutHelper. In this case callsiteCalloutHelper
1669 // is guaranteed not to return.
1670 // - CORINFO_ACCESS_RUNTIME_CHECK - The jit must insert the callsiteCalloutHelper at the call site.
1671 // the helper may return
1672 CorInfoIsAccessAllowedResult accessAllowed;
1673 CORINFO_HELPER_DESC callsiteCalloutHelper;
1674
1675 // See above section on constraintCalls to understand when these are set to unusual values.
1676 CORINFO_THIS_TRANSFORM thisTransform;
1677
1678 CORINFO_CALL_KIND kind;
1679 BOOL nullInstanceCheck;
1680
1681 // Context for inlining and hidden arg
1682 CORINFO_CONTEXT_HANDLE contextHandle;
1683 BOOL exactContextNeedsRuntimeLookup; // Set if contextHandle is approx handle. Runtime lookup is required to get the exact handle.
1684
1685 // If kind.CORINFO_VIRTUALCALL_STUB then stubLookup will be set.
1686 // If kind.CORINFO_CALL_CODE_POINTER then entryPointLookup will be set.
1687 union
1688 {
1689 CORINFO_LOOKUP stubLookup;
1690
1691 CORINFO_LOOKUP codePointerLookup;
1692 };
1693
1694 CORINFO_CONST_LOOKUP instParamLookup; // Used by Ready-to-Run
1695
1696 BOOL secureDelegateInvoke;
1697};
1698
1699//----------------------------------------------------------------------------
1700// getFieldInfo and CORINFO_FIELD_INFO: The EE instructs the JIT about how to access a field
1701
1702enum CORINFO_FIELD_ACCESSOR
1703{
1704 CORINFO_FIELD_INSTANCE, // regular instance field at given offset from this-ptr
1705 CORINFO_FIELD_INSTANCE_WITH_BASE, // instance field with base offset (used by Ready-to-Run)
1706 CORINFO_FIELD_INSTANCE_HELPER, // instance field accessed using helper (arguments are this, FieldDesc * and the value)
1707 CORINFO_FIELD_INSTANCE_ADDR_HELPER, // instance field accessed using address-of helper (arguments are this and FieldDesc *)
1708
1709 CORINFO_FIELD_STATIC_ADDRESS, // field at given address
1710 CORINFO_FIELD_STATIC_RVA_ADDRESS, // RVA field at given address
1711 CORINFO_FIELD_STATIC_SHARED_STATIC_HELPER, // static field accessed using the "shared static" helper (arguments are ModuleID + ClassID)
1712 CORINFO_FIELD_STATIC_GENERICS_STATIC_HELPER, // static field access using the "generic static" helper (argument is MethodTable *)
1713 CORINFO_FIELD_STATIC_ADDR_HELPER, // static field accessed using address-of helper (argument is FieldDesc *)
1714 CORINFO_FIELD_STATIC_TLS, // unmanaged TLS access
1715 CORINFO_FIELD_STATIC_READYTORUN_HELPER, // static field access using a runtime lookup helper
1716
1717 CORINFO_FIELD_INTRINSIC_ZERO, // intrinsic zero (IntPtr.Zero, UIntPtr.Zero)
1718 CORINFO_FIELD_INTRINSIC_EMPTY_STRING, // intrinsic emptry string (String.Empty)
1719 CORINFO_FIELD_INTRINSIC_ISLITTLEENDIAN, // intrinsic BitConverter.IsLittleEndian
1720};
1721
1722// Set of flags returned in CORINFO_FIELD_INFO::fieldFlags
1723enum CORINFO_FIELD_FLAGS
1724{
1725 CORINFO_FLG_FIELD_STATIC = 0x00000001,
1726 CORINFO_FLG_FIELD_UNMANAGED = 0x00000002, // RVA field
1727 CORINFO_FLG_FIELD_FINAL = 0x00000004,
1728 CORINFO_FLG_FIELD_STATIC_IN_HEAP = 0x00000008, // See code:#StaticFields. This static field is in the GC heap as a boxed object
1729 CORINFO_FLG_FIELD_SAFESTATIC_BYREF_RETURN = 0x00000010, // Field can be returned safely (has GC heap lifetime)
1730 CORINFO_FLG_FIELD_INITCLASS = 0x00000020, // initClass has to be called before accessing the field
1731 CORINFO_FLG_FIELD_PROTECTED = 0x00000040,
1732};
1733
1734struct CORINFO_FIELD_INFO
1735{
1736 CORINFO_FIELD_ACCESSOR fieldAccessor;
1737 unsigned fieldFlags;
1738
1739 // Helper to use if the field access requires it
1740 CorInfoHelpFunc helper;
1741
1742 // Field offset if there is one
1743 DWORD offset;
1744
1745 CorInfoType fieldType;
1746 CORINFO_CLASS_HANDLE structType; //possibly null
1747
1748 //See CORINFO_CALL_INFO.accessAllowed
1749 CorInfoIsAccessAllowedResult accessAllowed;
1750 CORINFO_HELPER_DESC accessCalloutHelper;
1751
1752 CORINFO_CONST_LOOKUP fieldLookup; // Used by Ready-to-Run
1753};
1754
1755//----------------------------------------------------------------------------
1756// Exception handling
1757
1758struct CORINFO_EH_CLAUSE
1759{
1760 CORINFO_EH_CLAUSE_FLAGS Flags;
1761 DWORD TryOffset;
1762 DWORD TryLength;
1763 DWORD HandlerOffset;
1764 DWORD HandlerLength;
1765 union
1766 {
1767 DWORD ClassToken; // use for type-based exception handlers
1768 DWORD FilterOffset; // use for filter-based exception handlers (COR_ILEXCEPTION_FILTER is set)
1769 };
1770};
1771
1772enum CORINFO_OS
1773{
1774 CORINFO_WINNT,
1775 CORINFO_PAL,
1776};
1777
1778struct CORINFO_CPU
1779{
1780 DWORD dwCPUType;
1781 DWORD dwFeatures;
1782 DWORD dwExtendedFeatures;
1783};
1784
1785enum CORINFO_RUNTIME_ABI
1786{
1787 CORINFO_DESKTOP_ABI = 0x100,
1788 CORINFO_CORECLR_ABI = 0x200,
1789 CORINFO_CORERT_ABI = 0x300,
1790};
1791
1792// For some highly optimized paths, the JIT must generate code that directly
1793// manipulates internal EE data structures. The getEEInfo() helper returns
1794// this structure containing the needed offsets and values.
1795struct CORINFO_EE_INFO
1796{
1797 // Information about the InlinedCallFrame structure layout
1798 struct InlinedCallFrameInfo
1799 {
1800 // Size of the Frame structure
1801 unsigned size;
1802
1803 unsigned offsetOfGSCookie;
1804 unsigned offsetOfFrameVptr;
1805 unsigned offsetOfFrameLink;
1806 unsigned offsetOfCallSiteSP;
1807 unsigned offsetOfCalleeSavedFP;
1808 unsigned offsetOfCallTarget;
1809 unsigned offsetOfReturnAddress;
1810 }
1811 inlinedCallFrameInfo;
1812
1813 // Offsets into the Thread structure
1814 unsigned offsetOfThreadFrame; // offset of the current Frame
1815 unsigned offsetOfGCState; // offset of the preemptive/cooperative state of the Thread
1816
1817 // Delegate offsets
1818 unsigned offsetOfDelegateInstance;
1819 unsigned offsetOfDelegateFirstTarget;
1820
1821 // Secure delegate offsets
1822 unsigned offsetOfSecureDelegateIndirectCell;
1823
1824 // Remoting offsets
1825 unsigned offsetOfTransparentProxyRP;
1826 unsigned offsetOfRealProxyServer;
1827
1828 // Array offsets
1829 unsigned offsetOfObjArrayData;
1830
1831 // Reverse PInvoke offsets
1832 unsigned sizeOfReversePInvokeFrame;
1833
1834 // OS Page size
1835 size_t osPageSize;
1836
1837 // Null object offset
1838 size_t maxUncheckedOffsetForNullObject;
1839
1840 // Target ABI. Combined with target architecture and OS to determine
1841 // GC, EH, and unwind styles.
1842 CORINFO_RUNTIME_ABI targetAbi;
1843
1844 CORINFO_OS osType;
1845 unsigned osMajor;
1846 unsigned osMinor;
1847 unsigned osBuild;
1848};
1849
1850// This is used to indicate that a finally has been called
1851// "locally" by the try block
1852enum { LCL_FINALLY_MARK = 0xFC }; // FC = "Finally Call"
1853
1854/**********************************************************************************
1855 * The following is the internal structure of an object that the compiler knows about
1856 * when it generates code
1857 **********************************************************************************/
1858
1859#include <pshpack4.h>
1860
1861typedef void* CORINFO_MethodPtr; // a generic method pointer
1862
1863struct CORINFO_Object
1864{
1865 CORINFO_MethodPtr *methTable; // the vtable for the object
1866};
1867
1868struct CORINFO_String : public CORINFO_Object
1869{
1870 unsigned stringLen;
1871 wchar_t chars[1]; // actually of variable size
1872};
1873
1874struct CORINFO_Array : public CORINFO_Object
1875{
1876 unsigned length;
1877#ifdef _WIN64
1878 unsigned alignpad;
1879#endif // _WIN64
1880
1881#if 0
1882 /* Multi-dimensional arrays have the lengths and bounds here */
1883 unsigned dimLength[length];
1884 unsigned dimBound[length];
1885#endif
1886
1887 union
1888 {
1889 __int8 i1Elems[1]; // actually of variable size
1890 unsigned __int8 u1Elems[1];
1891 __int16 i2Elems[1];
1892 unsigned __int16 u2Elems[1];
1893 __int32 i4Elems[1];
1894 unsigned __int32 u4Elems[1];
1895 float r4Elems[1];
1896 };
1897};
1898
1899#include <pshpack4.h>
1900struct CORINFO_Array8 : public CORINFO_Object
1901{
1902 unsigned length;
1903#ifdef _WIN64
1904 unsigned alignpad;
1905#endif // _WIN64
1906
1907 union
1908 {
1909 double r8Elems[1];
1910 __int64 i8Elems[1];
1911 unsigned __int64 u8Elems[1];
1912 };
1913};
1914
1915#include <poppack.h>
1916
1917struct CORINFO_RefArray : public CORINFO_Object
1918{
1919 unsigned length;
1920#ifdef _WIN64
1921 unsigned alignpad;
1922#endif // _WIN64
1923
1924#if 0
1925 /* Multi-dimensional arrays have the lengths and bounds here */
1926 unsigned dimLength[length];
1927 unsigned dimBound[length];
1928#endif
1929
1930 CORINFO_Object* refElems[1]; // actually of variable size;
1931};
1932
1933struct CORINFO_RefAny
1934{
1935 void * dataPtr;
1936 CORINFO_CLASS_HANDLE type;
1937};
1938
1939// The jit assumes the CORINFO_VARARGS_HANDLE is a pointer to a subclass of this
1940struct CORINFO_VarArgInfo
1941{
1942 unsigned argBytes; // number of bytes the arguments take up.
1943 // (The CORINFO_VARARGS_HANDLE counts as an arg)
1944};
1945
1946#include <poppack.h>
1947
1948#define SIZEOF__CORINFO_Object TARGET_POINTER_SIZE /* methTable */
1949
1950#define OFFSETOF__CORINFO_Array__length SIZEOF__CORINFO_Object
1951#ifdef _TARGET_64BIT_
1952#define OFFSETOF__CORINFO_Array__data (OFFSETOF__CORINFO_Array__length + sizeof(unsigned __int32) /* length */ + sizeof(unsigned __int32) /* alignpad */)
1953#else
1954#define OFFSETOF__CORINFO_Array__data (OFFSETOF__CORINFO_Array__length + sizeof(unsigned __int32) /* length */)
1955#endif
1956
1957#define OFFSETOF__CORINFO_TypedReference__dataPtr 0
1958#define OFFSETOF__CORINFO_TypedReference__type (OFFSETOF__CORINFO_TypedReference__dataPtr + TARGET_POINTER_SIZE /* dataPtr */)
1959
1960#define OFFSETOF__CORINFO_String__stringLen SIZEOF__CORINFO_Object
1961#define OFFSETOF__CORINFO_String__chars (OFFSETOF__CORINFO_String__stringLen + sizeof(unsigned __int32) /* stringLen */)
1962
1963enum CorInfoSecurityRuntimeChecks
1964{
1965 CORINFO_ACCESS_SECURITY_NONE = 0,
1966 CORINFO_ACCESS_SECURITY_TRANSPARENCY = 0x0001 // check that transparency rules are enforced between the caller and callee
1967};
1968
1969
1970/* data to optimize delegate construction */
1971struct DelegateCtorArgs
1972{
1973 void * pMethod;
1974 void * pArg3;
1975 void * pArg4;
1976 void * pArg5;
1977};
1978
1979// use offsetof to get the offset of the fields above
1980#include <stddef.h> // offsetof
1981
1982// Guard-stack cookie for preventing against stack buffer overruns
1983typedef SIZE_T GSCookie;
1984
1985#include "cordebuginfo.h"
1986
1987/**********************************************************************************/
1988// Some compilers cannot arbitrarily allow the handler nesting level to grow
1989// arbitrarily during Edit'n'Continue.
1990// This is the maximum nesting level that a compiler needs to support for EnC
1991
1992const int MAX_EnC_HANDLER_NESTING_LEVEL = 6;
1993
1994// Results from type comparison queries
1995enum class TypeCompareState
1996{
1997 MustNot = -1, // types are not equal
1998 May = 0, // types may be equal (must test at runtime)
1999 Must = 1, // type are equal
2000};
2001
2002//
2003// This interface is logically split into sections for each class of information
2004// (ICorMethodInfo, ICorModuleInfo, etc.). This split used to exist physically as well
2005// using virtual inheritance, but was eliminated to improve efficiency of the JIT-EE
2006// interface calls.
2007//
2008class ICorStaticInfo
2009{
2010public:
2011 /**********************************************************************************/
2012 //
2013 // ICorMethodInfo
2014 //
2015 /**********************************************************************************/
2016
2017 // return flags (defined above, CORINFO_FLG_PUBLIC ...)
2018 virtual DWORD getMethodAttribs (
2019 CORINFO_METHOD_HANDLE ftn /* IN */
2020 ) = 0;
2021
2022 // sets private JIT flags, which can be, retrieved using getAttrib.
2023 virtual void setMethodAttribs (
2024 CORINFO_METHOD_HANDLE ftn, /* IN */
2025 CorInfoMethodRuntimeFlags attribs /* IN */
2026 ) = 0;
2027
2028 // Given a method descriptor ftnHnd, extract signature information into sigInfo
2029 //
2030 // 'memberParent' is typically only set when verifying. It should be the
2031 // result of calling getMemberParent.
2032 virtual void getMethodSig (
2033 CORINFO_METHOD_HANDLE ftn, /* IN */
2034 CORINFO_SIG_INFO *sig, /* OUT */
2035 CORINFO_CLASS_HANDLE memberParent = NULL /* IN */
2036 ) = 0;
2037
2038 /*********************************************************************
2039 * Note the following methods can only be used on functions known
2040 * to be IL. This includes the method being compiled and any method
2041 * that 'getMethodInfo' returns true for
2042 *********************************************************************/
2043
2044 // return information about a method private to the implementation
2045 // returns false if method is not IL, or is otherwise unavailable.
2046 // This method is used to fetch data needed to inline functions
2047 virtual bool getMethodInfo (
2048 CORINFO_METHOD_HANDLE ftn, /* IN */
2049 CORINFO_METHOD_INFO* info /* OUT */
2050 ) = 0;
2051
2052 // Decides if you have any limitations for inlining. If everything's OK, it will return
2053 // INLINE_PASS and will fill out pRestrictions with a mask of restrictions the caller of this
2054 // function must respect. If caller passes pRestrictions = NULL, if there are any restrictions
2055 // INLINE_FAIL will be returned
2056 //
2057 // The callerHnd must be the immediate caller (i.e. when we have a chain of inlined calls)
2058 //
2059 // The inlined method need not be verified
2060
2061 virtual CorInfoInline canInline (
2062 CORINFO_METHOD_HANDLE callerHnd, /* IN */
2063 CORINFO_METHOD_HANDLE calleeHnd, /* IN */
2064 DWORD* pRestrictions /* OUT */
2065 ) = 0;
2066
2067 // Reports whether or not a method can be inlined, and why. canInline is responsible for reporting all
2068 // inlining results when it returns INLINE_FAIL and INLINE_NEVER. All other results are reported by the
2069 // JIT.
2070 virtual void reportInliningDecision (CORINFO_METHOD_HANDLE inlinerHnd,
2071 CORINFO_METHOD_HANDLE inlineeHnd,
2072 CorInfoInline inlineResult,
2073 const char * reason) = 0;
2074
2075
2076 // Returns false if the call is across security boundaries thus we cannot tailcall
2077 //
2078 // The callerHnd must be the immediate caller (i.e. when we have a chain of inlined calls)
2079 virtual bool canTailCall (
2080 CORINFO_METHOD_HANDLE callerHnd, /* IN */
2081 CORINFO_METHOD_HANDLE declaredCalleeHnd, /* IN */
2082 CORINFO_METHOD_HANDLE exactCalleeHnd, /* IN */
2083 bool fIsTailPrefix /* IN */
2084 ) = 0;
2085
2086 // Reports whether or not a method can be tail called, and why.
2087 // canTailCall is responsible for reporting all results when it returns
2088 // false. All other results are reported by the JIT.
2089 virtual void reportTailCallDecision (CORINFO_METHOD_HANDLE callerHnd,
2090 CORINFO_METHOD_HANDLE calleeHnd,
2091 bool fIsTailPrefix,
2092 CorInfoTailCall tailCallResult,
2093 const char * reason) = 0;
2094
2095 // get individual exception handler
2096 virtual void getEHinfo(
2097 CORINFO_METHOD_HANDLE ftn, /* IN */
2098 unsigned EHnumber, /* IN */
2099 CORINFO_EH_CLAUSE* clause /* OUT */
2100 ) = 0;
2101
2102 // return class it belongs to
2103 virtual CORINFO_CLASS_HANDLE getMethodClass (
2104 CORINFO_METHOD_HANDLE method
2105 ) = 0;
2106
2107 // return module it belongs to
2108 virtual CORINFO_MODULE_HANDLE getMethodModule (
2109 CORINFO_METHOD_HANDLE method
2110 ) = 0;
2111
2112 // This function returns the offset of the specified method in the
2113 // vtable of it's owning class or interface.
2114 virtual void getMethodVTableOffset (
2115 CORINFO_METHOD_HANDLE method, /* IN */
2116 unsigned* offsetOfIndirection, /* OUT */
2117 unsigned* offsetAfterIndirection, /* OUT */
2118 bool* isRelative /* OUT */
2119 ) = 0;
2120
2121 // Find the virtual method in implementingClass that overrides virtualMethod,
2122 // or the method in implementingClass that implements the interface method
2123 // represented by virtualMethod.
2124 //
2125 // Return null if devirtualization is not possible. Owner type is optional
2126 // and provides additional context for shared interface devirtualization.
2127 virtual CORINFO_METHOD_HANDLE resolveVirtualMethod(
2128 CORINFO_METHOD_HANDLE virtualMethod, /* IN */
2129 CORINFO_CLASS_HANDLE implementingClass, /* IN */
2130 CORINFO_CONTEXT_HANDLE ownerType = NULL /* IN */
2131 ) = 0;
2132
2133 // Get the unboxed entry point for a method, if possible.
2134 virtual CORINFO_METHOD_HANDLE getUnboxedEntry(
2135 CORINFO_METHOD_HANDLE ftn,
2136 bool* requiresInstMethodTableArg = NULL /* OUT */
2137 ) = 0;
2138
2139 // Given T, return the type of the default EqualityComparer<T>.
2140 // Returns null if the type can't be determined exactly.
2141 virtual CORINFO_CLASS_HANDLE getDefaultEqualityComparerClass(
2142 CORINFO_CLASS_HANDLE elemType
2143 ) = 0;
2144
2145 // Given resolved token that corresponds to an intrinsic classified as
2146 // a CORINFO_INTRINSIC_GetRawHandle intrinsic, fetch the handle associated
2147 // with the token. If this is not possible at compile-time (because the current method's
2148 // code is shared and the token contains generic parameters) then indicate
2149 // how the handle should be looked up at runtime.
2150 virtual void expandRawHandleIntrinsic(
2151 CORINFO_RESOLVED_TOKEN * pResolvedToken,
2152 CORINFO_GENERICHANDLE_RESULT * pResult) = 0;
2153
2154 // If a method's attributes have (getMethodAttribs) CORINFO_FLG_INTRINSIC set,
2155 // getIntrinsicID() returns the intrinsic ID.
2156 // *pMustExpand tells whether or not JIT must expand the intrinsic.
2157 virtual CorInfoIntrinsics getIntrinsicID(
2158 CORINFO_METHOD_HANDLE method,
2159 bool* pMustExpand = NULL /* OUT */
2160 ) = 0;
2161
2162 // Is the given module the System.Numerics.Vectors module?
2163 // This defaults to false.
2164 virtual bool isInSIMDModule(
2165 CORINFO_CLASS_HANDLE classHnd
2166 ) { return false; }
2167
2168 // return the unmanaged calling convention for a PInvoke
2169 virtual CorInfoUnmanagedCallConv getUnmanagedCallConv(
2170 CORINFO_METHOD_HANDLE method
2171 ) = 0;
2172
2173 // return if any marshaling is required for PInvoke methods. Note that
2174 // method == 0 => calli. The call site sig is only needed for the varargs or calli case
2175 virtual BOOL pInvokeMarshalingRequired(
2176 CORINFO_METHOD_HANDLE method,
2177 CORINFO_SIG_INFO* callSiteSig
2178 ) = 0;
2179
2180 // Check constraints on method type arguments (only).
2181 // The parent class should be checked separately using satisfiesClassConstraints(parent).
2182 virtual BOOL satisfiesMethodConstraints(
2183 CORINFO_CLASS_HANDLE parent, // the exact parent of the method
2184 CORINFO_METHOD_HANDLE method
2185 ) = 0;
2186
2187 // Given a delegate target class, a target method parent class, a target method,
2188 // a delegate class, check if the method signature is compatible with the Invoke method of the delegate
2189 // (under the typical instantiation of any free type variables in the memberref signatures).
2190 virtual BOOL isCompatibleDelegate(
2191 CORINFO_CLASS_HANDLE objCls, /* type of the delegate target, if any */
2192 CORINFO_CLASS_HANDLE methodParentCls, /* exact parent of the target method, if any */
2193 CORINFO_METHOD_HANDLE method, /* (representative) target method, if any */
2194 CORINFO_CLASS_HANDLE delegateCls, /* exact type of the delegate */
2195 BOOL *pfIsOpenDelegate /* is the delegate open */
2196 ) = 0;
2197
2198 // Indicates if the method is an instance of the generic
2199 // method that passes (or has passed) verification
2200 virtual CorInfoInstantiationVerification isInstantiationOfVerifiedGeneric (
2201 CORINFO_METHOD_HANDLE method /* IN */
2202 ) = 0;
2203
2204 // Loads the constraints on a typical method definition, detecting cycles;
2205 // for use in verification.
2206 virtual void initConstraintsForVerification(
2207 CORINFO_METHOD_HANDLE method, /* IN */
2208 BOOL *pfHasCircularClassConstraints, /* OUT */
2209 BOOL *pfHasCircularMethodConstraint /* OUT */
2210 ) = 0;
2211
2212 // Returns enum whether the method does not require verification
2213 // Also see ICorModuleInfo::canSkipVerification
2214 virtual CorInfoCanSkipVerificationResult canSkipMethodVerification (
2215 CORINFO_METHOD_HANDLE ftnHandle
2216 ) = 0;
2217
2218 // load and restore the method
2219 virtual void methodMustBeLoadedBeforeCodeIsRun(
2220 CORINFO_METHOD_HANDLE method
2221 ) = 0;
2222
2223 virtual CORINFO_METHOD_HANDLE mapMethodDeclToMethodImpl(
2224 CORINFO_METHOD_HANDLE method
2225 ) = 0;
2226
2227 // Returns the global cookie for the /GS unsafe buffer checks
2228 // The cookie might be a constant value (JIT), or a handle to memory location (Ngen)
2229 virtual void getGSCookie(
2230 GSCookie * pCookieVal, // OUT
2231 GSCookie ** ppCookieVal // OUT
2232 ) = 0;
2233
2234 /**********************************************************************************/
2235 //
2236 // ICorModuleInfo
2237 //
2238 /**********************************************************************************/
2239
2240 // Resolve metadata token into runtime method handles. This function may not
2241 // return normally (e.g. it may throw) if it encounters invalid metadata or other
2242 // failures during token resolution.
2243 virtual void resolveToken(/* IN, OUT */ CORINFO_RESOLVED_TOKEN * pResolvedToken) = 0;
2244
2245 // Attempt to resolve a metadata token into a runtime method handle. Returns true
2246 // if resolution succeeded and false otherwise (e.g. if it encounters invalid metadata
2247 // during token reoslution). This method should be used instead of `resolveToken` in
2248 // situations that need to be resilient to invalid metadata.
2249 virtual bool tryResolveToken(/* IN, OUT */ CORINFO_RESOLVED_TOKEN * pResolvedToken) = 0;
2250
2251 // Signature information about the call sig
2252 virtual void findSig (
2253 CORINFO_MODULE_HANDLE module, /* IN */
2254 unsigned sigTOK, /* IN */
2255 CORINFO_CONTEXT_HANDLE context, /* IN */
2256 CORINFO_SIG_INFO *sig /* OUT */
2257 ) = 0;
2258
2259 // for Varargs, the signature at the call site may differ from
2260 // the signature at the definition. Thus we need a way of
2261 // fetching the call site information
2262 virtual void findCallSiteSig (
2263 CORINFO_MODULE_HANDLE module, /* IN */
2264 unsigned methTOK, /* IN */
2265 CORINFO_CONTEXT_HANDLE context, /* IN */
2266 CORINFO_SIG_INFO *sig /* OUT */
2267 ) = 0;
2268
2269 virtual CORINFO_CLASS_HANDLE getTokenTypeAsHandle (
2270 CORINFO_RESOLVED_TOKEN * pResolvedToken /* IN */) = 0;
2271
2272 // Returns true if the module does not require verification
2273 //
2274 // If fQuickCheckOnlyWithoutCommit=TRUE, the function only checks that the
2275 // module does not currently require verification in the current AppDomain.
2276 // This decision could change in the future, and so should not be cached.
2277 // If it is cached, it should only be used as a hint.
2278 // This is only used by ngen for calculating certain hints.
2279 //
2280
2281 // Returns enum whether the module does not require verification
2282 // Also see ICorMethodInfo::canSkipMethodVerification();
2283 virtual CorInfoCanSkipVerificationResult canSkipVerification (
2284 CORINFO_MODULE_HANDLE module /* IN */
2285 ) = 0;
2286
2287 // Checks if the given metadata token is valid
2288 virtual BOOL isValidToken (
2289 CORINFO_MODULE_HANDLE module, /* IN */
2290 unsigned metaTOK /* IN */
2291 ) = 0;
2292
2293 // Checks if the given metadata token is valid StringRef
2294 virtual BOOL isValidStringRef (
2295 CORINFO_MODULE_HANDLE module, /* IN */
2296 unsigned metaTOK /* IN */
2297 ) = 0;
2298
2299 virtual BOOL shouldEnforceCallvirtRestriction(
2300 CORINFO_MODULE_HANDLE scope
2301 ) = 0;
2302
2303 /**********************************************************************************/
2304 //
2305 // ICorClassInfo
2306 //
2307 /**********************************************************************************/
2308
2309 // If the value class 'cls' is isomorphic to a primitive type it will
2310 // return that type, otherwise it will return CORINFO_TYPE_VALUECLASS
2311 virtual CorInfoType asCorInfoType (
2312 CORINFO_CLASS_HANDLE cls
2313 ) = 0;
2314
2315 // for completeness
2316 virtual const char* getClassName (
2317 CORINFO_CLASS_HANDLE cls
2318 ) = 0;
2319
2320 // Return class name as in metadata, or nullptr if there is none.
2321 // Suitable for non-debugging use.
2322 virtual const char* getClassNameFromMetadata (
2323 CORINFO_CLASS_HANDLE cls,
2324 const char **namespaceName /* OUT */
2325 ) = 0;
2326
2327 // Return the type argument of the instantiated generic class,
2328 // which is specified by the index
2329 virtual CORINFO_CLASS_HANDLE getTypeInstantiationArgument(
2330 CORINFO_CLASS_HANDLE cls,
2331 unsigned index
2332 ) = 0;
2333
2334
2335 // Append a (possibly truncated) representation of the type cls to the preallocated buffer ppBuf of length pnBufLen
2336 // If fNamespace=TRUE, include the namespace/enclosing classes
2337 // If fFullInst=TRUE (regardless of fNamespace and fAssembly), include namespace and assembly for any type parameters
2338 // If fAssembly=TRUE, suffix with a comma and the full assembly qualification
2339 // return size of representation
2340 virtual int appendClassName(
2341 __deref_inout_ecount(*pnBufLen) WCHAR** ppBuf,
2342 int* pnBufLen,
2343 CORINFO_CLASS_HANDLE cls,
2344 BOOL fNamespace,
2345 BOOL fFullInst,
2346 BOOL fAssembly
2347 ) = 0;
2348
2349 // Quick check whether the type is a value class. Returns the same value as getClassAttribs(cls) & CORINFO_FLG_VALUECLASS, except faster.
2350 virtual BOOL isValueClass(CORINFO_CLASS_HANDLE cls) = 0;
2351
2352 // Decides how the JIT should do the optimization to inline the check for
2353 // GetTypeFromHandle(handle) == obj.GetType() (for CORINFO_INLINE_TYPECHECK_SOURCE_VTABLE)
2354 // GetTypeFromHandle(X) == GetTypeFromHandle(Y) (for CORINFO_INLINE_TYPECHECK_SOURCE_TOKEN)
2355 virtual CorInfoInlineTypeCheck canInlineTypeCheck(CORINFO_CLASS_HANDLE cls, CorInfoInlineTypeCheckSource source) = 0;
2356
2357 // If this method returns true, JIT will do optimization to inline the check for
2358 // GetTypeFromHandle(handle) == obj.GetType()
2359 virtual BOOL canInlineTypeCheckWithObjectVTable(CORINFO_CLASS_HANDLE cls) = 0;
2360
2361 // return flags (defined above, CORINFO_FLG_PUBLIC ...)
2362 virtual DWORD getClassAttribs (
2363 CORINFO_CLASS_HANDLE cls
2364 ) = 0;
2365
2366 // Returns "TRUE" iff "cls" is a struct type such that return buffers used for returning a value
2367 // of this type must be stack-allocated. This will generally be true only if the struct
2368 // contains GC pointers, and does not exceed some size limit. Maintaining this as an invariant allows
2369 // an optimization: the JIT may assume that return buffer pointers for return types for which this predicate
2370 // returns TRUE are always stack allocated, and thus, that stores to the GC-pointer fields of such return
2371 // buffers do not require GC write barriers.
2372 virtual BOOL isStructRequiringStackAllocRetBuf(CORINFO_CLASS_HANDLE cls) = 0;
2373
2374 virtual CORINFO_MODULE_HANDLE getClassModule (
2375 CORINFO_CLASS_HANDLE cls
2376 ) = 0;
2377
2378 // Returns the assembly that contains the module "mod".
2379 virtual CORINFO_ASSEMBLY_HANDLE getModuleAssembly (
2380 CORINFO_MODULE_HANDLE mod
2381 ) = 0;
2382
2383 // Returns the name of the assembly "assem".
2384 virtual const char* getAssemblyName (
2385 CORINFO_ASSEMBLY_HANDLE assem
2386 ) = 0;
2387
2388 // Allocate and delete process-lifetime objects. Should only be
2389 // referred to from static fields, lest a leak occur.
2390 // Note that "LongLifetimeFree" does not execute destructors, if "obj"
2391 // is an array of a struct type with a destructor.
2392 virtual void* LongLifetimeMalloc(size_t sz) = 0;
2393 virtual void LongLifetimeFree(void* obj) = 0;
2394
2395 virtual size_t getClassModuleIdForStatics (
2396 CORINFO_CLASS_HANDLE cls,
2397 CORINFO_MODULE_HANDLE *pModule,
2398 void **ppIndirection
2399 ) = 0;
2400
2401 // return the number of bytes needed by an instance of the class
2402 virtual unsigned getClassSize (
2403 CORINFO_CLASS_HANDLE cls
2404 ) = 0;
2405
2406 // return the number of bytes needed by an instance of the class allocated on the heap
2407 virtual unsigned getHeapClassSize(
2408 CORINFO_CLASS_HANDLE cls
2409 ) = 0;
2410
2411 virtual BOOL canAllocateOnStack(
2412 CORINFO_CLASS_HANDLE cls
2413 ) = 0;
2414
2415 virtual unsigned getClassAlignmentRequirement (
2416 CORINFO_CLASS_HANDLE cls,
2417 BOOL fDoubleAlignHint = FALSE
2418 ) = 0;
2419
2420 // This is only called for Value classes. It returns a boolean array
2421 // in representing of 'cls' from a GC perspective. The class is
2422 // assumed to be an array of machine words
2423 // (of length // getClassSize(cls) / TARGET_POINTER_SIZE),
2424 // 'gcPtrs' is a pointer to an array of BYTEs of this length.
2425 // getClassGClayout fills in this array so that gcPtrs[i] is set
2426 // to one of the CorInfoGCType values which is the GC type of
2427 // the i-th machine word of an object of type 'cls'
2428 // returns the number of GC pointers in the array
2429 virtual unsigned getClassGClayout (
2430 CORINFO_CLASS_HANDLE cls, /* IN */
2431 BYTE *gcPtrs /* OUT */
2432 ) = 0;
2433
2434 // returns the number of instance fields in a class
2435 virtual unsigned getClassNumInstanceFields (
2436 CORINFO_CLASS_HANDLE cls /* IN */
2437 ) = 0;
2438
2439 virtual CORINFO_FIELD_HANDLE getFieldInClass(
2440 CORINFO_CLASS_HANDLE clsHnd,
2441 INT num
2442 ) = 0;
2443
2444 virtual BOOL checkMethodModifier(
2445 CORINFO_METHOD_HANDLE hMethod,
2446 LPCSTR modifier,
2447 BOOL fOptional
2448 ) = 0;
2449
2450 // returns the "NEW" helper optimized for "newCls."
2451 virtual CorInfoHelpFunc getNewHelper(
2452 CORINFO_RESOLVED_TOKEN * pResolvedToken,
2453 CORINFO_METHOD_HANDLE callerHandle,
2454 bool * pHasSideEffects = NULL /* OUT */
2455 ) = 0;
2456
2457 // returns the newArr (1-Dim array) helper optimized for "arrayCls."
2458 virtual CorInfoHelpFunc getNewArrHelper(
2459 CORINFO_CLASS_HANDLE arrayCls
2460 ) = 0;
2461
2462 // returns the optimized "IsInstanceOf" or "ChkCast" helper
2463 virtual CorInfoHelpFunc getCastingHelper(
2464 CORINFO_RESOLVED_TOKEN * pResolvedToken,
2465 bool fThrowing
2466 ) = 0;
2467
2468 // returns helper to trigger static constructor
2469 virtual CorInfoHelpFunc getSharedCCtorHelper(
2470 CORINFO_CLASS_HANDLE clsHnd
2471 ) = 0;
2472
2473 virtual CorInfoHelpFunc getSecurityPrologHelper(
2474 CORINFO_METHOD_HANDLE ftn
2475 ) = 0;
2476
2477 // This is not pretty. Boxing nullable<T> actually returns
2478 // a boxed<T> not a boxed Nullable<T>. This call allows the verifier
2479 // to call back to the EE on the 'box' instruction and get the transformed
2480 // type to use for verification.
2481 virtual CORINFO_CLASS_HANDLE getTypeForBox(
2482 CORINFO_CLASS_HANDLE cls
2483 ) = 0;
2484
2485 // returns the correct box helper for a particular class. Note
2486 // that if this returns CORINFO_HELP_BOX, the JIT can assume
2487 // 'standard' boxing (allocate object and copy), and optimize
2488 virtual CorInfoHelpFunc getBoxHelper(
2489 CORINFO_CLASS_HANDLE cls
2490 ) = 0;
2491
2492 // returns the unbox helper. If 'helperCopies' points to a true
2493 // value it means the JIT is requesting a helper that unboxes the
2494 // value into a particular location and thus has the signature
2495 // void unboxHelper(void* dest, CORINFO_CLASS_HANDLE cls, Object* obj)
2496 // Otherwise (it is null or points at a FALSE value) it is requesting
2497 // a helper that returns a pointer to the unboxed data
2498 // void* unboxHelper(CORINFO_CLASS_HANDLE cls, Object* obj)
2499 // The EE has the option of NOT returning the copy style helper
2500 // (But must be able to always honor the non-copy style helper)
2501 // The EE set 'helperCopies' on return to indicate what kind of
2502 // helper has been created.
2503
2504 virtual CorInfoHelpFunc getUnBoxHelper(
2505 CORINFO_CLASS_HANDLE cls
2506 ) = 0;
2507
2508 virtual bool getReadyToRunHelper(
2509 CORINFO_RESOLVED_TOKEN * pResolvedToken,
2510 CORINFO_LOOKUP_KIND * pGenericLookupKind,
2511 CorInfoHelpFunc id,
2512 CORINFO_CONST_LOOKUP * pLookup
2513 ) = 0;
2514
2515 virtual void getReadyToRunDelegateCtorHelper(
2516 CORINFO_RESOLVED_TOKEN * pTargetMethod,
2517 CORINFO_CLASS_HANDLE delegateType,
2518 CORINFO_LOOKUP * pLookup
2519 ) = 0;
2520
2521 virtual const char* getHelperName(
2522 CorInfoHelpFunc
2523 ) = 0;
2524
2525 // This function tries to initialize the class (run the class constructor).
2526 // this function returns whether the JIT must insert helper calls before
2527 // accessing static field or method.
2528 //
2529 // See code:ICorClassInfo#ClassConstruction.
2530 virtual CorInfoInitClassResult initClass(
2531 CORINFO_FIELD_HANDLE field, // Non-NULL - inquire about cctor trigger before static field access
2532 // NULL - inquire about cctor trigger in method prolog
2533 CORINFO_METHOD_HANDLE method, // Method referencing the field or prolog
2534 CORINFO_CONTEXT_HANDLE context, // Exact context of method
2535 BOOL speculative = FALSE // TRUE means don't actually run it
2536 ) = 0;
2537
2538 // This used to be called "loadClass". This records the fact
2539 // that the class must be loaded (including restored if necessary) before we execute the
2540 // code that we are currently generating. When jitting code
2541 // the function loads the class immediately. When zapping code
2542 // the zapper will if necessary use the call to record the fact that we have
2543 // to do a fixup/restore before running the method currently being generated.
2544 //
2545 // This is typically used to ensure value types are loaded before zapped
2546 // code that manipulates them is executed, so that the GC can access information
2547 // about those value types.
2548 virtual void classMustBeLoadedBeforeCodeIsRun(
2549 CORINFO_CLASS_HANDLE cls
2550 ) = 0;
2551
2552 // returns the class handle for the special builtin classes
2553 virtual CORINFO_CLASS_HANDLE getBuiltinClass (
2554 CorInfoClassId classId
2555 ) = 0;
2556
2557 // "System.Int32" ==> CORINFO_TYPE_INT..
2558 virtual CorInfoType getTypeForPrimitiveValueClass(
2559 CORINFO_CLASS_HANDLE cls
2560 ) = 0;
2561
2562 // "System.Int32" ==> CORINFO_TYPE_INT..
2563 // "System.UInt32" ==> CORINFO_TYPE_UINT..
2564 virtual CorInfoType getTypeForPrimitiveNumericClass(
2565 CORINFO_CLASS_HANDLE cls
2566 ) = 0;
2567
2568 // TRUE if child is a subtype of parent
2569 // if parent is an interface, then does child implement / extend parent
2570 virtual BOOL canCast(
2571 CORINFO_CLASS_HANDLE child, // subtype (extends parent)
2572 CORINFO_CLASS_HANDLE parent // base type
2573 ) = 0;
2574
2575 // TRUE if cls1 and cls2 are considered equivalent types.
2576 virtual BOOL areTypesEquivalent(
2577 CORINFO_CLASS_HANDLE cls1,
2578 CORINFO_CLASS_HANDLE cls2
2579 ) = 0;
2580
2581 // See if a cast from fromClass to toClass will succeed, fail, or needs
2582 // to be resolved at runtime.
2583 virtual TypeCompareState compareTypesForCast(
2584 CORINFO_CLASS_HANDLE fromClass,
2585 CORINFO_CLASS_HANDLE toClass
2586 ) = 0;
2587
2588 // See if types represented by cls1 and cls2 compare equal, not
2589 // equal, or the comparison needs to be resolved at runtime.
2590 virtual TypeCompareState compareTypesForEquality(
2591 CORINFO_CLASS_HANDLE cls1,
2592 CORINFO_CLASS_HANDLE cls2
2593 ) = 0;
2594
2595 // returns is the intersection of cls1 and cls2.
2596 virtual CORINFO_CLASS_HANDLE mergeClasses(
2597 CORINFO_CLASS_HANDLE cls1,
2598 CORINFO_CLASS_HANDLE cls2
2599 ) = 0;
2600
2601 // Given a class handle, returns the Parent type.
2602 // For COMObjectType, it returns Class Handle of System.Object.
2603 // Returns 0 if System.Object is passed in.
2604 virtual CORINFO_CLASS_HANDLE getParentType (
2605 CORINFO_CLASS_HANDLE cls
2606 ) = 0;
2607
2608 // Returns the CorInfoType of the "child type". If the child type is
2609 // not a primitive type, *clsRet will be set.
2610 // Given an Array of Type Foo, returns Foo.
2611 // Given BYREF Foo, returns Foo
2612 virtual CorInfoType getChildType (
2613 CORINFO_CLASS_HANDLE clsHnd,
2614 CORINFO_CLASS_HANDLE *clsRet
2615 ) = 0;
2616
2617 // Check constraints on type arguments of this class and parent classes
2618 virtual BOOL satisfiesClassConstraints(
2619 CORINFO_CLASS_HANDLE cls
2620 ) = 0;
2621
2622 // Check if this is a single dimensional array type
2623 virtual BOOL isSDArray(
2624 CORINFO_CLASS_HANDLE cls
2625 ) = 0;
2626
2627 // Get the numbmer of dimensions in an array
2628 virtual unsigned getArrayRank(
2629 CORINFO_CLASS_HANDLE cls
2630 ) = 0;
2631
2632 // Get static field data for an array
2633 virtual void * getArrayInitializationData(
2634 CORINFO_FIELD_HANDLE field,
2635 DWORD size
2636 ) = 0;
2637
2638 // Check Visibility rules.
2639 virtual CorInfoIsAccessAllowedResult canAccessClass(
2640 CORINFO_RESOLVED_TOKEN * pResolvedToken,
2641 CORINFO_METHOD_HANDLE callerHandle,
2642 CORINFO_HELPER_DESC *pAccessHelper /* If canAccessMethod returns something other
2643 than ALLOWED, then this is filled in. */
2644 ) = 0;
2645
2646 /**********************************************************************************/
2647 //
2648 // ICorFieldInfo
2649 //
2650 /**********************************************************************************/
2651
2652 // this function is for debugging only. It returns the field name
2653 // and if 'moduleName' is non-null, it sets it to something that will
2654 // says which method (a class name, or a module name)
2655 virtual const char* getFieldName (
2656 CORINFO_FIELD_HANDLE ftn, /* IN */
2657 const char **moduleName /* OUT */
2658 ) = 0;
2659
2660 // return class it belongs to
2661 virtual CORINFO_CLASS_HANDLE getFieldClass (
2662 CORINFO_FIELD_HANDLE field
2663 ) = 0;
2664
2665 // Return the field's type, if it is CORINFO_TYPE_VALUECLASS 'structType' is set
2666 // the field's value class (if 'structType' == 0, then don't bother
2667 // the structure info).
2668 //
2669 // 'memberParent' is typically only set when verifying. It should be the
2670 // result of calling getMemberParent.
2671 virtual CorInfoType getFieldType(
2672 CORINFO_FIELD_HANDLE field,
2673 CORINFO_CLASS_HANDLE *structType = NULL,
2674 CORINFO_CLASS_HANDLE memberParent = NULL /* IN */
2675 ) = 0;
2676
2677 // return the data member's instance offset
2678 virtual unsigned getFieldOffset(
2679 CORINFO_FIELD_HANDLE field
2680 ) = 0;
2681
2682 // TODO: jit64 should be switched to the same plan as the i386 jits - use
2683 // getClassGClayout to figure out the need for writebarrier helper, and inline the copying.
2684 // The interpretted value class copy is slow. Once this happens, USE_WRITE_BARRIER_HELPERS
2685 virtual bool isWriteBarrierHelperRequired(
2686 CORINFO_FIELD_HANDLE field) = 0;
2687
2688 virtual void getFieldInfo (CORINFO_RESOLVED_TOKEN * pResolvedToken,
2689 CORINFO_METHOD_HANDLE callerHandle,
2690 CORINFO_ACCESS_FLAGS flags,
2691 CORINFO_FIELD_INFO *pResult
2692 ) = 0;
2693
2694 // Returns true iff "fldHnd" represents a static field.
2695 virtual bool isFieldStatic(CORINFO_FIELD_HANDLE fldHnd) = 0;
2696
2697 /*********************************************************************************/
2698 //
2699 // ICorDebugInfo
2700 //
2701 /*********************************************************************************/
2702
2703 // Query the EE to find out where interesting break points
2704 // in the code are. The native compiler will ensure that these places
2705 // have a corresponding break point in native code.
2706 //
2707 // Note that unless CORJIT_FLAG_DEBUG_CODE is specified, this function will
2708 // be used only as a hint and the native compiler should not change its
2709 // code generation.
2710 virtual void getBoundaries(
2711 CORINFO_METHOD_HANDLE ftn, // [IN] method of interest
2712 unsigned int *cILOffsets, // [OUT] size of pILOffsets
2713 DWORD **pILOffsets, // [OUT] IL offsets of interest
2714 // jit MUST free with freeArray!
2715 ICorDebugInfo::BoundaryTypes *implictBoundaries // [OUT] tell jit, all boundries of this type
2716 ) = 0;
2717
2718 // Report back the mapping from IL to native code,
2719 // this map should include all boundaries that 'getBoundaries'
2720 // reported as interesting to the debugger.
2721
2722 // Note that debugger (and profiler) is assuming that all of the
2723 // offsets form a contiguous block of memory, and that the
2724 // OffsetMapping is sorted in order of increasing native offset.
2725 virtual void setBoundaries(
2726 CORINFO_METHOD_HANDLE ftn, // [IN] method of interest
2727 ULONG32 cMap, // [IN] size of pMap
2728 ICorDebugInfo::OffsetMapping *pMap // [IN] map including all points of interest.
2729 // jit allocated with allocateArray, EE frees
2730 ) = 0;
2731
2732 // Query the EE to find out the scope of local varables.
2733 // normally the JIT would trash variables after last use, but
2734 // under debugging, the JIT needs to keep them live over their
2735 // entire scope so that they can be inspected.
2736 //
2737 // Note that unless CORJIT_FLAG_DEBUG_CODE is specified, this function will
2738 // be used only as a hint and the native compiler should not change its
2739 // code generation.
2740 virtual void getVars(
2741 CORINFO_METHOD_HANDLE ftn, // [IN] method of interest
2742 ULONG32 *cVars, // [OUT] size of 'vars'
2743 ICorDebugInfo::ILVarInfo **vars, // [OUT] scopes of variables of interest
2744 // jit MUST free with freeArray!
2745 bool *extendOthers // [OUT] it TRUE, then assume the scope
2746 // of unmentioned vars is entire method
2747 ) = 0;
2748
2749 // Report back to the EE the location of every variable.
2750 // note that the JIT might split lifetimes into different
2751 // locations etc.
2752
2753 virtual void setVars(
2754 CORINFO_METHOD_HANDLE ftn, // [IN] method of interest
2755 ULONG32 cVars, // [IN] size of 'vars'
2756 ICorDebugInfo::NativeVarInfo *vars // [IN] map telling where local vars are stored at what points
2757 // jit allocated with allocateArray, EE frees
2758 ) = 0;
2759
2760 /*-------------------------- Misc ---------------------------------------*/
2761
2762 // Used to allocate memory that needs to handed to the EE.
2763 // For eg, use this to allocated memory for reporting debug info,
2764 // which will be handed to the EE by setVars() and setBoundaries()
2765 virtual void * allocateArray(
2766 ULONG cBytes
2767 ) = 0;
2768
2769 // JitCompiler will free arrays passed by the EE using this
2770 // For eg, The EE returns memory in getVars() and getBoundaries()
2771 // to the JitCompiler, which the JitCompiler should release using
2772 // freeArray()
2773 virtual void freeArray(
2774 void *array
2775 ) = 0;
2776
2777 /*********************************************************************************/
2778 //
2779 // ICorArgInfo
2780 //
2781 /*********************************************************************************/
2782
2783 // advance the pointer to the argument list.
2784 // a ptr of 0, is special and always means the first argument
2785 virtual CORINFO_ARG_LIST_HANDLE getArgNext (
2786 CORINFO_ARG_LIST_HANDLE args /* IN */
2787 ) = 0;
2788
2789 // Get the type of a particular argument
2790 // CORINFO_TYPE_UNDEF is returned when there are no more arguments
2791 // If the type returned is a primitive type (or an enum) *vcTypeRet set to NULL
2792 // otherwise it is set to the TypeHandle associted with the type
2793 // Enumerations will always look their underlying type (probably should fix this)
2794 // Otherwise vcTypeRet is the type as would be seen by the IL,
2795 // The return value is the type that is used for calling convention purposes
2796 // (Thus if the EE wants a value class to be passed like an int, then it will
2797 // return CORINFO_TYPE_INT
2798 virtual CorInfoTypeWithMod getArgType (
2799 CORINFO_SIG_INFO* sig, /* IN */
2800 CORINFO_ARG_LIST_HANDLE args, /* IN */
2801 CORINFO_CLASS_HANDLE *vcTypeRet /* OUT */
2802 ) = 0;
2803
2804 // If the Arg is a CORINFO_TYPE_CLASS fetch the class handle associated with it
2805 virtual CORINFO_CLASS_HANDLE getArgClass (
2806 CORINFO_SIG_INFO* sig, /* IN */
2807 CORINFO_ARG_LIST_HANDLE args /* IN */
2808 ) = 0;
2809
2810 // Returns type of HFA for valuetype
2811 virtual CorInfoType getHFAType (
2812 CORINFO_CLASS_HANDLE hClass
2813 ) = 0;
2814
2815 /*****************************************************************************
2816 * ICorErrorInfo contains methods to deal with SEH exceptions being thrown
2817 * from the corinfo interface. These methods may be called when an exception
2818 * with code EXCEPTION_COMPLUS is caught.
2819 *****************************************************************************/
2820
2821 // Returns the HRESULT of the current exception
2822 virtual HRESULT GetErrorHRESULT(
2823 struct _EXCEPTION_POINTERS *pExceptionPointers
2824 ) = 0;
2825
2826 // Fetches the message of the current exception
2827 // Returns the size of the message (including terminating null). This can be
2828 // greater than bufferLength if the buffer is insufficient.
2829 virtual ULONG GetErrorMessage(
2830 __inout_ecount(bufferLength) LPWSTR buffer,
2831 ULONG bufferLength
2832 ) = 0;
2833
2834 // returns EXCEPTION_EXECUTE_HANDLER if it is OK for the compile to handle the
2835 // exception, abort some work (like the inlining) and continue compilation
2836 // returns EXCEPTION_CONTINUE_SEARCH if exception must always be handled by the EE
2837 // things like ThreadStoppedException ...
2838 // returns EXCEPTION_CONTINUE_EXECUTION if exception is fixed up by the EE
2839
2840 virtual int FilterException(
2841 struct _EXCEPTION_POINTERS *pExceptionPointers
2842 ) = 0;
2843
2844 // Cleans up internal EE tracking when an exception is caught.
2845 virtual void HandleException(
2846 struct _EXCEPTION_POINTERS *pExceptionPointers
2847 ) = 0;
2848
2849 virtual void ThrowExceptionForJitResult(
2850 HRESULT result) = 0;
2851
2852 //Throws an exception defined by the given throw helper.
2853 virtual void ThrowExceptionForHelper(
2854 const CORINFO_HELPER_DESC * throwHelper) = 0;
2855
2856 // Runs the given function under an error trap. This allows the JIT to make calls
2857 // to interface functions that may throw exceptions without needing to be aware of
2858 // the EH ABI, exception types, etc. Returns true if the given function completed
2859 // successfully and false otherwise.
2860 virtual bool runWithErrorTrap(
2861 void (*function)(void*), // The function to run
2862 void* parameter // The context parameter that will be passed to the function and the handler
2863 ) = 0;
2864
2865/*****************************************************************************
2866 * ICorStaticInfo contains EE interface methods which return values that are
2867 * constant from invocation to invocation. Thus they may be embedded in
2868 * persisted information like statically generated code. (This is of course
2869 * assuming that all code versions are identical each time.)
2870 *****************************************************************************/
2871
2872 // Return details about EE internal data structures
2873 virtual void getEEInfo(
2874 CORINFO_EE_INFO *pEEInfoOut
2875 ) = 0;
2876
2877 // Returns name of the JIT timer log
2878 virtual LPCWSTR getJitTimeLogFilename() = 0;
2879
2880 /*********************************************************************************/
2881 //
2882 // Diagnostic methods
2883 //
2884 /*********************************************************************************/
2885
2886 // this function is for debugging only. Returns method token.
2887 // Returns mdMethodDefNil for dynamic methods.
2888 virtual mdMethodDef getMethodDefFromMethod(
2889 CORINFO_METHOD_HANDLE hMethod
2890 ) = 0;
2891
2892 // this function is for debugging only. It returns the method name
2893 // and if 'moduleName' is non-null, it sets it to something that will
2894 // says which method (a class name, or a module name)
2895 virtual const char* getMethodName (
2896 CORINFO_METHOD_HANDLE ftn, /* IN */
2897 const char **moduleName /* OUT */
2898 ) = 0;
2899
2900 // Return method name as in metadata, or nullptr if there is none,
2901 // and optionally return the class, enclosing class, and namespace names
2902 // as in metadata.
2903 // Suitable for non-debugging use.
2904 virtual const char* getMethodNameFromMetadata(
2905 CORINFO_METHOD_HANDLE ftn, /* IN */
2906 const char **className, /* OUT */
2907 const char **namespaceName, /* OUT */
2908 const char **enclosingClassName /* OUT */
2909 ) = 0;
2910
2911 // this function is for debugging only. It returns a value that
2912 // is will always be the same for a given method. It is used
2913 // to implement the 'jitRange' functionality
2914 virtual unsigned getMethodHash (
2915 CORINFO_METHOD_HANDLE ftn /* IN */
2916 ) = 0;
2917
2918 // this function is for debugging only.
2919 virtual size_t findNameOfToken (
2920 CORINFO_MODULE_HANDLE module, /* IN */
2921 mdToken metaTOK, /* IN */
2922 __out_ecount (FQNameCapacity) char * szFQName, /* OUT */
2923 size_t FQNameCapacity /* IN */
2924 ) = 0;
2925
2926 // returns whether the struct is enregisterable. Only valid on a System V VM. Returns true on success, false on failure.
2927 virtual bool getSystemVAmd64PassStructInRegisterDescriptor(
2928 /* IN */ CORINFO_CLASS_HANDLE structHnd,
2929 /* OUT */ SYSTEMV_AMD64_CORINFO_STRUCT_REG_PASSING_DESCRIPTOR* structPassInRegDescPtr
2930 ) = 0;
2931
2932};
2933
2934/*****************************************************************************
2935 * ICorDynamicInfo contains EE interface methods which return values that may
2936 * change from invocation to invocation. They cannot be embedded in persisted
2937 * data; they must be requeried each time the EE is run.
2938 *****************************************************************************/
2939
2940class ICorDynamicInfo : public ICorStaticInfo
2941{
2942public:
2943
2944 //
2945 // These methods return values to the JIT which are not constant
2946 // from session to session.
2947 //
2948 // These methods take an extra parameter : void **ppIndirection.
2949 // If a JIT supports generation of prejit code (install-o-jit), it
2950 // must pass a non-null value for this parameter, and check the
2951 // resulting value. If *ppIndirection is NULL, code should be
2952 // generated normally. If non-null, then the value of
2953 // *ppIndirection is an address in the cookie table, and the code
2954 // generator needs to generate an indirection through the table to
2955 // get the resulting value. In this case, the return result of the
2956 // function must NOT be directly embedded in the generated code.
2957 //
2958 // Note that if a JIT does not support prejit code generation, it
2959 // may ignore the extra parameter & pass the default of NULL - the
2960 // prejit ICorDynamicInfo implementation will see this & generate
2961 // an error if the jitter is used in a prejit scenario.
2962 //
2963
2964 // Return details about EE internal data structures
2965
2966 virtual DWORD getThreadTLSIndex(
2967 void **ppIndirection = NULL
2968 ) = 0;
2969
2970 virtual const void * getInlinedCallFrameVptr(
2971 void **ppIndirection = NULL
2972 ) = 0;
2973
2974 virtual LONG * getAddrOfCaptureThreadGlobal(
2975 void **ppIndirection = NULL
2976 ) = 0;
2977
2978 // return the native entry point to an EE helper (see CorInfoHelpFunc)
2979 virtual void* getHelperFtn (
2980 CorInfoHelpFunc ftnNum,
2981 void **ppIndirection = NULL
2982 ) = 0;
2983
2984 // return a callable address of the function (native code). This function
2985 // may return a different value (depending on whether the method has
2986 // been JITed or not.
2987 virtual void getFunctionEntryPoint(
2988 CORINFO_METHOD_HANDLE ftn, /* IN */
2989 CORINFO_CONST_LOOKUP * pResult, /* OUT */
2990 CORINFO_ACCESS_FLAGS accessFlags = CORINFO_ACCESS_ANY) = 0;
2991
2992 // return a directly callable address. This can be used similarly to the
2993 // value returned by getFunctionEntryPoint() except that it is
2994 // guaranteed to be multi callable entrypoint.
2995 virtual void getFunctionFixedEntryPoint(
2996 CORINFO_METHOD_HANDLE ftn,
2997 CORINFO_CONST_LOOKUP * pResult) = 0;
2998
2999 // get the synchronization handle that is passed to monXstatic function
3000 virtual void* getMethodSync(
3001 CORINFO_METHOD_HANDLE ftn,
3002 void **ppIndirection = NULL
3003 ) = 0;
3004
3005 // get slow lazy string literal helper to use (CORINFO_HELP_STRCNS*).
3006 // Returns CORINFO_HELP_UNDEF if lazy string literal helper cannot be used.
3007 virtual CorInfoHelpFunc getLazyStringLiteralHelper(
3008 CORINFO_MODULE_HANDLE handle
3009 ) = 0;
3010
3011 virtual CORINFO_MODULE_HANDLE embedModuleHandle(
3012 CORINFO_MODULE_HANDLE handle,
3013 void **ppIndirection = NULL
3014 ) = 0;
3015
3016 virtual CORINFO_CLASS_HANDLE embedClassHandle(
3017 CORINFO_CLASS_HANDLE handle,
3018 void **ppIndirection = NULL
3019 ) = 0;
3020
3021 virtual CORINFO_METHOD_HANDLE embedMethodHandle(
3022 CORINFO_METHOD_HANDLE handle,
3023 void **ppIndirection = NULL
3024 ) = 0;
3025
3026 virtual CORINFO_FIELD_HANDLE embedFieldHandle(
3027 CORINFO_FIELD_HANDLE handle,
3028 void **ppIndirection = NULL
3029 ) = 0;
3030
3031 // Given a module scope (module), a method handle (context) and
3032 // a metadata token (metaTOK), fetch the handle
3033 // (type, field or method) associated with the token.
3034 // If this is not possible at compile-time (because the current method's
3035 // code is shared and the token contains generic parameters)
3036 // then indicate how the handle should be looked up at run-time.
3037 //
3038 virtual void embedGenericHandle(
3039 CORINFO_RESOLVED_TOKEN * pResolvedToken,
3040 BOOL fEmbedParent, // TRUE - embeds parent type handle of the field/method handle
3041 CORINFO_GENERICHANDLE_RESULT * pResult) = 0;
3042
3043 // Return information used to locate the exact enclosing type of the current method.
3044 // Used only to invoke .cctor method from code shared across generic instantiations
3045 // !needsRuntimeLookup statically known (enclosing type of method itself)
3046 // needsRuntimeLookup:
3047 // CORINFO_LOOKUP_THISOBJ use vtable pointer of 'this' param
3048 // CORINFO_LOOKUP_CLASSPARAM use vtable hidden param
3049 // CORINFO_LOOKUP_METHODPARAM use enclosing type of method-desc hidden param
3050 virtual CORINFO_LOOKUP_KIND getLocationOfThisType(
3051 CORINFO_METHOD_HANDLE context
3052 ) = 0;
3053
3054 // NOTE: the two methods below--getPInvokeUnmanagedTarget and getAddressOfPInvokeFixup--are
3055 // deprecated. New code should instead use getAddressOfPInvokeTarget, which subsumes the
3056 // functionality of these methods.
3057
3058 // return the unmanaged target *if method has already been prelinked.*
3059 virtual void* getPInvokeUnmanagedTarget(
3060 CORINFO_METHOD_HANDLE method,
3061 void **ppIndirection = NULL
3062 ) = 0;
3063
3064 // return address of fixup area for late-bound PInvoke calls.
3065 virtual void* getAddressOfPInvokeFixup(
3066 CORINFO_METHOD_HANDLE method,
3067 void **ppIndirection = NULL
3068 ) = 0;
3069
3070 // return the address of the PInvoke target. May be a fixup area in the
3071 // case of late-bound PInvoke calls.
3072 virtual void getAddressOfPInvokeTarget(
3073 CORINFO_METHOD_HANDLE method,
3074 CORINFO_CONST_LOOKUP *pLookup
3075 ) = 0;
3076
3077 // Generate a cookie based on the signature that would needs to be passed
3078 // to CORINFO_HELP_PINVOKE_CALLI
3079 virtual LPVOID GetCookieForPInvokeCalliSig(
3080 CORINFO_SIG_INFO* szMetaSig,
3081 void ** ppIndirection = NULL
3082 ) = 0;
3083
3084 // returns true if a VM cookie can be generated for it (might be false due to cross-module
3085 // inlining, in which case the inlining should be aborted)
3086 virtual bool canGetCookieForPInvokeCalliSig(
3087 CORINFO_SIG_INFO* szMetaSig
3088 ) = 0;
3089
3090 // Gets a handle that is checked to see if the current method is
3091 // included in "JustMyCode"
3092 virtual CORINFO_JUST_MY_CODE_HANDLE getJustMyCodeHandle(
3093 CORINFO_METHOD_HANDLE method,
3094 CORINFO_JUST_MY_CODE_HANDLE**ppIndirection = NULL
3095 ) = 0;
3096
3097 // Gets a method handle that can be used to correlate profiling data.
3098 // This is the IP of a native method, or the address of the descriptor struct
3099 // for IL. Always guaranteed to be unique per process, and not to move. */
3100 virtual void GetProfilingHandle(
3101 BOOL *pbHookFunction,
3102 void **pProfilerHandle,
3103 BOOL *pbIndirectedHandles
3104 ) = 0;
3105
3106 // Returns instructions on how to make the call. See code:CORINFO_CALL_INFO for possible return values.
3107 virtual void getCallInfo(
3108 // Token info
3109 CORINFO_RESOLVED_TOKEN * pResolvedToken,
3110
3111 //Generics info
3112 CORINFO_RESOLVED_TOKEN * pConstrainedResolvedToken,
3113
3114 //Security info
3115 CORINFO_METHOD_HANDLE callerHandle,
3116
3117 //Jit info
3118 CORINFO_CALLINFO_FLAGS flags,
3119
3120 //out params
3121 CORINFO_CALL_INFO *pResult
3122 ) = 0;
3123
3124 virtual BOOL canAccessFamily(CORINFO_METHOD_HANDLE hCaller,
3125 CORINFO_CLASS_HANDLE hInstanceType) = 0;
3126
3127 // Returns TRUE if the Class Domain ID is the RID of the class (currently true for every class
3128 // except reflection emitted classes and generics)
3129 virtual BOOL isRIDClassDomainID(CORINFO_CLASS_HANDLE cls) = 0;
3130
3131 // returns the class's domain ID for accessing shared statics
3132 virtual unsigned getClassDomainID (
3133 CORINFO_CLASS_HANDLE cls,
3134 void **ppIndirection = NULL
3135 ) = 0;
3136
3137
3138 // return the data's address (for static fields only)
3139 virtual void* getFieldAddress(
3140 CORINFO_FIELD_HANDLE field,
3141 void **ppIndirection = NULL
3142 ) = 0;
3143
3144 // If pIsSpeculative is NULL, return the class handle for the value of ref-class typed
3145 // static readonly fields, if there is a unique location for the static and the class
3146 // is already initialized.
3147 //
3148 // If pIsSpeculative is not NULL, fetch the class handle for the value of all ref-class
3149 // typed static fields, if there is a unique location for the static and the field is
3150 // not null.
3151 //
3152 // Set *pIsSpeculative true if this type may change over time (field is not readonly or
3153 // is readonly but class has not yet finished initialization). Set *pIsSpeculative false
3154 // if this type will not change.
3155 virtual CORINFO_CLASS_HANDLE getStaticFieldCurrentClass(
3156 CORINFO_FIELD_HANDLE field,
3157 bool *pIsSpeculative = NULL
3158 ) = 0;
3159
3160 // registers a vararg sig & returns a VM cookie for it (which can contain other stuff)
3161 virtual CORINFO_VARARGS_HANDLE getVarArgsHandle(
3162 CORINFO_SIG_INFO *pSig,
3163 void **ppIndirection = NULL
3164 ) = 0;
3165
3166 // returns true if a VM cookie can be generated for it (might be false due to cross-module
3167 // inlining, in which case the inlining should be aborted)
3168 virtual bool canGetVarArgsHandle(
3169 CORINFO_SIG_INFO *pSig
3170 ) = 0;
3171
3172 // Allocate a string literal on the heap and return a handle to it
3173 virtual InfoAccessType constructStringLiteral(
3174 CORINFO_MODULE_HANDLE module,
3175 mdToken metaTok,
3176 void **ppValue
3177 ) = 0;
3178
3179 virtual InfoAccessType emptyStringLiteral(
3180 void **ppValue
3181 ) = 0;
3182
3183 // (static fields only) given that 'field' refers to thread local store,
3184 // return the ID (TLS index), which is used to find the begining of the
3185 // TLS data area for the particular DLL 'field' is associated with.
3186 virtual DWORD getFieldThreadLocalStoreID (
3187 CORINFO_FIELD_HANDLE field,
3188 void **ppIndirection = NULL
3189 ) = 0;
3190
3191 // Sets another object to intercept calls to "self" and current method being compiled
3192 virtual void setOverride(
3193 ICorDynamicInfo *pOverride,
3194 CORINFO_METHOD_HANDLE currentMethod
3195 ) = 0;
3196
3197 // Adds an active dependency from the context method's module to the given module
3198 // This is internal callback for the EE. JIT should not call it directly.
3199 virtual void addActiveDependency(
3200 CORINFO_MODULE_HANDLE moduleFrom,
3201 CORINFO_MODULE_HANDLE moduleTo
3202 ) = 0;
3203
3204 virtual CORINFO_METHOD_HANDLE GetDelegateCtor(
3205 CORINFO_METHOD_HANDLE methHnd,
3206 CORINFO_CLASS_HANDLE clsHnd,
3207 CORINFO_METHOD_HANDLE targetMethodHnd,
3208 DelegateCtorArgs * pCtorData
3209 ) = 0;
3210
3211 virtual void MethodCompileComplete(
3212 CORINFO_METHOD_HANDLE methHnd
3213 ) = 0;
3214
3215 // return a thunk that will copy the arguments for the given signature.
3216 virtual void* getTailCallCopyArgsThunk (
3217 CORINFO_SIG_INFO *pSig,
3218 CorInfoHelperTailCallSpecialHandling flags
3219 ) = 0;
3220
3221 // Optionally, convert calli to regular method call. This is for PInvoke argument marshalling.
3222 virtual bool convertPInvokeCalliToCall(
3223 CORINFO_RESOLVED_TOKEN * pResolvedToken,
3224 bool fMustConvert
3225 ) = 0;
3226};
3227
3228/**********************************************************************************/
3229
3230// It would be nicer to use existing IMAGE_REL_XXX constants instead of defining our own here...
3231#define IMAGE_REL_BASED_REL32 0x10
3232#define IMAGE_REL_BASED_THUMB_BRANCH24 0x13
3233
3234// The identifier for ARM32-specific PC-relative address
3235// computation corresponds to the following instruction
3236// sequence:
3237// l0: movw rX, #imm_lo // 4 byte
3238// l4: movt rX, #imm_hi // 4 byte
3239// l8: add rX, pc <- after this instruction rX = relocTarget
3240//
3241// Program counter at l8 is address of l8 + 4
3242// Address of relocated movw/movt is l0
3243// So, imm should be calculated as the following:
3244// imm = relocTarget - (l8 + 4) = relocTarget - (l0 + 8 + 4) = relocTarget - (l_0 + 12)
3245// So, the value of offset correction is 12
3246//
3247#define IMAGE_REL_BASED_REL_THUMB_MOV32_PCREL 0x14
3248
3249#endif // _COR_INFO_H_
3250