[mono] Remove domain lock (#50328)
authorZoltan Varga <vargaz@gmail.com>
Tue, 30 Mar 2021 23:18:03 +0000 (19:18 -0400)
committerGitHub <noreply@github.com>
Tue, 30 Mar 2021 23:18:03 +0000 (19:18 -0400)
* [mono] Reduce domain lock usage.

* Avoid double locking the loader+domain lock, its not needed.
* Use the mem manager lock and the loader lock in a few places instead of
  the domain lock.
* Use lock free code in mono_jit_runtime_invoke ().
* Avoid locking around mono_jit_info_table_add (), it does locking itself.

* [mono] Internalize access to MonoMemoryManager.mp to memory-manager.c.

Also add a separate non-coop lock to protect it, since its accessed
very frequently.

* Use a separate lock for each memory manager.

* Remove the domain lock.

12 files changed:
src/mono/mono/metadata/appdomain.c
src/mono/mono/metadata/domain-internals.h
src/mono/mono/metadata/domain.c
src/mono/mono/metadata/loader-internals.h
src/mono/mono/metadata/lock-tracer.h
src/mono/mono/metadata/memory-manager.c
src/mono/mono/metadata/object.c
src/mono/mono/metadata/sre.c
src/mono/mono/mini/interp/interp.c
src/mono/mono/mini/mini-generic-sharing.c
src/mono/mono/mini/mini-runtime.c
src/mono/mono/mini/mini.c

index bbb9209..11b20d7 100644 (file)
@@ -605,13 +605,7 @@ exit:
 gboolean
 mono_domain_owns_vtable_slot (MonoDomain *domain, gpointer vtable_slot)
 {
-       gboolean res;
-       MonoMemoryManager *memory_manager = mono_mem_manager_get_ambient ();
-
-       mono_mem_manager_lock (memory_manager);
-       res = mono_mempool_contains_addr (memory_manager->mp, vtable_slot);
-       mono_mem_manager_unlock (memory_manager);
-       return res;
+       return mono_mem_manager_mp_contains_addr (mono_mem_manager_get_ambient (), vtable_slot);
 }
 
 gboolean
index c822b14..9465be2 100644 (file)
@@ -48,13 +48,6 @@ typedef struct _MonoJitCodeHash MonoJitCodeHash;
 
 struct _MonoDomain {
        /*
-        * This lock must never be taken before the loader lock,
-        * i.e. if both are taken by the same thread, the loader lock
-        * must taken first.
-        */
-       MonoCoopMutex    lock;
-
-       /*
         * keep all the managed objects close to each other for the precise GC
         * For the Boehm GC we additionally keep close also other GC-tracked pointers.
         */
@@ -112,9 +105,6 @@ mono_domain_assemblies_unlock (MonoDomain *domain)
 
 typedef MonoDomain* (*MonoLoadFunc) (const char *filename, const char *runtime_version);
 
-void mono_domain_lock (MonoDomain *domain);
-void mono_domain_unlock (MonoDomain *domain);
-
 void
 mono_install_runtime_load  (MonoLoadFunc func);
 
index ba2ea79..c887af3 100644 (file)
@@ -316,8 +316,6 @@ mono_domain_create (void)
 
        domain->domain_assemblies = NULL;
 
-       mono_coop_mutex_init_recursive (&domain->lock);
-
        mono_coop_mutex_init_recursive (&domain->assemblies_lock);
 
        mono_appdomains_lock ();
@@ -1257,18 +1255,6 @@ mono_get_runtime_info (void)
        return current_runtime;
 }
 
-void
-mono_domain_lock (MonoDomain *domain)
-{
-       mono_locks_coop_acquire (&domain->lock, DomainLock);
-}
-
-void
-mono_domain_unlock (MonoDomain *domain)
-{
-       mono_locks_coop_release (&domain->lock, DomainLock);
-}
-
 GPtrArray*
 mono_domain_get_assemblies (MonoDomain *domain)
 {
index 051b11a..34f5576 100644 (file)
@@ -86,7 +86,6 @@ struct _MonoAssemblyLoadContext {
 };
 
 struct _MonoMemoryManager {
-       MonoDomain *domain;
        // Whether the MemoryManager can be unloaded on netcore; should only be set at creation
        gboolean collectible;
        // Whether this is a singleton or generic MemoryManager
@@ -98,10 +97,15 @@ struct _MonoMemoryManager {
        // Currently unused, we take the domain lock instead
        MonoCoopMutex lock;
 
-       MonoMemPool *mp;
+       // Private, don't access directly
+       MonoMemPool *_mp;
        MonoCodeManager *code_mp;
        LockFreeMempool *lock_free_mp;
 
+       // Protects access to _mp
+       // Non-coop, non-recursive
+       mono_mutex_t mp_mutex;
+
        GPtrArray *class_vtable_array;
        GHashTable *generic_virtual_cases;
 
@@ -238,14 +242,8 @@ void *
 mono_mem_manager_alloc (MonoMemoryManager *memory_manager, guint size);
 
 void *
-mono_mem_manager_alloc_nolock (MonoMemoryManager *memory_manager, guint size);
-
-void *
 mono_mem_manager_alloc0 (MonoMemoryManager *memory_manager, guint size);
 
-void *
-mono_mem_manager_alloc0_nolock (MonoMemoryManager *memory_manager, guint size);
-
 gpointer
 mono_mem_manager_alloc0_lock_free (MonoMemoryManager *memory_manager, guint size);
 
@@ -271,6 +269,9 @@ mono_mem_manager_strdup (MonoMemoryManager *memory_manager, const char *s);
 void
 mono_mem_manager_free_debug_info (MonoMemoryManager *memory_manager);
 
+gboolean
+mono_mem_manager_mp_contains_addr (MonoMemoryManager *memory_manager, gpointer addr);
+
 G_END_DECLS
 
 #endif
index f9b0bb3..8a111ff 100644 (file)
@@ -15,7 +15,6 @@ typedef enum {
        InvalidLock = 0,
        LoaderLock,
        ImageDataLock,
-       DomainLock,
        DomainAssembliesLock,
        DomainJitCodeHashLock,
        IcallLock,
index b8cf5cb..901e945 100644 (file)
@@ -95,12 +95,12 @@ memory_manager_init (MonoMemoryManager *memory_manager, gboolean collectible)
 {
        MonoDomain *domain = mono_get_root_domain ();
 
-       memory_manager->domain = domain;
        memory_manager->freeing = FALSE;
 
        mono_coop_mutex_init_recursive (&memory_manager->lock);
+       mono_os_mutex_init (&memory_manager->mp_mutex);
 
-       memory_manager->mp = mono_mempool_new ();
+       memory_manager->_mp = mono_mempool_new ();
        memory_manager->code_mp = mono_code_manager_new ();
        memory_manager->lock_free_mp = lock_free_mempool_new ();
 
@@ -183,15 +183,15 @@ memory_manager_delete (MonoMemoryManager *memory_manager, gboolean debug_unload)
        mono_coop_mutex_destroy (&memory_manager->lock);
 
        if (debug_unload) {
-               mono_mempool_invalidate (memory_manager->mp);
+               mono_mempool_invalidate (memory_manager->_mp);
                mono_code_manager_invalidate (memory_manager->code_mp);
        } else {
 #ifndef DISABLE_PERFCOUNTERS
                /* FIXME: use an explicit subtraction method as soon as it's available */
-               mono_atomic_fetch_add_i32 (&mono_perfcounters->loader_bytes, -1 * mono_mempool_get_allocated (memory_manager->mp));
+               mono_atomic_fetch_add_i32 (&mono_perfcounters->loader_bytes, -1 * mono_mempool_get_allocated (memory_manager->_mp));
 #endif
-               mono_mempool_destroy (memory_manager->mp);
-               memory_manager->mp = NULL;
+               mono_mempool_destroy (memory_manager->_mp);
+               memory_manager->_mp = NULL;
                mono_code_manager_destroy (memory_manager->code_mp);
                memory_manager->code_mp = NULL;
        }
@@ -217,57 +217,55 @@ mono_mem_manager_free_singleton (MonoSingletonMemoryManager *memory_manager, gbo
 void
 mono_mem_manager_lock (MonoMemoryManager *memory_manager)
 {
-       //mono_coop_mutex_lock (&memory_manager->lock);
-       mono_domain_lock (memory_manager->domain);
+       mono_coop_mutex_lock (&memory_manager->lock);
 }
 
 void
 mono_mem_manager_unlock (MonoMemoryManager *memory_manager)
 {
-       //mono_coop_mutex_unlock (&memory_manager->lock);
-       mono_domain_unlock (memory_manager->domain);
+       mono_coop_mutex_unlock (&memory_manager->lock);
 }
 
-void *
-mono_mem_manager_alloc (MonoMemoryManager *memory_manager, guint size)
+static inline void
+alloc_lock (MonoMemoryManager *memory_manager)
 {
-       void *res;
-
-       mono_mem_manager_lock (memory_manager);
-       res = mono_mem_manager_alloc_nolock (memory_manager, size);
-       mono_mem_manager_unlock (memory_manager);
-
-       return res;
+       mono_os_mutex_lock (&memory_manager->mp_mutex);
 }
 
-void *
-mono_mem_manager_alloc_nolock (MonoMemoryManager *memory_manager, guint size)
+static inline void
+alloc_unlock (MonoMemoryManager *memory_manager)
 {
-#ifndef DISABLE_PERFCOUNTERS
-       mono_atomic_fetch_add_i32 (&mono_perfcounters->loader_bytes, size);
-#endif
-       return mono_mempool_alloc (memory_manager->mp, size);
+       mono_os_mutex_unlock (&memory_manager->mp_mutex);
 }
 
 void *
-mono_mem_manager_alloc0 (MonoMemoryManager *memory_manager, guint size)
+mono_mem_manager_alloc (MonoMemoryManager *memory_manager, guint size)
 {
        void *res;
 
-       mono_mem_manager_lock (memory_manager);
-       res = mono_mem_manager_alloc0_nolock (memory_manager, size);
-       mono_mem_manager_unlock (memory_manager);
+       alloc_lock (memory_manager);
+#ifndef DISABLE_PERFCOUNTERS
+       mono_atomic_fetch_add_i32 (&mono_perfcounters->loader_bytes, size);
+#endif
+       res = mono_mempool_alloc (memory_manager->_mp, size);
+       alloc_unlock (memory_manager);
 
        return res;
 }
 
 void *
-mono_mem_manager_alloc0_nolock (MonoMemoryManager *memory_manager, guint size)
+mono_mem_manager_alloc0 (MonoMemoryManager *memory_manager, guint size)
 {
+       void *res;
+
+       alloc_lock (memory_manager);
 #ifndef DISABLE_PERFCOUNTERS
        mono_atomic_fetch_add_i32 (&mono_perfcounters->loader_bytes, size);
 #endif
-       return mono_mempool_alloc0 (memory_manager->mp, size);
+       res = mono_mempool_alloc0 (memory_manager->_mp, size);
+       alloc_unlock (memory_manager);
+
+       return res;
 }
 
 char*
@@ -275,10 +273,21 @@ mono_mem_manager_strdup (MonoMemoryManager *memory_manager, const char *s)
 {
        char *res;
 
-       mono_mem_manager_lock (memory_manager);
-       res = mono_mempool_strdup (memory_manager->mp, s);
-       mono_mem_manager_unlock (memory_manager);
+       alloc_lock (memory_manager);
+       res = mono_mempool_strdup (memory_manager->_mp, s);
+       alloc_unlock (memory_manager);
+
+       return res;
+}
+
+gboolean
+mono_mem_manager_mp_contains_addr (MonoMemoryManager *memory_manager, gpointer addr)
+{
+       gboolean res;
 
+       alloc_lock (memory_manager);
+       res = mono_mempool_contains_addr (memory_manager->_mp, addr);
+       alloc_unlock (memory_manager);
        return res;
 }
 
index 0618631..f90bb34 100644 (file)
@@ -1468,7 +1468,7 @@ static MonoImtBuilderEntry*
 get_generic_virtual_entries (MonoMemoryManager *mem_manager, gpointer *vtable_slot);
 
 /*
- * LOCKING: requires the loader and domain locks.
+ * LOCKING: assume the loader lock is held
  *
 */
 static void
@@ -1626,7 +1626,9 @@ build_imt (MonoClass *klass, MonoVTable *vt, gpointer* imt, GSList *extra_interf
 {
        MONO_REQ_GC_NEUTRAL_MODE;
 
+       mono_loader_lock ();
        build_imt_slots (klass, vt, imt, extra_interfaces, -1);
+       mono_loader_unlock ();
 }
 
 /**
@@ -1636,7 +1638,7 @@ build_imt (MonoClass *klass, MonoVTable *vt, gpointer* imt, GSList *extra_interf
  * Fill the given \p imt_slot in the IMT table of \p vtable with
  * a trampoline or a trampoline for the case of collisions.
  * This is part of the internal mono API.
- * LOCKING: Take the domain lock.
+ * LOCKING: Take the loader lock.
  */
 void
 mono_vtable_build_imt_slot (MonoVTable* vtable, int imt_slot)
@@ -1652,12 +1654,10 @@ mono_vtable_build_imt_slot (MonoVTable* vtable, int imt_slot)
         * Update and heck needs to ahppen inside the proper domain lock, as all
         * the changes made to a MonoVTable.
         */
-       mono_loader_lock (); /*FIXME build_imt_slots requires the loader lock.*/
-       mono_domain_lock (vtable->domain);
+       mono_loader_lock ();
        /* we change the slot only if it wasn't changed from the generic imt trampoline already */
        if (!callbacks.imt_entry_inited (vtable, imt_slot))
                build_imt_slots (vtable->klass, vtable, imt, NULL, imt_slot);
-       mono_domain_unlock (vtable->domain);
        mono_loader_unlock ();
 }
 
@@ -1684,9 +1684,8 @@ get_generic_virtual_entries (MonoMemoryManager *mem_manager, gpointer *vtable_sl
 
        GenericVirtualCase *list;
        MonoImtBuilderEntry *entries;
-       MonoDomain *domain = mono_get_root_domain ();
 
-       mono_domain_lock (domain);
+       mono_mem_manager_lock (mem_manager);
        if (!mem_manager->generic_virtual_cases)
                mem_manager->generic_virtual_cases = g_hash_table_new (mono_aligned_addr_hash, NULL);
  
@@ -1709,7 +1708,7 @@ get_generic_virtual_entries (MonoMemoryManager *mem_manager, gpointer *vtable_sl
                entries = entry;
        }
  
-       mono_domain_unlock (domain);
+       mono_mem_manager_unlock (mem_manager);
  
        /* FIXME: Leaking memory ? */
        return entries;
@@ -1740,10 +1739,11 @@ mono_method_add_generic_virtual_invocation (MonoVTable *vtable,
        GenericVirtualCase *gvc, *list;
        MonoImtBuilderEntry *entries;
        GPtrArray *sorted;
-       MonoDomain *domain = mono_get_root_domain ();
        MonoMemoryManager *mem_manager = m_class_get_mem_manager (vtable->klass);
 
-       mono_domain_lock (domain);
+       mono_loader_lock ();
+
+       mono_mem_manager_lock (mem_manager);
        if (!mem_manager->generic_virtual_cases)
                mem_manager->generic_virtual_cases = g_hash_table_new (mono_aligned_addr_hash, NULL);
 
@@ -1775,6 +1775,8 @@ mono_method_add_generic_virtual_invocation (MonoVTable *vtable,
                num_added++;
        }
 
+       mono_mem_manager_unlock (mem_manager);
+
        if (++gvc->count == THUNK_THRESHOLD) {
                gpointer *old_thunk = (void **)*vtable_slot;
                gpointer vtable_trampoline = NULL;
@@ -1812,7 +1814,7 @@ mono_method_add_generic_virtual_invocation (MonoVTable *vtable,
                }
        }
 
-       mono_domain_unlock (domain);
+       mono_loader_unlock ();
 }
 
 static MonoVTable *mono_class_create_runtime_vtable (MonoClass *klass, MonoError *error);
@@ -2173,7 +2175,6 @@ mono_class_create_runtime_vtable (MonoClass *klass, MonoError *error)
                MonoReflectionTypeHandle vt_type = mono_type_get_object_handle (m_class_get_byval_arg (klass), error);
                vt->type = MONO_HANDLE_RAW (vt_type);
                if (!is_ok (error)) {
-                       mono_domain_unlock (domain);
                        mono_loader_unlock ();
                        MONO_PROFILER_RAISE (vtable_failed, (vt));
                        goto return_null;
index c70b302..aa7c53a 100644 (file)
@@ -3853,21 +3853,15 @@ ves_icall_TypeBuilder_create_runtime_class (MonoReflectionTypeBuilderHandle ref_
        reflection_setup_internal_class (ref_tb, error);
        mono_error_assert_ok (error);
 
-       MonoDomain *domain = MONO_HANDLE_DOMAIN (ref_tb);
        MonoType *type = MONO_HANDLE_GETVAL (MONO_HANDLE_CAST (MonoReflectionType, ref_tb), type);
        MonoClass *klass = mono_class_from_mono_type_internal (type);
 
        MonoArrayHandle cattrs = MONO_HANDLE_NEW_GET (MonoArray, ref_tb, cattrs);
        mono_save_custom_attrs (klass->image, klass, MONO_HANDLE_RAW (cattrs)); /* FIXME use handles */
 
-       /* 
-        * we need to lock the domain because the lock will be taken inside
-        * So, we need to keep the locking order correct.
-        */
        mono_loader_lock ();
-       mono_domain_lock (domain);
+
        if (klass->wastypebuilder) {
-               mono_domain_unlock (domain);
                mono_loader_unlock ();
 
                return mono_type_get_object_handle (m_class_get_byval_arg (klass), error);
@@ -3957,7 +3951,6 @@ ves_icall_TypeBuilder_create_runtime_class (MonoReflectionTypeBuilderHandle ref_
                goto_if_nok (error, failure);
        }
 
-       mono_domain_unlock (domain);
        mono_loader_unlock ();
 
        if (klass->enumtype && !mono_class_is_valid_enum (klass)) {
@@ -3975,7 +3968,6 @@ ves_icall_TypeBuilder_create_runtime_class (MonoReflectionTypeBuilderHandle ref_
 failure:
        mono_class_set_type_load_failure (klass, "TypeBuilder could not create runtime class due to: %s", mono_error_get_message (error));
        klass->wastypebuilder = TRUE;
-       mono_domain_unlock (domain);
        mono_loader_unlock ();
 failure_unlocked:
        return MONO_HANDLE_CAST (MonoReflectionType, NULL_HANDLE);
index 1fa5e26..daaae50 100644 (file)
@@ -632,6 +632,25 @@ typedef struct {
        InterpMethod *target_imethod;
 } InterpVTableEntry;
 
+static inline GSList*
+g_slist_append_node (GSList *list, GSList *new_list, gpointer data)
+{
+       GSList *last;
+
+       new_list->data = data;
+       new_list->next = NULL;
+
+       if (list) {
+               last = list;
+               while (last->next)
+                       last = last->next;
+               last->next = new_list;
+
+               return list;
+       } else
+               return new_list;
+}
+
 /* memory manager lock must be held */
 static GSList*
 append_imethod (MonoMemoryManager *memory_manager, GSList *list, InterpMethod *imethod, InterpMethod *target_imethod)
@@ -639,10 +658,11 @@ append_imethod (MonoMemoryManager *memory_manager, GSList *list, InterpMethod *i
        GSList *ret;
        InterpVTableEntry *entry;
 
-       entry = (InterpVTableEntry*) mono_mem_manager_alloc_nolock (memory_manager, sizeof (InterpVTableEntry));
+       entry = (InterpVTableEntry*) mono_mem_manager_alloc0 (memory_manager, sizeof (InterpVTableEntry));
        entry->imethod = imethod;
        entry->target_imethod = target_imethod;
-       ret = g_slist_append_mempool (memory_manager->mp, list, entry);
+       ret = mono_mem_manager_alloc0 (memory_manager, sizeof (GSList));
+       ret = g_slist_append_node (list, ret, entry);
 
        return ret;
 }
index 513df68..6661dd6 100644 (file)
@@ -2901,7 +2901,6 @@ fill_runtime_generic_context (MonoVTable *class_vtable, MonoRuntimeGenericContex
 {
        gpointer info;
        int i, first_slot, size;
-       MonoDomain *domain = mono_get_root_domain ();
        MonoClass *klass = class_vtable->klass;
        MonoGenericContext *class_context;
        MonoRuntimeGenericContextInfoTemplate oti;
@@ -2963,7 +2962,7 @@ fill_runtime_generic_context (MonoVTable *class_vtable, MonoRuntimeGenericContex
        class_context = mono_class_is_ginst (klass) ? &mono_class_get_generic_class (klass)->context : NULL;
        MonoGenericContext context = { class_context ? class_context->class_inst : NULL, method_inst };
 
-       mono_domain_lock (domain);
+       mono_mem_manager_lock (jit_mm->mem_manager);
 
        /* First check whether that slot isn't already instantiated.
           This might happen because lookup doesn't lock.  Allocate
@@ -2984,7 +2983,7 @@ fill_runtime_generic_context (MonoVTable *class_vtable, MonoRuntimeGenericContex
                        rgctx_index = slot - first_slot + 1 + offset;
                        info = (MonoRuntimeGenericContext*)rgctx [rgctx_index];
                        if (info) {
-                               mono_domain_unlock (domain);
+                               mono_mem_manager_unlock (jit_mm->mem_manager);
                                return info;
                        }
                        break;
@@ -3002,7 +3001,7 @@ fill_runtime_generic_context (MonoVTable *class_vtable, MonoRuntimeGenericContex
 
        g_assert (!rgctx [rgctx_index]);
 
-       mono_domain_unlock (domain);
+       mono_mem_manager_unlock (jit_mm->mem_manager);
 
        oti = class_get_rgctx_template_oti (get_shared_class (klass),
                                                                                method_inst ? method_inst->type_argc : 0, slot, TRUE, TRUE, &do_free);
@@ -3017,7 +3016,7 @@ fill_runtime_generic_context (MonoVTable *class_vtable, MonoRuntimeGenericContex
        */
 
        /*FIXME We should use CAS here, no need to take a lock.*/
-       mono_domain_lock (domain);
+       mono_mem_manager_lock (jit_mm->mem_manager);
 
        /* Check whether the slot hasn't been instantiated in the
           meantime. */
@@ -3029,7 +3028,7 @@ fill_runtime_generic_context (MonoVTable *class_vtable, MonoRuntimeGenericContex
                rgctx [rgctx_index] = info;
        }
 
-       mono_domain_unlock (domain);
+       mono_mem_manager_unlock (jit_mm->mem_manager);
 
        if (do_free)
                free_inflated_info (oti.info_type, oti.data);
index 6af9844..48b3f76 100644 (file)
@@ -3267,22 +3267,19 @@ mono_jit_runtime_invoke (MonoMethod *method, void *obj, void **params, MonoObjec
                *exc = NULL;
 
 #ifdef MONO_ARCH_DYN_CALL_SUPPORTED
-       MonoDomain *domain = mono_get_root_domain ();
        static RuntimeInvokeDynamicFunction dyn_runtime_invoke = NULL;
        if (info->dyn_call_info) {
                if (!dyn_runtime_invoke) {
-                       mono_domain_lock (domain);
-
                        invoke = mono_marshal_get_runtime_invoke_dynamic ();
-                       dyn_runtime_invoke = (RuntimeInvokeDynamicFunction)mono_jit_compile_method_jit_only (invoke, error);
+                       RuntimeInvokeDynamicFunction invoke_func = (RuntimeInvokeDynamicFunction)mono_jit_compile_method_jit_only (invoke, error);
+                       mono_memory_barrier ();
+                       dyn_runtime_invoke = invoke_func;
                        if (!dyn_runtime_invoke && mono_use_interpreter) {
                                info->use_interp = TRUE;
                                info->dyn_call_info = NULL;
                        } else if (!is_ok (error)) {
-                               mono_domain_unlock (domain);
                                return NULL;
                        }
-                       mono_domain_unlock (domain);
                }
        }
        if (info->dyn_call_info) {
index c188f36..1937846 100644 (file)
@@ -3800,10 +3800,7 @@ mini_method_compile (MonoMethod *method, guint32 opts, JitFlags flags, int parts
        }
 
        if (!cfg->compile_aot && !(flags & JIT_FLAG_DISCARD_RESULTS)) {
-               MonoDomain *domain = mono_get_root_domain ();
-               mono_domain_lock (domain);
                mono_jit_info_table_add (cfg->jit_info);
-               mono_domain_unlock (domain);
 
                if (cfg->method->dynamic) {
                        MonoJitMemoryManager *jit_mm = (MonoJitMemoryManager*)cfg->jit_mm;
@@ -3963,7 +3960,6 @@ mono_jit_compile_method_inner (MonoMethod *method, int opt, MonoError *error)
        MonoException *ex = NULL;
        gint64 start;
        MonoMethod *prof_method, *shared;
-       MonoDomain *target_domain = mono_get_root_domain ();
 
        error_init (error);
 
@@ -4034,7 +4030,7 @@ mono_jit_compile_method_inner (MonoMethod *method, int opt, MonoError *error)
                shared = NULL;
        }
 
-       mono_domain_lock (target_domain);
+       mono_loader_lock ();
 
        if (mono_stats_method_desc && mono_method_desc_full_match (mono_stats_method_desc, method)) {
                g_printf ("Printing runtime stats at method: %s\n", mono_method_get_full_name (method));
@@ -4081,7 +4077,7 @@ mono_jit_compile_method_inner (MonoMethod *method, int opt, MonoError *error)
        mono_emit_jit_map (jinfo);
        mono_emit_jit_dump (jinfo, code);
 #endif
-       mono_domain_unlock (target_domain);
+       mono_loader_unlock ();
 
        if (!is_ok (error))
                return NULL;