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 | #include "common.h" |
6 | #include "gctoclreventsink.h" |
7 | #include "eventtrace.h" |
8 | |
9 | GCToCLREventSink g_gcToClrEventSink; |
10 | |
11 | void GCToCLREventSink::FireDynamicEvent(const char* eventName, void* payload, uint32_t payloadSize) |
12 | { |
13 | LIMITED_METHOD_CONTRACT; |
14 | |
15 | const size_t EventNameMaxSize = 255; |
16 | |
17 | WCHAR wideEventName[EventNameMaxSize]; |
18 | if (MultiByteToWideChar(CP_ACP, 0, eventName, -1, wideEventName, EventNameMaxSize) == 0) |
19 | { |
20 | return; |
21 | } |
22 | |
23 | FireEtwGCDynamicEvent(wideEventName, payloadSize, (const BYTE*)payload, GetClrInstanceId()); |
24 | } |
25 | |
26 | void GCToCLREventSink::FireGCStart_V2(uint32_t count, uint32_t depth, uint32_t reason, uint32_t type) |
27 | { |
28 | LIMITED_METHOD_CONTRACT; |
29 | |
30 | ETW::GCLog::ETW_GC_INFO gcStartInfo; |
31 | gcStartInfo.GCStart.Count = count; |
32 | gcStartInfo.GCStart.Depth = depth; |
33 | gcStartInfo.GCStart.Reason = static_cast<ETW::GCLog::ETW_GC_INFO::GC_REASON>(reason); |
34 | gcStartInfo.GCStart.Type = static_cast<ETW::GCLog::ETW_GC_INFO::GC_TYPE>(type); |
35 | ETW::GCLog::FireGcStart(&gcStartInfo); |
36 | } |
37 | |
38 | void GCToCLREventSink::FireGCGenerationRange(uint8_t generation, void* rangeStart, uint64_t rangeUsedLength, uint64_t rangeReservedLength) |
39 | { |
40 | LIMITED_METHOD_CONTRACT; |
41 | |
42 | FireEtwGCGenerationRange(generation, rangeStart, rangeUsedLength, rangeReservedLength, GetClrInstanceId()); |
43 | } |
44 | |
45 | void GCToCLREventSink::FireGCEnd_V1(uint32_t count, uint32_t depth) |
46 | { |
47 | LIMITED_METHOD_CONTRACT; |
48 | |
49 | FireEtwGCEnd_V1(count, depth, GetClrInstanceId()); |
50 | } |
51 | |
52 | void GCToCLREventSink::FireGCHeapStats_V1( |
53 | uint64_t generationSize0, |
54 | uint64_t totalPromotedSize0, |
55 | uint64_t generationSize1, |
56 | uint64_t totalPromotedSize1, |
57 | uint64_t generationSize2, |
58 | uint64_t totalPromotedSize2, |
59 | uint64_t generationSize3, |
60 | uint64_t totalPromotedSize3, |
61 | uint64_t finalizationPromotedSize, |
62 | uint64_t finalizationPromotedCount, |
63 | uint32_t pinnedObjectCount, |
64 | uint32_t sinkBlockCount, |
65 | uint32_t gcHandleCount) |
66 | { |
67 | LIMITED_METHOD_CONTRACT; |
68 | |
69 | FireEtwGCHeapStats_V1(generationSize0, totalPromotedSize0, generationSize1, totalPromotedSize1, |
70 | generationSize2, totalPromotedSize2, generationSize3, totalPromotedSize3, |
71 | finalizationPromotedSize, finalizationPromotedCount, pinnedObjectCount, |
72 | sinkBlockCount, gcHandleCount, GetClrInstanceId()); |
73 | } |
74 | |
75 | void GCToCLREventSink::FireGCCreateSegment_V1(void* address, size_t size, uint32_t type) |
76 | { |
77 | LIMITED_METHOD_CONTRACT; |
78 | |
79 | FireEtwGCCreateSegment_V1((uint64_t)address, static_cast<uint64_t>(size), type, GetClrInstanceId()); |
80 | } |
81 | |
82 | void GCToCLREventSink::FireGCFreeSegment_V1(void* address) |
83 | { |
84 | LIMITED_METHOD_CONTRACT; |
85 | |
86 | FireEtwGCFreeSegment_V1((uint64_t)address, GetClrInstanceId()); |
87 | } |
88 | |
89 | void GCToCLREventSink::FireGCCreateConcurrentThread_V1() |
90 | { |
91 | LIMITED_METHOD_CONTRACT; |
92 | |
93 | FireEtwGCCreateConcurrentThread_V1(GetClrInstanceId()); |
94 | } |
95 | |
96 | void GCToCLREventSink::FireGCTerminateConcurrentThread_V1() |
97 | { |
98 | LIMITED_METHOD_CONTRACT; |
99 | |
100 | FireEtwGCTerminateConcurrentThread_V1(GetClrInstanceId()); |
101 | } |
102 | |
103 | void GCToCLREventSink::FireGCTriggered(uint32_t reason) |
104 | { |
105 | LIMITED_METHOD_CONTRACT; |
106 | |
107 | FireEtwGCTriggered(reason, GetClrInstanceId()); |
108 | } |
109 | |
110 | void GCToCLREventSink::FireGCMarkWithType(uint32_t heapNum, uint32_t type, uint64_t bytes) |
111 | { |
112 | LIMITED_METHOD_CONTRACT; |
113 | |
114 | FireEtwGCMarkWithType(heapNum, GetClrInstanceId(), type, bytes); |
115 | } |
116 | |
117 | void GCToCLREventSink::FireGCJoin_V2(uint32_t heap, uint32_t joinTime, uint32_t joinType, uint32_t joinId) |
118 | { |
119 | LIMITED_METHOD_CONTRACT; |
120 | |
121 | FireEtwGCJoin_V2(heap, joinTime, joinType, GetClrInstanceId(), joinId); |
122 | } |
123 | |
124 | void GCToCLREventSink::FireGCGlobalHeapHistory_V2(uint64_t finalYoungestDesired, |
125 | int32_t numHeaps, |
126 | uint32_t condemnedGeneration, |
127 | uint32_t gen0reductionCount, |
128 | uint32_t reason, |
129 | uint32_t globalMechanisms, |
130 | uint32_t pauseMode, |
131 | uint32_t memoryPressure) |
132 | { |
133 | LIMITED_METHOD_CONTRACT; |
134 | |
135 | FireEtwGCGlobalHeapHistory_V2(finalYoungestDesired, numHeaps, condemnedGeneration, gen0reductionCount, reason, |
136 | globalMechanisms, GetClrInstanceId(), pauseMode, memoryPressure); |
137 | } |
138 | |
139 | void GCToCLREventSink::FireGCAllocationTick_V1(uint32_t allocationAmount, uint32_t allocationKind) |
140 | { |
141 | LIMITED_METHOD_CONTRACT; |
142 | |
143 | FireEtwGCAllocationTick_V1(allocationAmount, allocationKind, GetClrInstanceId()); |
144 | } |
145 | |
146 | void GCToCLREventSink::FireGCAllocationTick_V3(uint64_t allocationAmount, uint32_t allocationKind, uint32_t heapIndex, void* objectAddress) |
147 | { |
148 | LIMITED_METHOD_CONTRACT; |
149 | |
150 | void * typeId = nullptr; |
151 | const WCHAR * name = nullptr; |
152 | InlineSString<MAX_CLASSNAME_LENGTH> strTypeName; |
153 | EX_TRY |
154 | { |
155 | TypeHandle th = GetThread()->GetTHAllocContextObj(); |
156 | |
157 | if (th != 0) |
158 | { |
159 | th.GetName(strTypeName); |
160 | name = strTypeName.GetUnicode(); |
161 | typeId = th.GetMethodTable(); |
162 | } |
163 | } |
164 | EX_CATCH {} |
165 | EX_END_CATCH(SwallowAllExceptions) |
166 | |
167 | if (typeId != nullptr) |
168 | { |
169 | FireEtwGCAllocationTick_V3(static_cast<uint32_t>(allocationAmount), |
170 | allocationKind, |
171 | GetClrInstanceId(), |
172 | allocationAmount, |
173 | typeId, |
174 | name, |
175 | heapIndex, |
176 | objectAddress); |
177 | } |
178 | } |
179 | |
180 | void GCToCLREventSink::FirePinObjectAtGCTime(void* object, uint8_t** ppObject) |
181 | { |
182 | LIMITED_METHOD_CONTRACT; |
183 | |
184 | Object* obj = (Object*)object; |
185 | |
186 | InlineSString<MAX_CLASSNAME_LENGTH> strTypeName; |
187 | |
188 | EX_TRY |
189 | { |
190 | FAULT_NOT_FATAL(); |
191 | |
192 | TypeHandle th = obj->GetGCSafeTypeHandleIfPossible(); |
193 | if(th != NULL) |
194 | { |
195 | th.GetName(strTypeName); |
196 | } |
197 | |
198 | FireEtwPinObjectAtGCTime(ppObject, |
199 | object, |
200 | obj->GetSize(), |
201 | strTypeName.GetUnicode(), |
202 | GetClrInstanceId()); |
203 | } |
204 | EX_CATCH {} |
205 | EX_END_CATCH(SwallowAllExceptions) |
206 | } |
207 | |
208 | void GCToCLREventSink::FirePinPlugAtGCTime(uint8_t* plugStart, uint8_t* plugEnd, uint8_t* gapBeforeSize) |
209 | { |
210 | LIMITED_METHOD_CONTRACT; |
211 | FireEtwPinPlugAtGCTime(plugStart, plugEnd, gapBeforeSize, GetClrInstanceId()); |
212 | } |
213 | |
214 | void GCToCLREventSink::FireGCPerHeapHistory_V3(void *freeListAllocated, |
215 | void *freeListRejected, |
216 | void *endOfSegAllocated, |
217 | void *condemnedAllocated, |
218 | void *pinnedAllocated, |
219 | void *pinnedAllocatedAdvance, |
220 | uint32_t runningFreeListEfficiency, |
221 | uint32_t condemnReasons0, |
222 | uint32_t condemnReasons1, |
223 | uint32_t compactMechanisms, |
224 | uint32_t expandMechanisms, |
225 | uint32_t heapIndex, |
226 | void *, |
227 | uint32_t count, |
228 | uint32_t valuesLen, |
229 | void *values) |
230 | { |
231 | FireEtwGCPerHeapHistory_V3(GetClrInstanceId(), |
232 | freeListAllocated, |
233 | freeListRejected, |
234 | endOfSegAllocated, |
235 | condemnedAllocated, |
236 | pinnedAllocated, |
237 | pinnedAllocatedAdvance, |
238 | runningFreeListEfficiency, |
239 | condemnReasons0, |
240 | condemnReasons1, |
241 | compactMechanisms, |
242 | expandMechanisms, |
243 | heapIndex, |
244 | extraGen0Commit, |
245 | count, |
246 | valuesLen, |
247 | values); |
248 | } |
249 | |
250 | |
251 | |
252 | void GCToCLREventSink::FireBGCBegin() |
253 | { |
254 | FireEtwBGCBegin(GetClrInstanceId()); |
255 | } |
256 | |
257 | void GCToCLREventSink::FireBGC1stNonConEnd() |
258 | { |
259 | FireEtwBGC1stNonConEnd(GetClrInstanceId()); |
260 | } |
261 | |
262 | void GCToCLREventSink::FireBGC1stConEnd() |
263 | { |
264 | FireEtwBGC1stConEnd(GetClrInstanceId()); |
265 | } |
266 | |
267 | void GCToCLREventSink::FireBGC1stSweepEnd(uint32_t genNumber) |
268 | { |
269 | FireEtwBGC1stSweepEnd(genNumber, GetClrInstanceId()); |
270 | } |
271 | |
272 | void GCToCLREventSink::FireBGC2ndNonConBegin() |
273 | { |
274 | FireEtwBGC2ndNonConBegin(GetClrInstanceId()); |
275 | } |
276 | |
277 | void GCToCLREventSink::FireBGC2ndNonConEnd() |
278 | { |
279 | FireEtwBGC2ndNonConEnd(GetClrInstanceId()); |
280 | } |
281 | |
282 | void GCToCLREventSink::FireBGC2ndConBegin() |
283 | { |
284 | FireEtwBGC2ndConBegin(GetClrInstanceId()); |
285 | } |
286 | |
287 | void GCToCLREventSink::FireBGC2ndConEnd() |
288 | { |
289 | FireEtwBGC2ndConEnd(GetClrInstanceId()); |
290 | } |
291 | |
292 | void GCToCLREventSink::FireBGCDrainMark(uint64_t objects) |
293 | { |
294 | FireEtwBGCDrainMark(objects, GetClrInstanceId()); |
295 | } |
296 | |
297 | void GCToCLREventSink::FireBGCRevisit(uint64_t pages, uint64_t objects, uint32_t isLarge) |
298 | { |
299 | FireEtwBGCRevisit(pages, objects, isLarge, GetClrInstanceId()); |
300 | } |
301 | |
302 | void GCToCLREventSink::FireBGCOverflow(uint64_t min, uint64_t max, uint64_t objects, uint32_t isLarge) |
303 | { |
304 | FireEtwBGCOverflow(min, max, objects, isLarge, GetClrInstanceId()); |
305 | } |
306 | |
307 | void GCToCLREventSink::FireBGCAllocWaitBegin(uint32_t reason) |
308 | { |
309 | FireEtwBGCAllocWaitBegin(reason, GetClrInstanceId()); |
310 | } |
311 | |
312 | void GCToCLREventSink::FireBGCAllocWaitEnd(uint32_t reason) |
313 | { |
314 | FireEtwBGCAllocWaitEnd(reason, GetClrInstanceId()); |
315 | } |
316 | |
317 | void GCToCLREventSink::FireGCFullNotify_V1(uint32_t genNumber, uint32_t isAlloc) |
318 | { |
319 | FireEtwGCFullNotify_V1(genNumber, isAlloc, GetClrInstanceId()); |
320 | } |
321 | |
322 | void GCToCLREventSink::FireSetGCHandle(void *handleID, void *objectID, uint32_t kind, uint32_t generation, uint64_t appDomainID) |
323 | { |
324 | FireEtwSetGCHandle(handleID, objectID, kind, generation, appDomainID, GetClrInstanceId()); |
325 | } |
326 | |
327 | void GCToCLREventSink::FirePrvSetGCHandle(void *handleID, void *objectID, uint32_t kind, uint32_t generation, uint64_t appDomainID) |
328 | { |
329 | FireEtwPrvSetGCHandle(handleID, objectID, kind, generation, appDomainID, GetClrInstanceId()); |
330 | } |
331 | |
332 | void GCToCLREventSink::FireDestroyGCHandle(void *handleID) |
333 | { |
334 | FireEtwDestroyGCHandle(handleID, GetClrInstanceId()); |
335 | } |
336 | |
337 | void GCToCLREventSink::FirePrvDestroyGCHandle(void *handleID) |
338 | { |
339 | FireEtwPrvDestroyGCHandle(handleID, GetClrInstanceId()); |
340 | } |
341 | |