[profiler] Implement call context introspection for enter/leave events.
[mono.git] / mono / mini / mini.c
index 10d6eac8b16d0b4a0306565c4a7642c07e5f1edd..5e6e718486f8b7c29b519017b2acf237b41b8e58 100644 (file)
@@ -36,7 +36,6 @@
 #include <mono/metadata/threads.h>
 #include <mono/metadata/appdomain.h>
 #include <mono/metadata/debug-helpers.h>
-#include "mono/metadata/profiler.h"
 #include <mono/metadata/profiler-private.h>
 #include <mono/metadata/mono-config.h>
 #include <mono/metadata/environment.h>
@@ -2078,8 +2077,11 @@ mono_compile_create_vars (MonoCompile *cfg)
        if (cfg->verbose_level > 2)
                g_print ("creating locals\n");
 
-       for (i = 0; i < header->num_locals; ++i)
+       for (i = 0; i < header->num_locals; ++i) {
+               if (cfg->verbose_level > 2)
+                       g_print ("\tlocal [%d]: ", i);
                cfg->locals [i] = mono_compile_create_var (cfg, header->locals [i], OP_LOCAL);
+       }
 
        if (cfg->verbose_level > 2)
                g_print ("locals done\n");
@@ -2230,9 +2232,6 @@ mono_codegen (MonoCompile *cfg)
                        mono_bb_deduplicate_op_il_seq_points (cfg, bb);
        }
 
-       if (cfg->prof_options & MONO_PROFILE_COVERAGE)
-               cfg->coverage_info = mono_profiler_coverage_alloc (cfg->method, cfg->num_bblocks);
-
        code = mono_arch_emit_prolog (cfg);
 
        cfg->code_len = code - cfg->native_code;
@@ -2255,6 +2254,9 @@ mono_codegen (MonoCompile *cfg)
                        mono_arch_emit_epilog (cfg);
                        cfg->epilog_end = cfg->code_len;
                }
+
+               if (bb->clause_hole)
+                       mono_cfg_add_try_hole (cfg, bb->clause_hole, cfg->native_code + bb->native_offset, bb);
        }
 
        mono_arch_emit_exceptions (cfg);
@@ -2378,7 +2380,7 @@ mono_codegen (MonoCompile *cfg)
        } else {
                mono_domain_code_commit (code_domain, cfg->native_code, cfg->code_size, cfg->code_len);
        }
-       mono_profiler_code_buffer_new (cfg->native_code, cfg->code_len, MONO_PROFILER_CODE_BUFFER_METHOD, cfg->method);
+       MONO_PROFILER_RAISE (jit_code_buffer, (cfg->native_code, cfg->code_len, MONO_PROFILER_CODE_BUFFER_METHOD, cfg->method));
        
        mono_arch_flush_icache (cfg->native_code, cfg->code_len);
 
@@ -2653,27 +2655,15 @@ create_jit_info (MonoCompile *cfg, MonoMethod *method_to_compile)
                        MonoExceptionClause *ec = &header->clauses [i];
                        MonoJitExceptionInfo *ei = &jinfo->clauses [i];
                        MonoBasicBlock *tblock;
-                       MonoInst *exvar, *spvar;
+                       MonoInst *exvar;
 
                        ei->flags = ec->flags;
 
                        if (G_UNLIKELY (cfg->verbose_level >= 4))
                                printf ("IL clause: try 0x%x-0x%x handler 0x%x-0x%x filter 0x%x\n", ec->try_offset, ec->try_offset + ec->try_len, ec->handler_offset, ec->handler_offset + ec->handler_len, ec->flags == MONO_EXCEPTION_CLAUSE_FILTER ? ec->data.filter_offset : 0);
 
