From 4c1de70bcd86c272af6910ad466f160cf8d754ac Mon Sep 17 00:00:00 2001 From: mdh1418 Date: Mon, 11 Apr 2022 17:34:56 -0400 Subject: [PATCH 01/28] [coreclr]Extend lttngDataTypeMapping for mono Writing arrays in generateWriteEventBody had not been previously hit on Mono. With a goal of emitting MethodDetails events on Mono, lttngDataTypeMapping needs to be extended to be compatible with mono types. --- src/coreclr/scripts/genEventPipe.py | 4 +- src/coreclr/scripts/genLttngProvider.py | 62 ++++++++++++++++++------- 2 files changed, 47 insertions(+), 19 deletions(-) diff --git a/src/coreclr/scripts/genEventPipe.py b/src/coreclr/scripts/genEventPipe.py index 934b6cd8c6179a..2f46735cc43e2c 100644 --- a/src/coreclr/scripts/genEventPipe.py +++ b/src/coreclr/scripts/genEventPipe.py @@ -278,7 +278,7 @@ def generateWriteEventBody(template, providerName, eventName, runtimeFlavor): emittedWriteToBuffer = True elif paramName in template.arrays: size = "sizeof(%s) * (int)%s" % ( - lttngDataTypeMapping[parameter.winType], + getLttngDataTypeMapping(runtimeFlavor)[parameter.winType], parameter.prop) if template.name in specialCaseSizes and paramName in specialCaseSizes[template.name]: size = "(int)(%s)" % specialCaseSizes[template.name][paramName] @@ -1041,7 +1041,7 @@ def generateEventPipeImplFiles( ) eventpipeImpl.write( - "EventPipeProvider *EventPipeProvider" + providerPrettyName + + "EventPipeProvider *EventPipeProvider" + providerPrettyName + (" = nullptr;\n" if target_cpp else " = NULL;\n") ) templateNodes = providerNode.getElementsByTagName('template') diff --git a/src/coreclr/scripts/genLttngProvider.py b/src/coreclr/scripts/genLttngProvider.py index 16f849fd86eeb3..f073d326e9c634 100644 --- a/src/coreclr/scripts/genLttngProvider.py +++ b/src/coreclr/scripts/genLttngProvider.py @@ -66,7 +66,7 @@ specialCaseSizes = { "BulkType" : { "Values" : "Values_ElementSize" }, "GCBulkRootCCW" : { "Values" : "Values_ElementSize" }, "GCBulkRCW" : { "Values" : "Values_ElementSize" }, "GCBulkRootStaticVar" : { "Values" : "Values_ElementSize" } } -lttngDataTypeMapping ={ +coreCLRLttngDataTypeMapping ={ #constructed types "win:null" :" ", "win:Int64" :"const __int64", @@ -88,6 +88,34 @@ "win:Binary" :"const BYTE" } +monoLttngDataTypeMapping ={ + #constructed types + "win:null" :" ", + "win:Int64" :"const int64_t", + "win:ULong" :"const uint32_t", + "win:count" :"*", + "win:Struct" :"const uint8_t *", + #actual spec + "win:GUID" :"const int32_t", + "win:AnsiString" :"const uint8_t*", + "win:UnicodeString" :"const uint8_t*", + "win:Double" :"const double", + "win:Int32" :"const int32_t", + "win:Boolean" :"const bool", + "win:UInt64" :"const uint64_t", + "win:UInt32" :"const uint32_t", + "win:UInt16" :"const uint16_t", + "win:UInt8" :"const uint8_t", + "win:Pointer" :"const size_t", + "win:Binary" :"const BYTE" + } + +def getLttngDataTypeMapping(runtimeFlavor): + if runtimeFlavor.coreclr: + return coreCLRLttngDataTypeMapping + elif runtimeFlavor.mono: + return monoLttngDataTypeMapping + ctfDataTypeMapping ={ #constructed types "win:Int64" :"ctf_integer", @@ -114,7 +142,7 @@ def shouldPackTemplate(template): return template.num_params > MAX_LTTNG_ARGS or len(template.structs) > 0 or len(template.arrays) > 0 -def generateArgList(template): +def generateArgList(template, runtimeFlavor): header = "TP_ARGS( \\\n" footer = ")\n" @@ -131,9 +159,9 @@ def generateArgList(template): for params in fnSig.paramlist: fnparam = fnSig.getParam(params) wintypeName = fnparam.winType - typewName = lttngDataTypeMapping[wintypeName] + typewName = getLttngDataTypeMapping(runtimeFlavor)[wintypeName] winCount = fnparam.count - countw = lttngDataTypeMapping[winCount] + countw = getLttngDataTypeMapping(runtimeFlavor)[winCount] arg = " " + typewName if countw != " ": @@ -145,7 +173,7 @@ def generateArgList(template): return header + args + footer -def generateFieldList(template): +def generateFieldList(template, runtimeFlavor): header = " " + " TP_FIELDS(\n" footer = "\n )\n)\n" @@ -160,8 +188,8 @@ def generateFieldList(template): fnparam = fnSig.getParam(params) wintypeName = fnparam.winType winCount = fnparam.count - countw = lttngDataTypeMapping[winCount] - typewName = lttngDataTypeMapping[wintypeName].replace("const ","") + countw = getLttngDataTypeMapping(runtimeFlavor)[winCount] + typewName = getLttngDataTypeMapping(runtimeFlavor)[wintypeName].replace("const ","") field_body = None ctf_type = None @@ -193,7 +221,7 @@ def generateFieldList(template): return header + field_list + footer -def generateLttngHeader(providerName, allTemplates, eventNodes): +def generateLttngHeader(providerName, allTemplates, eventNodes, runtimeFlavor): lTTngHdr = [] for templateName in allTemplates: template = allTemplates[templateName] @@ -202,7 +230,7 @@ def generateLttngHeader(providerName, allTemplates, eventNodes): lTTngHdr.append("\n#define " + templateName + "_TRACEPOINT_ARGS \\\n") #TP_ARGS - tp_args = generateArgList(template) + tp_args = generateArgList(template, runtimeFlavor) lTTngHdr.append(tp_args) #TP_EVENT_CLASS @@ -212,7 +240,7 @@ def generateLttngHeader(providerName, allTemplates, eventNodes): lTTngHdr.append(" " + templateName + "_TRACEPOINT_ARGS,\n") #TP_FIELDS - tp_fields = generateFieldList(template) + tp_fields = generateFieldList(template, runtimeFlavor) lTTngHdr.append(tp_fields) # Macro for defining event instance @@ -270,7 +298,7 @@ def generateLttngHeader(providerName, allTemplates, eventNodes): return ''.join(lTTngHdr) -def generateMethodBody(template, providerName, eventName): +def generateMethodBody(template, providerName, eventName, runtimeFlavor): #emit code to init variables convert unicode to ansi string result = [] @@ -331,9 +359,9 @@ def generateMethodBody(template, providerName, eventName): continue elif ctf_type == "ctf_sequence" or wintypeName == "win:Pointer": - line += "(" + lttngDataTypeMapping[wintypeName] - if not lttngDataTypeMapping[winCount] == " ": - line += lttngDataTypeMapping[winCount] + line += "(" + getLttngDataTypeMapping(runtimeFlavor)[wintypeName] + if not getLttngDataTypeMapping(runtimeFlavor)[winCount] == " ": + line += getLttngDataTypeMapping(runtimeFlavor)[winCount] line += ") " linefnbody.append(line + paramname) @@ -358,7 +386,7 @@ def generateMethodBody(template, providerName, eventName): pack_list.append(" success &= WriteToBuffer((const BYTE *)%s, %s, buffer, offset, size, fixedBuffer);" % (paramName, size)) emittedWriteToBuffer = True elif paramName in template.arrays: - size = "sizeof(%s) * (int)%s" % (lttngDataTypeMapping[parameter.winType], parameter.prop) + size = "sizeof(%s) * (int)%s" % (getLttngDataTypeMapping(runtimeFlavor)[parameter.winType], parameter.prop) if template.name in specialCaseSizes and paramName in specialCaseSizes[template.name]: size = "(int)(%s)" % specialCaseSizes[template.name][paramName] pack_list.append(" success &= WriteToBuffer((const BYTE *)%s, %s, buffer, offset, size, fixedBuffer);" % (paramName, size)) @@ -451,7 +479,7 @@ def generateLttngTpProvider(providerName, eventNodes, allTemplates, runtimeFlavo lTTngImpl.append(" if (!EventXplatEnabled%s())\n" % (eventName,)) lTTngImpl.append(" return ERROR_SUCCESS;\n") - result = generateMethodBody(template, providerName, eventName) + result = generateMethodBody(template, providerName, eventName, runtimeFlavor) lTTngImpl.append(result) lTTngImpl.append("\n return ERROR_SUCCESS;\n}\n\n") @@ -529,7 +557,7 @@ def generateLttngFiles(etwmanifest, eventprovider_directory, runtimeFlavor, dryR lttnghdr_file.write("\n#include \n\n") - lttnghdr_file.write(generateLttngHeader(providerName,allTemplates,eventNodes) + "\n") + lttnghdr_file.write(generateLttngHeader(providerName,allTemplates,eventNodes,runtimeFlavor) + "\n") with open_for_update(lttngevntprov) as lttngimpl_file: lttngimpl_file.write(stdprolog + "\n") From 5e2022e18b80a92576d78bd546d48fb5534c394b Mon Sep 17 00:00:00 2001 From: mdh1418 Date: Mon, 11 Apr 2022 17:43:09 -0400 Subject: [PATCH 02/28] [mono][eventpipe] Implement SendMethodDetailsEvents on mono --- src/mono/mono/eventpipe/ep-rt-mono.c | 75 ++++++++++++++++++- src/mono/mono/eventpipe/ep-rt-mono.h | 3 + .../mono/eventpipe/gen-eventing-event-inc.lst | 1 + 3 files changed, 77 insertions(+), 2 deletions(-) diff --git a/src/mono/mono/eventpipe/ep-rt-mono.c b/src/mono/mono/eventpipe/ep-rt-mono.c index 096bc198184b0c..407c58fbf217b5 100644 --- a/src/mono/mono/eventpipe/ep-rt-mono.c +++ b/src/mono/mono/eventpipe/ep-rt-mono.c @@ -2857,6 +2857,77 @@ ep_rt_mono_write_event_ee_startup_start (void) NULL); } +//--------------------------------------------------------------------------------------- +// +// ep_rt_mono_send_method_details_event is the method responsible for sending details of +// methods involved in events such as JitStart, Load/Unload, Rundown, R2R, and other +// eventpipe events. It calls ep_rt_mono_log_type_and_parameters_if_necessary to log +// unique types from the method type and available method instantiation parameter types +// that are ultimately emitted as a BulkType event in ep_rt_mono_fire_bulk_type_event. +// After appropraitely logging type information, it sends method details outlined by +// the generated dotnetruntime.c and ClrEtwAll manifest. +// +// Arguments: +// * method - a MonoMethod hit during an eventpipe event + +void +ep_rt_mono_send_method_details_event (MonoMethod *method) +{ + if (method->dynamic) + return; + + MonoGenericContext *method_ctx = mono_method_get_context(method); + + MonoGenericInst *method_inst = NULL; + if (method_ctx) + method_inst = method_ctx->method_inst; + + if (method_inst) + if (method_inst->type_argc > 1024) // ETW has a limit for maximum event size. Do not log overly large method type argument sets + return; + + intptr_t method_type_id = 0; + uint32_t method_token = (method->token & 0xFFFFFF) | 0x06000000; // dotnet-pgo ResolveMethodID expects method tokens with a 0x06 mask + uint64_t loader_module_id = 0; + MonoClass *klass = method->klass; + if (klass) + { + // Get the unique identifier for a MonoMethod's type + if (m_class_is_byreflike (klass)) + method_type_id = (intptr_t)m_class_get_this_arg (klass); + else + method_type_id = (intptr_t)m_class_get_byval_arg (klass); + + loader_module_id = (uint64_t)mono_class_get_image (klass); + } + + uint32_t method_inst_parameter_types_count = 0; + if (method_inst) + method_inst_parameter_types_count = method_inst->type_argc; + + intptr_t method_inst_parameters_type_ids[method_inst_parameter_types_count]; + for (int i = 0; i < method_inst_parameter_types_count; i++) + { + // Get the unique identifier for a MonoMethod's instantiation parameter's type + MonoClass* method_inst_type_parameter_class = mono_class_from_mono_type_internal (method_inst->type_argv[i]); + if (m_class_is_byreflike (method_inst_type_parameter_class)) + method_inst_parameters_type_ids[i] = m_class_get_this_arg (method_inst_type_parameter_class); + else + method_inst_parameters_type_ids[i] = m_class_get_byval_arg (method_inst_type_parameter_class); + } + + // Fire bulk type event + + FireEtwMethodDetails((uint64_t)method, + (uint64_t)method_type_id, + method_token, + method_inst_parameter_types_count, + loader_module_id, + (uint64_t*)method_inst_parameters_type_ids, + NULL, + NULL); +} + bool ep_rt_mono_write_event_jit_start (MonoMethod *method) { @@ -2873,7 +2944,7 @@ ep_rt_mono_write_event_jit_start (MonoMethod *method) const char *method_name = NULL; char *method_signature = NULL; - //TODO: SendMethodDetailsEvent + ep_rt_mono_send_method_details_event(method); method_id = (uint64_t)method; @@ -3039,7 +3110,7 @@ ep_rt_mono_write_event_method_load ( method_flags |= METHOD_FLAGS_GENERIC_METHOD; } - //TODO: SendMethodDetailsEvent + ep_rt_mono_send_method_details_event(method); if (verbose) { method_name = method->name; diff --git a/src/mono/mono/eventpipe/ep-rt-mono.h b/src/mono/mono/eventpipe/ep-rt-mono.h index 40a7e15d3d26f7..499f4438eabd97 100644 --- a/src/mono/mono/eventpipe/ep-rt-mono.h +++ b/src/mono/mono/eventpipe/ep-rt-mono.h @@ -2179,6 +2179,9 @@ ep_rt_volatile_store_ptr_without_barrier ( bool ep_rt_mono_write_event_ee_startup_start (void); +void +ep_rt_mono_send_method_details_events (MonoMethod *method); + bool ep_rt_mono_write_event_jit_start (MonoMethod *method); diff --git a/src/mono/mono/eventpipe/gen-eventing-event-inc.lst b/src/mono/mono/eventpipe/gen-eventing-event-inc.lst index ad52dd9f8c8ebb..f96cca6b288124 100644 --- a/src/mono/mono/eventpipe/gen-eventing-event-inc.lst +++ b/src/mono/mono/eventpipe/gen-eventing-event-inc.lst @@ -28,6 +28,7 @@ MethodJitMemoryAllocatedForCode MethodJittingStarted_V1 MethodLoad_V1 MethodLoadVerbose_V1 +MethodDetails ModuleDCEnd_V2 ModuleLoad_V2 ModuleUnload_V2 From 76015cfd21f94983026c4239c5f3a5eabf15e21c Mon Sep 17 00:00:00 2001 From: mdh1418 Date: Tue, 26 Apr 2022 12:13:42 -0400 Subject: [PATCH 03/28] [mono][eventpipe] Utilize method signature getter to avoid uncreated signature --- src/mono/mono/eventpipe/ep-rt-mono.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/mono/mono/eventpipe/ep-rt-mono.c b/src/mono/mono/eventpipe/ep-rt-mono.c index 407c58fbf217b5..a2733ac6b87d3c 100644 --- a/src/mono/mono/eventpipe/ep-rt-mono.c +++ b/src/mono/mono/eventpipe/ep-rt-mono.c @@ -1443,7 +1443,7 @@ eventpipe_fire_method_events ( if (verbose) { method_name = method->name; - method_signature = mono_signature_full_name (method->signature); + method_signature = mono_signature_full_name (mono_method_signature_internal (method)); if (method->klass) method_namespace = mono_type_get_name_full (m_class_get_byval_arg (method->klass), MONO_TYPE_NAME_FORMAT_IL); } @@ -2959,7 +2959,7 @@ ep_rt_mono_write_event_jit_start (MonoMethod *method) } method_name = method->name; - method_signature = mono_signature_full_name (method->signature); + method_signature = mono_signature_full_name (mono_method_signature_internal (method)); if (method->klass) { module_id = (uint64_t)m_class_get_image (method->klass); @@ -3114,7 +3114,7 @@ ep_rt_mono_write_event_method_load ( if (verbose) { method_name = method->name; - method_signature = mono_signature_full_name (method->signature); + method_signature = mono_signature_full_name (mono_method_signature_internal (method)); if (method->klass) method_namespace = mono_type_get_name_full (m_class_get_byval_arg (method->klass), MONO_TYPE_NAME_FORMAT_IL); @@ -5376,7 +5376,7 @@ mono_profiler_jit_done ( if (verbose) { //TODO: Optimize string formatting into functions accepting GString to reduce heap alloc. method_name = method->name; - method_signature = mono_signature_full_name (method->signature); + method_signature = mono_signature_full_name (mono_method_signature_internal (method)); if (method->klass) method_namespace = mono_type_get_name_full (m_class_get_byval_arg (method->klass), MONO_TYPE_NAME_FORMAT_IL); } From 76a52a629d0692b1466d5609923c4ed0ab7d0460 Mon Sep 17 00:00:00 2001 From: mdh1418 Date: Tue, 26 Apr 2022 12:07:53 -0400 Subject: [PATCH 04/28] [mono][eventpipe] Implement BulkType on mono --- src/mono/mono/eventpipe/ep-rt-mono.c | 301 +++++++++++++++++- src/mono/mono/eventpipe/ep-rt-mono.h | 12 + .../mono/eventpipe/gen-eventing-event-inc.lst | 1 + 3 files changed, 313 insertions(+), 1 deletion(-) diff --git a/src/mono/mono/eventpipe/ep-rt-mono.c b/src/mono/mono/eventpipe/ep-rt-mono.c index a2733ac6b87d3c..92045c046c7f16 100644 --- a/src/mono/mono/eventpipe/ep-rt-mono.c +++ b/src/mono/mono/eventpipe/ep-rt-mono.c @@ -2857,6 +2857,301 @@ ep_rt_mono_write_event_ee_startup_start (void) NULL); } +// !!!!!!! NOTE !!!!!!!! +// The flags must match those in the ETW manifest exactly +// !!!!!!! NOTE !!!!!!!! + +typedef enum { + K_ETW_TYPE_FLAGS_ARRAY = 0x8, +} EtwTypeFlags; + +// This only contains the fixed-size data at the top of each struct in +// the bulk type event. These fields must still match exactly the initial +// fields of the struct described in the manifest. +typedef struct _EventStructBulkTypeFixedSizedData { + uint64_t type_id; + uint64_t module_id; + uint32_t type_name_id; + uint32_t flags; + uint8_t cor_element_type; +} EventStructBulkTypeFixedSizedData; + +// Represents one instance of the Value struct inside a single BulkType event +typedef struct _BultTypeValue { + EventStructBulkTypeFixedSizedData fixed_sized_data; + uint32_t c_type_parameters; + intptr_t rg_type_parameters[100]; // Should be variable length to save space + char *s_name; +} BulkTypeValue; + +static +uint32_t +ep_rt_mono_get_byte_count_in_event(BulkTypeValue *bulk_type_value) +{ + return + sizeof(bulk_type_value->fixed_sized_data) + + sizeof(bulk_type_value->c_type_parameters) + + (sizeof(bulk_type_value->s_name) + 1) * sizeof(char) + // Size of name, including null terminator + bulk_type_value->c_type_parameters * sizeof(uint64_t); // Type parameters +} + +// ETW has a limitation of 64K for TOTAL event Size, however there is overhead associated with +// the event headers. It is unclear exactly how much that is, but 1K should be sufficiently +// far away to avoid problems without sacrificing the perf of bulk processing. +static const uint32_t cb_max_etw_event = 63 * 1024; + +// Estimate of how many bytes we can squeeze in the event data for the value struct +// array. (Intentionally overestimate the size of the non-array parts to keep it safe.) +static const uint32_t k_max_bytes_type_values = (cb_max_etw_event - 0x30); + +// Estimate of how many type value elements we can put into the struct array, while +// staying under the ETW event size limit. Note that this is impossible to calculate +// perfectly, since each element of the struct array has variable size. +// +// In addition to the byte-size limit per event, Windows always forces on us a +// max-number-of-descriptors per event, which in the case of BulkType, will kick in +// far sooner. There's a max number of 128 descriptors allowed per event. 2 are used +// for Count + ClrInstanceID. Then 4 per batched value. (Might actually be 3 if there +// are no type parameters to log, but let's overestimate at 4 per value). +static const uint32_t k_max_count_type_values = (128 - 2) / 4; + +BulkTypeValue m_rg_bulk_type_values[k_max_count_type_values]; +uint32_t m_n_bulk_type_value_count; +uint32_t m_n_bulk_type_value_byte_count; +uint8_t *m_p_bulk_type_event_buffer[65536]; + +//--------------------------------------------------------------------------------------- +// +// ep_rt_mono_fire_bulk_type_event fires an ETW event for all the types batched so far, +// it then resets the state to start batching new types at the beginning of the +// m_rg_bulk_type_values array. +// + +void +ep_rt_mono_fire_bulk_type_event (void) +{ + if (m_n_bulk_type_value_count == 0) + return; + memset(m_p_bulk_type_event_buffer, 0, 65536 * sizeof(uint8_t)); + uint16_t n_clr_instance_id = clr_instance_get_id(); + + uint32_t i_size = 0; + + for (int i_type_data = 0; i_type_data < m_n_bulk_type_value_count; i_type_data++) + { + BulkTypeValue *target = &m_rg_bulk_type_values[i_type_data]; + + memcpy(m_p_bulk_type_event_buffer + i_size, + &target->fixed_sized_data, + sizeof(target->fixed_sized_data)); + i_size += sizeof(target->fixed_sized_data); + + char *wsz_name = target->s_name; + if (!wsz_name) + { + m_p_bulk_type_event_buffer[i_size++] = 0; + m_p_bulk_type_event_buffer[i_size++] = 0; + } + else + { + uint32_t name_size = (strlen(target->s_name) + 1) * sizeof(wchar_t); + memcpy(m_p_bulk_type_event_buffer + i_size, wsz_name, name_size); + i_size += strlen(wsz_name); + } + + uint32_t *ptr_int = (uint32_t*)(m_p_bulk_type_event_buffer + i_size); + *ptr_int = target->c_type_parameters; + i_size += 4; + + if (target->c_type_parameters > 0) + { + memcpy(m_p_bulk_type_event_buffer + i_size, target->rg_type_parameters, sizeof(uint64_t) * target->c_type_parameters); + i_size += sizeof(uint64_t) * target->c_type_parameters; + } + } + + FireEtwBulkType(m_n_bulk_type_value_count, + n_clr_instance_id, + i_size, + m_p_bulk_type_event_buffer, + NULL, + NULL); + + m_n_bulk_type_value_count = 0; + m_n_bulk_type_value_byte_count = 0; +} + +//--------------------------------------------------------------------------------------- +// +// ep_rt_mono_log_single_type batches a single type into the bulk type array and flushes +// the array to ETW if it fills up. Most interaction with the type system (type analysis) +// is done here. This does not recursively batch up any parameter types (arrays or generics), +// but does add their unique identifiers to the rg_type_parameters array. +// ep_rt_mono_log_type_and_parameters is responsible for initiating any recursive calls to +// deal with type parameters. +// +// Arguments: +// type_id - Unique identifier for a mono type +// +// Return Value: +// Index into array of where this type got batched. -1 if there was a failure. + +uint32_t +ep_rt_mono_log_single_type (intptr_t type_id) +{ + // If there's no room for another type, flush what we've got + if (m_n_bulk_type_value_count == k_max_count_type_values) + ep_rt_mono_fire_bulk_type_event(); + + EP_ASSERT (m_n_bulk_type_value_count < k_max_count_type_values); + + BulkTypeValue *p_val = &m_rg_bulk_type_values[m_n_bulk_type_value_count]; + + MonoType *mono_type = (MonoType*)type_id; + MonoClass *klass = mono_class_from_mono_type_internal (mono_type); + + // Clear out p_val before filling it out (array elements can get reused if there + // are enough types that we need to flush to multiple events). + memset(p_val->rg_type_parameters, 0, 100); + if (p_val->s_name) + p_val->s_name[0] = '\0'; + p_val->c_type_parameters = 0; + + // Initialize p_val fixed_sized_data + p_val->fixed_sized_data.type_id = (uint64_t)type_id; + p_val->fixed_sized_data.module_id = (uint64_t)m_class_get_image (klass); + p_val->fixed_sized_data.type_name_id = (0x00FFFFFF & m_class_get_type_token (klass)) | 0x02000000; // dotnet-pgo ResolveMethodID expects type name ids with a 0x02 mask + p_val->fixed_sized_data.flags = 0; + p_val->fixed_sized_data.cor_element_type = (uint8_t)mono_type->type; + + // Sets p_val variable sized parameter type data c_type_parameters and rg_type_parameters + // associated with arrays or generics and add unique identifiers to rg_type_parameters array + // to be recursively batched in the same ep_rt_mono_log_type_and_parameters call + if ((mono_type->type == MONO_TYPE_ARRAY) || (mono_type->type == MONO_TYPE_SZARRAY)) + { + MonoArrayType *mono_array_type = mono_type_get_array_type (mono_type); + p_val->fixed_sized_data.flags |= K_ETW_TYPE_FLAGS_ARRAY; + if (mono_type->type == MONO_TYPE_ARRAY) + { + // Only ranks less than kEtwTypeFlagsArrayRankMax are supported. + // Fortunately kEtwTypeFlagsArrayRankMax should be greater than the + // number of ranks the type loader will support + uint32_t rank = mono_array_type->rank; + if (rank < (0x3700 >> 8)) + { + rank <<= 8; + p_val->fixed_sized_data.flags |= rank; + } + } + + // Add array's element's class' unique type identifier to rg_type_parameters array + if (m_class_is_byreflike (mono_array_type->eklass)) + p_val->rg_type_parameters[p_val->c_type_parameters++] = m_class_get_this_arg (mono_array_type->eklass); + else + p_val->rg_type_parameters[p_val->c_type_parameters++] = m_class_get_byval_arg (mono_array_type->eklass); + } + else if (mono_type->type == MONO_TYPE_GENERICINST) + { + MonoGenericInst *class_inst = mono_type->data.generic_class->context.class_inst; + p_val->c_type_parameters = class_inst->type_argc; + for (int i = 0; i < class_inst->type_argc; i++) + { + // Add generic inst parameter's unique type identifier to rg_type_parameters array + MonoClass *mono_class_inst_type_class = mono_class_from_mono_type_internal (class_inst->type_argv[i]); + if (m_class_is_byreflike (mono_class_inst_type_class)) + p_val->rg_type_parameters[i] = m_class_get_this_arg (mono_class_inst_type_class); + else + p_val->rg_type_parameters[i] = m_class_get_byval_arg (mono_class_inst_type_class); + } + } + + // Now that we know the full size of this type's data, see if it fits in our + // batch or whether we need to flush + int cb_val = ep_rt_mono_get_byte_count_in_event(p_val); + if (cb_val > k_max_bytes_type_values) + { + if (p_val->s_name) + p_val->s_name[0] = '\0'; + cb_val = ep_rt_mono_get_byte_count_in_event(p_val); + + if (cb_val > k_max_bytes_type_values) + { + // This type is apparently so huge, it's too big to squeeze into an event, even + // if it were the only type batched in the whole event. Bail + return -1; + } + } + if (m_n_bulk_type_value_byte_count + cb_val > k_max_bytes_type_values) + { + // Although this type fits into the array, its size is so big that the entire + // array can't be logged via ETW. So flush the array, and start over by + // calling ourselves--this refetches the type info and puts it at the + // beginning of the array. Since we know this type is small enough to be + // batched into an event on its own, this recursive call will not try to + // call itself again. + ep_rt_mono_fire_bulk_type_event(); + return ep_rt_mono_log_single_type(type_id); + } + + // The type fits into the batch, so update our state + m_n_bulk_type_value_count++; + m_n_bulk_type_value_byte_count += cb_val; + return m_n_bulk_type_value_count - 1; +} + +//--------------------------------------------------------------------------------------- +// +// High-level method to batch a type and (recursively) its type parameters, flushing to +// ETW as needed. This is called by ep_rt_mono_log_type_and_parameters_if_necessary. +// +// Arguments: +// * type_id - Unique type identifier to batch + +void +ep_rt_mono_log_type_and_parameters (intptr_t type_id) +{ + // Batch up this type. This grabs useful info about the type, including any + // type parameters it may have, and sticks it in m_rg_bulk_type_values + uint32_t i_bulk_type_event_data = ep_rt_mono_log_single_type (type_id); + if (i_bulk_type_event_data == -1) + { + // There was a failure trying to log the type, so don't bother with its type + // parameters + return; + } + + // Look at the type info we just batched, so we can get the type parameters + BulkTypeValue *p_val = &m_rg_bulk_type_values[i_bulk_type_event_data]; + + // We're about to recursively call ourselves for the type parameters, so make a + // local copy of their type handles first (else, as we log them we could flush + // and clear out m_rg_bulk_type_values, thus trashing p_val) + uint32_t c_params = p_val->c_type_parameters; + intptr_t rg_type_parameters[c_params]; + for (uint32_t i = 0; i < c_params; i++) + rg_type_parameters[i] = p_val->rg_type_parameters[i]; + + for (uint32_t i = 0; i < c_params; i++) + ep_rt_mono_log_type_and_parameters_if_necessary (rg_type_parameters[i]); +} + +//--------------------------------------------------------------------------------------- +// +// Outermost level of ETW-type-logging. This method is used to log a unique type identifier +// (in this case a MonoType) and (recursively) its type parameters when present. +// +// Arguments: +// * type_id - Unique type identifier + +// static +void +ep_rt_mono_log_type_and_parameters_if_necessary (intptr_t type_id) +{ + // TODO Log the type if necessary + + ep_rt_mono_log_type_and_parameters (type_id); +} + //--------------------------------------------------------------------------------------- // // ep_rt_mono_send_method_details_event is the method responsible for sending details of @@ -2898,6 +3193,8 @@ ep_rt_mono_send_method_details_event (MonoMethod *method) else method_type_id = (intptr_t)m_class_get_byval_arg (klass); + ep_rt_mono_log_type_and_parameters_if_necessary (method_type_id); + loader_module_id = (uint64_t)mono_class_get_image (klass); } @@ -2914,9 +3211,11 @@ ep_rt_mono_send_method_details_event (MonoMethod *method) method_inst_parameters_type_ids[i] = m_class_get_this_arg (method_inst_type_parameter_class); else method_inst_parameters_type_ids[i] = m_class_get_byval_arg (method_inst_type_parameter_class); + + ep_rt_mono_log_type_and_parameters_if_necessary (method_inst_parameters_type_ids[i]); } - // Fire bulk type event + ep_rt_mono_fire_bulk_type_event(); FireEtwMethodDetails((uint64_t)method, (uint64_t)method_type_id, diff --git a/src/mono/mono/eventpipe/ep-rt-mono.h b/src/mono/mono/eventpipe/ep-rt-mono.h index 499f4438eabd97..917e7e94919e92 100644 --- a/src/mono/mono/eventpipe/ep-rt-mono.h +++ b/src/mono/mono/eventpipe/ep-rt-mono.h @@ -2179,6 +2179,18 @@ ep_rt_volatile_store_ptr_without_barrier ( bool ep_rt_mono_write_event_ee_startup_start (void); +void +ep_rt_mono_fire_bulk_type_event (void); + +uint32_t +ep_rt_mono_log_single_type (intptr_t type_id); + +void +ep_rt_mono_log_type_and_parameters (intptr_t type_id); + +void +ep_rt_mono_log_type_and_parameters_if_necessary (intptr_t type_id); + void ep_rt_mono_send_method_details_events (MonoMethod *method); diff --git a/src/mono/mono/eventpipe/gen-eventing-event-inc.lst b/src/mono/mono/eventpipe/gen-eventing-event-inc.lst index f96cca6b288124..e3dbca56cd860b 100644 --- a/src/mono/mono/eventpipe/gen-eventing-event-inc.lst +++ b/src/mono/mono/eventpipe/gen-eventing-event-inc.lst @@ -4,6 +4,7 @@ AppDomainDCEnd_V1 AssemblyDCEnd_V1 AssemblyLoad_V1 AssemblyUnload_V1 +BulkType ContentionStart_V1 ContentionStop DCEndComplete_V1 From 73cf3a8b75390281e8a6cece0e148abfc4e380b8 Mon Sep 17 00:00:00 2001 From: mdh1418 Date: Tue, 26 Apr 2022 12:43:39 -0400 Subject: [PATCH 05/28] debug traces --- src/mono/mono/eventpipe/ep-rt-mono.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/mono/mono/eventpipe/ep-rt-mono.c b/src/mono/mono/eventpipe/ep-rt-mono.c index 92045c046c7f16..46ea92f95a272c 100644 --- a/src/mono/mono/eventpipe/ep-rt-mono.c +++ b/src/mono/mono/eventpipe/ep-rt-mono.c @@ -2970,6 +2970,7 @@ ep_rt_mono_fire_bulk_type_event (void) } } + mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_DIAGNOSTICS, "Firing BulkTypeEvent!"); FireEtwBulkType(m_n_bulk_type_value_count, n_clr_instance_id, i_size, @@ -3092,6 +3093,11 @@ ep_rt_mono_log_single_type (intptr_t type_id) ep_rt_mono_fire_bulk_type_event(); return ep_rt_mono_log_single_type(type_id); } + mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_DIAGNOSTICS, "p_val added at index: %d\ntype_id: %d\nmodule_id: %d\ntype_name_id: %d\ntype: %d\nc_type_parameters: %d", m_n_bulk_type_value_count, p_val->fixed_sized_data.type_id, p_val->fixed_sized_data.module_id, p_val->fixed_sized_data.type_name_id, mono_type->type, p_val->c_type_parameters); + for (int i = 0; i < p_val->c_type_parameters; i++) + { + mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_DIAGNOSTICS, "type: %d\n", ((MonoType*)p_val->rg_type_parameters[i])->type); + } // The type fits into the batch, so update our state m_n_bulk_type_value_count++; @@ -3217,6 +3223,7 @@ ep_rt_mono_send_method_details_event (MonoMethod *method) ep_rt_mono_fire_bulk_type_event(); + mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_DIAGNOSTICS, "Firing Method:\n%s[%d]\ntype ID [%d]\nToken %d -> %d\nNumParam %d\nmodule %d\n", method->name, (uint64_t)method, method_type_id, method->token, method_token, method_inst_parameter_types_count, loader_module_id); FireEtwMethodDetails((uint64_t)method, (uint64_t)method_type_id, method_token, From 95a749454fcd37d1fd9bd26d5d02477bbde11ede Mon Sep 17 00:00:00 2001 From: mdh1418 Date: Wed, 27 Apr 2022 10:55:05 -0400 Subject: [PATCH 06/28] Address struct tab formatting feedback --- src/mono/mono/eventpipe/ep-rt-mono.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/mono/mono/eventpipe/ep-rt-mono.c b/src/mono/mono/eventpipe/ep-rt-mono.c index 46ea92f95a272c..89b5c58251d803 100644 --- a/src/mono/mono/eventpipe/ep-rt-mono.c +++ b/src/mono/mono/eventpipe/ep-rt-mono.c @@ -2870,9 +2870,9 @@ typedef enum { // fields of the struct described in the manifest. typedef struct _EventStructBulkTypeFixedSizedData { uint64_t type_id; - uint64_t module_id; - uint32_t type_name_id; - uint32_t flags; + uint64_t module_id; + uint32_t type_name_id; + uint32_t flags; uint8_t cor_element_type; } EventStructBulkTypeFixedSizedData; From 74262082ebcd82bf1fd4daf2158f9bb4fc5cc1e7 Mon Sep 17 00:00:00 2001 From: mdh1418 Date: Wed, 27 Apr 2022 11:34:06 -0400 Subject: [PATCH 07/28] Address rg_type_parameter preallocated stack array size --- src/mono/mono/eventpipe/ep-rt-mono.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mono/mono/eventpipe/ep-rt-mono.c b/src/mono/mono/eventpipe/ep-rt-mono.c index 89b5c58251d803..6ae3510e5f00d4 100644 --- a/src/mono/mono/eventpipe/ep-rt-mono.c +++ b/src/mono/mono/eventpipe/ep-rt-mono.c @@ -2880,7 +2880,7 @@ typedef struct _EventStructBulkTypeFixedSizedData { typedef struct _BultTypeValue { EventStructBulkTypeFixedSizedData fixed_sized_data; uint32_t c_type_parameters; - intptr_t rg_type_parameters[100]; // Should be variable length to save space + intptr_t rg_type_parameters[32]; char *s_name; } BulkTypeValue; @@ -3013,7 +3013,7 @@ ep_rt_mono_log_single_type (intptr_t type_id) // Clear out p_val before filling it out (array elements can get reused if there // are enough types that we need to flush to multiple events). - memset(p_val->rg_type_parameters, 0, 100); + memset(p_val->rg_type_parameters, 0, 32); if (p_val->s_name) p_val->s_name[0] = '\0'; p_val->c_type_parameters = 0; From 30b7826110e7c30ab34c8ff84bcddd9084efbe09 Mon Sep 17 00:00:00 2001 From: mdh1418 Date: Wed, 27 Apr 2022 14:22:44 -0400 Subject: [PATCH 08/28] [mono][eventpipe] Add helper function to get mono type unique type identifier --- src/mono/mono/eventpipe/ep-rt-mono.c | 51 ++++++++++++++++------------ 1 file changed, 29 insertions(+), 22 deletions(-) diff --git a/src/mono/mono/eventpipe/ep-rt-mono.c b/src/mono/mono/eventpipe/ep-rt-mono.c index 6ae3510e5f00d4..3a4616c6a25f5f 100644 --- a/src/mono/mono/eventpipe/ep-rt-mono.c +++ b/src/mono/mono/eventpipe/ep-rt-mono.c @@ -2982,6 +2982,29 @@ ep_rt_mono_fire_bulk_type_event (void) m_n_bulk_type_value_byte_count = 0; } +//--------------------------------------------------------------------------------------- +// +// get_typeid_for_type is responsible for obtaining the unique type identifier for a +// particular MonoType. MonoTypes are structs that are not unique pointers. There +// can be two different MonoTypes that both System.Thread or int32 or bool[]. There +// is exactly one MonoClass * for any type, so we leverage the MonoClass a MonoType +// points to in order to obtain a unique type identifier in mono. With that unique +// MonoClass, its fields this_arg and _byval_arg are unique as well. +// +// Arguments: +// * mono_type - MonoType to be logged +// +// Return Value: +// type_id - Unique type identifier of mono_type + +static intptr_t +get_typeid_for_type (MonoType *t) { + if (m_type_is_byref (t)) + return m_class_get_this_arg (mono_class_from_mono_type_internal (t)); + else + return m_class_get_byval_arg (mono_class_from_mono_type_internal (t)); +} + //--------------------------------------------------------------------------------------- // // ep_rt_mono_log_single_type batches a single type into the bulk type array and flushes @@ -3045,11 +3068,8 @@ ep_rt_mono_log_single_type (intptr_t type_id) } } - // Add array's element's class' unique type identifier to rg_type_parameters array - if (m_class_is_byreflike (mono_array_type->eklass)) - p_val->rg_type_parameters[p_val->c_type_parameters++] = m_class_get_this_arg (mono_array_type->eklass); - else - p_val->rg_type_parameters[p_val->c_type_parameters++] = m_class_get_byval_arg (mono_array_type->eklass); + // mono arrays are always arrays of by value types + p_val->rg_type_parameters[p_val->c_type_parameters++] = get_typeid_for_type (m_class_get_byval_arg (mono_array_type->eklass)); } else if (mono_type->type == MONO_TYPE_GENERICINST) { @@ -3057,12 +3077,7 @@ ep_rt_mono_log_single_type (intptr_t type_id) p_val->c_type_parameters = class_inst->type_argc; for (int i = 0; i < class_inst->type_argc; i++) { - // Add generic inst parameter's unique type identifier to rg_type_parameters array - MonoClass *mono_class_inst_type_class = mono_class_from_mono_type_internal (class_inst->type_argv[i]); - if (m_class_is_byreflike (mono_class_inst_type_class)) - p_val->rg_type_parameters[i] = m_class_get_this_arg (mono_class_inst_type_class); - else - p_val->rg_type_parameters[i] = m_class_get_byval_arg (mono_class_inst_type_class); + p_val->rg_type_parameters[i] = get_typeid_for_type (class_inst->type_argv[i]) } } @@ -3193,11 +3208,8 @@ ep_rt_mono_send_method_details_event (MonoMethod *method) MonoClass *klass = method->klass; if (klass) { - // Get the unique identifier for a MonoMethod's type - if (m_class_is_byreflike (klass)) - method_type_id = (intptr_t)m_class_get_this_arg (klass); - else - method_type_id = (intptr_t)m_class_get_byval_arg (klass); + MonoType *method_mono_type = mono_class_get_type (klass); + method_type_id = get_typeid_for_type (method_mono_type); ep_rt_mono_log_type_and_parameters_if_necessary (method_type_id); @@ -3211,12 +3223,7 @@ ep_rt_mono_send_method_details_event (MonoMethod *method) intptr_t method_inst_parameters_type_ids[method_inst_parameter_types_count]; for (int i = 0; i < method_inst_parameter_types_count; i++) { - // Get the unique identifier for a MonoMethod's instantiation parameter's type - MonoClass* method_inst_type_parameter_class = mono_class_from_mono_type_internal (method_inst->type_argv[i]); - if (m_class_is_byreflike (method_inst_type_parameter_class)) - method_inst_parameters_type_ids[i] = m_class_get_this_arg (method_inst_type_parameter_class); - else - method_inst_parameters_type_ids[i] = m_class_get_byval_arg (method_inst_type_parameter_class); + method_inst_parameters_type_ids[i] = get_typeid_for_type (method_inst->type_argv[i]) ep_rt_mono_log_type_and_parameters_if_necessary (method_inst_parameters_type_ids[i]); } From 280d4a7f9e69b32c272a24a8a263ec4d6298cbb0 Mon Sep 17 00:00:00 2001 From: mdh1418 Date: Wed, 27 Apr 2022 15:00:41 -0400 Subject: [PATCH 09/28] [mono][eventpipe] Differentiate MonoType and TypeID and pass separately --- src/mono/mono/eventpipe/ep-rt-mono.c | 45 +++++++++++++++++----------- src/mono/mono/eventpipe/ep-rt-mono.h | 6 ++-- 2 files changed, 31 insertions(+), 20 deletions(-) diff --git a/src/mono/mono/eventpipe/ep-rt-mono.c b/src/mono/mono/eventpipe/ep-rt-mono.c index 3a4616c6a25f5f..46d0909c3707be 100644 --- a/src/mono/mono/eventpipe/ep-rt-mono.c +++ b/src/mono/mono/eventpipe/ep-rt-mono.c @@ -2881,6 +2881,7 @@ typedef struct _BultTypeValue { EventStructBulkTypeFixedSizedData fixed_sized_data; uint32_t c_type_parameters; intptr_t rg_type_parameters[32]; + MonoType *rg_mono_type_parameters[32]; char *s_name; } BulkTypeValue; @@ -3015,13 +3016,14 @@ get_typeid_for_type (MonoType *t) { // deal with type parameters. // // Arguments: -// type_id - Unique identifier for a mono type +// * mono_type - MonoType to be logged +// * type_id - Unique type identifier of mono_type // // Return Value: // Index into array of where this type got batched. -1 if there was a failure. uint32_t -ep_rt_mono_log_single_type (intptr_t type_id) +ep_rt_mono_log_single_type (MonoType *mono_type, intptr_t type_id) { // If there's no room for another type, flush what we've got if (m_n_bulk_type_value_count == k_max_count_type_values) @@ -3031,12 +3033,12 @@ ep_rt_mono_log_single_type (intptr_t type_id) BulkTypeValue *p_val = &m_rg_bulk_type_values[m_n_bulk_type_value_count]; - MonoType *mono_type = (MonoType*)type_id; MonoClass *klass = mono_class_from_mono_type_internal (mono_type); // Clear out p_val before filling it out (array elements can get reused if there // are enough types that we need to flush to multiple events). memset(p_val->rg_type_parameters, 0, 32); + memset(p_val->rg_mono_type_parameters, 0, 32); if (p_val->s_name) p_val->s_name[0] = '\0'; p_val->c_type_parameters = 0; @@ -3069,7 +3071,9 @@ ep_rt_mono_log_single_type (intptr_t type_id) } // mono arrays are always arrays of by value types - p_val->rg_type_parameters[p_val->c_type_parameters++] = get_typeid_for_type (m_class_get_byval_arg (mono_array_type->eklass)); + p_val->rg_mono_type_parameters[p_val->c_type_parameters] = m_class_get_byval_arg (mono_array_type->eklass); + p_val->rg_type_parameters[p_val->c_type_parameters] = get_typeid_for_type (m_class_get_byval_arg (mono_array_type->eklass)); + p_val->c_type_parameters++; } else if (mono_type->type == MONO_TYPE_GENERICINST) { @@ -3077,7 +3081,8 @@ ep_rt_mono_log_single_type (intptr_t type_id) p_val->c_type_parameters = class_inst->type_argc; for (int i = 0; i < class_inst->type_argc; i++) { - p_val->rg_type_parameters[i] = get_typeid_for_type (class_inst->type_argv[i]) + p_val->rg_mono_type_parameters[i] = class_inst->type_argv[i]; + p_val->rg_type_parameters[i] = get_typeid_for_type (class_inst->type_argv[i]); } } @@ -3106,7 +3111,7 @@ ep_rt_mono_log_single_type (intptr_t type_id) // batched into an event on its own, this recursive call will not try to // call itself again. ep_rt_mono_fire_bulk_type_event(); - return ep_rt_mono_log_single_type(type_id); + return ep_rt_mono_log_single_type(mono_type, type_id); } mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_DIAGNOSTICS, "p_val added at index: %d\ntype_id: %d\nmodule_id: %d\ntype_name_id: %d\ntype: %d\nc_type_parameters: %d", m_n_bulk_type_value_count, p_val->fixed_sized_data.type_id, p_val->fixed_sized_data.module_id, p_val->fixed_sized_data.type_name_id, mono_type->type, p_val->c_type_parameters); for (int i = 0; i < p_val->c_type_parameters; i++) @@ -3126,14 +3131,15 @@ ep_rt_mono_log_single_type (intptr_t type_id) // ETW as needed. This is called by ep_rt_mono_log_type_and_parameters_if_necessary. // // Arguments: -// * type_id - Unique type identifier to batch +// * mono_type - MonoType to be logged +// * type_id - Unique type identifier of mono_type to batch void -ep_rt_mono_log_type_and_parameters (intptr_t type_id) +ep_rt_mono_log_type_and_parameters (MonoType *mono_type, intptr_t type_id) { // Batch up this type. This grabs useful info about the type, including any // type parameters it may have, and sticks it in m_rg_bulk_type_values - uint32_t i_bulk_type_event_data = ep_rt_mono_log_single_type (type_id); + uint32_t i_bulk_type_event_data = ep_rt_mono_log_single_type (mono_type, type_id); if (i_bulk_type_event_data == -1) { // There was a failure trying to log the type, so don't bother with its type @@ -3149,11 +3155,15 @@ ep_rt_mono_log_type_and_parameters (intptr_t type_id) // and clear out m_rg_bulk_type_values, thus trashing p_val) uint32_t c_params = p_val->c_type_parameters; intptr_t rg_type_parameters[c_params]; + MonoType *rg_mono_type_parameters[c_params]; for (uint32_t i = 0; i < c_params; i++) + { rg_type_parameters[i] = p_val->rg_type_parameters[i]; + rg_mono_type_parameters[i] = p_val->rg_mono_type_parameters[i]; + } for (uint32_t i = 0; i < c_params; i++) - ep_rt_mono_log_type_and_parameters_if_necessary (rg_type_parameters[i]); + ep_rt_mono_log_type_and_parameters_if_necessary (rg_mono_type_parameters[i], rg_type_parameters[i]); } //--------------------------------------------------------------------------------------- @@ -3162,15 +3172,16 @@ ep_rt_mono_log_type_and_parameters (intptr_t type_id) // (in this case a MonoType) and (recursively) its type parameters when present. // // Arguments: -// * type_id - Unique type identifier +// * mono_type - MonoType to be logged +// * type_id - Unique type identifier of mono_type // static void -ep_rt_mono_log_type_and_parameters_if_necessary (intptr_t type_id) +ep_rt_mono_log_type_and_parameters_if_necessary (MonoType *mono_type, intptr_t type_id) { // TODO Log the type if necessary - ep_rt_mono_log_type_and_parameters (type_id); + ep_rt_mono_log_type_and_parameters (mono_type, type_id); } //--------------------------------------------------------------------------------------- @@ -3208,10 +3219,10 @@ ep_rt_mono_send_method_details_event (MonoMethod *method) MonoClass *klass = method->klass; if (klass) { - MonoType *method_mono_type = mono_class_get_type (klass); + MonoType *method_mono_type = m_class_get_byval_arg (klass); method_type_id = get_typeid_for_type (method_mono_type); - ep_rt_mono_log_type_and_parameters_if_necessary (method_type_id); + ep_rt_mono_log_type_and_parameters_if_necessary (method_mono_type, method_type_id); loader_module_id = (uint64_t)mono_class_get_image (klass); } @@ -3223,9 +3234,9 @@ ep_rt_mono_send_method_details_event (MonoMethod *method) intptr_t method_inst_parameters_type_ids[method_inst_parameter_types_count]; for (int i = 0; i < method_inst_parameter_types_count; i++) { - method_inst_parameters_type_ids[i] = get_typeid_for_type (method_inst->type_argv[i]) + method_inst_parameters_type_ids[i] = get_typeid_for_type (method_inst->type_argv[i]); - ep_rt_mono_log_type_and_parameters_if_necessary (method_inst_parameters_type_ids[i]); + ep_rt_mono_log_type_and_parameters_if_necessary (method_inst->type_argv[i], method_inst_parameters_type_ids[i]); } ep_rt_mono_fire_bulk_type_event(); diff --git a/src/mono/mono/eventpipe/ep-rt-mono.h b/src/mono/mono/eventpipe/ep-rt-mono.h index 917e7e94919e92..fff3d7e31b9977 100644 --- a/src/mono/mono/eventpipe/ep-rt-mono.h +++ b/src/mono/mono/eventpipe/ep-rt-mono.h @@ -2183,13 +2183,13 @@ void ep_rt_mono_fire_bulk_type_event (void); uint32_t -ep_rt_mono_log_single_type (intptr_t type_id); +ep_rt_mono_log_single_type (MonoType *mono_type, intptr_t type_id); void -ep_rt_mono_log_type_and_parameters (intptr_t type_id); +ep_rt_mono_log_type_and_parameters (MonoType *mono_type, intptr_t type_id); void -ep_rt_mono_log_type_and_parameters_if_necessary (intptr_t type_id); +ep_rt_mono_log_type_and_parameters_if_necessary (MonoType *mono_type, intptr_t type_id); void ep_rt_mono_send_method_details_events (MonoMethod *method); From 46f16b672c198297931a707145cc84cd86ceb935 Mon Sep 17 00:00:00 2001 From: mdh1418 Date: Wed, 27 Apr 2022 15:53:37 -0400 Subject: [PATCH 10/28] Address array max rank feedback --- src/mono/mono/eventpipe/ep-rt-mono.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/mono/mono/eventpipe/ep-rt-mono.c b/src/mono/mono/eventpipe/ep-rt-mono.c index 46d0909c3707be..2861804c46a69e 100644 --- a/src/mono/mono/eventpipe/ep-rt-mono.c +++ b/src/mono/mono/eventpipe/ep-rt-mono.c @@ -2863,6 +2863,10 @@ ep_rt_mono_write_event_ee_startup_start (void) typedef enum { K_ETW_TYPE_FLAGS_ARRAY = 0x8, + + K_ETW_TYPE_FLAGS_ARRAY_RANK_MASK = 0x3F00, + K_ETW_TYPE_FLAGS_ARRAY_RANK_SHIFT = 8, + K_ETW_TYPE_FLAGS_ARRAY_RANK_MAX = K_ETW_TYPE_FLAGS_ARRAY_RANK_MASK >> K_ETW_TYPE_FLAGS_ARRAY_RANK_SHIFT } EtwTypeFlags; // This only contains the fixed-size data at the top of each struct in @@ -3063,7 +3067,7 @@ ep_rt_mono_log_single_type (MonoType *mono_type, intptr_t type_id) // Fortunately kEtwTypeFlagsArrayRankMax should be greater than the // number of ranks the type loader will support uint32_t rank = mono_array_type->rank; - if (rank < (0x3700 >> 8)) + if (rank < K_ETW_TYPE_FLAGS_ARRAY_RANK_MAX) { rank <<= 8; p_val->fixed_sized_data.flags |= rank; From 5396c048fe2d8276ac73094b763bbfa9fc432f05 Mon Sep 17 00:00:00 2001 From: mdh1418 Date: Wed, 27 Apr 2022 15:54:02 -0400 Subject: [PATCH 11/28] Address byte_count bug feedback --- src/mono/mono/eventpipe/ep-rt-mono.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mono/mono/eventpipe/ep-rt-mono.c b/src/mono/mono/eventpipe/ep-rt-mono.c index 2861804c46a69e..4b0592dfc3100c 100644 --- a/src/mono/mono/eventpipe/ep-rt-mono.c +++ b/src/mono/mono/eventpipe/ep-rt-mono.c @@ -2896,7 +2896,7 @@ ep_rt_mono_get_byte_count_in_event(BulkTypeValue *bulk_type_value) return sizeof(bulk_type_value->fixed_sized_data) + sizeof(bulk_type_value->c_type_parameters) + - (sizeof(bulk_type_value->s_name) + 1) * sizeof(char) + // Size of name, including null terminator + (strlen(bulk_type_value->s_name) + 1) * sizeof(char) + // Size of name, including null terminator bulk_type_value->c_type_parameters * sizeof(uint64_t); // Type parameters } From 6c3080ca6414e5dda9ff7e730375359603a32528 Mon Sep 17 00:00:00 2001 From: mdh1418 Date: Thu, 28 Apr 2022 15:32:37 -0400 Subject: [PATCH 12/28] Address Etw Type Flags feedback --- src/mono/mono/eventpipe/ep-rt-mono.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/mono/mono/eventpipe/ep-rt-mono.c b/src/mono/mono/eventpipe/ep-rt-mono.c index 4b0592dfc3100c..07575cd4a53df1 100644 --- a/src/mono/mono/eventpipe/ep-rt-mono.c +++ b/src/mono/mono/eventpipe/ep-rt-mono.c @@ -2862,6 +2862,9 @@ ep_rt_mono_write_event_ee_startup_start (void) // !!!!!!! NOTE !!!!!!!! typedef enum { + K_ETW_TYPE_FLAGS_DELEGATE = 0x1, + K_ETW_TYPE_FLAGS_FINALIZABLE = 0x2, + K_ETW_TYPE_FLAGS_EXTERNALLY_IMPLEMENTED_COM_OBJECT = 0x4, K_ETW_TYPE_FLAGS_ARRAY = 0x8, K_ETW_TYPE_FLAGS_ARRAY_RANK_MASK = 0x3F00, @@ -3090,6 +3093,15 @@ ep_rt_mono_log_single_type (MonoType *mono_type, intptr_t type_id) } } + if (mono_class_has_finalizer (klass)) + p_val->fixed_sized_data.flags |= K_ETW_TYPE_FLAGS_FINALIZABLE; + + if (m_class_is_delegate (klass)) + p_val->fixed_sized_data.flags |= K_ETW_TYPE_FLAGS_DELEGATE; + + if (mono_class_is_com_object (klass)) + p_val->fixed_sized_data.flags |= K_ETW_TYPE_FLAGS_EXTERNALLY_IMPLEMENTED_COM_OBJECT; + // Now that we know the full size of this type's data, see if it fits in our // batch or whether we need to flush int cb_val = ep_rt_mono_get_byte_count_in_event(p_val); From 0389903ea0e2b04463d60d479e9e3a0a0ef78413 Mon Sep 17 00:00:00 2001 From: mdh1418 Date: Thu, 28 Apr 2022 15:33:15 -0400 Subject: [PATCH 13/28] Address cor_element_type underlying type feedback --- src/mono/mono/eventpipe/ep-rt-mono.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/mono/mono/eventpipe/ep-rt-mono.c b/src/mono/mono/eventpipe/ep-rt-mono.c index 07575cd4a53df1..c1b7260daf84a1 100644 --- a/src/mono/mono/eventpipe/ep-rt-mono.c +++ b/src/mono/mono/eventpipe/ep-rt-mono.c @@ -3041,6 +3041,7 @@ ep_rt_mono_log_single_type (MonoType *mono_type, intptr_t type_id) BulkTypeValue *p_val = &m_rg_bulk_type_values[m_n_bulk_type_value_count]; MonoClass *klass = mono_class_from_mono_type_internal (mono_type); + MonoType *mono_underlying_type = mono_type_get_underlying_type (mono_type); // Clear out p_val before filling it out (array elements can get reused if there // are enough types that we need to flush to multiple events). @@ -3055,16 +3056,16 @@ ep_rt_mono_log_single_type (MonoType *mono_type, intptr_t type_id) p_val->fixed_sized_data.module_id = (uint64_t)m_class_get_image (klass); p_val->fixed_sized_data.type_name_id = (0x00FFFFFF & m_class_get_type_token (klass)) | 0x02000000; // dotnet-pgo ResolveMethodID expects type name ids with a 0x02 mask p_val->fixed_sized_data.flags = 0; - p_val->fixed_sized_data.cor_element_type = (uint8_t)mono_type->type; + p_val->fixed_sized_data.cor_element_type = (uint8_t)mono_underlying_type->type; // Sets p_val variable sized parameter type data c_type_parameters and rg_type_parameters // associated with arrays or generics and add unique identifiers to rg_type_parameters array // to be recursively batched in the same ep_rt_mono_log_type_and_parameters call - if ((mono_type->type == MONO_TYPE_ARRAY) || (mono_type->type == MONO_TYPE_SZARRAY)) + if ((mono_underlying_type == MONO_TYPE_ARRAY) || (mono_underlying_type == MONO_TYPE_SZARRAY)) { MonoArrayType *mono_array_type = mono_type_get_array_type (mono_type); p_val->fixed_sized_data.flags |= K_ETW_TYPE_FLAGS_ARRAY; - if (mono_type->type == MONO_TYPE_ARRAY) + if (mono_underlying_type == MONO_TYPE_ARRAY) { // Only ranks less than kEtwTypeFlagsArrayRankMax are supported. // Fortunately kEtwTypeFlagsArrayRankMax should be greater than the @@ -3082,7 +3083,7 @@ ep_rt_mono_log_single_type (MonoType *mono_type, intptr_t type_id) p_val->rg_type_parameters[p_val->c_type_parameters] = get_typeid_for_type (m_class_get_byval_arg (mono_array_type->eklass)); p_val->c_type_parameters++; } - else if (mono_type->type == MONO_TYPE_GENERICINST) + else if (mono_underlying_type == MONO_TYPE_GENERICINST) { MonoGenericInst *class_inst = mono_type->data.generic_class->context.class_inst; p_val->c_type_parameters = class_inst->type_argc; @@ -3092,6 +3093,12 @@ ep_rt_mono_log_single_type (MonoType *mono_type, intptr_t type_id) p_val->rg_type_parameters[i] = get_typeid_for_type (class_inst->type_argv[i]); } } + else if (mono_underlying_type == MONO_TYPE_CLASS || mono_underlying_type == MONO_TYPE_VALUETYPE || mono_underlying_type == MONO_TYPE_PTR || mono_underlying_type == MONO_TYPE_BYREF) + { + p_val->rg_mono_type_parameters[p_val->c_type_parameters] = mono_type_get_underlying_type (mono_type); + p_val->rg_type_parameters[p_val->c_type_parameters] = get_typeid_for_type (mono_type_get_underlying_type (mono_type)); + p_val->c_type_parameters++; + } if (mono_class_has_finalizer (klass)) p_val->fixed_sized_data.flags |= K_ETW_TYPE_FLAGS_FINALIZABLE; @@ -3129,7 +3136,7 @@ ep_rt_mono_log_single_type (MonoType *mono_type, intptr_t type_id) ep_rt_mono_fire_bulk_type_event(); return ep_rt_mono_log_single_type(mono_type, type_id); } - mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_DIAGNOSTICS, "p_val added at index: %d\ntype_id: %d\nmodule_id: %d\ntype_name_id: %d\ntype: %d\nc_type_parameters: %d", m_n_bulk_type_value_count, p_val->fixed_sized_data.type_id, p_val->fixed_sized_data.module_id, p_val->fixed_sized_data.type_name_id, mono_type->type, p_val->c_type_parameters); + mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_DIAGNOSTICS, "p_val added at index: %d\ntype_id: %d\nmodule_id: %d\ntype_name_id: %d\ntype: %d\nc_type_parameters: %d", p_type_logger->m_n_bulk_type_value_count, p_val->fixed_sized_data.type_id, p_val->fixed_sized_data.module_id, p_val->fixed_sized_data.type_name_id, mono_underlying_type, p_val->c_type_parameters); for (int i = 0; i < p_val->c_type_parameters; i++) { mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_DIAGNOSTICS, "type: %d\n", ((MonoType*)p_val->rg_type_parameters[i])->type); From 5bea5d7addc87e5e35a18558cfbac1b68cdead1a Mon Sep 17 00:00:00 2001 From: mdh1418 Date: Thu, 28 Apr 2022 23:52:15 -0400 Subject: [PATCH 14/28] Address logger instance and if_necessary feedback --- src/mono/mono/eventpipe/ep-rt-mono.c | 83 +++++++++++++++------------- src/mono/mono/eventpipe/ep-rt-mono.h | 10 ++-- 2 files changed, 50 insertions(+), 43 deletions(-) diff --git a/src/mono/mono/eventpipe/ep-rt-mono.c b/src/mono/mono/eventpipe/ep-rt-mono.c index c1b7260daf84a1..87131c492216e4 100644 --- a/src/mono/mono/eventpipe/ep-rt-mono.c +++ b/src/mono/mono/eventpipe/ep-rt-mono.c @@ -2923,10 +2923,12 @@ static const uint32_t k_max_bytes_type_values = (cb_max_etw_event - 0x30); // are no type parameters to log, but let's overestimate at 4 per value). static const uint32_t k_max_count_type_values = (128 - 2) / 4; -BulkTypeValue m_rg_bulk_type_values[k_max_count_type_values]; -uint32_t m_n_bulk_type_value_count; -uint32_t m_n_bulk_type_value_byte_count; -uint8_t *m_p_bulk_type_event_buffer[65536]; +struct _BulkTypeEventLogger { + BulkTypeValue m_rg_bulk_type_values[k_max_count_type_values]; + uint32_t m_n_bulk_type_value_count; + uint32_t m_n_bulk_type_value_byte_count; + uint8_t *m_p_bulk_type_event_buffer[65536]; +}; //--------------------------------------------------------------------------------------- // @@ -2936,20 +2938,20 @@ uint8_t *m_p_bulk_type_event_buffer[65536]; // void -ep_rt_mono_fire_bulk_type_event (void) +ep_rt_mono_fire_bulk_type_event (BulkTypeEventLogger *p_type_logger) { - if (m_n_bulk_type_value_count == 0) + if (p_type_logger->m_n_bulk_type_value_count == 0) return; - memset(m_p_bulk_type_event_buffer, 0, 65536 * sizeof(uint8_t)); + memset(p_type_logger->m_p_bulk_type_event_buffer, 0, 65536 * sizeof(uint8_t)); uint16_t n_clr_instance_id = clr_instance_get_id(); uint32_t i_size = 0; - for (int i_type_data = 0; i_type_data < m_n_bulk_type_value_count; i_type_data++) + for (int i_type_data = 0; i_type_data < p_type_logger->m_n_bulk_type_value_count; i_type_data++) { - BulkTypeValue *target = &m_rg_bulk_type_values[i_type_data]; + BulkTypeValue *target = &p_type_logger->m_rg_bulk_type_values[i_type_data]; - memcpy(m_p_bulk_type_event_buffer + i_size, + memcpy(p_type_logger->m_p_bulk_type_event_buffer + i_size, &target->fixed_sized_data, sizeof(target->fixed_sized_data)); i_size += sizeof(target->fixed_sized_data); @@ -2957,37 +2959,37 @@ ep_rt_mono_fire_bulk_type_event (void) char *wsz_name = target->s_name; if (!wsz_name) { - m_p_bulk_type_event_buffer[i_size++] = 0; - m_p_bulk_type_event_buffer[i_size++] = 0; + p_type_logger->m_p_bulk_type_event_buffer[i_size++] = 0; + p_type_logger->m_p_bulk_type_event_buffer[i_size++] = 0; } else { uint32_t name_size = (strlen(target->s_name) + 1) * sizeof(wchar_t); - memcpy(m_p_bulk_type_event_buffer + i_size, wsz_name, name_size); + memcpy(p_type_logger->m_p_bulk_type_event_buffer + i_size, wsz_name, name_size); i_size += strlen(wsz_name); } - uint32_t *ptr_int = (uint32_t*)(m_p_bulk_type_event_buffer + i_size); + uint32_t *ptr_int = (uint32_t*)(p_type_logger->m_p_bulk_type_event_buffer + i_size); *ptr_int = target->c_type_parameters; i_size += 4; if (target->c_type_parameters > 0) { - memcpy(m_p_bulk_type_event_buffer + i_size, target->rg_type_parameters, sizeof(uint64_t) * target->c_type_parameters); + memcpy(p_type_logger->m_p_bulk_type_event_buffer + i_size, target->rg_type_parameters, sizeof(uint64_t) * target->c_type_parameters); i_size += sizeof(uint64_t) * target->c_type_parameters; } } mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_DIAGNOSTICS, "Firing BulkTypeEvent!"); - FireEtwBulkType(m_n_bulk_type_value_count, + FireEtwBulkType(p_type_logger->m_n_bulk_type_value_count, n_clr_instance_id, i_size, - m_p_bulk_type_event_buffer, + p_type_logger->m_p_bulk_type_event_buffer, NULL, NULL); - m_n_bulk_type_value_count = 0; - m_n_bulk_type_value_byte_count = 0; + p_type_logger->m_n_bulk_type_value_count = 0; + p_type_logger->m_n_bulk_type_value_byte_count = 0; } //--------------------------------------------------------------------------------------- @@ -3030,15 +3032,15 @@ get_typeid_for_type (MonoType *t) { // Index into array of where this type got batched. -1 if there was a failure. uint32_t -ep_rt_mono_log_single_type (MonoType *mono_type, intptr_t type_id) +ep_rt_mono_log_single_type (BulkTypeEventLogger *p_type_logger, MonoType *mono_type, intptr_t type_id) { // If there's no room for another type, flush what we've got - if (m_n_bulk_type_value_count == k_max_count_type_values) - ep_rt_mono_fire_bulk_type_event(); + if (p_type_logger->m_n_bulk_type_value_count == k_max_count_type_values) + ep_rt_mono_fire_bulk_type_event(p_type_logger); - EP_ASSERT (m_n_bulk_type_value_count < k_max_count_type_values); + EP_ASSERT (p_type_logger->m_n_bulk_type_value_count < k_max_count_type_values); - BulkTypeValue *p_val = &m_rg_bulk_type_values[m_n_bulk_type_value_count]; + BulkTypeValue *p_val = &p_type_logger->m_rg_bulk_type_values[p_type_logger->m_n_bulk_type_value_count]; MonoClass *klass = mono_class_from_mono_type_internal (mono_type); MonoType *mono_underlying_type = mono_type_get_underlying_type (mono_type); @@ -3125,7 +3127,7 @@ ep_rt_mono_log_single_type (MonoType *mono_type, intptr_t type_id) return -1; } } - if (m_n_bulk_type_value_byte_count + cb_val > k_max_bytes_type_values) + if (p_type_logger->m_n_bulk_type_value_byte_count + cb_val > k_max_bytes_type_values) { // Although this type fits into the array, its size is so big that the entire // array can't be logged via ETW. So flush the array, and start over by @@ -3133,8 +3135,8 @@ ep_rt_mono_log_single_type (MonoType *mono_type, intptr_t type_id) // beginning of the array. Since we know this type is small enough to be // batched into an event on its own, this recursive call will not try to // call itself again. - ep_rt_mono_fire_bulk_type_event(); - return ep_rt_mono_log_single_type(mono_type, type_id); + ep_rt_mono_fire_bulk_type_event(p_type_logger); + return ep_rt_mono_log_single_type(p_type_logger, mono_type, type_id); } mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_DIAGNOSTICS, "p_val added at index: %d\ntype_id: %d\nmodule_id: %d\ntype_name_id: %d\ntype: %d\nc_type_parameters: %d", p_type_logger->m_n_bulk_type_value_count, p_val->fixed_sized_data.type_id, p_val->fixed_sized_data.module_id, p_val->fixed_sized_data.type_name_id, mono_underlying_type, p_val->c_type_parameters); for (int i = 0; i < p_val->c_type_parameters; i++) @@ -3143,9 +3145,9 @@ ep_rt_mono_log_single_type (MonoType *mono_type, intptr_t type_id) } // The type fits into the batch, so update our state - m_n_bulk_type_value_count++; - m_n_bulk_type_value_byte_count += cb_val; - return m_n_bulk_type_value_count - 1; + p_type_logger->m_n_bulk_type_value_count++; + p_type_logger->m_n_bulk_type_value_byte_count += cb_val; + return p_type_logger->m_n_bulk_type_value_count - 1; } //--------------------------------------------------------------------------------------- @@ -3158,11 +3160,11 @@ ep_rt_mono_log_single_type (MonoType *mono_type, intptr_t type_id) // * type_id - Unique type identifier of mono_type to batch void -ep_rt_mono_log_type_and_parameters (MonoType *mono_type, intptr_t type_id) +ep_rt_mono_log_type_and_parameters (BulkTypeEventLogger *p_type_logger, MonoType *mono_type, intptr_t type_id) { // Batch up this type. This grabs useful info about the type, including any // type parameters it may have, and sticks it in m_rg_bulk_type_values - uint32_t i_bulk_type_event_data = ep_rt_mono_log_single_type (mono_type, type_id); + uint32_t i_bulk_type_event_data = ep_rt_mono_log_single_type (p_type_logger, mono_type, type_id); if (i_bulk_type_event_data == -1) { // There was a failure trying to log the type, so don't bother with its type @@ -3171,7 +3173,7 @@ ep_rt_mono_log_type_and_parameters (MonoType *mono_type, intptr_t type_id) } // Look at the type info we just batched, so we can get the type parameters - BulkTypeValue *p_val = &m_rg_bulk_type_values[i_bulk_type_event_data]; + BulkTypeValue *p_val = &p_type_logger->m_rg_bulk_type_values[i_bulk_type_event_data]; // We're about to recursively call ourselves for the type parameters, so make a // local copy of their type handles first (else, as we log them we could flush @@ -3186,7 +3188,7 @@ ep_rt_mono_log_type_and_parameters (MonoType *mono_type, intptr_t type_id) } for (uint32_t i = 0; i < c_params; i++) - ep_rt_mono_log_type_and_parameters_if_necessary (rg_mono_type_parameters[i], rg_type_parameters[i]); + ep_rt_mono_log_type_and_parameters_if_necessary (p_type_logger, rg_mono_type_parameters[i], rg_type_parameters[i]); } //--------------------------------------------------------------------------------------- @@ -3200,11 +3202,11 @@ ep_rt_mono_log_type_and_parameters (MonoType *mono_type, intptr_t type_id) // static void -ep_rt_mono_log_type_and_parameters_if_necessary (MonoType *mono_type, intptr_t type_id) +ep_rt_mono_log_type_and_parameters_if_necessary (BulkTypeEventLogger *p_type_logger, MonoType *mono_type, intptr_t type_id) { // TODO Log the type if necessary - ep_rt_mono_log_type_and_parameters (mono_type, type_id); + ep_rt_mono_log_type_and_parameters (p_type_logger, mono_type, type_id); } //--------------------------------------------------------------------------------------- @@ -3236,6 +3238,8 @@ ep_rt_mono_send_method_details_event (MonoMethod *method) if (method_inst->type_argc > 1024) // ETW has a limit for maximum event size. Do not log overly large method type argument sets return; + BulkTypeEventLogger *p_type_logger = malloc(sizeof(BulkTypeEventLogger)); + intptr_t method_type_id = 0; uint32_t method_token = (method->token & 0xFFFFFF) | 0x06000000; // dotnet-pgo ResolveMethodID expects method tokens with a 0x06 mask uint64_t loader_module_id = 0; @@ -3245,7 +3249,7 @@ ep_rt_mono_send_method_details_event (MonoMethod *method) MonoType *method_mono_type = m_class_get_byval_arg (klass); method_type_id = get_typeid_for_type (method_mono_type); - ep_rt_mono_log_type_and_parameters_if_necessary (method_mono_type, method_type_id); + ep_rt_mono_log_type_and_parameters_if_necessary (p_type_logger, method_mono_type, method_type_id); loader_module_id = (uint64_t)mono_class_get_image (klass); } @@ -3259,10 +3263,10 @@ ep_rt_mono_send_method_details_event (MonoMethod *method) { method_inst_parameters_type_ids[i] = get_typeid_for_type (method_inst->type_argv[i]); - ep_rt_mono_log_type_and_parameters_if_necessary (method_inst->type_argv[i], method_inst_parameters_type_ids[i]); + ep_rt_mono_log_type_and_parameters_if_necessary (p_type_logger, method_inst->type_argv[i], method_inst_parameters_type_ids[i]); } - ep_rt_mono_fire_bulk_type_event(); + ep_rt_mono_fire_bulk_type_event(p_type_logger); mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_DIAGNOSTICS, "Firing Method:\n%s[%d]\ntype ID [%d]\nToken %d -> %d\nNumParam %d\nmodule %d\n", method->name, (uint64_t)method, method_type_id, method->token, method_token, method_inst_parameter_types_count, loader_module_id); FireEtwMethodDetails((uint64_t)method, @@ -3273,6 +3277,7 @@ ep_rt_mono_send_method_details_event (MonoMethod *method) (uint64_t*)method_inst_parameters_type_ids, NULL, NULL); + g_free (p_type_logger); } bool diff --git a/src/mono/mono/eventpipe/ep-rt-mono.h b/src/mono/mono/eventpipe/ep-rt-mono.h index fff3d7e31b9977..0e3bb958bbafa3 100644 --- a/src/mono/mono/eventpipe/ep-rt-mono.h +++ b/src/mono/mono/eventpipe/ep-rt-mono.h @@ -2179,17 +2179,19 @@ ep_rt_volatile_store_ptr_without_barrier ( bool ep_rt_mono_write_event_ee_startup_start (void); +typedef struct _BulkTypeEventLogger BulkTypeEventLogger; + void -ep_rt_mono_fire_bulk_type_event (void); +ep_rt_mono_fire_bulk_type_event (BulkTypeEventLogger *p_type_logger); uint32_t -ep_rt_mono_log_single_type (MonoType *mono_type, intptr_t type_id); +ep_rt_mono_log_single_type (BulkTypeEventLogger *p_type_logger, MonoType *mono_type, intptr_t type_id); void -ep_rt_mono_log_type_and_parameters (MonoType *mono_type, intptr_t type_id); +ep_rt_mono_log_type_and_parameters (BulkTypeEventLogger *p_type_logger, MonoType *mono_type, intptr_t type_id); void -ep_rt_mono_log_type_and_parameters_if_necessary (MonoType *mono_type, intptr_t type_id); +ep_rt_mono_log_type_and_parameters_if_necessary (BulkTypeEventLogger *p_type_logger, MonoType *mono_type, intptr_t type_id); void ep_rt_mono_send_method_details_events (MonoMethod *method); From b51d791ef2e7016c58e4c6f2c47d2c08a01fe811 Mon Sep 17 00:00:00 2001 From: mdh1418 Date: Thu, 28 Apr 2022 19:06:49 -0400 Subject: [PATCH 15/28] Fix s_name --- src/mono/mono/eventpipe/ep-rt-mono.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/mono/mono/eventpipe/ep-rt-mono.c b/src/mono/mono/eventpipe/ep-rt-mono.c index 87131c492216e4..740f604a5f586f 100644 --- a/src/mono/mono/eventpipe/ep-rt-mono.c +++ b/src/mono/mono/eventpipe/ep-rt-mono.c @@ -2896,10 +2896,14 @@ static uint32_t ep_rt_mono_get_byte_count_in_event(BulkTypeValue *bulk_type_value) { + uint32_t s_name_len = 0; + if (bulk_type_value->s_name) + s_name_len = strlen(bulk_type_value->s_name); + return sizeof(bulk_type_value->fixed_sized_data) + sizeof(bulk_type_value->c_type_parameters) + - (strlen(bulk_type_value->s_name) + 1) * sizeof(char) + // Size of name, including null terminator + (s_name_len + 1) * sizeof(char) + // Size of name, including null terminator bulk_type_value->c_type_parameters * sizeof(uint64_t); // Type parameters } @@ -2957,7 +2961,7 @@ ep_rt_mono_fire_bulk_type_event (BulkTypeEventLogger *p_type_logger) i_size += sizeof(target->fixed_sized_data); char *wsz_name = target->s_name; - if (!wsz_name) + if (!wsz_name || strlen(wsz_name) == 0) { p_type_logger->m_p_bulk_type_event_buffer[i_size++] = 0; p_type_logger->m_p_bulk_type_event_buffer[i_size++] = 0; @@ -3050,7 +3054,7 @@ ep_rt_mono_log_single_type (BulkTypeEventLogger *p_type_logger, MonoType *mono_t memset(p_val->rg_type_parameters, 0, 32); memset(p_val->rg_mono_type_parameters, 0, 32); if (p_val->s_name) - p_val->s_name[0] = '\0'; + p_val->s_name = '\0'; p_val->c_type_parameters = 0; // Initialize p_val fixed_sized_data From 3e2fa0012578dfa64f2dc86cee6129e41c88bcd5 Mon Sep 17 00:00:00 2001 From: mdh1418 Date: Thu, 28 Apr 2022 23:45:38 -0400 Subject: [PATCH 16/28] Cleanup comment tab spacing --- src/mono/mono/eventpipe/ep-rt-mono.c | 44 ++++++++++++++-------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/src/mono/mono/eventpipe/ep-rt-mono.c b/src/mono/mono/eventpipe/ep-rt-mono.c index 740f604a5f586f..6bb67a2f7d55f4 100644 --- a/src/mono/mono/eventpipe/ep-rt-mono.c +++ b/src/mono/mono/eventpipe/ep-rt-mono.c @@ -2903,7 +2903,7 @@ ep_rt_mono_get_byte_count_in_event(BulkTypeValue *bulk_type_value) return sizeof(bulk_type_value->fixed_sized_data) + sizeof(bulk_type_value->c_type_parameters) + - (s_name_len + 1) * sizeof(char) + // Size of name, including null terminator + (s_name_len + 1) * sizeof(char) + // Size of name, including null terminator bulk_type_value->c_type_parameters * sizeof(uint64_t); // Type parameters } @@ -3038,7 +3038,7 @@ get_typeid_for_type (MonoType *t) { uint32_t ep_rt_mono_log_single_type (BulkTypeEventLogger *p_type_logger, MonoType *mono_type, intptr_t type_id) { - // If there's no room for another type, flush what we've got + // If there's no room for another type, flush what we've got if (p_type_logger->m_n_bulk_type_value_count == k_max_count_type_values) ep_rt_mono_fire_bulk_type_event(p_type_logger); @@ -3049,8 +3049,8 @@ ep_rt_mono_log_single_type (BulkTypeEventLogger *p_type_logger, MonoType *mono_t MonoClass *klass = mono_class_from_mono_type_internal (mono_type); MonoType *mono_underlying_type = mono_type_get_underlying_type (mono_type); - // Clear out p_val before filling it out (array elements can get reused if there - // are enough types that we need to flush to multiple events). + // Clear out p_val before filling it out (array elements can get reused if there + // are enough types that we need to flush to multiple events). memset(p_val->rg_type_parameters, 0, 32); memset(p_val->rg_mono_type_parameters, 0, 32); if (p_val->s_name) @@ -3115,8 +3115,8 @@ ep_rt_mono_log_single_type (BulkTypeEventLogger *p_type_logger, MonoType *mono_t if (mono_class_is_com_object (klass)) p_val->fixed_sized_data.flags |= K_ETW_TYPE_FLAGS_EXTERNALLY_IMPLEMENTED_COM_OBJECT; - // Now that we know the full size of this type's data, see if it fits in our - // batch or whether we need to flush + // Now that we know the full size of this type's data, see if it fits in our + // batch or whether we need to flush int cb_val = ep_rt_mono_get_byte_count_in_event(p_val); if (cb_val > k_max_bytes_type_values) { @@ -3127,18 +3127,18 @@ ep_rt_mono_log_single_type (BulkTypeEventLogger *p_type_logger, MonoType *mono_t if (cb_val > k_max_bytes_type_values) { // This type is apparently so huge, it's too big to squeeze into an event, even - // if it were the only type batched in the whole event. Bail + // if it were the only type batched in the whole event. Bail return -1; } } if (p_type_logger->m_n_bulk_type_value_byte_count + cb_val > k_max_bytes_type_values) { - // Although this type fits into the array, its size is so big that the entire - // array can't be logged via ETW. So flush the array, and start over by - // calling ourselves--this refetches the type info and puts it at the - // beginning of the array. Since we know this type is small enough to be - // batched into an event on its own, this recursive call will not try to - // call itself again. + // Although this type fits into the array, its size is so big that the entire + // array can't be logged via ETW. So flush the array, and start over by + // calling ourselves--this refetches the type info and puts it at the + // beginning of the array. Since we know this type is small enough to be + // batched into an event on its own, this recursive call will not try to + // call itself again. ep_rt_mono_fire_bulk_type_event(p_type_logger); return ep_rt_mono_log_single_type(p_type_logger, mono_type, type_id); } @@ -3148,7 +3148,7 @@ ep_rt_mono_log_single_type (BulkTypeEventLogger *p_type_logger, MonoType *mono_t mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_DIAGNOSTICS, "type: %d\n", ((MonoType*)p_val->rg_type_parameters[i])->type); } - // The type fits into the batch, so update our state + // The type fits into the batch, so update our state p_type_logger->m_n_bulk_type_value_count++; p_type_logger->m_n_bulk_type_value_byte_count += cb_val; return p_type_logger->m_n_bulk_type_value_count - 1; @@ -3166,22 +3166,22 @@ ep_rt_mono_log_single_type (BulkTypeEventLogger *p_type_logger, MonoType *mono_t void ep_rt_mono_log_type_and_parameters (BulkTypeEventLogger *p_type_logger, MonoType *mono_type, intptr_t type_id) { - // Batch up this type. This grabs useful info about the type, including any - // type parameters it may have, and sticks it in m_rg_bulk_type_values + // Batch up this type. This grabs useful info about the type, including any + // type parameters it may have, and sticks it in m_rg_bulk_type_values uint32_t i_bulk_type_event_data = ep_rt_mono_log_single_type (p_type_logger, mono_type, type_id); if (i_bulk_type_event_data == -1) { - // There was a failure trying to log the type, so don't bother with its type - // parameters + // There was a failure trying to log the type, so don't bother with its type + // parameters return; } - // Look at the type info we just batched, so we can get the type parameters + // Look at the type info we just batched, so we can get the type parameters BulkTypeValue *p_val = &p_type_logger->m_rg_bulk_type_values[i_bulk_type_event_data]; - // We're about to recursively call ourselves for the type parameters, so make a - // local copy of their type handles first (else, as we log them we could flush - // and clear out m_rg_bulk_type_values, thus trashing p_val) + // We're about to recursively call ourselves for the type parameters, so make a + // local copy of their type handles first (else, as we log them we could flush + // and clear out m_rg_bulk_type_values, thus trashing p_val) uint32_t c_params = p_val->c_type_parameters; intptr_t rg_type_parameters[c_params]; MonoType *rg_mono_type_parameters[c_params]; From 43ea8b671d1fcffbab4280bdae63bd42f03ece00 Mon Sep 17 00:00:00 2001 From: mdh1418 Date: Mon, 2 May 2022 21:36:02 -0400 Subject: [PATCH 17/28] Address feedback Fix bulk type event buffer Fix mono type check Fix mono type check Clear bulk type event logger Debug bulktype event firing Fix tab bulktype firing Fix fixed_sized_data byte copy Address constants feedback Add maximum event size constant Add maximum bulk type value type parameters constant Add maximum method type argument count constant Fix typo Address BulkType Value s_name type size feedback Address softcode buffer size increment Address switch case feedback Address fixed sized array feedback Fix spacing Add init/fini for BulkTypeEventLogger and BulkTypeValue instances Fix return type ep_rt_mono_log_single_type Add get_typeid_for_class helper Add assertion for large types Fix lttng map Use helper methods to write into bulk type event logger buffer Fix typo ep_rt_mono_send_method_details_event definition Change s_name to ep_char8_t and write with gunichar2 --- src/coreclr/scripts/genLttngProvider.py | 8 +- src/mono/mono/eventpipe/ep-rt-mono.c | 290 ++++++++++++++++++------ src/mono/mono/eventpipe/ep-rt-mono.h | 4 +- 3 files changed, 224 insertions(+), 78 deletions(-) diff --git a/src/coreclr/scripts/genLttngProvider.py b/src/coreclr/scripts/genLttngProvider.py index f073d326e9c634..c5b16e6d1ef554 100644 --- a/src/coreclr/scripts/genLttngProvider.py +++ b/src/coreclr/scripts/genLttngProvider.py @@ -97,8 +97,8 @@ "win:Struct" :"const uint8_t *", #actual spec "win:GUID" :"const int32_t", - "win:AnsiString" :"const uint8_t*", - "win:UnicodeString" :"const uint8_t*", + "win:AnsiString" :"const char*", + "win:UnicodeString" :"const ep_char8_t*", "win:Double" :"const double", "win:Int32" :"const int32_t", "win:Boolean" :"const bool", @@ -106,8 +106,8 @@ "win:UInt32" :"const uint32_t", "win:UInt16" :"const uint16_t", "win:UInt8" :"const uint8_t", - "win:Pointer" :"const size_t", - "win:Binary" :"const BYTE" + "win:Pointer" :"const void*", + "win:Binary" :"const uint8_t" } def getLttngDataTypeMapping(runtimeFlavor): diff --git a/src/mono/mono/eventpipe/ep-rt-mono.c b/src/mono/mono/eventpipe/ep-rt-mono.c index 6bb67a2f7d55f4..307b79671ec8b2 100644 --- a/src/mono/mono/eventpipe/ep-rt-mono.c +++ b/src/mono/mono/eventpipe/ep-rt-mono.c @@ -2857,6 +2857,12 @@ ep_rt_mono_write_event_ee_startup_start (void) NULL); } +#define STACK_ALLOC 256 + +// The maximum number of type parameters for a BulkTypeValue instance +// Aligned with coreCLR StackSArray rgTypeParameters +static const uint32_t k_size_of_type_parameter_array = STACK_ALLOC / sizeof(intptr_t); + // !!!!!!! NOTE !!!!!!!! // The flags must match those in the ETW manifest exactly // !!!!!!! NOTE !!!!!!!! @@ -2884,26 +2890,50 @@ typedef struct _EventStructBulkTypeFixedSizedData { } EventStructBulkTypeFixedSizedData; // Represents one instance of the Value struct inside a single BulkType event -typedef struct _BultTypeValue { +typedef struct _BulkTypeValue { EventStructBulkTypeFixedSizedData fixed_sized_data; uint32_t c_type_parameters; - intptr_t rg_type_parameters[32]; - MonoType *rg_mono_type_parameters[32]; - char *s_name; + intptr_t rg_type_parameters[k_size_of_type_parameter_array]; + MonoType *rg_mono_type_parameters[k_size_of_type_parameter_array]; + ep_char8_t *s_name; } BulkTypeValue; +// Clear out BulkTypeValue before filling it out (array elements can get reused if there +// are enough types that we need to flush to multiple events). +static +void +ep_rt_bulk_type_value_init(BulkTypeValue *bulk_type_value) +{ + bulk_type_value->fixed_sized_data.type_id = 0; + bulk_type_value->fixed_sized_data.module_id = 0; + bulk_type_value->fixed_sized_data.type_name_id = 0; + bulk_type_value->fixed_sized_data.flags = 0; + bulk_type_value->fixed_sized_data.cor_element_type = 0; + bulk_type_value->c_type_parameters = 0; + memset(bulk_type_value->rg_type_parameters, 0, k_size_of_type_parameter_array); + memset(bulk_type_value->rg_mono_type_parameters, 0, k_size_of_type_parameter_array); + if (bulk_type_value->s_name) + bulk_type_value->s_name[0] = '\0'; +} + static uint32_t ep_rt_mono_get_byte_count_in_event(BulkTypeValue *bulk_type_value) { - uint32_t s_name_len = 0; + size_t s_name_len = 0; + if (bulk_type_value->s_name) - s_name_len = strlen(bulk_type_value->s_name); + while (bulk_type_value->s_name [s_name_len]) + s_name_len++; return - sizeof(bulk_type_value->fixed_sized_data) + - sizeof(bulk_type_value->c_type_parameters) + - (s_name_len + 1) * sizeof(char) + // Size of name, including null terminator + sizeof(bulk_type_value->fixed_sized_data.type_id) + // sizeof(bulk_type_value->fixed_sized_data) + + sizeof(bulk_type_value->fixed_sized_data.module_id) + + sizeof(bulk_type_value->fixed_sized_data.type_name_id) + + sizeof(bulk_type_value->fixed_sized_data.flags) + + sizeof(bulk_type_value->fixed_sized_data.cor_element_type) + + sizeof(bulk_type_value->c_type_parameters) + // Type parameters + (s_name_len + 1) * sizeof(ep_char8_t) + // Size of name, including null terminator bulk_type_value->c_type_parameters * sizeof(uint64_t); // Type parameters } @@ -2912,8 +2942,12 @@ ep_rt_mono_get_byte_count_in_event(BulkTypeValue *bulk_type_value) // far away to avoid problems without sacrificing the perf of bulk processing. static const uint32_t cb_max_etw_event = 63 * 1024; +// The maximum event size, and the size of the buffer that we allocate to hold the event contents. +static const size_t k_size_of_event_buffer = 65536; + // Estimate of how many bytes we can squeeze in the event data for the value struct // array. (Intentionally overestimate the size of the non-array parts to keep it safe.) +// This follows CoreCLR's kMaxBytesTypeValues. static const uint32_t k_max_bytes_type_values = (cb_max_etw_event - 0x30); // Estimate of how many type value elements we can put into the struct array, while @@ -2931,60 +2965,147 @@ struct _BulkTypeEventLogger { BulkTypeValue m_rg_bulk_type_values[k_max_count_type_values]; uint32_t m_n_bulk_type_value_count; uint32_t m_n_bulk_type_value_byte_count; - uint8_t *m_p_bulk_type_event_buffer[65536]; + uint8_t *m_p_bulk_type_event_buffer; }; +static +BulkTypeEventLogger* +ep_rt_bulk_type_event_logger_init() +{ + BulkTypeEventLogger *p_type_logger = g_malloc0 (sizeof(BulkTypeEventLogger)); + for (int i = 0; i < k_max_count_type_values; i++) + ep_rt_bulk_type_value_init (&p_type_logger->m_rg_bulk_type_values[i]); + p_type_logger->m_p_bulk_type_event_buffer = g_malloc0 (sizeof(uint8_t) * k_size_of_event_buffer); + return p_type_logger; +} + +static +void +ep_rt_bulk_type_event_logger_fini(BulkTypeEventLogger *p_type_logger) +{ + g_free (p_type_logger->m_p_bulk_type_event_buffer); + g_free (p_type_logger); +} + +static +int +write_event_buffer (const uint8_t *val, size_t size, char *buf_start, char **buf_next) +{ + memcpy (buf_start, val, size); + *buf_next = buf_start + size; + return size; +} + +static +int +write_event_buffer_int8 (int8_t val, char *buf_start, char **buf_next) +{ + return write_event_buffer ((const uint8_t *)&val, sizeof (int8_t), buf_start, buf_next); +} + +static +int +write_event_buffer_int16 (int16_t val, char *buf_start, char **buf_next) +{ + return write_event_buffer ((const uint8_t *)&val, sizeof (int16_t), buf_start, buf_next); +} + +static +int +write_event_buffer_int32 (int32_t val, char *buf_start, char **buf_next) +{ + return write_event_buffer ((const uint8_t *)&val, sizeof (int32_t), buf_start, buf_next); +} + +static +int +write_event_buffer_int64 (int64_t val, char *buf_start, char **buf_next) +{ + return write_event_buffer ((const uint8_t *)&val, sizeof (int64_t), buf_start, buf_next); +} + +static +int +write_event_buffer_intptr (intptr_t val, char *buf_start, char **buf_next) +{ + return write_event_buffer ((const uint8_t *)&val, sizeof (intptr_t), buf_start, buf_next); +} + +static +int +write_event_buffer_utf16_str (gunichar2 *value, char *buf_start, char **buf_next) +{ + if (!value) + return 0; + + size_t value_len = 0; + while (value [value_len]) + value_len++; + + return write_event_buffer ((const uint8_t *)value, (value_len + 1) * sizeof(*value), buf_start, buf_next); +} + //--------------------------------------------------------------------------------------- // // ep_rt_mono_fire_bulk_type_event fires an ETW event for all the types batched so far, // it then resets the state to start batching new types at the beginning of the // m_rg_bulk_type_values array. // +// This follows CoreCLR's BulkTypeEventLogger::FireBulkTypeEvent void ep_rt_mono_fire_bulk_type_event (BulkTypeEventLogger *p_type_logger) { if (p_type_logger->m_n_bulk_type_value_count == 0) return; - memset(p_type_logger->m_p_bulk_type_event_buffer, 0, 65536 * sizeof(uint8_t)); + + mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_DIAGNOSTICS, "Firing BulkTypeEvent!"); + uint16_t n_clr_instance_id = clr_instance_get_id(); uint32_t i_size = 0; + char *ptr = (char *)p_type_logger->m_p_bulk_type_event_buffer; + for (int i_type_data = 0; i_type_data < p_type_logger->m_n_bulk_type_value_count; i_type_data++) { + mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_DIAGNOSTICS, "TypeData[%lu]\n", i_type_data); BulkTypeValue *target = &p_type_logger->m_rg_bulk_type_values[i_type_data]; - memcpy(p_type_logger->m_p_bulk_type_event_buffer + i_size, - &target->fixed_sized_data, - sizeof(target->fixed_sized_data)); - i_size += sizeof(target->fixed_sized_data); + i_size += write_event_buffer_int64 (target->fixed_sized_data.type_id, ptr, &ptr); + i_size += write_event_buffer_int64 (target->fixed_sized_data.module_id, ptr, &ptr); + i_size += write_event_buffer_int32 (target->fixed_sized_data.type_name_id, ptr, &ptr); + i_size += write_event_buffer_int32 (target->fixed_sized_data.flags, ptr, &ptr); + i_size += write_event_buffer_int8 (target->fixed_sized_data.cor_element_type, ptr, &ptr); + + mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_DIAGNOSTICS, "FSB\ntype_id: %lu\nmodule_id: %lu\ntype_name_id: %lu\nflags: %lu\ncor_element_type: %lu\n", target->fixed_sized_data.type_id, target->fixed_sized_data.module_id, target->fixed_sized_data.type_name_id, target->fixed_sized_data.flags, target->fixed_sized_data.cor_element_type); - char *wsz_name = target->s_name; - if (!wsz_name || strlen(wsz_name) == 0) + gunichar2 *wsz_name = g_utf8_to_utf16 (target->s_name, -1, NULL, NULL, NULL); + if (!wsz_name) { - p_type_logger->m_p_bulk_type_event_buffer[i_size++] = 0; - p_type_logger->m_p_bulk_type_event_buffer[i_size++] = 0; + i_size += write_event_buffer_int16 (0, ptr, &ptr); } else { - uint32_t name_size = (strlen(target->s_name) + 1) * sizeof(wchar_t); - memcpy(p_type_logger->m_p_bulk_type_event_buffer + i_size, wsz_name, name_size); - i_size += strlen(wsz_name); + i_size += write_event_buffer_utf16_str (wsz_name, ptr, &ptr); + g_free (wsz_name); } - uint32_t *ptr_int = (uint32_t*)(p_type_logger->m_p_bulk_type_event_buffer + i_size); - *ptr_int = target->c_type_parameters; - i_size += 4; + i_size += write_event_buffer_int32 (target->c_type_parameters, ptr, &ptr); + mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_DIAGNOSTICS, "c_type_parameters: %lu\n", target->c_type_parameters); - if (target->c_type_parameters > 0) + for (int i = 0; i < target->c_type_parameters; i++) { - memcpy(p_type_logger->m_p_bulk_type_event_buffer + i_size, target->rg_type_parameters, sizeof(uint64_t) * target->c_type_parameters); - i_size += sizeof(uint64_t) * target->c_type_parameters; + i_size += write_event_buffer_intptr (target->rg_type_parameters[i], ptr, &ptr); + } + for (int i = 0; i < target->c_type_parameters; i++) + { + mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_DIAGNOSTICS, "target->rg_mono_type_parameters[%lu]: %lu\n", i, target->rg_mono_type_parameters[i]); + mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_DIAGNOSTICS, "target->rg_type_parameters[%lu]: %lu\n", i, target->rg_type_parameters[i]); } } - mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_DIAGNOSTICS, "Firing BulkTypeEvent!"); + mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_DIAGNOSTICS, "Count: %lu\nClrInstanceID: %lu\nValues_ElementSize: %lu\n", p_type_logger->m_n_bulk_type_value_count, n_clr_instance_id, i_size); FireEtwBulkType(p_type_logger->m_n_bulk_type_value_count, n_clr_instance_id, i_size, @@ -2992,6 +3113,7 @@ ep_rt_mono_fire_bulk_type_event (BulkTypeEventLogger *p_type_logger) NULL, NULL); + memset (p_type_logger->m_p_bulk_type_event_buffer, 0, sizeof(uint8_t) * k_size_of_event_buffer); p_type_logger->m_n_bulk_type_value_count = 0; p_type_logger->m_n_bulk_type_value_byte_count = 0; } @@ -3014,9 +3136,14 @@ ep_rt_mono_fire_bulk_type_event (BulkTypeEventLogger *p_type_logger) static intptr_t get_typeid_for_type (MonoType *t) { if (m_type_is_byref (t)) - return m_class_get_this_arg (mono_class_from_mono_type_internal (t)); + return (intptr_t)m_class_get_this_arg (mono_class_from_mono_type_internal (t)); else - return m_class_get_byval_arg (mono_class_from_mono_type_internal (t)); + return (intptr_t)m_class_get_byval_arg (mono_class_from_mono_type_internal (t)); +} + +static intptr_t +get_typeid_for_class (MonoClass *c) { + return get_typeid_for_type (m_class_get_byval_arg (c)); } //--------------------------------------------------------------------------------------- @@ -3034,44 +3161,46 @@ get_typeid_for_type (MonoType *t) { // // Return Value: // Index into array of where this type got batched. -1 if there was a failure. +// +// This follows CoreCLR's BulkTypeEventLogger::LogSingleType -uint32_t +int ep_rt_mono_log_single_type (BulkTypeEventLogger *p_type_logger, MonoType *mono_type, intptr_t type_id) { // If there's no room for another type, flush what we've got if (p_type_logger->m_n_bulk_type_value_count == k_max_count_type_values) - ep_rt_mono_fire_bulk_type_event(p_type_logger); + ep_rt_mono_fire_bulk_type_event (p_type_logger); EP_ASSERT (p_type_logger->m_n_bulk_type_value_count < k_max_count_type_values); BulkTypeValue *p_val = &p_type_logger->m_rg_bulk_type_values[p_type_logger->m_n_bulk_type_value_count]; + ep_rt_bulk_type_value_init (p_val); MonoClass *klass = mono_class_from_mono_type_internal (mono_type); MonoType *mono_underlying_type = mono_type_get_underlying_type (mono_type); - // Clear out p_val before filling it out (array elements can get reused if there - // are enough types that we need to flush to multiple events). - memset(p_val->rg_type_parameters, 0, 32); - memset(p_val->rg_mono_type_parameters, 0, 32); - if (p_val->s_name) - p_val->s_name = '\0'; - p_val->c_type_parameters = 0; - // Initialize p_val fixed_sized_data p_val->fixed_sized_data.type_id = (uint64_t)type_id; p_val->fixed_sized_data.module_id = (uint64_t)m_class_get_image (klass); - p_val->fixed_sized_data.type_name_id = (0x00FFFFFF & m_class_get_type_token (klass)) | 0x02000000; // dotnet-pgo ResolveMethodID expects type name ids with a 0x02 mask - p_val->fixed_sized_data.flags = 0; + p_val->fixed_sized_data.type_name_id = mono_metadata_make_token (MONO_TABLE_TYPEDEF, mono_metadata_token_index (m_class_get_type_token (klass))); + if (mono_class_has_finalizer (klass)) + p_val->fixed_sized_data.flags |= K_ETW_TYPE_FLAGS_FINALIZABLE; + if (m_class_is_delegate (klass)) + p_val->fixed_sized_data.flags |= K_ETW_TYPE_FLAGS_DELEGATE; + if (mono_class_is_com_object (klass)) + p_val->fixed_sized_data.flags |= K_ETW_TYPE_FLAGS_EXTERNALLY_IMPLEMENTED_COM_OBJECT; p_val->fixed_sized_data.cor_element_type = (uint8_t)mono_underlying_type->type; // Sets p_val variable sized parameter type data c_type_parameters and rg_type_parameters // associated with arrays or generics and add unique identifiers to rg_type_parameters array // to be recursively batched in the same ep_rt_mono_log_type_and_parameters call - if ((mono_underlying_type == MONO_TYPE_ARRAY) || (mono_underlying_type == MONO_TYPE_SZARRAY)) + switch (mono_underlying_type->type) { + case MONO_TYPE_ARRAY: + case MONO_TYPE_SZARRAY: { MonoArrayType *mono_array_type = mono_type_get_array_type (mono_type); p_val->fixed_sized_data.flags |= K_ETW_TYPE_FLAGS_ARRAY; - if (mono_underlying_type == MONO_TYPE_ARRAY) + if (mono_underlying_type->type == MONO_TYPE_ARRAY) { // Only ranks less than kEtwTypeFlagsArrayRankMax are supported. // Fortunately kEtwTypeFlagsArrayRankMax should be greater than the @@ -3086,10 +3215,11 @@ ep_rt_mono_log_single_type (BulkTypeEventLogger *p_type_logger, MonoType *mono_t // mono arrays are always arrays of by value types p_val->rg_mono_type_parameters[p_val->c_type_parameters] = m_class_get_byval_arg (mono_array_type->eklass); - p_val->rg_type_parameters[p_val->c_type_parameters] = get_typeid_for_type (m_class_get_byval_arg (mono_array_type->eklass)); + p_val->rg_type_parameters[p_val->c_type_parameters] = get_typeid_for_class (mono_array_type->eklass); p_val->c_type_parameters++; + break; } - else if (mono_underlying_type == MONO_TYPE_GENERICINST) + case MONO_TYPE_GENERICINST: { MonoGenericInst *class_inst = mono_type->data.generic_class->context.class_inst; p_val->c_type_parameters = class_inst->type_argc; @@ -3098,22 +3228,24 @@ ep_rt_mono_log_single_type (BulkTypeEventLogger *p_type_logger, MonoType *mono_t p_val->rg_mono_type_parameters[i] = class_inst->type_argv[i]; p_val->rg_type_parameters[i] = get_typeid_for_type (class_inst->type_argv[i]); } + break; } - else if (mono_underlying_type == MONO_TYPE_CLASS || mono_underlying_type == MONO_TYPE_VALUETYPE || mono_underlying_type == MONO_TYPE_PTR || mono_underlying_type == MONO_TYPE_BYREF) + case MONO_TYPE_CLASS: + case MONO_TYPE_VALUETYPE: + case MONO_TYPE_PTR: + case MONO_TYPE_BYREF: { - p_val->rg_mono_type_parameters[p_val->c_type_parameters] = mono_type_get_underlying_type (mono_type); - p_val->rg_type_parameters[p_val->c_type_parameters] = get_typeid_for_type (mono_type_get_underlying_type (mono_type)); - p_val->c_type_parameters++; + if (mono_underlying_type != mono_type) + { + p_val->rg_mono_type_parameters[p_val->c_type_parameters] = mono_type_get_underlying_type (mono_type); + p_val->rg_type_parameters[p_val->c_type_parameters] = get_typeid_for_type (mono_type_get_underlying_type (mono_type)); + p_val->c_type_parameters++; + } + break; + } + default: + break; } - - if (mono_class_has_finalizer (klass)) - p_val->fixed_sized_data.flags |= K_ETW_TYPE_FLAGS_FINALIZABLE; - - if (m_class_is_delegate (klass)) - p_val->fixed_sized_data.flags |= K_ETW_TYPE_FLAGS_DELEGATE; - - if (mono_class_is_com_object (klass)) - p_val->fixed_sized_data.flags |= K_ETW_TYPE_FLAGS_EXTERNALLY_IMPLEMENTED_COM_OBJECT; // Now that we know the full size of this type's data, see if it fits in our // batch or whether we need to flush @@ -3128,9 +3260,11 @@ ep_rt_mono_log_single_type (BulkTypeEventLogger *p_type_logger, MonoType *mono_t { // This type is apparently so huge, it's too big to squeeze into an event, even // if it were the only type batched in the whole event. Bail + mono_trace (G_LOG_LEVEL_ERROR, MONO_TRACE_DIAGNOSTICS, "Failed to log single mono type %lu with typeID %lu. Type is too large for the BulkType Event.\n", mono_type, type_id); return -1; } } + if (p_type_logger->m_n_bulk_type_value_byte_count + cb_val > k_max_bytes_type_values) { // Although this type fits into the array, its size is so big that the entire @@ -3139,13 +3273,14 @@ ep_rt_mono_log_single_type (BulkTypeEventLogger *p_type_logger, MonoType *mono_t // beginning of the array. Since we know this type is small enough to be // batched into an event on its own, this recursive call will not try to // call itself again. + g_assert (p_type_logger->m_n_bulk_type_value_byte_count + cb_val > k_max_bytes_type_values); ep_rt_mono_fire_bulk_type_event(p_type_logger); return ep_rt_mono_log_single_type(p_type_logger, mono_type, type_id); } - mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_DIAGNOSTICS, "p_val added at index: %d\ntype_id: %d\nmodule_id: %d\ntype_name_id: %d\ntype: %d\nc_type_parameters: %d", p_type_logger->m_n_bulk_type_value_count, p_val->fixed_sized_data.type_id, p_val->fixed_sized_data.module_id, p_val->fixed_sized_data.type_name_id, mono_underlying_type, p_val->c_type_parameters); + mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_DIAGNOSTICS, "p_val added at index: %lu\ntype_id: %lu\nmodule_id: %lu\ntype_name_id: %lu\ntype: %lu\nc_type_parameters: %lu", p_type_logger->m_n_bulk_type_value_count, p_val->fixed_sized_data.type_id, p_val->fixed_sized_data.module_id, p_val->fixed_sized_data.type_name_id, mono_underlying_type->type, p_val->c_type_parameters); for (int i = 0; i < p_val->c_type_parameters; i++) { - mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_DIAGNOSTICS, "type: %d\n", ((MonoType*)p_val->rg_type_parameters[i])->type); + mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_DIAGNOSTICS, "type: %lu\n", ((MonoType*)p_val->rg_type_parameters[i])->type); } // The type fits into the batch, so update our state @@ -3162,13 +3297,15 @@ ep_rt_mono_log_single_type (BulkTypeEventLogger *p_type_logger, MonoType *mono_t // Arguments: // * mono_type - MonoType to be logged // * type_id - Unique type identifier of mono_type to batch +// +// This follows CoreCLR's BulkTypeEventLogger::LogTypeAndParameter void ep_rt_mono_log_type_and_parameters (BulkTypeEventLogger *p_type_logger, MonoType *mono_type, intptr_t type_id) { // Batch up this type. This grabs useful info about the type, including any // type parameters it may have, and sticks it in m_rg_bulk_type_values - uint32_t i_bulk_type_event_data = ep_rt_mono_log_single_type (p_type_logger, mono_type, type_id); + int i_bulk_type_event_data = ep_rt_mono_log_single_type (p_type_logger, mono_type, type_id); if (i_bulk_type_event_data == -1) { // There was a failure trying to log the type, so don't bother with its type @@ -3183,8 +3320,8 @@ ep_rt_mono_log_type_and_parameters (BulkTypeEventLogger *p_type_logger, MonoType // local copy of their type handles first (else, as we log them we could flush // and clear out m_rg_bulk_type_values, thus trashing p_val) uint32_t c_params = p_val->c_type_parameters; - intptr_t rg_type_parameters[c_params]; - MonoType *rg_mono_type_parameters[c_params]; + intptr_t rg_type_parameters[k_size_of_type_parameter_array]; + MonoType *rg_mono_type_parameters[k_size_of_type_parameter_array]; for (uint32_t i = 0; i < c_params; i++) { rg_type_parameters[i] = p_val->rg_type_parameters[i]; @@ -3203,6 +3340,8 @@ ep_rt_mono_log_type_and_parameters (BulkTypeEventLogger *p_type_logger, MonoType // Arguments: // * mono_type - MonoType to be logged // * type_id - Unique type identifier of mono_type +// +// This follows CoreCLR's BulkTypeEventLogger::LogTypeAndParameters // static void @@ -3213,6 +3352,9 @@ ep_rt_mono_log_type_and_parameters_if_necessary (BulkTypeEventLogger *p_type_log ep_rt_mono_log_type_and_parameters (p_type_logger, mono_type, type_id); } +// ETW has a limit for maximum event size. Do not log overly large method type argument sets +static const uint32_t k_max_method_type_argument_count = 1024; + //--------------------------------------------------------------------------------------- // // ep_rt_mono_send_method_details_event is the method responsible for sending details of @@ -3225,11 +3367,13 @@ ep_rt_mono_log_type_and_parameters_if_necessary (BulkTypeEventLogger *p_type_log // // Arguments: // * method - a MonoMethod hit during an eventpipe event +// +// This follows CoreCLR's ETW::MethodLog::SendMethodDetailsEvent void ep_rt_mono_send_method_details_event (MonoMethod *method) { - if (method->dynamic) + if (method->wrapper_type != MONO_WRAPPER_NONE || method->dynamic) return; MonoGenericContext *method_ctx = mono_method_get_context(method); @@ -3239,19 +3383,20 @@ ep_rt_mono_send_method_details_event (MonoMethod *method) method_inst = method_ctx->method_inst; if (method_inst) - if (method_inst->type_argc > 1024) // ETW has a limit for maximum event size. Do not log overly large method type argument sets + if (method_inst->type_argc > k_max_method_type_argument_count) return; - BulkTypeEventLogger *p_type_logger = malloc(sizeof(BulkTypeEventLogger)); + BulkTypeEventLogger *p_type_logger = ep_rt_bulk_type_event_logger_init(); intptr_t method_type_id = 0; - uint32_t method_token = (method->token & 0xFFFFFF) | 0x06000000; // dotnet-pgo ResolveMethodID expects method tokens with a 0x06 mask + g_assert (mono_metadata_token_index (method->token) != 0); + uint32_t method_token = mono_metadata_make_token (MONO_TABLE_METHOD, mono_metadata_token_index (method->token)); uint64_t loader_module_id = 0; MonoClass *klass = method->klass; if (klass) { MonoType *method_mono_type = m_class_get_byval_arg (klass); - method_type_id = get_typeid_for_type (method_mono_type); + method_type_id = get_typeid_for_class (klass); ep_rt_mono_log_type_and_parameters_if_necessary (p_type_logger, method_mono_type, method_type_id); @@ -3272,7 +3417,7 @@ ep_rt_mono_send_method_details_event (MonoMethod *method) ep_rt_mono_fire_bulk_type_event(p_type_logger); - mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_DIAGNOSTICS, "Firing Method:\n%s[%d]\ntype ID [%d]\nToken %d -> %d\nNumParam %d\nmodule %d\n", method->name, (uint64_t)method, method_type_id, method->token, method_token, method_inst_parameter_types_count, loader_module_id); + mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_DIAGNOSTICS, "Firing Method: %s\n%s[%lu]\ntype ID [%lu]\nToken %lu -> %lu\nNumParam %lu\nmodule %lu\n", mono_method_get_full_name (method), method->name, (uint64_t)method, method_type_id, method->token, method_token, method_inst_parameter_types_count, loader_module_id); FireEtwMethodDetails((uint64_t)method, (uint64_t)method_type_id, method_token, @@ -3281,7 +3426,8 @@ ep_rt_mono_send_method_details_event (MonoMethod *method) (uint64_t*)method_inst_parameters_type_ids, NULL, NULL); - g_free (p_type_logger); + + ep_rt_bulk_type_event_logger_fini (p_type_logger); } bool diff --git a/src/mono/mono/eventpipe/ep-rt-mono.h b/src/mono/mono/eventpipe/ep-rt-mono.h index 0e3bb958bbafa3..ad1c5ae5a83305 100644 --- a/src/mono/mono/eventpipe/ep-rt-mono.h +++ b/src/mono/mono/eventpipe/ep-rt-mono.h @@ -2184,7 +2184,7 @@ typedef struct _BulkTypeEventLogger BulkTypeEventLogger; void ep_rt_mono_fire_bulk_type_event (BulkTypeEventLogger *p_type_logger); -uint32_t +int ep_rt_mono_log_single_type (BulkTypeEventLogger *p_type_logger, MonoType *mono_type, intptr_t type_id); void @@ -2194,7 +2194,7 @@ void ep_rt_mono_log_type_and_parameters_if_necessary (BulkTypeEventLogger *p_type_logger, MonoType *mono_type, intptr_t type_id); void -ep_rt_mono_send_method_details_events (MonoMethod *method); +ep_rt_mono_send_method_details_event (MonoMethod *method); bool ep_rt_mono_write_event_jit_start (MonoMethod *method); From ac86cd236c5cbfaa30fc24befeea4d464a3a0d02 Mon Sep 17 00:00:00 2001 From: mdh1418 Date: Thu, 5 May 2022 11:39:44 -0400 Subject: [PATCH 18/28] Removed temporary debug traces Set BulkTypeValue s_name to null for now Fixed debug trace formatting for pointers Fix type_name_id for types with no token Remove write_event_buffer_intptr as the size is different on Windows x86 Rename ep_rt_bulk_type_value_init to ep_rt_bulk_type_value_clear --- src/mono/mono/eventpipe/ep-rt-mono.c | 60 +++++----------------------- 1 file changed, 9 insertions(+), 51 deletions(-) diff --git a/src/mono/mono/eventpipe/ep-rt-mono.c b/src/mono/mono/eventpipe/ep-rt-mono.c index 307b79671ec8b2..45db3bf0efe0f9 100644 --- a/src/mono/mono/eventpipe/ep-rt-mono.c +++ b/src/mono/mono/eventpipe/ep-rt-mono.c @@ -2895,14 +2895,14 @@ typedef struct _BulkTypeValue { uint32_t c_type_parameters; intptr_t rg_type_parameters[k_size_of_type_parameter_array]; MonoType *rg_mono_type_parameters[k_size_of_type_parameter_array]; - ep_char8_t *s_name; + ep_char8_t *s_name; // Currently should only be NULL, TODO if we want to provide the name in the BulkTypeEvent data, figure out memory management to use } BulkTypeValue; // Clear out BulkTypeValue before filling it out (array elements can get reused if there // are enough types that we need to flush to multiple events). static void -ep_rt_bulk_type_value_init(BulkTypeValue *bulk_type_value) +ep_rt_bulk_type_value_clear(BulkTypeValue *bulk_type_value) { bulk_type_value->fixed_sized_data.type_id = 0; bulk_type_value->fixed_sized_data.module_id = 0; @@ -2912,8 +2912,7 @@ ep_rt_bulk_type_value_init(BulkTypeValue *bulk_type_value) bulk_type_value->c_type_parameters = 0; memset(bulk_type_value->rg_type_parameters, 0, k_size_of_type_parameter_array); memset(bulk_type_value->rg_mono_type_parameters, 0, k_size_of_type_parameter_array); - if (bulk_type_value->s_name) - bulk_type_value->s_name[0] = '\0'; + bulk_type_value->s_name = NULL; } static @@ -2922,10 +2921,6 @@ ep_rt_mono_get_byte_count_in_event(BulkTypeValue *bulk_type_value) { size_t s_name_len = 0; - if (bulk_type_value->s_name) - while (bulk_type_value->s_name [s_name_len]) - s_name_len++; - return sizeof(bulk_type_value->fixed_sized_data.type_id) + // sizeof(bulk_type_value->fixed_sized_data) + sizeof(bulk_type_value->fixed_sized_data.module_id) + @@ -2973,8 +2968,6 @@ BulkTypeEventLogger* ep_rt_bulk_type_event_logger_init() { BulkTypeEventLogger *p_type_logger = g_malloc0 (sizeof(BulkTypeEventLogger)); - for (int i = 0; i < k_max_count_type_values; i++) - ep_rt_bulk_type_value_init (&p_type_logger->m_rg_bulk_type_values[i]); p_type_logger->m_p_bulk_type_event_buffer = g_malloc0 (sizeof(uint8_t) * k_size_of_event_buffer); return p_type_logger; } @@ -3024,13 +3017,6 @@ write_event_buffer_int64 (int64_t val, char *buf_start, char **buf_next) return write_event_buffer ((const uint8_t *)&val, sizeof (int64_t), buf_start, buf_next); } -static -int -write_event_buffer_intptr (intptr_t val, char *buf_start, char **buf_next) -{ - return write_event_buffer ((const uint8_t *)&val, sizeof (intptr_t), buf_start, buf_next); -} - static int write_event_buffer_utf16_str (gunichar2 *value, char *buf_start, char **buf_next) @@ -3059,8 +3045,6 @@ ep_rt_mono_fire_bulk_type_event (BulkTypeEventLogger *p_type_logger) if (p_type_logger->m_n_bulk_type_value_count == 0) return; - mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_DIAGNOSTICS, "Firing BulkTypeEvent!"); - uint16_t n_clr_instance_id = clr_instance_get_id(); uint32_t i_size = 0; @@ -3069,7 +3053,6 @@ ep_rt_mono_fire_bulk_type_event (BulkTypeEventLogger *p_type_logger) for (int i_type_data = 0; i_type_data < p_type_logger->m_n_bulk_type_value_count; i_type_data++) { - mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_DIAGNOSTICS, "TypeData[%lu]\n", i_type_data); BulkTypeValue *target = &p_type_logger->m_rg_bulk_type_values[i_type_data]; i_size += write_event_buffer_int64 (target->fixed_sized_data.type_id, ptr, &ptr); @@ -3078,34 +3061,17 @@ ep_rt_mono_fire_bulk_type_event (BulkTypeEventLogger *p_type_logger) i_size += write_event_buffer_int32 (target->fixed_sized_data.flags, ptr, &ptr); i_size += write_event_buffer_int8 (target->fixed_sized_data.cor_element_type, ptr, &ptr); - mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_DIAGNOSTICS, "FSB\ntype_id: %lu\nmodule_id: %lu\ntype_name_id: %lu\nflags: %lu\ncor_element_type: %lu\n", target->fixed_sized_data.type_id, target->fixed_sized_data.module_id, target->fixed_sized_data.type_name_id, target->fixed_sized_data.flags, target->fixed_sized_data.cor_element_type); - - gunichar2 *wsz_name = g_utf8_to_utf16 (target->s_name, -1, NULL, NULL, NULL); - if (!wsz_name) - { - i_size += write_event_buffer_int16 (0, ptr, &ptr); - } - else - { - i_size += write_event_buffer_utf16_str (wsz_name, ptr, &ptr); - g_free (wsz_name); - } + g_assert (target->s_name == NULL); + i_size += write_event_buffer_int16 (0, ptr, &ptr); i_size += write_event_buffer_int32 (target->c_type_parameters, ptr, &ptr); - mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_DIAGNOSTICS, "c_type_parameters: %lu\n", target->c_type_parameters); for (int i = 0; i < target->c_type_parameters; i++) { - i_size += write_event_buffer_intptr (target->rg_type_parameters[i], ptr, &ptr); - } - for (int i = 0; i < target->c_type_parameters; i++) - { - mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_DIAGNOSTICS, "target->rg_mono_type_parameters[%lu]: %lu\n", i, target->rg_mono_type_parameters[i]); - mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_DIAGNOSTICS, "target->rg_type_parameters[%lu]: %lu\n", i, target->rg_type_parameters[i]); + i_size += write_event_buffer_int64 ((int64_t)target->rg_type_parameters[i], ptr, &ptr); } } - mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_DIAGNOSTICS, "Count: %lu\nClrInstanceID: %lu\nValues_ElementSize: %lu\n", p_type_logger->m_n_bulk_type_value_count, n_clr_instance_id, i_size); FireEtwBulkType(p_type_logger->m_n_bulk_type_value_count, n_clr_instance_id, i_size, @@ -3174,7 +3140,7 @@ ep_rt_mono_log_single_type (BulkTypeEventLogger *p_type_logger, MonoType *mono_t EP_ASSERT (p_type_logger->m_n_bulk_type_value_count < k_max_count_type_values); BulkTypeValue *p_val = &p_type_logger->m_rg_bulk_type_values[p_type_logger->m_n_bulk_type_value_count]; - ep_rt_bulk_type_value_init (p_val); + ep_rt_bulk_type_value_clear (p_val); MonoClass *klass = mono_class_from_mono_type_internal (mono_type); MonoType *mono_underlying_type = mono_type_get_underlying_type (mono_type); @@ -3182,7 +3148,7 @@ ep_rt_mono_log_single_type (BulkTypeEventLogger *p_type_logger, MonoType *mono_t // Initialize p_val fixed_sized_data p_val->fixed_sized_data.type_id = (uint64_t)type_id; p_val->fixed_sized_data.module_id = (uint64_t)m_class_get_image (klass); - p_val->fixed_sized_data.type_name_id = mono_metadata_make_token (MONO_TABLE_TYPEDEF, mono_metadata_token_index (m_class_get_type_token (klass))); + p_val->fixed_sized_data.type_name_id = m_class_get_type_token (klass) ? mono_metadata_make_token (MONO_TABLE_TYPEDEF, mono_metadata_token_index (m_class_get_type_token (klass))) : 0; if (mono_class_has_finalizer (klass)) p_val->fixed_sized_data.flags |= K_ETW_TYPE_FLAGS_FINALIZABLE; if (m_class_is_delegate (klass)) @@ -3252,15 +3218,13 @@ ep_rt_mono_log_single_type (BulkTypeEventLogger *p_type_logger, MonoType *mono_t int cb_val = ep_rt_mono_get_byte_count_in_event(p_val); if (cb_val > k_max_bytes_type_values) { - if (p_val->s_name) - p_val->s_name[0] = '\0'; cb_val = ep_rt_mono_get_byte_count_in_event(p_val); if (cb_val > k_max_bytes_type_values) { // This type is apparently so huge, it's too big to squeeze into an event, even // if it were the only type batched in the whole event. Bail - mono_trace (G_LOG_LEVEL_ERROR, MONO_TRACE_DIAGNOSTICS, "Failed to log single mono type %lu with typeID %lu. Type is too large for the BulkType Event.\n", mono_type, type_id); + mono_trace (G_LOG_LEVEL_ERROR, MONO_TRACE_DIAGNOSTICS, "Failed to log single mono type %p with typeID %p. Type is too large for the BulkType Event.\n", (gpointer)mono_type, type_id); return -1; } } @@ -3277,11 +3241,6 @@ ep_rt_mono_log_single_type (BulkTypeEventLogger *p_type_logger, MonoType *mono_t ep_rt_mono_fire_bulk_type_event(p_type_logger); return ep_rt_mono_log_single_type(p_type_logger, mono_type, type_id); } - mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_DIAGNOSTICS, "p_val added at index: %lu\ntype_id: %lu\nmodule_id: %lu\ntype_name_id: %lu\ntype: %lu\nc_type_parameters: %lu", p_type_logger->m_n_bulk_type_value_count, p_val->fixed_sized_data.type_id, p_val->fixed_sized_data.module_id, p_val->fixed_sized_data.type_name_id, mono_underlying_type->type, p_val->c_type_parameters); - for (int i = 0; i < p_val->c_type_parameters; i++) - { - mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_DIAGNOSTICS, "type: %lu\n", ((MonoType*)p_val->rg_type_parameters[i])->type); - } // The type fits into the batch, so update our state p_type_logger->m_n_bulk_type_value_count++; @@ -3417,7 +3376,6 @@ ep_rt_mono_send_method_details_event (MonoMethod *method) ep_rt_mono_fire_bulk_type_event(p_type_logger); - mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_DIAGNOSTICS, "Firing Method: %s\n%s[%lu]\ntype ID [%lu]\nToken %lu -> %lu\nNumParam %lu\nmodule %lu\n", mono_method_get_full_name (method), method->name, (uint64_t)method, method_type_id, method->token, method_token, method_inst_parameter_types_count, loader_module_id); FireEtwMethodDetails((uint64_t)method, (uint64_t)method_type_id, method_token, From 5001aaf5014e4e5e8ee7a737dda68767b732a57c Mon Sep 17 00:00:00 2001 From: mdh1418 Date: Thu, 5 May 2022 18:17:17 -0400 Subject: [PATCH 19/28] Utilize macros for array size initialization Cleanup formatting and style Remove unused write_event_buffer_utf16_str Add BulkTypeEventLogger pointer to function description --- src/mono/mono/eventpipe/ep-rt-mono.c | 325 ++++++++++++++++----------- src/mono/mono/eventpipe/ep-rt-mono.h | 15 +- 2 files changed, 206 insertions(+), 134 deletions(-) diff --git a/src/mono/mono/eventpipe/ep-rt-mono.c b/src/mono/mono/eventpipe/ep-rt-mono.c index 45db3bf0efe0f9..d758386b6779e8 100644 --- a/src/mono/mono/eventpipe/ep-rt-mono.c +++ b/src/mono/mono/eventpipe/ep-rt-mono.c @@ -2861,7 +2861,7 @@ ep_rt_mono_write_event_ee_startup_start (void) // The maximum number of type parameters for a BulkTypeValue instance // Aligned with coreCLR StackSArray rgTypeParameters -static const uint32_t k_size_of_type_parameter_array = STACK_ALLOC / sizeof(intptr_t); +#define K_SIZE_OF_TYPE_PARAMETER_ARRAY ((uint32_t)(STACK_ALLOC / sizeof (intptr_t))) // !!!!!!! NOTE !!!!!!!! // The flags must match those in the ETW manifest exactly @@ -2893,16 +2893,76 @@ typedef struct _EventStructBulkTypeFixedSizedData { typedef struct _BulkTypeValue { EventStructBulkTypeFixedSizedData fixed_sized_data; uint32_t c_type_parameters; - intptr_t rg_type_parameters[k_size_of_type_parameter_array]; - MonoType *rg_mono_type_parameters[k_size_of_type_parameter_array]; + intptr_t rg_type_parameters [K_SIZE_OF_TYPE_PARAMETER_ARRAY]; + MonoType *rg_mono_type_parameters [K_SIZE_OF_TYPE_PARAMETER_ARRAY]; ep_char8_t *s_name; // Currently should only be NULL, TODO if we want to provide the name in the BulkTypeEvent data, figure out memory management to use } BulkTypeValue; +static +void +ep_rt_bulk_type_value_clear (BulkTypeValue *bulk_type_value); + +static +uint32_t +ep_rt_mono_get_byte_count_in_event (BulkTypeValue *bulk_type_value); + +static +BulkTypeEventLogger* +ep_rt_bulk_type_event_logger_init (void); + +static +void +ep_rt_bulk_type_event_logger_fini (BulkTypeEventLogger *p_type_logger); + +static +int +write_event_buffer ( + const uint8_t *val, + size_t size, + char *buf_start, + char **buf_next); + +static +int +write_event_buffer_int8 ( + int8_t val, + char *buf_start, + char **buf_next); + +static +int +write_event_buffer_int16 ( + int16_t val, + char *buf_start, + char **buf_next); + +static +int +write_event_buffer_int32 ( + int32_t val, + char *buf_start, + char **buf_next); + +static +int +write_event_buffer_int64 ( + int64_t val, + char *buf_start, + char **buf_next); + +static +intptr_t +get_typeid_for_type (MonoType *t); + +static +intptr_t +get_typeid_for_class (MonoClass *c); + // Clear out BulkTypeValue before filling it out (array elements can get reused if there // are enough types that we need to flush to multiple events). static void -ep_rt_bulk_type_value_clear(BulkTypeValue *bulk_type_value) +ep_rt_bulk_type_value_clear (BulkTypeValue *bulk_type_value) { bulk_type_value->fixed_sized_data.type_id = 0; bulk_type_value->fixed_sized_data.module_id = 0; @@ -2910,40 +2970,39 @@ ep_rt_bulk_type_value_clear(BulkTypeValue *bulk_type_value) bulk_type_value->fixed_sized_data.flags = 0; bulk_type_value->fixed_sized_data.cor_element_type = 0; bulk_type_value->c_type_parameters = 0; - memset(bulk_type_value->rg_type_parameters, 0, k_size_of_type_parameter_array); - memset(bulk_type_value->rg_mono_type_parameters, 0, k_size_of_type_parameter_array); + memset (bulk_type_value->rg_type_parameters, 0, K_SIZE_OF_TYPE_PARAMETER_ARRAY); + memset (bulk_type_value->rg_mono_type_parameters, 0, K_SIZE_OF_TYPE_PARAMETER_ARRAY); bulk_type_value->s_name = NULL; } static uint32_t -ep_rt_mono_get_byte_count_in_event(BulkTypeValue *bulk_type_value) +ep_rt_mono_get_byte_count_in_event (BulkTypeValue *bulk_type_value) { size_t s_name_len = 0; - return - sizeof(bulk_type_value->fixed_sized_data.type_id) + // sizeof(bulk_type_value->fixed_sized_data) + - sizeof(bulk_type_value->fixed_sized_data.module_id) + - sizeof(bulk_type_value->fixed_sized_data.type_name_id) + - sizeof(bulk_type_value->fixed_sized_data.flags) + - sizeof(bulk_type_value->fixed_sized_data.cor_element_type) + - sizeof(bulk_type_value->c_type_parameters) + // Type parameters - (s_name_len + 1) * sizeof(ep_char8_t) + // Size of name, including null terminator - bulk_type_value->c_type_parameters * sizeof(uint64_t); // Type parameters + return sizeof (bulk_type_value->fixed_sized_data.type_id) + // Fixed Sized Data + sizeof (bulk_type_value->fixed_sized_data.module_id) + + sizeof (bulk_type_value->fixed_sized_data.type_name_id) + + sizeof (bulk_type_value->fixed_sized_data.flags) + + sizeof (bulk_type_value->fixed_sized_data.cor_element_type) + + sizeof (bulk_type_value->c_type_parameters) + // Type parameters + (s_name_len + 1) * sizeof (ep_char8_t) + // Size of name, including null terminator + bulk_type_value->c_type_parameters * sizeof (uint64_t); // Type parameters } // ETW has a limitation of 64K for TOTAL event Size, however there is overhead associated with // the event headers. It is unclear exactly how much that is, but 1K should be sufficiently // far away to avoid problems without sacrificing the perf of bulk processing. -static const uint32_t cb_max_etw_event = 63 * 1024; +static const uint32_t CB_MAX_ETW_EVENT = 63 * 1024; // The maximum event size, and the size of the buffer that we allocate to hold the event contents. -static const size_t k_size_of_event_buffer = 65536; +static const size_t K_SIZE_OF_EVENT_BUFFER = 65536; // Estimate of how many bytes we can squeeze in the event data for the value struct -// array. (Intentionally overestimate the size of the non-array parts to keep it safe.) +// array. (Intentionally overestimate the size of the non-array parts to keep it safe.) // This follows CoreCLR's kMaxBytesTypeValues. -static const uint32_t k_max_bytes_type_values = (cb_max_etw_event - 0x30); +static const uint32_t K_MAX_BYTES_TYPE_VALUES = (CB_MAX_ETW_EVENT - 0x30); // Estimate of how many type value elements we can put into the struct array, while // staying under the ETW event size limit. Note that this is impossible to calculate @@ -2954,10 +3013,10 @@ static const uint32_t k_max_bytes_type_values = (cb_max_etw_event - 0x30); // far sooner. There's a max number of 128 descriptors allowed per event. 2 are used // for Count + ClrInstanceID. Then 4 per batched value. (Might actually be 3 if there // are no type parameters to log, but let's overestimate at 4 per value). -static const uint32_t k_max_count_type_values = (128 - 2) / 4; +#define K_MAX_COUNT_TYPE_VALUES ((uint32_t)(128 - 2) / 4) struct _BulkTypeEventLogger { - BulkTypeValue m_rg_bulk_type_values[k_max_count_type_values]; + BulkTypeValue m_rg_bulk_type_values [K_MAX_COUNT_TYPE_VALUES]; uint32_t m_n_bulk_type_value_count; uint32_t m_n_bulk_type_value_byte_count; uint8_t *m_p_bulk_type_event_buffer; @@ -2965,16 +3024,16 @@ struct _BulkTypeEventLogger { static BulkTypeEventLogger* -ep_rt_bulk_type_event_logger_init() +ep_rt_bulk_type_event_logger_init () { - BulkTypeEventLogger *p_type_logger = g_malloc0 (sizeof(BulkTypeEventLogger)); - p_type_logger->m_p_bulk_type_event_buffer = g_malloc0 (sizeof(uint8_t) * k_size_of_event_buffer); + BulkTypeEventLogger *p_type_logger = g_malloc0 (sizeof (BulkTypeEventLogger)); + p_type_logger->m_p_bulk_type_event_buffer = g_malloc0 (sizeof (uint8_t) * K_SIZE_OF_EVENT_BUFFER); return p_type_logger; } static void -ep_rt_bulk_type_event_logger_fini(BulkTypeEventLogger *p_type_logger) +ep_rt_bulk_type_event_logger_fini (BulkTypeEventLogger *p_type_logger) { g_free (p_type_logger->m_p_bulk_type_event_buffer); g_free (p_type_logger); @@ -2982,7 +3041,11 @@ ep_rt_bulk_type_event_logger_fini(BulkTypeEventLogger *p_type_logger) static int -write_event_buffer (const uint8_t *val, size_t size, char *buf_start, char **buf_next) +write_event_buffer ( + const uint8_t *val, + size_t size, + char *buf_start, + char **buf_next) { memcpy (buf_start, val, size); *buf_next = buf_start + size; @@ -2991,46 +3054,44 @@ write_event_buffer (const uint8_t *val, size_t size, char *buf_start, char **buf static int -write_event_buffer_int8 (int8_t val, char *buf_start, char **buf_next) +write_event_buffer_int8 ( + int8_t val, + char *buf_start, + char **buf_next) { return write_event_buffer ((const uint8_t *)&val, sizeof (int8_t), buf_start, buf_next); } static int -write_event_buffer_int16 (int16_t val, char *buf_start, char **buf_next) +write_event_buffer_int16 ( + int16_t val, + char *buf_start, + char **buf_next) { return write_event_buffer ((const uint8_t *)&val, sizeof (int16_t), buf_start, buf_next); } static int -write_event_buffer_int32 (int32_t val, char *buf_start, char **buf_next) +write_event_buffer_int32 ( + int32_t val, + char *buf_start, + char **buf_next) { return write_event_buffer ((const uint8_t *)&val, sizeof (int32_t), buf_start, buf_next); } static int -write_event_buffer_int64 (int64_t val, char *buf_start, char **buf_next) +write_event_buffer_int64 ( + int64_t val, + char *buf_start, + char **buf_next) { return write_event_buffer ((const uint8_t *)&val, sizeof (int64_t), buf_start, buf_next); } -static -int -write_event_buffer_utf16_str (gunichar2 *value, char *buf_start, char **buf_next) -{ - if (!value) - return 0; - - size_t value_len = 0; - while (value [value_len]) - value_len++; - - return write_event_buffer ((const uint8_t *)value, (value_len + 1) * sizeof(*value), buf_start, buf_next); -} - //--------------------------------------------------------------------------------------- // // ep_rt_mono_fire_bulk_type_event fires an ETW event for all the types batched so far, @@ -3045,15 +3106,14 @@ ep_rt_mono_fire_bulk_type_event (BulkTypeEventLogger *p_type_logger) if (p_type_logger->m_n_bulk_type_value_count == 0) return; - uint16_t n_clr_instance_id = clr_instance_get_id(); + uint16_t n_clr_instance_id = clr_instance_get_id (); uint32_t i_size = 0; char *ptr = (char *)p_type_logger->m_p_bulk_type_event_buffer; - for (int i_type_data = 0; i_type_data < p_type_logger->m_n_bulk_type_value_count; i_type_data++) - { - BulkTypeValue *target = &p_type_logger->m_rg_bulk_type_values[i_type_data]; + for (int i_type_data = 0; i_type_data < p_type_logger->m_n_bulk_type_value_count; i_type_data++) { + BulkTypeValue *target = &p_type_logger->m_rg_bulk_type_values [i_type_data]; i_size += write_event_buffer_int64 (target->fixed_sized_data.type_id, ptr, &ptr); i_size += write_event_buffer_int64 (target->fixed_sized_data.module_id, ptr, &ptr); @@ -3067,19 +3127,18 @@ ep_rt_mono_fire_bulk_type_event (BulkTypeEventLogger *p_type_logger) i_size += write_event_buffer_int32 (target->c_type_parameters, ptr, &ptr); for (int i = 0; i < target->c_type_parameters; i++) - { - i_size += write_event_buffer_int64 ((int64_t)target->rg_type_parameters[i], ptr, &ptr); - } + i_size += write_event_buffer_int64 ((int64_t)target->rg_type_parameters [i], ptr, &ptr); } - FireEtwBulkType(p_type_logger->m_n_bulk_type_value_count, - n_clr_instance_id, - i_size, - p_type_logger->m_p_bulk_type_event_buffer, - NULL, - NULL); + FireEtwBulkType ( + p_type_logger->m_n_bulk_type_value_count, + n_clr_instance_id, + i_size, + p_type_logger->m_p_bulk_type_event_buffer, + NULL, + NULL); - memset (p_type_logger->m_p_bulk_type_event_buffer, 0, sizeof(uint8_t) * k_size_of_event_buffer); + memset (p_type_logger->m_p_bulk_type_event_buffer, 0, sizeof (uint8_t) * K_SIZE_OF_EVENT_BUFFER); p_type_logger->m_n_bulk_type_value_count = 0; p_type_logger->m_n_bulk_type_value_byte_count = 0; } @@ -3088,7 +3147,7 @@ ep_rt_mono_fire_bulk_type_event (BulkTypeEventLogger *p_type_logger) // // get_typeid_for_type is responsible for obtaining the unique type identifier for a // particular MonoType. MonoTypes are structs that are not unique pointers. There -// can be two different MonoTypes that both System.Thread or int32 or bool[]. There +// can be two different MonoTypes that both System.Thread or int32 or bool []. There // is exactly one MonoClass * for any type, so we leverage the MonoClass a MonoType // points to in order to obtain a unique type identifier in mono. With that unique // MonoClass, its fields this_arg and _byval_arg are unique as well. @@ -3099,16 +3158,20 @@ ep_rt_mono_fire_bulk_type_event (BulkTypeEventLogger *p_type_logger) // Return Value: // type_id - Unique type identifier of mono_type -static intptr_t -get_typeid_for_type (MonoType *t) { +static +intptr_t +get_typeid_for_type (MonoType *t) +{ if (m_type_is_byref (t)) return (intptr_t)m_class_get_this_arg (mono_class_from_mono_type_internal (t)); else return (intptr_t)m_class_get_byval_arg (mono_class_from_mono_type_internal (t)); } -static intptr_t -get_typeid_for_class (MonoClass *c) { +static +intptr_t +get_typeid_for_class (MonoClass *c) +{ return get_typeid_for_type (m_class_get_byval_arg (c)); } @@ -3122,6 +3185,7 @@ get_typeid_for_class (MonoClass *c) { // deal with type parameters. // // Arguments: +// * p_type_logger - BulkTypeEventLogger instance // * mono_type - MonoType to be logged // * type_id - Unique type identifier of mono_type // @@ -3131,15 +3195,18 @@ get_typeid_for_class (MonoClass *c) { // This follows CoreCLR's BulkTypeEventLogger::LogSingleType int -ep_rt_mono_log_single_type (BulkTypeEventLogger *p_type_logger, MonoType *mono_type, intptr_t type_id) +ep_rt_mono_log_single_type ( + BulkTypeEventLogger *p_type_logger, + MonoType *mono_type, + intptr_t type_id) { // If there's no room for another type, flush what we've got - if (p_type_logger->m_n_bulk_type_value_count == k_max_count_type_values) + if (p_type_logger->m_n_bulk_type_value_count == K_MAX_COUNT_TYPE_VALUES) ep_rt_mono_fire_bulk_type_event (p_type_logger); - EP_ASSERT (p_type_logger->m_n_bulk_type_value_count < k_max_count_type_values); + EP_ASSERT (p_type_logger->m_n_bulk_type_value_count < K_MAX_COUNT_TYPE_VALUES); - BulkTypeValue *p_val = &p_type_logger->m_rg_bulk_type_values[p_type_logger->m_n_bulk_type_value_count]; + BulkTypeValue *p_val = &p_type_logger->m_rg_bulk_type_values [p_type_logger->m_n_bulk_type_value_count]; ep_rt_bulk_type_value_clear (p_val); MonoClass *klass = mono_class_from_mono_type_internal (mono_type); @@ -3166,22 +3233,20 @@ ep_rt_mono_log_single_type (BulkTypeEventLogger *p_type_logger, MonoType *mono_t { MonoArrayType *mono_array_type = mono_type_get_array_type (mono_type); p_val->fixed_sized_data.flags |= K_ETW_TYPE_FLAGS_ARRAY; - if (mono_underlying_type->type == MONO_TYPE_ARRAY) - { + if (mono_underlying_type->type == MONO_TYPE_ARRAY) { // Only ranks less than kEtwTypeFlagsArrayRankMax are supported. // Fortunately kEtwTypeFlagsArrayRankMax should be greater than the // number of ranks the type loader will support uint32_t rank = mono_array_type->rank; - if (rank < K_ETW_TYPE_FLAGS_ARRAY_RANK_MAX) - { + if (rank < K_ETW_TYPE_FLAGS_ARRAY_RANK_MAX) { rank <<= 8; p_val->fixed_sized_data.flags |= rank; } } // mono arrays are always arrays of by value types - p_val->rg_mono_type_parameters[p_val->c_type_parameters] = m_class_get_byval_arg (mono_array_type->eklass); - p_val->rg_type_parameters[p_val->c_type_parameters] = get_typeid_for_class (mono_array_type->eklass); + p_val->rg_mono_type_parameters [p_val->c_type_parameters] = m_class_get_byval_arg (mono_array_type->eklass); + p_val->rg_type_parameters [p_val->c_type_parameters] = get_typeid_for_class (mono_array_type->eklass); p_val->c_type_parameters++; break; } @@ -3189,10 +3254,9 @@ ep_rt_mono_log_single_type (BulkTypeEventLogger *p_type_logger, MonoType *mono_t { MonoGenericInst *class_inst = mono_type->data.generic_class->context.class_inst; p_val->c_type_parameters = class_inst->type_argc; - for (int i = 0; i < class_inst->type_argc; i++) - { - p_val->rg_mono_type_parameters[i] = class_inst->type_argv[i]; - p_val->rg_type_parameters[i] = get_typeid_for_type (class_inst->type_argv[i]); + for (int i = 0; i < class_inst->type_argc; i++) { + p_val->rg_mono_type_parameters [i] = class_inst->type_argv [i]; + p_val->rg_type_parameters [i] = get_typeid_for_type (class_inst->type_argv [i]); } break; } @@ -3201,12 +3265,11 @@ ep_rt_mono_log_single_type (BulkTypeEventLogger *p_type_logger, MonoType *mono_t case MONO_TYPE_PTR: case MONO_TYPE_BYREF: { - if (mono_underlying_type != mono_type) - { - p_val->rg_mono_type_parameters[p_val->c_type_parameters] = mono_type_get_underlying_type (mono_type); - p_val->rg_type_parameters[p_val->c_type_parameters] = get_typeid_for_type (mono_type_get_underlying_type (mono_type)); - p_val->c_type_parameters++; - } + if (mono_underlying_type == mono_type) + break; + p_val->rg_mono_type_parameters [p_val->c_type_parameters] = mono_type_get_underlying_type (mono_type); + p_val->rg_type_parameters [p_val->c_type_parameters] = get_typeid_for_type (mono_type_get_underlying_type (mono_type)); + p_val->c_type_parameters++; break; } default: @@ -3215,31 +3278,28 @@ ep_rt_mono_log_single_type (BulkTypeEventLogger *p_type_logger, MonoType *mono_t // Now that we know the full size of this type's data, see if it fits in our // batch or whether we need to flush - int cb_val = ep_rt_mono_get_byte_count_in_event(p_val); - if (cb_val > k_max_bytes_type_values) - { - cb_val = ep_rt_mono_get_byte_count_in_event(p_val); + int cb_val = ep_rt_mono_get_byte_count_in_event (p_val); + if (cb_val > K_MAX_BYTES_TYPE_VALUES) { + cb_val = ep_rt_mono_get_byte_count_in_event (p_val); - if (cb_val > k_max_bytes_type_values) - { + if (cb_val > K_MAX_BYTES_TYPE_VALUES) { // This type is apparently so huge, it's too big to squeeze into an event, even // if it were the only type batched in the whole event. Bail - mono_trace (G_LOG_LEVEL_ERROR, MONO_TRACE_DIAGNOSTICS, "Failed to log single mono type %p with typeID %p. Type is too large for the BulkType Event.\n", (gpointer)mono_type, type_id); + mono_trace (G_LOG_LEVEL_ERROR, MONO_TRACE_DIAGNOSTICS, "Failed to log single mono type %p with typeID %p. Type is too large for the BulkType Event.\n", (gpointer)mono_type, (gpointer)type_id); return -1; } } - if (p_type_logger->m_n_bulk_type_value_byte_count + cb_val > k_max_bytes_type_values) - { + if (p_type_logger->m_n_bulk_type_value_byte_count + cb_val > K_MAX_BYTES_TYPE_VALUES) { // Although this type fits into the array, its size is so big that the entire // array can't be logged via ETW. So flush the array, and start over by // calling ourselves--this refetches the type info and puts it at the // beginning of the array. Since we know this type is small enough to be // batched into an event on its own, this recursive call will not try to // call itself again. - g_assert (p_type_logger->m_n_bulk_type_value_byte_count + cb_val > k_max_bytes_type_values); - ep_rt_mono_fire_bulk_type_event(p_type_logger); - return ep_rt_mono_log_single_type(p_type_logger, mono_type, type_id); + g_assert (p_type_logger->m_n_bulk_type_value_byte_count + cb_val > K_MAX_BYTES_TYPE_VALUES); + ep_rt_mono_fire_bulk_type_event (p_type_logger); + return ep_rt_mono_log_single_type (p_type_logger, mono_type, type_id); } // The type fits into the batch, so update our state @@ -3254,41 +3314,43 @@ ep_rt_mono_log_single_type (BulkTypeEventLogger *p_type_logger, MonoType *mono_t // ETW as needed. This is called by ep_rt_mono_log_type_and_parameters_if_necessary. // // Arguments: +// * p_type_logger - BulkTypeEventLogger instance // * mono_type - MonoType to be logged // * type_id - Unique type identifier of mono_type to batch // // This follows CoreCLR's BulkTypeEventLogger::LogTypeAndParameter void -ep_rt_mono_log_type_and_parameters (BulkTypeEventLogger *p_type_logger, MonoType *mono_type, intptr_t type_id) +ep_rt_mono_log_type_and_parameters ( + BulkTypeEventLogger *p_type_logger, + MonoType *mono_type, + intptr_t type_id) { // Batch up this type. This grabs useful info about the type, including any // type parameters it may have, and sticks it in m_rg_bulk_type_values int i_bulk_type_event_data = ep_rt_mono_log_single_type (p_type_logger, mono_type, type_id); - if (i_bulk_type_event_data == -1) - { + if (i_bulk_type_event_data == -1) { // There was a failure trying to log the type, so don't bother with its type // parameters return; } // Look at the type info we just batched, so we can get the type parameters - BulkTypeValue *p_val = &p_type_logger->m_rg_bulk_type_values[i_bulk_type_event_data]; + BulkTypeValue *p_val = &p_type_logger->m_rg_bulk_type_values [i_bulk_type_event_data]; // We're about to recursively call ourselves for the type parameters, so make a // local copy of their type handles first (else, as we log them we could flush // and clear out m_rg_bulk_type_values, thus trashing p_val) uint32_t c_params = p_val->c_type_parameters; - intptr_t rg_type_parameters[k_size_of_type_parameter_array]; - MonoType *rg_mono_type_parameters[k_size_of_type_parameter_array]; - for (uint32_t i = 0; i < c_params; i++) - { - rg_type_parameters[i] = p_val->rg_type_parameters[i]; - rg_mono_type_parameters[i] = p_val->rg_mono_type_parameters[i]; + intptr_t rg_type_parameters [K_SIZE_OF_TYPE_PARAMETER_ARRAY]; + MonoType *rg_mono_type_parameters [K_SIZE_OF_TYPE_PARAMETER_ARRAY]; + for (uint32_t i = 0; i < c_params; i++) { + rg_type_parameters [i] = p_val->rg_type_parameters [i]; + rg_mono_type_parameters [i] = p_val->rg_mono_type_parameters [i]; } for (uint32_t i = 0; i < c_params; i++) - ep_rt_mono_log_type_and_parameters_if_necessary (p_type_logger, rg_mono_type_parameters[i], rg_type_parameters[i]); + ep_rt_mono_log_type_and_parameters_if_necessary (p_type_logger, rg_mono_type_parameters [i], rg_type_parameters [i]); } //--------------------------------------------------------------------------------------- @@ -3297,14 +3359,17 @@ ep_rt_mono_log_type_and_parameters (BulkTypeEventLogger *p_type_logger, MonoType // (in this case a MonoType) and (recursively) its type parameters when present. // // Arguments: +// * p_type_logger - BulkTypeEventLogger instance // * mono_type - MonoType to be logged // * type_id - Unique type identifier of mono_type // // This follows CoreCLR's BulkTypeEventLogger::LogTypeAndParameters -// static void -ep_rt_mono_log_type_and_parameters_if_necessary (BulkTypeEventLogger *p_type_logger, MonoType *mono_type, intptr_t type_id) +ep_rt_mono_log_type_and_parameters_if_necessary ( + BulkTypeEventLogger *p_type_logger, + MonoType *mono_type, + intptr_t type_id) { // TODO Log the type if necessary @@ -3312,7 +3377,7 @@ ep_rt_mono_log_type_and_parameters_if_necessary (BulkTypeEventLogger *p_type_log } // ETW has a limit for maximum event size. Do not log overly large method type argument sets -static const uint32_t k_max_method_type_argument_count = 1024; +static const uint32_t K_MAX_METHOD_TYPE_ARGUMENT_COUNT = 1024; //--------------------------------------------------------------------------------------- // @@ -3335,25 +3400,23 @@ ep_rt_mono_send_method_details_event (MonoMethod *method) if (method->wrapper_type != MONO_WRAPPER_NONE || method->dynamic) return; - MonoGenericContext *method_ctx = mono_method_get_context(method); + MonoGenericContext *method_ctx = mono_method_get_context (method); MonoGenericInst *method_inst = NULL; if (method_ctx) method_inst = method_ctx->method_inst; - if (method_inst) - if (method_inst->type_argc > k_max_method_type_argument_count) - return; + if (method_inst && method_inst->type_argc > K_MAX_METHOD_TYPE_ARGUMENT_COUNT) + return; - BulkTypeEventLogger *p_type_logger = ep_rt_bulk_type_event_logger_init(); + BulkTypeEventLogger *p_type_logger = ep_rt_bulk_type_event_logger_init (); intptr_t method_type_id = 0; g_assert (mono_metadata_token_index (method->token) != 0); uint32_t method_token = mono_metadata_make_token (MONO_TABLE_METHOD, mono_metadata_token_index (method->token)); uint64_t loader_module_id = 0; MonoClass *klass = method->klass; - if (klass) - { + if (klass) { MonoType *method_mono_type = m_class_get_byval_arg (klass); method_type_id = get_typeid_for_class (klass); @@ -3366,24 +3429,24 @@ ep_rt_mono_send_method_details_event (MonoMethod *method) if (method_inst) method_inst_parameter_types_count = method_inst->type_argc; - intptr_t method_inst_parameters_type_ids[method_inst_parameter_types_count]; - for (int i = 0; i < method_inst_parameter_types_count; i++) - { - method_inst_parameters_type_ids[i] = get_typeid_for_type (method_inst->type_argv[i]); + intptr_t method_inst_parameters_type_ids [method_inst_parameter_types_count]; + for (int 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_rt_mono_log_type_and_parameters_if_necessary (p_type_logger, method_inst->type_argv[i], method_inst_parameters_type_ids[i]); + ep_rt_mono_log_type_and_parameters_if_necessary (p_type_logger, method_inst->type_argv [i], method_inst_parameters_type_ids [i]); } - ep_rt_mono_fire_bulk_type_event(p_type_logger); + ep_rt_mono_fire_bulk_type_event (p_type_logger); - FireEtwMethodDetails((uint64_t)method, - (uint64_t)method_type_id, - method_token, - method_inst_parameter_types_count, - loader_module_id, - (uint64_t*)method_inst_parameters_type_ids, - NULL, - NULL); + FireEtwMethodDetails ( + (uint64_t)method, + (uint64_t)method_type_id, + method_token, + method_inst_parameter_types_count, + loader_module_id, + (uint64_t*)method_inst_parameters_type_ids, + NULL, + NULL); ep_rt_bulk_type_event_logger_fini (p_type_logger); } diff --git a/src/mono/mono/eventpipe/ep-rt-mono.h b/src/mono/mono/eventpipe/ep-rt-mono.h index ad1c5ae5a83305..915d609084f1bb 100644 --- a/src/mono/mono/eventpipe/ep-rt-mono.h +++ b/src/mono/mono/eventpipe/ep-rt-mono.h @@ -2185,13 +2185,22 @@ void ep_rt_mono_fire_bulk_type_event (BulkTypeEventLogger *p_type_logger); int -ep_rt_mono_log_single_type (BulkTypeEventLogger *p_type_logger, MonoType *mono_type, intptr_t type_id); +ep_rt_mono_log_single_type ( + BulkTypeEventLogger *p_type_logger, + MonoType *mono_type, + intptr_t type_id); void -ep_rt_mono_log_type_and_parameters (BulkTypeEventLogger *p_type_logger, MonoType *mono_type, intptr_t type_id); +ep_rt_mono_log_type_and_parameters ( + BulkTypeEventLogger *p_type_logger, + MonoType *mono_type, + intptr_t type_id); void -ep_rt_mono_log_type_and_parameters_if_necessary (BulkTypeEventLogger *p_type_logger, MonoType *mono_type, intptr_t type_id); +ep_rt_mono_log_type_and_parameters_if_necessary ( + BulkTypeEventLogger *p_type_logger, + MonoType *mono_type, + intptr_t type_id); void ep_rt_mono_send_method_details_event (MonoMethod *method); From 481716488b7f02501761fba08d25767d1da84456 Mon Sep 17 00:00:00 2001 From: mdh1418 Date: Thu, 5 May 2022 18:36:31 -0400 Subject: [PATCH 20/28] [mono] Mark mono_class_has_finalizer as MONO_COMPONENT_API --- src/mono/mono/metadata/class-internals.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mono/mono/metadata/class-internals.h b/src/mono/mono/metadata/class-internals.h index c0c447f71099c2..8574b19a17a0af 100644 --- a/src/mono/mono/metadata/class-internals.h +++ b/src/mono/mono/metadata/class-internals.h @@ -1226,7 +1226,7 @@ mono_class_get_fields_lazy (MonoClass* klass, gpointer *iter); gboolean mono_class_check_vtable_constraints (MonoClass *klass, GList *in_setup); -gboolean +MONO_COMPONENT_API gboolean mono_class_has_finalizer (MonoClass *klass); void From e3c9a65171f70ac53f7983fee0e2e26a715ebcce Mon Sep 17 00:00:00 2001 From: mdh1418 Date: Thu, 5 May 2022 18:36:31 -0400 Subject: [PATCH 21/28] Set global static const to macros Change ep_rt_mono_get_byte_count_in_event type --- src/mono/mono/eventpipe/ep-rt-mono.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/mono/mono/eventpipe/ep-rt-mono.c b/src/mono/mono/eventpipe/ep-rt-mono.c index d758386b6779e8..bd7b4179e95b5a 100644 --- a/src/mono/mono/eventpipe/ep-rt-mono.c +++ b/src/mono/mono/eventpipe/ep-rt-mono.c @@ -2903,7 +2903,7 @@ void ep_rt_bulk_type_value_clear (BulkTypeValue *bulk_type_value); static -uint32_t +int ep_rt_mono_get_byte_count_in_event (BulkTypeValue *bulk_type_value); static @@ -2976,10 +2976,10 @@ ep_rt_bulk_type_value_clear (BulkTypeValue *bulk_type_value) } static -uint32_t +int ep_rt_mono_get_byte_count_in_event (BulkTypeValue *bulk_type_value) { - size_t s_name_len = 0; + int s_name_len = 0; return sizeof (bulk_type_value->fixed_sized_data.type_id) + // Fixed Sized Data sizeof (bulk_type_value->fixed_sized_data.module_id) + @@ -2987,22 +2987,22 @@ ep_rt_mono_get_byte_count_in_event (BulkTypeValue *bulk_type_value) sizeof (bulk_type_value->fixed_sized_data.flags) + sizeof (bulk_type_value->fixed_sized_data.cor_element_type) + sizeof (bulk_type_value->c_type_parameters) + // Type parameters - (s_name_len + 1) * sizeof (ep_char8_t) + // Size of name, including null terminator + (s_name_len + 1) * sizeof (ep_char8_t) + // Size of name, including null terminator bulk_type_value->c_type_parameters * sizeof (uint64_t); // Type parameters } // ETW has a limitation of 64K for TOTAL event Size, however there is overhead associated with // the event headers. It is unclear exactly how much that is, but 1K should be sufficiently // far away to avoid problems without sacrificing the perf of bulk processing. -static const uint32_t CB_MAX_ETW_EVENT = 63 * 1024; +#define CB_MAX_ETW_EVENT (63 * 1024) // The maximum event size, and the size of the buffer that we allocate to hold the event contents. -static const size_t K_SIZE_OF_EVENT_BUFFER = 65536; +#define K_SIZE_OF_EVENT_BUFFER 65536 // Estimate of how many bytes we can squeeze in the event data for the value struct // array. (Intentionally overestimate the size of the non-array parts to keep it safe.) // This follows CoreCLR's kMaxBytesTypeValues. -static const uint32_t K_MAX_BYTES_TYPE_VALUES = (CB_MAX_ETW_EVENT - 0x30); +#define K_MAX_BYTES_TYPE_VALUES (CB_MAX_ETW_EVENT - 0x30) // Estimate of how many type value elements we can put into the struct array, while // staying under the ETW event size limit. Note that this is impossible to calculate @@ -3429,7 +3429,7 @@ ep_rt_mono_send_method_details_event (MonoMethod *method) if (method_inst) method_inst_parameter_types_count = method_inst->type_argc; - intptr_t method_inst_parameters_type_ids [method_inst_parameter_types_count]; + intptr_t method_inst_parameters_type_ids [K_MAX_METHOD_TYPE_ARGUMENT_COUNT]; for (int i = 0; i < method_inst_parameter_types_count; i++) { method_inst_parameters_type_ids [i] = get_typeid_for_type (method_inst->type_argv [i]); From 274b5eeee17a30308abcac9156579bcd69ebbe5f Mon Sep 17 00:00:00 2001 From: mdh1418 Date: Fri, 6 May 2022 12:28:27 -0400 Subject: [PATCH 22/28] Address feedback Drop variable prefixes Clear BulkTypeValue via memset Rename bulk_type_event_logger helpers to alloc and free Remove redundant bulk type value byte count calculation Utilize memcpy to copy type parameter arrays Reduce padding by moving bulk_type_event_buffer field in struct --- src/mono/mono/eventpipe/ep-rt-mono.c | 267 +++++++++++++-------------- 1 file changed, 127 insertions(+), 140 deletions(-) diff --git a/src/mono/mono/eventpipe/ep-rt-mono.c b/src/mono/mono/eventpipe/ep-rt-mono.c index bd7b4179e95b5a..9bd2b4e0c5e25d 100644 --- a/src/mono/mono/eventpipe/ep-rt-mono.c +++ b/src/mono/mono/eventpipe/ep-rt-mono.c @@ -2861,22 +2861,22 @@ ep_rt_mono_write_event_ee_startup_start (void) // The maximum number of type parameters for a BulkTypeValue instance // Aligned with coreCLR StackSArray rgTypeParameters -#define K_SIZE_OF_TYPE_PARAMETER_ARRAY ((uint32_t)(STACK_ALLOC / sizeof (intptr_t))) +#define MAX_SIZE_OF_TYPE_PARAMETER_ARRAY ((uint32_t)(STACK_ALLOC / sizeof (intptr_t))) // !!!!!!! NOTE !!!!!!!! // The flags must match those in the ETW manifest exactly // !!!!!!! NOTE !!!!!!!! typedef enum { - K_ETW_TYPE_FLAGS_DELEGATE = 0x1, - K_ETW_TYPE_FLAGS_FINALIZABLE = 0x2, - K_ETW_TYPE_FLAGS_EXTERNALLY_IMPLEMENTED_COM_OBJECT = 0x4, - K_ETW_TYPE_FLAGS_ARRAY = 0x8, + TYPE_FLAGS_DELEGATE = 0x1, + TYPE_FLAGS_FINALIZABLE = 0x2, + TYPE_FLAGS_EXTERNALLY_IMPLEMENTED_COM_OBJECT = 0x4, + TYPE_FLAGS_ARRAY = 0x8, - K_ETW_TYPE_FLAGS_ARRAY_RANK_MASK = 0x3F00, - K_ETW_TYPE_FLAGS_ARRAY_RANK_SHIFT = 8, - K_ETW_TYPE_FLAGS_ARRAY_RANK_MAX = K_ETW_TYPE_FLAGS_ARRAY_RANK_MASK >> K_ETW_TYPE_FLAGS_ARRAY_RANK_SHIFT -} EtwTypeFlags; + TYPE_FLAGS_ARRAY_RANK_MASK = 0x3F00, + TYPE_FLAGS_ARRAY_RANK_SHIFT = 8, + TYPE_FLAGS_ARRAY_RANK_MAX = TYPE_FLAGS_ARRAY_RANK_MASK >> TYPE_FLAGS_ARRAY_RANK_SHIFT +} TypeFlags; // This only contains the fixed-size data at the top of each struct in // the bulk type event. These fields must still match exactly the initial @@ -2892,10 +2892,10 @@ typedef struct _EventStructBulkTypeFixedSizedData { // Represents one instance of the Value struct inside a single BulkType event typedef struct _BulkTypeValue { EventStructBulkTypeFixedSizedData fixed_sized_data; - uint32_t c_type_parameters; - intptr_t rg_type_parameters [K_SIZE_OF_TYPE_PARAMETER_ARRAY]; - MonoType *rg_mono_type_parameters [K_SIZE_OF_TYPE_PARAMETER_ARRAY]; - ep_char8_t *s_name; // Currently should only be NULL, TODO if we want to provide the name in the BulkTypeEvent data, figure out memory management to use + uint32_t type_parameters_count; + intptr_t type_parameters [MAX_SIZE_OF_TYPE_PARAMETER_ARRAY]; + MonoType *mono_type_parameters [MAX_SIZE_OF_TYPE_PARAMETER_ARRAY]; + ep_char8_t *name; // Currently should only be NULL, TODO if we want to provide the name in the BulkTypeEvent data, figure out memory management to use } BulkTypeValue; static @@ -2908,11 +2908,11 @@ ep_rt_mono_get_byte_count_in_event (BulkTypeValue *bulk_type_value); static BulkTypeEventLogger* -ep_rt_bulk_type_event_logger_init (void); +ep_rt_bulk_type_event_logger_alloc (void); static void -ep_rt_bulk_type_event_logger_fini (BulkTypeEventLogger *p_type_logger); +ep_rt_bulk_type_event_logger_free (BulkTypeEventLogger *type_logger); static int @@ -2964,45 +2964,37 @@ static void ep_rt_bulk_type_value_clear (BulkTypeValue *bulk_type_value) { - bulk_type_value->fixed_sized_data.type_id = 0; - bulk_type_value->fixed_sized_data.module_id = 0; - bulk_type_value->fixed_sized_data.type_name_id = 0; - bulk_type_value->fixed_sized_data.flags = 0; - bulk_type_value->fixed_sized_data.cor_element_type = 0; - bulk_type_value->c_type_parameters = 0; - memset (bulk_type_value->rg_type_parameters, 0, K_SIZE_OF_TYPE_PARAMETER_ARRAY); - memset (bulk_type_value->rg_mono_type_parameters, 0, K_SIZE_OF_TYPE_PARAMETER_ARRAY); - bulk_type_value->s_name = NULL; + memset (bulk_type_value, 0, sizeof(BulkTypeValue)); } static int ep_rt_mono_get_byte_count_in_event (BulkTypeValue *bulk_type_value) { - int s_name_len = 0; + int name_len = 0; return sizeof (bulk_type_value->fixed_sized_data.type_id) + // Fixed Sized Data sizeof (bulk_type_value->fixed_sized_data.module_id) + sizeof (bulk_type_value->fixed_sized_data.type_name_id) + sizeof (bulk_type_value->fixed_sized_data.flags) + sizeof (bulk_type_value->fixed_sized_data.cor_element_type) + - sizeof (bulk_type_value->c_type_parameters) + // Type parameters - (s_name_len + 1) * sizeof (ep_char8_t) + // Size of name, including null terminator - bulk_type_value->c_type_parameters * sizeof (uint64_t); // Type parameters + sizeof (bulk_type_value->type_parameters_count) + // Type parameters + (name_len + 1) * sizeof (ep_char8_t) + // Size of name, including null terminator + bulk_type_value->type_parameters_count * sizeof (uint64_t); // Type parameters } // ETW has a limitation of 64K for TOTAL event Size, however there is overhead associated with // the event headers. It is unclear exactly how much that is, but 1K should be sufficiently // far away to avoid problems without sacrificing the perf of bulk processing. -#define CB_MAX_ETW_EVENT (63 * 1024) +#define MAX_EVENT_BYTE_COUNT (63 * 1024) // The maximum event size, and the size of the buffer that we allocate to hold the event contents. -#define K_SIZE_OF_EVENT_BUFFER 65536 +#define MAX_SIZE_OF_EVENT_BUFFER 65536 // Estimate of how many bytes we can squeeze in the event data for the value struct // array. (Intentionally overestimate the size of the non-array parts to keep it safe.) // This follows CoreCLR's kMaxBytesTypeValues. -#define K_MAX_BYTES_TYPE_VALUES (CB_MAX_ETW_EVENT - 0x30) +#define MAX_TYPE_VALUES_BYTES (MAX_EVENT_BYTE_COUNT - 0x30) // Estimate of how many type value elements we can put into the struct array, while // staying under the ETW event size limit. Note that this is impossible to calculate @@ -3016,27 +3008,27 @@ ep_rt_mono_get_byte_count_in_event (BulkTypeValue *bulk_type_value) #define K_MAX_COUNT_TYPE_VALUES ((uint32_t)(128 - 2) / 4) struct _BulkTypeEventLogger { - BulkTypeValue m_rg_bulk_type_values [K_MAX_COUNT_TYPE_VALUES]; - uint32_t m_n_bulk_type_value_count; - uint32_t m_n_bulk_type_value_byte_count; - uint8_t *m_p_bulk_type_event_buffer; + BulkTypeValue bulk_type_values [K_MAX_COUNT_TYPE_VALUES]; + uint8_t *bulk_type_event_buffer; + uint32_t bulk_type_value_count; + uint32_t bulk_type_value_byte_count; }; static BulkTypeEventLogger* -ep_rt_bulk_type_event_logger_init () +ep_rt_bulk_type_event_logger_alloc () { - BulkTypeEventLogger *p_type_logger = g_malloc0 (sizeof (BulkTypeEventLogger)); - p_type_logger->m_p_bulk_type_event_buffer = g_malloc0 (sizeof (uint8_t) * K_SIZE_OF_EVENT_BUFFER); - return p_type_logger; + BulkTypeEventLogger *type_logger = g_malloc0 (sizeof (BulkTypeEventLogger)); + type_logger->bulk_type_event_buffer = g_malloc0 (sizeof (uint8_t) * MAX_SIZE_OF_EVENT_BUFFER); + return type_logger; } static void -ep_rt_bulk_type_event_logger_fini (BulkTypeEventLogger *p_type_logger) +ep_rt_bulk_type_event_logger_free (BulkTypeEventLogger *type_logger) { - g_free (p_type_logger->m_p_bulk_type_event_buffer); - g_free (p_type_logger); + g_free (type_logger->bulk_type_event_buffer); + g_free (type_logger); } static @@ -3096,51 +3088,51 @@ write_event_buffer_int64 ( // // ep_rt_mono_fire_bulk_type_event fires an ETW event for all the types batched so far, // it then resets the state to start batching new types at the beginning of the -// m_rg_bulk_type_values array. +// bulk_type_values array. // // This follows CoreCLR's BulkTypeEventLogger::FireBulkTypeEvent void -ep_rt_mono_fire_bulk_type_event (BulkTypeEventLogger *p_type_logger) +ep_rt_mono_fire_bulk_type_event (BulkTypeEventLogger *type_logger) { - if (p_type_logger->m_n_bulk_type_value_count == 0) + if (type_logger->bulk_type_value_count == 0) return; - uint16_t n_clr_instance_id = clr_instance_get_id (); + uint16_t clr_instance_id = clr_instance_get_id (); - uint32_t i_size = 0; + uint32_t values_element_size = 0; - char *ptr = (char *)p_type_logger->m_p_bulk_type_event_buffer; + char *ptr = (char *)type_logger->bulk_type_event_buffer; - for (int i_type_data = 0; i_type_data < p_type_logger->m_n_bulk_type_value_count; i_type_data++) { - BulkTypeValue *target = &p_type_logger->m_rg_bulk_type_values [i_type_data]; + for (int 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]; - i_size += write_event_buffer_int64 (target->fixed_sized_data.type_id, ptr, &ptr); - i_size += write_event_buffer_int64 (target->fixed_sized_data.module_id, ptr, &ptr); - i_size += write_event_buffer_int32 (target->fixed_sized_data.type_name_id, ptr, &ptr); - i_size += write_event_buffer_int32 (target->fixed_sized_data.flags, ptr, &ptr); - i_size += write_event_buffer_int8 (target->fixed_sized_data.cor_element_type, ptr, &ptr); + 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); - g_assert (target->s_name == NULL); - i_size += write_event_buffer_int16 (0, ptr, &ptr); + g_assert (target->name == NULL); + values_element_size += write_event_buffer_int16 (0, ptr, &ptr); - i_size += write_event_buffer_int32 (target->c_type_parameters, ptr, &ptr); + values_element_size += write_event_buffer_int32 (target->type_parameters_count, ptr, &ptr); - for (int i = 0; i < target->c_type_parameters; i++) - i_size += write_event_buffer_int64 ((int64_t)target->rg_type_parameters [i], ptr, &ptr); + for (int i = 0; i < target->type_parameters_count; i++) + values_element_size += write_event_buffer_int64 ((int64_t)target->type_parameters [i], ptr, &ptr); } FireEtwBulkType ( - p_type_logger->m_n_bulk_type_value_count, - n_clr_instance_id, - i_size, - p_type_logger->m_p_bulk_type_event_buffer, + type_logger->bulk_type_value_count, + clr_instance_id, + values_element_size, + type_logger->bulk_type_event_buffer, NULL, NULL); - memset (p_type_logger->m_p_bulk_type_event_buffer, 0, sizeof (uint8_t) * K_SIZE_OF_EVENT_BUFFER); - p_type_logger->m_n_bulk_type_value_count = 0; - p_type_logger->m_n_bulk_type_value_byte_count = 0; + memset (type_logger->bulk_type_event_buffer, 0, sizeof (uint8_t) * MAX_SIZE_OF_EVENT_BUFFER); + type_logger->bulk_type_value_count = 0; + type_logger->bulk_type_value_byte_count = 0; } //--------------------------------------------------------------------------------------- @@ -3180,12 +3172,12 @@ get_typeid_for_class (MonoClass *c) // ep_rt_mono_log_single_type batches a single type into the bulk type array and flushes // the array to ETW if it fills up. Most interaction with the type system (type analysis) // is done here. This does not recursively batch up any parameter types (arrays or generics), -// but does add their unique identifiers to the rg_type_parameters array. +// but does add their unique identifiers to the type_parameters array. // ep_rt_mono_log_type_and_parameters is responsible for initiating any recursive calls to // deal with type parameters. // // Arguments: -// * p_type_logger - BulkTypeEventLogger instance +// * type_logger - BulkTypeEventLogger instance // * mono_type - MonoType to be logged // * type_id - Unique type identifier of mono_type // @@ -3196,67 +3188,67 @@ get_typeid_for_class (MonoClass *c) int ep_rt_mono_log_single_type ( - BulkTypeEventLogger *p_type_logger, + BulkTypeEventLogger *type_logger, MonoType *mono_type, intptr_t type_id) { // If there's no room for another type, flush what we've got - if (p_type_logger->m_n_bulk_type_value_count == K_MAX_COUNT_TYPE_VALUES) - ep_rt_mono_fire_bulk_type_event (p_type_logger); + if (type_logger->bulk_type_value_count == K_MAX_COUNT_TYPE_VALUES) + ep_rt_mono_fire_bulk_type_event (type_logger); - EP_ASSERT (p_type_logger->m_n_bulk_type_value_count < K_MAX_COUNT_TYPE_VALUES); + EP_ASSERT (type_logger->bulk_type_value_count < K_MAX_COUNT_TYPE_VALUES); - BulkTypeValue *p_val = &p_type_logger->m_rg_bulk_type_values [p_type_logger->m_n_bulk_type_value_count]; - ep_rt_bulk_type_value_clear (p_val); + BulkTypeValue *val = &type_logger->bulk_type_values [type_logger->bulk_type_value_count]; + ep_rt_bulk_type_value_clear (val); MonoClass *klass = mono_class_from_mono_type_internal (mono_type); MonoType *mono_underlying_type = mono_type_get_underlying_type (mono_type); - // Initialize p_val fixed_sized_data - p_val->fixed_sized_data.type_id = (uint64_t)type_id; - p_val->fixed_sized_data.module_id = (uint64_t)m_class_get_image (klass); - p_val->fixed_sized_data.type_name_id = m_class_get_type_token (klass) ? mono_metadata_make_token (MONO_TABLE_TYPEDEF, mono_metadata_token_index (m_class_get_type_token (klass))) : 0; + // Initialize val fixed_sized_data + val->fixed_sized_data.type_id = (uint64_t)type_id; + val->fixed_sized_data.module_id = (uint64_t)m_class_get_image (klass); + val->fixed_sized_data.type_name_id = m_class_get_type_token (klass) ? mono_metadata_make_token (MONO_TABLE_TYPEDEF, mono_metadata_token_index (m_class_get_type_token (klass))) : 0; if (mono_class_has_finalizer (klass)) - p_val->fixed_sized_data.flags |= K_ETW_TYPE_FLAGS_FINALIZABLE; + val->fixed_sized_data.flags |= TYPE_FLAGS_FINALIZABLE; if (m_class_is_delegate (klass)) - p_val->fixed_sized_data.flags |= K_ETW_TYPE_FLAGS_DELEGATE; + val->fixed_sized_data.flags |= TYPE_FLAGS_DELEGATE; if (mono_class_is_com_object (klass)) - p_val->fixed_sized_data.flags |= K_ETW_TYPE_FLAGS_EXTERNALLY_IMPLEMENTED_COM_OBJECT; - p_val->fixed_sized_data.cor_element_type = (uint8_t)mono_underlying_type->type; + val->fixed_sized_data.flags |= TYPE_FLAGS_EXTERNALLY_IMPLEMENTED_COM_OBJECT; + val->fixed_sized_data.cor_element_type = (uint8_t)mono_underlying_type->type; - // Sets p_val variable sized parameter type data c_type_parameters and rg_type_parameters - // associated with arrays or generics and add unique identifiers to rg_type_parameters array + // Sets val variable sized parameter type data type_parameters_count and type_parameters + // associated with arrays or generics and add unique identifiers to type_parameters array // to be recursively batched in the same ep_rt_mono_log_type_and_parameters call switch (mono_underlying_type->type) { case MONO_TYPE_ARRAY: case MONO_TYPE_SZARRAY: { MonoArrayType *mono_array_type = mono_type_get_array_type (mono_type); - p_val->fixed_sized_data.flags |= K_ETW_TYPE_FLAGS_ARRAY; + val->fixed_sized_data.flags |= TYPE_FLAGS_ARRAY; if (mono_underlying_type->type == MONO_TYPE_ARRAY) { - // Only ranks less than kEtwTypeFlagsArrayRankMax are supported. - // Fortunately kEtwTypeFlagsArrayRankMax should be greater than the + // Only ranks less than TypeFlagsArrayRankMax are supported. + // Fortunately TypeFlagsArrayRankMax should be greater than the // number of ranks the type loader will support uint32_t rank = mono_array_type->rank; - if (rank < K_ETW_TYPE_FLAGS_ARRAY_RANK_MAX) { + if (rank < TYPE_FLAGS_ARRAY_RANK_MAX) { rank <<= 8; - p_val->fixed_sized_data.flags |= rank; + val->fixed_sized_data.flags |= rank; } } // mono arrays are always arrays of by value types - p_val->rg_mono_type_parameters [p_val->c_type_parameters] = m_class_get_byval_arg (mono_array_type->eklass); - p_val->rg_type_parameters [p_val->c_type_parameters] = get_typeid_for_class (mono_array_type->eklass); - p_val->c_type_parameters++; + val->mono_type_parameters [val->type_parameters_count] = m_class_get_byval_arg (mono_array_type->eklass); + val->type_parameters [val->type_parameters_count] = get_typeid_for_class (mono_array_type->eklass); + val->type_parameters_count++; break; } case MONO_TYPE_GENERICINST: { MonoGenericInst *class_inst = mono_type->data.generic_class->context.class_inst; - p_val->c_type_parameters = class_inst->type_argc; + val->type_parameters_count = class_inst->type_argc; for (int i = 0; i < class_inst->type_argc; i++) { - p_val->rg_mono_type_parameters [i] = class_inst->type_argv [i]; - p_val->rg_type_parameters [i] = get_typeid_for_type (class_inst->type_argv [i]); + val->mono_type_parameters [i] = class_inst->type_argv [i]; + val->type_parameters [i] = get_typeid_for_type (class_inst->type_argv [i]); } break; } @@ -3267,9 +3259,9 @@ ep_rt_mono_log_single_type ( { if (mono_underlying_type == mono_type) break; - p_val->rg_mono_type_parameters [p_val->c_type_parameters] = mono_type_get_underlying_type (mono_type); - p_val->rg_type_parameters [p_val->c_type_parameters] = get_typeid_for_type (mono_type_get_underlying_type (mono_type)); - p_val->c_type_parameters++; + val->mono_type_parameters [val->type_parameters_count] = mono_type_get_underlying_type (mono_type); + val->type_parameters [val->type_parameters_count] = get_typeid_for_type (mono_type_get_underlying_type (mono_type)); + val->type_parameters_count++; break; } default: @@ -3278,34 +3270,31 @@ ep_rt_mono_log_single_type ( // Now that we know the full size of this type's data, see if it fits in our // batch or whether we need to flush - int cb_val = ep_rt_mono_get_byte_count_in_event (p_val); - if (cb_val > K_MAX_BYTES_TYPE_VALUES) { - cb_val = ep_rt_mono_get_byte_count_in_event (p_val); - - if (cb_val > K_MAX_BYTES_TYPE_VALUES) { - // This type is apparently so huge, it's too big to squeeze into an event, even - // if it were the only type batched in the whole event. Bail - mono_trace (G_LOG_LEVEL_ERROR, MONO_TRACE_DIAGNOSTICS, "Failed to log single mono type %p with typeID %p. Type is too large for the BulkType Event.\n", (gpointer)mono_type, (gpointer)type_id); - return -1; - } + int val_byte_count = ep_rt_mono_get_byte_count_in_event (val); + if (val_byte_count > MAX_TYPE_VALUES_BYTES) { + // NOTE: If name is actively used, set it to NULL and relevant memory management to reduce byte count + // This type is apparently so huge, it's too big to squeeze into an event, even + // if it were the only type batched in the whole event. Bail + mono_trace (G_LOG_LEVEL_ERROR, MONO_TRACE_DIAGNOSTICS, "Failed to log single mono type %p with typeID %p. Type is too large for the BulkType Event.\n", (gpointer)mono_type, (gpointer)type_id); + return -1; } - if (p_type_logger->m_n_bulk_type_value_byte_count + cb_val > K_MAX_BYTES_TYPE_VALUES) { + if (type_logger->bulk_type_value_byte_count + val_byte_count > MAX_TYPE_VALUES_BYTES) { // Although this type fits into the array, its size is so big that the entire // array can't be logged via ETW. So flush the array, and start over by // calling ourselves--this refetches the type info and puts it at the // beginning of the array. Since we know this type is small enough to be // batched into an event on its own, this recursive call will not try to // call itself again. - g_assert (p_type_logger->m_n_bulk_type_value_byte_count + cb_val > K_MAX_BYTES_TYPE_VALUES); - ep_rt_mono_fire_bulk_type_event (p_type_logger); - return ep_rt_mono_log_single_type (p_type_logger, mono_type, type_id); + g_assert (type_logger->bulk_type_value_byte_count + val_byte_count > MAX_TYPE_VALUES_BYTES); + ep_rt_mono_fire_bulk_type_event (type_logger); + return ep_rt_mono_log_single_type (type_logger, mono_type, type_id); } // The type fits into the batch, so update our state - p_type_logger->m_n_bulk_type_value_count++; - p_type_logger->m_n_bulk_type_value_byte_count += cb_val; - return p_type_logger->m_n_bulk_type_value_count - 1; + type_logger->bulk_type_value_count++; + type_logger->bulk_type_value_byte_count += val_byte_count; + return type_logger->bulk_type_value_count - 1; } //--------------------------------------------------------------------------------------- @@ -3314,7 +3303,7 @@ ep_rt_mono_log_single_type ( // ETW as needed. This is called by ep_rt_mono_log_type_and_parameters_if_necessary. // // Arguments: -// * p_type_logger - BulkTypeEventLogger instance +// * type_logger - BulkTypeEventLogger instance // * mono_type - MonoType to be logged // * type_id - Unique type identifier of mono_type to batch // @@ -3322,35 +3311,33 @@ ep_rt_mono_log_single_type ( void ep_rt_mono_log_type_and_parameters ( - BulkTypeEventLogger *p_type_logger, + BulkTypeEventLogger *type_logger, MonoType *mono_type, intptr_t type_id) { // Batch up this type. This grabs useful info about the type, including any - // type parameters it may have, and sticks it in m_rg_bulk_type_values - int i_bulk_type_event_data = ep_rt_mono_log_single_type (p_type_logger, mono_type, type_id); - if (i_bulk_type_event_data == -1) { + // type parameters it may have, and sticks it in bulk_type_values + int bulk_type_value_index = ep_rt_mono_log_single_type (type_logger, mono_type, type_id); + if (bulk_type_value_index == -1) { // There was a failure trying to log the type, so don't bother with its type // parameters return; } // Look at the type info we just batched, so we can get the type parameters - BulkTypeValue *p_val = &p_type_logger->m_rg_bulk_type_values [i_bulk_type_event_data]; + BulkTypeValue *val = &type_logger->bulk_type_values [bulk_type_value_index]; // We're about to recursively call ourselves for the type parameters, so make a // local copy of their type handles first (else, as we log them we could flush - // and clear out m_rg_bulk_type_values, thus trashing p_val) - uint32_t c_params = p_val->c_type_parameters; - intptr_t rg_type_parameters [K_SIZE_OF_TYPE_PARAMETER_ARRAY]; - MonoType *rg_mono_type_parameters [K_SIZE_OF_TYPE_PARAMETER_ARRAY]; - for (uint32_t i = 0; i < c_params; i++) { - rg_type_parameters [i] = p_val->rg_type_parameters [i]; - rg_mono_type_parameters [i] = p_val->rg_mono_type_parameters [i]; - } + // and clear out bulk_type_values, thus trashing val) + uint32_t param_count = val->type_parameters_count; + intptr_t type_parameters [MAX_SIZE_OF_TYPE_PARAMETER_ARRAY]; + MonoType *mono_type_parameters [MAX_SIZE_OF_TYPE_PARAMETER_ARRAY]; + memcpy (type_parameters, val->type_parameters, sizeof(intptr_t) * param_count); + memcpy (mono_type_parameters, val->mono_type_parameters, sizeof(MonoType*) * param_count); - for (uint32_t i = 0; i < c_params; i++) - ep_rt_mono_log_type_and_parameters_if_necessary (p_type_logger, rg_mono_type_parameters [i], rg_type_parameters [i]); + for (uint32_t i = 0; i < param_count; i++) + ep_rt_mono_log_type_and_parameters_if_necessary (type_logger, mono_type_parameters [i], type_parameters [i]); } //--------------------------------------------------------------------------------------- @@ -3359,7 +3346,7 @@ ep_rt_mono_log_type_and_parameters ( // (in this case a MonoType) and (recursively) its type parameters when present. // // Arguments: -// * p_type_logger - BulkTypeEventLogger instance +// * type_logger - BulkTypeEventLogger instance // * mono_type - MonoType to be logged // * type_id - Unique type identifier of mono_type // @@ -3367,13 +3354,13 @@ ep_rt_mono_log_type_and_parameters ( void ep_rt_mono_log_type_and_parameters_if_necessary ( - BulkTypeEventLogger *p_type_logger, + BulkTypeEventLogger *type_logger, MonoType *mono_type, intptr_t type_id) { // TODO Log the type if necessary - ep_rt_mono_log_type_and_parameters (p_type_logger, mono_type, type_id); + ep_rt_mono_log_type_and_parameters (type_logger, mono_type, type_id); } // ETW has a limit for maximum event size. Do not log overly large method type argument sets @@ -3409,7 +3396,7 @@ ep_rt_mono_send_method_details_event (MonoMethod *method) if (method_inst && method_inst->type_argc > K_MAX_METHOD_TYPE_ARGUMENT_COUNT) return; - BulkTypeEventLogger *p_type_logger = ep_rt_bulk_type_event_logger_init (); + BulkTypeEventLogger *type_logger = ep_rt_bulk_type_event_logger_alloc (); intptr_t method_type_id = 0; g_assert (mono_metadata_token_index (method->token) != 0); @@ -3420,7 +3407,7 @@ ep_rt_mono_send_method_details_event (MonoMethod *method) MonoType *method_mono_type = m_class_get_byval_arg (klass); method_type_id = get_typeid_for_class (klass); - ep_rt_mono_log_type_and_parameters_if_necessary (p_type_logger, method_mono_type, method_type_id); + ep_rt_mono_log_type_and_parameters_if_necessary (type_logger, method_mono_type, method_type_id); loader_module_id = (uint64_t)mono_class_get_image (klass); } @@ -3433,10 +3420,10 @@ ep_rt_mono_send_method_details_event (MonoMethod *method) for (int 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_rt_mono_log_type_and_parameters_if_necessary (p_type_logger, method_inst->type_argv [i], method_inst_parameters_type_ids [i]); + ep_rt_mono_log_type_and_parameters_if_necessary (type_logger, method_inst->type_argv [i], method_inst_parameters_type_ids [i]); } - ep_rt_mono_fire_bulk_type_event (p_type_logger); + ep_rt_mono_fire_bulk_type_event (type_logger); FireEtwMethodDetails ( (uint64_t)method, @@ -3448,7 +3435,7 @@ ep_rt_mono_send_method_details_event (MonoMethod *method) NULL, NULL); - ep_rt_bulk_type_event_logger_fini (p_type_logger); + ep_rt_bulk_type_event_logger_free (type_logger); } bool From 87f87f2f93457bed292d979668dbad01beb1e5f1 Mon Sep 17 00:00:00 2001 From: mdh1418 Date: Fri, 6 May 2022 15:10:52 -0400 Subject: [PATCH 23/28] Change Event struct parameter _ElementSize type to size_t --- src/coreclr/scripts/genEventPipe.py | 10 +++++----- src/coreclr/scripts/genEventing.py | 2 +- src/mono/mono/eventpipe/ep-rt-mono.c | 22 +++++++++++----------- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/coreclr/scripts/genEventPipe.py b/src/coreclr/scripts/genEventPipe.py index 2f46735cc43e2c..fdf0c7648fa24d 100644 --- a/src/coreclr/scripts/genEventPipe.py +++ b/src/coreclr/scripts/genEventPipe.py @@ -53,7 +53,7 @@ def generateMethodSignatureWrite(eventName, template, extern, runtimeFlavor): if paramName in template.structs: sig_pieces.append( - "%sint %s_ElementSize,\n" % + "%ssize_t %s_ElementSize,\n" % (lindent, paramName)) sig_pieces.append(lindent) @@ -262,10 +262,10 @@ def generateWriteEventBody(template, providerName, eventName, runtimeFlavor): parameter = fnSig.getParam(paramName) if paramName in template.structs: - size = "(int)%s_ElementSize * (int)%s" % ( + size = "(size_t)%s_ElementSize * (size_t)%s" % ( paramName, parameter.prop) if template.name in specialCaseSizes and paramName in specialCaseSizes[template.name]: - size = "(int)(%s)" % specialCaseSizes[template.name][paramName] + size = "(size_t)(%s)" % specialCaseSizes[template.name][paramName] if runtimeFlavor.mono: pack_list.append( " success &= write_buffer((const uint8_t *)%s, %s, &buffer, &offset, &size, &fixedBuffer);" % @@ -277,11 +277,11 @@ def generateWriteEventBody(template, providerName, eventName, runtimeFlavor): (paramName, size)) emittedWriteToBuffer = True elif paramName in template.arrays: - size = "sizeof(%s) * (int)%s" % ( + size = "sizeof(%s) * (size_t)%s" % ( getLttngDataTypeMapping(runtimeFlavor)[parameter.winType], parameter.prop) if template.name in specialCaseSizes and paramName in specialCaseSizes[template.name]: - size = "(int)(%s)" % specialCaseSizes[template.name][paramName] + size = "(size_t)(%s)" % specialCaseSizes[template.name][paramName] if runtimeFlavor.mono: pack_list.append( " success &= write_buffer((const uint8_t *)%s, %s, &buffer, &offset, &size, &fixedBuffer);" % diff --git a/src/coreclr/scripts/genEventing.py b/src/coreclr/scripts/genEventing.py index f1e341a36b297e..1abe7b3bef3675 100644 --- a/src/coreclr/scripts/genEventing.py +++ b/src/coreclr/scripts/genEventing.py @@ -533,7 +533,7 @@ def generateClrEventPipeWriteEvents(eventNodes, allTemplates, extern, target_cpp countw = getPalDataTypeMapping(runtimeFlavor)[winCount] if params in template.structs: - fnptypeline.append("%sint %s_ElementSize,\n" % (lindent, params)) + fnptypeline.append("%ssize_t %s_ElementSize,\n" % (lindent, params)) fnptypeline.append(lindent) fnptypeline.append(typewName) diff --git a/src/mono/mono/eventpipe/ep-rt-mono.c b/src/mono/mono/eventpipe/ep-rt-mono.c index 9bd2b4e0c5e25d..96701e73424dc7 100644 --- a/src/mono/mono/eventpipe/ep-rt-mono.c +++ b/src/mono/mono/eventpipe/ep-rt-mono.c @@ -2915,7 +2915,7 @@ void ep_rt_bulk_type_event_logger_free (BulkTypeEventLogger *type_logger); static -int +size_t write_event_buffer ( const uint8_t *val, size_t size, @@ -2923,28 +2923,28 @@ write_event_buffer ( char **buf_next); static -int +size_t write_event_buffer_int8 ( int8_t val, char *buf_start, char **buf_next); static -int +size_t write_event_buffer_int16 ( int16_t val, char *buf_start, char **buf_next); static -int +size_t write_event_buffer_int32 ( int32_t val, char *buf_start, char **buf_next); static -int +size_t write_event_buffer_int64 ( int64_t val, char *buf_start, @@ -3032,7 +3032,7 @@ ep_rt_bulk_type_event_logger_free (BulkTypeEventLogger *type_logger) } static -int +size_t write_event_buffer ( const uint8_t *val, size_t size, @@ -3045,7 +3045,7 @@ write_event_buffer ( } static -int +size_t write_event_buffer_int8 ( int8_t val, char *buf_start, @@ -3055,7 +3055,7 @@ write_event_buffer_int8 ( } static -int +size_t write_event_buffer_int16 ( int16_t val, char *buf_start, @@ -3065,7 +3065,7 @@ write_event_buffer_int16 ( } static -int +size_t write_event_buffer_int32 ( int32_t val, char *buf_start, @@ -3075,7 +3075,7 @@ write_event_buffer_int32 ( } static -int +size_t write_event_buffer_int64 ( int64_t val, char *buf_start, @@ -3100,7 +3100,7 @@ ep_rt_mono_fire_bulk_type_event (BulkTypeEventLogger *type_logger) uint16_t clr_instance_id = clr_instance_get_id (); - uint32_t values_element_size = 0; + size_t values_element_size = 0; char *ptr = (char *)type_logger->bulk_type_event_buffer; From bfb21fa47170604753ba784ddf627fbe91d438a9 Mon Sep 17 00:00:00 2001 From: mdh1418 Date: Mon, 9 May 2022 14:02:17 -0400 Subject: [PATCH 24/28] Remove parallel type id array to reduce bookkeeping and create type ids from mono types when needed Change type id type from intptr_t to uint64_t as ids in eventpipe are standardized to uint64_t --- src/mono/mono/eventpipe/ep-rt-mono.c | 75 ++++++++++++---------------- src/mono/mono/eventpipe/ep-rt-mono.h | 9 ++-- 2 files changed, 35 insertions(+), 49 deletions(-) diff --git a/src/mono/mono/eventpipe/ep-rt-mono.c b/src/mono/mono/eventpipe/ep-rt-mono.c index 96701e73424dc7..e2b04ef019bba6 100644 --- a/src/mono/mono/eventpipe/ep-rt-mono.c +++ b/src/mono/mono/eventpipe/ep-rt-mono.c @@ -2861,7 +2861,7 @@ ep_rt_mono_write_event_ee_startup_start (void) // The maximum number of type parameters for a BulkTypeValue instance // Aligned with coreCLR StackSArray rgTypeParameters -#define MAX_SIZE_OF_TYPE_PARAMETER_ARRAY ((uint32_t)(STACK_ALLOC / sizeof (intptr_t))) +#define INIT_SIZE_OF_TYPE_PARAMETER_ARRAY ((uint32_t)(STACK_ALLOC / sizeof (intptr_t))) // !!!!!!! NOTE !!!!!!!! // The flags must match those in the ETW manifest exactly @@ -2893,8 +2893,7 @@ typedef struct _EventStructBulkTypeFixedSizedData { typedef struct _BulkTypeValue { EventStructBulkTypeFixedSizedData fixed_sized_data; uint32_t type_parameters_count; - intptr_t type_parameters [MAX_SIZE_OF_TYPE_PARAMETER_ARRAY]; - MonoType *mono_type_parameters [MAX_SIZE_OF_TYPE_PARAMETER_ARRAY]; + MonoType *mono_type_parameters [INIT_SIZE_OF_TYPE_PARAMETER_ARRAY]; ep_char8_t *name; // Currently should only be NULL, TODO if we want to provide the name in the BulkTypeEvent data, figure out memory management to use } BulkTypeValue; @@ -2951,11 +2950,11 @@ write_event_buffer_int64 ( char **buf_next); static -intptr_t +uint64_t get_typeid_for_type (MonoType *t); static -intptr_t +uint64_t get_typeid_for_class (MonoClass *c); // Clear out BulkTypeValue before filling it out (array elements can get reused if there @@ -3118,8 +3117,10 @@ ep_rt_mono_fire_bulk_type_event (BulkTypeEventLogger *type_logger) values_element_size += write_event_buffer_int32 (target->type_parameters_count, ptr, &ptr); - for (int i = 0; i < target->type_parameters_count; i++) - values_element_size += write_event_buffer_int64 ((int64_t)target->type_parameters [i], ptr, &ptr); + for (int 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); + } } FireEtwBulkType ( @@ -3151,17 +3152,17 @@ ep_rt_mono_fire_bulk_type_event (BulkTypeEventLogger *type_logger) // type_id - Unique type identifier of mono_type static -intptr_t +uint64_t get_typeid_for_type (MonoType *t) { if (m_type_is_byref (t)) - return (intptr_t)m_class_get_this_arg (mono_class_from_mono_type_internal (t)); + return (uint64_t)m_class_get_this_arg (mono_class_from_mono_type_internal (t)); else - return (intptr_t)m_class_get_byval_arg (mono_class_from_mono_type_internal (t)); + return (uint64_t)m_class_get_byval_arg (mono_class_from_mono_type_internal (t)); } static -intptr_t +uint64_t get_typeid_for_class (MonoClass *c) { return get_typeid_for_type (m_class_get_byval_arg (c)); @@ -3172,14 +3173,13 @@ get_typeid_for_class (MonoClass *c) // ep_rt_mono_log_single_type batches a single type into the bulk type array and flushes // the array to ETW if it fills up. Most interaction with the type system (type analysis) // is done here. This does not recursively batch up any parameter types (arrays or generics), -// but does add their unique identifiers to the type_parameters array. +// but does add their unique identifiers to the mono_type_parameters array. // ep_rt_mono_log_type_and_parameters is responsible for initiating any recursive calls to // deal with type parameters. // // Arguments: // * type_logger - BulkTypeEventLogger instance // * mono_type - MonoType to be logged -// * type_id - Unique type identifier of mono_type // // Return Value: // Index into array of where this type got batched. -1 if there was a failure. @@ -3189,8 +3189,7 @@ get_typeid_for_class (MonoClass *c) int ep_rt_mono_log_single_type ( BulkTypeEventLogger *type_logger, - MonoType *mono_type, - intptr_t type_id) + MonoType *mono_type) { // If there's no room for another type, flush what we've got if (type_logger->bulk_type_value_count == K_MAX_COUNT_TYPE_VALUES) @@ -3205,7 +3204,7 @@ ep_rt_mono_log_single_type ( MonoType *mono_underlying_type = mono_type_get_underlying_type (mono_type); // Initialize val fixed_sized_data - val->fixed_sized_data.type_id = (uint64_t)type_id; + val->fixed_sized_data.type_id = get_typeid_for_type (mono_type); val->fixed_sized_data.module_id = (uint64_t)m_class_get_image (klass); val->fixed_sized_data.type_name_id = m_class_get_type_token (klass) ? mono_metadata_make_token (MONO_TABLE_TYPEDEF, mono_metadata_token_index (m_class_get_type_token (klass))) : 0; if (mono_class_has_finalizer (klass)) @@ -3216,9 +3215,8 @@ ep_rt_mono_log_single_type ( val->fixed_sized_data.flags |= TYPE_FLAGS_EXTERNALLY_IMPLEMENTED_COM_OBJECT; val->fixed_sized_data.cor_element_type = (uint8_t)mono_underlying_type->type; - // Sets val variable sized parameter type data type_parameters_count and type_parameters - // associated with arrays or generics and add unique identifiers to type_parameters array - // to be recursively batched in the same ep_rt_mono_log_type_and_parameters call + // Sets val variable sized parameter type data, type_parameters_count, and mono_type_parameters associated + // with arrays or generics to be recursively batched in the same ep_rt_mono_log_type_and_parameters call switch (mono_underlying_type->type) { case MONO_TYPE_ARRAY: case MONO_TYPE_SZARRAY: @@ -3238,7 +3236,6 @@ ep_rt_mono_log_single_type ( // mono arrays are always arrays of by value types val->mono_type_parameters [val->type_parameters_count] = m_class_get_byval_arg (mono_array_type->eklass); - val->type_parameters [val->type_parameters_count] = get_typeid_for_class (mono_array_type->eklass); val->type_parameters_count++; break; } @@ -3248,7 +3245,6 @@ ep_rt_mono_log_single_type ( val->type_parameters_count = class_inst->type_argc; for (int i = 0; i < class_inst->type_argc; i++) { val->mono_type_parameters [i] = class_inst->type_argv [i]; - val->type_parameters [i] = get_typeid_for_type (class_inst->type_argv [i]); } break; } @@ -3260,7 +3256,6 @@ ep_rt_mono_log_single_type ( if (mono_underlying_type == mono_type) break; val->mono_type_parameters [val->type_parameters_count] = mono_type_get_underlying_type (mono_type); - val->type_parameters [val->type_parameters_count] = get_typeid_for_type (mono_type_get_underlying_type (mono_type)); val->type_parameters_count++; break; } @@ -3275,7 +3270,7 @@ ep_rt_mono_log_single_type ( // NOTE: If name is actively used, set it to NULL and relevant memory management to reduce byte count // This type is apparently so huge, it's too big to squeeze into an event, even // if it were the only type batched in the whole event. Bail - mono_trace (G_LOG_LEVEL_ERROR, MONO_TRACE_DIAGNOSTICS, "Failed to log single mono type %p with typeID %p. Type is too large for the BulkType Event.\n", (gpointer)mono_type, (gpointer)type_id); + mono_trace (G_LOG_LEVEL_ERROR, MONO_TRACE_DIAGNOSTICS, "Failed to log single mono type %p with typeID %llu. Type is too large for the BulkType Event.\n", (gpointer)mono_type, val->fixed_sized_data.type_id); return -1; } @@ -3288,7 +3283,7 @@ ep_rt_mono_log_single_type ( // call itself again. g_assert (type_logger->bulk_type_value_byte_count + val_byte_count > MAX_TYPE_VALUES_BYTES); ep_rt_mono_fire_bulk_type_event (type_logger); - return ep_rt_mono_log_single_type (type_logger, mono_type, type_id); + return ep_rt_mono_log_single_type (type_logger, mono_type); } // The type fits into the batch, so update our state @@ -3305,19 +3300,17 @@ ep_rt_mono_log_single_type ( // Arguments: // * type_logger - BulkTypeEventLogger instance // * mono_type - MonoType to be logged -// * type_id - Unique type identifier of mono_type to batch // // This follows CoreCLR's BulkTypeEventLogger::LogTypeAndParameter void ep_rt_mono_log_type_and_parameters ( BulkTypeEventLogger *type_logger, - MonoType *mono_type, - intptr_t type_id) + MonoType *mono_type) { // Batch up this type. This grabs useful info about the type, including any // type parameters it may have, and sticks it in bulk_type_values - int bulk_type_value_index = ep_rt_mono_log_single_type (type_logger, mono_type, type_id); + int bulk_type_value_index = ep_rt_mono_log_single_type (type_logger, mono_type); if (bulk_type_value_index == -1) { // There was a failure trying to log the type, so don't bother with its type // parameters @@ -3331,13 +3324,11 @@ ep_rt_mono_log_type_and_parameters ( // local copy of their type handles first (else, as we log them we could flush // and clear out bulk_type_values, thus trashing val) uint32_t param_count = val->type_parameters_count; - intptr_t type_parameters [MAX_SIZE_OF_TYPE_PARAMETER_ARRAY]; - MonoType *mono_type_parameters [MAX_SIZE_OF_TYPE_PARAMETER_ARRAY]; - memcpy (type_parameters, val->type_parameters, sizeof(intptr_t) * param_count); + MonoType *mono_type_parameters [INIT_SIZE_OF_TYPE_PARAMETER_ARRAY]; memcpy (mono_type_parameters, val->mono_type_parameters, sizeof(MonoType*) * param_count); for (uint32_t i = 0; i < param_count; i++) - ep_rt_mono_log_type_and_parameters_if_necessary (type_logger, mono_type_parameters [i], type_parameters [i]); + ep_rt_mono_log_type_and_parameters_if_necessary (type_logger, mono_type_parameters [i]); } //--------------------------------------------------------------------------------------- @@ -3348,23 +3339,21 @@ ep_rt_mono_log_type_and_parameters ( // Arguments: // * type_logger - BulkTypeEventLogger instance // * mono_type - MonoType to be logged -// * type_id - Unique type identifier of mono_type // // This follows CoreCLR's BulkTypeEventLogger::LogTypeAndParameters void ep_rt_mono_log_type_and_parameters_if_necessary ( BulkTypeEventLogger *type_logger, - MonoType *mono_type, - intptr_t type_id) + MonoType *mono_type) { // TODO Log the type if necessary - ep_rt_mono_log_type_and_parameters (type_logger, mono_type, type_id); + ep_rt_mono_log_type_and_parameters (type_logger, mono_type); } // ETW has a limit for maximum event size. Do not log overly large method type argument sets -static const uint32_t K_MAX_METHOD_TYPE_ARGUMENT_COUNT = 1024; +static const uint32_t MAX_METHOD_TYPE_ARGUMENT_COUNT = 1024; //--------------------------------------------------------------------------------------- // @@ -3393,12 +3382,12 @@ ep_rt_mono_send_method_details_event (MonoMethod *method) if (method_ctx) method_inst = method_ctx->method_inst; - if (method_inst && method_inst->type_argc > K_MAX_METHOD_TYPE_ARGUMENT_COUNT) + if (method_inst && method_inst->type_argc > MAX_METHOD_TYPE_ARGUMENT_COUNT) return; BulkTypeEventLogger *type_logger = ep_rt_bulk_type_event_logger_alloc (); - intptr_t method_type_id = 0; + uint64_t method_type_id = 0; g_assert (mono_metadata_token_index (method->token) != 0); uint32_t method_token = mono_metadata_make_token (MONO_TABLE_METHOD, mono_metadata_token_index (method->token)); uint64_t loader_module_id = 0; @@ -3407,7 +3396,7 @@ ep_rt_mono_send_method_details_event (MonoMethod *method) MonoType *method_mono_type = m_class_get_byval_arg (klass); method_type_id = get_typeid_for_class (klass); - ep_rt_mono_log_type_and_parameters_if_necessary (type_logger, method_mono_type, method_type_id); + ep_rt_mono_log_type_and_parameters_if_necessary (type_logger, method_mono_type); loader_module_id = (uint64_t)mono_class_get_image (klass); } @@ -3416,18 +3405,18 @@ ep_rt_mono_send_method_details_event (MonoMethod *method) if (method_inst) method_inst_parameter_types_count = method_inst->type_argc; - intptr_t method_inst_parameters_type_ids [K_MAX_METHOD_TYPE_ARGUMENT_COUNT]; + uint64_t *method_inst_parameters_type_ids = g_alloca (method_inst_parameter_types_count * sizeof (intptr_t)); for (int 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_rt_mono_log_type_and_parameters_if_necessary (type_logger, method_inst->type_argv [i], method_inst_parameters_type_ids [i]); + ep_rt_mono_log_type_and_parameters_if_necessary (type_logger, method_inst->type_argv [i]); } ep_rt_mono_fire_bulk_type_event (type_logger); FireEtwMethodDetails ( (uint64_t)method, - (uint64_t)method_type_id, + method_type_id, method_token, method_inst_parameter_types_count, loader_module_id, diff --git a/src/mono/mono/eventpipe/ep-rt-mono.h b/src/mono/mono/eventpipe/ep-rt-mono.h index 915d609084f1bb..801d4180e04f2c 100644 --- a/src/mono/mono/eventpipe/ep-rt-mono.h +++ b/src/mono/mono/eventpipe/ep-rt-mono.h @@ -2187,20 +2187,17 @@ ep_rt_mono_fire_bulk_type_event (BulkTypeEventLogger *p_type_logger); int ep_rt_mono_log_single_type ( BulkTypeEventLogger *p_type_logger, - MonoType *mono_type, - intptr_t type_id); + MonoType *mono_type); void ep_rt_mono_log_type_and_parameters ( BulkTypeEventLogger *p_type_logger, - MonoType *mono_type, - intptr_t type_id); + MonoType *mono_type); void ep_rt_mono_log_type_and_parameters_if_necessary ( BulkTypeEventLogger *p_type_logger, - MonoType *mono_type, - intptr_t type_id); + MonoType *mono_type); void ep_rt_mono_send_method_details_event (MonoMethod *method); From f64fdd57134cc00e5ed3f2f25d473c2d75e4a504 Mon Sep 17 00:00:00 2001 From: mdh1418 Date: Tue, 10 May 2022 09:45:05 -0400 Subject: [PATCH 25/28] [mono][eventpipe] Add dedicated mempool for BulkTypeEventLogger to dynamically allocate enough space for type parameters --- src/mono/mono/eventpipe/ep-rt-mono.c | 39 +++++++++++++++++----------- src/mono/mono/eventpipe/ep-rt-mono.h | 3 +++ 2 files changed, 27 insertions(+), 15 deletions(-) diff --git a/src/mono/mono/eventpipe/ep-rt-mono.c b/src/mono/mono/eventpipe/ep-rt-mono.c index e2b04ef019bba6..685fab195e6e43 100644 --- a/src/mono/mono/eventpipe/ep-rt-mono.c +++ b/src/mono/mono/eventpipe/ep-rt-mono.c @@ -2893,7 +2893,7 @@ typedef struct _EventStructBulkTypeFixedSizedData { typedef struct _BulkTypeValue { EventStructBulkTypeFixedSizedData fixed_sized_data; uint32_t type_parameters_count; - MonoType *mono_type_parameters [INIT_SIZE_OF_TYPE_PARAMETER_ARRAY]; + MonoType **mono_type_parameters; ep_char8_t *name; // Currently should only be NULL, TODO if we want to provide the name in the BulkTypeEvent data, figure out memory management to use } BulkTypeValue; @@ -3189,6 +3189,7 @@ get_typeid_for_class (MonoClass *c) int ep_rt_mono_log_single_type ( BulkTypeEventLogger *type_logger, + MonoMemPool *mem_pool, MonoType *mono_type) { // If there's no room for another type, flush what we've got @@ -3235,7 +3236,8 @@ ep_rt_mono_log_single_type ( } // mono arrays are always arrays of by value types - val->mono_type_parameters [val->type_parameters_count] = m_class_get_byval_arg (mono_array_type->eklass); + val->mono_type_parameters = mono_mempool_alloc0 (mem_pool, 1 * sizeof (MonoType*)); + *val->mono_type_parameters = m_class_get_byval_arg (mono_array_type->eklass); val->type_parameters_count++; break; } @@ -3243,9 +3245,8 @@ ep_rt_mono_log_single_type ( { MonoGenericInst *class_inst = mono_type->data.generic_class->context.class_inst; val->type_parameters_count = class_inst->type_argc; - for (int i = 0; i < class_inst->type_argc; i++) { - val->mono_type_parameters [i] = class_inst->type_argv [i]; - } + val->mono_type_parameters = mono_mempool_alloc0 (mem_pool, val->type_parameters_count * sizeof (MonoType*)); + memcpy (val->mono_type_parameters, class_inst->type_argv, val->type_parameters_count * sizeof (MonoType*)); break; } case MONO_TYPE_CLASS: @@ -3255,7 +3256,8 @@ ep_rt_mono_log_single_type ( { if (mono_underlying_type == mono_type) break; - val->mono_type_parameters [val->type_parameters_count] = mono_type_get_underlying_type (mono_type); + val->mono_type_parameters = mono_mempool_alloc0 (mem_pool, 1 * sizeof (MonoType*)); + *val->mono_type_parameters = mono_underlying_type; val->type_parameters_count++; break; } @@ -3283,7 +3285,7 @@ ep_rt_mono_log_single_type ( // call itself again. g_assert (type_logger->bulk_type_value_byte_count + val_byte_count > MAX_TYPE_VALUES_BYTES); ep_rt_mono_fire_bulk_type_event (type_logger); - return ep_rt_mono_log_single_type (type_logger, mono_type); + return ep_rt_mono_log_single_type (type_logger, mem_pool, mono_type); } // The type fits into the batch, so update our state @@ -3306,11 +3308,12 @@ ep_rt_mono_log_single_type ( void ep_rt_mono_log_type_and_parameters ( BulkTypeEventLogger *type_logger, + MonoMemPool *mem_pool, MonoType *mono_type) { // Batch up this type. This grabs useful info about the type, including any // type parameters it may have, and sticks it in bulk_type_values - int bulk_type_value_index = ep_rt_mono_log_single_type (type_logger, mono_type); + int bulk_type_value_index = ep_rt_mono_log_single_type (type_logger, mem_pool, mono_type); if (bulk_type_value_index == -1) { // There was a failure trying to log the type, so don't bother with its type // parameters @@ -3324,11 +3327,14 @@ ep_rt_mono_log_type_and_parameters ( // local copy of their type handles first (else, as we log them we could flush // and clear out bulk_type_values, thus trashing val) uint32_t param_count = val->type_parameters_count; - MonoType *mono_type_parameters [INIT_SIZE_OF_TYPE_PARAMETER_ARRAY]; - memcpy (mono_type_parameters, val->mono_type_parameters, sizeof(MonoType*) * param_count); + if (param_count == 0) + return; + + MonoType **mono_type_parameters = mono_mempool_alloc0 (mem_pool, param_count * sizeof (MonoType*)); + memcpy (mono_type_parameters, val->mono_type_parameters, sizeof (MonoType*) * param_count); for (uint32_t i = 0; i < param_count; i++) - ep_rt_mono_log_type_and_parameters_if_necessary (type_logger, mono_type_parameters [i]); + ep_rt_mono_log_type_and_parameters_if_necessary (type_logger, mem_pool, mono_type_parameters [i]); } //--------------------------------------------------------------------------------------- @@ -3345,11 +3351,12 @@ ep_rt_mono_log_type_and_parameters ( void ep_rt_mono_log_type_and_parameters_if_necessary ( BulkTypeEventLogger *type_logger, + MonoMemPool *mem_pool, MonoType *mono_type) { // TODO Log the type if necessary - ep_rt_mono_log_type_and_parameters (type_logger, mono_type); + ep_rt_mono_log_type_and_parameters (type_logger, mem_pool, mono_type); } // ETW has a limit for maximum event size. Do not log overly large method type argument sets @@ -3386,6 +3393,7 @@ ep_rt_mono_send_method_details_event (MonoMethod *method) return; BulkTypeEventLogger *type_logger = ep_rt_bulk_type_event_logger_alloc (); + MonoMemPool *mem_pool = mono_mempool_new (); uint64_t method_type_id = 0; g_assert (mono_metadata_token_index (method->token) != 0); @@ -3396,7 +3404,7 @@ ep_rt_mono_send_method_details_event (MonoMethod *method) MonoType *method_mono_type = m_class_get_byval_arg (klass); method_type_id = get_typeid_for_class (klass); - ep_rt_mono_log_type_and_parameters_if_necessary (type_logger, method_mono_type); + ep_rt_mono_log_type_and_parameters_if_necessary (type_logger, mem_pool, method_mono_type); loader_module_id = (uint64_t)mono_class_get_image (klass); } @@ -3405,11 +3413,11 @@ ep_rt_mono_send_method_details_event (MonoMethod *method) if (method_inst) method_inst_parameter_types_count = method_inst->type_argc; - uint64_t *method_inst_parameters_type_ids = g_alloca (method_inst_parameter_types_count * sizeof (intptr_t)); + uint64_t *method_inst_parameters_type_ids = mono_mempool_alloc0 (mem_pool, method_inst_parameter_types_count * sizeof (uint64_t)); for (int 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_rt_mono_log_type_and_parameters_if_necessary (type_logger, method_inst->type_argv [i]); + ep_rt_mono_log_type_and_parameters_if_necessary (type_logger, mem_pool, method_inst->type_argv [i]); } ep_rt_mono_fire_bulk_type_event (type_logger); @@ -3424,6 +3432,7 @@ ep_rt_mono_send_method_details_event (MonoMethod *method) NULL, NULL); + mono_mempool_destroy (mem_pool); ep_rt_bulk_type_event_logger_free (type_logger); } diff --git a/src/mono/mono/eventpipe/ep-rt-mono.h b/src/mono/mono/eventpipe/ep-rt-mono.h index 801d4180e04f2c..430f0916d32364 100644 --- a/src/mono/mono/eventpipe/ep-rt-mono.h +++ b/src/mono/mono/eventpipe/ep-rt-mono.h @@ -2187,16 +2187,19 @@ ep_rt_mono_fire_bulk_type_event (BulkTypeEventLogger *p_type_logger); int ep_rt_mono_log_single_type ( BulkTypeEventLogger *p_type_logger, + MonoMemPool *mem_pool, MonoType *mono_type); void ep_rt_mono_log_type_and_parameters ( BulkTypeEventLogger *p_type_logger, + MonoMemPool *mem_pool, MonoType *mono_type); void ep_rt_mono_log_type_and_parameters_if_necessary ( BulkTypeEventLogger *p_type_logger, + MonoMemPool *mem_pool, MonoType *mono_type); void From b8985c54d0da5fd6da120441a41a478153bf0325 Mon Sep 17 00:00:00 2001 From: mdh1418 Date: Fri, 13 May 2022 10:21:54 -0400 Subject: [PATCH 26/28] Revert "Change Event struct parameter _ElementSize type to size_t" This reverts commit 87f87f2f93457bed292d979668dbad01beb1e5f1. --- src/coreclr/scripts/genEventPipe.py | 10 +++++----- src/coreclr/scripts/genEventing.py | 2 +- src/mono/mono/eventpipe/ep-rt-mono.c | 22 +++++++++++----------- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/coreclr/scripts/genEventPipe.py b/src/coreclr/scripts/genEventPipe.py index fdf0c7648fa24d..2f46735cc43e2c 100644 --- a/src/coreclr/scripts/genEventPipe.py +++ b/src/coreclr/scripts/genEventPipe.py @@ -53,7 +53,7 @@ def generateMethodSignatureWrite(eventName, template, extern, runtimeFlavor): if paramName in template.structs: sig_pieces.append( - "%ssize_t %s_ElementSize,\n" % + "%sint %s_ElementSize,\n" % (lindent, paramName)) sig_pieces.append(lindent) @@ -262,10 +262,10 @@ def generateWriteEventBody(template, providerName, eventName, runtimeFlavor): parameter = fnSig.getParam(paramName) if paramName in template.structs: - size = "(size_t)%s_ElementSize * (size_t)%s" % ( + size = "(int)%s_ElementSize * (int)%s" % ( paramName, parameter.prop) if template.name in specialCaseSizes and paramName in specialCaseSizes[template.name]: - size = "(size_t)(%s)" % specialCaseSizes[template.name][paramName] + size = "(int)(%s)" % specialCaseSizes[template.name][paramName] if runtimeFlavor.mono: pack_list.append( " success &= write_buffer((const uint8_t *)%s, %s, &buffer, &offset, &size, &fixedBuffer);" % @@ -277,11 +277,11 @@ def generateWriteEventBody(template, providerName, eventName, runtimeFlavor): (paramName, size)) emittedWriteToBuffer = True elif paramName in template.arrays: - size = "sizeof(%s) * (size_t)%s" % ( + size = "sizeof(%s) * (int)%s" % ( getLttngDataTypeMapping(runtimeFlavor)[parameter.winType], parameter.prop) if template.name in specialCaseSizes and paramName in specialCaseSizes[template.name]: - size = "(size_t)(%s)" % specialCaseSizes[template.name][paramName] + size = "(int)(%s)" % specialCaseSizes[template.name][paramName] if runtimeFlavor.mono: pack_list.append( " success &= write_buffer((const uint8_t *)%s, %s, &buffer, &offset, &size, &fixedBuffer);" % diff --git a/src/coreclr/scripts/genEventing.py b/src/coreclr/scripts/genEventing.py index 1abe7b3bef3675..f1e341a36b297e 100644 --- a/src/coreclr/scripts/genEventing.py +++ b/src/coreclr/scripts/genEventing.py @@ -533,7 +533,7 @@ def generateClrEventPipeWriteEvents(eventNodes, allTemplates, extern, target_cpp countw = getPalDataTypeMapping(runtimeFlavor)[winCount] if params in template.structs: - fnptypeline.append("%ssize_t %s_ElementSize,\n" % (lindent, params)) + fnptypeline.append("%sint %s_ElementSize,\n" % (lindent, params)) fnptypeline.append(lindent) fnptypeline.append(typewName) diff --git a/src/mono/mono/eventpipe/ep-rt-mono.c b/src/mono/mono/eventpipe/ep-rt-mono.c index 685fab195e6e43..25dd337bf66deb 100644 --- a/src/mono/mono/eventpipe/ep-rt-mono.c +++ b/src/mono/mono/eventpipe/ep-rt-mono.c @@ -2914,7 +2914,7 @@ void ep_rt_bulk_type_event_logger_free (BulkTypeEventLogger *type_logger); static -size_t +int write_event_buffer ( const uint8_t *val, size_t size, @@ -2922,28 +2922,28 @@ write_event_buffer ( char **buf_next); static -size_t +int write_event_buffer_int8 ( int8_t val, char *buf_start, char **buf_next); static -size_t +int write_event_buffer_int16 ( int16_t val, char *buf_start, char **buf_next); static -size_t +int write_event_buffer_int32 ( int32_t val, char *buf_start, char **buf_next); static -size_t +int write_event_buffer_int64 ( int64_t val, char *buf_start, @@ -3031,7 +3031,7 @@ ep_rt_bulk_type_event_logger_free (BulkTypeEventLogger *type_logger) } static -size_t +int write_event_buffer ( const uint8_t *val, size_t size, @@ -3044,7 +3044,7 @@ write_event_buffer ( } static -size_t +int write_event_buffer_int8 ( int8_t val, char *buf_start, @@ -3054,7 +3054,7 @@ write_event_buffer_int8 ( } static -size_t +int write_event_buffer_int16 ( int16_t val, char *buf_start, @@ -3064,7 +3064,7 @@ write_event_buffer_int16 ( } static -size_t +int write_event_buffer_int32 ( int32_t val, char *buf_start, @@ -3074,7 +3074,7 @@ write_event_buffer_int32 ( } static -size_t +int write_event_buffer_int64 ( int64_t val, char *buf_start, @@ -3099,7 +3099,7 @@ ep_rt_mono_fire_bulk_type_event (BulkTypeEventLogger *type_logger) uint16_t clr_instance_id = clr_instance_get_id (); - size_t values_element_size = 0; + uint32_t values_element_size = 0; char *ptr = (char *)type_logger->bulk_type_event_buffer; From 50bacd17c4693c35c4feb96780d88e50115c72e1 Mon Sep 17 00:00:00 2001 From: mdh1418 Date: Fri, 13 May 2022 11:21:55 -0400 Subject: [PATCH 27/28] Fix write_event_buffer parameter type to avoid C4267 error on windows --- src/mono/mono/eventpipe/ep-rt-mono.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mono/mono/eventpipe/ep-rt-mono.c b/src/mono/mono/eventpipe/ep-rt-mono.c index 25dd337bf66deb..5b970d918d62ad 100644 --- a/src/mono/mono/eventpipe/ep-rt-mono.c +++ b/src/mono/mono/eventpipe/ep-rt-mono.c @@ -2917,7 +2917,7 @@ static int write_event_buffer ( const uint8_t *val, - size_t size, + int size, char *buf_start, char **buf_next); @@ -3034,7 +3034,7 @@ static int write_event_buffer ( const uint8_t *val, - size_t size, + int size, char *buf_start, char **buf_next) { From 49d73665e05c9d205d368ebf6f796900f633f339 Mon Sep 17 00:00:00 2001 From: mdh1418 Date: Fri, 13 May 2022 11:34:17 -0400 Subject: [PATCH 28/28] Move mem_pool under BulkTypeEventLogger --- src/mono/mono/eventpipe/ep-rt-mono.c | 30 +++++++++++++--------------- src/mono/mono/eventpipe/ep-rt-mono.h | 3 --- 2 files changed, 14 insertions(+), 19 deletions(-) diff --git a/src/mono/mono/eventpipe/ep-rt-mono.c b/src/mono/mono/eventpipe/ep-rt-mono.c index 5b970d918d62ad..aeaeb605c361ad 100644 --- a/src/mono/mono/eventpipe/ep-rt-mono.c +++ b/src/mono/mono/eventpipe/ep-rt-mono.c @@ -3011,6 +3011,7 @@ struct _BulkTypeEventLogger { uint8_t *bulk_type_event_buffer; uint32_t bulk_type_value_count; uint32_t bulk_type_value_byte_count; + MonoMemPool *mem_pool; }; static @@ -3019,6 +3020,7 @@ ep_rt_bulk_type_event_logger_alloc () { BulkTypeEventLogger *type_logger = g_malloc0 (sizeof (BulkTypeEventLogger)); type_logger->bulk_type_event_buffer = g_malloc0 (sizeof (uint8_t) * MAX_SIZE_OF_EVENT_BUFFER); + type_logger->mem_pool = mono_mempool_new (); return type_logger; } @@ -3026,6 +3028,7 @@ static void ep_rt_bulk_type_event_logger_free (BulkTypeEventLogger *type_logger) { + mono_mempool_destroy (type_logger->mem_pool); g_free (type_logger->bulk_type_event_buffer); g_free (type_logger); } @@ -3189,7 +3192,6 @@ get_typeid_for_class (MonoClass *c) int ep_rt_mono_log_single_type ( BulkTypeEventLogger *type_logger, - MonoMemPool *mem_pool, MonoType *mono_type) { // If there's no room for another type, flush what we've got @@ -3236,7 +3238,7 @@ ep_rt_mono_log_single_type ( } // mono arrays are always arrays of by value types - val->mono_type_parameters = mono_mempool_alloc0 (mem_pool, 1 * sizeof (MonoType*)); + val->mono_type_parameters = mono_mempool_alloc0 (type_logger->mem_pool, 1 * sizeof (MonoType*)); *val->mono_type_parameters = m_class_get_byval_arg (mono_array_type->eklass); val->type_parameters_count++; break; @@ -3245,7 +3247,7 @@ ep_rt_mono_log_single_type ( { MonoGenericInst *class_inst = mono_type->data.generic_class->context.class_inst; val->type_parameters_count = class_inst->type_argc; - val->mono_type_parameters = mono_mempool_alloc0 (mem_pool, val->type_parameters_count * sizeof (MonoType*)); + val->mono_type_parameters = mono_mempool_alloc0 (type_logger->mem_pool, val->type_parameters_count * sizeof (MonoType*)); memcpy (val->mono_type_parameters, class_inst->type_argv, val->type_parameters_count * sizeof (MonoType*)); break; } @@ -3256,7 +3258,7 @@ ep_rt_mono_log_single_type ( { if (mono_underlying_type == mono_type) break; - val->mono_type_parameters = mono_mempool_alloc0 (mem_pool, 1 * sizeof (MonoType*)); + val->mono_type_parameters = mono_mempool_alloc0 (type_logger->mem_pool, 1 * sizeof (MonoType*)); *val->mono_type_parameters = mono_underlying_type; val->type_parameters_count++; break; @@ -3285,7 +3287,7 @@ ep_rt_mono_log_single_type ( // call itself again. g_assert (type_logger->bulk_type_value_byte_count + val_byte_count > MAX_TYPE_VALUES_BYTES); ep_rt_mono_fire_bulk_type_event (type_logger); - return ep_rt_mono_log_single_type (type_logger, mem_pool, mono_type); + return ep_rt_mono_log_single_type (type_logger, mono_type); } // The type fits into the batch, so update our state @@ -3308,12 +3310,11 @@ ep_rt_mono_log_single_type ( void ep_rt_mono_log_type_and_parameters ( BulkTypeEventLogger *type_logger, - MonoMemPool *mem_pool, MonoType *mono_type) { // Batch up this type. This grabs useful info about the type, including any // type parameters it may have, and sticks it in bulk_type_values - int bulk_type_value_index = ep_rt_mono_log_single_type (type_logger, mem_pool, mono_type); + int bulk_type_value_index = ep_rt_mono_log_single_type (type_logger, mono_type); if (bulk_type_value_index == -1) { // There was a failure trying to log the type, so don't bother with its type // parameters @@ -3330,11 +3331,11 @@ ep_rt_mono_log_type_and_parameters ( if (param_count == 0) return; - MonoType **mono_type_parameters = mono_mempool_alloc0 (mem_pool, param_count * sizeof (MonoType*)); + MonoType **mono_type_parameters = mono_mempool_alloc0 (type_logger->mem_pool, param_count * sizeof (MonoType*)); memcpy (mono_type_parameters, val->mono_type_parameters, sizeof (MonoType*) * param_count); for (uint32_t i = 0; i < param_count; i++) - ep_rt_mono_log_type_and_parameters_if_necessary (type_logger, mem_pool, mono_type_parameters [i]); + ep_rt_mono_log_type_and_parameters_if_necessary (type_logger, mono_type_parameters [i]); } //--------------------------------------------------------------------------------------- @@ -3351,12 +3352,11 @@ ep_rt_mono_log_type_and_parameters ( void ep_rt_mono_log_type_and_parameters_if_necessary ( BulkTypeEventLogger *type_logger, - MonoMemPool *mem_pool, MonoType *mono_type) { // TODO Log the type if necessary - ep_rt_mono_log_type_and_parameters (type_logger, mem_pool, mono_type); + ep_rt_mono_log_type_and_parameters (type_logger, mono_type); } // ETW has a limit for maximum event size. Do not log overly large method type argument sets @@ -3393,7 +3393,6 @@ ep_rt_mono_send_method_details_event (MonoMethod *method) return; BulkTypeEventLogger *type_logger = ep_rt_bulk_type_event_logger_alloc (); - MonoMemPool *mem_pool = mono_mempool_new (); uint64_t method_type_id = 0; g_assert (mono_metadata_token_index (method->token) != 0); @@ -3404,7 +3403,7 @@ ep_rt_mono_send_method_details_event (MonoMethod *method) MonoType *method_mono_type = m_class_get_byval_arg (klass); method_type_id = get_typeid_for_class (klass); - ep_rt_mono_log_type_and_parameters_if_necessary (type_logger, mem_pool, method_mono_type); + ep_rt_mono_log_type_and_parameters_if_necessary (type_logger, method_mono_type); loader_module_id = (uint64_t)mono_class_get_image (klass); } @@ -3413,11 +3412,11 @@ ep_rt_mono_send_method_details_event (MonoMethod *method) if (method_inst) method_inst_parameter_types_count = method_inst->type_argc; - uint64_t *method_inst_parameters_type_ids = mono_mempool_alloc0 (mem_pool, method_inst_parameter_types_count * sizeof (uint64_t)); + uint64_t *method_inst_parameters_type_ids = mono_mempool_alloc0 (type_logger->mem_pool, method_inst_parameter_types_count * sizeof (uint64_t)); for (int 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_rt_mono_log_type_and_parameters_if_necessary (type_logger, mem_pool, method_inst->type_argv [i]); + ep_rt_mono_log_type_and_parameters_if_necessary (type_logger, method_inst->type_argv [i]); } ep_rt_mono_fire_bulk_type_event (type_logger); @@ -3432,7 +3431,6 @@ ep_rt_mono_send_method_details_event (MonoMethod *method) NULL, NULL); - mono_mempool_destroy (mem_pool); ep_rt_bulk_type_event_logger_free (type_logger); } diff --git a/src/mono/mono/eventpipe/ep-rt-mono.h b/src/mono/mono/eventpipe/ep-rt-mono.h index 430f0916d32364..801d4180e04f2c 100644 --- a/src/mono/mono/eventpipe/ep-rt-mono.h +++ b/src/mono/mono/eventpipe/ep-rt-mono.h @@ -2187,19 +2187,16 @@ ep_rt_mono_fire_bulk_type_event (BulkTypeEventLogger *p_type_logger); int ep_rt_mono_log_single_type ( BulkTypeEventLogger *p_type_logger, - MonoMemPool *mem_pool, MonoType *mono_type); void ep_rt_mono_log_type_and_parameters ( BulkTypeEventLogger *p_type_logger, - MonoMemPool *mem_pool, MonoType *mono_type); void ep_rt_mono_log_type_and_parameters_if_necessary ( BulkTypeEventLogger *p_type_logger, - MonoMemPool *mem_pool, MonoType *mono_type); void