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 * 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.
21 #define MONO_PROFILER_API_VERSION 2
24 * Loads a profiler module based on the specified description. The description
25 * can be of the form "name:args" or just "name". For example, "log:sample" and
26 * "log" will both load "libmono-profiler-log.so". The description is passed to
27 * the module after it has been loaded. If the specified module has already
28 * been loaded, this function has no effect.
30 * A module should declare an entry point like so:
32 * void mono_profiler_init (const char *desc)
36 * This function is not async safe.
38 MONO_API
void mono_profiler_load (const char *desc
);
40 typedef struct _MonoProfiler MonoProfiler
;
41 typedef struct _MonoProfilerDesc
*MonoProfilerHandle
;
44 * Installs a profiler and returns a handle for it. The handle is used with the
45 * other functions in the profiler API (e.g. for setting up callbacks).
47 * This function may only be called from your profiler's init function.
51 * struct _MonoProfiler {
56 * MonoProfiler *prof = calloc (1, sizeof (MonoProfiler));
57 * MonoProfilerHandle handle = mono_profiler_install (prof);
58 * mono_profiler_set_shutdown_callback (handle, my_shutdown_cb);
60 * This function is not async safe.
62 MONO_API MonoProfilerHandle
mono_profiler_install (MonoProfiler
*prof
);
64 typedef mono_bool (*MonoProfilerCoverageFilterCallback
) (MonoProfiler
*prof
, MonoMethod
*method
);
67 * Sets a code coverage filter function. The profiler API will invoke filter
68 * functions from all installed profilers. If any of them return TRUE, then the
69 * given method will be instrumented for coverage analysis. All filters are
70 * guaranteed to be called exactly once per method, even if an earlier filter
71 * has already returned TRUE.
73 * Note that filter functions must be installed before a method is compiled in
74 * order to have any effect, i.e. you should register your filter function in
75 * your profiler's init function.
77 * This function is async safe.
79 MONO_API
void mono_profiler_set_coverage_filter_callback (MonoProfilerHandle handle
, MonoProfilerCoverageFilterCallback cb
);
85 const char *file_name
;
88 } MonoProfilerCoverageData
;
90 typedef void (*MonoProfilerCoverageCallback
) (MonoProfiler
*prof
, const MonoProfilerCoverageData
*data
);
93 * Retrieves all coverage data for the specified method and invokes the given
94 * callback for each entry.
96 * This function is not async safe.
98 MONO_API
void mono_profiler_get_coverage_data (MonoProfilerHandle handle
, MonoMethod
*method
, MonoProfilerCoverageCallback cb
);
102 * Do not perform sampling. Will make the sampling thread sleep until the
103 * sampling mode is changed to one of the below modes.
105 MONO_PROFILER_SAMPLE_MODE_NONE
= 0,
107 * Try to base sampling frequency on process activity. Falls back to
108 * MONO_PROFILER_SAMPLE_MODE_REAL if such a clock is not available.
110 MONO_PROFILER_SAMPLE_MODE_PROCESS
= 1,
112 * Base sampling frequency on wall clock time. Uses a monotonic clock when
113 * available (all major platforms).
115 MONO_PROFILER_SAMPLE_MODE_REAL
= 2,
116 } MonoProfilerSampleMode
;
119 * Enables the sampling thread. You must call this function if you intend to use
120 * statistical sampling; mono_profiler_set_sample_mode will have no effect if
121 * this function has not been called. The first profiler to call this function
122 * will get ownership over sampling settings (mode and frequency) so that no
123 * other profiler can change those settings. Returns TRUE if the sampling
124 * thread was enabled, or FALSE if the function was called too late for this
127 * Note that you still need to call mono_profiler_set_sample_mode with a mode
128 * other than MONO_PROFILER_SAMPLE_MODE_NONE to actually start sampling.
130 * This function may only be called from your profiler's init function.
132 * This function is not async safe.
134 MONO_API mono_bool
mono_profiler_enable_sampling (MonoProfilerHandle handle
);
137 * Sets the sampling mode and frequency (in Hz). The frequency must be a
138 * positive number. If the calling profiler has ownership over sampling
139 * settings, the settings will be changed and this function will return TRUE;
140 * otherwise, it returns FALSE without changing any settings.
142 * This function is async safe.
144 MONO_API mono_bool
mono_profiler_set_sample_mode (MonoProfilerHandle handle
, MonoProfilerSampleMode mode
, uint64_t freq
);
147 * Retrieves the current sampling mode and/or frequency (in Hz). Returns TRUE if
148 * the calling profiler is allowed to change the sampling settings; otherwise,
151 * This function is async safe.
153 MONO_API mono_bool
mono_profiler_get_sample_mode (MonoProfilerHandle handle
, MonoProfilerSampleMode
*mode
, uint64_t *freq
);
156 * Enables instrumentation of GC allocations. This is necessary so that managed
157 * allocators can be instrumented with a call into the profiler API. Allocations
158 * will not be reported unless this function is called. Returns TRUE if
159 * allocation instrumentation was enabled, or FALSE if the function was called
160 * too late for this to be possible.
162 * This function may only be called from your profiler's init function.
164 * This function is not async safe.
166 MONO_API mono_bool
mono_profiler_enable_allocations (void);
169 /* Do not instrument calls. */
170 MONO_PROFILER_CALL_INSTRUMENTATION_NONE
= 1 << 0,
171 /* Instrument method prologues. */
172 MONO_PROFILER_CALL_INSTRUMENTATION_PROLOGUE
= 1 << 1,
173 /* Instrument method epilogues. */
174 MONO_PROFILER_CALL_INSTRUMENTATION_EPILOGUE
= 1 << 2,
175 } MonoProfilerCallInstrumentationFlags
;
177 typedef MonoProfilerCallInstrumentationFlags (*MonoProfilerCallInstrumentationFilterCallback
) (MonoProfiler
*prof
, MonoMethod
*method
);
180 * Sets a call instrumentation filter function. The profiler API will invoke
181 * filter functions from all installed profilers. If any of them return flags
182 * other than MONO_PROFILER_CALL_INSTRUMENTATION_NONE, then the given method
183 * will be instrumented as requested. All filters are guaranteed to be called
184 * at least once (possibly more) per method entry and exit, even if earlier
185 * filters have already specified all flags.
187 * Note that filter functions must be installed before a method is compiled in
188 * order to have any effect, i.e. you should register your filter function in
189 * your profiler's init function.
191 * Keep in mind that method instrumentation is extremely heavy and will slow
192 * down most applications to a crawl. Consider using sampling instead if it
193 * would work for your use case.
195 * This function is async safe.
197 MONO_API
void mono_profiler_set_call_instrumentation_filter_callback (MonoProfilerHandle handle
, MonoProfilerCallInstrumentationFilterCallback cb
);
199 #ifdef MONO_PROFILER_UNSTABLE_GC_ROOTS
202 MONO_PROFILER_GC_ROOT_PINNING
= 1 << 8,
203 MONO_PROFILER_GC_ROOT_WEAKREF
= 2 << 8,
204 MONO_PROFILER_GC_ROOT_INTERIOR
= 4 << 8,
206 /* Lower 2 bytes (flags). */
207 MONO_PROFILER_GC_ROOT_STACK
= 1 << 0,
208 MONO_PROFILER_GC_ROOT_FINALIZER
= 1 << 1,
209 MONO_PROFILER_GC_ROOT_HANDLE
= 1 << 2,
210 MONO_PROFILER_GC_ROOT_OTHER
= 1 << 3,
211 MONO_PROFILER_GC_ROOT_MISC
= 1 << 4,
213 MONO_PROFILER_GC_ROOT_TYPEMASK
= 0xff,
214 } MonoProfilerGCRootType
;
218 /* data = MonoMethod *method */
219 MONO_PROFILER_CODE_BUFFER_METHOD
= 0,
220 MONO_PROFILER_CODE_BUFFER_METHOD_TRAMPOLINE
= 1,
221 MONO_PROFILER_CODE_BUFFER_UNBOX_TRAMPOLINE
= 2,
222 MONO_PROFILER_CODE_BUFFER_IMT_TRAMPOLINE
= 3,
223 MONO_PROFILER_CODE_BUFFER_GENERICS_TRAMPOLINE
= 4,
224 /* data = const char *name */
225 MONO_PROFILER_CODE_BUFFER_SPECIFIC_TRAMPOLINE
= 5,
226 MONO_PROFILER_CODE_BUFFER_HELPER
= 6,
227 MONO_PROFILER_CODE_BUFFER_MONITOR
= 7,
228 MONO_PROFILER_CODE_BUFFER_DELEGATE_INVOKE
= 8,
229 MONO_PROFILER_CODE_BUFFER_EXCEPTION_HANDLING
= 9,
230 } MonoProfilerCodeBufferType
;
232 // Keep somewhat in sync with libgc/include/gc.h : GC_EventType.
234 MONO_GC_EVENT_START
= 0,
235 MONO_GC_EVENT_MARK_START
= 1,
236 MONO_GC_EVENT_MARK_END
= 2,
237 MONO_GC_EVENT_RECLAIM_START
= 3,
238 MONO_GC_EVENT_RECLAIM_END
= 4,
239 MONO_GC_EVENT_END
= 5,
240 MONO_GC_EVENT_PRE_STOP_WORLD
= 6,
241 /* When this event arrives, the GC and suspend locks are acquired. */
242 MONO_GC_EVENT_PRE_STOP_WORLD_LOCKED
= 10,
243 MONO_GC_EVENT_POST_STOP_WORLD
= 7,
244 MONO_GC_EVENT_PRE_START_WORLD
= 8,
245 /* When this event arrives, the GC and suspend locks are released. */
246 MONO_GC_EVENT_POST_START_WORLD_UNLOCKED
= 11,
247 MONO_GC_EVENT_POST_START_WORLD
= 9,
248 } MonoProfilerGCEvent
;
251 * The macros below will generate the majority of the callback API. Refer to
252 * mono/metadata/profiler-events.h for a list of callbacks. They are expanded
255 * typedef void (*MonoProfilerRuntimeInitializedCallback (MonoProfiler *prof);
256 * MONO_API void mono_profiler_set_runtime_initialized_callback (MonoProfiler *prof, MonoProfilerRuntimeInitializedCallback cb);
258 * typedef void (*MonoProfilerRuntimeShutdownCallback (MonoProfiler *prof);
259 * MONO_API void mono_profiler_set_runtime_shutdown_callback (MonoProfiler *prof, MonoProfilerRuntimeShutdownCallback cb);
261 * typedef void (*MonoProfilerContextLoadedCallback (MonoProfiler *prof);
262 * MONO_API void mono_profiler_set_context_loaded_callback (MonoProfiler *prof, MonoProfilerContextLoadedCallback cb);
264 * typedef void (*MonoProfilerContextUnloadedCallback (MonoProfiler *prof);
265 * MONO_API void mono_profiler_set_context_unloaded_callback (MonoProfiler *prof, MonoProfilerContextUnloadedCallback cb);
269 * To remove a callback, pass NULL instead of a valid function pointer.
270 * Callbacks can be changed at any point, but note that doing so is inherently
271 * racy with respect to threads that aren't suspended, i.e. you may still see a
272 * call from another thread right after you change a callback.
274 * These functions are async safe.
277 #define _MONO_PROFILER_EVENT(type, ...) \
278 typedef void (*MonoProfiler ## type ## Callback) (__VA_ARGS__);
279 #define MONO_PROFILER_EVENT_0(name, type) \
280 _MONO_PROFILER_EVENT(type, MonoProfiler *prof)
281 #define MONO_PROFILER_EVENT_1(name, type, arg1_type, arg1_name) \
282 _MONO_PROFILER_EVENT(type, MonoProfiler *prof, arg1_type arg1_name)
283 #define MONO_PROFILER_EVENT_2(name, type, arg1_type, arg1_name, arg2_type, arg2_name) \
284 _MONO_PROFILER_EVENT(type, MonoProfiler *prof, arg1_type arg1_name, arg2_type arg2_name)
285 #define MONO_PROFILER_EVENT_3(name, type, arg1_type, arg1_name, arg2_type, arg2_name, arg3_type, arg3_name) \
286 _MONO_PROFILER_EVENT(type, MonoProfiler *prof, arg1_type arg1_name, arg2_type arg2_name, arg3_type arg3_name)
287 #define MONO_PROFILER_EVENT_4(name, type, arg1_type, arg1_name, arg2_type, arg2_name, arg3_type, arg3_name, arg4_type, arg4_name) \
288 _MONO_PROFILER_EVENT(type, MonoProfiler *prof, arg1_type arg1_name, arg2_type arg2_name, arg3_type arg3_name, arg4_type arg4_name)
289 #include <mono/metadata/profiler-events.h>
290 #undef MONO_PROFILER_EVENT_0
291 #undef MONO_PROFILER_EVENT_1
292 #undef MONO_PROFILER_EVENT_2
293 #undef MONO_PROFILER_EVENT_3
294 #undef MONO_PROFILER_EVENT_4
295 #undef _MONO_PROFILER_EVENT
297 #define _MONO_PROFILER_EVENT(name, type) \
298 MONO_API void mono_profiler_set_ ## name ## _callback (MonoProfilerHandle handle, MonoProfiler ## type ## Callback cb);
299 #define MONO_PROFILER_EVENT_0(name, type) \
300 _MONO_PROFILER_EVENT(name, type)
301 #define MONO_PROFILER_EVENT_1(name, type, arg1_type, arg1_name) \
302 _MONO_PROFILER_EVENT(name, type)
303 #define MONO_PROFILER_EVENT_2(name, type, arg1_type, arg1_name, arg2_type, arg2_name) \
304 _MONO_PROFILER_EVENT(name, type)
305 #define MONO_PROFILER_EVENT_3(name, type, arg1_type, arg1_name, arg2_type, arg2_name, arg3_type, arg3_name) \
306 _MONO_PROFILER_EVENT(name, type)
307 #define MONO_PROFILER_EVENT_4(name, type, arg1_type, arg1_name, arg2_type, arg2_name, arg3_type, arg3_name, arg4_type, arg4_name) \
308 _MONO_PROFILER_EVENT(name, type)
309 #include <mono/metadata/profiler-events.h>
310 #undef MONO_PROFILER_EVENT_0
311 #undef MONO_PROFILER_EVENT_1
312 #undef MONO_PROFILER_EVENT_2
313 #undef MONO_PROFILER_EVENT_3
314 #undef MONO_PROFILER_EVENT_4
315 #undef _MONO_PROFILER_EVENT
319 #endif // __MONO_PROFILER_H__