7877b797b12fa780126a58f545d267a2ac8ecea6
[platform/upstream/coreclr.git] / src / vm / eventpipeeventinstance.cpp
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 "eventpipeeventinstance.h"
7 #include "eventpipejsonfile.h"
8 #include "fastserializer.h"
9 #include "sampleprofiler.h"
10
11 #ifdef FEATURE_PERFTRACING
12
13 EventPipeEventInstance::EventPipeEventInstance(
14     EventPipeEvent &event,
15     DWORD threadID,
16     BYTE *pData,
17     unsigned int length)
18 {
19     CONTRACTL
20     {
21         THROWS;
22         GC_TRIGGERS;
23         MODE_ANY;
24     }
25     CONTRACTL_END;
26
27 #ifdef _DEBUG
28     m_debugEventStart = 0xDEADBEEF;
29     m_debugEventEnd = 0xCAFEBABE;
30 #endif // _DEBUG
31     m_pEvent = &event;
32     m_threadID = threadID;
33     m_pData = pData;
34     m_dataLength = length;
35     QueryPerformanceCounter(&m_timeStamp);
36
37     if(event.NeedStack())
38     {
39         EventPipe::WalkManagedStackForCurrentThread(m_stackContents);
40     }
41
42 #ifdef _DEBUG
43     EnsureConsistency();
44 #endif // _DEBUG
45 }
46
47 StackContents* EventPipeEventInstance::GetStack()
48 {
49     LIMITED_METHOD_CONTRACT;
50
51     return &m_stackContents;
52 }
53
54 EventPipeEvent* EventPipeEventInstance::GetEvent() const
55 {
56     LIMITED_METHOD_CONTRACT;
57
58     return m_pEvent;
59 }
60
61 LARGE_INTEGER EventPipeEventInstance::GetTimeStamp() const
62 {
63     LIMITED_METHOD_CONTRACT;
64
65     return m_timeStamp;
66 }
67
68 BYTE* EventPipeEventInstance::GetData() const
69 {
70     LIMITED_METHOD_CONTRACT;
71
72     return m_pData;
73 }
74
75 unsigned int EventPipeEventInstance::GetLength() const
76 {
77     LIMITED_METHOD_CONTRACT;
78
79     return m_dataLength;
80 }
81
82 void EventPipeEventInstance::FastSerialize(FastSerializer *pSerializer, StreamLabel metadataLabel)
83 {
84     CONTRACTL
85     {
86         THROWS;
87         GC_TRIGGERS;
88         MODE_ANY;
89     }
90     CONTRACTL_END;
91
92 #ifdef _DEBUG
93     // Useful for diagnosing serialization bugs.
94     const unsigned int value = 0xDEADBEEF;
95     pSerializer->WriteBuffer((BYTE*)&value, sizeof(value));
96 #endif
97
98     // Calculate the size of the total payload so that it can be written to the file.
99     unsigned int payloadLength =
100         sizeof(metadataLabel) +
101         sizeof(m_threadID) +        // Thread ID
102         sizeof(m_timeStamp) +       // TimeStamp
103         m_dataLength +              // Event payload data length
104         m_stackContents.GetSize();  // Stack payload size
105
106     // Write the size of the event to the file.
107     pSerializer->WriteBuffer((BYTE*)&payloadLength, sizeof(payloadLength));
108
109     // Write the metadata label.
110     pSerializer->WriteBuffer((BYTE*)&metadataLabel, sizeof(metadataLabel));
111
112     // Write the thread ID.
113     pSerializer->WriteBuffer((BYTE*)&m_threadID, sizeof(m_threadID));
114
115     // Write the timestamp.
116     pSerializer->WriteBuffer((BYTE*)&m_timeStamp, sizeof(m_timeStamp));
117
118     // Write the event data payload.
119     if(m_dataLength > 0)
120     {
121         pSerializer->WriteBuffer(m_pData, m_dataLength);
122     }
123
124     // Write the stack if present.
125     if(m_stackContents.GetSize() > 0)
126     {
127         pSerializer->WriteBuffer(m_stackContents.GetPointer(), m_stackContents.GetSize());
128     }
129 }
130
131 #ifdef _DEBUG
132 void EventPipeEventInstance::SerializeToJsonFile(EventPipeJsonFile *pFile)
133 {
134     CONTRACTL
135     {
136         NOTHROW;
137         GC_NOTRIGGER;
138         MODE_ANY;
139     }
140     CONTRACTL_END;
141
142     if(pFile == NULL)
143     {
144         return;
145     }
146
147     EX_TRY
148     {
149         const unsigned int guidSize = 39;
150         WCHAR wszProviderID[guidSize];
151         if(!StringFromGUID2(m_pEvent->GetProvider()->GetProviderID(), wszProviderID, guidSize))
152         {
153             wszProviderID[0] = '\0';
154         }
155
156         // Strip off the {}.
157         StackScratchBuffer scratch;
158         SString guidStr(&wszProviderID[1], guidSize-3);
159
160         SString message;
161         message.Printf("Provider=%s/EventID=%d/Version=%d", guidStr.GetANSI(scratch), m_pEvent->GetEventID(), m_pEvent->GetEventVersion());
162         pFile->WriteEvent(m_timeStamp, m_threadID, message, m_stackContents);
163     }
164     EX_CATCH{} EX_END_CATCH(SwallowAllExceptions);
165 }
166 #endif
167
168 void EventPipeEventInstance::SetTimeStamp(LARGE_INTEGER timeStamp)
169 {
170     LIMITED_METHOD_CONTRACT;
171
172     m_timeStamp = timeStamp;
173 }
174
175 #ifdef _DEBUG
176 bool EventPipeEventInstance::EnsureConsistency()
177 {
178     CONTRACTL
179     {
180         NOTHROW;
181         GC_NOTRIGGER;
182         MODE_ANY;
183     }
184     CONTRACTL_END;
185
186     // Validate event start.
187     _ASSERTE(m_debugEventStart == 0xDEADBEEF);
188
189     // Validate event end.
190     _ASSERTE(m_debugEventEnd == 0xCAFEBABE);
191
192     return true;
193 }
194 #endif // _DEBUG
195
196 SampleProfilerEventInstance::SampleProfilerEventInstance(Thread *pThread)
197     :EventPipeEventInstance(*SampleProfiler::s_pThreadTimeEvent, pThread->GetOSThreadId(), NULL, 0)
198 {
199     LIMITED_METHOD_CONTRACT;
200 }
201
202 #endif // FEATURE_PERFTRACING