[profiler] Some improvements to the code coverage 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 #define MONO_PROFILER_UNSTABLE_GC_ROOTS
11 #include <mono/metadata/profiler.h>
12 #include <mono/utils/mono-context.h>
13 #include <mono/utils/mono-os-mutex.h>
14 #include <mono/utils/mono-os-semaphore.h>
15
16 struct _MonoProfilerDesc {
17         MonoProfilerHandle next;
18         MonoProfiler *prof;
19         volatile gpointer coverage_filter;
20         volatile gpointer call_instrumentation_filter;
21
22 #define _MONO_PROFILER_EVENT(name) \
23         volatile gpointer name ## _cb;
24 #define MONO_PROFILER_EVENT_0(name, type) \
25         _MONO_PROFILER_EVENT(name)
26 #define MONO_PROFILER_EVENT_1(name, type, arg1_type, arg1_name) \
27         _MONO_PROFILER_EVENT(name)
28 #define MONO_PROFILER_EVENT_2(name, type, arg1_type, arg1_name, arg2_type, arg2_name) \
29         _MONO_PROFILER_EVENT(name)
30 #define MONO_PROFILER_EVENT_3(name, type, arg1_type, arg1_name, arg2_type, arg2_name, arg3_type, arg3_name) \
31         _MONO_PROFILER_EVENT(name)
32 #define MONO_PROFILER_EVENT_4(name, type, arg1_type, arg1_name, arg2_type, arg2_name, arg3_type, arg3_name, arg4_type, arg4_name) \
33         _MONO_PROFILER_EVENT(name)
34 #include <mono/metadata/profiler-events.h>
35 #undef MONO_PROFILER_EVENT_0
36 #undef MONO_PROFILER_EVENT_1
37 #undef MONO_PROFILER_EVENT_2
38 #undef MONO_PROFILER_EVENT_3
39 #undef MONO_PROFILER_EVENT_4
40 #undef _MONO_PROFILER_EVENT
41 };
42
43 typedef struct {
44         gboolean startup_done;
45
46         MonoProfilerHandle profilers;
47
48         gboolean code_coverage;
49         mono_mutex_t coverage_mutex;
50         GHashTable *coverage_hash;
51
52         MonoProfilerHandle sampling_owner;
53         MonoSemType sampling_semaphore;
54         MonoProfilerSampleMode sample_mode;
55         guint32 sample_freq;
56
57         gboolean allocations;
58
59         gboolean call_contexts;
60         void (*context_enable) (void);
61         gpointer (*context_get_this) (MonoProfilerCallContext *);
62         gpointer (*context_get_argument) (MonoProfilerCallContext *, guint32);
63         gpointer (*context_get_local) (MonoProfilerCallContext *, guint32);
64         gpointer (*context_get_result) (MonoProfilerCallContext *);
65         void (*context_free_buffer) (gpointer);
66
67 #define _MONO_PROFILER_EVENT(name) \
68         volatile gint32 name ## _count;
69 #define MONO_PROFILER_EVENT_0(name, type) \
70         _MONO_PROFILER_EVENT(name)
71 #define MONO_PROFILER_EVENT_1(name, type, arg1_type, arg1_name) \
72         _MONO_PROFILER_EVENT(name)
73 #define MONO_PROFILER_EVENT_2(name, type, arg1_type, arg1_name, arg2_type, arg2_name) \
74         _MONO_PROFILER_EVENT(name)
75 #define MONO_PROFILER_EVENT_3(name, type, arg1_type, arg1_name, arg2_type, arg2_name, arg3_type, arg3_name) \
76         _MONO_PROFILER_EVENT(name)
77 #define MONO_PROFILER_EVENT_4(name, type, arg1_type, arg1_name, arg2_type, arg2_name, arg3_type, arg3_name, arg4_type, arg4_name) \
78         _MONO_PROFILER_EVENT(name)
79 #include <mono/metadata/profiler-events.h>
80 #undef MONO_PROFILER_EVENT_0
81 #undef MONO_PROFILER_EVENT_1
82 #undef MONO_PROFILER_EVENT_2
83 #undef MONO_PROFILER_EVENT_3
84 #undef MONO_PROFILER_EVENT_4
85 #undef _MONO_PROFILER_EVENT
86 } MonoProfilerState;
87
88 extern MonoProfilerState mono_profiler_state;
89
90 typedef struct {
91         guint32 entries;
92         struct {
93                 guchar *cil_code;
94                 guint32 count;
95         } data [1];
96 } MonoProfilerCoverageInfo;
97
98 void mono_profiler_started (void);
99 void mono_profiler_cleanup (void);
100
101 static inline gboolean
102 mono_profiler_installed (void)
103 {
104         return !!mono_profiler_state.profilers;
105 }
106
107 MonoProfilerCoverageInfo *mono_profiler_coverage_alloc (MonoMethod *method, guint32 entries);
108
109 struct _MonoProfilerCallContext {
110         /*
111          * Must be the first field (the JIT relies on it). Only filled out if this
112          * is a JIT frame; otherwise, zeroed.
113          */
114         MonoContext context;
115         /*
116          * A non-NULL MonoInterpFrameHandle if this is an interpreter frame.
117          */
118         gpointer interp_frame;
119         MonoMethod *method;
120         /*
121          * Points to the return value for an epilogue context. For a prologue, this
122          * is set to NULL.
123          */
124         gpointer return_value;
125 };
126
127 MonoProfilerCallInstrumentationFlags mono_profiler_get_call_instrumentation_flags (MonoMethod *method);
128
129 gboolean mono_profiler_sampling_enabled (void);
130 void mono_profiler_sampling_thread_post (void);
131 void mono_profiler_sampling_thread_wait (void);
132
133 static inline gboolean
134 mono_profiler_allocations_enabled (void)
135 {
136         return mono_profiler_state.allocations;
137 }
138
139 #define _MONO_PROFILER_EVENT(name, ...) \
140         void mono_profiler_raise_ ## name (__VA_ARGS__);
141 #define MONO_PROFILER_EVENT_0(name, type) \
142         _MONO_PROFILER_EVENT(name, void)
143 #define MONO_PROFILER_EVENT_1(name, type, arg1_type, arg1_name) \
144         _MONO_PROFILER_EVENT(name, arg1_type arg1_name)
145 #define MONO_PROFILER_EVENT_2(name, type, arg1_type, arg1_name, arg2_type, arg2_name) \
146         _MONO_PROFILER_EVENT(name, arg1_type arg1_name, arg2_type arg2_name)
147 #define MONO_PROFILER_EVENT_3(name, type, arg1_type, arg1_name, arg2_type, arg2_name, arg3_type, arg3_name) \
148         _MONO_PROFILER_EVENT(name, arg1_type arg1_name, arg2_type arg2_name, arg3_type arg3_name)
149 #define MONO_PROFILER_EVENT_4(name, type, arg1_type, arg1_name, arg2_type, arg2_name, arg3_type, arg3_name, arg4_type, arg4_name) \
150         _MONO_PROFILER_EVENT(name, arg1_type arg1_name, arg2_type arg2_name, arg3_type arg3_name, arg4_type arg4_name)
151 #include <mono/metadata/profiler-events.h>
152 #undef MONO_PROFILER_EVENT_0
153 #undef MONO_PROFILER_EVENT_1
154 #undef MONO_PROFILER_EVENT_2
155 #undef MONO_PROFILER_EVENT_3
156 #undef MONO_PROFILER_EVENT_4
157 #undef _MONO_PROFILER_EVENT
158
159 // These are the macros the rest of the runtime should use.
160
161 #define MONO_PROFILER_ENABLED(name) \
162         G_UNLIKELY (mono_profiler_state.name ## _count)
163
164 #define MONO_PROFILER_RAISE(name, args) \
165         do { \
166                 if (MONO_PROFILER_ENABLED (name)) \
167                         mono_profiler_raise_ ## name args; \
168         } while (0)
169
170 #endif // __MONO_PROFILER_PRIVATE_H__