| 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 | |