Adapt more Mono profiler events into NativeRuntimeEvents. (#53677)
authorJohan Lorensson <lateralusx.github@gmail.com>
Fri, 4 Jun 2021 15:17:11 +0000 (17:17 +0200)
committerGitHub <noreply@github.com>
Fri, 4 Jun 2021 15:17:11 +0000 (17:17 +0200)
src/mono/mono/eventpipe/ep-rt-mono.c
src/mono/mono/eventpipe/ep-rt-mono.h
src/mono/mono/eventpipe/gen-eventing-event-inc.lst
src/mono/mono/metadata/gc-internals.h
src/mono/mono/metadata/object-internals.h
src/mono/mono/metadata/profiler-private.h
src/mono/mono/metadata/profiler.c

index 6a57467..8416cf0 100644 (file)
@@ -19,6 +19,7 @@
 #include <mono/metadata/class-internals.h>
 #include <mono/metadata/debug-internals.h>
 #include <mono/metadata/gc-internals.h>
+#include <mono/metadata/profiler-private.h>
 #include <mono/mini/mini-runtime.h>
 #include <runtime_version.h>
 #include <clretwallmain.h>
@@ -136,6 +137,45 @@ typedef struct _EventPipeSampleProfileData {
 #define DOMAIN_FLAGS_DEFAULT_DOMAIN 0x1
 #define DOMAIN_FLAGS_EXECUTABLE_DOMAIN 0x2
 
+// Event data types.
+struct _ModuleEventData {
+       uint8_t signature [EP_GUID_SIZE];
+       uint64_t domain_id;
+       uint64_t module_id;
+       uint64_t assembly_id;
+       const char *module_il_path;
+       const char *module_il_pdb_path;
+       const char *module_native_path;
+       const char *module_native_pdb_path;
+       uint32_t module_il_pdb_age;
+       uint32_t module_native_pdb_age;
+       uint32_t reserved_flags;
+       uint32_t module_flags;
+};
+
+typedef struct _ModuleEventData ModuleEventData;
+
+struct _AssemblyEventData {
+       uint64_t domain_id;
+       uint64_t assembly_id;
+       uint64_t binding_id;
+       char *assembly_name;
+       uint32_t assembly_flags;
+};
+
+typedef struct _AssemblyEventData AssemblyEventData;
+
+// Event flags.
+#define THREAD_FLAGS_GC_SPECIAL 0x00000001
+#define THREAD_FLAGS_FINALIZER 0x00000002
+#define THREAD_FLAGS_THREADPOOL_WORKER 0x00000004
+
+#define EXCEPTION_THROWN_FLAGS_HAS_INNER 0x1
+#define EXCEPTION_THROWN_FLAGS_IS_NESTED 0x2
+#define EXCEPTION_THROWN_FLAGS_IS_RETHROWN 0x4
+#define EXCEPTION_THROWN_FLAGS_IS_CSE 0x8
+#define EXCEPTION_THROWN_FLAGS_IS_CLS_COMPLIANT 0x10
+
 /*
  * Forward declares of all static functions.
  */
@@ -237,6 +277,29 @@ profiler_eventpipe_thread_exited (
        uintptr_t tid);
 
 static
+bool
+get_module_event_data (
+       MonoImage *image,
+       ModuleEventData *module_data);
+
+static
+bool
+get_assembly_event_data (
+       MonoAssembly *assembly,
+       AssemblyEventData *assembly_data);
+
+static
+uint32_t
+get_type_start_id (MonoType *type);
+
+static
+gboolean
+get_exception_ip_func (
+       MonoStackFrameInfo *frame,
+       MonoContext *ctx,
+       void *data);
+
+static
 void
 profiler_jit_begin (
        MonoProfiler *prof,
@@ -263,10 +326,94 @@ profiler_image_loaded (
 
 static
 void
+profiler_image_unloaded (
+       MonoProfiler *prof,
+       MonoImage *image);
+
+static
+void
 profiler_assembly_loaded (
        MonoProfiler *prof,
        MonoAssembly *assembly);
 
+static
+void
+profiler_assembly_unloaded (
+       MonoProfiler *prof,
+       MonoAssembly *assembly);
+
+static
+void
+profiler_thread_started (
+       MonoProfiler *prof,
+       uintptr_t tid);
+
+static
+void
+profiler_thread_stopped (
+       MonoProfiler *prof,
+       uintptr_t tid);
+
+static
+void
+profiler_class_loading (
+       MonoProfiler *prof,
+       MonoClass *klass);
+
+static
+void
+profiler_class_failed (
+       MonoProfiler *prof,
+       MonoClass *klass);
+
+static
+void
+profiler_class_loaded (
+       MonoProfiler *prof,
+       MonoClass *klass);
+
+static
+void
+profiler_exception_throw (
+       MonoProfiler *prof,
+       MonoObject *exception);
+
+static
+void
+profiler_exception_clause (
+       MonoProfiler *prof,
+       MonoMethod *method,
+       uint32_t clause_num,
+       MonoExceptionEnum clause_type,
+       MonoObject *exc);
+
+static
+void
+profiler_monitor_contention (
+       MonoProfiler *prof,
+       MonoObject *obj);
+
+static
+void
+profiler_monitor_acquired (
+       MonoProfiler *prof,
+       MonoObject *obj);
+
+static
+void
+profiler_monitor_failed (
+       MonoProfiler *prof,
+       MonoObject *obj);
+
+static
+void
+profiler_jit_code_buffer (
+       MonoProfiler *prof,
+       const mono_byte *buffer,
+       uint64_t size,
+       MonoProfilerCodeBufferType type,
+       const void *data);
+
 /*
  * Forward declares of all private functions (accessed using extern in ep-rt-mono.h).
  */
@@ -1284,9 +1431,9 @@ ep_rt_mono_walk_managed_stack_for_thread (
 {
        EP_ASSERT (thread != NULL && stack_contents != NULL);
 
-       if (thread == ep_rt_thread_get_handle ())
+       if (thread == ep_rt_thread_get_handle () && mono_get_eh_callbacks ()->mono_walk_stack_with_ctx)
                mono_get_eh_callbacks ()->mono_walk_stack_with_ctx (eventpipe_walk_managed_stack_for_thread_func, NULL, MONO_UNWIND_SIGNAL_SAFE, stack_contents);
-       else
+       else if (mono_get_eh_callbacks ()->mono_walk_stack_with_state)
                mono_get_eh_callbacks ()->mono_walk_stack_with_state (eventpipe_walk_managed_stack_for_thread_func, mono_thread_info_get_suspend_state (thread), MONO_UNWIND_SIGNAL_SAFE, stack_contents);
 
        return true;
@@ -1724,109 +1871,520 @@ ep_rt_mono_write_event_method_load (
        return true;
 }
 
+static
 bool
-ep_rt_mono_write_event_module_load (MonoImage *image)
+get_module_event_data (
+       MonoImage *image,
+       ModuleEventData *module_data)
 {
-       if (!EventEnabledModuleLoad_V2 () && !EventEnabledDomainModuleLoad_V1())
-               return true;
+       if (image && module_data) {
+               memset (module_data->signature, 0, EP_GUID_SIZE);
 
-       if (image) {
                // Under netcore we only have root domain.
                MonoDomain *root_domain = mono_get_root_domain ();
 
-               uint64_t domain_id = (uint64_t)root_domain;
-               uint64_t module_id = (uint64_t)image;
-               uint64_t assembly_id = (uint64_t)image->assembly;
+               module_data->domain_id = (uint64_t)root_domain;
+               module_data->module_id = (uint64_t)image;
+               module_data->assembly_id = (uint64_t)image->assembly;
 
                // TODO: Extract all module IL/Native paths and pdb metadata when available.
-               const char *module_il_path = "";
-               const char *module_il_pdb_path = "";
-               const char *module_native_path = "";
-               const char *module_native_pdb_path = "";
-               uint8_t signature [EP_GUID_SIZE] = { 0 };
-               uint32_t module_il_pdb_age = 0;
-               uint32_t module_native_pdb_age = 0;
+               module_data->module_il_path = "";
+               module_data->module_il_pdb_path = "";
+               module_data->module_native_path = "";
+               module_data->module_native_pdb_path = "";
 
-               uint32_t reserved_flags = 0;
+               module_data->module_il_pdb_age = 0;
+               module_data->module_native_pdb_age = 0;
+
+               module_data->reserved_flags = 0;
 
                // Netcore has a 1:1 between assemblies and modules, so its always a manifest module.
-               uint32_t module_flags = MODULE_FLAGS_MANIFEST_MODULE;
+               module_data->module_flags = MODULE_FLAGS_MANIFEST_MODULE;
                if (image->dynamic)
-                       module_flags |= MODULE_FLAGS_DYNAMIC_MODULE;
+                       module_data->module_flags |= MODULE_FLAGS_DYNAMIC_MODULE;
                if (image->aot_module)
-                       module_flags |= MODULE_FLAGS_NATIVE_MODULE;
+                       module_data->module_flags |= MODULE_FLAGS_NATIVE_MODULE;
 
-               module_il_path = image->filename ? image->filename : "";
+               module_data->module_il_path = image->filename ? image->filename : "";
+       }
 
-               FireEtwModuleLoad_V2 (
-                       module_id,
-                       assembly_id,
-                       module_flags,
-                       reserved_flags,
-                       module_il_path,
-                       module_native_path,
-                       clr_instance_get_id (),
-                       signature,
-                       module_il_pdb_age,
-                       module_il_pdb_path,
-                       signature,
-                       module_native_pdb_age,
-                       module_native_pdb_path,
-                       NULL,
-                       NULL);
+       return true;
+}
 
-               FireEtwDomainModuleLoad_V1 (
-                       module_id,
-                       assembly_id,
-                       domain_id,
-                       module_flags,
-                       reserved_flags,
-                       module_il_path,
-                       module_native_path,
-                       clr_instance_get_id (),
-                       NULL,
-                       NULL);
+bool
+ep_rt_mono_write_event_module_load (MonoImage *image)
+{
+       if (!EventEnabledModuleLoad_V2 () && !EventEnabledDomainModuleLoad_V1())
+               return true;
+
+       if (image) {
+               ModuleEventData module_data;
+               if (get_module_event_data (image, &module_data)) {
+                       FireEtwModuleLoad_V2 (
+                               module_data.module_id,
+                               module_data.assembly_id,
+                               module_data.module_flags,
+                               module_data.reserved_flags,
+                               module_data.module_il_path,
+                               module_data.module_native_path,
+                               clr_instance_get_id (),
+                               module_data.signature,
+                               module_data.module_il_pdb_age,
+                               module_data.module_il_pdb_path,
+                               module_data.signature,
+                               module_data.module_native_pdb_age,
+                               module_data.module_native_pdb_path,
+                               NULL,
+                               NULL);
+
+                       FireEtwDomainModuleLoad_V1 (
+                               module_data.module_id,
+                               module_data.assembly_id,
+                               module_data.domain_id,
+                               module_data.module_flags,
+                               module_data.reserved_flags,
+                               module_data.module_il_path,
+                               module_data.module_native_path,
+                               clr_instance_get_id (),
+                               NULL,
+                               NULL);
+               }
        }
 
        return true;
 }
 
 bool
-ep_rt_mono_write_event_assembly_load (MonoAssembly *assembly)
+ep_rt_mono_write_event_module_unload (MonoImage *image)
 {
-       if (!EventEnabledAssemblyLoad_V1 ())
+       if (!EventEnabledModuleUnload_V2())
                return true;
 
-       if (assembly) {
+       if (image) {
+               ModuleEventData module_data;
+               if (get_module_event_data (image, &module_data)) {
+                       FireEtwModuleUnload_V2 (
+                               module_data.module_id,
+                               module_data.assembly_id,
+                               module_data.module_flags,
+                               module_data.reserved_flags,
+                               module_data.module_il_path,
+                               module_data.module_native_path,
+                               clr_instance_get_id (),
+                               module_data.signature,
+                               module_data.module_il_pdb_age,
+                               module_data.module_il_pdb_path,
+                               module_data.signature,
+                               module_data.module_native_pdb_age,
+                               module_data.module_native_pdb_path,
+                               NULL,
+                               NULL);
+               }
+       }
+
+       return true;
+}
+
+static
+bool
+get_assembly_event_data (
+       MonoAssembly *assembly,
+       AssemblyEventData *assembly_data)
+{
+       if (assembly && assembly_data) {
                // Under netcore we only have root domain.
                MonoDomain *root_domain = mono_get_root_domain ();
 
-               uint64_t domain_id = (uint64_t)root_domain;
-               uint64_t assembly_id = (uint64_t)assembly;
-               uint64_t binding_id = 0;
+               assembly_data->domain_id = (uint64_t)root_domain;
+               assembly_data->assembly_id = (uint64_t)assembly;
+               assembly_data->binding_id = 0;
 
-               uint32_t assembly_flags = 0;
+               assembly_data->assembly_flags = 0;
                if (assembly->dynamic)
-                       assembly_flags |= ASSEMBLY_FLAGS_DYNAMIC_ASSEMBLY;
+                       assembly_data->assembly_flags |= ASSEMBLY_FLAGS_DYNAMIC_ASSEMBLY;
 
                if (assembly->image && assembly->image->aot_module)
-                       assembly_flags |= ASSEMBLY_FLAGS_NATIVE_ASSEMBLY;
+                       assembly_data->assembly_flags |= ASSEMBLY_FLAGS_NATIVE_ASSEMBLY;
 
-               char *assembly_name = mono_stringify_assembly_name (&assembly->aname);
+               assembly_data->assembly_name = mono_stringify_assembly_name (&assembly->aname);
+       }
 
-               FireEtwAssemblyLoad_V1 (
-                       assembly_id,
-                       domain_id,
-                       binding_id,
-                       assembly_flags,
-                       assembly_name,
+       return true;
+}
+
+bool
+ep_rt_mono_write_event_assembly_load (MonoAssembly *assembly)
+{
+       if (!EventEnabledAssemblyLoad_V1 ())
+               return true;
+
+       if (assembly) {
+               AssemblyEventData assembly_data;
+               if (get_assembly_event_data (assembly, &assembly_data)) {
+                       FireEtwAssemblyLoad_V1 (
+                               assembly_data.assembly_id,
+                               assembly_data.domain_id,
+                               assembly_data.binding_id,
+                               assembly_data.assembly_flags,
+                               assembly_data.assembly_name,
+                               clr_instance_get_id (),
+                               NULL,
+                               NULL);
+
+                       g_free (assembly_data.assembly_name);
+               }
+       }
+
+       return true;
+}
+
+bool
+ep_rt_mono_write_event_assembly_unload (MonoAssembly *assembly)
+{
+       if (!EventEnabledAssemblyUnload_V1 ())
+               return true;
+
+       if (assembly) {
+               AssemblyEventData assembly_data;
+               if (get_assembly_event_data (assembly, &assembly_data)) {
+                       FireEtwAssemblyUnload_V1 (
+                               assembly_data.assembly_id,
+                               assembly_data.domain_id,
+                               assembly_data.binding_id,
+                               assembly_data.assembly_flags,
+                               assembly_data.assembly_name,
+                               clr_instance_get_id (),
+                               NULL,
+                               NULL);
+
+                       g_free (assembly_data.assembly_name);
+               }
+       }
+
+       return true;
+}
+
+bool
+ep_rt_mono_write_event_thread_created (ep_rt_thread_id_t tid)
+{
+       if (!EventEnabledThreadCreated ())
+               return true;
+
+       uint64_t managed_thread = 0;
+       uint64_t native_thread_id = ep_rt_thread_id_t_to_uint64_t (tid);
+       uint64_t managed_thread_id = 0;
+       uint32_t flags = 0;
+
+       MonoThread *thread = mono_thread_current ();
+       if (thread && mono_thread_info_get_tid (thread->thread_info) == tid) {
+               managed_thread_id = (uint64_t)mono_thread_get_managed_id (thread);
+               managed_thread = (uint64_t)thread;
+
+               switch (mono_thread_info_get_flags (thread->thread_info)) {
+               case MONO_THREAD_INFO_FLAGS_NO_GC:
+               case MONO_THREAD_INFO_FLAGS_NO_SAMPLE:
+                       flags |= THREAD_FLAGS_GC_SPECIAL;
+               }
+
+               if (mono_gc_is_finalizer_thread (thread))
+                       flags |= THREAD_FLAGS_FINALIZER;
+
+               if (thread->threadpool_thread)
+                       flags |= THREAD_FLAGS_THREADPOOL_WORKER;
+       }
+
+       FireEtwThreadCreated (
+               managed_thread,
+               (uint64_t)mono_get_root_domain (),
+               flags,
+               managed_thread_id,
+               native_thread_id,
+               clr_instance_get_id (),
+               NULL,
+               NULL);
+
+       return true;
+}
+
+bool
+ep_rt_mono_write_event_thread_terminated (ep_rt_thread_id_t tid)
+{
+       if (!EventEnabledThreadTerminated ())
+               return true;
+
+       uint64_t managed_thread = 0;
+       MonoThread *thread = mono_thread_current ();
+       if (thread && mono_thread_info_get_tid (thread->thread_info) == tid)
+               managed_thread = (uint64_t)thread;
+
+       FireEtwThreadTerminated (
+               managed_thread,
+               (uint64_t)mono_get_root_domain (),
+               clr_instance_get_id (),
+               NULL,
+               NULL);
+
+       return true;
+}
+
+static
+uint32_t
+get_type_start_id (MonoType *type)
+{
+       uint32_t start_id = (uint32_t)(uintptr_t)type;
+
+       start_id = (((start_id * 215497) >> 16) ^ ((start_id * 1823231) + start_id));
+
+       // Mix in highest bits on 64-bit systems only
+       if (sizeof (type) > 4)
+               start_id = start_id ^ (((uint64_t)type >> 31) >> 1);
+
+       return start_id;
+}
+
+bool
+ep_rt_mono_write_event_type_load_start (MonoType *type)
+{
+       if (!EventEnabledTypeLoadStart ())
+               return true;
+
+       FireEtwTypeLoadStart (
+               get_type_start_id (type),
+               clr_instance_get_id (),
+               NULL,
+               NULL);
+
+       return true;
+}
+
+bool
+ep_rt_mono_write_event_type_load_stop (MonoType *type)
+{
+       if (!EventEnabledTypeLoadStop ())
+               return true;
+
+       char *type_name = NULL;
+       if (type)
+               type_name = mono_type_get_name_full (type, MONO_TYPE_NAME_FORMAT_IL);
+
+       FireEtwTypeLoadStop (
+               get_type_start_id (type),
+               clr_instance_get_id (),
+               6 /* CLASS_LOADED */,
+               (uint64_t)type,
+               type_name,
+               NULL,
+               NULL);
+
+       g_free (type_name);
+
+       return true;
+}
+
+static
+gboolean
+get_exception_ip_func (
+       MonoStackFrameInfo *frame,
+       MonoContext *ctx,
+       void *data)
+{
+       *(uintptr_t *)data = (uintptr_t)MONO_CONTEXT_GET_IP (ctx);
+       return TRUE;
+}
+
+bool
+ep_rt_mono_write_event_exception_thrown (MonoObject *obj)
+{
+       if (!EventEnabledExceptionThrown_V1 ())
+               return true;
+
+       if (obj) {
+               ERROR_DECL (error);
+               char *type_name = NULL;
+               char *exception_message = NULL;
+               uint16_t flags = 0;
+               uint32_t hresult = 0;
+               uintptr_t ip = 0;
+
+               if (mono_object_isinst_checked ((MonoObject *) obj, mono_get_exception_class (), error)) {
+                       MonoException *exception = (MonoException *)obj;
+                       flags |= EXCEPTION_THROWN_FLAGS_IS_CLS_COMPLIANT;
+                       if (exception->inner_ex)
+                               flags |= EXCEPTION_THROWN_FLAGS_HAS_INNER;
+                       exception_message = ep_rt_utf16_to_utf8_string (mono_string_chars_internal (exception->message), mono_string_length_internal (exception->message));
+                       hresult = exception->hresult;
+               }
+
+               if (mono_get_eh_callbacks ()->mono_walk_stack_with_ctx)
+                       mono_get_eh_callbacks ()->mono_walk_stack_with_ctx (get_exception_ip_func, NULL, MONO_UNWIND_SIGNAL_SAFE, (void *)&ip);
+
+               type_name = mono_type_get_name_full (m_class_get_byval_arg (mono_object_class (obj)), MONO_TYPE_NAME_FORMAT_IL);
+
+               FireEtwExceptionThrown_V1 (
+                       type_name,
+                       exception_message,
+                       (void *)&ip,
+                       hresult,
+                       flags,
+                       clr_instance_get_id (),
+                       NULL,
+                       NULL);
+
+               if (!mono_component_profiler_clauses_enabled ()) {
+                       FireEtwExceptionThrownStop (
+                               NULL,
+                               NULL);
+               }
+
+               g_free (exception_message);
+               g_free (type_name);
+
+               mono_error_cleanup (error);
+       }
+
+       return true;
+}
+
+bool
+ep_rt_mono_write_event_exception_clause (
+       MonoMethod *method,
+       uint32_t clause_num,
+       MonoExceptionEnum clause_type,
+       MonoObject *obj)
+{
+       if (!mono_component_profiler_clauses_enabled ())
+               return true;
+
+       if ((clause_type == MONO_EXCEPTION_CLAUSE_FAULT || clause_type == MONO_EXCEPTION_CLAUSE_NONE) && (!EventEnabledExceptionCatchStart() || !EventEnabledExceptionCatchStop()))
+               return true;
+
+       if (clause_type == MONO_EXCEPTION_CLAUSE_FILTER && (!EventEnabledExceptionFilterStart() || !EventEnabledExceptionFilterStop()))
+               return true;
+
+       if (clause_type == MONO_EXCEPTION_CLAUSE_FINALLY && (!EventEnabledExceptionFinallyStart() || !EventEnabledExceptionFinallyStop()))
+               return true;
+
+       uintptr_t ip = 0; //TODO: Have profiler pass along IP of handler block.
+       uint64_t method_id = (uint64_t)method;
+       char *method_name = NULL;
+
+       method_name = mono_method_get_name_full (method, TRUE, TRUE, MONO_TYPE_NAME_FORMAT_IL);
+
+       if ((clause_type == MONO_EXCEPTION_CLAUSE_FAULT || clause_type == MONO_EXCEPTION_CLAUSE_NONE)) {
+               FireEtwExceptionCatchStart (
+                       (uint64_t)ip,
+                       method_id,
+                       (const ep_char8_t *)method_name,
                        clr_instance_get_id (),
                        NULL,
                        NULL);
 
-               g_free (assembly_name);
+               FireEtwExceptionCatchStop (
+                       NULL,
+                       NULL);
+
+               FireEtwExceptionThrownStop (
+                       NULL,
+                       NULL);
        }
 
+       if (clause_type == MONO_EXCEPTION_CLAUSE_FILTER) {
+               FireEtwExceptionFilterStart (
+                       (uint64_t)ip,
+                       method_id,
+                       (const ep_char8_t *)method_name,
+                       clr_instance_get_id (),
+                       NULL,
+                       NULL);
+
+               FireEtwExceptionFilterStop (
+                       NULL,
+                       NULL);
+       }
+
+       if (clause_type == MONO_EXCEPTION_CLAUSE_FINALLY) {
+               FireEtwExceptionFinallyStart (
+                       (uint64_t)ip,
+                       method_id,
+                       (const ep_char8_t *)method_name,
+                       clr_instance_get_id (),
+                       NULL,
+                       NULL);
+
+               FireEtwExceptionFinallyStop (
+                       NULL,
+                       NULL);
+       }
+
+       g_free (method_name);
+       return true;
+}
+
+bool
+ep_rt_mono_write_event_monitor_contention_start (MonoObject *obj)
+{
+       if (!EventEnabledContentionStart_V1 ())
+               return true;
+
+       FireEtwContentionStart_V1 (
+               0 /* ManagedContention */,
+               clr_instance_get_id (),
+               NULL,
+               NULL);
+
+       return true;
+}
+
+bool
+ep_rt_mono_write_event_monitor_contention_stop (MonoObject *obj)
+{
+       if (!EventEnabledContentionStop ())
+               return true;
+
+       FireEtwContentionStop (
+               0 /* ManagedContention */,
+               clr_instance_get_id (),
+               NULL,
+               NULL);
+
+       return true;
+}
+
+bool
+ep_rt_mono_write_event_method_jit_memory_allocated_for_code (
+       const uint8_t *buffer,
+       uint64_t size,
+       MonoProfilerCodeBufferType type,
+       const void *data)
+{
+       if (!EventEnabledMethodJitMemoryAllocatedForCode ())
+               return true;
+
+       if (type != MONO_PROFILER_CODE_BUFFER_METHOD)
+               return true;
+
+       uint64_t method_id = 0;
+       uint64_t module_id = 0;
+
+       if (data) {
+               MonoMethod *method;
+               method = (MonoMethod *)data;
+               method_id = (uint64_t)method;
+               if (method->klass)
+                       module_id = (uint64_t)(uint64_t)m_class_get_image (method->klass);
+       }
+
+       FireEtwMethodJitMemoryAllocatedForCode (
+               method_id,
+               module_id,
+               size,
+               0,
+               size,
+               0 /* CORJIT_ALLOCMEM_DEFAULT_CODE_ALIGN */,
+               clr_instance_get_id (),
+               NULL,
+               NULL);
+
        return true;
 }
 
@@ -2013,6 +2571,16 @@ profiler_image_loaded (
 
 static
 void
+profiler_image_unloaded (
+       MonoProfiler *prof,
+       MonoImage *image)
+{
+       if (image && image->heap_pdb.size == 0)
+               ep_rt_mono_write_event_module_unload (image);
+}
+
+static
+void
 profiler_assembly_loaded (
        MonoProfiler *prof,
        MonoAssembly *assembly)
@@ -2020,6 +2588,120 @@ profiler_assembly_loaded (
        ep_rt_mono_write_event_assembly_load (assembly);
 }
 
+static
+void
+profiler_assembly_unloaded (
+       MonoProfiler *prof,
+       MonoAssembly *assembly)
+{
+       ep_rt_mono_write_event_assembly_unload (assembly);
+}
+
+static
+void
+profiler_thread_started (
+       MonoProfiler *prof,
+       uintptr_t tid)
+{
+       ep_rt_mono_write_event_thread_created (ep_rt_uint64_t_to_thread_id_t (tid));
+}
+
+static
+void
+profiler_thread_stopped (
+       MonoProfiler *prof,
+       uintptr_t tid)
+{
+       ep_rt_mono_write_event_thread_terminated (ep_rt_uint64_t_to_thread_id_t (tid));
+}
+
+static
+void
+profiler_class_loading (
+       MonoProfiler *prof,
+       MonoClass *klass)
+{
+       ep_rt_mono_write_event_type_load_start (m_class_get_byval_arg (klass));
+}
+
+static
+void
+profiler_class_failed (
+       MonoProfiler *prof,
+       MonoClass *klass)
+{
+       ep_rt_mono_write_event_type_load_stop (m_class_get_byval_arg (klass));
+}
+
+static
+void
+profiler_class_loaded (
+       MonoProfiler *prof,
+       MonoClass *klass)
+{
+       ep_rt_mono_write_event_type_load_stop (m_class_get_byval_arg (klass));
+}
+
+static
+void
+profiler_exception_throw (
+       MonoProfiler *prof,
+       MonoObject *exc)
+{
+       ep_rt_mono_write_event_exception_thrown (exc);
+}
+
+static
+void
+profiler_exception_clause (
+       MonoProfiler *prof,
+       MonoMethod *method,
+       uint32_t clause_num,
+       MonoExceptionEnum clause_type,
+       MonoObject *exc)
+{
+       ep_rt_mono_write_event_exception_clause (method, clause_num, clause_type, exc);
+}
+
+static
+void
+profiler_monitor_contention (
+       MonoProfiler *prof,
+       MonoObject *obj)
+{
+       ep_rt_mono_write_event_monitor_contention_start (obj);
+}
+
+static
+void
+profiler_monitor_acquired (
+       MonoProfiler *prof,
+       MonoObject *obj)
+{
+       ep_rt_mono_write_event_monitor_contention_stop (obj);
+}
+
+static
+void
+profiler_monitor_failed (
+       MonoProfiler *prof,
+       MonoObject *obj)
+{
+       ep_rt_mono_write_event_monitor_contention_stop (obj);
+}
+
+static
+void
+profiler_jit_code_buffer (
+       MonoProfiler *prof,
+       const mono_byte *buffer,
+       uint64_t size,
+       MonoProfilerCodeBufferType type,
+       const void *data)
+{
+       ep_rt_mono_write_event_method_jit_memory_allocated_for_code ((const uint8_t *)buffer, size, type, data);
+}
+
 void
 EventPipeEtwCallbackDotNETRuntime (
        const uint8_t *source_id,
@@ -2042,10 +2724,36 @@ EventPipeEtwCallbackDotNETRuntime (
                        mono_profiler_set_jit_failed_callback (_ep_rt_mono_profiler, profiler_jit_failed);
                        mono_profiler_set_jit_done_callback (_ep_rt_mono_profiler, profiler_jit_done);
                        mono_profiler_set_image_loaded_callback (_ep_rt_mono_profiler, profiler_image_loaded);
+                       mono_profiler_set_image_unloaded_callback (_ep_rt_mono_profiler, profiler_image_unloaded);
                        mono_profiler_set_assembly_loaded_callback (_ep_rt_mono_profiler, profiler_assembly_loaded);
+                       mono_profiler_set_assembly_unloaded_callback (_ep_rt_mono_profiler, profiler_assembly_unloaded);
+                       mono_profiler_set_thread_started_callback (_ep_rt_mono_profiler, profiler_thread_started);
+                       mono_profiler_set_thread_stopped_callback (_ep_rt_mono_profiler, profiler_thread_stopped);
+                       mono_profiler_set_class_loading_callback (_ep_rt_mono_profiler, profiler_class_loading);
+                       mono_profiler_set_class_failed_callback (_ep_rt_mono_profiler, profiler_class_failed);
+                       mono_profiler_set_class_loaded_callback (_ep_rt_mono_profiler, profiler_class_loaded);
+                       mono_profiler_set_exception_throw_callback (_ep_rt_mono_profiler, profiler_exception_throw);
+                       mono_profiler_set_exception_clause_callback (_ep_rt_mono_profiler, profiler_exception_clause);
+                       mono_profiler_set_monitor_contention_callback (_ep_rt_mono_profiler, profiler_monitor_contention);
+                       mono_profiler_set_monitor_acquired_callback (_ep_rt_mono_profiler, profiler_monitor_acquired);
+                       mono_profiler_set_monitor_failed_callback (_ep_rt_mono_profiler, profiler_monitor_failed);
+                       mono_profiler_set_jit_code_buffer_callback (_ep_rt_mono_profiler, profiler_jit_code_buffer);
                } else if (is_enabled == 0 && MICROSOFT_WINDOWS_DOTNETRUNTIME_PROVIDER_EVENTPIPE_Context.IsEnabled) {
                        // Remove profiler callbacks for DotNETRuntime provider events.
+                       mono_profiler_set_jit_code_buffer_callback (_ep_rt_mono_profiler, NULL);
+                       mono_profiler_set_monitor_failed_callback (_ep_rt_mono_profiler, NULL);
+                       mono_profiler_set_monitor_acquired_callback (_ep_rt_mono_profiler, NULL);
+                       mono_profiler_set_monitor_contention_callback (_ep_rt_mono_profiler, NULL);
+                       mono_profiler_set_exception_clause_callback (_ep_rt_mono_profiler, NULL);
+                       mono_profiler_set_exception_throw_callback (_ep_rt_mono_profiler, NULL);
+                       mono_profiler_set_class_loaded_callback (_ep_rt_mono_profiler, NULL);
+                       mono_profiler_set_class_failed_callback (_ep_rt_mono_profiler, NULL);
+                       mono_profiler_set_class_loading_callback (_ep_rt_mono_profiler, NULL);
+                       mono_profiler_set_thread_started_callback (_ep_rt_mono_profiler, NULL);
+                       mono_profiler_set_thread_started_callback (_ep_rt_mono_profiler, NULL);
+                       mono_profiler_set_assembly_unloaded_callback (_ep_rt_mono_profiler, NULL);
                        mono_profiler_set_assembly_loaded_callback (_ep_rt_mono_profiler, NULL);
+                       mono_profiler_set_image_unloaded_callback (_ep_rt_mono_profiler, NULL);
                        mono_profiler_set_image_loaded_callback (_ep_rt_mono_profiler, NULL);
                        mono_profiler_set_jit_done_callback (_ep_rt_mono_profiler, NULL);
                        mono_profiler_set_jit_failed_callback (_ep_rt_mono_profiler, NULL);
index 5ef853a..c048682 100644 (file)
@@ -23,6 +23,7 @@
 #include <mono/metadata/w32file.h>
 #include <mono/metadata/w32event.h>
 #include <mono/metadata/environment-internals.h>
+#include <mono/metadata/profiler.h>
 
 #undef EP_ARRAY_SIZE
 #define EP_ARRAY_SIZE(expr) G_N_ELEMENTS(expr)
@@ -2166,9 +2167,50 @@ bool
 ep_rt_mono_write_event_module_load (MonoImage *image);
 
 bool
+ep_rt_mono_write_event_module_unload (MonoImage *image);
+
+bool
 ep_rt_mono_write_event_assembly_load (MonoAssembly *assembly);
 
 bool
+ep_rt_mono_write_event_assembly_unload (MonoAssembly *assembly);
+
+bool
+ep_rt_mono_write_event_thread_created (ep_rt_thread_id_t tid);
+
+bool
+ep_rt_mono_write_event_thread_terminated (ep_rt_thread_id_t tid);
+
+bool
+ep_rt_mono_write_event_type_load_start (MonoType *type);
+
+bool
+ep_rt_mono_write_event_type_load_stop (MonoType *type);
+
+bool
+ep_rt_mono_write_event_exception_thrown (MonoObject *object);
+
+bool
+ep_rt_mono_write_event_exception_clause (
+       MonoMethod *method,
+       uint32_t clause_num,
+       MonoExceptionEnum clause_type,
+       MonoObject *obj);
+
+bool
+ep_rt_mono_write_event_monitor_contention_start (MonoObject *obj);
+
+bool
+ep_rt_mono_write_event_monitor_contention_stop (MonoObject *obj);
+
+bool
+ep_rt_mono_write_event_method_jit_memory_allocated_for_code (
+       const uint8_t *buffer,
+       uint64_t size,
+       MonoProfilerCodeBufferType type,
+       const void *data);
+
+bool
 ep_rt_write_event_threadpool_worker_thread_start (
        uint32_t active_thread_count,
        uint32_t retired_worker_thread_count,
index 2ce6999..f74d476 100644 (file)
@@ -3,22 +3,36 @@
 AppDomainDCEnd_V1
 AssemblyDCEnd_V1
 AssemblyLoad_V1
+AssemblyUnload_V1
+ContentionStart_V1
+ContentionStop
 DCEndComplete_V1
 DCEndInit_V1
 DomainModuleDCEnd_V1
 DomainModuleLoad_V1
 EEStartupStart_V1
+ExceptionCatchStart
+ExceptionCatchStop
 ExecutionCheckpointDCEnd
+ExceptionFilterStart
+ExceptionFilterStop
+ExceptionFinallyStart
+ExceptionFinallyStop
+ExceptionThrown_V1
+ExceptionThrownStop
 MethodDCEndILToNativeMap
 MethodDCEnd_V1
 MethodDCEndVerbose_V1
 MethodILToNativeMap
+MethodJitMemoryAllocatedForCode
 MethodJittingStarted_V1
 MethodLoad_V1
 MethodLoadVerbose_V1
 ModuleDCEnd_V2
 ModuleLoad_V2
+ModuleUnload_V2
 RuntimeInformationDCStart
+ThreadCreated
 ThreadPoolIODequeue
 ThreadPoolIOEnqueue
 ThreadPoolWorkerThreadAdjustmentAdjustment
@@ -28,3 +42,6 @@ ThreadPoolWorkerThreadStart
 ThreadPoolWorkerThreadStop
 ThreadPoolWorkerThreadWait
 ThreadPoolWorkingThreadCount
+ThreadTerminated
+TypeLoadStart
+TypeLoadStop
index 7cf59fa..d1bd559 100644 (file)
@@ -86,7 +86,7 @@ extern void mono_gc_set_stack_end (void *stack_end);
  * Not exported in public headers, but can be linked to (unsupported).
  */
 gboolean mono_object_is_alive (MonoObject* obj);
-gboolean mono_gc_is_finalizer_thread (MonoThread *thread);
+MONO_COMPONENT_API gboolean mono_gc_is_finalizer_thread (MonoThread *thread);
 
 void mono_gchandle_set_target (MonoGCHandle gchandle, MonoObject *obj);
 
index e985bdb..cf3eda5 100644 (file)
@@ -1751,7 +1751,7 @@ mono_object_clone_checked (MonoObject *obj, MonoError *error);
 MonoObjectHandle
 mono_object_clone_handle (MonoObjectHandle obj, MonoError *error);
 
-MonoObject *
+MONO_COMPONENT_API MonoObject *
 mono_object_isinst_checked (MonoObject *obj, MonoClass *klass, MonoError *error);
 
 MonoObjectHandle
index e149f9a..9149dcd 100644 (file)
@@ -157,6 +157,9 @@ mono_profiler_clauses_enabled (void)
        return mono_profiler_state.clauses;
 }
 
+MONO_COMPONENT_API gboolean
+mono_component_profiler_clauses_enabled (void);
+
 #define _MONO_PROFILER_EVENT(name, ...) \
        ICALL_EXPORT void mono_profiler_raise_ ## name (__VA_ARGS__);
 #define MONO_PROFILER_EVENT_0(name, type) \
index 61f29b9..9c3ff57 100644 (file)
@@ -595,6 +595,12 @@ mono_profiler_enable_clauses (void)
        return mono_profiler_state.clauses = TRUE;
 }
 
+gboolean
+mono_component_profiler_clauses_enabled (void)
+{
+       return mono_profiler_clauses_enabled ();
+}
+
 /**
  * mono_profiler_set_call_instrumentation_filter_callback:
  *