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.
7 #ifndef __MONO_PROFILER_H__
8 #define __MONO_PROFILER_H__
10 #include <mono/metadata/appdomain.h>
11 #include <mono/metadata/mono-gc.h>
12 #include <mono/metadata/object.h>
17 * Loads a profiler module based on the specified description. The description
18 * can be of the form "name:args" or just "name". For example, "log:sample" and
19 * "log" will both load "libmono-profiler-log.so". The description is passed to
20 * the module after it has been loaded. If the specified module has already
21 * been loaded, this function has no effect.
23 * A module should declare an entry point like so:
25 * void mono_profiler_init (const char *desc)
29 * This function is not async safe.
31 MONO_API void mono_profiler_load (const char *desc);
33 typedef struct _MonoProfiler MonoProfiler;
34 typedef struct _MonoProfilerDesc *MonoProfilerHandle;
37 * Installs a profiler and returns a handle for it. The handle is used with the
38 * other functions in the profiler API (e.g. for setting up callbacks).
40 * This function may only be called from your profiler's init function.
44 * struct _MonoProfiler {
49 * MonoProfiler *prof = calloc (1, sizeof (MonoProfiler));
50 * MonoProfilerHandle handle = mono_profiler_install (prof);
51 * mono_profiler_set_shutdown_callback (handle, my_shutdown_cb);
53 * This function is not async safe.
55 MONO_API MonoProfilerHandle mono_profiler_install (MonoProfiler *prof);
57 typedef mono_bool (*MonoProfilerCoverageFilterCallback) (MonoProfiler *prof, MonoMethod *method);
60 * Sets a code coverage filter function. The profiler API will invoke filter
61 * functions from all installed profilers. If any of them return TRUE, then the
62 * given method will be instrumented for coverage analysis. All filters are
63 * guaranteed to be called exactly once per method, even if an earlier filter
64 * has already returned TRUE.
66 * Note that filter functions must be installed before a method is compiled in
67 * order to have any effect, i.e. you should register your filter function in
68 * your profiler's init function.
70 * This function is async safe.
72 MONO_API void mono_profiler_set_coverage_filter_callback (MonoProfilerHandle handle, MonoProfilerCoverageFilterCallback cb);
78 const char *file_name;
81 } MonoProfilerCoverageData;
83 typedef void (*MonoProfilerCoverageCallback) (MonoProfiler *prof, const MonoProfilerCoverageData *data);
86 * Retrieves all coverage data for the specified method and invokes the given
87 * callback for each entry.
89 * This function is not async safe.
91 MONO_API void mono_profiler_get_coverage_data (MonoProfilerHandle handle, MonoMethod *method, MonoProfilerCoverageCallback cb);
95 * Do not perform sampling. Will make the sampling thread sleep until the
96 * sampling mode is changed to one of the below modes.
98 MONO_PROFILER_SAMPLE_MODE_NONE = 0,
100 * Try to base sampling frequency on process activity. Falls back to
101 * MONO_PROFILER_SAMPLE_MODE_REAL if such a clock is not available.
103 MONO_PROFILER_SAMPLE_MODE_PROCESS = 1,
105 * Base sampling frequency on wall clock time. Uses a monotonic clock when
106 * available (all major platforms).
108 MONO_PROFILER_SAMPLE_MODE_REAL = 2,
109 } MonoProfilerSampleMode;
112 * Enables the sampling thread. You must call this function if you intend to use
113 * statistical sampling; mono_profiler_set_sample_mode will have no effect if
114 * this function has not been called. The first profiler to call this function
115 * will get ownership over sampling settings (mode and frequency) so that no
116 * other profiler can change those settings. Returns TRUE if the sampling
117 * thread was enabled, or FALSE if the function was called too late for this
120 * Note that you still need to call mono_profiler_set_sample_mode with a mode
121 * other than MONO_PROFILER_SAMPLE_MODE_NONE to actually start sampling.
123 * This function may only be called from your profiler's init function.
125 * This function is not async safe.
127 MONO_API mono_bool mono_profiler_enable_sampling (MonoProfilerHandle handle);
130 * Sets the sampling mode and frequency (in Hz). If the calling profiler has
131 * ownership over sampling settings, the settings will be changed and this
132 * function will return TRUE; otherwise, it returns FALSE without changing any
135 * This function is async safe.
137 MONO_API mono_bool mono_profiler_set_sample_mode (MonoProfilerHandle handle, MonoProfilerSampleMode mode, uint64_t freq);
140 * Retrieves the current sampling mode and/or frequency (in Hz). Returns TRUE if
141 * the calling profiler is allowed to change the sampling settings; otherwise,
144 * This function is async safe.
146 MONO_API mono_bool mono_profiler_get_sample_mode (MonoProfilerHandle handle, MonoProfilerSampleMode *mode, uint64_t *freq);
149 * Enables instrumentation of GC allocations. This is necessary so that managed
150 * allocators can be instrumented with a call into the profiler API. Allocations
151 * will not be reported unless this function is called. Returns TRUE if
152 * allocation instrumentation was enabled, or FALSE if the function was called
153 * too late for this to be possible.
155 * This function may only be called from your profiler's init function.
157 * This function is not async safe.
159 MONO_API mono_bool mono_profiler_enable_allocations (void);
162 /* Do not instrument calls. */
163 MONO_PROFILER_CALL_INSTRUMENTATION_NONE = 1 << 0,
164 /* Instrument method prologues. */
165 MONO_PROFILER_CALL_INSTRUMENTATION_PROLOGUE = 1 << 1,
166 /* Instrument method epilogues. */
167 MONO_PROFILER_CALL_INSTRUMENTATION_EPILOGUE = 1 << 2,
168 } MonoProfilerCallInstrumentationFlags;
170 typedef MonoProfilerCallInstrumentationFlags (*MonoProfilerCallInstrumentationFilterCallback) (MonoProfiler *prof, MonoMethod *method);
173 * Sets a call instrumentation filter function. The profiler API will invoke
174 * filter functions from all installed profilers. If any of them return flags
175 * other than MONO_PROFILER_CALL_INSTRUMENTATION_NONE, then the given method
176 * will be instrumented as requested. All filters are guaranteed to be called
177 * at least once (possibly more) per method entry and exit, even if earlier
178 * filters have already specified all flags.
180 * Note that filter functions must be installed before a method is compiled in
181 * order to have any effect, i.e. you should register your filter function in
182 * your profiler's init function.
184 * Keep in mind that method instrumentation is extremely heavy and will slow
185 * down most applications to a crawl. Consider using sampling instead if it
186 * would work for your use case.
188 * This function is async safe.
190 MONO_API void mono_profiler_set_call_instrumentation_filter_callback (MonoProfilerHandle handle, MonoProfilerCallInstrumentationFilterCallback cb);
194 MONO_PROFILER_GC_ROOT_PINNING = 1 << 8,
195 MONO_PROFILER_GC_ROOT_WEAKREF = 2 << 8,
196 MONO_PROFILER_GC_ROOT_INTERIOR = 4 << 8,
198 /* Lower 2 bytes (flags). */
199 MONO_PROFILER_GC_ROOT_STACK = 1 << 0,
200 MONO_PROFILER_GC_ROOT_FINALIZER = 1 << 1,
201 MONO_PROFILER_GC_ROOT_HANDLE = 1 << 2,
202 MONO_PROFILER_GC_ROOT_OTHER = 1 << 3,
203 MONO_PROFILER_GC_ROOT_MISC = 1 << 4,
205 MONO_PROFILER_GC_ROOT_TYPEMASK = 0xff,
206 } MonoProfilerGCRootType;
209 /* data = MonoMethod *method */
210 MONO_PROFILER_CODE_BUFFER_METHOD = 0,
211 MONO_PROFILER_CODE_BUFFER_METHOD_TRAMPOLINE = 1,
212 MONO_PROFILER_CODE_BUFFER_UNBOX_TRAMPOLINE = 2,
213 MONO_PROFILER_CODE_BUFFER_IMT_TRAMPOLINE = 3,
214 MONO_PROFILER_CODE_BUFFER_GENERICS_TRAMPOLINE = 4,
215 /* data = const char *name */
216 MONO_PROFILER_CODE_BUFFER_SPECIFIC_TRAMPOLINE = 5,
217 MONO_PROFILER_CODE_BUFFER_HELPER = 6,
218 MONO_PROFILER_CODE_BUFFER_MONITOR = 7,
219 MONO_PROFILER_CODE_BUFFER_DELEGATE_INVOKE = 8,
220 MONO_PROFILER_CODE_BUFFER_EXCEPTION_HANDLING = 9,
221 } MonoProfilerCodeBufferType;
223 // Keep somewhat in sync with libgc/include/gc.h : GC_EventType.
225 MONO_GC_EVENT_START = 0,
226 MONO_GC_EVENT_MARK_START = 1,
227 MONO_GC_EVENT_MARK_END = 2,
228 MONO_GC_EVENT_RECLAIM_START = 3,
229 MONO_GC_EVENT_RECLAIM_END = 4,
230 MONO_GC_EVENT_END = 5,
231 MONO_GC_EVENT_PRE_STOP_WORLD = 6,
232 /* When this event arrives, the GC and suspend locks are acquired. */
233 MONO_GC_EVENT_PRE_STOP_WORLD_LOCKED = 10,
234 MONO_GC_EVENT_POST_STOP_WORLD = 7,
235 MONO_GC_EVENT_PRE_START_WORLD = 8,
236 /* When this event arrives, the GC and suspend locks are released. */
237 MONO_GC_EVENT_POST_START_WORLD_UNLOCKED = 11,
238 MONO_GC_EVENT_POST_START_WORLD = 9,
239 } MonoProfilerGCEvent;
242 * The macros below will generate the majority of the callback API. Refer to
243 * mono/metadata/profiler-events.h for a list of callbacks. They are expanded
246 * typedef void (*MonoProfilerRuntimeInitializedCallback (MonoProfiler *prof);
247 * MONO_API void mono_profiler_set_runtime_initialized_callback (MonoProfiler *prof, MonoProfilerRuntimeInitializedCallback cb);
249 * typedef void (*MonoProfilerRuntimeShutdownCallback (MonoProfiler *prof);
250 * MONO_API void mono_profiler_set_runtime_shutdown_callback (MonoProfiler *prof, MonoProfilerRuntimeShutdownCallback cb);
252 * typedef void (*MonoProfilerContextLoadedCallback (MonoProfiler *prof);
253 * MONO_API void mono_profiler_set_context_loaded_callback (MonoProfiler *prof, MonoProfilerContextLoadedCallback cb);
255 * typedef void (*MonoProfilerContextUnloadedCallback (MonoProfiler *prof);
256 * MONO_API void mono_profiler_set_context_unloaded_callback (MonoProfiler *prof, MonoProfilerContextUnloadedCallback cb);
260 * To remove a callback, pass NULL instead of a valid function pointer.
261 * Callbacks can be changed at any point, but note that doing so is inherently
262 * racy with respect to threads that aren't suspended, i.e. you may still see a
263 * call from another thread right after you change a callback.
265 * These functions are async safe.
268 #define _MONO_PROFILER_EVENT(type, ...) \
269 typedef void (*MonoProfiler ## type ## Callback) (__VA_ARGS__);
270 #define MONO_PROFILER_EVENT_0(name, type) \
271 _MONO_PROFILER_EVENT(type, MonoProfiler *prof)
272 #define MONO_PROFILER_EVENT_1(name, type, arg1_type, arg1_name) \
273 _MONO_PROFILER_EVENT(type, MonoProfiler *prof, arg1_type arg1_name)
274 #define MONO_PROFILER_EVENT_2(name, type, arg1_type, arg1_name, arg2_type, arg2_name) \
275 _MONO_PROFILER_EVENT(type, MonoProfiler *prof, arg1_type arg1_name, arg2_type arg2_name)
276 #define MONO_PROFILER_EVENT_3(name, type, arg1_type, arg1_name, arg2_type, arg2_name, arg3_type, arg3_name) \
277 _MONO_PROFILER_EVENT(type, MonoProfiler *prof, arg1_type arg1_name, arg2_type arg2_name, arg3_type arg3_name)
278 #define MONO_PROFILER_EVENT_4(name, type, arg1_type, arg1_name, arg2_type, arg2_name, arg3_type, arg3_name, arg4_type, arg4_name) \
279 _MONO_PROFILER_EVENT(type, MonoProfiler *prof, arg1_type arg1_name, arg2_type arg2_name, arg3_type arg3_name, arg4_type arg4_name)
280 #include <mono/metadata/profiler-events.h>
281 #undef MONO_PROFILER_EVENT_0
282 #undef MONO_PROFILER_EVENT_1
283 #undef MONO_PROFILER_EVENT_2
284 #undef MONO_PROFILER_EVENT_3
285 #undef MONO_PROFILER_EVENT_4
286 #undef _MONO_PROFILER_EVENT
288 #define _MONO_PROFILER_EVENT(name, type) \
289 MONO_API void mono_profiler_set_ ## name ## _callback (MonoProfilerHandle handle, MonoProfiler ## type ## Callback cb);
290 #define MONO_PROFILER_EVENT_0(name, type) \
291 _MONO_PROFILER_EVENT(name, type)
292 #define MONO_PROFILER_EVENT_1(name, type, arg1_type, arg1_name) \
293 _MONO_PROFILER_EVENT(name, type)
294 #define MONO_PROFILER_EVENT_2(name, type, arg1_type, arg1_name, arg2_type, arg2_name) \
295 _MONO_PROFILER_EVENT(name, type)
296 #define MONO_PROFILER_EVENT_3(name, type, arg1_type, arg1_name, arg2_type, arg2_name, arg3_type, arg3_name) \
297 _MONO_PROFILER_EVENT(name, type)
298 #define MONO_PROFILER_EVENT_4(name, type, arg1_type, arg1_name, arg2_type, arg2_name, arg3_type, arg3_name, arg4_type, arg4_name) \
299 _MONO_PROFILER_EVENT(name, type)
300 #include <mono/metadata/profiler-events.h>
301 #undef MONO_PROFILER_EVENT_0
302 #undef MONO_PROFILER_EVENT_1
303 #undef MONO_PROFILER_EVENT_2
304 #undef MONO_PROFILER_EVENT_3
305 #undef MONO_PROFILER_EVENT_4
306 #undef _MONO_PROFILER_EVENT
310 #endif // __MONO_PROFILER_H__