76759d9f845d22acc3e9f14893332e73b74437c4
[mono.git] / mono / metadata / profiler.h
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 /*
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.
29  *
30  * A module called foo should declare an entry point like so:
31  *
32  * void mono_profiler_init_foo (const char *desc)
33  * {
34  * }
35  *
36  * This function is not async safe.
37  */
38 MONO_API void mono_profiler_load (const char *desc);
39
40 typedef struct _MonoProfiler MonoProfiler;
41 typedef struct _MonoProfilerDesc *MonoProfilerHandle;
42
43 /*
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). The
46  * given structure pointer will be passed to all callbacks from the profiler
47  * API. It can be NULL.
48  *
49  * This function may only be called from your profiler's init function.
50  *
51  * Example usage:
52  *
53  * struct _MonoProfiler {
54  *      int my_stuff;
55  *      // ...
56  * };
57  *
58  * MonoProfiler *prof = calloc (1, sizeof (MonoProfiler));
59  * MonoProfilerHandle handle = mono_profiler_create (prof);
60  * mono_profiler_set_shutdown_callback (handle, my_shutdown_cb);
61  *
62  * This function is not async safe.
63  */
64 MONO_API MonoProfilerHandle mono_profiler_create (MonoProfiler *prof);
65
66 /*
67  * Enables support for code coverage instrumentation. At the moment, this means
68  * enabling the debug info subsystem. If you do not call this function, you
69  * will not be able to use mono_profiler_get_coverage_data. Returns TRUE if
70  * code coverage support was enabled, or FALSE if the function was called too
71  * late for this to be possible.
72  *
73  * This function may only be called from your profiler's init function.
74  *
75  * This function is not async safe.
76  */
77 MONO_API mono_bool mono_profiler_enable_coverage (void);
78
79 typedef mono_bool (*MonoProfilerCoverageFilterCallback) (MonoProfiler *prof, MonoMethod *method);
80
81 /*
82  * Sets a code coverage filter function. The profiler API will invoke filter
83  * functions from all installed profilers. If any of them return TRUE, then the
84  * given method will be instrumented for coverage analysis. All filters are
85  * guaranteed to be called at least once per method, even if an earlier filter
86  * has already returned TRUE.
87  *
88  * Note that filter functions must be installed before a method is compiled in
89  * order to have any effect, i.e. you should register your filter function in
90  * your profiler's init function.
91  *
92  * This function is async safe.
93  */
94 MONO_API void mono_profiler_set_coverage_filter_callback (MonoProfilerHandle handle, MonoProfilerCoverageFilterCallback cb);
95
96 typedef struct {
97         MonoMethod *method;
98         uint32_t il_offset;
99         uint32_t counter;
100         const char *file_name;
101         uint32_t line;
102         uint32_t column;
103 } MonoProfilerCoverageData;
104
105 typedef void (*MonoProfilerCoverageCallback) (MonoProfiler *prof, const MonoProfilerCoverageData *data);
106
107 /*
108  * Retrieves all coverage data for the specified method and invokes the given
109  * callback for each entry. Source location information will only be filled out
110  * if the given method has debug info available. Returns TRUE if the given
111  * method was instrumented for code coverage; otherwise, FALSE.
112  *
113  * Please note that the structure passed to the callback is only valid for the
114  * duration of the callback.
115  *
116  * This function is not async safe.
117  */
118 MONO_API mono_bool mono_profiler_get_coverage_data (MonoProfilerHandle handle, MonoMethod *method, MonoProfilerCoverageCallback cb);
119
120 typedef enum {
121         /*
122          * Do not perform sampling. Will make the sampling thread sleep until the
123          * sampling mode is changed to one of the below modes.
124          */
125         MONO_PROFILER_SAMPLE_MODE_NONE = 0,
126         /*
127          * Try to base sampling frequency on process activity. Falls back to
128          * MONO_PROFILER_SAMPLE_MODE_REAL if such a clock is not available.
129          */
130         MONO_PROFILER_SAMPLE_MODE_PROCESS = 1,
131         /*
132          * Base sampling frequency on wall clock time. Uses a monotonic clock when
133          * available (all major platforms).
134          */
135         MONO_PROFILER_SAMPLE_MODE_REAL = 2,
136 } MonoProfilerSampleMode;
137
138 /*
139  * Enables the sampling thread. You must call this function if you intend to use
140  * statistical sampling; mono_profiler_set_sample_mode will have no effect if
141  * this function has not been called. The first profiler to call this function
142  * will get ownership over sampling settings (mode and frequency) so that no
143  * other profiler can change those settings. Returns TRUE if the sampling
144  * thread was enabled, or FALSE if the function was called too late for this
145  * to be possible.
146  *
147  * Note that you still need to call mono_profiler_set_sample_mode with a mode
148  * other than MONO_PROFILER_SAMPLE_MODE_NONE to actually start sampling.
149  *
150  * This function may only be called from your profiler's init function.
151  *
152  * This function is not async safe.
153  */
154 MONO_API mono_bool mono_profiler_enable_sampling (MonoProfilerHandle handle);
155
156 /*
157  * Sets the sampling mode and frequency (in Hz). The frequency must be a
158  * positive number. If the calling profiler has ownership over sampling
159  * settings, the settings will be changed and this function will return TRUE;
160  * otherwise, it returns FALSE without changing any settings.
161  *
162  * This function is async safe.
163  */
164 MONO_API mono_bool mono_profiler_set_sample_mode (MonoProfilerHandle handle, MonoProfilerSampleMode mode, uint32_t freq);
165
166 /*
167  * Retrieves the current sampling mode and/or frequency (in Hz). Returns TRUE if
168  * the calling profiler is allowed to change the sampling settings; otherwise,
169  * FALSE.
170  *
171  * This function is async safe.
172  */
173 MONO_API mono_bool mono_profiler_get_sample_mode (MonoProfilerHandle handle, MonoProfilerSampleMode *mode, uint32_t *freq);
174
175 /*
176  * Enables instrumentation of GC allocations. This is necessary so that managed
177  * allocators can be instrumented with a call into the profiler API. Allocations
178  * will not be reported unless this function is called. Returns TRUE if
179  * allocation instrumentation was enabled, or FALSE if the function was called
180  * too late for this to be possible.
181  *
182  * This function may only be called from your profiler's init function.
183  *
184  * This function is not async safe.
185  */
186 MONO_API mono_bool mono_profiler_enable_allocations (void);
187
188 typedef enum {
189         /* Do not instrument calls. */
190         MONO_PROFILER_CALL_INSTRUMENTATION_NONE = 0,
191         /* Instrument method prologues. */
192         MONO_PROFILER_CALL_INSTRUMENTATION_PROLOGUE = 1 << 1,
193         /* Also capture a call context for prologues. */
194         MONO_PROFILER_CALL_INSTRUMENTATION_PROLOGUE_CONTEXT = 1 << 2,
195         /* Instrument method epilogues. */
196         MONO_PROFILER_CALL_INSTRUMENTATION_EPILOGUE = 1 << 3,
197         /* Also capture a call context for epilogues. */
198         MONO_PROFILER_CALL_INSTRUMENTATION_EPILOGUE_CONTEXT = 1 << 4,
199 } MonoProfilerCallInstrumentationFlags;
200
201 typedef MonoProfilerCallInstrumentationFlags (*MonoProfilerCallInstrumentationFilterCallback) (MonoProfiler *prof, MonoMethod *method);
202
203 /*
204  * Sets a call instrumentation filter function. The profiler API will invoke
205  * filter functions from all installed profilers. If any of them return flags
206  * other than MONO_PROFILER_CALL_INSTRUMENTATION_NONE, then the given method
207  * will be instrumented as requested. All filters are guaranteed to be called
208  * exactly once per method, even if earlier filters have already specified all
209  * flags.
210  *
211  * Note that filter functions must be installed before a method is compiled in
212  * order to have any effect, i.e. you should register your filter function in
213  * your profiler's init function. Also, if you want to instrument a method
214  * that's going to be AOT-compiled, you must attach your profiler and install a
215  * call instrumentation filter function at AOT time. This can be done in
216  * exactly the same way as you would normally, i.e. by passing the --profile
217  * option on the command line, by calling mono_profiler_load, or simply by
218  * using the profiler API as an embedder.
219  *
220  * Keep in mind that indiscriminate method instrumentation is extremely heavy
221  * and will slow down most applications to a crawl. Consider using sampling
222  * instead if it would work for your use case.
223  *
224  * This function is async safe.
225  */
226 MONO_API void mono_profiler_set_call_instrumentation_filter_callback (MonoProfilerHandle handle, MonoProfilerCallInstrumentationFilterCallback cb);
227
228 /*
229  * Enables support for retrieving stack frame data from a call context. At the
230  * moment, this means enabling the debug info subsystem. If you do not call
231  * this function, you will not be able to use the call context introspection
232  * functions (they will simply return NULL). Returns TRUE if call context
233  * introspection was enabled, or FALSE if the function was called too late for
234  * this to be possible.
235  *
236  * Please note: Mono's LLVM backend does not support this feature. This means
237  * that methods with call context instrumentation will be handled by Mono's
238  * JIT even in LLVM mode. There is also a special case when Mono is compiling
239  * in LLVM-only mode: Since LLVM does not provide a way to implement call
240  * contexts, a NULL context will always be passed to enter/leave events even
241  * though this method returns TRUE.
242  *
243  * This function may only be called from your profiler's init function.
244  *
245  * This function is not async safe.
246  */
247 MONO_API mono_bool mono_profiler_enable_call_context_introspection (void);
248
249 typedef struct _MonoProfilerCallContext MonoProfilerCallContext;
250
251 /*
252  * Given a valid call context from an enter/leave event, retrieves a pointer to
253  * the this reference for the method. Returns NULL if none exists (i.e. it's a
254  * static method) or if call context introspection was not enabled.
255  *
256  * The buffer returned by this function must be freed with
257  * mono_profiler_call_context_free_buffer.
258  *
259  * Please note that a call context is only valid for the duration of the
260  * enter/leave callback it was passed to.
261  *
262  * This function is not async safe.
263  */
264 MONO_API void *mono_profiler_call_context_get_this (MonoProfilerCallContext *context);
265
266 /*
267  * Given a valid call context from an enter/leave event, retrieves a pointer to
268  * the method argument at the given position. Returns NULL if position is out
269  * of bounds or if call context introspection was not enabled.
270  *
271  * The buffer returned by this function must be freed with
272  * mono_profiler_call_context_free_buffer.
273  *
274  * Please note that a call context is only valid for the duration of the
275  * enter/leave callback it was passed to.
276  *
277  * This function is not async safe.
278  */
279 MONO_API void *mono_profiler_call_context_get_argument (MonoProfilerCallContext *context, uint32_t position);
280
281 /*
282  * Given a valid call context from an enter/leave event, retrieves a pointer to
283  * the local variable at the given position. Returns NULL if position is out of
284  * bounds or if call context introspection was not enabled.
285  *
286  * The buffer returned by this function must be freed with
287  * mono_profiler_call_context_free_buffer.
288  *
289  * Please note that a call context is only valid for the duration of the
290  * enter/leave callback it was passed to.
291  *
292  * This function is not async safe.
293  */
294 MONO_API void *mono_profiler_call_context_get_local (MonoProfilerCallContext *context, uint32_t position);
295
296 /*
297  * Given a valid call context from an enter/leave event, retrieves a pointer to
298  * return value of a method. Returns NULL if the method has no return value
299  * (i.e. it returns void), if the leave event was the result of a tail call, if
300  * the function is called on a context from an enter event, or if call context
301  * introspection was not enabled.
302  *
303  * The buffer returned by this function must be freed with
304  * mono_profiler_call_context_free_buffer.
305  *
306  * Please note that a call context is only valid for the duration of the
307  * enter/leave callback it was passed to.
308  *
309  * This function is not async safe.
310  */
311 MONO_API void *mono_profiler_call_context_get_result (MonoProfilerCallContext *context);
312
313 /*
314  * Frees a buffer returned by one of the call context introspection functions.
315  * Passing a NULL buffer is allowed, which makes this function a no-op.
316  *
317  * This function is not async safe.
318  */
319 MONO_API void mono_profiler_call_context_free_buffer (void *buffer);
320
321 #ifdef MONO_PROFILER_UNSTABLE_GC_ROOTS
322 typedef enum {
323         /* Upper 2 bytes. */
324         MONO_PROFILER_GC_ROOT_PINNING = 1 << 8,
325         MONO_PROFILER_GC_ROOT_WEAKREF = 2 << 8,
326         MONO_PROFILER_GC_ROOT_INTERIOR = 4 << 8,
327
328         /* Lower 2 bytes (flags). */
329         MONO_PROFILER_GC_ROOT_STACK = 1 << 0,
330         MONO_PROFILER_GC_ROOT_FINALIZER = 1 << 1,
331         MONO_PROFILER_GC_ROOT_HANDLE = 1 << 2,
332         MONO_PROFILER_GC_ROOT_OTHER = 1 << 3,
333         MONO_PROFILER_GC_ROOT_MISC = 1 << 4,
334
335         MONO_PROFILER_GC_ROOT_TYPEMASK = 0xff,
336 } MonoProfilerGCRootType;
337 #endif
338
339 typedef enum {
340         /* data = MonoMethod *method */
341         MONO_PROFILER_CODE_BUFFER_METHOD = 0,
342         MONO_PROFILER_CODE_BUFFER_METHOD_TRAMPOLINE = 1,
343         MONO_PROFILER_CODE_BUFFER_UNBOX_TRAMPOLINE = 2,
344         MONO_PROFILER_CODE_BUFFER_IMT_TRAMPOLINE = 3,
345         MONO_PROFILER_CODE_BUFFER_GENERICS_TRAMPOLINE = 4,
346         /* data = const char *name */
347         MONO_PROFILER_CODE_BUFFER_SPECIFIC_TRAMPOLINE = 5,
348         MONO_PROFILER_CODE_BUFFER_HELPER = 6,
349         MONO_PROFILER_CODE_BUFFER_MONITOR = 7,
350         MONO_PROFILER_CODE_BUFFER_DELEGATE_INVOKE = 8,
351         MONO_PROFILER_CODE_BUFFER_EXCEPTION_HANDLING = 9,
352 } MonoProfilerCodeBufferType;
353
354 typedef enum {
355         MONO_GC_EVENT_PRE_STOP_WORLD = 6,
356         /* When this event arrives, the GC and suspend locks are acquired. */
357         MONO_GC_EVENT_PRE_STOP_WORLD_LOCKED = 10,
358         MONO_GC_EVENT_POST_STOP_WORLD = 7,
359         MONO_GC_EVENT_START = 0,
360         MONO_GC_EVENT_END = 5,
361         MONO_GC_EVENT_PRE_START_WORLD = 8,
362         /* When this event arrives, the GC and suspend locks are released. */
363         MONO_GC_EVENT_POST_START_WORLD_UNLOCKED = 11,
364         MONO_GC_EVENT_POST_START_WORLD = 9,
365 } MonoProfilerGCEvent;
366
367 /*
368  * The macros below will generate the majority of the callback API. Refer to
369  * mono/metadata/profiler-events.h for a list of callbacks. They are expanded
370  * like so:
371  *
372  * typedef void (*MonoProfilerRuntimeInitializedCallback (MonoProfiler *prof);
373  * MONO_API void mono_profiler_set_runtime_initialized_callback (MonoProfiler *prof, MonoProfilerRuntimeInitializedCallback cb);
374  *
375  * typedef void (*MonoProfilerRuntimeShutdownCallback (MonoProfiler *prof);
376  * MONO_API void mono_profiler_set_runtime_shutdown_callback (MonoProfiler *prof, MonoProfilerRuntimeShutdownCallback cb);
377  *
378  * typedef void (*MonoProfilerContextLoadedCallback (MonoProfiler *prof);
379  * MONO_API void mono_profiler_set_context_loaded_callback (MonoProfiler *prof, MonoProfilerContextLoadedCallback cb);
380  *
381  * typedef void (*MonoProfilerContextUnloadedCallback (MonoProfiler *prof);
382  * MONO_API void mono_profiler_set_context_unloaded_callback (MonoProfiler *prof, MonoProfilerContextUnloadedCallback cb);
383  *
384  * Etc.
385  *
386  * To remove a callback, pass NULL instead of a valid function pointer.
387  * Callbacks can be changed at any point, but note that doing so is inherently
388  * racy with respect to threads that aren't suspended, i.e. you may still see a
389  * call from another thread right after you change a callback.
390  *
391  * These functions are async safe.
392  */
393
394 #define _MONO_PROFILER_EVENT(type, ...) \
395         typedef void (*MonoProfiler ## type ## Callback) (__VA_ARGS__);
396 #define MONO_PROFILER_EVENT_0(name, type) \
397                 _MONO_PROFILER_EVENT(type, MonoProfiler *prof)
398 #define MONO_PROFILER_EVENT_1(name, type, arg1_type, arg1_name) \
399                 _MONO_PROFILER_EVENT(type, MonoProfiler *prof, arg1_type arg1_name)
400 #define MONO_PROFILER_EVENT_2(name, type, arg1_type, arg1_name, arg2_type, arg2_name) \
401                 _MONO_PROFILER_EVENT(type, MonoProfiler *prof, arg1_type arg1_name, arg2_type arg2_name)
402 #define MONO_PROFILER_EVENT_3(name, type, arg1_type, arg1_name, arg2_type, arg2_name, arg3_type, arg3_name) \
403                 _MONO_PROFILER_EVENT(type, MonoProfiler *prof, arg1_type arg1_name, arg2_type arg2_name, arg3_type arg3_name)
404 #define MONO_PROFILER_EVENT_4(name, type, arg1_type, arg1_name, arg2_type, arg2_name, arg3_type, arg3_name, arg4_type, arg4_name) \
405                 _MONO_PROFILER_EVENT(type, MonoProfiler *prof, arg1_type arg1_name, arg2_type arg2_name, arg3_type arg3_name, arg4_type arg4_name)
406 #include <mono/metadata/profiler-events.h>
407 #undef MONO_PROFILER_EVENT_0
408 #undef MONO_PROFILER_EVENT_1
409 #undef MONO_PROFILER_EVENT_2
410 #undef MONO_PROFILER_EVENT_3
411 #undef MONO_PROFILER_EVENT_4
412 #undef _MONO_PROFILER_EVENT
413
414 #define _MONO_PROFILER_EVENT(name, type) \
415         MONO_API void mono_profiler_set_ ## name ## _callback (MonoProfilerHandle handle, MonoProfiler ## type ## Callback cb);
416 #define MONO_PROFILER_EVENT_0(name, type) \
417         _MONO_PROFILER_EVENT(name, type)
418 #define MONO_PROFILER_EVENT_1(name, type, arg1_type, arg1_name) \
419         _MONO_PROFILER_EVENT(name, type)
420 #define MONO_PROFILER_EVENT_2(name, type, arg1_type, arg1_name, arg2_type, arg2_name) \
421         _MONO_PROFILER_EVENT(name, type)
422 #define MONO_PROFILER_EVENT_3(name, type, arg1_type, arg1_name, arg2_type, arg2_name, arg3_type, arg3_name) \
423         _MONO_PROFILER_EVENT(name, type)
424 #define MONO_PROFILER_EVENT_4(name, type, arg1_type, arg1_name, arg2_type, arg2_name, arg3_type, arg3_name, arg4_type, arg4_name) \
425         _MONO_PROFILER_EVENT(name, type)
426 #include <mono/metadata/profiler-events.h>
427 #undef MONO_PROFILER_EVENT_0
428 #undef MONO_PROFILER_EVENT_1
429 #undef MONO_PROFILER_EVENT_2
430 #undef MONO_PROFILER_EVENT_3
431 #undef MONO_PROFILER_EVENT_4
432 #undef _MONO_PROFILER_EVENT
433
434 MONO_END_DECLS
435
436 #endif // __MONO_PROFILER_H__