Skip to content

Commit

Permalink
[eventpipe] Perform endian aware serialization of structs and arrays …
Browse files Browse the repository at this point in the history
…above FireETW layer (#80493)
  • Loading branch information
stefan-sf-ibm committed Mar 20, 2023
1 parent 9834339 commit 5b71f85
Show file tree
Hide file tree
Showing 5 changed files with 76 additions and 74 deletions.
31 changes: 0 additions & 31 deletions src/coreclr/scripts/genEventPipe.py
Expand Up @@ -281,33 +281,9 @@ def winTypeToFixedWidthType(t):
if template.name in specialCaseSizes and paramName in specialCaseSizes[template.name]:
size = "(int)(%s)" % specialCaseSizes[template.name][paramName]
if runtimeFlavor.mono:
pack_list.append("#if BIGENDIAN")
pack_list.append(" const uint8_t *valuePtr = %s;" % paramName)
pack_list.append(" for (uint32_t i = 0; i < %s; ++i) {" % template.structs[paramName])
types = [winTypeToFixedWidthType(t) for t in template.structTypes[paramName]]
for t in set(types) - {"UTF8String", "UTF16String"}:
pack_list.append(" %(type)s value_%(type)s;" % {'type': t})
if "UTF8String" in types or "UTF16String" in types:
pack_list.append(" size_t value_len;")
for t in types:
if t == "UTF8String":
pack_list.append(" value_len = strlen((const char *)valuePtr);")
pack_list.append(" success &= write_buffer_string_utf8_t((const ep_char8_t *)valuePtr, value_len, &buffer, &offset, &size, &fixedBuffer);")
pack_list.append(" valuePtr += value_len + 1;")
elif t == "UTF16String":
pack_list.append(" value_len = strlen((const char *)valuePtr);")
pack_list.append(" success &= write_buffer_string_utf8_to_utf16_t((const ep_char8_t *)valuePtr, value_len, &buffer, &offset, &size, &fixedBuffer);")
pack_list.append(" valuePtr += value_len + 1;")
else:
pack_list.append(" memcpy (&value_%(type)s, valuePtr, sizeof (value_%(type)s));" % {'type': t})
pack_list.append(" valuePtr += sizeof (%s);" % t)
pack_list.append(" success &= write_buffer_%(type)s (value_%(type)s, &buffer, &offset, &size, &fixedBuffer);" % {'type': t})
pack_list.append(" }")
pack_list.append("#else")
pack_list.append(
" success &= write_buffer((const uint8_t *)%s, %s, &buffer, &offset, &size, &fixedBuffer);" %
(paramName, size))
pack_list.append("#endif // BIGENDIAN")
emittedWriteToBuffer = True
elif runtimeFlavor.coreclr:
pack_list.append(
Expand All @@ -321,16 +297,9 @@ def winTypeToFixedWidthType(t):
if template.name in specialCaseSizes and paramName in specialCaseSizes[template.name]:
size = "(int)(%s)" % specialCaseSizes[template.name][paramName]
if runtimeFlavor.mono:
t = winTypeToFixedWidthType(parameter.winType)
pack_list.append("#if BIGENDIAN")
pack_list.append(" for (uint32_t i = 0; i < %s; ++i) {" % template.arrays[paramName])
pack_list.append(" success &= write_buffer_%(type)s (%(name)s[i], &buffer, &offset, &size, &fixedBuffer);" % {'name': paramName, 'type': t})
pack_list.append(" }")
pack_list.append("#else")
pack_list.append(
" success &= write_buffer((const uint8_t *)%s, %s, &buffer, &offset, &size, &fixedBuffer);" %
(paramName, size))
pack_list.append("#endif // BIGENDIAN")
emittedWriteToBuffer = True
elif runtimeFlavor.coreclr:
pack_list.append(
Expand Down
7 changes: 2 additions & 5 deletions src/coreclr/scripts/genEventing.py
Expand Up @@ -188,11 +188,10 @@ class Template:
def __repr__(self):
return "<Template " + self.name + ">"

def __init__(self, templateName, fnPrototypes, dependencies, structSizes, structTypes, arrays):
def __init__(self, templateName, fnPrototypes, dependencies, structSizes, arrays):
self.name = templateName
self.signature = FunctionSignature()
self.structs = structSizes
self.structTypes = structTypes
self.arrays = arrays

for variable in fnPrototypes.paramlist:
Expand Down Expand Up @@ -274,7 +273,6 @@ def parseTemplateNodes(templateNodes):

for templateNode in templateNodes:
structCounts = {}
structTypes = {}
arrays = {}
templateName = templateNode.getAttribute('tid')
var_Dependencies = {}
Expand Down Expand Up @@ -339,12 +337,11 @@ def parseTemplateNodes(templateNodes):
types = [x.attributes['inType'].value for x in structToBeMarshalled.getElementsByTagName("data")]

structCounts[structName] = countVarName
structTypes[structName] = types
var_Dependencies[structName] = [countVarName, structName]
fnparam_pointer = FunctionParameter("win:Struct", structName, "win:count", countVarName)
fnPrototypes.append(structName, fnparam_pointer)

allTemplates[templateName] = Template(templateName, fnPrototypes, var_Dependencies, structCounts, structTypes, arrays)
allTemplates[templateName] = Template(templateName, fnPrototypes, var_Dependencies, structCounts, arrays)

return allTemplates

Expand Down
55 changes: 27 additions & 28 deletions src/mono/mono/eventpipe/ep-rt-mono.c
Expand Up @@ -1503,9 +1503,11 @@ eventpipe_fire_method_events (
il_offsets = (uint32_t*)events_data->buffer;
native_offsets = il_offsets + offset_entries;

uint8_t *il_offsets_ptr = (uint8_t *)il_offsets;
uint8_t *native_offsets_ptr = (uint8_t *)native_offsets;
for (uint32_t offset_count = 0; offset_count < offset_entries; ++offset_count) {
il_offsets [offset_count] = debug_info->line_numbers [offset_count].il_offset;
native_offsets [offset_count] = debug_info->line_numbers [offset_count].native_offset;
ep_write_buffer_uint32_t (&il_offsets_ptr, debug_info->line_numbers [offset_count].il_offset);
ep_write_buffer_uint32_t (&native_offsets_ptr, debug_info->line_numbers [offset_count].native_offset);
}
}
}
Expand All @@ -1520,7 +1522,7 @@ eventpipe_fire_method_events (
il_offsets = (uint32_t*)events_data->buffer;
native_offsets = il_offsets + offset_entries;
il_offsets [0] = 0;
native_offsets [0] = (uint32_t)ji->code_size;
native_offsets [0] = ep_rt_val_uint32_t ((uint32_t)ji->code_size);
}

events_data->method_events_func (
Expand Down Expand Up @@ -3169,25 +3171,25 @@ ep_rt_mono_fire_bulk_type_event (BulkTypeEventLogger *type_logger)

uint32_t values_element_size = 0;

char *ptr = (char *)type_logger->bulk_type_event_buffer;
uint8_t *ptr = type_logger->bulk_type_event_buffer;

for (uint32_t type_value_index = 0; type_value_index < type_logger->bulk_type_value_count; type_value_index++) {
BulkTypeValue *target = &type_logger->bulk_type_values [type_value_index];

values_element_size += write_event_buffer_int64 (target->fixed_sized_data.type_id, ptr, &ptr);
values_element_size += write_event_buffer_int64 (target->fixed_sized_data.module_id, ptr, &ptr);
values_element_size += write_event_buffer_int32 (target->fixed_sized_data.type_name_id, ptr, &ptr);
values_element_size += write_event_buffer_int32 (target->fixed_sized_data.flags, ptr, &ptr);
values_element_size += write_event_buffer_int8 (target->fixed_sized_data.cor_element_type, ptr, &ptr);
values_element_size += ep_write_buffer_uint64_t (&ptr, target->fixed_sized_data.type_id);
values_element_size += ep_write_buffer_uint64_t (&ptr, target->fixed_sized_data.module_id);
values_element_size += ep_write_buffer_uint32_t (&ptr, target->fixed_sized_data.type_name_id);
values_element_size += ep_write_buffer_uint32_t (&ptr, target->fixed_sized_data.flags);
values_element_size += ep_write_buffer_uint8_t (&ptr, target->fixed_sized_data.cor_element_type);

g_assert (target->name == NULL);
values_element_size += write_event_buffer_int16 (0, ptr, &ptr);
values_element_size += ep_write_buffer_string_utf8_to_utf16_t (&ptr, "", 0);

values_element_size += write_event_buffer_int32 (target->type_parameters_count, ptr, &ptr);
values_element_size += ep_write_buffer_uint32_t (&ptr, target->type_parameters_count);

for (uint32_t i = 0; i < target->type_parameters_count; i++) {
uint64_t type_parameter = get_typeid_for_type (target->mono_type_parameters [i]);
values_element_size += write_event_buffer_int64 ((int64_t)type_parameter, ptr, &ptr);
values_element_size += ep_write_buffer_uint64_t (&ptr, type_parameter);
}
}

Expand Down Expand Up @@ -3478,8 +3480,9 @@ ep_rt_mono_send_method_details_event (MonoMethod *method)
method_inst_parameter_types_count = method_inst->type_argc;

uint64_t *method_inst_parameters_type_ids = mono_mempool_alloc0 (type_logger->mem_pool, method_inst_parameter_types_count * sizeof (uint64_t));
uint8_t *buffer = (uint8_t *)method_inst_parameters_type_ids;
for (uint32_t i = 0; i < method_inst_parameter_types_count; i++) {
method_inst_parameters_type_ids [i] = get_typeid_for_type (method_inst->type_argv [i]);
ep_write_buffer_uint64_t (&buffer, get_typeid_for_type (method_inst->type_argv [i]));

ep_rt_mono_log_type_and_parameters_if_necessary (type_logger, method_inst->type_argv [i]);
}
Expand Down Expand Up @@ -3589,9 +3592,11 @@ ep_rt_mono_write_event_method_il_to_native_map (
}
if (il_offsets) {
native_offsets = il_offsets + offset_entries;
uint8_t *il_offsets_ptr = (uint8_t *)il_offsets;
uint8_t *native_offsets_ptr = (uint8_t *)native_offsets;
for (uint32_t offset_count = 0; offset_count < offset_entries; ++offset_count) {
il_offsets [offset_count] = debug_info->line_numbers [offset_count].il_offset;
native_offsets [offset_count] = debug_info->line_numbers [offset_count].native_offset;
ep_write_buffer_uint32_t (&il_offsets_ptr, debug_info->line_numbers [offset_count].il_offset);
ep_write_buffer_uint32_t (&native_offsets_ptr, debug_info->line_numbers [offset_count].native_offset);
}
}
}
Expand All @@ -3606,7 +3611,7 @@ ep_rt_mono_write_event_method_il_to_native_map (
il_offsets = fixed_buffer;
native_offsets = il_offsets + offset_entries;
il_offsets [0] = 0;
native_offsets [0] = ji ? (uint32_t)ji->code_size : 0;
native_offsets [0] = ji ? ep_rt_val_uint32_t ((uint32_t)ji->code_size) : 0;
}

FireEtwMethodILToNativeMap (
Expand Down Expand Up @@ -5451,14 +5456,12 @@ mono_profiler_fire_buffered_gc_event_moves (
for (uint64_t i = 0; i < count; i++) {
// GCMoves.Values[].ObjectID.
object_id = (uintptr_t)SGEN_POINTER_UNTAG_ALL (*objects);
memcpy (buffer, &object_id, sizeof (object_id));
buffer += sizeof (object_id);
ep_write_buffer_uintptr_t (&buffer, object_id);
objects++;

// GCMoves.Values[].AddressID.
address_id = (uintptr_t)*objects;
memcpy (buffer, &address_id, sizeof (address_id));
buffer += sizeof (address_id);
ep_write_buffer_uintptr_t (&buffer, address_id);
objects++;
}
}
Expand Down Expand Up @@ -5518,14 +5521,12 @@ mono_profiler_fire_buffered_gc_event_roots (
for (uint64_t i = 0; i < count; i++) {
// GCRoots.Values[].ObjectID.
object_id = (uintptr_t)SGEN_POINTER_UNTAG_ALL (*objects);
memcpy (buffer, &object_id, sizeof (object_id));
buffer += sizeof (object_id);
ep_write_buffer_uintptr_t (&buffer, object_id);
objects++;

// GCRoots.Values[].AddressID.
address_id = (uintptr_t)*addresses;
memcpy (buffer, &address_id, sizeof (address_id));
buffer += sizeof (address_id);
ep_write_buffer_uintptr_t (&buffer, address_id);
addresses++;
}
}
Expand Down Expand Up @@ -5646,13 +5647,11 @@ mono_profiler_fire_buffered_gc_event_heap_dump_object_reference (
for (uintptr_t i = 0; i < object_ref_count; i++) {
// GCEvent.Values[].ReferencesOffset
object_ref_offset = GUINTPTR_TO_UINT32 (offsets [i] - last_offset);
memcpy (buffer, &object_ref_offset, sizeof (object_ref_offset));
buffer += sizeof (object_ref_offset);
ep_write_buffer_uint32_t (&buffer, object_ref_offset);

// GCEvent.Values[].ObjectID
object_id = (uintptr_t)SGEN_POINTER_UNTAG_ALL (refs[i]);
memcpy (buffer, &object_id, sizeof (object_id));
buffer += sizeof (object_id);
ep_write_buffer_uintptr_t (&buffer, object_id);

last_offset = offsets [i];
}
Expand Down
4 changes: 2 additions & 2 deletions src/native/eventpipe/ep-config.c
Expand Up @@ -391,8 +391,8 @@ ep_config_build_event_metadata_event (
const ep_char16_t *provider_name_utf16 = ep_provider_get_provider_name_utf16 (provider);
const uint8_t *payload_data = ep_event_get_metadata (source_event);
uint32_t payload_data_len = ep_event_get_metadata_len (source_event);
uint32_t provider_name_len = (uint32_t)((ep_rt_utf16_string_len (provider_name_utf16) + 1) * sizeof (ep_char16_t));
uint32_t instance_payload_size = sizeof (metadata_id) + provider_name_len + payload_data_len;
uint32_t provider_name_len = (uint32_t)ep_rt_utf16_string_len (provider_name_utf16);
uint32_t instance_payload_size = sizeof (metadata_id) + ((provider_name_len + 1) * sizeof (ep_char16_t)) + payload_data_len;

// Allocate the payload.
instance_payload = ep_rt_byte_array_alloc (instance_payload_size);
Expand Down
53 changes: 45 additions & 8 deletions src/native/eventpipe/ep.h
Expand Up @@ -293,22 +293,24 @@ ep_ipc_stream_factory_callback_set (EventPipeIpcStreamFactorySuspendedPortsCallb

static
inline
void
uint32_t
ep_write_buffer_uint8_t (uint8_t **buffer, uint8_t value)
{
memcpy (*buffer, &value, sizeof (value));
*buffer += sizeof (value);
return sizeof (value);
}

#define EP_WRITE_BUFFER_INT(BITS, SIGNEDNESS) \
static \
inline \
void \
uint32_t \
ep_write_buffer_##SIGNEDNESS##int##BITS##_t (uint8_t **buffer, SIGNEDNESS##int##BITS##_t value) \
{ \
value = ep_rt_val_##SIGNEDNESS##int##BITS##_t (value); \
memcpy (*buffer, &value, sizeof (value)); \
*buffer += sizeof (value); \
return sizeof (value); \
}

EP_WRITE_BUFFER_INT (16, )
Expand All @@ -322,19 +324,54 @@ EP_WRITE_BUFFER_INT (64, u)

static
inline
void
ep_write_buffer_string_utf16_t (uint8_t **buf, const ep_char16_t *str, size_t len)
uint32_t
ep_write_buffer_uintptr_t (uint8_t **buffer, uintptr_t value)
{
memcpy (*buf, str, len);
*buf += len;
value = ep_rt_val_uintptr_t (value);
memcpy (*buffer, &value, sizeof (value));
*buffer += sizeof (value);
return sizeof (value);
}

static
inline
void
uint32_t
ep_write_buffer_string_utf8_to_utf16_t (uint8_t **buf, const ep_char8_t *str, uint32_t len)
{
if (len == 0) {
(*buf)[0] = 0;
(*buf)[1] = 0;
*buf += sizeof (ep_char16_t);
return sizeof (ep_char16_t);
}
ep_char16_t *str_utf16 = ep_rt_utf8_to_utf16le_string (str, len);
uint32_t num_bytes_utf16_str = 0;
while (str_utf16[num_bytes_utf16_str] != 0)
++num_bytes_utf16_str;
num_bytes_utf16_str = (num_bytes_utf16_str + 1) * sizeof (ep_char16_t);
memcpy (*buf, str_utf16, num_bytes_utf16_str);
*buf += num_bytes_utf16_str;
ep_rt_utf16_string_free (str_utf16);
return num_bytes_utf16_str;
}

static
inline
uint32_t
ep_write_buffer_string_utf16_t (uint8_t **buf, const ep_char16_t *str, uint32_t len)
{
uint32_t num_bytes = (len + 1) * sizeof (ep_char16_t);
memcpy (*buf, str, num_bytes);
*buf += num_bytes;
return num_bytes;
}

static
inline
uint32_t
ep_write_buffer_timestamp (uint8_t **buffer, ep_timestamp_t value)
{
ep_write_buffer_int64_t (buffer, value);
return ep_write_buffer_int64_t (buffer, value);
}

#else /* ENABLE_PERFTRACING */
Expand Down

0 comments on commit 5b71f85

Please sign in to comment.