2010-02-10 Miguel de Icaza <miguel@novell.com>
[mono.git] / mono / mini / mini-trampolines.c
index 46010dd4194fb48af02a7d13acda86d5fc17be5e..2860fb4e20fd544126fdb0728d809dab4a73bcb3 100644 (file)
@@ -20,6 +20,7 @@ guint8* mono_trampoline_code [MONO_TRAMPOLINE_NUM];
 static GHashTable *class_init_hash_addr = NULL;
 static GHashTable *rgctx_lazy_fetch_trampoline_hash = NULL;
 static GHashTable *rgctx_lazy_fetch_trampoline_hash_addr = NULL;
+static guint32 trampoline_calls;
 
 #define mono_trampolines_lock() EnterCriticalSection (&trampolines_mutex)
 #define mono_trampolines_unlock() LeaveCriticalSection (&trampolines_mutex)
@@ -247,7 +248,7 @@ mono_convert_imt_slot_to_vtable_slot (gpointer* slot, mgreg_t *regs, guint8 *cod
 static gpointer
 common_call_trampoline (mgreg_t *regs, guint8 *code, gpointer arg, guint8* tramp, MonoVTable *vt, gpointer *vtable_slot, gboolean need_rgctx_tramp)
 {
-       gpointer addr;
+       gpointer addr, compiled_method;
        gboolean generic_shared = FALSE;
        MonoMethod *m;
        MonoMethod *declaring = NULL;
@@ -487,7 +488,7 @@ common_call_trampoline (mgreg_t *regs, guint8 *code, gpointer arg, guint8* tramp
        if (!code && mono_method_needs_static_rgctx_invoke (m, FALSE))
                need_rgctx_tramp = TRUE;
 
-       addr = mono_compile_method (m);
+       addr = compiled_method = mono_compile_method (m);
        g_assert (addr);
 
        mono_debugger_trampoline_compiled (code, m, addr);
@@ -572,7 +573,7 @@ common_call_trampoline (mgreg_t *regs, guint8 *code, gpointer arg, guint8* tramp
 
                        } else {
                                MonoJitInfo *target_ji = 
-                                       mono_jit_info_table_find (mono_domain_get (), mono_get_addr_from_ftnptr (addr));
+                                       mono_jit_info_table_find (mono_domain_get (), mono_get_addr_from_ftnptr (compiled_method));
 
                                if (!ji)
                                        ji = mono_jit_info_table_find (mono_domain_get (), (char*)code);
@@ -598,6 +599,8 @@ mono_magic_trampoline (mgreg_t *regs, guint8 *code, gpointer arg, guint8* tramp)
        int displacement;
        MonoVTable *vt;
 
+       trampoline_calls ++;
+
        if (code && !mono_use_llvm)
                vt = mono_arch_get_vcall_slot (code, regs, &displacement);
        else
@@ -624,6 +627,8 @@ mono_llvm_vcall_trampoline (mgreg_t *regs, guint8 *code, MonoMethod *m, guint8 *
        gpointer *vtable_slot;
        int slot;
 
+       trampoline_calls ++;
+
        /* 
         * We have the method which is called, we need to obtain the vtable slot without
         * disassembly which is impossible with LLVM.
@@ -655,6 +660,8 @@ mono_generic_virtual_remoting_trampoline (mgreg_t *regs, guint8 *code, MonoMetho
        MonoMethod *imt_method, *declaring;
        gpointer addr;
 
+       trampoline_calls ++;
+
        g_assert (m->is_generic);
 
        if (m->is_inflated)
@@ -703,6 +710,8 @@ mono_aot_trampoline (mgreg_t *regs, guint8 *code, guint8 *token_info,
        guint8 *plt_entry;
        gboolean need_rgctx_tramp = FALSE;
 
+       trampoline_calls ++;
+
        image = *(gpointer*)(gpointer)token_info;
        token_info += sizeof (gpointer);
        token = *(guint32*)(gpointer)token_info;
@@ -760,6 +769,8 @@ mono_aot_plt_trampoline (mgreg_t *regs, guint8 *code, guint8 *aot_module,
        guint32 plt_info_offset = mono_aot_get_plt_info_offset (regs, code);
        gpointer res;
 
+       trampoline_calls ++;
+
        res = mono_aot_plt_resolve (aot_module, plt_info_offset, code);
        if (!res) {
                if (mono_loader_get_last_error ())
@@ -783,6 +794,8 @@ mono_class_init_trampoline (mgreg_t *regs, guint8 *code, MonoVTable *vtable, gui
 {
        guint8 *plt_entry = mono_aot_get_plt_entry (code);
 
+       trampoline_calls ++;
+
        mono_runtime_class_init (vtable);
 
        if (plt_entry) {
@@ -801,6 +814,8 @@ mono_class_init_trampoline (mgreg_t *regs, guint8 *code, MonoVTable *vtable, gui
 void
 mono_generic_class_init_trampoline (mgreg_t *regs, guint8 *code, MonoVTable *vtable, guint8 *tramp)
 {
+       trampoline_calls ++;
+
        mono_runtime_class_init (vtable);
 }
 
@@ -816,6 +831,8 @@ mono_rgctx_lazy_fetch_trampoline (mgreg_t *regs, guint8 *code, gpointer data, gu
        guint32 index = MONO_RGCTX_SLOT_INDEX (slot);
        gboolean mrgctx = MONO_RGCTX_SLOT_IS_MRGCTX (slot);
 
+       trampoline_calls ++;
+
        if (!inited) {
                mono_counters_register ("RGCTX unmanaged lookups", MONO_COUNTER_GENERICS | MONO_COUNTER_INT, &num_lookups);
                inited = TRUE;
@@ -866,6 +883,8 @@ mono_delegate_trampoline (mgreg_t *regs, guint8 *code, gpointer *tramp_data, gui
        guint8 *impl_this = tramp_data [1];
        guint8 *impl_nothis = tramp_data [2];
 
+       trampoline_calls ++;
+
        /* Obtain the delegate object according to the calling convention */
 
        /* 
@@ -1026,6 +1045,8 @@ mono_trampolines_init (void)
 #ifdef MONO_ARCH_LLVM_SUPPORTED
        mono_trampoline_code [MONO_TRAMPOLINE_LLVM_VCALL] = mono_arch_create_trampoline_code (MONO_TRAMPOLINE_LLVM_VCALL);
 #endif
+
+       mono_counters_register ("Calls to trampolines", MONO_COUNTER_JIT | MONO_COUNTER_INT, &trampoline_calls);
 }
 
 void