diff --git a/src/mono/mono/metadata/assembly-load-context.c b/src/mono/mono/metadata/assembly-load-context.c index 04aaeaaef826f4..dec9f96b6755f3 100644 --- a/src/mono/mono/metadata/assembly-load-context.c +++ b/src/mono/mono/metadata/assembly-load-context.c @@ -682,6 +682,21 @@ mono_alc_get_all_loaded_assemblies (void) return assemblies; } +GPtrArray* +mono_alc_get_all (void) +{ + // FIXME: prevent the individual ALCs from being collected until the iteration is done. + GSList *tmp; + GPtrArray *all_alcs = g_ptr_array_new (); + MonoAssemblyLoadContext *alc; + alcs_lock (); + for (tmp = alcs; tmp; tmp = tmp->next) { + alc = (MonoAssemblyLoadContext *)tmp->data; + g_ptr_array_add (all_alcs, alc); + } + alcs_unlock (); + return all_alcs; +} MonoBoolean ves_icall_System_Reflection_LoaderAllocatorScout_Destroy (gpointer native) @@ -722,3 +737,4 @@ ves_icall_System_Reflection_LoaderAllocatorScout_Destroy (gpointer native) return TRUE; #endif } + diff --git a/src/mono/mono/metadata/loader-internals.h b/src/mono/mono/metadata/loader-internals.h index d58404aff6b693..8356a0bcb1dc5c 100644 --- a/src/mono/mono/metadata/loader-internals.h +++ b/src/mono/mono/metadata/loader-internals.h @@ -305,6 +305,9 @@ mono_alc_find_assembly (MonoAssemblyLoadContext *alc, MonoAssemblyName *aname); MONO_COMPONENT_API GPtrArray* mono_alc_get_all_loaded_assemblies (void); +GPtrArray* +mono_alc_get_all (void); + MONO_API void mono_loader_save_bundled_library (int fd, uint64_t offset, uint64_t size, const char *destfname); diff --git a/src/mono/mono/mini/interp/interp.c b/src/mono/mono/mini/interp/interp.c index 294b395f18783b..e368f2e4b397e8 100644 --- a/src/mono/mono/mini/interp/interp.c +++ b/src/mono/mono/mini/interp/interp.c @@ -80,6 +80,7 @@ #include #include +#include #ifdef TARGET_ARM #include @@ -8591,7 +8592,6 @@ metadata_update_prepare_to_invalidate (void) /* (2) invalidate all the registered imethods */ } - static void interp_invalidate_transformed (void) { @@ -8602,17 +8602,27 @@ interp_invalidate_transformed (void) need_stw_restart = TRUE; } - // FIXME: Enumerate all memory managers - MonoJitMemoryManager *jit_mm = get_default_jit_mm (); + GPtrArray *alcs = mono_alc_get_all (); - jit_mm_lock (jit_mm); - mono_internal_hash_table_apply (&jit_mm->interp_code_hash, invalidate_transform, NULL); - jit_mm_unlock (jit_mm); + if (alcs) { + MonoAssemblyLoadContext* alc; + for (guint i = 0; i < alcs->len; ++i) { + alc = (MonoAssemblyLoadContext*)g_ptr_array_index (alcs, i); + MonoJitMemoryManager *jit_mm = (MonoJitMemoryManager*)(alc->memory_manager->runtime_info); + + jit_mm_lock (jit_mm); + mono_internal_hash_table_apply (&jit_mm->interp_code_hash, invalidate_transform, NULL); + jit_mm_unlock (jit_mm); + } + + g_ptr_array_free (alcs, TRUE); + } if (need_stw_restart) mono_restart_world (MONO_THREAD_INFO_FLAGS_NO_GC); } + typedef struct { MonoJitInfo **jit_info_array; gint size; @@ -8630,27 +8640,34 @@ interp_copy_jit_info_func (gpointer imethod, gpointer user_data) static void interp_jit_info_foreach (InterpJitInfoFunc func, gpointer user_data) { - InterpCopyJitInfoFuncUserData copy_jit_info_data; - - // FIXME: Enumerate all memory managers - MonoJitMemoryManager *jit_mm = get_default_jit_mm (); + GPtrArray *alcs = mono_alc_get_all (); + + if (alcs) { + MonoAssemblyLoadContext* alc; + for (guint i = 0; i < alcs->len; ++i) { + alc = (MonoAssemblyLoadContext*)g_ptr_array_index (alcs, i); + MonoJitMemoryManager *jit_mm = (MonoJitMemoryManager*)(alc->memory_manager->runtime_info); + InterpCopyJitInfoFuncUserData copy_jit_info_data; + // Can't keep memory manager lock while iterating and calling callback since it might take other locks + // causing poential deadlock situations. Instead, create copy of interpreter imethod jinfo pointers into + // plain array and use pointers from array when when running callbacks. + copy_jit_info_data.size = mono_atomic_load_i32 (&(jit_mm->interp_code_hash.num_entries)); + copy_jit_info_data.next = 0; + copy_jit_info_data.jit_info_array = (MonoJitInfo**) g_new (MonoJitInfo*, copy_jit_info_data.size); + if (copy_jit_info_data.jit_info_array) { + jit_mm_lock (jit_mm); + mono_internal_hash_table_apply (&jit_mm->interp_code_hash, interp_copy_jit_info_func, ©_jit_info_data); + jit_mm_unlock (jit_mm); + } - // Can't keep memory manager lock while iterating and calling callback since it might take other locks - // causing poential deadlock situations. Instead, create copy of interpreter imethod jinfo pointers into - // plain array and use pointers from array when when running callbacks. - copy_jit_info_data.size = mono_atomic_load_i32 (&(jit_mm->interp_code_hash.num_entries)); - copy_jit_info_data.next = 0; - copy_jit_info_data.jit_info_array = (MonoJitInfo**) g_new (MonoJitInfo*, copy_jit_info_data.size); - if (copy_jit_info_data.jit_info_array) { - jit_mm_lock (jit_mm); - mono_internal_hash_table_apply (&jit_mm->interp_code_hash, interp_copy_jit_info_func, ©_jit_info_data); - jit_mm_unlock (jit_mm); - } - - if (copy_jit_info_data.jit_info_array) { - for (int i = 0; i < copy_jit_info_data.next; ++i) - func (copy_jit_info_data.jit_info_array [i], user_data); - g_free (copy_jit_info_data.jit_info_array); + if (copy_jit_info_data.jit_info_array) { + for (int j = 0; j < copy_jit_info_data.next; ++j) + func (copy_jit_info_data.jit_info_array [j], user_data); + g_free (copy_jit_info_data.jit_info_array); + } + } + + g_ptr_array_free (alcs, TRUE); } }