Skip to content

Commit 788260a

Browse files
committed
Support emitting array in dynamic event
1 parent 46e4f66 commit 788260a

File tree

3 files changed

+95
-18
lines changed

3 files changed

+95
-18
lines changed

src/coreclr/gc/gc.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22342,6 +22342,27 @@ size_t gc_heap::exponential_smoothing (int gen, size_t collection_count, size_t
2234222342
//internal part of gc used by the serial and concurrent version
2234322343
void gc_heap::gc1()
2234422344
{
22345+
#ifdef FEATURE_EVENT_TRACE
22346+
EventArray<uint8_t> arr1;
22347+
arr1.Count = 10;
22348+
arr1.Data = new (nothrow) uint8_t[10];
22349+
for (uint8_t i = 0; i < 10; i++)
22350+
{
22351+
arr1.Data[i] = i * i + i + 1;
22352+
}
22353+
22354+
EventArray<uint16_t> arr2;
22355+
arr2.Count = 6;
22356+
arr2.Data = new (nothrow) uint16_t[6];
22357+
for (uint16_t i = 0; i < 6; i++)
22358+
{
22359+
arr2.Data[i] = i * (i + 1);
22360+
}
22361+
22362+
GCEventFireTestArray_V1 (arr1, arr2);
22363+
delete[] arr1.Data;
22364+
delete[] arr2.Data;
22365+
#endif //FEATURE_EVENT_TRACE
2234522366
#ifdef BACKGROUND_GC
2234622367
assert (settings.concurrent == (uint32_t)(bgc_thread_id.IsCurrentThread()));
2234722368
#endif //BACKGROUND_GC

src/coreclr/gc/gcevent_serializers.h

Lines changed: 73 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -48,15 +48,22 @@
4848
#define ByteSwap64 __builtin_bswap64
4949
#endif // MSC_VER
5050

51-
namespace gc_event
51+
template<class T>
52+
class EventArray
5253
{
54+
public:
55+
uint8_t Count;
56+
T* Data;
57+
};
5358

59+
namespace gc_event
60+
{
5461
/*
55-
* `EventSerializatonTraits` is a trait implemented by types that
56-
* can be serialized to the payload of a dynamic event.
62+
* `PrimitiveEventSerializatonTraits` is a trait implemented by types that
63+
* can be serialized to the payload of a dynamic event with a fixed size.
5764
*/
5865
template<class T>
59-
struct EventSerializationTraits
66+
struct PrimitiveEventSerializationTraits
6067
{
6168
/*
6269
* Serializes the value `value` to the buffer `buffer`, incrementing
@@ -66,37 +73,36 @@ struct EventSerializationTraits
6673
* large enough to accommodate the serialized form of T.
6774
*/
6875
static void Serialize(const T& value, uint8_t** buffer) = delete;
69-
7076
/*
71-
* Returns the size of the value `value` if it were to be serialized.
77+
* Returns the size required for serializing this type.
7278
*/
73-
static size_t SerializedSize(const T& value) = delete;
79+
static size_t SerializedSize() = delete;
7480
};
7581

7682
/*
77-
* EventSerializationTraits implementation for uint16_t. Other integral types
83+
* PrimitiveEventSerializationTraits implementation for uint8_t. Other integral types
7884
* can follow this pattern.
7985
*
8086
* The convention here is that integral types are always serialized as
8187
* little-endian.
8288
*/
8389
template<>
84-
struct EventSerializationTraits<uint8_t>
90+
struct PrimitiveEventSerializationTraits<uint8_t>
8591
{
8692
static void Serialize(const uint8_t& value, uint8_t** buffer)
8793
{
8894
**((uint8_t**)buffer) = value;
8995
*buffer += sizeof(uint8_t);
9096
}
9197

92-
static size_t SerializedSize(const uint8_t& value)
98+
static size_t SerializedSize()
9399
{
94100
return sizeof(uint8_t);
95101
}
96102
};
97103

98104
template<>
99-
struct EventSerializationTraits<uint16_t>
105+
struct PrimitiveEventSerializationTraits<uint16_t>
100106
{
101107
static void Serialize(const uint16_t& value, uint8_t** buffer)
102108
{
@@ -109,14 +115,14 @@ struct EventSerializationTraits<uint16_t>
109115
*buffer += sizeof(uint16_t);
110116
}
111117

112-
static size_t SerializedSize(const uint16_t& value)
118+
static size_t SerializedSize()
113119
{
114120
return sizeof(uint16_t);
115121
}
116122
};
117123

118124
template<>
119-
struct EventSerializationTraits<uint32_t>
125+
struct PrimitiveEventSerializationTraits<uint32_t>
120126
{
121127
static void Serialize(const uint32_t& value, uint8_t** buffer)
122128
{
@@ -129,14 +135,14 @@ struct EventSerializationTraits<uint32_t>
129135
*buffer += sizeof(uint32_t);
130136
}
131137

132-
static size_t SerializedSize(const uint32_t& value)
138+
static size_t SerializedSize()
133139
{
134140
return sizeof(uint32_t);
135141
}
136142
};
137143

138144
template<>
139-
struct EventSerializationTraits<uint64_t>
145+
struct PrimitiveEventSerializationTraits<uint64_t>
140146
{
141147
static void Serialize(const uint64_t& value, uint8_t** buffer)
142148
{
@@ -149,27 +155,76 @@ struct EventSerializationTraits<uint64_t>
149155
*buffer += sizeof(uint64_t);
150156
}
151157

152-
static size_t SerializedSize(const uint64_t& value)
158+
static size_t SerializedSize()
153159
{
154160
return sizeof(uint64_t);
155161
}
156162
};
157163

158164
template<>
159-
struct EventSerializationTraits<float>
165+
struct PrimitiveEventSerializationTraits<float>
160166
{
161167
static void Serialize(const float& value, uint8_t** buffer)
162168
{
163169
memcpy(*buffer, &value, sizeof(float));
164170
*buffer += sizeof(float);
165171
}
166172

167-
static size_t SerializedSize(const float& value)
173+
static size_t SerializedSize()
168174
{
169175
return sizeof(float);
170176
}
171177
};
172178

179+
/*
180+
* `EventSerializatonTraits` is a trait implemented by types that
181+
* can be serialized to the payload of a dynamic event.
182+
*/
183+
template<class T>
184+
struct EventSerializationTraits
185+
{
186+
/*
187+
* Serializes the value `value` to the buffer `buffer`, incrementing
188+
* the buffer double-pointer to point to the next byte to be written.
189+
*
190+
* It is the responsibility of the caller to ensure that the buffer is
191+
* large enough to accommodate the serialized form of T.
192+
*/
193+
static void Serialize(const T& value, uint8_t** buffer)
194+
{
195+
PrimitiveEventSerializationTraits<T>::Serialize(value, buffer);
196+
}
197+
198+
/*
199+
* Returns the size of the value `value` if it were to be serialized.
200+
*/
201+
static size_t SerializedSize(const T& value)
202+
{
203+
return PrimitiveEventSerializationTraits<T>::SerializedSize();
204+
}
205+
};
206+
207+
template<class T>
208+
struct EventSerializationTraits<EventArray<T>>
209+
{
210+
static void Serialize(const EventArray<T>& value, uint8_t** pBuffer)
211+
{
212+
uint8_t* buffer = *pBuffer;
213+
buffer[0] = value.Count;
214+
buffer += 1;
215+
for (uint8_t i = 0; i < value.Count; i++)
216+
{
217+
PrimitiveEventSerializationTraits<T>::Serialize(value.Data[i], &buffer);
218+
}
219+
*pBuffer = buffer;
220+
}
221+
222+
static size_t SerializedSize(const EventArray<T>& value)
223+
{
224+
return sizeof(uint8_t) + PrimitiveEventSerializationTraits<T>::SerializedSize() * value.Count;
225+
}
226+
};
227+
173228
/*
174229
* Helper routines for serializing lists of arguments.
175230
*/

src/coreclr/gc/gcevents.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ DYNAMIC_EVENT(CommittedUsage, GCEventLevel_Information, GCEventKeyword_GC, 1)
5252
DYNAMIC_EVENT(SizeAdaptationTuning, GCEventLevel_Information, GCEventKeyword_GC, 1)
5353
DYNAMIC_EVENT(SizeAdaptationFullGCTuning, GCEventLevel_Information, GCEventKeyword_GC, 1)
5454
DYNAMIC_EVENT(SizeAdaptationSample, GCEventLevel_Information, GCEventKeyword_GC, 1)
55+
DYNAMIC_EVENT(TestArray, GCEventLevel_Information, GCEventKeyword_GC, 1)
5556

5657
#undef KNOWN_EVENT
5758
#undef DYNAMIC_EVENT

0 commit comments

Comments
 (0)