X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fprofiler%2Flog.c;h=8a677c2720d48bba530592351a5f6283d87f970b;hb=bfc76bafbf72f8e10c4d2cc7b12e779715c527fa;hp=1f6f9f3b92894108970b77d1916ce80cf0e131b4;hpb=6a1ceec1fab5cdb6230fc61cc67f2dd6d63a5775;p=mono.git diff --git a/mono/profiler/log.c b/mono/profiler/log.c index 1f6f9f3b928..8a677c2720d 100644 --- a/mono/profiler/log.c +++ b/mono/profiler/log.c @@ -12,16 +12,20 @@ #include #include +#include #include -#include "../metadata/metadata-internals.h" +#include +#include #include #include #include +#include #include #include #include #include #include +#include #include #include #include @@ -209,7 +213,9 @@ process_id (void) #endif } -#define ENABLED(EVT) (log_config.effective_mask & (EVT)) +#define ENABLED(EVT) (!!(log_config.effective_mask & (EVT))) +#define ENABLE(EVT) do { log_config.effective_mask |= (EVT); } while (0) +#define DISABLE(EVT) do { log_config.effective_mask &= ~(EVT); } while (0) /* * These macros should be used when writing an event to a log buffer. They @@ -357,6 +363,8 @@ struct _MonoProfiler { guint32 coverage_previous_offset; guint32 coverage_method_id; + + MonoCoopMutex api_mutex; }; static ProfilerConfig log_config; @@ -1134,7 +1142,7 @@ sync_point_mark (MonoProfilerSyncPointType type) ENTER_LOG (&sync_points_ctr, logbuffer, EVENT_SIZE /* event */ + - LEB128_SIZE /* type */ + BYTE_SIZE /* type */ ); emit_event (logbuffer, TYPE_META | TYPE_SYNC_POINT); @@ -1211,7 +1219,7 @@ gc_roots (MonoProfiler *prof, MonoObject *const *objects, const MonoProfilerGCRo for (int i = 0; i < num; ++i) { emit_obj (logbuffer, objects [i]); - emit_byte (logbuffer, root_types [i]); + emit_value (logbuffer, root_types [i]); emit_value (logbuffer, extra_info [i]); } @@ -1246,10 +1254,7 @@ gc_event (MonoProfiler *profiler, MonoProfilerGCEvent ev, uint32_t generation) } switch (ev) { - case MONO_GC_EVENT_START: - if (generation == mono_gc_max_generation ()) - log_profiler.gc_count++; - + case MONO_GC_EVENT_PRE_STOP_WORLD_LOCKED: switch (log_config.hs_mode) { case MONO_PROFILER_HEAPSHOT_NONE: log_profiler.do_heap_walk = FALSE; @@ -1270,16 +1275,25 @@ gc_event (MonoProfiler *profiler, MonoProfilerGCEvent ev, uint32_t generation) g_assert_not_reached (); } + /* + * heapshot_requested is set either because on-demand heapshot is + * enabled and a heapshot was triggered, or because we're doing a + * shutdown heapshot. In the latter case, we won't check it in the + * switch above, so check it here and override any decision we made + * above. + */ + if (InterlockedRead (&log_profiler.heapshot_requested)) + log_profiler.do_heap_walk = TRUE; + if (ENABLED (PROFLOG_GC_ROOT_EVENTS) && log_profiler.do_heap_walk) mono_profiler_set_gc_roots_callback (log_profiler.handle, gc_roots); - break; - case MONO_GC_EVENT_PRE_STOP_WORLD_LOCKED: /* * Ensure that no thread can be in the middle of writing to * a buffer when the world stops... */ buffer_lock_excl (); + break; case MONO_GC_EVENT_POST_STOP_WORLD: /* @@ -1303,6 +1317,11 @@ gc_event (MonoProfiler *profiler, MonoProfilerGCEvent ev, uint32_t generation) EXIT_LOG; } + break; + case MONO_GC_EVENT_START: + if (generation == mono_gc_max_generation ()) + log_profiler.gc_count++; + break; case MONO_GC_EVENT_PRE_START_WORLD: mono_profiler_set_gc_roots_callback (log_profiler.handle, NULL); @@ -1332,6 +1351,7 @@ gc_event (MonoProfiler *profiler, MonoProfilerGCEvent ev, uint32_t generation) */ if (ENABLED (ALL_GC_EVENTS_MASK)) sync_point_mark (SYNC_POINT_WORLD_START); + break; case MONO_GC_EVENT_POST_START_WORLD_UNLOCKED: /* @@ -1339,6 +1359,7 @@ gc_event (MonoProfiler *profiler, MonoProfilerGCEvent ev, uint32_t generation) * their buffers again. */ buffer_unlock_excl (); + break; default: break; @@ -1529,7 +1550,7 @@ static void finalize_end (MonoProfiler *prof) { trigger_on_demand_heapshot (); - if (ENABLED (PROFLOG_FINALIZATION_EVENTS)) { + if (ENABLED (PROFLOG_GC_FINALIZATION_EVENTS)) { ENTER_LOG (&finalize_ends_ctr, buf, EVENT_SIZE /* event */ ); @@ -1739,7 +1760,7 @@ class_loaded (MonoProfiler *prof, MonoClass *klass) } static void -method_enter (MonoProfiler *prof, MonoMethod *method) +method_enter (MonoProfiler *prof, MonoMethod *method, MonoProfilerCallContext *ctx) { if (get_thread ()->call_depth++ <= log_config.max_call_depth) { ENTER_LOG (&method_entries_ctr, logbuffer, @@ -1755,7 +1776,7 @@ method_enter (MonoProfiler *prof, MonoMethod *method) } static void -method_leave (MonoProfiler *prof, MonoMethod *method) +method_leave (MonoProfiler *prof, MonoMethod *method, MonoProfilerCallContext *ctx) { if (--get_thread ()->call_depth <= log_config.max_call_depth) { ENTER_LOG (&method_exits_ctr, logbuffer, @@ -1770,6 +1791,12 @@ method_leave (MonoProfiler *prof, MonoMethod *method) } } +static void +tail_call (MonoProfiler *prof, MonoMethod *method, MonoMethod *target) +{ + method_leave (prof, method, NULL); +} + static void method_exc_leave (MonoProfiler *prof, MonoMethod *method, MonoObject *exc) { @@ -1789,7 +1816,14 @@ method_exc_leave (MonoProfiler *prof, MonoMethod *method, MonoObject *exc) static MonoProfilerCallInstrumentationFlags method_filter (MonoProfiler *prof, MonoMethod *method) { - return MONO_PROFILER_CALL_INSTRUMENTATION_PROLOGUE | MONO_PROFILER_CALL_INSTRUMENTATION_EPILOGUE; + if (log_config.callspec.len > 0 && + !mono_callspec_eval (method, &log_config.callspec)) + return MONO_PROFILER_CALL_INSTRUMENTATION_NONE; + + return MONO_PROFILER_CALL_INSTRUMENTATION_ENTER | + MONO_PROFILER_CALL_INSTRUMENTATION_LEAVE | + MONO_PROFILER_CALL_INSTRUMENTATION_TAIL_CALL | + MONO_PROFILER_CALL_INSTRUMENTATION_EXCEPTION_LEAVE; } static void @@ -1875,7 +1909,8 @@ clause_exc (MonoProfiler *prof, MonoMethod *method, uint32_t clause_num, MonoExc EVENT_SIZE /* event */ + BYTE_SIZE /* clause type */ + LEB128_SIZE /* clause num */ + - LEB128_SIZE /* method */ + LEB128_SIZE /* method */ + + LEB128_SIZE /* exc */ ); emit_event (logbuffer, TYPE_EXCEPTION | TYPE_CLAUSE); @@ -2238,7 +2273,7 @@ dump_ubin (const char *filename, uintptr_t load_addr, uint64_t offset, uintptr_t LEB128_SIZE /* load address */ + LEB128_SIZE /* offset */ + LEB128_SIZE /* size */ + - nlen /* file name */ + len /* file name */ ); emit_event (logbuffer, TYPE_SAMPLE | TYPE_SAMPLE_UBIN); @@ -2641,6 +2676,12 @@ counters_sample (uint64_t timestamp) ; for (agent = log_profiler.counters; agent; agent = agent->next) { + /* + * FIXME: This calculation is incorrect for string counters since + * mono_counter_get_size () just returns 0 in that case. We should + * address this if we ever actually add any string counters to Mono. + */ + size += LEB128_SIZE /* index */ + BYTE_SIZE /* type */ + @@ -3218,8 +3259,8 @@ coverage_filter (MonoProfiler *prof, MonoMethod *method) MonoLockFreeQueueNode *node; flags = mono_method_get_flags (method, &iflags); - if ((iflags & 0x1000 /*METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL*/) || - (flags & 0x2000 /*METHOD_ATTRIBUTE_PINVOKE_IMPL*/)) + if ((iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL) || + (flags & METHOD_ATTRIBUTE_PINVOKE_IMPL)) return FALSE; // Don't need to do anything else if we're already tracking this method @@ -3479,6 +3520,15 @@ cleanup_reusable_samples (void) mono_thread_hazardous_try_free (sample, free_sample_hit); } +static void +log_early_shutdown (MonoProfiler *prof) +{ + if (log_config.hs_on_shutdown) { + InterlockedWrite (&log_profiler.heapshot_requested, 1); + mono_gc_collect (mono_gc_max_generation ()); + } +} + static void log_shutdown (MonoProfiler *prof) { @@ -3493,7 +3543,7 @@ log_shutdown (MonoProfiler *prof) char c = 1; if (write (prof->pipes [1], &c, 1) != 1) { - mono_profiler_printf_err ("Could not write to log profiler pipe: %s", strerror (errno)); + mono_profiler_printf_err ("Could not write to log profiler pipe: %s", g_strerror (errno)); exit (1); } @@ -3592,6 +3642,8 @@ log_shutdown (MonoProfiler *prof) mono_os_mutex_destroy (&log_profiler.coverage_mutex); } + mono_coop_mutex_destroy (&log_profiler.api_mutex); + PROF_TLS_FREE (); g_free (prof->args); @@ -3705,7 +3757,7 @@ helper_thread (void *arg) if (errno == EINTR) continue; - mono_profiler_printf_err ("Could not poll in log profiler helper thread: %s", strerror (errno)); + mono_profiler_printf_err ("Could not poll in log profiler helper thread: %s", g_strerror (errno)); exit (1); } @@ -3783,14 +3835,14 @@ static void start_helper_thread (void) { if (pipe (log_profiler.pipes) == -1) { - mono_profiler_printf_err ("Could not create log profiler pipe: %s", strerror (errno)); + mono_profiler_printf_err ("Could not create log profiler pipe: %s", g_strerror (errno)); exit (1); } log_profiler.server_socket = socket (PF_INET, SOCK_STREAM, 0); if (log_profiler.server_socket == -1) { - mono_profiler_printf_err ("Could not create log profiler server socket: %s", strerror (errno)); + mono_profiler_printf_err ("Could not create log profiler server socket: %s", g_strerror (errno)); exit (1); } @@ -3802,13 +3854,13 @@ start_helper_thread (void) server_address.sin_port = htons (log_profiler.command_port); if (bind (log_profiler.server_socket, (struct sockaddr *) &server_address, sizeof (server_address)) == -1) { - mono_profiler_printf_err ("Could not bind log profiler server socket on port %d: %s", log_profiler.command_port, strerror (errno)); + mono_profiler_printf_err ("Could not bind log profiler server socket on port %d: %s", log_profiler.command_port, g_strerror (errno)); close (log_profiler.server_socket); exit (1); } if (listen (log_profiler.server_socket, 1) == -1) { - mono_profiler_printf_err ("Could not listen on log profiler server socket: %s", strerror (errno)); + mono_profiler_printf_err ("Could not listen on log profiler server socket: %s", g_strerror (errno)); close (log_profiler.server_socket); exit (1); } @@ -3816,7 +3868,7 @@ start_helper_thread (void) socklen_t slen = sizeof (server_address); if (getsockname (log_profiler.server_socket, (struct sockaddr *) &server_address, &slen)) { - mono_profiler_printf_err ("Could not retrieve assigned port for log profiler server socket: %s", strerror (errno)); + mono_profiler_printf_err ("Could not retrieve assigned port for log profiler server socket: %s", g_strerror (errno)); close (log_profiler.server_socket); exit (1); } @@ -4083,6 +4135,325 @@ register_counter (const char *name, gint32 *counter) mono_counters_register (name, MONO_COUNTER_UINT | MONO_COUNTER_PROFILER | MONO_COUNTER_MONOTONIC, counter); } +ICALL_EXPORT gint32 +proflog_icall_GetMaxStackTraceFrames (void) +{ + return MAX_FRAMES; +} + +ICALL_EXPORT gint32 +proflog_icall_GetStackTraceFrames (void) +{ + return log_config.num_frames; +} + +ICALL_EXPORT void +proflog_icall_SetStackTraceFrames (gint32 value) +{ + log_config.num_frames = value; +} + +ICALL_EXPORT MonoProfilerHeapshotMode +proflog_icall_GetHeapshotMode (void) +{ + return log_config.hs_mode; +} + +ICALL_EXPORT void +proflog_icall_SetHeapshotMode (MonoProfilerHeapshotMode value) +{ + log_config.hs_mode = value; +} + +ICALL_EXPORT gint32 +proflog_icall_GetHeapshotMillisecondsFrequency (void) +{ + return log_config.hs_freq_ms; +} + +ICALL_EXPORT void +proflog_icall_SetHeapshotMillisecondsFrequency (gint32 value) +{ + log_config.hs_freq_ms = value; +} + +ICALL_EXPORT gint32 +proflog_icall_GetHeapshotCollectionsFrequency (void) +{ + return log_config.hs_freq_gc; +} + +ICALL_EXPORT void +proflog_icall_SetHeapshotCollectionsFrequency (gint32 value) +{ + log_config.hs_freq_gc = value; +} + +ICALL_EXPORT gint32 +proflog_icall_GetCallDepth (void) +{ + return log_config.max_call_depth; +} + +ICALL_EXPORT void +proflog_icall_SetCallDepth (gint32 value) +{ + log_config.max_call_depth = value; +} + +ICALL_EXPORT void +proflog_icall_GetSampleMode (MonoProfilerSampleMode *mode, gint32 *frequency) +{ + uint32_t freq; + + mono_profiler_get_sample_mode (log_profiler.handle, mode, &freq); + + *frequency = freq; +} + +ICALL_EXPORT MonoBoolean +proflog_icall_SetSampleMode (MonoProfilerSampleMode mode, gint32 frequency) +{ + mono_coop_mutex_lock (&log_profiler.api_mutex); + + mono_bool result = mono_profiler_set_sample_mode (log_profiler.handle, mode, frequency); + + if (mode != MONO_PROFILER_SAMPLE_MODE_NONE) { + ENABLE (PROFLOG_SAMPLE_EVENTS); + mono_profiler_set_sample_hit_callback (log_profiler.handle, mono_sample_hit); + } else { + DISABLE (PROFLOG_SAMPLE_EVENTS); + mono_profiler_set_sample_hit_callback (log_profiler.handle, NULL); + } + + mono_coop_mutex_unlock (&log_profiler.api_mutex); + + return result; +} + +ICALL_EXPORT MonoBoolean +proflog_icall_GetExceptionEvents (void) +{ + return ENABLED (PROFLOG_EXCEPTION_EVENTS); +} + +ICALL_EXPORT void +proflog_icall_SetExceptionEvents (MonoBoolean value) +{ + mono_coop_mutex_lock (&log_profiler.api_mutex); + + if (value) { + ENABLE (PROFLOG_EXCEPTION_EVENTS); + mono_profiler_set_exception_throw_callback (log_profiler.handle, throw_exc); + mono_profiler_set_exception_clause_callback (log_profiler.handle, clause_exc); + } else { + DISABLE (PROFLOG_EXCEPTION_EVENTS); + mono_profiler_set_exception_throw_callback (log_profiler.handle, NULL); + mono_profiler_set_exception_clause_callback (log_profiler.handle, NULL); + } + + mono_coop_mutex_unlock (&log_profiler.api_mutex); +} + +ICALL_EXPORT MonoBoolean +proflog_icall_GetMonitorEvents (void) +{ + return ENABLED (PROFLOG_MONITOR_EVENTS); +} + +ICALL_EXPORT void +proflog_icall_SetMonitorEvents (MonoBoolean value) +{ + mono_coop_mutex_lock (&log_profiler.api_mutex); + + if (value) { + ENABLE (PROFLOG_MONITOR_EVENTS); + mono_profiler_set_monitor_contention_callback (log_profiler.handle, monitor_contention); + mono_profiler_set_monitor_acquired_callback (log_profiler.handle, monitor_acquired); + mono_profiler_set_monitor_failed_callback (log_profiler.handle, monitor_failed); + } else { + DISABLE (PROFLOG_MONITOR_EVENTS); + mono_profiler_set_monitor_contention_callback (log_profiler.handle, NULL); + mono_profiler_set_monitor_acquired_callback (log_profiler.handle, NULL); + mono_profiler_set_monitor_failed_callback (log_profiler.handle, NULL); + } + + mono_coop_mutex_unlock (&log_profiler.api_mutex); +} + +ICALL_EXPORT MonoBoolean +proflog_icall_GetGCEvents (void) +{ + return ENABLED (PROFLOG_GC_EVENTS); +} + +ICALL_EXPORT void +proflog_icall_SetGCEvents (MonoBoolean value) +{ + mono_coop_mutex_lock (&log_profiler.api_mutex); + + if (value) + ENABLE (PROFLOG_GC_EVENTS); + else + DISABLE (PROFLOG_GC_EVENTS); + + mono_coop_mutex_unlock (&log_profiler.api_mutex); +} + +ICALL_EXPORT MonoBoolean +proflog_icall_GetGCAllocationEvents (void) +{ + return ENABLED (PROFLOG_GC_ALLOCATION_EVENTS); +} + +ICALL_EXPORT void +proflog_icall_SetGCAllocationEvents (MonoBoolean value) +{ + mono_coop_mutex_lock (&log_profiler.api_mutex); + + if (value) { + ENABLE (PROFLOG_GC_ALLOCATION_EVENTS); + mono_profiler_set_gc_allocation_callback (log_profiler.handle, gc_alloc); + } else { + DISABLE (PROFLOG_GC_ALLOCATION_EVENTS); + mono_profiler_set_gc_allocation_callback (log_profiler.handle, NULL); + } + + mono_coop_mutex_unlock (&log_profiler.api_mutex); +} + +ICALL_EXPORT MonoBoolean +proflog_icall_GetGCMoveEvents (void) +{ + return ENABLED (PROFLOG_GC_MOVE_EVENTS); +} + +ICALL_EXPORT void +proflog_icall_SetGCMoveEvents (MonoBoolean value) +{ + mono_coop_mutex_lock (&log_profiler.api_mutex); + + if (value) { + ENABLE (PROFLOG_GC_MOVE_EVENTS); + mono_profiler_set_gc_moves_callback (log_profiler.handle, gc_moves); + } else { + DISABLE (PROFLOG_GC_MOVE_EVENTS); + mono_profiler_set_gc_moves_callback (log_profiler.handle, NULL); + } + + mono_coop_mutex_unlock (&log_profiler.api_mutex); +} + +ICALL_EXPORT MonoBoolean +proflog_icall_GetGCRootEvents (void) +{ + return ENABLED (PROFLOG_GC_ROOT_EVENTS); +} + +ICALL_EXPORT void +proflog_icall_SetGCRootEvents (MonoBoolean value) +{ + mono_coop_mutex_lock (&log_profiler.api_mutex); + + if (value) + ENABLE (PROFLOG_GC_ROOT_EVENTS); + else + DISABLE (PROFLOG_GC_ROOT_EVENTS); + + mono_coop_mutex_unlock (&log_profiler.api_mutex); +} + +ICALL_EXPORT MonoBoolean +proflog_icall_GetGCHandleEvents (void) +{ + return ENABLED (PROFLOG_GC_HANDLE_EVENTS); +} + +ICALL_EXPORT void +proflog_icall_SetGCHandleEvents (MonoBoolean value) +{ + mono_coop_mutex_lock (&log_profiler.api_mutex); + + if (value) { + ENABLE (PROFLOG_GC_HANDLE_EVENTS); + mono_profiler_set_gc_handle_created_callback (log_profiler.handle, gc_handle_created); + mono_profiler_set_gc_handle_deleted_callback (log_profiler.handle, gc_handle_deleted); + } else { + DISABLE (PROFLOG_GC_HANDLE_EVENTS); + mono_profiler_set_gc_handle_created_callback (log_profiler.handle, NULL); + mono_profiler_set_gc_handle_deleted_callback (log_profiler.handle, NULL); + } + + mono_coop_mutex_unlock (&log_profiler.api_mutex); +} + +ICALL_EXPORT MonoBoolean +proflog_icall_GetGCFinalizationEvents (void) +{ + return ENABLED (PROFLOG_GC_FINALIZATION_EVENTS); +} + +ICALL_EXPORT void +proflog_icall_SetGCFinalizationEvents (MonoBoolean value) +{ + mono_coop_mutex_lock (&log_profiler.api_mutex); + + if (value) { + ENABLE (PROFLOG_GC_FINALIZATION_EVENTS); + mono_profiler_set_gc_finalizing_callback (log_profiler.handle, finalize_begin); + mono_profiler_set_gc_finalizing_object_callback (log_profiler.handle, finalize_object_begin); + mono_profiler_set_gc_finalized_object_callback (log_profiler.handle, finalize_object_end); + } else { + DISABLE (PROFLOG_GC_FINALIZATION_EVENTS); + mono_profiler_set_gc_finalizing_callback (log_profiler.handle, NULL); + mono_profiler_set_gc_finalizing_object_callback (log_profiler.handle, NULL); + mono_profiler_set_gc_finalized_object_callback (log_profiler.handle, NULL); + } + + mono_coop_mutex_unlock (&log_profiler.api_mutex); +} + +ICALL_EXPORT MonoBoolean +proflog_icall_GetCounterEvents (void) +{ + return ENABLED (PROFLOG_COUNTER_EVENTS); +} + +ICALL_EXPORT void +proflog_icall_SetCounterEvents (MonoBoolean value) +{ + mono_coop_mutex_lock (&log_profiler.api_mutex); + + if (value) + ENABLE (PROFLOG_COUNTER_EVENTS); + else + DISABLE (PROFLOG_COUNTER_EVENTS); + + mono_coop_mutex_unlock (&log_profiler.api_mutex); +} + +ICALL_EXPORT MonoBoolean +proflog_icall_GetJitEvents (void) +{ + return ENABLED (PROFLOG_JIT_EVENTS); +} + +ICALL_EXPORT void +proflog_icall_SetJitEvents (MonoBoolean value) +{ + mono_coop_mutex_lock (&log_profiler.api_mutex); + + if (value) { + ENABLE (PROFLOG_JIT_EVENTS); + mono_profiler_set_jit_code_buffer_callback (log_profiler.handle, code_buffer_new); + } else { + DISABLE (PROFLOG_JIT_EVENTS); + mono_profiler_set_jit_code_buffer_callback (log_profiler.handle, NULL); + } + + mono_coop_mutex_unlock (&log_profiler.api_mutex); +} + static void runtime_initialized (MonoProfiler *profiler) { @@ -4150,6 +4521,47 @@ runtime_initialized (MonoProfiler *profiler) start_helper_thread (); start_writer_thread (); start_dumper_thread (); + + mono_coop_mutex_init (&log_profiler.api_mutex); + +#define ADD_ICALL(NAME) \ + mono_add_internal_call ("Mono.Profiler.Log.LogProfiler::" EGLIB_STRINGIFY (NAME), proflog_icall_ ## NAME); + + ADD_ICALL (GetMaxStackTraceFrames); + ADD_ICALL (GetStackTraceFrames); + ADD_ICALL (SetStackTraceFrames); + ADD_ICALL (GetHeapshotMode); + ADD_ICALL (SetHeapshotMode); + ADD_ICALL (GetHeapshotMillisecondsFrequency); + ADD_ICALL (SetHeapshotMillisecondsFrequency); + ADD_ICALL (GetHeapshotCollectionsFrequency); + ADD_ICALL (SetHeapshotCollectionsFrequency); + ADD_ICALL (GetCallDepth); + ADD_ICALL (SetCallDepth); + ADD_ICALL (GetSampleMode); + ADD_ICALL (SetSampleMode); + ADD_ICALL (GetExceptionEvents); + ADD_ICALL (SetExceptionEvents); + ADD_ICALL (GetMonitorEvents); + ADD_ICALL (SetMonitorEvents); + ADD_ICALL (GetGCEvents); + ADD_ICALL (SetGCEvents); + ADD_ICALL (GetGCAllocationEvents); + ADD_ICALL (SetGCAllocationEvents); + ADD_ICALL (GetGCMoveEvents); + ADD_ICALL (SetGCMoveEvents); + ADD_ICALL (GetGCRootEvents); + ADD_ICALL (SetGCRootEvents); + ADD_ICALL (GetGCHandleEvents); + ADD_ICALL (SetGCHandleEvents); + ADD_ICALL (GetGCFinalizationEvents); + ADD_ICALL (SetGCFinalizationEvents); + ADD_ICALL (GetCounterEvents); + ADD_ICALL (SetCounterEvents); + ADD_ICALL (GetJitEvents); + ADD_ICALL (SetJitEvents); + +#undef ADD_ICALL } static void @@ -4234,28 +4646,11 @@ create_profiler (const char *args, const char *filename, GPtrArray *filters) log_profiler.startup_time = current_time (); } -/* - * declaration to silence the compiler: this is the entry point that - * mono will load from the shared library and call. - */ -extern void -mono_profiler_init (const char *desc); - -extern void +MONO_API void mono_profiler_init_log (const char *desc); -/* - * this is the entry point that will be used when the profiler - * is embedded inside the main executable. - */ void mono_profiler_init_log (const char *desc) -{ - mono_profiler_init (desc); -} - -void -mono_profiler_init (const char *desc) { GPtrArray *filters = NULL; @@ -4278,7 +4673,7 @@ mono_profiler_init (const char *desc) mono_lls_init (&log_profiler.profiler_thread_list, NULL); - MonoProfilerHandle handle = log_profiler.handle = mono_profiler_install (&log_profiler); + MonoProfilerHandle handle = log_profiler.handle = mono_profiler_create (&log_profiler); /* * Required callbacks. These are either necessary for the profiler itself @@ -4286,6 +4681,7 @@ mono_profiler_init (const char *desc) * allocations, exceptions) are dynamically enabled/disabled. */ + mono_profiler_set_runtime_shutdown_begin_callback (handle, log_early_shutdown); mono_profiler_set_runtime_shutdown_end_callback (handle, log_shutdown); mono_profiler_set_runtime_initialized_callback (handle, runtime_initialized); @@ -4326,10 +4722,8 @@ mono_profiler_init (const char *desc) if (ENABLED (PROFLOG_GC_EVENTS)) mono_profiler_set_gc_resize_callback (handle, gc_resize); - if (ENABLED (PROFLOG_GC_ALLOCATION_EVENTS)) { - mono_profiler_enable_allocations (); + if (ENABLED (PROFLOG_GC_ALLOCATION_EVENTS)) mono_profiler_set_gc_allocation_callback (handle, gc_alloc); - } if (ENABLED (PROFLOG_GC_MOVE_EVENTS)) mono_profiler_set_gc_moves_callback (handle, gc_moves); @@ -4342,16 +4736,15 @@ mono_profiler_init (const char *desc) mono_profiler_set_gc_handle_deleted_callback (handle, gc_handle_deleted); } - if (ENABLED (PROFLOG_FINALIZATION_EVENTS)) { + if (ENABLED (PROFLOG_GC_FINALIZATION_EVENTS)) { mono_profiler_set_gc_finalizing_callback (handle, finalize_begin); mono_profiler_set_gc_finalized_callback (handle, finalize_end); mono_profiler_set_gc_finalizing_object_callback (handle, finalize_object_begin); - mono_profiler_set_gc_finalized_object_callback (handle, finalize_object_end); - } else if (log_config.hs_mode == MONO_PROFILER_HEAPSHOT_ON_DEMAND) { - //On Demand heapshot uses the finalizer thread to force a collection and thus a heapshot - mono_profiler_set_gc_finalized_callback (handle, finalize_end); } + //On Demand heapshot uses the finalizer thread to force a collection and thus a heapshot + mono_profiler_set_gc_finalized_callback (handle, finalize_end); + if (ENABLED (PROFLOG_SAMPLE_EVENTS)) mono_profiler_set_sample_hit_callback (handle, mono_sample_hit); @@ -4362,12 +4755,16 @@ mono_profiler_init (const char *desc) mono_profiler_set_call_instrumentation_filter_callback (handle, method_filter); mono_profiler_set_method_enter_callback (handle, method_enter); mono_profiler_set_method_leave_callback (handle, method_leave); + mono_profiler_set_method_tail_call_callback (handle, tail_call); mono_profiler_set_method_exception_leave_callback (handle, method_exc_leave); } - if (log_config.collect_coverage) + if (log_config.collect_coverage) { + mono_profiler_enable_coverage (); mono_profiler_set_coverage_filter_callback (handle, coverage_filter); + } + mono_profiler_enable_allocations (); mono_profiler_enable_sampling (handle); /*