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 | // Macro template for inline observations |
6 | // |
7 | // INLINE_OBSERVATION(name, type, description, impact, target) |
8 | // |
9 | // name will be used to create an InlineObservation enum member |
10 | // (enum name prepends scope, eg CALLEE_MARKED_AS_SKIPPED) |
11 | // type is the data type for the observation |
12 | // description is a user string for diagnostics |
13 | // impact is one of the members of InlineImpact |
14 | // target is one of the members of InlineTarget |
15 | // |
16 | // Note: the impact classification is work in progress. |
17 | // |
18 | // Some subset of the FATAL cases here can be refined to SERIOUS, |
19 | // LIMITATION, or PERFORMANCE. While the refined observations may |
20 | // eventually veto inlining, the jit can safely keep making more |
21 | // observations. |
22 | |
23 | // ------ Initial Sentinel ------- |
24 | |
25 | INLINE_OBSERVATION(UNUSED_INITIAL, bool, "unused initial observation" , FATAL, CALLEE) |
26 | |
27 | // ------ Callee Fatal ------- |
28 | |
29 | INLINE_OBSERVATION(BAD_ARGUMENT_NUMBER, bool, "invalid argument number" , FATAL, CALLEE) |
30 | INLINE_OBSERVATION(BAD_LOCAL_NUMBER, bool, "invalid local number" , FATAL, CALLEE) |
31 | INLINE_OBSERVATION(CLASS_INIT_FAILURE, bool, "class init failed" , FATAL, CALLEE) |
32 | INLINE_OBSERVATION(COMPILATION_ERROR, bool, "compilation error" , FATAL, CALLEE) |
33 | INLINE_OBSERVATION(EXCEEDS_THRESHOLD, bool, "exceeds profit threshold" , FATAL, CALLEE) |
34 | INLINE_OBSERVATION(HAS_DELEGATE_INVOKE, bool, "delegate invoke" , FATAL, CALLEE) |
35 | INLINE_OBSERVATION(HAS_EH, bool, "has exception handling" , FATAL, CALLEE) |
36 | INLINE_OBSERVATION(HAS_ENDFILTER, bool, "has endfilter" , FATAL, CALLEE) |
37 | INLINE_OBSERVATION(HAS_ENDFINALLY, bool, "has endfinally" , FATAL, CALLEE) |
38 | INLINE_OBSERVATION(HAS_LEAVE, bool, "has leave" , FATAL, CALLEE) |
39 | INLINE_OBSERVATION(HAS_MANAGED_VARARGS, bool, "managed varargs" , FATAL, CALLEE) |
40 | INLINE_OBSERVATION(HAS_NATIVE_VARARGS, bool, "native varargs" , FATAL, CALLEE) |
41 | INLINE_OBSERVATION(HAS_NO_BODY, bool, "has no body" , FATAL, CALLEE) |
42 | INLINE_OBSERVATION(HAS_NULL_FOR_LDELEM, bool, "has null pointer for ldelem" , FATAL, CALLEE) |
43 | INLINE_OBSERVATION(IS_ARRAY_METHOD, bool, "is array method" , FATAL, CALLEE) |
44 | INLINE_OBSERVATION(IS_GENERIC_VIRTUAL, bool, "generic virtual" , FATAL, CALLEE) |
45 | INLINE_OBSERVATION(IS_JIT_NOINLINE, bool, "noinline per JitNoinline" , FATAL, CALLEE) |
46 | INLINE_OBSERVATION(IS_NOINLINE, bool, "noinline per IL/cached result" , FATAL, CALLEE) |
47 | INLINE_OBSERVATION(IS_SYNCHRONIZED, bool, "is synchronized" , FATAL, CALLEE) |
48 | INLINE_OBSERVATION(IS_VM_NOINLINE, bool, "noinline per VM" , FATAL, CALLEE) |
49 | INLINE_OBSERVATION(LACKS_RETURN, bool, "no return opcode" , FATAL, CALLEE) |
50 | INLINE_OBSERVATION(LDFLD_NEEDS_HELPER, bool, "ldfld needs helper" , FATAL, CALLEE) |
51 | INLINE_OBSERVATION(LOCALLOC_TOO_LARGE, bool, "localloc size too large" , FATAL, CALLEE) |
52 | INLINE_OBSERVATION(LOG_REPLAY_REJECT, bool, "rejected by log replay" , FATAL, CALLEE) |
53 | INLINE_OBSERVATION(MARKED_AS_SKIPPED, bool, "skipped by complus request" , FATAL, CALLEE) |
54 | INLINE_OBSERVATION(MAXSTACK_TOO_BIG, bool, "maxstack too big" , FATAL, CALLEE) |
55 | INLINE_OBSERVATION(NEEDS_SECURITY_CHECK, bool, "needs security check" , FATAL, CALLEE) |
56 | INLINE_OBSERVATION(NO_METHOD_INFO, bool, "cannot get method info" , FATAL, CALLEE) |
57 | INLINE_OBSERVATION(NOT_PROFITABLE_INLINE, bool, "unprofitable inline" , FATAL, CALLEE) |
58 | INLINE_OBSERVATION(RANDOM_REJECT, bool, "random reject" , FATAL, CALLEE) |
59 | INLINE_OBSERVATION(STACK_CRAWL_MARK, bool, "uses stack crawl mark" , FATAL, CALLEE) |
60 | INLINE_OBSERVATION(STFLD_NEEDS_HELPER, bool, "stfld needs helper" , FATAL, CALLEE) |
61 | INLINE_OBSERVATION(THROW_WITH_INVALID_STACK, bool, "throw with invalid stack" , FATAL, CALLEE) |
62 | INLINE_OBSERVATION(TOO_MANY_ARGUMENTS, bool, "too many arguments" , FATAL, CALLEE) |
63 | INLINE_OBSERVATION(TOO_MANY_LOCALS, bool, "too many locals" , FATAL, CALLEE) |
64 | INLINE_OBSERVATION(EXPLICIT_TAIL_PREFIX, bool, "explicit tail prefix in callee" ,FATAL, CALLEE) |
65 | |
66 | // ------ Callee Performance ------- |
67 | |
68 | INLINE_OBSERVATION(LDFLD_STATIC_VALUECLASS, bool, "ldsfld of value class" , PERFORMANCE, CALLEE) |
69 | INLINE_OBSERVATION(TOO_MANY_BASIC_BLOCKS, bool, "too many basic blocks" , PERFORMANCE, CALLEE) |
70 | INLINE_OBSERVATION(TOO_MUCH_IL, bool, "too many il bytes" , PERFORMANCE, CALLEE) |
71 | |
72 | // ------ Callee Information ------- |
73 | |
74 | INLINE_OBSERVATION(ARG_FEEDS_CONSTANT_TEST, bool, "argument feeds constant test" , INFORMATION, CALLEE) |
75 | INLINE_OBSERVATION(ARG_FEEDS_TEST, bool, "argument feeds test" , INFORMATION, CALLEE) |
76 | INLINE_OBSERVATION(ARG_FEEDS_RANGE_CHECK, bool, "argument feeds range check" , INFORMATION, CALLEE) |
77 | INLINE_OBSERVATION(BEGIN_OPCODE_SCAN, bool, "prepare to look at opcodes" , INFORMATION, CALLEE) |
78 | INLINE_OBSERVATION(BELOW_ALWAYS_INLINE_SIZE, bool, "below ALWAYS_INLINE size" , INFORMATION, CALLEE) |
79 | INLINE_OBSERVATION(CLASS_PROMOTABLE, bool, "promotable value class" , INFORMATION, CALLEE) |
80 | INLINE_OBSERVATION(DOES_NOT_RETURN, bool, "does not return" , INFORMATION, CALLEE) |
81 | INLINE_OBSERVATION(END_OPCODE_SCAN, bool, "done looking at opcodes" , INFORMATION, CALLEE) |
82 | INLINE_OBSERVATION(HAS_GC_STRUCT, bool, "has gc field in struct local" , INFORMATION, CALLEE) |
83 | INLINE_OBSERVATION(HAS_LOCALLOC, bool, "has localloc" , INFORMATION, CALLEE) |
84 | INLINE_OBSERVATION(HAS_PINNED_LOCALS, bool, "has pinned locals" , INFORMATION, CALLEE) |
85 | INLINE_OBSERVATION(HAS_SIMD, bool, "has SIMD arg, local, or ret" , INFORMATION, CALLEE) |
86 | INLINE_OBSERVATION(HAS_SWITCH, bool, "has switch" , INFORMATION, CALLEE) |
87 | INLINE_OBSERVATION(IL_CODE_SIZE, int, "number of bytes of IL" , INFORMATION, CALLEE) |
88 | INLINE_OBSERVATION(IS_CLASS_CTOR, bool, "class constructor" , INFORMATION, CALLEE) |
89 | INLINE_OBSERVATION(IS_DISCRETIONARY_INLINE, bool, "can inline, check heuristics" , INFORMATION, CALLEE) |
90 | INLINE_OBSERVATION(IS_FORCE_INLINE, bool, "aggressive inline attribute" , INFORMATION, CALLEE) |
91 | INLINE_OBSERVATION(IS_INSTANCE_CTOR, bool, "instance constructor" , INFORMATION, CALLEE) |
92 | INLINE_OBSERVATION(IS_PROFITABLE_INLINE, bool, "profitable inline" , INFORMATION, CALLEE) |
93 | INLINE_OBSERVATION(IS_SIZE_DECREASING_INLINE, bool, "size decreasing inline" , INFORMATION, CALLEE) |
94 | INLINE_OBSERVATION(LOG_REPLAY_ACCEPT, bool, "accepted by log replay" , INFORMATION, CALLEE) |
95 | INLINE_OBSERVATION(LOOKS_LIKE_WRAPPER, bool, "thin wrapper around a call" , INFORMATION, CALLEE) |
96 | INLINE_OBSERVATION(MAXSTACK, int, "maxstack" , INFORMATION, CALLEE) |
97 | INLINE_OBSERVATION(OPCODE, int, "next opcode in IL stream" , INFORMATION, CALLEE) |
98 | INLINE_OBSERVATION(OPCODE_NORMED, int, "next opcode in IL stream" , INFORMATION, CALLEE) |
99 | INLINE_OBSERVATION(NUMBER_OF_ARGUMENTS, int, "number of arguments" , INFORMATION, CALLEE) |
100 | INLINE_OBSERVATION(NUMBER_OF_BASIC_BLOCKS, int, "number of basic blocks" , INFORMATION, CALLEE) |
101 | INLINE_OBSERVATION(NUMBER_OF_LOCALS, int, "number of locals" , INFORMATION, CALLEE) |
102 | INLINE_OBSERVATION(RANDOM_ACCEPT, bool, "random accept" , INFORMATION, CALLEE) |
103 | INLINE_OBSERVATION(UNSUPPORTED_OPCODE, bool, "unsupported opcode" , INFORMATION, CALLEE) |
104 | |
105 | // ------ Caller Correctness ------- |
106 | |
107 | INLINE_OBSERVATION(DEBUG_CODEGEN, bool, "debug codegen" , FATAL, CALLER) |
108 | INLINE_OBSERVATION(IS_JIT_NOINLINE, bool, "noinline per JitNoInlineRange" , FATAL, CALLER) |
109 | INLINE_OBSERVATION(NEEDS_SECURITY_CHECK, bool, "needs security check" , FATAL, CALLER) |
110 | |
111 | // ------ Caller Information ------- |
112 | |
113 | INLINE_OBSERVATION(HAS_NEWARRAY, bool, "has newarray" , INFORMATION, CALLER) |
114 | INLINE_OBSERVATION(HAS_NEWOBJ, bool, "has newobj" , INFORMATION, CALLER) |
115 | |
116 | // ------ Call Site Correctness ------- |
117 | |
118 | INLINE_OBSERVATION(ARG_HAS_NULL_THIS, bool, "this pointer argument is null" , FATAL, CALLSITE) |
119 | INLINE_OBSERVATION(ARG_IS_MKREFANY, bool, "argument is mkrefany" , FATAL, CALLSITE) |
120 | INLINE_OBSERVATION(ARG_NO_BASH_TO_INT, bool, "argument can't bash to int" , FATAL, CALLSITE) |
121 | INLINE_OBSERVATION(ARG_NO_BASH_TO_REF, bool, "argument can't bash to ref" , FATAL, CALLSITE) |
122 | INLINE_OBSERVATION(ARG_TYPES_INCOMPATIBLE, bool, "argument types incompatible" , FATAL, CALLSITE) |
123 | INLINE_OBSERVATION(CANT_EMBED_PINVOKE_COOKIE, bool, "can't embed pinvoke cookie" , FATAL, CALLSITE) |
124 | INLINE_OBSERVATION(CANT_EMBED_VARARGS_COOKIE, bool, "can't embed varargs cookie" , FATAL, CALLSITE) |
125 | INLINE_OBSERVATION(CLASS_INIT_FAILURE_SPEC, bool, "speculative class init failed" , FATAL, CALLSITE) |
126 | INLINE_OBSERVATION(COMPILATION_ERROR, bool, "compilation error" , FATAL, CALLSITE) |
127 | INLINE_OBSERVATION(COMPILATION_FAILURE, bool, "failed to compile" , FATAL, CALLSITE) |
128 | INLINE_OBSERVATION(CROSS_BOUNDARY_CALLI, bool, "cross-boundary calli" , FATAL, CALLSITE) |
129 | INLINE_OBSERVATION(CROSS_BOUNDARY_SECURITY, bool, "cross-boundary security check" , FATAL, CALLSITE) |
130 | INLINE_OBSERVATION(EXCEEDS_THRESHOLD, bool, "exceeds profit threshold" , FATAL, CALLSITE) |
131 | INLINE_OBSERVATION(EXPLICIT_TAIL_PREFIX, bool, "explicit tail prefix" , FATAL, CALLSITE) |
132 | INLINE_OBSERVATION(GENERIC_DICTIONARY_LOOKUP, bool, "runtime dictionary lookup" , FATAL, CALLSITE) |
133 | INLINE_OBSERVATION(HAS_CALL_VIA_LDVIRTFTN, bool, "call via ldvirtftn" , FATAL, CALLSITE) |
134 | INLINE_OBSERVATION(HAS_COMPLEX_HANDLE, bool, "complex handle access" , FATAL, CALLSITE) |
135 | INLINE_OBSERVATION(HAS_LDSTR_RESTRICTION, bool, "has ldstr VM restriction" , FATAL, CALLSITE) |
136 | INLINE_OBSERVATION(IMPLICIT_REC_TAIL_CALL, bool, "implicit recursive tail call" , FATAL, CALLSITE) |
137 | INLINE_OBSERVATION(IS_CALL_TO_HELPER, bool, "target is helper" , FATAL, CALLSITE) |
138 | INLINE_OBSERVATION(IS_NOT_DIRECT, bool, "target not direct" , FATAL, CALLSITE) |
139 | INLINE_OBSERVATION(IS_NOT_DIRECT_MANAGED, bool, "target not direct managed" , FATAL, CALLSITE) |
140 | INLINE_OBSERVATION(IS_RECURSIVE, bool, "recursive" , FATAL, CALLSITE) |
141 | INLINE_OBSERVATION(IS_TOO_DEEP, bool, "too deep" , FATAL, CALLSITE) |
142 | INLINE_OBSERVATION(IS_VIRTUAL, bool, "virtual" , FATAL, CALLSITE) |
143 | INLINE_OBSERVATION(IS_VM_NOINLINE, bool, "noinline per VM" , FATAL, CALLSITE) |
144 | INLINE_OBSERVATION(IS_WITHIN_CATCH, bool, "within catch region" , FATAL, CALLSITE) |
145 | INLINE_OBSERVATION(IS_WITHIN_FILTER, bool, "within filter region" , FATAL, CALLSITE) |
146 | INLINE_OBSERVATION(LDARGA_NOT_LOCAL_VAR, bool, "ldarga not on local var" , FATAL, CALLSITE) |
147 | INLINE_OBSERVATION(LDFLD_NEEDS_HELPER, bool, "ldfld needs helper" , FATAL, CALLSITE) |
148 | INLINE_OBSERVATION(LDVIRTFN_ON_NON_VIRTUAL, bool, "ldvirtfn on non-virtual" , FATAL, CALLSITE) |
149 | INLINE_OBSERVATION(LOCALLOC_IN_LOOP, bool, "within loop, has localloc" , FATAL, CALLSITE) |
150 | INLINE_OBSERVATION(LOCALLOC_SIZE_UNKNOWN, bool, "localloc size unknown" , FATAL, CALLSITE) |
151 | INLINE_OBSERVATION(LOG_REPLAY_REJECT, bool, "rejected by log replay" , FATAL, CALLSITE) |
152 | INLINE_OBSERVATION(NOT_CANDIDATE, bool, "not inline candidate" , FATAL, CALLSITE) |
153 | INLINE_OBSERVATION(NOT_PROFITABLE_INLINE, bool, "unprofitable inline" , FATAL, CALLSITE) |
154 | INLINE_OBSERVATION(OVER_BUDGET, bool, "inline exceeds budget" , FATAL, CALLSITE) |
155 | INLINE_OBSERVATION(OVER_INLINE_LIMIT, bool, "limited by JitInlineLimit" , FATAL, CALLSITE) |
156 | INLINE_OBSERVATION(PIN_IN_TRY_REGION, bool, "within try region, pinned" , FATAL, CALLSITE) |
157 | INLINE_OBSERVATION(RANDOM_REJECT, bool, "random reject" , FATAL, CALLSITE) |
158 | INLINE_OBSERVATION(REQUIRES_SAME_THIS, bool, "requires same this" , FATAL, CALLSITE) |
159 | INLINE_OBSERVATION(RETURN_TYPE_MISMATCH, bool, "return type mismatch" , FATAL, CALLSITE) |
160 | INLINE_OBSERVATION(STFLD_NEEDS_HELPER, bool, "stfld needs helper" , FATAL, CALLSITE) |
161 | INLINE_OBSERVATION(TOO_MANY_LOCALS, bool, "too many locals" , FATAL, CALLSITE) |
162 | INLINE_OBSERVATION(PINVOKE_EH, bool, "PInvoke call site with EH" , FATAL, CALLSITE) |
163 | |
164 | // ------ Call Site Performance ------- |
165 | |
166 | INLINE_OBSERVATION(RARE_GC_STRUCT, bool, "rarely called, has gc struct" , INFORMATION, CALLSITE) |
167 | |
168 | // ------ Call Site Information ------- |
169 | |
170 | INLINE_OBSERVATION(CONSTANT_ARG_FEEDS_TEST, bool, "constant argument feeds test" , INFORMATION, CALLSITE) |
171 | INLINE_OBSERVATION(DEPTH, int, "depth" , INFORMATION, CALLSITE) |
172 | INLINE_OBSERVATION(FREQUENCY, int, "rough call site frequency" , INFORMATION, CALLSITE) |
173 | INLINE_OBSERVATION(IN_LOOP, bool, "call site is in a loop" , INFORMATION, CALLSITE) |
174 | INLINE_OBSERVATION(IN_TRY_REGION, bool, "call site is in a try region" , INFORMATION, CALLSITE) |
175 | INLINE_OBSERVATION(IS_PROFITABLE_INLINE, bool, "profitable inline" , INFORMATION, CALLSITE) |
176 | INLINE_OBSERVATION(IS_SAME_THIS, bool, "same this as root caller" , INFORMATION, CALLSITE) |
177 | INLINE_OBSERVATION(IS_SIZE_DECREASING_INLINE, bool, "size decreasing inline" , INFORMATION, CALLSITE) |
178 | INLINE_OBSERVATION(LOG_REPLAY_ACCEPT, bool, "accepted by log replay" , INFORMATION, CALLSITE) |
179 | INLINE_OBSERVATION(RANDOM_ACCEPT, bool, "random accept" , INFORMATION, CALLSITE) |
180 | INLINE_OBSERVATION(WEIGHT, int, "call site frequency" , INFORMATION, CALLSITE) |
181 | |
182 | // ------ Final Sentinel ------- |
183 | |
184 | INLINE_OBSERVATION(UNUSED_FINAL, bool, "unused final observation" , FATAL, CALLEE) |
185 | |
186 | |