[jit] Add counters for number of JITted method discarded as duplicates and the time...
[mono.git] / mono / mini / mini-runtime.c
index 92eb960a82278bc8c39c64cbb37d2cbeb5c5fb1f..4c504f1e93a50742d736ff7cfafc2a0aa1523324 100644 (file)
@@ -65,7 +65,7 @@
 #include <mono/utils/mono-threads.h>
 #include <mono/utils/mono-threads-coop.h>
 #include <mono/utils/checked-build.h>
-#include <mono/utils/w32handle.h>
+#include <mono/metadata/w32handle.h>
 #include <mono/io-layer/io-layer.h>
 
 #include "mini.h"
@@ -253,6 +253,8 @@ mono_print_method_from_ip (void *ip)
        MonoGenericSharingContext*gsctx;
        const char *shared_type;
 
+       if (!domain)
+               domain = mono_get_root_domain ();
        ji = mini_jit_info_table_find_ext (domain, (char *)ip, TRUE, &target_domain);
        if (ji && ji->is_trampoline) {
                MonoTrampInfo *tinfo = (MonoTrampInfo *)ji->d.tramp_info;
@@ -1094,6 +1096,63 @@ mono_patch_info_list_prepend (MonoJumpInfo *list, int ip, MonoJumpInfoType type,
        return ji;
 }
 
+#if !defined(DISABLE_LOGGING) && !defined(DISABLE_JIT)
+
+static const char* const patch_info_str[] = {
+#define PATCH_INFO(a,b) "" #a,
+#include "patch-info.h"
+#undef PATCH_INFO
+};
+
+const char*
+mono_ji_type_to_string (MonoJumpInfoType type)
+{
+       return patch_info_str [type];
+}
+
+void
+mono_print_ji (const MonoJumpInfo *ji)
+{
+       switch (ji->type) {
+       case MONO_PATCH_INFO_RGCTX_FETCH: {
+               MonoJumpInfoRgctxEntry *entry = ji->data.rgctx_entry;
+
+               printf ("[RGCTX_FETCH ");
+               mono_print_ji (entry->data);
+               printf (" - %s]", mono_rgctx_info_type_to_str (entry->info_type));
+               break;
+       }
+       case MONO_PATCH_INFO_METHODCONST: {
+               char *s = mono_method_full_name (ji->data.method, TRUE);
+               printf ("[METHODCONST - %s]", s);
+               g_free (s);
+               break;
+       }
+       case MONO_PATCH_INFO_INTERNAL_METHOD: {
+               printf ("[INTERNAL_METHOD - %s]", ji->data.name);
+               break;
+       }
+       default:
+               printf ("[%s]", patch_info_str [ji->type]);
+               break;
+       }
+}
+
+#else
+
+const char*
+mono_ji_type_to_string (MonoJumpInfoType type)
+{
+       return "";
+}
+
+void
+mono_print_ji (const MonoJumpInfo *ji)
+{
+}
+
+#endif
+
 /**
  * mono_patch_info_dup_mp:
  *
@@ -1222,6 +1281,8 @@ mono_patch_info_hash (gconstpointer data)
        case MONO_PATCH_INFO_GOT_OFFSET:
        case MONO_PATCH_INFO_GC_SAFE_POINT_FLAG:
        case MONO_PATCH_INFO_AOT_MODULE:
+       case MONO_PATCH_INFO_GET_TLS_TRAMP:
+       case MONO_PATCH_INFO_JIT_THREAD_ATTACH:
                return (ji->type << 8);
        case MONO_PATCH_INFO_CASTCLASS_CACHE:
                return (ji->type << 8) | (ji->data.index);
@@ -1441,11 +1502,11 @@ mono_resolve_patch_target (MonoMethod *method, MonoDomain *domain, guint8 *code,
                break;
        case MONO_PATCH_INFO_IID:
                mono_class_init (patch_info->data.klass);
-               target = GINT_TO_POINTER ((int)patch_info->data.klass->interface_id);
+               target = GUINT_TO_POINTER (patch_info->data.klass->interface_id);
                break;
        case MONO_PATCH_INFO_ADJUSTED_IID:
                mono_class_init (patch_info->data.klass);
-               target = GINT_TO_POINTER ((int)(-((patch_info->data.klass->interface_id + 1) * SIZEOF_VOID_P)));
+               target = GUINT_TO_POINTER ((guint32)(-((patch_info->data.klass->interface_id + 1) * SIZEOF_VOID_P)));
                break;
        case MONO_PATCH_INFO_VTABLE:
                target = mono_class_vtable (domain, patch_info->data.klass);
@@ -1475,7 +1536,7 @@ mono_resolve_patch_target (MonoMethod *method, MonoDomain *domain, guint8 *code,
                }
 
                g_assert (vtable);
-               if (!vtable->initialized && !(vtable->klass->flags & TYPE_ATTRIBUTE_BEFORE_FIELD_INIT) && (method && mono_class_needs_cctor_run (vtable->klass, method)))
+               if (!vtable->initialized && !mono_class_is_before_field_init (vtable->klass) && (method && mono_class_needs_cctor_run (vtable->klass, method)))
                        /* Done by the generated code */
                        ;
                else {
@@ -1661,6 +1722,19 @@ mono_resolve_patch_target (MonoMethod *method, MonoDomain *domain, guint8 *code,
        case MONO_PATCH_INFO_GSHAREDVT_IN_WRAPPER:
                target = mini_get_gsharedvt_wrapper (TRUE, NULL, patch_info->data.sig, NULL, -1, FALSE);
                break;
+       case MONO_PATCH_INFO_GET_TLS_TRAMP:
+#ifdef MONO_ARCH_HAVE_GET_TLS_TRAMP
+               target = mono_arch_get_get_tls_tramp ();
+#else
+               target = NULL;
+#endif
+               break;
+       case MONO_PATCH_INFO_JIT_THREAD_ATTACH: {
+               MonoJitICallInfo *mi = mono_find_jit_icall_by_name ("mono_jit_thread_attach");
+               g_assert (mi);
+               target = mi->func;
+               break;
+       }
        default:
                g_assert_not_reached ();
        }
@@ -1879,6 +1953,15 @@ mono_jit_compile_method_with_opt (MonoMethod *method, guint32 opt, MonoError *er
                if ((code = mono_aot_get_method_checked (domain, method, error))) {
                        MonoVTable *vtable;
 
+                       if (mono_runtime_is_critical_method (method) || mono_gc_is_critical_method (method)) {
+                               /*
+                                * The suspend code needs to be able to lookup these methods by ip in async context,
+                                * so preload their jit info.
+                                */
+                               MonoJitInfo *ji = mono_jit_info_table_find (domain, code);
+                               g_assert (ji);
+                       }
+
                        /*
                         * In llvm-only mode, method might be a shared method, so we can't initialize its class.
                         * This is not a problem, since it will be initialized when the method is first
@@ -3086,7 +3169,7 @@ mono_get_delegate_virtual_invoke_impl (MonoMethodSignature *sig, MonoMethod *met
                return NULL;
 
        is_virtual_generic = method->is_inflated && mono_method_get_declaring_generic_method (method)->is_generic;
-       is_interface = method->klass->flags & TYPE_ATTRIBUTE_INTERFACE ? TRUE : FALSE;
+       is_interface = mono_class_is_interface (method->klass);
        load_imt_reg = is_virtual_generic || is_interface;
 
        if (is_interface)
@@ -3512,6 +3595,8 @@ mini_init (const char *filename, const char *runtime_version)
 
        mono_cross_helpers_run ();
 
+       mono_counters_init ();
+
        mini_jit_init ();
 
        /* Happens when using the embedding interface */
@@ -3560,6 +3645,11 @@ mini_init (const char *filename, const char *runtime_version)
        callbacks.compile_method = mono_jit_compile_method;
        callbacks.create_jump_trampoline = mono_create_jump_trampoline;
        callbacks.create_jit_trampoline = mono_create_jit_trampoline;
+       callbacks.create_delegate_trampoline = mono_create_delegate_trampoline;
+       callbacks.free_method = mono_jit_free_method;
+#ifndef DISABLE_REMOTING
+       callbacks.create_remoting_trampoline = mono_jit_create_remoting_trampoline;
+#endif
 #endif
 
        mono_install_callbacks (&callbacks);
@@ -3570,8 +3660,6 @@ mini_init (const char *filename, const char *runtime_version)
        ticallbacks.thread_state_init_from_handle = mono_thread_state_init_from_handle;
        ticallbacks.thread_state_init = mono_thread_state_init;
 
-       mono_counters_init ();
-
 #ifndef HOST_WIN32
        mono_w32handle_init ();
 #endif
@@ -3635,11 +3723,6 @@ mini_init (const char *filename, const char *runtime_version)
        mono_threads_install_cleanup (mini_thread_cleanup);
 
 #ifdef JIT_TRAMPOLINES_WORK
-       mono_install_free_method (mono_jit_free_method);
-#ifndef DISABLE_REMOTING
-       mono_install_remoting_trampoline (mono_jit_create_remoting_trampoline);
-#endif
-       mono_install_delegate_trampoline (mono_create_delegate_trampoline);
        mono_install_create_domain_hook (mini_create_jit_domain_info);
        mono_install_free_domain_hook (mini_free_jit_domain_info);
 #endif
@@ -4201,7 +4284,7 @@ mono_precompile_assembly (MonoAssembly *ass, void *user_data)
                }
                if (method->flags & METHOD_ATTRIBUTE_ABSTRACT)
                        continue;
-               if (method->is_generic || method->klass->generic_container)
+               if (method->is_generic || mono_class_is_gtd (method->klass))
                        continue;
 
                count++;