[sgen] Move the logic to determine whenever an ip is in a critical method to sgen...
authorZoltan Varga <vargaz@gmail.com>
Mon, 31 Oct 2016 17:18:28 +0000 (13:18 -0400)
committerGitHub <noreply@github.com>
Mon, 31 Oct 2016 17:18:28 +0000 (13:18 -0400)
mono/metadata/boehm-gc.c
mono/metadata/gc-internals.h
mono/metadata/sgen-mono.c
mono/mini/mini-runtime.c
mono/utils/mono-threads.c
mono/utils/mono-threads.h

index 2c648c85da6d7bf8bb36a165c5931bafe013fe3a..0d47d88beda989a173d99301957aa1dc1f0abd86 100644 (file)
@@ -1115,7 +1115,7 @@ create_allocator (int atype, int tls_key, gboolean slowpath)
 static MonoMethod* alloc_method_cache [ATYPE_NUM];
 static MonoMethod* slowpath_alloc_method_cache [ATYPE_NUM];
 
 static MonoMethod* alloc_method_cache [ATYPE_NUM];
 static MonoMethod* slowpath_alloc_method_cache [ATYPE_NUM];
 
-static G_GNUC_UNUSED gboolean
+gboolean
 mono_gc_is_critical_method (MonoMethod *method)
 {
        int i;
 mono_gc_is_critical_method (MonoMethod *method)
 {
        int i;
@@ -1234,7 +1234,7 @@ mono_gc_get_write_barrier (void)
 
 #else
 
 
 #else
 
-static G_GNUC_UNUSED gboolean
+gboolean
 mono_gc_is_critical_method (MonoMethod *method)
 {
        return FALSE;
 mono_gc_is_critical_method (MonoMethod *method)
 {
        return FALSE;
index afb6522d1cba060c2c664bc069377fcc0aa1b621..2ef55c6e6733baa729f9a37c2bbb544d82c7d03d 100644 (file)
@@ -360,6 +360,8 @@ guint mono_gc_get_vtable_bits (MonoClass *klass);
 
 void mono_gc_register_altstack (gpointer stack, gint32 stack_size, gpointer altstack, gint32 altstack_size);
 
 
 void mono_gc_register_altstack (gpointer stack, gint32 stack_size, gpointer altstack, gint32 altstack_size);
 
+gboolean mono_gc_is_critical_method (MonoMethod *method);
+
 /* If set, print debugging messages around finalizers. */
 extern gboolean log_finalizers;
 
 /* If set, print debugging messages around finalizers. */
 extern gboolean log_finalizers;
 
index 6372084d21dfb43b801fd1a0374c5aeb12a463c1..26e6a089b5dbb987e5d5cb6af8efc54b7c63eca1 100644 (file)
@@ -212,6 +212,32 @@ sgen_has_critical_method (void)
        return sgen_has_managed_allocator ();
 }
 
        return sgen_has_managed_allocator ();
 }
 
+static gboolean
+ip_in_critical_region (MonoDomain *domain, gpointer ip)
+{
+       MonoJitInfo *ji;
+       MonoMethod *method;
+
+       /*
+        * We pass false for 'try_aot' so this becomes async safe.
+        * It won't find aot methods whose jit info is not yet loaded,
+        * so we preload their jit info in the JIT.
+        */
+       ji = mono_jit_info_table_find_internal (domain, ip, FALSE, FALSE);
+       if (!ji)
+               return FALSE;
+
+       method = mono_jit_info_get_method (ji);
+
+       return mono_runtime_is_critical_method (method) || sgen_is_critical_method (method);
+}
+
+gboolean
+mono_gc_is_critical_method (MonoMethod *method)
+{
+       return sgen_is_critical_method (method);
+}
+
 #ifndef DISABLE_JIT
 
 static void
 #ifndef DISABLE_JIT
 
 static void
@@ -2285,12 +2311,6 @@ mono_gc_set_skip_thread (gboolean skip)
        UNLOCK_GC;
 }
 
        UNLOCK_GC;
 }
 
-static gboolean
-is_critical_method (MonoMethod *method)
-{
-       return mono_runtime_is_critical_method (method) || sgen_is_critical_method (method);
-}
-
 static gboolean
 thread_in_critical_region (SgenThreadInfo *info)
 {
 static gboolean
 thread_in_critical_region (SgenThreadInfo *info)
 {
@@ -2845,8 +2865,8 @@ sgen_client_init (void)
        cb.thread_detach = sgen_thread_detach;
        cb.thread_unregister = sgen_thread_unregister;
        cb.thread_attach = sgen_thread_attach;
        cb.thread_detach = sgen_thread_detach;
        cb.thread_unregister = sgen_thread_unregister;
        cb.thread_attach = sgen_thread_attach;
-       cb.mono_method_is_critical = (gboolean (*)(void *))is_critical_method;
        cb.mono_thread_in_critical_region = thread_in_critical_region;
        cb.mono_thread_in_critical_region = thread_in_critical_region;
+       cb.ip_in_critical_region = ip_in_critical_region;
 
        mono_threads_init (&cb, sizeof (SgenThreadInfo));
 
 
        mono_threads_init (&cb, sizeof (SgenThreadInfo));
 
index 307470970e18a7e59718b02555a841d065164c68..987f8de2df90daab83d358542da79071dd6fc237 100644 (file)
@@ -1879,6 +1879,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 ((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
                        /*
                         * 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
index 836ac22d5f6bf0759e1ad81d161a577ca4834448..c4d9cc3229dcd35d14f418d1b4ae7919dc1f89fc 100644 (file)
@@ -875,6 +875,9 @@ is_thread_in_critical_region (MonoThreadInfo *info)
        if (stack_start < info->stack_start_limit || stack_start >= info->stack_end)
                return TRUE;
 
        if (stack_start < info->stack_start_limit || stack_start >= info->stack_end)
                return TRUE;
 
+       if (threads_callbacks.ip_in_critical_region)
+               return threads_callbacks.ip_in_critical_region ((MonoDomain *) state->unwind_data [MONO_UNWIND_DATA_DOMAIN], (char *) MONO_CONTEXT_GET_IP (&state->ctx));
+
        ji = mono_jit_info_table_find (
                (MonoDomain *) state->unwind_data [MONO_UNWIND_DATA_DOMAIN],
                (char *) MONO_CONTEXT_GET_IP (&state->ctx));
        ji = mono_jit_info_table_find (
                (MonoDomain *) state->unwind_data [MONO_UNWIND_DATA_DOMAIN],
                (char *) MONO_CONTEXT_GET_IP (&state->ctx));
index 36c297c060bd520fd89e737eb5b491d3938c1616..a9776c32dbf8dc99a4e47fef09064210cdf23848 100644 (file)
@@ -229,6 +229,7 @@ typedef struct {
        void (*thread_detach)(THREAD_INFO_TYPE *info);
        void (*thread_attach)(THREAD_INFO_TYPE *info);
        gboolean (*mono_method_is_critical) (void *method);
        void (*thread_detach)(THREAD_INFO_TYPE *info);
        void (*thread_attach)(THREAD_INFO_TYPE *info);
        gboolean (*mono_method_is_critical) (void *method);
+       gboolean (*ip_in_critical_region) (MonoDomain *domain, gpointer ip);
        gboolean (*mono_thread_in_critical_region) (THREAD_INFO_TYPE *info);
 } MonoThreadInfoCallbacks;
 
        gboolean (*mono_thread_in_critical_region) (THREAD_INFO_TYPE *info);
 } MonoThreadInfoCallbacks;