[interp] Reduce computation under calc_section mutex
authorVlad Brezae <brezaevlad@gmail.com>
Tue, 25 Jun 2019 15:43:25 +0000 (18:43 +0300)
committerLarry Ewing <lewing@microsoft.com>
Wed, 26 Jun 2019 12:10:37 +0000 (07:10 -0500)
Calc_section mutex is meant to be a lower level mutex used only for synchronization on InterpMethod contents. Before this commit we were taking the loader mutex which was leading to deadlocks.

Commit migrated from https://github.com/mono/mono/commit/aa05d4f43c127a3d34aeb5e7b8ece58a452aa7e3

src/mono/mono/mini/interp/transform.c

index cc1fdeb..4c8c8e1 100644 (file)
@@ -6124,9 +6124,7 @@ mono_interp_transform_method (InterpMethod *imethod, ThreadContext *context, Mon
 
        if (method->iflags & (METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL | METHOD_IMPL_ATTRIBUTE_RUNTIME)) {
                MonoMethod *nm = NULL;
-               mono_os_mutex_lock (&calc_section);
                if (imethod->transformed) {
-                       mono_os_mutex_unlock (&calc_section);
                        MONO_PROFILER_RAISE (jit_done, (method, imethod->jinfo));
                        return;
                }
@@ -6160,16 +6158,17 @@ mono_interp_transform_method (InterpMethod *imethod, ThreadContext *context, Mon
                                g_assert_not_reached ();
                }
                if (nm == NULL) {
+                       mono_os_mutex_lock (&calc_section);
                        imethod->stack_size = sizeof (stackval); /* for tracing */
                        imethod->alloca_size = imethod->stack_size;
+                       mono_memory_barrier ();
                        imethod->transformed = TRUE;
-                       mono_os_mutex_unlock(&calc_section);
+                       mono_os_mutex_unlock (&calc_section);
                        MONO_PROFILER_RAISE (jit_done, (method, NULL));
                        return;
                }
                method = nm;
                header = interp_method_get_header (nm, error);
-               mono_os_mutex_unlock (&calc_section);
                return_if_nok (error);
        }