1 /* 2 * Licensed to the .NET Foundation under one or more agreements. 3 * The .NET Foundation licenses this file to you under the MIT license. 4 * See the LICENSE file in the project root for more information. 5 */ 6 7 #ifndef __MONO_PROFILER_H__ 8 #define __MONO_PROFILER_H__ 9 10 #include <mono/metadata/appdomain.h> 11 #include <mono/metadata/mono-gc.h> 12 #include <mono/metadata/object.h> 13 14 MONO_BEGIN_DECLS 15 16 /** 17 * This value will be incremented whenever breaking changes to the profiler API 18 * are made. This macro is intended for use in profiler modules that wish to 19 * support older versions of the profiler API. 20 */ 21 #define MONO_PROFILER_API_VERSION 2 22 23 typedef struct _MonoProfiler MonoProfiler; 24 typedef struct _MonoProfilerDesc *MonoProfilerHandle; 25 26 typedef void (*MonoProfilerCleanupCallback) (MonoProfiler *prof); 27 28 MONO_API void mono_profiler_load (const char *desc); 29 MONO_API MonoProfilerHandle mono_profiler_create (MonoProfiler *prof); 30 MONO_API void mono_profiler_set_cleanup_callback (MonoProfilerHandle handle, MonoProfilerCleanupCallback cb); 31 32 typedef struct { 33 MonoMethod *method; 34 uint32_t il_offset; 35 uint32_t counter; 36 const char *file_name; 37 uint32_t line; 38 uint32_t column; 39 } MonoProfilerCoverageData; 40 41 typedef mono_bool (*MonoProfilerCoverageFilterCallback) (MonoProfiler *prof, MonoMethod *method); 42 typedef void (*MonoProfilerCoverageCallback) (MonoProfiler *prof, const MonoProfilerCoverageData *data); 43 44 MONO_API mono_bool mono_profiler_enable_coverage (void); 45 MONO_API void mono_profiler_set_coverage_filter_callback (MonoProfilerHandle handle, MonoProfilerCoverageFilterCallback cb); 46 MONO_API mono_bool mono_profiler_get_coverage_data (MonoProfilerHandle handle, MonoMethod *method, MonoProfilerCoverageCallback cb); 47 48 typedef enum { 49 /** 50 * Do not perform sampling. Will make the sampling thread sleep until the 51 * sampling mode is changed to one of the below modes. 52 */ 53 MONO_PROFILER_SAMPLE_MODE_NONE = 0, 54 /** 55 * Try to base sampling frequency on process activity. Falls back to 56 * MONO_PROFILER_SAMPLE_MODE_REAL if such a clock is not available. 57 */ 58 MONO_PROFILER_SAMPLE_MODE_PROCESS = 1, 59 /** 60 * Base sampling frequency on wall clock time. Uses a monotonic clock when 61 * available (all major platforms). 62 */ 63 MONO_PROFILER_SAMPLE_MODE_REAL = 2, 64 } MonoProfilerSampleMode; 65 66 MONO_API mono_bool mono_profiler_enable_sampling (MonoProfilerHandle handle); 67 MONO_API mono_bool mono_profiler_set_sample_mode (MonoProfilerHandle handle, MonoProfilerSampleMode mode, uint32_t freq); 68 MONO_API mono_bool mono_profiler_get_sample_mode (MonoProfilerHandle handle, MonoProfilerSampleMode *mode, uint32_t *freq); 69 70 MONO_API mono_bool mono_profiler_enable_allocations (void); 71 72 typedef struct _MonoProfilerCallContext MonoProfilerCallContext; 73 74 typedef enum { 75 /** 76 * Do not instrument calls. 77 */ 78 MONO_PROFILER_CALL_INSTRUMENTATION_NONE = 0, 79 /** 80 * Instrument method entries. 81 */ 82 MONO_PROFILER_CALL_INSTRUMENTATION_ENTER = 1 << 1, 83 /** 84 * Also capture a call context for method entries. 85 */ 86 MONO_PROFILER_CALL_INSTRUMENTATION_ENTER_CONTEXT = 1 << 2, 87 /** 88 * Instrument method exits. 89 */ 90 MONO_PROFILER_CALL_INSTRUMENTATION_LEAVE = 1 << 3, 91 /** 92 * Also capture a call context for method exits. 93 */ 94 MONO_PROFILER_CALL_INSTRUMENTATION_LEAVE_CONTEXT = 1 << 4, 95 /** 96 * Instrument method exits as a result of a tail call. 97 */ 98 MONO_PROFILER_CALL_INSTRUMENTATION_TAIL_CALL = 1 << 5, 99 /** 100 * Instrument exceptional method exits. 101 */ 102 MONO_PROFILER_CALL_INSTRUMENTATION_EXCEPTION_LEAVE = 1 << 6, 103 } MonoProfilerCallInstrumentationFlags; 104 105 typedef MonoProfilerCallInstrumentationFlags (*MonoProfilerCallInstrumentationFilterCallback) (MonoProfiler *prof, MonoMethod *method); 106 107 MONO_API void mono_profiler_set_call_instrumentation_filter_callback (MonoProfilerHandle handle, MonoProfilerCallInstrumentationFilterCallback cb); 108 MONO_API mono_bool mono_profiler_enable_call_context_introspection (void); 109 MONO_API void *mono_profiler_call_context_get_this (MonoProfilerCallContext *context); 110 MONO_API void *mono_profiler_call_context_get_argument (MonoProfilerCallContext *context, uint32_t position); 111 MONO_API void *mono_profiler_call_context_get_local (MonoProfilerCallContext *context, uint32_t position); 112 MONO_API void *mono_profiler_call_context_get_result (MonoProfilerCallContext *context); 113 MONO_API void mono_profiler_call_context_free_buffer (void *buffer); 114 115 #ifdef MONO_PROFILER_UNSTABLE_GC_ROOTS 116 typedef enum { 117 /* Upper 2 bytes. */ 118 MONO_PROFILER_GC_ROOT_PINNING = 1 << 8, 119 MONO_PROFILER_GC_ROOT_WEAKREF = 2 << 8, 120 MONO_PROFILER_GC_ROOT_INTERIOR = 4 << 8, 121 122 /* Lower 2 bytes (flags). */ 123 MONO_PROFILER_GC_ROOT_STACK = 1 << 0, 124 MONO_PROFILER_GC_ROOT_FINALIZER = 1 << 1, 125 MONO_PROFILER_GC_ROOT_HANDLE = 1 << 2, 126 MONO_PROFILER_GC_ROOT_OTHER = 1 << 3, 127 MONO_PROFILER_GC_ROOT_MISC = 1 << 4, 128 129 MONO_PROFILER_GC_ROOT_TYPEMASK = 0xff, 130 } MonoProfilerGCRootType; 131 #endif 132 133 typedef enum { 134 /** 135 * The \c data parameter is a \c MonoMethod pointer. 136 */ 137 MONO_PROFILER_CODE_BUFFER_METHOD = 0, 138 MONO_PROFILER_CODE_BUFFER_METHOD_TRAMPOLINE = 1, 139 MONO_PROFILER_CODE_BUFFER_UNBOX_TRAMPOLINE = 2, 140 MONO_PROFILER_CODE_BUFFER_IMT_TRAMPOLINE = 3, 141 MONO_PROFILER_CODE_BUFFER_GENERICS_TRAMPOLINE = 4, 142 /** 143 * The \c data parameter is a C string. 144 */ 145 MONO_PROFILER_CODE_BUFFER_SPECIFIC_TRAMPOLINE = 5, 146 MONO_PROFILER_CODE_BUFFER_HELPER = 6, 147 MONO_PROFILER_CODE_BUFFER_MONITOR = 7, 148 MONO_PROFILER_CODE_BUFFER_DELEGATE_INVOKE = 8, 149 MONO_PROFILER_CODE_BUFFER_EXCEPTION_HANDLING = 9, 150 } MonoProfilerCodeBufferType; 151 152 typedef enum { 153 MONO_GC_EVENT_PRE_STOP_WORLD = 6, 154 /** 155 * When this event arrives, the GC and suspend locks are acquired. 156 */ 157 MONO_GC_EVENT_PRE_STOP_WORLD_LOCKED = 10, 158 MONO_GC_EVENT_POST_STOP_WORLD = 7, 159 MONO_GC_EVENT_START = 0, 160 MONO_GC_EVENT_END = 5, 161 MONO_GC_EVENT_PRE_START_WORLD = 8, 162 /** 163 * When this event arrives, the GC and suspend locks are released. 164 */ 165 MONO_GC_EVENT_POST_START_WORLD_UNLOCKED = 11, 166 MONO_GC_EVENT_POST_START_WORLD = 9, 167 } MonoProfilerGCEvent; 168 169 /* 170 * The macros below will generate the majority of the callback API. Refer to 171 * mono/metadata/profiler-events.h for a list of callbacks. They are expanded 172 * like so: 173 * 174 * typedef void (*MonoProfilerRuntimeInitializedCallback (MonoProfiler *prof); 175 * MONO_API void mono_profiler_set_runtime_initialized_callback (MonoProfiler *prof, MonoProfilerRuntimeInitializedCallback cb); 176 * 177 * typedef void (*MonoProfilerRuntimeShutdownCallback (MonoProfiler *prof); 178 * MONO_API void mono_profiler_set_runtime_shutdown_callback (MonoProfiler *prof, MonoProfilerRuntimeShutdownCallback cb); 179 * 180 * typedef void (*MonoProfilerContextLoadedCallback (MonoProfiler *prof); 181 * MONO_API void mono_profiler_set_context_loaded_callback (MonoProfiler *prof, MonoProfilerContextLoadedCallback cb); 182 * 183 * typedef void (*MonoProfilerContextUnloadedCallback (MonoProfiler *prof); 184 * MONO_API void mono_profiler_set_context_unloaded_callback (MonoProfiler *prof, MonoProfilerContextUnloadedCallback cb); 185 * 186 * Etc. 187 * 188 * To remove a callback, pass NULL instead of a valid function pointer. 189 * Callbacks can be changed at any point, but note that doing so is inherently 190 * racy with respect to threads that aren't suspended, i.e. you may still see a 191 * call from another thread right after you change a callback. 192 * 193 * These functions are async safe. 194 */ 195 196 #define _MONO_PROFILER_EVENT(type, ...) \ 197 typedef void (*MonoProfiler ## type ## Callback) (__VA_ARGS__); 198 #define MONO_PROFILER_EVENT_0(name, type) \ 199 _MONO_PROFILER_EVENT(type, MonoProfiler *prof) 200 #define MONO_PROFILER_EVENT_1(name, type, arg1_type, arg1_name) \ 201 _MONO_PROFILER_EVENT(type, MonoProfiler *prof, arg1_type arg1_name) 202 #define MONO_PROFILER_EVENT_2(name, type, arg1_type, arg1_name, arg2_type, arg2_name) \ 203 _MONO_PROFILER_EVENT(type, MonoProfiler *prof, arg1_type arg1_name, arg2_type arg2_name) 204 #define MONO_PROFILER_EVENT_3(name, type, arg1_type, arg1_name, arg2_type, arg2_name, arg3_type, arg3_name) \ 205 _MONO_PROFILER_EVENT(type, MonoProfiler *prof, arg1_type arg1_name, arg2_type arg2_name, arg3_type arg3_name) 206 #define MONO_PROFILER_EVENT_4(name, type, arg1_type, arg1_name, arg2_type, arg2_name, arg3_type, arg3_name, arg4_type, arg4_name) \ 207 _MONO_PROFILER_EVENT(type, MonoProfiler *prof, arg1_type arg1_name, arg2_type arg2_name, arg3_type arg3_name, arg4_type arg4_name) 208 #include <mono/metadata/profiler-events.h> 209 #undef MONO_PROFILER_EVENT_0 210 #undef MONO_PROFILER_EVENT_1 211 #undef MONO_PROFILER_EVENT_2 212 #undef MONO_PROFILER_EVENT_3 213 #undef MONO_PROFILER_EVENT_4 214 #undef _MONO_PROFILER_EVENT 215 216 #define _MONO_PROFILER_EVENT(name, type) \ 217 MONO_API void mono_profiler_set_ ## name ## _callback (MonoProfilerHandle handle, MonoProfiler ## type ## Callback cb); 218 #define MONO_PROFILER_EVENT_0(name, type) \ 219 _MONO_PROFILER_EVENT(name, type) 220 #define MONO_PROFILER_EVENT_1(name, type, arg1_type, arg1_name) \ 221 _MONO_PROFILER_EVENT(name, type) 222 #define MONO_PROFILER_EVENT_2(name, type, arg1_type, arg1_name, arg2_type, arg2_name) \ 223 _MONO_PROFILER_EVENT(name, type) 224 #define MONO_PROFILER_EVENT_3(name, type, arg1_type, arg1_name, arg2_type, arg2_name, arg3_type, arg3_name) \ 225 _MONO_PROFILER_EVENT(name, type) 226 #define MONO_PROFILER_EVENT_4(name, type, arg1_type, arg1_name, arg2_type, arg2_name, arg3_type, arg3_name, arg4_type, arg4_name) \ 227 _MONO_PROFILER_EVENT(name, type) 228 #include <mono/metadata/profiler-events.h> 229 #undef MONO_PROFILER_EVENT_0 230 #undef MONO_PROFILER_EVENT_1 231 #undef MONO_PROFILER_EVENT_2 232 #undef MONO_PROFILER_EVENT_3 233 #undef MONO_PROFILER_EVENT_4 234 #undef _MONO_PROFILER_EVENT 235 236 MONO_END_DECLS 237 238 #endif // __MONO_PROFILER_H__ 239