[runtime] New profiler API.
[mono.git] / mono / metadata / profiler-private.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_PRIVATE_H__
8 #define __MONO_PROFILER_PRIVATE_H__
9
10 #include <mono/metadata/profiler.h>
11 #include <mono/utils/mono-lazy-init.h>
12 #include <mono/utils/mono-os-mutex.h>
13 #include <mono/utils/mono-os-semaphore.h>
14
15 struct _MonoProfilerDesc {
16         MonoProfilerHandle next;
17         MonoProfiler *prof;
18         volatile gpointer coverage_filter;
19         volatile gpointer call_instrumentation_filter;
20
21 #define _MONO_PROFILER_EVENT(name) \
22         volatile gpointer name ## _cb;
23 #define MONO_PROFILER_EVENT_0(name, type) \
24         _MONO_PROFILER_EVENT(name)
25 #define MONO_PROFILER_EVENT_1(name, type, arg1_type, arg1_name) \
26         _MONO_PROFILER_EVENT(name)
27 #define MONO_PROFILER_EVENT_2(name, type, arg1_type, arg1_name, arg2_type, arg2_name) \
28         _MONO_PROFILER_EVENT(name)
29 #define MONO_PROFILER_EVENT_3(name, type, arg1_type, arg1_name, arg2_type, arg2_name, arg3_type, arg3_name) \
30         _MONO_PROFILER_EVENT(name)
31 #define MONO_PROFILER_EVENT_4(name, type, arg1_type, arg1_name, arg2_type, arg2_name, arg3_type, arg3_name, arg4_type, arg4_name) \
32         _MONO_PROFILER_EVENT(name)
33 #include <mono/metadata/profiler-events.h>
34 #undef MONO_PROFILER_EVENT_0
35 #undef MONO_PROFILER_EVENT_1
36 #undef MONO_PROFILER_EVENT_2
37 #undef MONO_PROFILER_EVENT_3
38 #undef MONO_PROFILER_EVENT_4
39 #undef _MONO_PROFILER_EVENT
40 };
41
42 typedef struct {
43         gboolean startup_done;
44         MonoProfilerHandle profilers;
45         mono_lazy_init_t coverage_status;
46         mono_mutex_t coverage_mutex;
47         GHashTable *coverage_hash;
48         MonoProfilerHandle sampling_owner;
49         MonoSemType sampling_semaphore;
50         MonoProfilerSampleMode sample_mode;
51         uint64_t sample_freq;
52         gboolean allocations;
53
54 #define _MONO_PROFILER_EVENT(name) \
55         volatile gint32 name ## _count;
56 #define MONO_PROFILER_EVENT_0(name, type) \
57         _MONO_PROFILER_EVENT(name)
58 #define MONO_PROFILER_EVENT_1(name, type, arg1_type, arg1_name) \
59         _MONO_PROFILER_EVENT(name)
60 #define MONO_PROFILER_EVENT_2(name, type, arg1_type, arg1_name, arg2_type, arg2_name) \
61         _MONO_PROFILER_EVENT(name)
62 #define MONO_PROFILER_EVENT_3(name, type, arg1_type, arg1_name, arg2_type, arg2_name, arg3_type, arg3_name) \
63         _MONO_PROFILER_EVENT(name)
64 #define MONO_PROFILER_EVENT_4(name, type, arg1_type, arg1_name, arg2_type, arg2_name, arg3_type, arg3_name, arg4_type, arg4_name) \
65         _MONO_PROFILER_EVENT(name)
66 #include <mono/metadata/profiler-events.h>
67 #undef MONO_PROFILER_EVENT_0
68 #undef MONO_PROFILER_EVENT_1
69 #undef MONO_PROFILER_EVENT_2
70 #undef MONO_PROFILER_EVENT_3
71 #undef MONO_PROFILER_EVENT_4
72 #undef _MONO_PROFILER_EVENT
73 } MonoProfilerState;
74
75 extern MonoProfilerState mono_profiler_state;
76
77 typedef struct {
78         guint32 entries;
79         struct {
80                 guchar *cil_code;
81                 guint32 count;
82         } data [1];
83 } MonoProfilerCoverageInfo;
84
85 void mono_profiler_started (void);
86 void mono_profiler_cleanup (void);
87
88 static inline gboolean
89 mono_profiler_installed (void)
90 {
91         return !!mono_profiler_state.profilers;
92 }
93
94 MonoProfilerCoverageInfo *mono_profiler_coverage_alloc (MonoMethod *method, guint32 entries);
95 void mono_profiler_coverage_free (MonoMethod *method);
96
97 gboolean mono_profiler_should_instrument_method (MonoMethod *method, gboolean entry);
98
99 gboolean mono_profiler_sampling_enabled (void);
100 void mono_profiler_sampling_thread_sleep (void);
101
102 static inline gboolean
103 mono_profiler_allocations_enabled (void)
104 {
105         return mono_profiler_state.allocations;
106 }
107
108 #define _MONO_PROFILER_EVENT(name, ...) \
109         void mono_profiler_raise_ ## name (__VA_ARGS__);
110 #define MONO_PROFILER_EVENT_0(name, type) \
111         _MONO_PROFILER_EVENT(name, void)
112 #define MONO_PROFILER_EVENT_1(name, type, arg1_type, arg1_name) \
113         _MONO_PROFILER_EVENT(name, arg1_type arg1_name)
114 #define MONO_PROFILER_EVENT_2(name, type, arg1_type, arg1_name, arg2_type, arg2_name) \
115         _MONO_PROFILER_EVENT(name, arg1_type arg1_name, arg2_type arg2_name)
116 #define MONO_PROFILER_EVENT_3(name, type, arg1_type, arg1_name, arg2_type, arg2_name, arg3_type, arg3_name) \
117         _MONO_PROFILER_EVENT(name, arg1_type arg1_name, arg2_type arg2_name, arg3_type arg3_name)
118 #define MONO_PROFILER_EVENT_4(name, type, arg1_type, arg1_name, arg2_type, arg2_name, arg3_type, arg3_name, arg4_type, arg4_name) \
119         _MONO_PROFILER_EVENT(name, arg1_type arg1_name, arg2_type arg2_name, arg3_type arg3_name, arg4_type arg4_name)
120 #include <mono/metadata/profiler-events.h>
121 #undef MONO_PROFILER_EVENT_0
122 #undef MONO_PROFILER_EVENT_1
123 #undef MONO_PROFILER_EVENT_2
124 #undef MONO_PROFILER_EVENT_3
125 #undef MONO_PROFILER_EVENT_4
126 #undef _MONO_PROFILER_EVENT
127
128 // These are the macros the rest of the runtime should use.
129
130 #define MONO_PROFILER_ENABLED(name) \
131         G_UNLIKELY (mono_profiler_state.name ## _count)
132
133 #define MONO_PROFILER_RAISE(name, args) \
134         do { \
135                 if (MONO_PROFILER_ENABLED (name)) \
136                         mono_profiler_raise_ ## name args; \
137         } while (0)
138
139 #endif // __MONO_PROFILER_PRIVATE_H__