-                       /*
-                        * The spvars are needed by mono_arch_install_handler_block_guard ().
-                        */
-                       if (ei->flags == MONO_EXCEPTION_CLAUSE_FINALLY) {
-                               int region;
-
-                               region = ((i + 1) << 8) | MONO_REGION_FINALLY | ec->flags;
-                               spvar = mono_find_spvar_for_region (cfg, region);
-                               g_assert (spvar);
-                               ei->exvar_offset = spvar->inst_offset;
-                       } else {
-                               exvar = mono_find_exvar_for_offset (cfg, ec->handler_offset);
-                               ei->exvar_offset = exvar ? exvar->inst_offset : 0;
-                       }
+                       exvar = mono_find_exvar_for_offset (cfg, ec->handler_offset);
+                       ei->exvar_offset = exvar ? exvar->inst_offset : 0;
 
                        if (ei->flags == MONO_EXCEPTION_CLAUSE_FILTER) {
                                tblock = cfg->cil_offset_to_bb [ec->data.filter_offset];
@@ -3097,8 +3087,7 @@ mini_method_compile (MonoMethod *method, guint32 opts, MonoDomain *domain, JitFl
        static char *verbose_method_name;
 
        InterlockedIncrement (&mono_jit_stats.methods_compiled);
-       if (mono_profiler_get_events () & MONO_PROFILE_JIT_COMPILATION)
-               mono_profiler_method_jit (method);
+       MONO_PROFILER_RAISE (jit_begin, (method));
        if (MONO_METHOD_COMPILE_BEGIN_ENABLED ())
                MONO_PROBE_METHOD_COMPILE_BEGIN (method);
 
@@ -3161,7 +3150,6 @@ mini_method_compile (MonoMethod *method, guint32 opts, MonoDomain *domain, JitFl
        cfg->method = method_to_compile;
        cfg->mempool = mono_mempool_new ();
        cfg->opt = opts;
-       cfg->prof_options = mono_profiler_get_events ();
        cfg->run_cctors = run_cctors;
        cfg->domain = domain;
        cfg->verbose_level = mini_verbose;
@@ -3306,8 +3294,10 @@ mini_method_compile (MonoMethod *method, guint32 opts, MonoDomain *domain, JitFl
        }
 #endif
 
+       cfg->prof_flags = mono_profiler_get_call_instrumentation_flags (cfg->method);
+
        /* The debugger has no liveness information, so avoid sharing registers/stack slots */
-       if (debug_options.mdb_optimizations) {
+       if (debug_options.mdb_optimizations || MONO_CFG_PROFILE_CALL_CONTEXT (cfg)) {
                cfg->disable_reuse_registers = TRUE;
                cfg->disable_reuse_stack_slots = TRUE;
                /* 
@@ -4039,7 +4029,6 @@ mono_jit_compile_method_inner (MonoMethod *method, MonoDomain *target_domain, in
        MonoJitInfo *jinfo, *info;
        MonoVTable *vtable;
        MonoException *ex = NULL;
-       guint32 prof_options;
        GTimer *jit_timer;
        MonoMethod *prof_method, *shared;
 
@@ -4070,7 +4059,7 @@ mono_jit_compile_method_inner (MonoMethod *method, MonoDomain *target_domain, in
                if (!jinfo)
                        jinfo = mono_jit_info_table_find (mono_domain_get (), (char *)code);
                if (jinfo)
-                       mono_profiler_method_end_jit (method, jinfo, MONO_PROFILE_OK);
+                       MONO_PROFILER_RAISE (jit_done, (method, jinfo));
                return code;
        } else if ((method->iflags & METHOD_IMPL_ATTRIBUTE_RUNTIME)) {
                const char *name = method->name;
@@ -4211,8 +4200,7 @@ mono_jit_compile_method_inner (MonoMethod *method, MonoDomain *target_domain, in
        }
 
        if (ex) {
-               if (cfg->prof_options & MONO_PROFILE_JIT_COMPILATION)
-                       mono_profiler_method_end_jit (method, NULL, MONO_PROFILE_FAILED);
+               MONO_PROFILER_RAISE (jit_failed, (method));
 
                mono_destroy_compile (cfg);
                mono_error_set_exception_instance (error, ex);
@@ -4255,8 +4243,6 @@ mono_jit_compile_method_inner (MonoMethod *method, MonoDomain *target_domain, in
 
        jinfo = cfg->jit_info;
 
-       prof_options = cfg->prof_options;
-
        /*
         * Update global stats while holding a lock, instead of doing many
         * InterlockedIncrement operations during JITting.
@@ -4321,19 +4307,16 @@ mono_jit_compile_method_inner (MonoMethod *method, MonoDomain *target_domain, in
                return NULL;
        }
 
-       if (prof_options & MONO_PROFILE_JIT_COMPILATION) {
-               if (method->wrapper_type == MONO_WRAPPER_MANAGED_TO_NATIVE) {
-                       if (mono_marshal_method_from_wrapper (method)) {
-                               /* Native func wrappers have no method */
-                               /* The profiler doesn't know about wrappers, so pass the original icall method */
-                               mono_profiler_method_end_jit (mono_marshal_method_from_wrapper (method), jinfo, MONO_PROFILE_OK);
-                       }
-               }
-               mono_profiler_method_end_jit (method, jinfo, MONO_PROFILE_OK);
-               if (prof_method != method) {
-                       mono_profiler_method_end_jit (prof_method, jinfo, MONO_PROFILE_OK);
+       if (method->wrapper_type == MONO_WRAPPER_MANAGED_TO_NATIVE) {
+               if (mono_marshal_method_from_wrapper (method)) {
+                       /* Native func wrappers have no method */
+                       /* The profiler doesn't know about wrappers, so pass the original icall method */
+                       MONO_PROFILER_RAISE (jit_done, (mono_marshal_method_from_wrapper (method), jinfo));
                }
        }
+       MONO_PROFILER_RAISE (jit_done, (method, jinfo));
+       if (prof_method != method)
+               MONO_PROFILER_RAISE (jit_done, (prof_method, jinfo));
 
        if (!(method->wrapper_type == MONO_WRAPPER_REMOTING_INVOKE ||
                  method->wrapper_type == MONO_WRAPPER_REMOTING_INVOKE_WITH_CHECK ||