X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmetadata%2Fprofiler.c;h=8323e3984cfcae0522a6c33690a0f7d3a77f1cee;hb=57cd4050c4c46d4e39717dadeae9516f147af7f6;hp=30ec536018b5eab2e73220dc502ea8724b605de0;hpb=ac15e6161a5ccecc392868665f92f89e5128e68c;p=mono.git diff --git a/mono/metadata/profiler.c b/mono/metadata/profiler.c index 30ec536018b..8323e3984cf 100644 --- a/mono/metadata/profiler.c +++ b/mono/metadata/profiler.c @@ -55,9 +55,12 @@ static MonoProfileClassFunc class_end_unload; static MonoProfileMethodFunc jit_start; static MonoProfileMethodResult jit_end; static MonoProfileJitResult jit_end2; +static MonoProfileMethodFunc method_free; static MonoProfileMethodResult man_unman_transition; static MonoProfileAllocFunc allocation_cb; static MonoProfileStatFunc statistical_cb; +static MonoProfileStatCallChainFunc statistical_call_chain_cb; +static int statistical_call_chain_depth; static MonoProfileMethodFunc method_enter; static MonoProfileMethodFunc method_leave; @@ -171,6 +174,12 @@ mono_profiler_install_jit_end (MonoProfileJitResult end) jit_end2 = end; } +void +mono_profiler_install_method_free (MonoProfileMethodFunc callback) +{ + method_free = callback; +} + void mono_profiler_install_thread (MonoProfileThreadFunc start, MonoProfileThreadFunc end) { @@ -196,6 +205,24 @@ mono_profiler_install_statistical (MonoProfileStatFunc callback) statistical_cb = callback; } +void +mono_profiler_install_statistical_call_chain (MonoProfileStatCallChainFunc callback, int call_chain_depth) { + statistical_call_chain_cb = callback; + statistical_call_chain_depth = call_chain_depth; + if (statistical_call_chain_depth > MONO_PROFILER_MAX_STAT_CALL_CHAIN_DEPTH) { + statistical_call_chain_depth = MONO_PROFILER_MAX_STAT_CALL_CHAIN_DEPTH; + } +} + +int +mono_profiler_stat_get_call_chain_depth (void) { + if (statistical_call_chain_cb != NULL) { + return statistical_call_chain_depth; + } else { + return 0; + } +} + void mono_profiler_install_exception (MonoProfileExceptionFunc throw_callback, MonoProfileMethodFunc exc_method_leave, MonoProfileExceptionClauseFunc clause_callback) { exception_throw_cb = throw_callback; @@ -282,6 +309,13 @@ mono_profiler_method_end_jit (MonoMethod *method, MonoJitInfo* jinfo, int result } } +void +mono_profiler_method_free (MonoMethod *method) +{ + if ((mono_profiler_events & MONO_PROFILE_METHOD_EVENTS) && method_free) + method_free (current_profiler, method); +} + void mono_profiler_code_transition (MonoMethod *method, int result) { @@ -303,6 +337,13 @@ mono_profiler_stat_hit (guchar *ip, void *context) statistical_cb (current_profiler, ip, context); } +void +mono_profiler_stat_call_chain (int call_chain_depth, guchar **ips, void *context) +{ + if ((mono_profiler_events & MONO_PROFILE_STATISTICAL) && statistical_call_chain_cb) + statistical_call_chain_cb (current_profiler, call_chain_depth, ips, context); +} + void mono_profiler_exception_thrown (MonoObject *exception) { @@ -875,7 +916,7 @@ output_profile (GList *funcs) m = method_get_name (p->method); fprintf (poutput, "########################\n"); fprintf (poutput, "% 8.3f ", (double) (p->total * 1000)); - fprintf (poutput, "%7" G_GUINT64_FORMAT " ", (unsigned long long)p->count); + fprintf (poutput, "%7" G_GUINT64_FORMAT " ", (guint64)p->count); fprintf (poutput, "% 8.3f ", (double) (p->total * 1000)/(double)p->count); fprintf (poutput, " %s\n", m); @@ -883,7 +924,7 @@ output_profile (GList *funcs) /* callers */ output_callers (p); } - fprintf (poutput, "Total number of calls: %" G_GINT64_FORMAT "\n", (long long)total_calls); + fprintf (poutput, "Total number of calls: %" G_GINT64_FORMAT "\n", (gint64)total_calls); } typedef struct { @@ -1377,12 +1418,13 @@ static void simple_appdomain_unload (MonoProfiler *prof, MonoDomain *domain) { /* FIXME: we should actually record partial data for each domain, - * since the ip->ji->method mappings are going away at domain unload time. + * but at this point it's must easier using the new logging profiler. */ - if (domain == mono_get_root_domain ()) - stat_prof_report (); + mono_profiler_shutdown (); } +static gint32 simple_shutdown_done = FALSE; + static void simple_shutdown (MonoProfiler *prof) { @@ -1390,7 +1432,22 @@ simple_shutdown (MonoProfiler *prof) MonoProfiler *tprof; GSList *tmp; char *str; + gint32 see_shutdown_done; + + mono_thread_attach(mono_get_root_domain()); + + // Make sure we execute simple_shutdown only once + see_shutdown_done = InterlockedExchange(& simple_shutdown_done, TRUE); + if (see_shutdown_done) + return; + if (mono_profiler_events & MONO_PROFILE_STATISTICAL) { + stat_prof_report (); + } + + // Stop all incoming events + mono_profiler_set_events (0); + for (tmp = prof->per_thread; tmp; tmp = tmp->next) { tprof = tmp->data; merge_thread_data (prof, tprof); @@ -1440,12 +1497,14 @@ mono_profiler_install_simple (const char *desc) for (ptr = args; ptr && *ptr; ptr++) { const char *arg = *ptr; + // Alwais listen to appdomaon events to shutdown at the first unload + flags |= MONO_PROFILE_APPDOMAIN_EVENTS; if (!strcmp (arg, "time")) flags |= MONO_PROFILE_ENTER_LEAVE | MONO_PROFILE_EXCEPTIONS; else if (!strcmp (arg, "alloc")) flags |= MONO_PROFILE_ALLOCATIONS; else if (!strcmp (arg, "stat")) - flags |= MONO_PROFILE_STATISTICAL | MONO_PROFILE_APPDOMAIN_EVENTS; + flags |= MONO_PROFILE_STATISTICAL; else if (!strcmp (arg, "jit")) flags |= MONO_PROFILE_JIT_COMPILATION; else if (strncmp (arg, "file=", 5) == 0) { @@ -1520,7 +1579,7 @@ mono_profiler_load (const char *desc) char *err; void *iter; if (col != NULL) { - mname = g_memdup (desc, col - desc); + mname = g_memdup (desc, col - desc + 1); mname [col - desc] = 0; } else { mname = g_strdup (desc);