-
Notifications
You must be signed in to change notification settings - Fork 4.8k
/
corinfo.h
3425 lines (2914 loc) · 153 KB
/
corinfo.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
//
/*****************************************************************************\
* *
* CorInfo.h - EE / Code generator interface *
* *
*******************************************************************************
*
* This file exposes CLR runtime functionality. It can be used by compilers,
* both Just-in-time and ahead-of-time, to generate native code which
* executes in the runtime environment.
*******************************************************************************
//////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE
//
// The JIT/EE interface is versioned. By "interface", we mean mean any and all communication between the
// JIT and the EE. Any time a change is made to the interface, the JIT/EE interface version identifier
// must be updated. See code:JITEEVersionIdentifier for more information.
//
// NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE
//
//////////////////////////////////////////////////////////////////////////////////////////////////////////
#EEJitContractDetails
The semantic contract between the EE and the JIT should be documented here It is incomplete, but as time goes
on, that hopefully will change
See file:../../doc/BookOfTheRuntime/JIT/JIT%20Design.doc for details on the JIT compiler. See
code:EEStartup#TableOfContents for information on the runtime as a whole.
-------------------------------------------------------------------------------
#Tokens
The tokens in IL stream needs to be resolved to EE handles (CORINFO_CLASS/METHOD/FIELD_HANDLE) that
the runtime operates with. ICorStaticInfo::resolveToken is the method that resolves the found in IL stream
to set of EE handles (CORINFO_RESOLVED_TOKEN). All other APIs take resolved token as input. This design
avoids redundant token resolutions.
The token validation is done as part of token resolution. The JIT is not required to do explicit upfront
token validation.
-------------------------------------------------------------------------------
#ClassConstruction
First of all class construction comes in two flavors precise and 'beforeFieldInit'. In C# you get the former
if you declare an explicit class constructor method and the later if you declaratively initialize static
fields. Precise class construction guarantees that the .cctor is run precisely before the first access to any
method or field of the class. 'beforeFieldInit' semantics guarantees only that the .cctor will be run some
time before the first static field access (note that calling methods (static or instance) or accessing
instance fields does not cause .cctors to be run).
Next you need to know that there are two kinds of code generation that can happen in the JIT: appdomain
neutral and appdomain specialized. The difference between these two kinds of code is how statics are handled.
For appdomain specific code, the address of a particular static variable is embedded in the code. This makes
it usable only for one appdomain (since every appdomain gets a own copy of its statics). Appdomain neutral
code calls a helper that looks up static variables off of a thread local variable. Thus the same code can be
used by multiple appdomains in the same process.
Generics also introduce a similar issue. Code for generic classes might be specialized for a particular set
of type arguments, or it could use helpers to access data that depends on type parameters and thus be shared
across several instantiations of the generic type.
Thus there four cases
* BeforeFieldInitCCtor - Unshared code. Cctors are only called when static fields are fetched. At the
time the method that touches the static field is JITed (or fixed up in the case of NGENed code), the
.cctor is called.
* BeforeFieldInitCCtor - Shared code. Since the same code is used for multiple classes, the act of JITing
the code can not be used as a hook. However, it is also the case that since the code is shared, it
can not wire in a particular address for the static and thus needs to use a helper that looks up the
correct address based on the thread ID. This helper does the .cctor check, and thus no additional
cctor logic is needed.
* PreciseCCtor - Unshared code. Any time a method is JITTed (or fixed up in the case of NGEN), a cctor
check for the class of the method being JITTed is done. In addition the JIT inserts explicit checks
before any static field accesses. Instance methods and fields do NOT have hooks because a .ctor
method must be called before the instance can be created.
* PreciseCctor - Shared code .cctor checks are placed in the prolog of every .ctor and static method. All
methods that access static fields have an explicit .cctor check before use. Again instance methods
don't have hooks because a .ctor would have to be called first.
Technically speaking, however the optimization of avoiding checks on instance methods is flawed. It requires
that a .ctor always precede a call to an instance methods. This break down when
* A NULL is passed to an instance method.
* A .ctor does not call its superclasses .ctor. This allows an instance to be created without necessarily
calling all the .cctors of all the superclasses. A virtual call can then be made to a instance of a
superclass without necessarily calling the superclass's .cctor.
* The class is a value class (which exists without a .ctor being called)
Nevertheless, the cost of plugging these holes is considered to high and the benefit is low.
----------------------------------------------------------------------
#ClassConstructionFlags
Thus the JIT's cctor responsibilities require it to check with the EE on every static field access using
initClass and before jitting any method to see if a .cctor check must be placed in the prolog.
* CORINFO_FLG_BEFOREFIELDINIT indicate the class has beforeFieldInit semantics. The jit does not strictly
need this information however, it is valuable in optimizing static field fetch helper calls. Helper
call for classes with BeforeFieldInit semantics can be hoisted before other side effects where
classes with precise .cctor semantics do not allow this optimization.
Inlining also complicates things. Because the class could have precise semantics it is also required that the
inlining of any constructor or static method must also do the initClass check. The inliner has the option of
inserting any required runtime check or simply not inlining the function.
-------------------------------------------------------------------------------
#StaticFields
The first 4 options are mutually exclusive
* CORINFO_FLG_HELPER If the field has this set, then the JIT must call getFieldHelper and call the
returned helper with the object ref (for an instance field) and a fieldDesc. Note that this should be
able to handle ANY field so to get a JIT up quickly, it has the option of using helper calls for all
field access (and skip the complexity below). Note that for statics it is assumed that you will
always ask for the ADDRESS helper and to the fetch in the JIT.
* CORINFO_FLG_SHARED_HELPER This is currently only used for static fields. If this bit is set it means
that the field is feched by a helper call that takes a module identifier (see getModuleDomainID) and
a class identifier (see getClassDomainID) as arguments. The exact helper to call is determined by
getSharedStaticBaseHelper. The return value is of this function is the base of all statics in the
module. The offset from getFieldOffset must be added to this value to get the address of the field
itself. (see also CORINFO_FLG_STATIC_IN_HEAP).
* CORINFO_FLG_GENERICS_STATIC This is currently only used for static fields (of generic type). This
function is intended to be called with a Generic handle as a argument (from embedGenericHandle). The
exact helper to call is determined by getSharedStaticBaseHelper. The returned value is the base of
all statics in the class. The offset from getFieldOffset must be added to this value to get the
address of the (see also CORINFO_FLG_STATIC_IN_HEAP).
* CORINFO_FLG_TLS This indicate that the static field is a Windows style Thread Local Static. (We also
have managed thread local statics, which work through the HELPER. Support for this is considered
legacy, and going forward, the EE should
* <NONE> This is a normal static field. Its address in memory is determined by getFieldInfo. (see
also CORINFO_FLG_STATIC_IN_HEAP).
This last field can modify any of the cases above except CORINFO_FLG_HELPER
CORINFO_FLG_STATIC_IN_HEAP This is currently only used for static fields of value classes. If the field has
this set then after computing what would normally be the field, what you actually get is a object pointer
(that must be reported to the GC) to a boxed version of the value. Thus the actual field address is computed
by addr = (*addr+sizeof(OBJECTREF))
Instance fields
* CORINFO_FLG_HELPER This is used if the class is MarshalByRef, which means that the object might be a
proxy to the real object in some other appdomain or process. If the field has this set, then the JIT
must call getFieldHelper and call the returned helper with the object ref. If the helper returned is
helpers that are for structures the args are as follows
* CORINFO_HELP_GETFIELDSTRUCT - args are: retBuff, object, fieldDesc
* CORINFO_HELP_SETFIELDSTRUCT - args are object fieldDesc value
The other GET helpers take an object fieldDesc and return the value The other SET helpers take an object
fieldDesc and value
Note that unlike static fields there is no helper to take the address of a field because in general there
is no address for proxies (LDFLDA is illegal on proxies).
CORINFO_FLG_EnC This is to support adding new field for edit and continue. This field also indicates that
a helper is needed to access this field. However this helper is always CORINFO_HELP_GETFIELDADDR, and
this helper always takes the object and field handle and returns the address of the field. It is the
JIT's responsibility to do the fetch or set.
-------------------------------------------------------------------------------
TODO: Talk about initializing strutures before use
*******************************************************************************
*/
#ifndef _COR_INFO_H_
#define _COR_INFO_H_
#include "corhdr.h"
#if !defined(_In_)
// Minimum set of SAL annotations so that non Windows builds work
#define _In_
#define _In_reads_(size)
#define _Inout_updates_(size)
#define _Out_
#define _Out_writes_(size)
#define _Outptr_
#define _Outptr_opt_
#define _Outptr_opt_result_maybenull_
#define _Outptr_result_z_
#define _Outptr_result_buffer_(size)
#define _Outptr_opt_result_buffer_(size)
#endif
#include "jiteeversionguid.h"
#ifdef _MSC_VER
typedef long JITINTERFACE_HRESULT;
#else
typedef int JITINTERFACE_HRESULT;
#endif // _MSC_VER
// For System V on the CLR type system number of registers to pass in and return a struct is the same.
// The CLR type system allows only up to 2 eightbytes to be passed in registers. There is no SSEUP classification types.
#define CLR_SYSTEMV_MAX_EIGHTBYTES_COUNT_TO_PASS_IN_REGISTERS 2
#define CLR_SYSTEMV_MAX_EIGHTBYTES_COUNT_TO_RETURN_IN_REGISTERS 2
#define CLR_SYSTEMV_MAX_STRUCT_BYTES_TO_PASS_IN_REGISTERS 16
// System V struct passing
// The Classification types are described in the ABI spec at https://software.intel.com/sites/default/files/article/402129/mpx-linux64-abi.pdf
enum SystemVClassificationType : uint8_t
{
SystemVClassificationTypeUnknown = 0,
SystemVClassificationTypeStruct = 1,
SystemVClassificationTypeNoClass = 2,
SystemVClassificationTypeMemory = 3,
SystemVClassificationTypeInteger = 4,
SystemVClassificationTypeIntegerReference = 5,
SystemVClassificationTypeIntegerByRef = 6,
SystemVClassificationTypeSSE = 7,
// SystemVClassificationTypeSSEUp = Unused, // Not supported by the CLR.
// SystemVClassificationTypeX87 = Unused, // Not supported by the CLR.
// SystemVClassificationTypeX87Up = Unused, // Not supported by the CLR.
// SystemVClassificationTypeComplexX87 = Unused, // Not supported by the CLR.
};
// Represents classification information for a struct.
struct SYSTEMV_AMD64_CORINFO_STRUCT_REG_PASSING_DESCRIPTOR
{
SYSTEMV_AMD64_CORINFO_STRUCT_REG_PASSING_DESCRIPTOR()
{
Initialize();
}
bool passedInRegisters; // Whether the struct is passable/passed (this includes struct returning) in registers.
uint8_t eightByteCount; // Number of eightbytes for this struct.
SystemVClassificationType eightByteClassifications[CLR_SYSTEMV_MAX_EIGHTBYTES_COUNT_TO_PASS_IN_REGISTERS]; // The eightbytes type classification.
uint8_t 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).
uint8_t eightByteOffsets[CLR_SYSTEMV_MAX_EIGHTBYTES_COUNT_TO_PASS_IN_REGISTERS]; // The start offset of the eightbytes (in bytes).
// Members
//------------------------------------------------------------------------
// CopyFrom: Copies a struct classification into this one.
//
// Arguments:
// 'copyFrom' the struct classification to copy from.
//
void CopyFrom(const SYSTEMV_AMD64_CORINFO_STRUCT_REG_PASSING_DESCRIPTOR& copyFrom)
{
passedInRegisters = copyFrom.passedInRegisters;
eightByteCount = copyFrom.eightByteCount;
for (int i = 0; i < CLR_SYSTEMV_MAX_EIGHTBYTES_COUNT_TO_PASS_IN_REGISTERS; i++)
{
eightByteClassifications[i] = copyFrom.eightByteClassifications[i];
eightByteSizes[i] = copyFrom.eightByteSizes[i];
eightByteOffsets[i] = copyFrom.eightByteOffsets[i];
}
}
//------------------------------------------------------------------------
// IsIntegralSlot: Returns whether the eightbyte at slotIndex is of integral type.
//
// Arguments:
// 'slotIndex' the slot number we are determining if it is of integral type.
//
// Return value:
// returns true if we the eightbyte at index slotIndex is of integral type.
//
bool IsIntegralSlot(unsigned slotIndex) const
{
return ((eightByteClassifications[slotIndex] == SystemVClassificationTypeInteger) ||
(eightByteClassifications[slotIndex] == SystemVClassificationTypeIntegerReference) ||
(eightByteClassifications[slotIndex] == SystemVClassificationTypeIntegerByRef));
}
//------------------------------------------------------------------------
// IsSseSlot: Returns whether the eightbyte at slotIndex is SSE type.
//
// Arguments:
// 'slotIndex' the slot number we are determining if it is of SSE type.
//
// Return value:
// returns true if we the eightbyte at index slotIndex is of SSE type.
//
// Follows the rules of the AMD64 System V ABI specification at https://software.intel.com/sites/default/files/article/402129/mpx-linux64-abi.pdf.
// Please refer to it for definitions/examples.
//
bool IsSseSlot(unsigned slotIndex) const
{
return (eightByteClassifications[slotIndex] == SystemVClassificationTypeSSE);
}
private:
void Initialize()
{
passedInRegisters = false;
eightByteCount = 0;
for (int i = 0; i < CLR_SYSTEMV_MAX_EIGHTBYTES_COUNT_TO_PASS_IN_REGISTERS; i++)
{
eightByteClassifications[i] = SystemVClassificationTypeUnknown;
eightByteSizes[i] = 0;
eightByteOffsets[i] = 0;
}
}
};
// StructFloadFieldInfoFlags: used on LoongArch64 architecture by `getLoongArch64PassStructInRegisterFlags` and
// `getRISCV64PassStructInRegisterFlags` API to convey struct argument passing information.
//
// `STRUCT_NO_FLOAT_FIELD` means structs are not passed using the float register(s).
//
// Otherwise, and only for structs with no more than two fields and a total struct size no larger
// than two pointers:
//
// The lowest four bits denote the floating-point info:
// bit 0: `1` means there is only one float or double field within the struct.
// bit 1: `1` means only the first field is floating-point type.
// bit 2: `1` means only the second field is floating-point type.
// bit 3: `1` means the two fields are both floating-point type.
// The bits[5:4] denoting whether the field size is 8-bytes:
// bit 4: `1` means the first field's size is 8.
// bit 5: `1` means the second field's size is 8.
//
// Note that bit 0 and 3 cannot both be set.
enum StructFloatFieldInfoFlags
{
STRUCT_NO_FLOAT_FIELD = 0x0,
STRUCT_FLOAT_FIELD_ONLY_ONE = 0x1,
STRUCT_FLOAT_FIELD_ONLY_TWO = 0x8,
STRUCT_FLOAT_FIELD_FIRST = 0x2,
STRUCT_FLOAT_FIELD_SECOND = 0x4,
STRUCT_FIRST_FIELD_SIZE_IS8 = 0x10,
STRUCT_SECOND_FIELD_SIZE_IS8 = 0x20,
STRUCT_FIRST_FIELD_DOUBLE = (STRUCT_FLOAT_FIELD_FIRST | STRUCT_FIRST_FIELD_SIZE_IS8),
STRUCT_SECOND_FIELD_DOUBLE = (STRUCT_FLOAT_FIELD_SECOND | STRUCT_SECOND_FIELD_SIZE_IS8),
STRUCT_FIELD_TWO_DOUBLES = (STRUCT_FIRST_FIELD_SIZE_IS8 | STRUCT_SECOND_FIELD_SIZE_IS8 | STRUCT_FLOAT_FIELD_ONLY_TWO),
STRUCT_MERGE_FIRST_SECOND = (STRUCT_FLOAT_FIELD_FIRST | STRUCT_FLOAT_FIELD_ONLY_TWO),
STRUCT_MERGE_FIRST_SECOND_8 = (STRUCT_FLOAT_FIELD_FIRST | STRUCT_FLOAT_FIELD_ONLY_TWO | STRUCT_SECOND_FIELD_SIZE_IS8),
STRUCT_HAS_FLOAT_FIELDS_MASK = (STRUCT_FLOAT_FIELD_FIRST | STRUCT_FLOAT_FIELD_SECOND | STRUCT_FLOAT_FIELD_ONLY_TWO | STRUCT_FLOAT_FIELD_ONLY_ONE),
STRUCT_HAS_8BYTES_FIELDS_MASK = (STRUCT_FIRST_FIELD_SIZE_IS8 | STRUCT_SECOND_FIELD_SIZE_IS8),
};
#include "corinfoinstructionset.h"
// CorInfoHelpFunc defines the set of helpers (accessed via the ICorDynamicInfo::getHelperFtn())
// These helpers can be called by native code which executes in the runtime.
// Compilers can emit calls to these helpers.
//
// The signatures of the helpers are below (see RuntimeHelperArgumentCheck)
enum CorInfoHelpFunc
{
CORINFO_HELP_UNDEF, // invalid value. This should never be used
/* Arithmetic helpers */
CORINFO_HELP_DIV, // For the ARM 32-bit integer divide uses a helper call :-(
CORINFO_HELP_MOD,
CORINFO_HELP_UDIV,
CORINFO_HELP_UMOD,
CORINFO_HELP_LLSH,
CORINFO_HELP_LRSH,
CORINFO_HELP_LRSZ,
CORINFO_HELP_LMUL,
CORINFO_HELP_LMUL_OVF,
CORINFO_HELP_ULMUL_OVF,
CORINFO_HELP_LDIV,
CORINFO_HELP_LMOD,
CORINFO_HELP_ULDIV,
CORINFO_HELP_ULMOD,
CORINFO_HELP_LNG2DBL, // Convert a signed int64 to a double
CORINFO_HELP_ULNG2DBL, // Convert a unsigned int64 to a double
CORINFO_HELP_DBL2INT,
CORINFO_HELP_DBL2INT_OVF,
CORINFO_HELP_DBL2LNG,
CORINFO_HELP_DBL2LNG_OVF,
CORINFO_HELP_DBL2UINT,
CORINFO_HELP_DBL2UINT_OVF,
CORINFO_HELP_DBL2ULNG,
CORINFO_HELP_DBL2ULNG_OVF,
CORINFO_HELP_FLTREM,
CORINFO_HELP_DBLREM,
CORINFO_HELP_FLTROUND, // unused, remove once MINIMUM_READYTORUN_MAJOR_VERSION > 9
CORINFO_HELP_DBLROUND, // unused, remove once MINIMUM_READYTORUN_MAJOR_VERSION > 9
/* Allocating a new object. Always use ICorClassInfo::getNewHelper() to decide
which is the right helper to use to allocate an object of a given type. */
CORINFO_HELP_NEWFAST,
CORINFO_HELP_NEWFAST_MAYBEFROZEN, // allocator for objects that *might* allocate them on a frozen segment
CORINFO_HELP_NEWSFAST, // allocator for small, non-finalizer, non-array object
CORINFO_HELP_NEWSFAST_FINALIZE, // allocator for small, finalizable, non-array object
CORINFO_HELP_NEWSFAST_ALIGN8, // allocator for small, non-finalizer, non-array object, 8 byte aligned
CORINFO_HELP_NEWSFAST_ALIGN8_VC,// allocator for small, value class, 8 byte aligned
CORINFO_HELP_NEWSFAST_ALIGN8_FINALIZE, // allocator for small, finalizable, non-array object, 8 byte aligned
CORINFO_HELP_NEW_MDARR,// multi-dim array helper for arrays Rank != 1 (with or without lower bounds - dimensions passed in as unmanaged array)
CORINFO_HELP_NEW_MDARR_RARE,// rare multi-dim array helper (Rank == 1)
CORINFO_HELP_NEWARR_1_DIRECT, // helper for any one dimensional array creation
CORINFO_HELP_NEWARR_1_MAYBEFROZEN, // allocator for arrays that *might* allocate them on a frozen segment
CORINFO_HELP_NEWARR_1_OBJ, // optimized 1-D object arrays
CORINFO_HELP_NEWARR_1_VC, // optimized 1-D value class arrays
CORINFO_HELP_NEWARR_1_ALIGN8, // like VC, but aligns the array start
CORINFO_HELP_STRCNS, // create a new string literal
/* Object model */
CORINFO_HELP_INITCLASS, // Initialize class if not already initialized
CORINFO_HELP_INITINSTCLASS, // Initialize class for instantiated type
// Use ICorClassInfo::getCastingHelper to determine
// the right helper to use
CORINFO_HELP_ISINSTANCEOFINTERFACE, // Optimized helper for interfaces
CORINFO_HELP_ISINSTANCEOFARRAY, // Optimized helper for arrays
CORINFO_HELP_ISINSTANCEOFCLASS, // Optimized helper for classes
CORINFO_HELP_ISINSTANCEOFANY, // Slow helper for any type
CORINFO_HELP_CHKCASTINTERFACE,
CORINFO_HELP_CHKCASTARRAY,
CORINFO_HELP_CHKCASTCLASS,
CORINFO_HELP_CHKCASTANY,
CORINFO_HELP_CHKCASTCLASS_SPECIAL, // Optimized helper for classes. Assumes that the trivial cases
// has been taken care of by the inlined check
CORINFO_HELP_ISINSTANCEOF_EXCEPTION,
CORINFO_HELP_BOX, // Fast box helper. Only possible exception is OutOfMemory
CORINFO_HELP_BOX_NULLABLE, // special form of boxing for Nullable<T>
CORINFO_HELP_UNBOX,
CORINFO_HELP_UNBOX_TYPETEST, // Verify unbox type, throws if incompatible
CORINFO_HELP_UNBOX_NULLABLE, // special form of unboxing for Nullable<T>
CORINFO_HELP_GETREFANY, // Extract the byref from a TypedReference, checking that it is the expected type
CORINFO_HELP_ARRADDR_ST, // assign to element of object array with type-checking
CORINFO_HELP_LDELEMA_REF, // does a precise type comparison and returns address
/* Exceptions */
CORINFO_HELP_THROW, // Throw an exception object
CORINFO_HELP_RETHROW, // Rethrow the currently active exception
CORINFO_HELP_USER_BREAKPOINT, // For a user program to break to the debugger
CORINFO_HELP_RNGCHKFAIL, // array bounds check failed
CORINFO_HELP_OVERFLOW, // throw an overflow exception
CORINFO_HELP_THROWDIVZERO, // throw a divide by zero exception
CORINFO_HELP_THROWNULLREF, // throw a null reference exception
CORINFO_HELP_VERIFICATION, // Throw a VerificationException
CORINFO_HELP_FAIL_FAST, // Kill the process avoiding any exceptions or stack and data dependencies (use for GuardStack unsafe buffer checks)
CORINFO_HELP_METHOD_ACCESS_EXCEPTION,//Throw an access exception due to a failed member/class access check.
CORINFO_HELP_FIELD_ACCESS_EXCEPTION,
CORINFO_HELP_CLASS_ACCESS_EXCEPTION,
CORINFO_HELP_ENDCATCH, // call back into the EE at the end of a catch block
/* Synchronization */
CORINFO_HELP_MON_ENTER,
CORINFO_HELP_MON_EXIT,
CORINFO_HELP_MON_ENTER_STATIC,
CORINFO_HELP_MON_EXIT_STATIC,
CORINFO_HELP_GETCLASSFROMMETHODPARAM, // Given a generics method handle, returns a class handle
CORINFO_HELP_GETSYNCFROMCLASSHANDLE, // Given a generics class handle, returns the sync monitor
// in its ManagedClassObject
/* GC support */
CORINFO_HELP_STOP_FOR_GC, // Call GC (force a GC)
CORINFO_HELP_POLL_GC, // Ask GC if it wants to collect
CORINFO_HELP_STRESS_GC, // Force a GC, but then update the JITTED code to be a noop call
CORINFO_HELP_CHECK_OBJ, // confirm that ECX is a valid object pointer (debugging only)
/* GC Write barrier support */
CORINFO_HELP_ASSIGN_REF, // universal helpers with F_CALL_CONV calling convention
CORINFO_HELP_CHECKED_ASSIGN_REF,
CORINFO_HELP_ASSIGN_REF_ENSURE_NONHEAP, // Do the store, and ensure that the target was not in the heap.
CORINFO_HELP_ASSIGN_BYREF,
CORINFO_HELP_BULK_WRITEBARRIER,
/* Accessing fields */
// For COM object support (using COM get/set routines to update object)
// and EnC and cross-context support
CORINFO_HELP_GETFIELD8,
CORINFO_HELP_SETFIELD8,
CORINFO_HELP_GETFIELD16,
CORINFO_HELP_SETFIELD16,
CORINFO_HELP_GETFIELD32,
CORINFO_HELP_SETFIELD32,
CORINFO_HELP_GETFIELD64,
CORINFO_HELP_SETFIELD64,
CORINFO_HELP_GETFIELDOBJ,
CORINFO_HELP_SETFIELDOBJ,
CORINFO_HELP_GETFIELDSTRUCT,
CORINFO_HELP_SETFIELDSTRUCT,
CORINFO_HELP_GETFIELDFLOAT,
CORINFO_HELP_SETFIELDFLOAT,
CORINFO_HELP_GETFIELDDOUBLE,
CORINFO_HELP_SETFIELDDOUBLE,
CORINFO_HELP_GETFIELDADDR,
CORINFO_HELP_GETSTATICFIELDADDR,
CORINFO_HELP_GETSTATICFIELDADDR_TLS, // Helper for PE TLS fields
// There are a variety of specialized helpers for accessing static fields. The JIT should use
// ICorClassInfo::getSharedStaticsOrCCtorHelper to determine which helper to use
// Helpers for regular statics
CORINFO_HELP_GET_GCSTATIC_BASE,
CORINFO_HELP_GET_NONGCSTATIC_BASE,
CORINFO_HELP_GETDYNAMIC_GCSTATIC_BASE,
CORINFO_HELP_GETDYNAMIC_NONGCSTATIC_BASE,
CORINFO_HELP_GETPINNED_GCSTATIC_BASE,
CORINFO_HELP_GETPINNED_NONGCSTATIC_BASE,
CORINFO_HELP_GET_GCSTATIC_BASE_NOCTOR,
CORINFO_HELP_GET_NONGCSTATIC_BASE_NOCTOR,
CORINFO_HELP_GETDYNAMIC_GCSTATIC_BASE_NOCTOR,
CORINFO_HELP_GETDYNAMIC_NONGCSTATIC_BASE_NOCTOR,
CORINFO_HELP_GETPINNED_GCSTATIC_BASE_NOCTOR,
CORINFO_HELP_GETPINNED_NONGCSTATIC_BASE_NOCTOR,
// Helpers for thread statics
CORINFO_HELP_GET_GCTHREADSTATIC_BASE,
CORINFO_HELP_GET_NONGCTHREADSTATIC_BASE,
CORINFO_HELP_GETDYNAMIC_GCTHREADSTATIC_BASE,
CORINFO_HELP_GETDYNAMIC_NONGCTHREADSTATIC_BASE,
CORINFO_HELP_GET_GCTHREADSTATIC_BASE_NOCTOR,
CORINFO_HELP_GET_NONGCTHREADSTATIC_BASE_NOCTOR,
CORINFO_HELP_GETDYNAMIC_GCTHREADSTATIC_BASE_NOCTOR,
CORINFO_HELP_GETDYNAMIC_NONGCTHREADSTATIC_BASE_NOCTOR,
CORINFO_HELP_GETDYNAMIC_GCTHREADSTATIC_BASE_NOCTOR_OPTIMIZED,
CORINFO_HELP_GETDYNAMIC_NONGCTHREADSTATIC_BASE_NOCTOR_OPTIMIZED,
CORINFO_HELP_GETDYNAMIC_NONGCTHREADSTATIC_BASE_NOCTOR_OPTIMIZED2,
/* Debugger */
CORINFO_HELP_DBG_IS_JUST_MY_CODE, // Check if this is "JustMyCode" and needs to be stepped through.
/* Profiling enter/leave probe addresses */
CORINFO_HELP_PROF_FCN_ENTER, // record the entry to a method (caller)
CORINFO_HELP_PROF_FCN_LEAVE, // record the completion of current method (caller)
CORINFO_HELP_PROF_FCN_TAILCALL, // record the completion of current method through tailcall (caller)
/* Miscellaneous */
CORINFO_HELP_BBT_FCN_ENTER, // record the entry to a method for collecting Tuning data
CORINFO_HELP_PINVOKE_CALLI, // Indirect pinvoke call
CORINFO_HELP_TAILCALL, // Perform a tail call
CORINFO_HELP_GETCURRENTMANAGEDTHREADID,
CORINFO_HELP_INIT_PINVOKE_FRAME, // initialize an inlined PInvoke Frame for the JIT-compiler
CORINFO_HELP_MEMSET, // Init block of memory
CORINFO_HELP_MEMZERO, // Init block of memory with zeroes
CORINFO_HELP_MEMCPY, // Copy block of memory
CORINFO_HELP_NATIVE_MEMSET, // Init block of memory using native memset (not safe for pDst being null,
// not safe for unbounded size, does not trigger GC)
CORINFO_HELP_RUNTIMEHANDLE_METHOD, // determine a type/field/method handle at run-time
CORINFO_HELP_RUNTIMEHANDLE_METHOD_LOG, // determine a type/field/method handle at run-time, with IBC logging
CORINFO_HELP_RUNTIMEHANDLE_CLASS, // determine a type/field/method handle at run-time
CORINFO_HELP_RUNTIMEHANDLE_CLASS_LOG, // determine a type/field/method handle at run-time, with IBC logging
CORINFO_HELP_TYPEHANDLE_TO_RUNTIMETYPE, // Convert from a TypeHandle (native structure pointer) to RuntimeType at run-time
CORINFO_HELP_TYPEHANDLE_TO_RUNTIMETYPE_MAYBENULL, // Convert from a TypeHandle (native structure pointer) to RuntimeType at run-time, the type may be null
CORINFO_HELP_METHODDESC_TO_STUBRUNTIMEMETHOD, // Convert from a MethodDesc (native structure pointer) to RuntimeMethodHandle at run-time
CORINFO_HELP_FIELDDESC_TO_STUBRUNTIMEFIELD, // Convert from a FieldDesc (native structure pointer) to RuntimeFieldHandle at run-time
CORINFO_HELP_TYPEHANDLE_TO_RUNTIMETYPEHANDLE, // Convert from a TypeHandle (native structure pointer) to RuntimeTypeHandle at run-time
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
CORINFO_HELP_VIRTUAL_FUNC_PTR, // look up a virtual method at run-time
// 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.
CORINFO_HELP_READYTORUN_NEW,
CORINFO_HELP_READYTORUN_NEWARR_1,
CORINFO_HELP_READYTORUN_ISINSTANCEOF,
CORINFO_HELP_READYTORUN_CHKCAST,
CORINFO_HELP_READYTORUN_GCSTATIC_BASE, // static gc field access
CORINFO_HELP_READYTORUN_NONGCSTATIC_BASE, // static non gc field access
CORINFO_HELP_READYTORUN_THREADSTATIC_BASE,
CORINFO_HELP_READYTORUN_THREADSTATIC_BASE_NOCTOR,
CORINFO_HELP_READYTORUN_NONGCTHREADSTATIC_BASE,
CORINFO_HELP_READYTORUN_VIRTUAL_FUNC_PTR,
CORINFO_HELP_READYTORUN_GENERIC_HANDLE,
CORINFO_HELP_READYTORUN_DELEGATE_CTOR,
CORINFO_HELP_READYTORUN_GENERIC_STATIC_BASE,
CORINFO_HELP_EE_PERSONALITY_ROUTINE,// Not real JIT helper. Used in native images.
CORINFO_HELP_EE_PERSONALITY_ROUTINE_FILTER_FUNCLET,// Not real JIT helper. Used in native images to detect filter funclets.
// ASSIGN_REF_EAX - CHECKED_ASSIGN_REF_EBP: NOGC_WRITE_BARRIERS JIT helper calls
//
// For unchecked versions EDX is required to point into GC heap.
//
// NOTE: these helpers are only used for x86.
CORINFO_HELP_ASSIGN_REF_EAX, // EAX holds GC ptr, do a 'mov [EDX], EAX' and inform GC
CORINFO_HELP_ASSIGN_REF_EBX, // EBX holds GC ptr, do a 'mov [EDX], EBX' and inform GC
CORINFO_HELP_ASSIGN_REF_ECX, // ECX holds GC ptr, do a 'mov [EDX], ECX' and inform GC
CORINFO_HELP_ASSIGN_REF_ESI, // ESI holds GC ptr, do a 'mov [EDX], ESI' and inform GC
CORINFO_HELP_ASSIGN_REF_EDI, // EDI holds GC ptr, do a 'mov [EDX], EDI' and inform GC
CORINFO_HELP_ASSIGN_REF_EBP, // EBP holds GC ptr, do a 'mov [EDX], EBP' and inform GC
CORINFO_HELP_CHECKED_ASSIGN_REF_EAX, // These are the same as ASSIGN_REF above ...
CORINFO_HELP_CHECKED_ASSIGN_REF_EBX, // ... but also check if EDX points into heap.
CORINFO_HELP_CHECKED_ASSIGN_REF_ECX,
CORINFO_HELP_CHECKED_ASSIGN_REF_ESI,
CORINFO_HELP_CHECKED_ASSIGN_REF_EDI,
CORINFO_HELP_CHECKED_ASSIGN_REF_EBP,
CORINFO_HELP_LOOP_CLONE_CHOICE_ADDR, // Return the reference to a counter to decide to take cloned path in debug stress.
CORINFO_HELP_DEBUG_LOG_LOOP_CLONING, // Print a message that a loop cloning optimization has occurred in debug mode.
CORINFO_HELP_THROW_ARGUMENTEXCEPTION, // throw ArgumentException
CORINFO_HELP_THROW_ARGUMENTOUTOFRANGEEXCEPTION, // throw ArgumentOutOfRangeException
CORINFO_HELP_THROW_NOT_IMPLEMENTED, // throw NotImplementedException
CORINFO_HELP_THROW_PLATFORM_NOT_SUPPORTED, // throw PlatformNotSupportedException
CORINFO_HELP_THROW_TYPE_NOT_SUPPORTED, // throw TypeNotSupportedException
CORINFO_HELP_THROW_AMBIGUOUS_RESOLUTION_EXCEPTION, // throw AmbiguousResolutionException for failed static virtual method resolution
CORINFO_HELP_THROW_ENTRYPOINT_NOT_FOUND_EXCEPTION, // throw EntryPointNotFoundException for failed static virtual method resolution
CORINFO_HELP_JIT_PINVOKE_BEGIN, // Transition to preemptive mode before a P/Invoke, frame is the first argument
CORINFO_HELP_JIT_PINVOKE_END, // Transition to cooperative mode after a P/Invoke, frame is the first argument
CORINFO_HELP_JIT_REVERSE_PINVOKE_ENTER, // Transition to cooperative mode in reverse P/Invoke prolog, frame is the first argument
CORINFO_HELP_JIT_REVERSE_PINVOKE_ENTER_TRACK_TRANSITIONS, // Transition to cooperative mode and track transitions in reverse P/Invoke prolog.
CORINFO_HELP_JIT_REVERSE_PINVOKE_EXIT, // Transition to preemptive mode in reverse P/Invoke epilog, frame is the first argument
CORINFO_HELP_JIT_REVERSE_PINVOKE_EXIT_TRACK_TRANSITIONS, // Transition to preemptive mode and track transitions in reverse P/Invoke prolog.
CORINFO_HELP_GVMLOOKUP_FOR_SLOT, // Resolve a generic virtual method target from this pointer and runtime method handle
CORINFO_HELP_STACK_PROBE, // Probes each page of the allocated stack frame
CORINFO_HELP_PATCHPOINT, // Notify runtime that code has reached a patchpoint
CORINFO_HELP_PARTIAL_COMPILATION_PATCHPOINT, // Notify runtime that code has reached a part of the method that wasn't originally jitted.
CORINFO_HELP_CLASSPROFILE32, // Update 32-bit class profile for a call site
CORINFO_HELP_CLASSPROFILE64, // Update 64-bit class profile for a call site
CORINFO_HELP_DELEGATEPROFILE32, // Update 32-bit method profile for a delegate call site
CORINFO_HELP_DELEGATEPROFILE64, // Update 64-bit method profile for a delegate call site
CORINFO_HELP_VTABLEPROFILE32, // Update 32-bit method profile for a vtable call site
CORINFO_HELP_VTABLEPROFILE64, // Update 64-bit method profile for a vtable call site
CORINFO_HELP_COUNTPROFILE32, // Update 32-bit block or edge count profile
CORINFO_HELP_COUNTPROFILE64, // Update 64-bit block or edge count profile
CORINFO_HELP_VALUEPROFILE32, // Update 32-bit value profile
CORINFO_HELP_VALUEPROFILE64, // Update 64-bit value profile
CORINFO_HELP_VALIDATE_INDIRECT_CALL, // CFG: Validate function pointer
CORINFO_HELP_DISPATCH_INDIRECT_CALL, // CFG: Validate and dispatch to pointer
CORINFO_HELP_COUNT,
};
//This describes the signature for a helper method.
enum CorInfoHelpSig
{
CORINFO_HELP_SIG_UNDEF,
CORINFO_HELP_SIG_NO_ALIGN_STUB,
CORINFO_HELP_SIG_NO_UNWIND_STUB,
CORINFO_HELP_SIG_REG_ONLY,
CORINFO_HELP_SIG_4_STACK,
CORINFO_HELP_SIG_8_STACK,
CORINFO_HELP_SIG_12_STACK,
CORINFO_HELP_SIG_16_STACK,
CORINFO_HELP_SIG_EBPCALL, //special calling convention that uses EDX and
//EBP as arguments
CORINFO_HELP_SIG_CANNOT_USE_ALIGN_STUB,
CORINFO_HELP_SIG_COUNT
};
// The enumeration is returned in 'getSig','getType', getArgType methods
enum CorInfoType
{
CORINFO_TYPE_UNDEF = 0x0,
CORINFO_TYPE_VOID = 0x1,
CORINFO_TYPE_BOOL = 0x2,
CORINFO_TYPE_CHAR = 0x3,
CORINFO_TYPE_BYTE = 0x4,
CORINFO_TYPE_UBYTE = 0x5,
CORINFO_TYPE_SHORT = 0x6,
CORINFO_TYPE_USHORT = 0x7,
CORINFO_TYPE_INT = 0x8,
CORINFO_TYPE_UINT = 0x9,
CORINFO_TYPE_LONG = 0xa,
CORINFO_TYPE_ULONG = 0xb,
CORINFO_TYPE_NATIVEINT = 0xc,
CORINFO_TYPE_NATIVEUINT = 0xd,
CORINFO_TYPE_FLOAT = 0xe,
CORINFO_TYPE_DOUBLE = 0xf,
CORINFO_TYPE_STRING = 0x10, // Not used, should remove
CORINFO_TYPE_PTR = 0x11,
CORINFO_TYPE_BYREF = 0x12,
CORINFO_TYPE_VALUECLASS = 0x13,
CORINFO_TYPE_CLASS = 0x14,
CORINFO_TYPE_REFANY = 0x15,
// CORINFO_TYPE_VAR is for a generic type variable.
// Generic type variables only appear when the JIT is doing
// verification (not NOT compilation) of generic code
// for the EE, in which case we're running
// the JIT in "import only" mode.
CORINFO_TYPE_VAR = 0x16,
CORINFO_TYPE_COUNT, // number of jit types
};
enum CorInfoTypeWithMod
{
CORINFO_TYPE_MASK = 0x3F, // lower 6 bits are type mask
CORINFO_TYPE_MOD_PINNED = 0x40, // can be applied to CLASS, or BYREF to indicate pinned
};
inline CorInfoType strip(CorInfoTypeWithMod val) {
return CorInfoType(val & CORINFO_TYPE_MASK);
}
// The enumeration is returned in 'getSig'
enum CorInfoCallConv
{
// These correspond to CorCallingConvention
CORINFO_CALLCONV_DEFAULT = 0x0,
// Instead of using the below values, use the CorInfoCallConvExtension enum for unmanaged calling conventions.
// CORINFO_CALLCONV_C = 0x1,
// CORINFO_CALLCONV_STDCALL = 0x2,
// CORINFO_CALLCONV_THISCALL = 0x3,
// CORINFO_CALLCONV_FASTCALL = 0x4,
CORINFO_CALLCONV_VARARG = 0x5,
CORINFO_CALLCONV_FIELD = 0x6,
CORINFO_CALLCONV_LOCAL_SIG = 0x7,
CORINFO_CALLCONV_PROPERTY = 0x8,
CORINFO_CALLCONV_UNMANAGED = 0x9,
CORINFO_CALLCONV_NATIVEVARARG = 0xb, // used ONLY for IL stub PInvoke vararg calls
CORINFO_CALLCONV_MASK = 0x0f, // Calling convention is bottom 4 bits
CORINFO_CALLCONV_GENERIC = 0x10,
CORINFO_CALLCONV_HASTHIS = 0x20,
CORINFO_CALLCONV_EXPLICITTHIS=0x40,
CORINFO_CALLCONV_PARAMTYPE = 0x80, // Passed last. Same as CORINFO_GENERICS_CTXT_FROM_PARAMTYPEARG
};
// Represents the calling conventions supported with the extensible calling convention syntax
// as well as the original metadata-encoded calling conventions.
enum class CorInfoCallConvExtension
{
Managed,
C,
Stdcall,
Thiscall,
Fastcall,
// New calling conventions supported with the extensible calling convention encoding go here.
CMemberFunction,
StdcallMemberFunction,
FastcallMemberFunction,
Swift
};
#ifdef TARGET_X86
inline bool IsCallerPop(CorInfoCallConvExtension callConv)
{
#ifdef UNIX_X86_ABI
return callConv == CorInfoCallConvExtension::Managed || callConv == CorInfoCallConvExtension::C || callConv == CorInfoCallConvExtension::CMemberFunction;
#else
return callConv == CorInfoCallConvExtension::C || callConv == CorInfoCallConvExtension::CMemberFunction;
#endif // UNIX_X86_ABI
}
#endif
// Determines whether or not this calling convention is an instance method calling convention.
inline bool callConvIsInstanceMethodCallConv(CorInfoCallConvExtension callConv)
{
return callConv == CorInfoCallConvExtension::Thiscall || callConv == CorInfoCallConvExtension::CMemberFunction || callConv == CorInfoCallConvExtension::StdcallMemberFunction || callConv == CorInfoCallConvExtension::FastcallMemberFunction;
}
// These are returned from getMethodOptions
enum CorInfoOptions
{
CORINFO_OPT_INIT_LOCALS = 0x00000010, // zero initialize all variables
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.
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
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
CORINFO_GENERICS_CTXT_MASK = (CORINFO_GENERICS_CTXT_FROM_THIS |
CORINFO_GENERICS_CTXT_FROM_METHODDESC |
CORINFO_GENERICS_CTXT_FROM_METHODTABLE),
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
};
//
// what type of code region we are in
//
enum CorInfoRegionKind
{
CORINFO_REGION_NONE,
CORINFO_REGION_HOT,
CORINFO_REGION_COLD,
CORINFO_REGION_JIT,
};
// these are the attribute flags for fields and methods (getMethodAttribs)
enum CorInfoFlag
{
// CORINFO_FLG_UNUSED = 0x00000001,
// CORINFO_FLG_UNUSED = 0x00000002,
// CORINFO_FLG_UNUSED = 0x00000004,
CORINFO_FLG_STATIC = 0x00000008,
CORINFO_FLG_FINAL = 0x00000010,
CORINFO_FLG_SYNCH = 0x00000020,
CORINFO_FLG_VIRTUAL = 0x00000040,
// CORINFO_FLG_UNUSED = 0x00000080,
// CORINFO_FLG_UNUSED = 0x00000100,
CORINFO_FLG_INTRINSIC_TYPE = 0x00000200, // This type is marked by [Intrinsic]
CORINFO_FLG_ABSTRACT = 0x00000400,
CORINFO_FLG_EnC = 0x00000800, // member was added by Edit'n'Continue
// These are internal flags that can only be on methods
CORINFO_FLG_FORCEINLINE = 0x00010000, // The method should be inlined if possible.
CORINFO_FLG_SHAREDINST = 0x00020000, // the code for this method is shared between different generic instantiations (also set on classes/types)
CORINFO_FLG_DELEGATE_INVOKE = 0x00040000, // "Delegate
CORINFO_FLG_PINVOKE = 0x00080000, // Is a P/Invoke call
// CORINFO_FLG_UNUSED = 0x00100000,
CORINFO_FLG_NOGCCHECK = 0x00200000, // This method is FCALL that has no GC check. Don't put alone in loops
CORINFO_FLG_INTRINSIC = 0x00400000, // This method MAY have an intrinsic ID
CORINFO_FLG_CONSTRUCTOR = 0x00800000, // This method is an instance or type initializer
CORINFO_FLG_AGGRESSIVE_OPT = 0x01000000, // The method may contain hot code and should be aggressively optimized if possible
CORINFO_FLG_DISABLE_TIER0_FOR_LOOPS = 0x02000000, // Indicates that tier 0 JIT should not be used for a method that contains a loop
// CORINFO_FLG_UNUSED = 0x04000000,
// CORINFO_FLG_UNUSED = 0x08000000,
CORINFO_FLG_DONT_INLINE = 0x10000000, // The method should not be inlined
CORINFO_FLG_DONT_INLINE_CALLER = 0x20000000, // The method should not be inlined, nor should its callers. It cannot be tail called.
// CORINFO_FLG_UNUSED = 0x40000000,
// These are internal flags that can only be on Classes
CORINFO_FLG_VALUECLASS = 0x00010000, // is the class a value class
// This flag is define din the Methods section, but is also valid on classes.
// CORINFO_FLG_SHAREDINST = 0x00020000, // This class is satisfies TypeHandle::IsCanonicalSubtype
CORINFO_FLG_VAROBJSIZE = 0x00040000, // the object size varies depending of constructor args
CORINFO_FLG_ARRAY = 0x00080000, // class is an array class (initialized differently)
CORINFO_FLG_OVERLAPPING_FIELDS = 0x00100000, // struct or class has fields that overlap (aka union)
CORINFO_FLG_INTERFACE = 0x00200000, // it is an interface
CORINFO_FLG_CONTAINS_GC_PTR = 0x01000000, // does the class contain a gc ptr ?
CORINFO_FLG_DELEGATE = 0x02000000, // is this a subclass of delegate or multicast delegate ?
CORINFO_FLG_INDEXABLE_FIELDS = 0x04000000, // struct fields may be accessed via indexing (used for inline arrays)
CORINFO_FLG_BYREF_LIKE = 0x08000000, // it is byref-like value type
// CORINFO_FLG_UNUSED = 0x10000000,
CORINFO_FLG_BEFOREFIELDINIT = 0x20000000, // Additional flexibility for when to run .cctor (see code:#ClassConstructionFlags)
CORINFO_FLG_GENERIC_TYPE_VARIABLE = 0x40000000, // This is really a handle for a variable type
CORINFO_FLG_UNSAFE_VALUECLASS = 0x80000000, // Unsafe (C++'s /GS) value type
};
// Flags computed by a runtime compiler
enum CorInfoMethodRuntimeFlags
{
CORINFO_FLG_BAD_INLINEE = 0x00000001, // The method is not suitable for inlining
// unused = 0x00000002,
// unused = 0x00000004,
CORINFO_FLG_SWITCHED_TO_MIN_OPT = 0x00000008, // The JIT decided to switch to MinOpt for this method, when it was not requested
CORINFO_FLG_SWITCHED_TO_OPTIMIZED = 0x00000010, // The JIT decided to switch to tier 1 for this method, when a different tier was requested
};
enum CORINFO_ACCESS_FLAGS
{
CORINFO_ACCESS_ANY = 0x0000, // Normal access
CORINFO_ACCESS_THIS = 0x0001, // Accessed via the this reference
// UNUSED = 0x0002,
CORINFO_ACCESS_NONNULL = 0x0004, // Instance is guaranteed non-null
CORINFO_ACCESS_LDFTN = 0x0010, // Accessed via ldftn
// Field access flags
CORINFO_ACCESS_GET = 0x0100, // Field get (ldfld)
CORINFO_ACCESS_SET = 0x0200, // Field set (stfld)
CORINFO_ACCESS_ADDRESS = 0x0400, // Field address (ldflda)
CORINFO_ACCESS_INIT_ARRAY = 0x0800, // Field use for InitializeArray
// UNUSED = 0x4000,
CORINFO_ACCESS_INLINECHECK= 0x8000, // Return fieldFlags and fieldAccessor only. Used by JIT64 during inlining.
};
// These are the flags set on an CORINFO_EH_CLAUSE
enum CORINFO_EH_CLAUSE_FLAGS
{
CORINFO_EH_CLAUSE_NONE = 0,
CORINFO_EH_CLAUSE_FILTER = 0x0001, // If this bit is on, then this EH entry is for a filter
CORINFO_EH_CLAUSE_FINALLY = 0x0002, // This clause is a finally clause
CORINFO_EH_CLAUSE_FAULT = 0x0004, // This clause is a fault clause
CORINFO_EH_CLAUSE_DUPLICATE = 0x0008, // Duplicated clause. This clause was duplicated to a funclet which was pulled out of line
CORINFO_EH_CLAUSE_SAMETRY = 0x0010, // This clause covers same try block as the previous one
};
// This enumeration is passed to InternalThrow
enum CorInfoException
{
CORINFO_NullReferenceException,
CORINFO_DivideByZeroException,
CORINFO_InvalidCastException,
CORINFO_IndexOutOfRangeException,
CORINFO_OverflowException,
CORINFO_SynchronizationLockException,
CORINFO_ArrayTypeMismatchException,
CORINFO_RankException,
CORINFO_ArgumentNullException,
CORINFO_ArgumentException,
CORINFO_Exception_Count,
};
// These are used to detect array methods as NamedIntrinsic in JIT importer,
// which otherwise don't have a name.
enum class CorInfoArrayIntrinsic
{
GET = 0,
SET = 1,
ADDRESS = 2,
ILLEGAL
};
// Can a value be accessed directly from JITed code.
enum InfoAccessType
{
IAT_VALUE, // The info value is directly available
IAT_PVALUE, // The value needs to be accessed via an indirection
IAT_PPVALUE, // The value needs to be accessed via a double indirection
IAT_RELPVALUE // The value needs to be accessed via a relative indirection
};
enum CorInfoGCType
{
TYPE_GC_NONE, // no embedded objectrefs
TYPE_GC_REF, // Is an object ref
TYPE_GC_BYREF, // Is an interior pointer - promote it but don't scan it
TYPE_GC_OTHER // requires type-specific treatment
};
enum CorInfoClassId
{
CLASSID_SYSTEM_OBJECT,
CLASSID_TYPED_BYREF,
CLASSID_TYPE_HANDLE,
CLASSID_FIELD_HANDLE,
CLASSID_METHOD_HANDLE,
CLASSID_STRING,
CLASSID_ARGUMENT_HANDLE,
CLASSID_RUNTIME_TYPE,
};
enum CorInfoInline
{
INLINE_PASS = 0, // Inlining OK
INLINE_PREJIT_SUCCESS = 1, // Inline check for prejit checking usage succeeded
INLINE_CHECK_CAN_INLINE_SUCCESS = 2, // JIT detected it is permitted to try to actually inline
INLINE_CHECK_CAN_INLINE_VMFAIL = 3, // VM specified that inline must fail via the CanInline api
// failures are negative
INLINE_FAIL = -1, // Inlining not OK for this case only
INLINE_NEVER = -2, // This method should never be inlined, regardless of context
};
// If you add more values here, keep it in sync with TailCallTypeMap in ..\vm\ClrEtwAll.man
// and the string enum in CEEInfo::reportTailCallDecision in ..\vm\JITInterface.cpp
enum CorInfoTailCall
{
TAILCALL_OPTIMIZED = 0, // Optimized tail call (epilog + jmp)
TAILCALL_RECURSIVE = 1, // Optimized into a loop (only when a method tail calls itself)
TAILCALL_HELPER = 2, // Helper assisted tail call (call to JIT_TailCall)
// failures are negative
TAILCALL_FAIL = -1, // Couldn't do a tail call