1// Licensed to the .NET Foundation under one or more agreements.
2// The .NET Foundation licenses this file to you under the MIT license.
3// See the LICENSE file in the project root for more information.
4//
5// EEToProfInterfaceWrapper.inl
6//
7
8//
9// Inline implementation of wrappers around code that calls into some of the profiler's
10// callback methods.
11//
12
13// ======================================================================================
14
15#ifndef _EETOPROFEXCEPTIONINTERFACEWRAPPER_INL_
16#define _EETOPROFEXCEPTIONINTERFACEWRAPPER_INL_
17
18#include "common.h"
19
20
21// A wrapper for the profiler. Various events to signal different phases of exception
22// handling.
23class EEToProfilerExceptionInterfaceWrapper
24{
25 public:
26
27#if defined(PROFILING_SUPPORTED)
28 //
29 // Exception creation
30 //
31
32 static inline void ExceptionThrown(Thread * pThread)
33 {
34 WRAPPER_NO_CONTRACT;
35 {
36 BEGIN_PIN_PROFILER(CORProfilerTrackExceptions());
37 _ASSERTE(pThread->PreemptiveGCDisabled());
38
39 // Get a reference to the object that won't move
40 OBJECTREF thrown = pThread->GetThrowable();
41
42 g_profControlBlock.pProfInterface->ExceptionThrown(
43 reinterpret_cast<ObjectID>((*(BYTE **)&thrown)));
44 END_PIN_PROFILER();
45 }
46 }
47
48 //
49 // Search phase
50 //
51
52 static inline void ExceptionSearchFunctionEnter(MethodDesc * pFunction)
53 {
54 WRAPPER_NO_CONTRACT;
55 // Notify the profiler of the function being searched for a handler.
56 {
57 BEGIN_PIN_PROFILER(CORProfilerTrackExceptions());
58 if (!pFunction->IsNoMetadata())
59 {
60 GCX_PREEMP();
61 g_profControlBlock.pProfInterface->ExceptionSearchFunctionEnter(
62 (FunctionID) pFunction);
63 }
64 END_PIN_PROFILER();
65 }
66 }
67
68 static inline void ExceptionSearchFunctionLeave(MethodDesc * pFunction)
69 {
70 WRAPPER_NO_CONTRACT;
71 // Notify the profiler of the function being searched for a handler.
72 {
73 BEGIN_PIN_PROFILER(CORProfilerTrackExceptions());
74 if (!pFunction->IsNoMetadata())
75 {
76 GCX_PREEMP();
77 g_profControlBlock.pProfInterface->ExceptionSearchFunctionLeave();
78 }
79 END_PIN_PROFILER();
80 }
81 }
82
83 static inline void ExceptionSearchFilterEnter(MethodDesc * pFunc)
84 {
85 WRAPPER_NO_CONTRACT;
86 // Notify the profiler of the filter.
87 {
88 BEGIN_PIN_PROFILER(CORProfilerTrackExceptions());
89 if (!pFunc->IsNoMetadata())
90 {
91 GCX_PREEMP();
92 g_profControlBlock.pProfInterface->ExceptionSearchFilterEnter(
93 (FunctionID) pFunc);
94 }
95 END_PIN_PROFILER();
96 }
97 }
98
99 static inline void ExceptionSearchFilterLeave()
100 {
101 WRAPPER_NO_CONTRACT;
102 // Notify the profiler of the filter.
103 {
104 BEGIN_PIN_PROFILER(CORProfilerTrackExceptions());
105 GCX_PREEMP();
106 g_profControlBlock.pProfInterface->ExceptionSearchFilterLeave();
107 END_PIN_PROFILER();
108 }
109 }
110
111 static inline void ExceptionSearchCatcherFound(MethodDesc * pFunc)
112 {
113 WRAPPER_NO_CONTRACT;
114 {
115 BEGIN_PIN_PROFILER(CORProfilerTrackExceptions());
116 if (!pFunc->IsNoMetadata())
117 {
118 GCX_PREEMP();
119 g_profControlBlock.pProfInterface->ExceptionSearchCatcherFound(
120 (FunctionID) pFunc);
121 }
122 END_PIN_PROFILER();
123 }
124 }
125
126 //
127 // Unwind phase
128 //
129 static inline void ExceptionUnwindFunctionEnter(MethodDesc * pFunc)
130 {
131 WRAPPER_NO_CONTRACT;
132 // Notify the profiler of the function being searched for a handler.
133 {
134 BEGIN_PIN_PROFILER(CORProfilerTrackExceptions());
135 if (!pFunc->IsNoMetadata())
136 {
137 g_profControlBlock.pProfInterface->ExceptionUnwindFunctionEnter(
138 (FunctionID) pFunc);
139 }
140 END_PIN_PROFILER();
141 }
142 }
143
144 static inline void ExceptionUnwindFunctionLeave(MethodDesc * pFunction)
145 {
146 WRAPPER_NO_CONTRACT;
147 // Notify the profiler that searching this function is over.
148 {
149 BEGIN_PIN_PROFILER(CORProfilerTrackExceptions());
150 if (!pFunction->IsNoMetadata())
151 {
152 g_profControlBlock.pProfInterface->ExceptionUnwindFunctionLeave();
153 }
154 END_PIN_PROFILER();
155 }
156 }
157
158 static inline void ExceptionUnwindFinallyEnter(MethodDesc * pFunc)
159 {
160 WRAPPER_NO_CONTRACT;
161 // Notify the profiler of the function being searched for a handler.
162 {
163 BEGIN_PIN_PROFILER(CORProfilerTrackExceptions());
164 if (!pFunc->IsNoMetadata())
165 {
166 g_profControlBlock.pProfInterface->ExceptionUnwindFinallyEnter(
167 (FunctionID) pFunc);
168 }
169 END_PIN_PROFILER();
170 }
171 }
172
173 static inline void ExceptionUnwindFinallyLeave()
174 {
175 WRAPPER_NO_CONTRACT;
176 // Notify the profiler of the function being searched for a handler.
177 {
178 BEGIN_PIN_PROFILER(CORProfilerTrackExceptions());
179 g_profControlBlock.pProfInterface->ExceptionUnwindFinallyLeave();
180 END_PIN_PROFILER();
181 }
182 }
183
184 static inline void ExceptionCatcherEnter(Thread * pThread, MethodDesc * pFunc)
185 {
186 WRAPPER_NO_CONTRACT;
187 // Notify the profiler.
188 {
189 BEGIN_PIN_PROFILER(CORProfilerTrackExceptions());
190 if (!pFunc->IsNoMetadata())
191 {
192 // <TODO>Remove the thrown variable as well as the
193 // gcprotect they are pointless.</TODO>
194
195 // Note that the callee must be aware that the ObjectID
196 // passed CAN change when gc happens.
197 OBJECTREF thrown = NULL;
198 GCPROTECT_BEGIN(thrown);
199 thrown = pThread->GetThrowable();
200 {
201 g_profControlBlock.pProfInterface->ExceptionCatcherEnter(
202 (FunctionID) pFunc,
203 reinterpret_cast<ObjectID>((*(BYTE **)&thrown)));
204 }
205 GCPROTECT_END();
206 }
207 END_PIN_PROFILER();
208 }
209 }
210
211 static inline void ExceptionCatcherLeave()
212 {
213 WRAPPER_NO_CONTRACT;
214 // Notify the profiler of the function being searched for a handler.
215 {
216 BEGIN_PIN_PROFILER(CORProfilerTrackExceptions());
217 g_profControlBlock.pProfInterface->ExceptionCatcherLeave();
218 END_PIN_PROFILER();
219 }
220 }
221
222
223#else // !PROFILING_SUPPORTED
224 static inline void ExceptionThrown(Thread * pThread) { LIMITED_METHOD_CONTRACT;}
225 static inline void ExceptionSearchFunctionEnter(MethodDesc * pFunction) { LIMITED_METHOD_CONTRACT;}
226 static inline void ExceptionSearchFunctionLeave(MethodDesc * pFunction) { LIMITED_METHOD_CONTRACT;}
227 static inline void ExceptionSearchFilterEnter(MethodDesc * pFunc) { LIMITED_METHOD_CONTRACT;}
228 static inline void ExceptionSearchFilterLeave() { LIMITED_METHOD_CONTRACT;}
229 static inline void ExceptionSearchCatcherFound(MethodDesc * pFunc) { LIMITED_METHOD_CONTRACT;}
230 static inline void ExceptionOSHandlerEnter(MethodDesc ** ppNotify, MethodDesc * pFunc) { LIMITED_METHOD_CONTRACT;}
231 static inline void ExceptionOSHandlerLeave(MethodDesc * pNotify) { LIMITED_METHOD_CONTRACT;}
232 static inline void ExceptionUnwindFunctionEnter(MethodDesc * pFunc) { LIMITED_METHOD_CONTRACT;}
233 static inline void ExceptionUnwindFunctionLeave(MethodDesc * pFunction) { LIMITED_METHOD_CONTRACT;}
234 static inline void ExceptionUnwindFinallyEnter(MethodDesc * pFunc) { LIMITED_METHOD_CONTRACT;}
235 static inline void ExceptionUnwindFinallyLeave() { LIMITED_METHOD_CONTRACT;}
236 static inline void ExceptionCatcherEnter(Thread * pThread, MethodDesc * pFunc) { LIMITED_METHOD_CONTRACT;}
237 static inline void ExceptionCatcherLeave() { LIMITED_METHOD_CONTRACT;}
238#endif // !PROFILING_SUPPORTED
239};
240
241
242#endif // _EETOPROFEXCEPTIONINTERFACEWRAPPER_INL_
243