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