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