diff --git a/src/mono/mono/metadata/appdomain.c b/src/mono/mono/metadata/appdomain.c index 11b20d7fc84fe..762858c430b3a 100644 --- a/src/mono/mono/metadata/appdomain.c +++ b/src/mono/mono/metadata/appdomain.c @@ -50,7 +50,6 @@ #include #include #include -#include #include #include #include @@ -81,14 +80,6 @@ #include "object-internals.h" #include "icall-decl.h" -typedef struct -{ - int runtime_count; - int assemblybinding_count; - MonoDomain *domain; - gchar *filename; -} RuntimeConfig; - static gboolean no_exec = FALSE; static int n_appctx_props; @@ -120,12 +111,6 @@ mono_domain_assembly_search (MonoAssemblyLoadContext *alc, MonoAssembly *request static void mono_domain_fire_assembly_load (MonoAssemblyLoadContext *alc, MonoAssembly *assembly, gpointer user_data, MonoError *error_out); -static void -add_assemblies_to_domain (MonoDomain *domain, MonoAssembly *ass, GHashTable *ht); - -static void -add_assembly_to_alc (MonoAssemblyLoadContext *alc, MonoAssembly *ass); - static const char * runtimeconfig_json_get_buffer (MonovmRuntimeConfigArguments *arg, MonoFileMap **file_map, gpointer *buf_handle); @@ -135,7 +120,6 @@ runtimeconfig_json_read_props (const char *ptr, const char **endp, int nprops, g static MonoLoadFunc load_function = NULL; /* Lazy class loading functions */ -static GENERATE_GET_CLASS_WITH_CACHE (assembly, "System.Reflection", "Assembly"); static GENERATE_GET_CLASS_WITH_CACHE (app_context, "System", "AppContext"); MonoClass* @@ -188,15 +172,10 @@ create_domain_objects (MonoDomain *domain) HANDLE_FUNCTION_ENTER (); ERROR_DECL (error); - MonoDomain *old_domain = mono_domain_get (); MonoStringHandle arg; MonoVTable *string_vt; MonoClassField *string_empty_fld; - if (domain != old_domain) { - mono_domain_set_internal_with_options (domain, FALSE); - } - /* * Initialize String.Empty. This enables the removal of * the static cctor of the String class. @@ -233,13 +212,10 @@ create_domain_objects (MonoDomain *domain) domain->stack_overflow_ex = MONO_HANDLE_RAW (mono_exception_from_name_two_strings_checked (mono_defaults.corlib, "System", "StackOverflowException", arg, NULL_HANDLE_STRING, error)); mono_error_assert_ok (error); - /*The ephemeron tombstone i*/ + /* The ephemeron tombstone */ domain->ephemeron_tombstone = MONO_HANDLE_RAW (mono_object_new_handle (mono_defaults.object_class, error)); mono_error_assert_ok (error); - if (domain != old_domain) - mono_domain_set_internal_with_options (old_domain, FALSE); - /* * This class is used during exception handling, so initialize it here, to prevent * stack overflows while handling stack overflows. @@ -412,16 +388,6 @@ mono_check_corlib_version_internal (void) #endif } -/** - * mono_context_init: - * \param domain The domain where the \c System.Runtime.Remoting.Context.Context is initialized - * Initializes the \p domain's default \c System.Runtime.Remoting 's Context. - */ -void -mono_context_init (MonoDomain *domain) -{ -} - /** * mono_runtime_cleanup: * \param domain unused. @@ -475,24 +441,6 @@ mono_runtime_quit_internal (void) quit_function (mono_get_root_domain (), NULL); } -/** - * mono_domain_set_config: - * \param domain \c MonoDomain initialized with the appdomain we want to change - * \param base_dir new base directory for the appdomain - * \param config_file_name path to the new configuration for the app domain - * - * Used to set the system configuration for an appdomain - * - * Without using this, embedded builds will get 'System.Configuration.ConfigurationErrorsException: - * Error Initializing the configuration system. ---> System.ArgumentException: - * The 'ExeConfigFilename' argument cannot be null.' for some managed calls. - */ -void -mono_domain_set_config (MonoDomain *domain, const char *base_dir, const char *config_file_name) -{ - g_assert_not_reached (); -} - /** * mono_domain_has_type_resolve: * \param domain application domain being looked up @@ -509,46 +457,8 @@ mono_domain_has_type_resolve (MonoDomain *domain) return TRUE; } -/** - * mono_domain_try_type_resolve: - * \param domain application domain in which to resolve the type - * \param name the name of the type to resolve or NULL. - * \param typebuilder A \c System.Reflection.Emit.TypeBuilder, used if name is NULL. - * - * This routine invokes the internal \c System.AppDomain.DoTypeResolve and returns - * the assembly that matches name, or ((TypeBuilder)typebuilder).FullName. - * - * \returns A \c MonoReflectionAssembly or NULL if not found - */ -MonoReflectionAssembly * -mono_domain_try_type_resolve (MonoDomain *domain, char *name, MonoObject *typebuilder_raw) -{ - HANDLE_FUNCTION_ENTER (); - - g_assert (domain); - g_assert (name || typebuilder_raw); - - ERROR_DECL (error); - - MonoReflectionAssemblyHandle ret = NULL_HANDLE_INIT; - - // This will not work correctly on netcore - if (name) { - MonoStringHandle name_handle = mono_string_new_handle (name, error); - goto_if_nok (error, exit); - ret = mono_domain_try_type_resolve_name (domain, NULL, name_handle, error); - } else { - // TODO: make this work on netcore when working on SRE.TypeBuilder - g_assert_not_reached (); - } - -exit: - mono_error_cleanup (error); - HANDLE_FUNCTION_RETURN_OBJ (ret); -} - MonoReflectionAssemblyHandle -mono_domain_try_type_resolve_name (MonoDomain *domain, MonoAssembly *assembly, MonoStringHandle name, MonoError *error) +mono_domain_try_type_resolve_name (MonoAssembly *assembly, MonoStringHandle name, MonoError *error) { MonoObjectHandle ret; MonoReflectionAssemblyHandle assembly_handle; @@ -573,7 +483,6 @@ mono_domain_try_type_resolve_name (MonoDomain *domain, MonoAssembly *assembly, M if (!method) goto return_null; - g_assert (domain); g_assert (MONO_HANDLE_BOOL (name)); if (mono_runtime_get_no_exec ()) @@ -608,54 +517,6 @@ mono_domain_owns_vtable_slot (MonoDomain *domain, gpointer vtable_slot) return mono_mem_manager_mp_contains_addr (mono_mem_manager_get_ambient (), vtable_slot); } -gboolean -mono_domain_set_fast (MonoDomain *domain, gboolean force) -{ - MONO_REQ_GC_UNSAFE_MODE; - - mono_domain_set_internal_with_options (domain, TRUE); - return TRUE; -} - -static gboolean -add_assembly_to_array (MonoArrayHandle dest, int dest_idx, MonoAssembly* assm, MonoError *error) -{ - HANDLE_FUNCTION_ENTER (); - error_init (error); - MonoReflectionAssemblyHandle assm_obj = mono_assembly_get_object_handle (assm, error); - goto_if_nok (error, leave); - MONO_HANDLE_ARRAY_SETREF (dest, dest_idx, assm_obj); -leave: - HANDLE_FUNCTION_RETURN_VAL (is_ok (error)); -} - -static MonoArrayHandle -get_assembly_array_from_domain (MonoDomain *domain, MonoError *error) -{ - int i; - GPtrArray *assemblies; - - assemblies = mono_domain_get_assemblies (domain); - - MonoArrayHandle res = mono_array_new_handle (mono_class_get_assembly_class (), assemblies->len, error); - goto_if_nok (error, leave); - for (i = 0; i < assemblies->len; ++i) { - if (!add_assembly_to_array (res, i, (MonoAssembly *)g_ptr_array_index (assemblies, i), error)) - goto leave; - } - -leave: - g_ptr_array_free (assemblies, TRUE); - return res; -} - -MonoArrayHandle -ves_icall_System_Runtime_Loader_AssemblyLoadContext_InternalGetLoadedAssemblies (MonoError *error) -{ - MonoDomain *domain = mono_domain_get (); - return get_assembly_array_from_domain (domain, error); -} - MonoAssembly* mono_try_assembly_resolve (MonoAssemblyLoadContext *alc, const char *fname_raw, MonoAssembly *requesting, MonoError *error) { @@ -740,65 +601,6 @@ mono_domain_assembly_postload_search (MonoAssemblyLoadContext *alc, MonoAssembly return assembly; } - -/* - * LOCKING: assumes assemblies_lock in the domain is already locked. - */ -static void -add_assemblies_to_domain (MonoDomain *domain, MonoAssembly *ass, GHashTable *ht) -{ - GSList *tmp; - gboolean destroy_ht = FALSE; - - g_assert (ass != NULL); - - if (!ass->aname.name) - return; - - if (!ht) { - ht = g_hash_table_new (mono_aligned_addr_hash, NULL); - destroy_ht = TRUE; - for (tmp = domain->domain_assemblies; tmp; tmp = tmp->next) { - g_hash_table_add (ht, tmp->data); - } - } - - if (!g_hash_table_lookup (ht, ass)) { - mono_assembly_addref (ass); - g_hash_table_add (ht, ass); - domain->domain_assemblies = g_slist_append (domain->domain_assemblies, ass); - mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_ASSEMBLY, "Assembly %s[%p] added to domain %s, ref_count=%d", ass->aname.name, ass, domain->friendly_name, ass->ref_count); - } - - if (destroy_ht) - g_hash_table_destroy (ht); -} - -/* - * LOCKING: assumes the ALC's assemblies lock is taken - */ -static void -add_assembly_to_alc (MonoAssemblyLoadContext *alc, MonoAssembly *ass) -{ - GSList *tmp; - - g_assert (ass != NULL); - - if (!ass->aname.name) - return; - - for (tmp = alc->loaded_assemblies; tmp; tmp = tmp->next) { - if (tmp->data == ass) { - return; - } - } - - mono_assembly_addref (ass); - // Prepending here will break the test suite with frequent InvalidCastExceptions, so we have to append - alc->loaded_assemblies = g_slist_append (alc->loaded_assemblies, ass); - mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_ASSEMBLY, "Assembly %s[%p] added to ALC (%p), ref_count=%d", ass->aname.name, ass, (gpointer)alc, ass->ref_count); - -} static void mono_domain_fire_assembly_load_event (MonoDomain *domain, MonoAssembly *assembly, MonoError *error) @@ -847,14 +649,7 @@ mono_domain_fire_assembly_load (MonoAssemblyLoadContext *alc, MonoAssembly *asse mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_ASSEMBLY, "Loading assembly %s (%p) into domain %s (%p) and ALC %p", assembly->aname.name, assembly, domain->friendly_name, domain, alc); - mono_domain_assemblies_lock (domain); - mono_alc_assemblies_lock (alc); - - add_assemblies_to_domain (domain, assembly, NULL); - add_assembly_to_alc (alc, assembly); - - mono_alc_assemblies_unlock (alc); - mono_domain_assemblies_unlock (domain); + mono_alc_add_assembly (alc, assembly); if (!MONO_BOOL (domain->domain)) goto leave; // This can happen during startup @@ -866,15 +661,6 @@ mono_domain_fire_assembly_load (MonoAssemblyLoadContext *alc, MonoAssembly *asse mono_error_cleanup (error); } -/** - * mono_domain_from_appdomain: - */ -MonoDomain * -mono_domain_from_appdomain (MonoAppDomain *appdomain_raw) -{ - return mono_get_root_domain (); -} - static gboolean try_load_from (MonoAssembly **assembly, const gchar *path1, const gchar *path2, @@ -1034,25 +820,8 @@ mono_domain_assembly_search (MonoAssemblyLoadContext *alc, MonoAssembly *request MonoError *error) { g_assert (aname != NULL); - GSList *tmp; - MonoAssembly *ass; - const MonoAssemblyNameEqFlags eq_flags = MONO_ANAME_EQ_IGNORE_PUBKEY | MONO_ANAME_EQ_IGNORE_VERSION | MONO_ANAME_EQ_IGNORE_CASE; - - mono_alc_assemblies_lock (alc); - for (tmp = alc->loaded_assemblies; tmp; tmp = tmp->next) { - ass = (MonoAssembly *)tmp->data; - g_assert (ass != NULL); - // FIXME: Can dynamic assemblies match here for netcore? - if (assembly_is_dynamic (ass) || !mono_assembly_names_equal_flags (aname, &ass->aname, eq_flags)) - continue; - - mono_alc_assemblies_unlock (alc); - return ass; - } - mono_alc_assemblies_unlock (alc); - - return NULL; + return mono_alc_find_assembly (alc, aname); } MonoReflectionAssemblyHandle @@ -1117,118 +886,6 @@ ves_icall_System_Reflection_Assembly_InternalLoad (MonoStringHandle name_handle, return MONO_HANDLE_CAST (MonoReflectionAssembly, NULL_HANDLE); } -static -MonoAssembly * -mono_alc_load_file (MonoAssemblyLoadContext *alc, MonoStringHandle fname, MonoAssembly *executing_assembly, MonoAssemblyContextKind asmctx, MonoError *error) -{ - MonoAssembly *ass = NULL; - HANDLE_FUNCTION_ENTER (); - char *filename = NULL; - if (MONO_HANDLE_IS_NULL (fname)) { - mono_error_set_argument_null (error, "assemblyFile", ""); - goto leave; - } - - filename = mono_string_handle_to_utf8 (fname, error); - goto_if_nok (error, leave); - - if (!g_path_is_absolute (filename)) { - mono_error_set_argument (error, "assemblyFile", "Absolute path information is required."); - goto leave; - } - - MonoImageOpenStatus status; - MonoAssemblyOpenRequest req; - mono_assembly_request_prepare_open (&req, asmctx, alc); - req.requesting_assembly = executing_assembly; - ass = mono_assembly_request_open (filename, &req, &status); - if (!ass) { - if (status == MONO_IMAGE_IMAGE_INVALID) - mono_error_set_bad_image_by_name (error, filename, "Invalid Image: %s", filename); - else - mono_error_set_simple_file_not_found (error, filename); - } - -leave: - g_free (filename); - HANDLE_FUNCTION_RETURN_VAL (ass); -} - -MonoReflectionAssemblyHandle -ves_icall_System_Runtime_Loader_AssemblyLoadContext_InternalLoadFile (gpointer alc_ptr, MonoStringHandle fname, MonoStackCrawlMark *stack_mark, MonoError *error) -{ - MonoReflectionAssemblyHandle result = MONO_HANDLE_CAST (MonoReflectionAssembly, NULL_HANDLE); - MonoAssemblyLoadContext *alc = (MonoAssemblyLoadContext *)alc_ptr; - - MonoAssembly *executing_assembly; - executing_assembly = mono_runtime_get_caller_from_stack_mark (stack_mark); - MonoAssembly *ass = mono_alc_load_file (alc, fname, executing_assembly, mono_alc_is_default (alc) ? MONO_ASMCTX_LOADFROM : MONO_ASMCTX_INDIVIDUAL, error); - goto_if_nok (error, leave); - - result = mono_assembly_get_object_handle (ass, error); - -leave: - return result; -} - -static MonoAssembly* -mono_alc_load_raw_bytes (MonoAssemblyLoadContext *alc, guint8 *raw_assembly, guint32 raw_assembly_len, guint8 *raw_symbol_data, guint32 raw_symbol_len, MonoError *error); - -MonoReflectionAssemblyHandle -ves_icall_System_Runtime_Loader_AssemblyLoadContext_InternalLoadFromStream (gpointer native_alc, gpointer raw_assembly_ptr, gint32 raw_assembly_len, gpointer raw_symbols_ptr, gint32 raw_symbols_len, MonoError *error) -{ - MonoAssemblyLoadContext *alc = (MonoAssemblyLoadContext *)native_alc; - MonoReflectionAssemblyHandle result = MONO_HANDLE_CAST (MonoReflectionAssembly, NULL_HANDLE); - MonoAssembly *assm = NULL; - assm = mono_alc_load_raw_bytes (alc, (guint8 *)raw_assembly_ptr, raw_assembly_len, (guint8 *)raw_symbols_ptr, raw_symbols_len, error); - goto_if_nok (error, leave); - - result = mono_assembly_get_object_handle (assm, error); - -leave: - return result; -} - -static MonoAssembly* -mono_alc_load_raw_bytes (MonoAssemblyLoadContext *alc, guint8 *assembly_data, guint32 raw_assembly_len, guint8 *raw_symbol_data, guint32 raw_symbol_len, MonoError *error) -{ - MonoAssembly *ass = NULL; - MonoImageOpenStatus status; - MonoImage *image = mono_image_open_from_data_internal (alc, (char*)assembly_data, raw_assembly_len, TRUE, NULL, FALSE, NULL, NULL); - - if (!image) { - mono_error_set_bad_image_by_name (error, "In memory assembly", "0x%p", assembly_data); - return ass; - } - - if (raw_symbol_data) - mono_debug_open_image_from_memory (image, raw_symbol_data, raw_symbol_len); - - MonoAssemblyLoadRequest req; - mono_assembly_request_prepare_load (&req, MONO_ASMCTX_INDIVIDUAL, alc); - ass = mono_assembly_request_load_from (image, "", &req, &status); - - if (!ass) { - mono_image_close (image); - mono_error_set_bad_image_by_name (error, "In Memory assembly", "0x%p", assembly_data); - return ass; - } - - /* Clear the reference added by mono_image_open_from_data_internal above */ - mono_image_close (image); - - return ass; -} - -/** - * mono_domain_is_unloading: - */ -gboolean -mono_domain_is_unloading (MonoDomain *domain) -{ - return FALSE; -} - /* Remember properties so they can be be installed in AppContext during runtime init */ void mono_runtime_register_appctx_properties (int nprops, const char **keys, const char **values) diff --git a/src/mono/mono/metadata/appdomain.h b/src/mono/mono/metadata/appdomain.h index fedeee1a9a038..e6a17ddd3df1d 100644 --- a/src/mono/mono/metadata/appdomain.h +++ b/src/mono/mono/metadata/appdomain.h @@ -73,13 +73,13 @@ mono_domain_set_config (MonoDomain *domain, const char *base_dir, const char *co MONO_API MonoDomain * mono_domain_get (void); -MONO_API MonoDomain * +MONO_API MONO_RT_EXTERNAL_ONLY MonoDomain * mono_domain_get_by_id (int32_t domainid); -MONO_API int32_t +MONO_API MONO_RT_EXTERNAL_ONLY int32_t mono_domain_get_id (MonoDomain *domain); -MONO_API const char * +MONO_API MONO_RT_EXTERNAL_ONLY const char * mono_domain_get_friendly_name (MonoDomain *domain); MONO_API MONO_RT_EXTERNAL_ONLY mono_bool @@ -91,16 +91,16 @@ mono_domain_set_internal (MonoDomain *domain); MONO_API MONO_RT_EXTERNAL_ONLY void mono_domain_unload (MonoDomain *domain); -MONO_API void +MONO_API MONO_RT_EXTERNAL_ONLY void mono_domain_try_unload (MonoDomain *domain, MonoObject **exc); -MONO_API mono_bool +MONO_API MONO_RT_EXTERNAL_ONLY mono_bool mono_domain_is_unloading (MonoDomain *domain); MONO_API MONO_RT_EXTERNAL_ONLY MonoDomain * mono_domain_from_appdomain (MonoAppDomain *appdomain); -MONO_API void +MONO_API MONO_RT_EXTERNAL_ONLY void mono_domain_foreach (MonoDomainFunc func, void* user_data); MONO_API MONO_RT_EXTERNAL_ONLY MonoAssembly * @@ -112,7 +112,7 @@ mono_domain_ensure_entry_assembly (MonoDomain *domain, MonoAssembly *assembly); MONO_API MONO_RT_EXTERNAL_ONLY mono_bool mono_domain_finalize (MonoDomain *domain, uint32_t timeout); -MONO_API void +MONO_API MONO_RT_EXTERNAL_ONLY void mono_domain_free (MonoDomain *domain, mono_bool force); MONO_API mono_bool @@ -130,13 +130,13 @@ mono_context_init (MonoDomain *domain); MONO_API MONO_RT_EXTERNAL_ONLY void mono_context_set (MonoAppContext *new_context); -MONO_API MonoAppContext * +MONO_API MONO_RT_EXTERNAL_ONLY MonoAppContext * mono_context_get (void); -MONO_API int32_t +MONO_API MONO_RT_EXTERNAL_ONLY int32_t mono_context_get_id (MonoAppContext *context); -MONO_API int32_t +MONO_API MONO_RT_EXTERNAL_ONLY int32_t mono_context_get_domain_id (MonoAppContext *context); MONO_API MonoJitInfo * diff --git a/src/mono/mono/metadata/assembly-load-context.c b/src/mono/mono/metadata/assembly-load-context.c index 24ac7ef6a6b58..1dbd387ab117f 100644 --- a/src/mono/mono/metadata/assembly-load-context.c +++ b/src/mono/mono/metadata/assembly-load-context.c @@ -2,20 +2,25 @@ #include "mono/utils/mono-compiler.h" #include "mono/metadata/assembly.h" +#include "mono/metadata/assembly-internals.h" #include "mono/metadata/domain-internals.h" #include "mono/metadata/exception-internals.h" #include "mono/metadata/icall-decl.h" #include "mono/metadata/loader-internals.h" #include "mono/metadata/loaded-images-internals.h" #include "mono/metadata/mono-private-unstable.h" +#include "mono/metadata/mono-debug.h" #include "mono/utils/mono-error-internals.h" #include "mono/utils/mono-logger-internals.h" GENERATE_GET_CLASS_WITH_CACHE (assembly_load_context, "System.Runtime.Loader", "AssemblyLoadContext"); +static GENERATE_GET_CLASS_WITH_CACHE (assembly, "System.Reflection", "Assembly"); static GSList *alcs; static MonoAssemblyLoadContext *default_alc; static MonoCoopMutex alc_list_lock; /* Used when accessing 'alcs' */ +/* Protected by alc_list_lock */ +static GSList *loaded_assemblies; static inline void alcs_lock (void) @@ -92,17 +97,18 @@ mono_alc_cleanup_assemblies (MonoAssemblyLoadContext *alc) // The minimum refcount on assemblies is 2: one for the domain and one for the ALC. // The domain refcount might be less than optimal on netcore, but its removal is too likely to cause issues for now. GSList *tmp; - MonoDomain *domain = mono_get_root_domain (); - // Remove the assemblies from domain_assemblies - mono_domain_assemblies_lock (domain); + // Remove the assemblies from loaded_assemblies for (tmp = alc->loaded_assemblies; tmp; tmp = tmp->next) { MonoAssembly *assembly = (MonoAssembly *)tmp->data; - domain->domain_assemblies = g_slist_remove (domain->domain_assemblies, assembly); + + alcs_lock (); + loaded_assemblies = g_slist_remove (loaded_assemblies, assembly); + alcs_unlock (); + mono_assembly_decref (assembly); - mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_ASSEMBLY, "Unloading ALC [%p], removing assembly %s[%p] from domain_assemblies, ref_count=%d\n", alc, assembly->aname.name, assembly, assembly->ref_count); + mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_ASSEMBLY, "Unloading ALC [%p], removing assembly %s[%p] from loaded_assemblies, ref_count=%d\n", alc, assembly->aname.name, assembly, assembly->ref_count); } - mono_domain_assemblies_unlock (domain); // Release the GC roots for (tmp = alc->loaded_assemblies; tmp; tmp = tmp->next) { @@ -262,6 +268,135 @@ ves_icall_System_Runtime_Loader_AssemblyLoadContext_GetLoadContextForAssembly (M return (gpointer)alc->gchandle; } +static gboolean +add_assembly_to_array (MonoArrayHandle dest, int dest_idx, MonoAssembly* assm, MonoError *error) +{ + HANDLE_FUNCTION_ENTER (); + error_init (error); + MonoReflectionAssemblyHandle assm_obj = mono_assembly_get_object_handle (assm, error); + goto_if_nok (error, leave); + MONO_HANDLE_ARRAY_SETREF (dest, dest_idx, assm_obj); +leave: + HANDLE_FUNCTION_RETURN_VAL (is_ok (error)); +} + +MonoArrayHandle +ves_icall_System_Runtime_Loader_AssemblyLoadContext_InternalGetLoadedAssemblies (MonoError *error) +{ + GPtrArray *assemblies = mono_alc_get_all_loaded_assemblies (); + + MonoArrayHandle res = mono_array_new_handle (mono_class_get_assembly_class (), assemblies->len, error); + goto_if_nok (error, leave); + for (int i = 0; i < assemblies->len; ++i) { + if (!add_assembly_to_array (res, i, (MonoAssembly *)g_ptr_array_index (assemblies, i), error)) + goto leave; + } + +leave: + g_ptr_array_free (assemblies, TRUE); + return res; +} + +static +MonoAssembly * +mono_alc_load_file (MonoAssemblyLoadContext *alc, MonoStringHandle fname, MonoAssembly *executing_assembly, MonoAssemblyContextKind asmctx, MonoError *error) +{ + MonoAssembly *ass = NULL; + HANDLE_FUNCTION_ENTER (); + char *filename = NULL; + if (MONO_HANDLE_IS_NULL (fname)) { + mono_error_set_argument_null (error, "assemblyFile", ""); + goto leave; + } + + filename = mono_string_handle_to_utf8 (fname, error); + goto_if_nok (error, leave); + + if (!g_path_is_absolute (filename)) { + mono_error_set_argument (error, "assemblyFile", "Absolute path information is required."); + goto leave; + } + + MonoImageOpenStatus status; + MonoAssemblyOpenRequest req; + mono_assembly_request_prepare_open (&req, asmctx, alc); + req.requesting_assembly = executing_assembly; + ass = mono_assembly_request_open (filename, &req, &status); + if (!ass) { + if (status == MONO_IMAGE_IMAGE_INVALID) + mono_error_set_bad_image_by_name (error, filename, "Invalid Image: %s", filename); + else + mono_error_set_simple_file_not_found (error, filename); + } + +leave: + g_free (filename); + HANDLE_FUNCTION_RETURN_VAL (ass); +} + +MonoReflectionAssemblyHandle +ves_icall_System_Runtime_Loader_AssemblyLoadContext_InternalLoadFile (gpointer alc_ptr, MonoStringHandle fname, MonoStackCrawlMark *stack_mark, MonoError *error) +{ + MonoReflectionAssemblyHandle result = MONO_HANDLE_CAST (MonoReflectionAssembly, NULL_HANDLE); + MonoAssemblyLoadContext *alc = (MonoAssemblyLoadContext *)alc_ptr; + + MonoAssembly *executing_assembly; + executing_assembly = mono_runtime_get_caller_from_stack_mark (stack_mark); + MonoAssembly *ass = mono_alc_load_file (alc, fname, executing_assembly, mono_alc_is_default (alc) ? MONO_ASMCTX_LOADFROM : MONO_ASMCTX_INDIVIDUAL, error); + goto_if_nok (error, leave); + + result = mono_assembly_get_object_handle (ass, error); + +leave: + return result; +} + +static MonoAssembly* +mono_alc_load_raw_bytes (MonoAssemblyLoadContext *alc, guint8 *assembly_data, guint32 raw_assembly_len, guint8 *raw_symbol_data, guint32 raw_symbol_len, MonoError *error) +{ + MonoAssembly *ass = NULL; + MonoImageOpenStatus status; + MonoImage *image = mono_image_open_from_data_internal (alc, (char*)assembly_data, raw_assembly_len, TRUE, NULL, FALSE, NULL, NULL); + + if (!image) { + mono_error_set_bad_image_by_name (error, "In memory assembly", "0x%p", assembly_data); + return ass; + } + + if (raw_symbol_data) + mono_debug_open_image_from_memory (image, raw_symbol_data, raw_symbol_len); + + MonoAssemblyLoadRequest req; + mono_assembly_request_prepare_load (&req, MONO_ASMCTX_INDIVIDUAL, alc); + ass = mono_assembly_request_load_from (image, "", &req, &status); + + if (!ass) { + mono_image_close (image); + mono_error_set_bad_image_by_name (error, "In Memory assembly", "0x%p", assembly_data); + return ass; + } + + /* Clear the reference added by mono_image_open_from_data_internal above */ + mono_image_close (image); + + return ass; +} + +MonoReflectionAssemblyHandle +ves_icall_System_Runtime_Loader_AssemblyLoadContext_InternalLoadFromStream (gpointer native_alc, gpointer raw_assembly_ptr, gint32 raw_assembly_len, gpointer raw_symbols_ptr, gint32 raw_symbols_len, MonoError *error) +{ + MonoAssemblyLoadContext *alc = (MonoAssemblyLoadContext *)native_alc; + MonoReflectionAssemblyHandle result = MONO_HANDLE_CAST (MonoReflectionAssembly, NULL_HANDLE); + MonoAssembly *assm = NULL; + assm = mono_alc_load_raw_bytes (alc, (guint8 *)raw_assembly_ptr, raw_assembly_len, (guint8 *)raw_symbols_ptr, raw_symbols_len, error); + goto_if_nok (error, leave); + + result = mono_assembly_get_object_handle (assm, error); + +leave: + return result; +} + gboolean mono_alc_is_default (MonoAssemblyLoadContext *alc) { @@ -420,3 +555,77 @@ mono_alc_invoke_resolve_using_resolve_satellite_nofail (MonoAssemblyLoadContext return result; } + +void +mono_alc_add_assembly (MonoAssemblyLoadContext *alc, MonoAssembly *ass) +{ + GSList *tmp; + + g_assert (ass); + + if (!ass->aname.name) + return; + + mono_alc_assemblies_lock (alc); + for (tmp = alc->loaded_assemblies; tmp; tmp = tmp->next) { + if (tmp->data == ass) { + mono_alc_assemblies_unlock (alc); + return; + } + } + + mono_assembly_addref (ass); + // Prepending here will break the test suite with frequent InvalidCastExceptions, so we have to append + alc->loaded_assemblies = g_slist_append (alc->loaded_assemblies, ass); + mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_ASSEMBLY, "Assembly %s[%p] added to ALC (%p), ref_count=%d", ass->aname.name, ass, (gpointer)alc, ass->ref_count); + mono_alc_assemblies_unlock (alc); + + alcs_lock (); + loaded_assemblies = g_slist_append (loaded_assemblies, ass); + alcs_unlock (); +} + +MonoAssembly* +mono_alc_find_assembly (MonoAssemblyLoadContext *alc, MonoAssemblyName *aname) +{ + GSList *tmp; + MonoAssembly *ass; + + const MonoAssemblyNameEqFlags eq_flags = MONO_ANAME_EQ_IGNORE_PUBKEY | MONO_ANAME_EQ_IGNORE_VERSION | MONO_ANAME_EQ_IGNORE_CASE; + + mono_alc_assemblies_lock (alc); + for (tmp = alc->loaded_assemblies; tmp; tmp = tmp->next) { + ass = (MonoAssembly *)tmp->data; + g_assert (ass != NULL); + // FIXME: Can dynamic assemblies match here for netcore? + if (assembly_is_dynamic (ass) || !mono_assembly_names_equal_flags (aname, &ass->aname, eq_flags)) + continue; + + mono_alc_assemblies_unlock (alc); + return ass; + } + mono_alc_assemblies_unlock (alc); + return NULL; +} + +/* + * mono_alc_get_all_loaded_assemblies: + * + * Return a list of loaded assemblies in all appdomains. + */ +GPtrArray* +mono_alc_get_all_loaded_assemblies (void) +{ + GSList *tmp; + GPtrArray *assemblies; + MonoAssembly *ass; + + assemblies = g_ptr_array_new (); + alcs_lock (); + for (tmp = loaded_assemblies; tmp; tmp = tmp->next) { + ass = (MonoAssembly *)tmp->data; + g_ptr_array_add (assemblies, ass); + } + alcs_unlock (); + return assemblies; +} diff --git a/src/mono/mono/metadata/class-internals.h b/src/mono/mono/metadata/class-internals.h index 3dbbcb429b7e7..f6130da1b81c6 100644 --- a/src/mono/mono/metadata/class-internals.h +++ b/src/mono/mono/metadata/class-internals.h @@ -1536,6 +1536,13 @@ m_field_get_offset (MonoClassField *field) * the lifetime of the image/class/method. */ +static inline MonoMemoryManager* +mono_mem_manager_get_ambient (void) +{ + // FIXME: All callers should get a MemoryManager from their callers or context + return (MonoMemoryManager *)mono_alc_get_default ()->memory_manager; +} + static inline MonoMemoryManager* m_image_get_mem_manager (MonoImage *image) { @@ -1582,7 +1589,7 @@ static inline MonoMemoryManager* m_method_get_mem_manager (MonoMethod *method) { // FIXME: - return mono_domain_memory_manager (mono_get_root_domain ()); + return (MonoMemoryManager *)mono_alc_get_default ()->memory_manager; } static inline void * diff --git a/src/mono/mono/metadata/domain-internals.h b/src/mono/mono/metadata/domain-internals.h index 9465be28d7b6f..9a626660c327b 100644 --- a/src/mono/mono/metadata/domain-internals.h +++ b/src/mono/mono/metadata/domain-internals.h @@ -38,14 +38,6 @@ struct _MonoAppContext { gint32 context_id; }; -typedef struct _MonoThunkFreeList { - guint32 size; - int length; /* only valid for the wait list */ - struct _MonoThunkFreeList *next; -} MonoThunkFreeList; - -typedef struct _MonoJitCodeHash MonoJitCodeHash; - struct _MonoDomain { /* * keep all the managed objects close to each other for the precise GC @@ -66,18 +58,7 @@ struct _MonoDomain { #define MONO_DOMAIN_LAST_OBJECT empty_string /* Needed by Thread:GetDomainID() */ gint32 domain_id; - /* - * For framework Mono, this is every assembly loaded in this - * domain. For netcore, this is every assembly loaded in every ALC in - * this domain. In netcore, the thread that adds an assembly to its - * MonoAssemblyLoadContext:loaded_assemblies should also add it to this - * list. - */ - GSList *domain_assemblies; char *friendly_name; - - /* Used when accessing 'domain_assemblies' */ - MonoCoopMutex assemblies_lock; }; typedef struct { @@ -91,18 +72,6 @@ typedef struct { AssemblyVersionSet version_sets [5]; } MonoRuntimeInfo; -static inline void -mono_domain_assemblies_lock (MonoDomain *domain) -{ - mono_locks_coop_acquire (&domain->assemblies_lock, DomainAssembliesLock); -} - -static inline void -mono_domain_assemblies_unlock (MonoDomain *domain) -{ - mono_locks_coop_release (&domain->assemblies_lock, DomainAssembliesLock); -} - typedef MonoDomain* (*MonoLoadFunc) (const char *filename, const char *runtime_version); void @@ -123,9 +92,6 @@ mono_domain_unset (void); void mono_domain_set_internal_with_options (MonoDomain *domain, gboolean migrate_exception); -void -mono_jit_code_hash_init (MonoInternalHashTable *jit_code_hash); - MonoAssembly * mono_assembly_load_corlib (MonoImageOpenStatus *status); @@ -142,7 +108,7 @@ gboolean mono_assembly_name_parse (const char *name, MonoAssemblyName *aname); MonoAssembly * -mono_domain_assembly_open_internal (MonoDomain *domain, MonoAssemblyLoadContext *alc, const char *name); +mono_domain_assembly_open_internal (MonoAssemblyLoadContext *alc, const char *name); MonoImage *mono_assembly_open_from_bundle (MonoAssemblyLoadContext *alc, const char *filename, @@ -155,24 +121,12 @@ mono_try_assembly_resolve (MonoAssemblyLoadContext *alc, const char *fname, Mono MonoAssembly * mono_domain_assembly_postload_search (MonoAssemblyLoadContext *alc, MonoAssembly *requesting, MonoAssemblyName *aname, gboolean postload, gpointer user_data, MonoError *error); -MonoJitInfo* mono_jit_info_table_find_internal (MonoDomain *domain, gpointer addr, gboolean try_aot, gboolean allow_trampolines); - -typedef void (*MonoJitInfoFunc) (MonoJitInfo *ji, gpointer user_data); - -void -mono_jit_info_table_foreach_internal (MonoDomain *domain, MonoJitInfoFunc func, gpointer user_data); - -void mono_enable_debug_domain_unload (gboolean enable); - void mono_runtime_init_checked (MonoDomain *domain, MonoThreadStartCB start_cb, MonoThreadAttachCB attach_cb, MonoError *error); gboolean mono_assembly_has_reference_assembly_attribute (MonoAssembly *assembly, MonoError *error); -GPtrArray* -mono_domain_get_assemblies (MonoDomain *domain); - void mono_runtime_register_appctx_properties (int nprops, const char **keys, const char **values); @@ -185,19 +139,6 @@ mono_runtime_install_appctx_properties (void); gboolean mono_domain_set_fast (MonoDomain *domain, gboolean force); -static inline MonoMemoryManager * -mono_domain_memory_manager (MonoDomain *domain) -{ - return (MonoMemoryManager *)mono_alc_get_default ()->memory_manager; -} - -static inline MonoMemoryManager* -mono_mem_manager_get_ambient (void) -{ - // FIXME: All callers should get a MemoryManager from their callers or context - return mono_domain_memory_manager (mono_get_root_domain ()); -} - G_END_DECLS #endif /* __MONO_METADATA_DOMAIN_INTERNALS_H__ */ diff --git a/src/mono/mono/metadata/domain.c b/src/mono/mono/metadata/domain.c index c887af37f1f8f..bee0701de21db 100644 --- a/src/mono/mono/metadata/domain.c +++ b/src/mono/mono/metadata/domain.c @@ -53,6 +53,11 @@ #include "external-only.h" #include "mono/utils/mono-tls-inline.h" +/* + * There is only one domain, but some code uses the domain TLS + * variable to check whenever a thread is attached to the runtime etc., + * so keep this for now. + */ #define GET_APPDOMAIN mono_tls_get_domain #define SET_APPDOMAIN(x) do { \ MonoThreadInfo *info; \ @@ -62,24 +67,12 @@ mono_thread_info_tls_set (info, TLS_KEY_DOMAIN, (x)); \ } while (FALSE) -static guint16 appdomain_list_size = 0; -static guint16 appdomain_next = 0; -static MonoDomain **appdomains_list = NULL; +static MonoDomain **appdomains_list; static MonoImage *exe_image; +static MonoDomain *mono_root_domain; gboolean mono_dont_free_domains; -#define mono_appdomains_lock() mono_coop_mutex_lock (&appdomains_mutex) -#define mono_appdomains_unlock() mono_coop_mutex_unlock (&appdomains_mutex) -static MonoCoopMutex appdomains_mutex; - -static MonoDomain *mono_root_domain = NULL; - -/* some statistics */ -static int max_domain_code_size = 0; -static int max_domain_code_alloc = 0; -static int total_domain_code_alloc = 0; - /* AppConfigInfo: Information about runtime versions supported by an * aplication. */ @@ -114,86 +107,6 @@ get_runtimes_from_exe (const char *exe_file, MonoImage **exe_image); static const MonoRuntimeInfo* get_runtime_by_version (const char *version); -gboolean -mono_string_equal_internal (MonoString *s1, MonoString *s2) -{ - int l1 = mono_string_length_internal (s1); - int l2 = mono_string_length_internal (s2); - - if (s1 == s2) - return TRUE; - if (l1 != l2) - return FALSE; - - return memcmp (mono_string_chars_internal (s1), mono_string_chars_internal (s2), l1 * 2) == 0; -} - -/** - * mono_string_equal: - * \param s1 First string to compare - * \param s2 Second string to compare - * - * Compares two \c MonoString* instances ordinally for equality. - * - * \returns FALSE if the strings differ. - */ -gboolean -mono_string_equal (MonoString *s1, MonoString *s2) -{ - MONO_EXTERNAL_ONLY (gboolean, mono_string_equal_internal (s1, s2)); -} - -guint -mono_string_hash_internal (MonoString *s) -{ - const gunichar2 *p = mono_string_chars_internal (s); - int i, len = mono_string_length_internal (s); - guint h = 0; - - for (i = 0; i < len; i++) { - h = (h << 5) - h + *p; - p++; - } - - return h; -} - -/** - * mono_string_hash: - * \param s the string to hash - * - * Compute the hash for a \c MonoString* - * \returns the hash for the string. - */ -guint -mono_string_hash (MonoString *s) -{ - MONO_EXTERNAL_ONLY (guint, mono_string_hash_internal (s)); -} - -static gboolean -mono_ptrarray_equal (gpointer *s1, gpointer *s2) -{ - int len = GPOINTER_TO_INT (s1 [0]); - if (len != GPOINTER_TO_INT (s2 [0])) - return FALSE; - - return memcmp (s1 + 1, s2 + 1, len * sizeof(gpointer)) == 0; -} - -static guint -mono_ptrarray_hash (gpointer *s) -{ - int i; - int len = GPOINTER_TO_INT (s [0]); - guint hash = 0; - - for (i = 1; i < len; i++) - hash += GPOINTER_TO_UINT (s [i]); - - return hash; -} - //g_malloc on sgen and mono_gc_alloc_fixed on boehm static void* gc_alloc_fixed_non_heap_list (size_t size) @@ -212,115 +125,32 @@ gc_free_fixed_non_heap_list (void *ptr) else mono_gc_free_fixed (ptr); } -/* - * Allocate an id for domain and set domain->domain_id. - * LOCKING: must be called while holding appdomains_mutex. - * We try to assign low numbers to the domain, so it can be used - * as an index in data tables to lookup domain-specific info - * with minimal memory overhead. We also try not to reuse the - * same id too quickly (to help debugging). - */ -static int -domain_id_alloc (MonoDomain *domain) -{ - int id = -1, i; - if (!appdomains_list) { - appdomain_list_size = 2; - appdomains_list = (MonoDomain **)gc_alloc_fixed_non_heap_list (appdomain_list_size * sizeof (void*)); - - } - for (i = appdomain_next; i < appdomain_list_size; ++i) { - if (!appdomains_list [i]) { - id = i; - break; - } - } - if (id == -1) { - for (i = 0; i < appdomain_next; ++i) { - if (!appdomains_list [i]) { - id = i; - break; - } - } - } - if (id == -1) { - MonoDomain **new_list; - int new_size = appdomain_list_size * 2; - if (new_size >= (1 << 16)) - g_assert_not_reached (); - id = appdomain_list_size; - new_list = (MonoDomain **)gc_alloc_fixed_non_heap_list (new_size * sizeof (void*)); - memcpy (new_list, appdomains_list, appdomain_list_size * sizeof (void*)); - gc_free_fixed_non_heap_list (appdomains_list); - appdomains_list = new_list; - appdomain_list_size = new_size; - } - domain->domain_id = id; - appdomains_list [id] = domain; - appdomain_next++; - if (appdomain_next > appdomain_list_size) - appdomain_next = 0; - return id; -} - -static gsize domain_gc_bitmap [sizeof(MonoDomain)/4/32 + 1]; -static MonoGCDescriptor domain_gc_desc = MONO_GC_DESCRIPTOR_NULL; -/** - * mono_domain_create: - * - * Creates a new application domain, the unmanaged representation - * of the actual domain. - * - * Application domains provide an isolation facilty for assemblies. You - * can load assemblies and execute code in them that will not be visible - * to other application domains. This is a runtime-based virtualization - * technology. - * - * It is possible to unload domains, which unloads the assemblies and - * data that was allocated in that domain. - * - * When a domain is created a mempool is allocated for domain-specific - * structures, along a dedicated code manager to hold code that is - * associated with the domain. - * - * \returns New initialized \c MonoDomain, with no configuration or assemblies - * loaded into it. - */ -MonoDomain * -mono_domain_create (void) +static MonoDomain * +create_root_domain (void) { MonoDomain *domain; - - mono_appdomains_lock (); - - if (!domain_gc_desc) { - unsigned int i, bit = 0; - for (i = G_STRUCT_OFFSET (MonoDomain, MONO_DOMAIN_FIRST_OBJECT); i <= G_STRUCT_OFFSET (MonoDomain, MONO_DOMAIN_LAST_OBJECT); i += sizeof (gpointer)) { - bit = i / sizeof (gpointer); - domain_gc_bitmap [bit / 32] |= (gsize) 1 << (bit % 32); - } - domain_gc_desc = mono_gc_make_descr_from_bitmap ((gsize*)domain_gc_bitmap, bit + 1); + gsize domain_gc_bitmap [sizeof(MonoDomain)/4/32 + 1]; + MonoGCDescriptor domain_gc_desc; + + unsigned int i, bit = 0; + memset (domain_gc_bitmap, 0, sizeof (domain_gc_bitmap)); + for (i = G_STRUCT_OFFSET (MonoDomain, MONO_DOMAIN_FIRST_OBJECT); i <= G_STRUCT_OFFSET (MonoDomain, MONO_DOMAIN_LAST_OBJECT); i += sizeof (gpointer)) { + bit = i / sizeof (gpointer); + domain_gc_bitmap [bit / 32] |= (gsize) 1 << (bit % 32); } - mono_appdomains_unlock (); + domain_gc_desc = mono_gc_make_descr_from_bitmap ((gsize*)domain_gc_bitmap, bit + 1); if (!mono_gc_is_moving ()) domain = (MonoDomain *)mono_gc_alloc_fixed (sizeof (MonoDomain), MONO_GC_DESCRIPTOR_NULL, MONO_ROOT_SOURCE_DOMAIN, NULL, "Domain Structure"); else domain = (MonoDomain *)mono_gc_alloc_fixed (sizeof (MonoDomain), domain_gc_desc, MONO_ROOT_SOURCE_DOMAIN, NULL, "Domain Structure"); - domain->domain = NULL; - domain->friendly_name = NULL; - MONO_PROFILER_RAISE (domain_loading, (domain)); - domain->domain_assemblies = NULL; - - mono_coop_mutex_init_recursive (&domain->assemblies_lock); - - mono_appdomains_lock (); - domain_id_alloc (domain); - mono_appdomains_unlock (); + // FIXME: why is this needed ? + appdomains_list = (MonoDomain **)gc_alloc_fixed_non_heap_list (sizeof (void*)); + appdomains_list [0] = domain; #ifndef DISABLE_PERFCOUNTERS mono_atomic_inc_i32 (&mono_perfcounters->loader_appdomains); @@ -373,17 +203,11 @@ mono_init_internal (const char *filename, const char *exe_filename, const char * #endif mono_counters_init (); - mono_counters_register ("Max native code in a domain", MONO_COUNTER_INT|MONO_COUNTER_JIT, &max_domain_code_size); - mono_counters_register ("Max code space allocated in a domain", MONO_COUNTER_INT|MONO_COUNTER_JIT, &max_domain_code_alloc); - mono_counters_register ("Total code space allocated", MONO_COUNTER_INT|MONO_COUNTER_JIT, &total_domain_code_alloc); - mono_counters_register ("Max HashTable Chain Length", MONO_COUNTER_INT|MONO_COUNTER_METADATA, &mono_g_hash_table_max_chain_length); mono_gc_base_init (); mono_thread_info_attach (); - mono_coop_mutex_init_recursive (&appdomains_mutex); - mono_metadata_init (); mono_images_init (); mono_assemblies_init (); @@ -393,7 +217,7 @@ mono_init_internal (const char *filename, const char *exe_filename, const char * mono_runtime_init_tls (); mono_icall_init (); - domain = mono_domain_create (); + domain = create_root_domain (); mono_root_domain = domain; mono_alcs_init (); @@ -416,7 +240,7 @@ mono_init_internal (const char *filename, const char *exe_filename, const char * runtimes = get_runtimes_from_exe (exe_filename, &exe_image); #ifdef HOST_WIN32 if (!exe_image) { - exe_image = mono_assembly_open_from_bundle (mono_alc_get_default (domain), exe_filename, NULL, NULL); + exe_image = mono_assembly_open_from_bundle (mono_alc_get_default (), exe_filename, NULL, NULL); if (!exe_image) exe_image = mono_image_open (exe_filename, NULL); } @@ -723,6 +547,15 @@ mono_domain_unset (void) SET_APPDOMAIN (NULL); } +gboolean +mono_domain_set_fast (MonoDomain *domain, gboolean force) +{ + MONO_REQ_GC_UNSAFE_MODE; + + mono_domain_set_internal_with_options (domain, TRUE); + return TRUE; +} + void mono_domain_set_internal_with_options (MonoDomain *domain, gboolean migrate_exception) { @@ -745,85 +578,17 @@ mono_domain_set_internal_with_options (MonoDomain *domain, gboolean migrate_exce } } -/** - * mono_domain_foreach: - * \param func function to invoke with the domain data - * \param user_data user-defined pointer that is passed to the supplied \p func fo reach domain - * - * Use this method to safely iterate over all the loaded application - * domains in the current runtime. The provided \p func is invoked with a - * pointer to the \c MonoDomain and is given the value of the \p user_data - * parameter which can be used to pass state to your called routine. - */ -void -mono_domain_foreach (MonoDomainFunc func, gpointer user_data) -{ - MONO_ENTER_GC_UNSAFE; - int i, size; - MonoDomain **copy; - - /* - * Create a copy of the data to avoid calling the user callback - * inside the lock because that could lead to deadlocks. - * We can do this because this function is not perf. critical. - */ - mono_appdomains_lock (); - size = appdomain_list_size; - copy = (MonoDomain **)gc_alloc_fixed_non_heap_list (appdomain_list_size * sizeof (void*)); - memcpy (copy, appdomains_list, appdomain_list_size * sizeof (void*)); - mono_appdomains_unlock (); - - for (i = 0; i < size; ++i) { - if (copy [i]) - func (copy [i], user_data); - } - - gc_free_fixed_non_heap_list (copy); - MONO_EXIT_GC_UNSAFE; -} - -void -mono_domain_ensure_entry_assembly (MonoDomain *domain, MonoAssembly *assembly) -{ - mono_runtime_ensure_entry_assembly (assembly); -} - -/** - * mono_domain_assembly_open: - * \param domain the application domain - * \param name file name of the assembly - */ -MonoAssembly * -mono_domain_assembly_open (MonoDomain *domain, const char *name) -{ - MonoAssembly *result; - MONO_ENTER_GC_UNSAFE; - result = mono_domain_assembly_open_internal (domain, mono_alc_get_default (), name); - MONO_EXIT_GC_UNSAFE; - return result; -} - -// Uses the domain on legacy mono and the ALC on current // Intended only for loading the main assembly MonoAssembly * -mono_domain_assembly_open_internal (MonoDomain *domain, MonoAssemblyLoadContext *alc, const char *name) +mono_domain_assembly_open_internal (MonoAssemblyLoadContext *alc, const char *name) { - MonoDomain *current; MonoAssembly *ass; MONO_REQ_GC_UNSAFE_MODE; MonoAssemblyOpenRequest req; mono_assembly_request_prepare_open (&req, MONO_ASMCTX_DEFAULT, alc); - if (domain != mono_domain_get ()) { - current = mono_domain_get (); - - mono_domain_set_fast (domain, FALSE); - ass = mono_assembly_request_open (name, &req, NULL); - mono_domain_set_fast (current, FALSE); - } else { - ass = mono_assembly_request_open (name, &req, NULL); - } + ass = mono_assembly_request_open (name, &req, NULL); // On netcore, this is necessary because we check the AppContext.BaseDirectory property as part of the assembly lookup algorithm // AppContext.BaseDirectory can sometimes fall back to checking the location of the entry_assembly, which should be non-null @@ -832,118 +597,6 @@ mono_domain_assembly_open_internal (MonoDomain *domain, MonoAssemblyLoadContext return ass; } -/** - * mono_domain_free: - * \param domain the domain to release - * \param force if TRUE, it allows the root domain to be released (used at shutdown only). - * - * This releases the resources associated with the specific domain. - * This is a low-level function that is invoked by the AppDomain infrastructure - * when necessary. - * - * In theory, this is dead code on netcore and thus does not need to be ALC-aware. - */ -void -mono_domain_free (MonoDomain *domain, gboolean force) -{ - g_assert_not_reached (); -} - -/** - * mono_domain_get_by_id: - * \param domainid the ID - * \returns the domain for a specific domain id. - */ -MonoDomain * -mono_domain_get_by_id (gint32 domainid) -{ - MonoDomain * domain; - - MONO_ENTER_GC_UNSAFE; - mono_appdomains_lock (); - if (domainid < appdomain_list_size) - domain = appdomains_list [domainid]; - else - domain = NULL; - mono_appdomains_unlock (); - MONO_EXIT_GC_UNSAFE; - return domain; -} - -/** - * mono_domain_get_id: - * - * A domain ID is guaranteed to be unique for as long as the domain - * using it is alive. It may be reused later once the domain has been - * unloaded. - * - * \returns The unique ID for \p domain. - */ -gint32 -mono_domain_get_id (MonoDomain *domain) -{ - return domain->domain_id; -} - -/** - * mono_domain_get_friendly_name: - * - * The returned string's lifetime is the same as \p domain's. Consider - * copying it if you need to store it somewhere. - * - * \returns The friendly name of \p domain. Can be NULL if not yet set. - */ -const char * -mono_domain_get_friendly_name (MonoDomain *domain) -{ - return domain->friendly_name; -} - -/** - * mono_context_set: - */ -void -mono_context_set (MonoAppContext * new_context) -{ -} - -/** - * mono_context_get: - * - * Returns: the current Mono Application Context. - */ -MonoAppContext * -mono_context_get (void) -{ - return NULL; -} - -/** - * mono_context_get_id: - * \param context the context to operate on. - * - * Context IDs are guaranteed to be unique for the duration of a Mono - * process; they are never reused. - * - * \returns The unique ID for \p context. - */ -gint32 -mono_context_get_id (MonoAppContext *context) -{ - return context->context_id; -} - -/** - * mono_context_get_domain_id: - * \param context the context to operate on. - * \returns The ID of the domain that \p context was created in. - */ -gint32 -mono_context_get_domain_id (MonoAppContext *context) -{ - return context->domain_id; -} - /** * mono_get_corlib: * Use this function to get the \c MonoImage* for the \c mscorlib.dll assembly @@ -1243,7 +896,6 @@ get_runtimes_from_exe (const char *file, MonoImage **out_image) return runtimes; } - /** * mono_get_runtime_info: * @@ -1254,20 +906,3 @@ mono_get_runtime_info (void) { return current_runtime; } - -GPtrArray* -mono_domain_get_assemblies (MonoDomain *domain) -{ - GSList *tmp; - GPtrArray *assemblies; - MonoAssembly *ass; - - assemblies = g_ptr_array_new (); - mono_domain_assemblies_lock (domain); - for (tmp = domain->domain_assemblies; tmp; tmp = tmp->next) { - ass = (MonoAssembly *)tmp->data; - g_ptr_array_add (assemblies, ass); - } - mono_domain_assemblies_unlock (domain); - return assemblies; -} diff --git a/src/mono/mono/metadata/external-only.c b/src/mono/mono/metadata/external-only.c index 4acef45a221f9..01a9e4ad15fb9 100644 --- a/src/mono/mono/metadata/external-only.c +++ b/src/mono/mono/metadata/external-only.c @@ -377,3 +377,290 @@ void mono_register_config_for_assembly (const char* assembly_name, const char* config_xml) { } + +/** + * mono_domain_free: + * \param domain the domain to release + * \param force if TRUE, it allows the root domain to be released (used at shutdown only). + * + * This releases the resources associated with the specific domain. + * This is a low-level function that is invoked by the AppDomain infrastructure + * when necessary. + * + * In theory, this is dead code on netcore and thus does not need to be ALC-aware. + */ +void +mono_domain_free (MonoDomain *domain, gboolean force) +{ + g_assert_not_reached (); +} + +/** + * mono_domain_get_id: + * + * A domain ID is guaranteed to be unique for as long as the domain + * using it is alive. It may be reused later once the domain has been + * unloaded. + * + * \returns The unique ID for \p domain. + */ +gint32 +mono_domain_get_id (MonoDomain *domain) +{ + return domain->domain_id; +} + +/** + * mono_domain_get_friendly_name: + * + * The returned string's lifetime is the same as \p domain's. Consider + * copying it if you need to store it somewhere. + * + * \returns The friendly name of \p domain. Can be NULL if not yet set. + */ +const char * +mono_domain_get_friendly_name (MonoDomain *domain) +{ + return domain->friendly_name; +} + +/** + * mono_domain_is_unloading: + */ +gboolean +mono_domain_is_unloading (MonoDomain *domain) +{ + return FALSE; +} + +/** + * mono_domain_from_appdomain: + */ +MonoDomain * +mono_domain_from_appdomain (MonoAppDomain *appdomain_raw) +{ + return mono_get_root_domain (); +} + +/** + * mono_context_set: + */ +void +mono_context_set (MonoAppContext * new_context) +{ +} + +/** + * mono_context_get: + * + * Returns: the current Mono Application Context. + */ +MonoAppContext * +mono_context_get (void) +{ + return NULL; +} + +/** + * mono_context_get_id: + * \param context the context to operate on. + * + * Context IDs are guaranteed to be unique for the duration of a Mono + * process; they are never reused. + * + * \returns The unique ID for \p context. + */ +gint32 +mono_context_get_id (MonoAppContext *context) +{ + return context->context_id; +} + +/** + * mono_context_get_domain_id: + * \param context the context to operate on. + * \returns The ID of the domain that \p context was created in. + */ +gint32 +mono_context_get_domain_id (MonoAppContext *context) +{ + return context->domain_id; +} + +/** + * mono_string_equal: + * \param s1 First string to compare + * \param s2 Second string to compare + * + * Compares two \c MonoString* instances ordinally for equality. + * + * \returns FALSE if the strings differ. + */ +gboolean +mono_string_equal (MonoString *s1, MonoString *s2) +{ + MONO_EXTERNAL_ONLY (gboolean, mono_string_equal_internal (s1, s2)); +} + +/** + * mono_string_hash: + * \param s the string to hash + * + * Compute the hash for a \c MonoString* + * \returns the hash for the string. + */ +guint +mono_string_hash (MonoString *s) +{ + MONO_EXTERNAL_ONLY (guint, mono_string_hash_internal (s)); +} + +/** + * mono_domain_create: + * + * Creates a new application domain, the unmanaged representation + * of the actual domain. + * + * Application domains provide an isolation facilty for assemblies. You + * can load assemblies and execute code in them that will not be visible + * to other application domains. This is a runtime-based virtualization + * technology. + * + * It is possible to unload domains, which unloads the assemblies and + * data that was allocated in that domain. + * + * When a domain is created a mempool is allocated for domain-specific + * structures, along a dedicated code manager to hold code that is + * associated with the domain. + * + * \returns New initialized \c MonoDomain, with no configuration or assemblies + * loaded into it. + */ +MonoDomain * +mono_domain_create (void) +{ + g_assert_not_reached (); +} + +/** + * mono_domain_get_by_id: + * \param domainid the ID + * \returns the domain for a specific domain id. + */ +MonoDomain * +mono_domain_get_by_id (gint32 domainid) +{ + MonoDomain * domain = mono_get_root_domain (); + + if (domain->domain_id == domainid) + return domain; + else + return NULL; +} + +/** + * mono_domain_assembly_open: + * \param domain the application domain + * \param name file name of the assembly + */ +MonoAssembly * +mono_domain_assembly_open (MonoDomain *domain, const char *name) +{ + MonoAssembly *result; + MONO_ENTER_GC_UNSAFE; + result = mono_domain_assembly_open_internal (mono_alc_get_default (), name); + MONO_EXIT_GC_UNSAFE; + return result; +} + +void +mono_domain_ensure_entry_assembly (MonoDomain *domain, MonoAssembly *assembly) +{ + mono_runtime_ensure_entry_assembly (assembly); +} + +/** + * mono_domain_foreach: + * \param func function to invoke with the domain data + * \param user_data user-defined pointer that is passed to the supplied \p func fo reach domain + * + * Use this method to safely iterate over all the loaded application + * domains in the current runtime. The provided \p func is invoked with a + * pointer to the \c MonoDomain and is given the value of the \p user_data + * parameter which can be used to pass state to your called routine. + */ +void +mono_domain_foreach (MonoDomainFunc func, gpointer user_data) +{ + MONO_ENTER_GC_UNSAFE; + + func (mono_get_root_domain (), user_data); + + MONO_EXIT_GC_UNSAFE; +} + +/** + * mono_context_init: + * \param domain The domain where the \c System.Runtime.Remoting.Context.Context is initialized + * Initializes the \p domain's default \c System.Runtime.Remoting 's Context. + */ +void +mono_context_init (MonoDomain *domain) +{ +} + +/** + * mono_domain_set_config: + * \param domain \c MonoDomain initialized with the appdomain we want to change + * \param base_dir new base directory for the appdomain + * \param config_file_name path to the new configuration for the app domain + * + * Used to set the system configuration for an appdomain + * + * Without using this, embedded builds will get 'System.Configuration.ConfigurationErrorsException: + * Error Initializing the configuration system. ---> System.ArgumentException: + * The 'ExeConfigFilename' argument cannot be null.' for some managed calls. + */ +void +mono_domain_set_config (MonoDomain *domain, const char *base_dir, const char *config_file_name) +{ + g_assert_not_reached (); +} + +/** + * mono_domain_try_type_resolve: + * \param domain application domain in which to resolve the type + * \param name the name of the type to resolve or NULL. + * \param typebuilder A \c System.Reflection.Emit.TypeBuilder, used if name is NULL. + * + * This routine invokes the internal \c System.AppDomain.DoTypeResolve and returns + * the assembly that matches name, or ((TypeBuilder)typebuilder).FullName. + * + * \returns A \c MonoReflectionAssembly or NULL if not found + */ +MonoReflectionAssembly * +mono_domain_try_type_resolve (MonoDomain *domain, char *name, MonoObject *typebuilder_raw) +{ + HANDLE_FUNCTION_ENTER (); + + g_assert (domain); + g_assert (name || typebuilder_raw); + + ERROR_DECL (error); + + MonoReflectionAssemblyHandle ret = NULL_HANDLE_INIT; + + // This will not work correctly on netcore + if (name) { + MonoStringHandle name_handle = mono_string_new_handle (name, error); + goto_if_nok (error, exit); + ret = mono_domain_try_type_resolve_name (NULL, name_handle, error); + } else { + // TODO: make this work on netcore when working on SRE.TypeBuilder + g_assert_not_reached (); + } + +exit: + mono_error_cleanup (error); + HANDLE_FUNCTION_RETURN_OBJ (ret); +} diff --git a/src/mono/mono/metadata/icall-eventpipe.c b/src/mono/mono/metadata/icall-eventpipe.c index 75ab4d55855d6..7c1f89eb396e0 100644 --- a/src/mono/mono/metadata/icall-eventpipe.c +++ b/src/mono/mono/metadata/icall-eventpipe.c @@ -523,7 +523,7 @@ eventpipe_execute_rundown ( g_free (events_data.buffer); // Iterate all assemblies in domain. - GPtrArray *assemblies = mono_domain_get_assemblies (root_domain); + GPtrArray *assemblies = mono_alc_get_all_loaded_assemblies (); if (assemblies) { for (int i = 0; i < assemblies->len; ++i) { MonoAssembly *assembly = (MonoAssembly *)g_ptr_array_index (assemblies, i); diff --git a/src/mono/mono/metadata/jit-info.h b/src/mono/mono/metadata/jit-info.h index 2f54f453882ae..f6d9f42090add 100644 --- a/src/mono/mono/metadata/jit-info.h +++ b/src/mono/mono/metadata/jit-info.h @@ -285,6 +285,16 @@ mono_jit_info_get_unwind_info (MonoJitInfo *ji); typedef MonoJitInfo *(*MonoJitInfoFindInAot) (MonoDomain *domain, MonoImage *image, gpointer addr); void mono_install_jit_info_find_in_aot (MonoJitInfoFindInAot func); +MonoJitInfo* mono_jit_info_table_find_internal (MonoDomain *domain, gpointer addr, gboolean try_aot, gboolean allow_trampolines); + +typedef void (*MonoJitInfoFunc) (MonoJitInfo *ji, gpointer user_data); + +void +mono_jit_info_table_foreach_internal (MonoDomain *domain, MonoJitInfoFunc func, gpointer user_data); + +void +mono_jit_code_hash_init (MonoInternalHashTable *jit_code_hash); + G_END_DECLS #endif /* __MONO_METADATA_JIT_INFO_H__ */ diff --git a/src/mono/mono/metadata/loader-internals.h b/src/mono/mono/metadata/loader-internals.h index e964c9bc09b69..743e808eb729f 100644 --- a/src/mono/mono/metadata/loader-internals.h +++ b/src/mono/mono/metadata/loader-internals.h @@ -224,6 +224,15 @@ mono_alc_from_gchandle (MonoGCHandle alc_gchandle); MonoLoadedImages * mono_alc_get_loaded_images (MonoAssemblyLoadContext *alc); +void +mono_alc_add_assembly (MonoAssemblyLoadContext *alc, MonoAssembly *ass); + +MonoAssembly* +mono_alc_find_assembly (MonoAssemblyLoadContext *alc, MonoAssemblyName *aname); + +GPtrArray* +mono_alc_get_all_loaded_assemblies (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/metadata/object.c b/src/mono/mono/metadata/object.c index 16343a14aff54..ac5334f8b24a0 100644 --- a/src/mono/mono/metadata/object.c +++ b/src/mono/mono/metadata/object.c @@ -5824,6 +5824,35 @@ ves_icall_array_new_specific (MonoVTable *vtable, uintptr_t n) return arr; } +gboolean +mono_string_equal_internal (MonoString *s1, MonoString *s2) +{ + int l1 = mono_string_length_internal (s1); + int l2 = mono_string_length_internal (s2); + + if (s1 == s2) + return TRUE; + if (l1 != l2) + return FALSE; + + return memcmp (mono_string_chars_internal (s1), mono_string_chars_internal (s2), l1 * 2) == 0; +} + +guint +mono_string_hash_internal (MonoString *s) +{ + const gunichar2 *p = mono_string_chars_internal (s); + int i, len = mono_string_length_internal (s); + guint h = 0; + + for (i = 0; i < len; i++) { + h = (h << 5) - h + *p; + p++; + } + + return h; +} + /** * mono_string_empty_wrapper: * diff --git a/src/mono/mono/metadata/reflection-internals.h b/src/mono/mono/metadata/reflection-internals.h index 7437f5448aec6..9ea2c1cdc9816 100644 --- a/src/mono/mono/metadata/reflection-internals.h +++ b/src/mono/mono/metadata/reflection-internals.h @@ -20,7 +20,7 @@ TYPED_HANDLE_DECL (MonoReflectionAssembly) TYPED_HANDLE_DECL (MonoReflectionTypeBuilder) MonoReflectionAssemblyHandle -mono_domain_try_type_resolve_name (MonoDomain *domain, MonoAssembly *assembly, MonoStringHandle name, MonoError *error); +mono_domain_try_type_resolve_name (MonoAssembly *assembly, MonoStringHandle name, MonoError *error); MonoReflectionTypeBuilderHandle mono_class_get_ref_info (MonoClass *klass); diff --git a/src/mono/mono/metadata/reflection.c b/src/mono/mono/metadata/reflection.c index e680f9905c406..78867108492ff 100644 --- a/src/mono/mono/metadata/reflection.c +++ b/src/mono/mono/metadata/reflection.c @@ -2256,7 +2256,7 @@ mono_reflection_get_type_with_rootimage (MonoAssemblyLoadContext *alc, MonoImage name_handle = mono_string_new_handle (fullName->str, error); goto_if_nok (error, return_null); - reflection_assembly = mono_domain_try_type_resolve_name (domain, image->assembly, name_handle, error); + reflection_assembly = mono_domain_try_type_resolve_name (image->assembly, name_handle, error); goto_if_nok (error, return_null); if (MONO_HANDLE_BOOL (reflection_assembly)) { diff --git a/src/mono/mono/metadata/runtime.c b/src/mono/mono/metadata/runtime.c index da8c553e677fb..a71933874505e 100644 --- a/src/mono/mono/metadata/runtime.c +++ b/src/mono/mono/metadata/runtime.c @@ -52,8 +52,9 @@ mono_runtime_is_shutting_down (void) } static void -fire_process_exit_event (MonoDomain *domain, gpointer user_data) +mono_runtime_fire_process_exit_event (void) { +#ifndef MONO_CROSS_COMPILE ERROR_DECL (error); MonoObject *exc; @@ -67,13 +68,6 @@ fire_process_exit_event (MonoDomain *domain, gpointer user_data) g_assert (procexit_method); mono_runtime_try_invoke (procexit_method, NULL, NULL, &exc, error); -} - -static void -mono_runtime_fire_process_exit_event (void) -{ -#ifndef MONO_CROSS_COMPILE - mono_domain_foreach (fire_process_exit_event, NULL); #endif } diff --git a/src/mono/mono/metadata/sre.c b/src/mono/mono/metadata/sre.c index aa7c53a4d6972..73d8cfd286ae6 100644 --- a/src/mono/mono/metadata/sre.c +++ b/src/mono/mono/metadata/sre.c @@ -1268,13 +1268,7 @@ mono_reflection_dynimage_basic_init (MonoReflectionAssemblyBuilder *assemblyb, M assembly->assembly.aname.name = image->image.name; assembly->assembly.image = &image->image; - mono_domain_assemblies_lock (domain); - domain->domain_assemblies = g_slist_append (domain->domain_assemblies, assembly); - // TODO: potentially relax the locking here? - mono_alc_assemblies_lock (alc); - alc->loaded_assemblies = g_slist_append (alc->loaded_assemblies, assembly); - mono_alc_assemblies_unlock (alc); - mono_domain_assemblies_unlock (domain); + mono_alc_add_assembly (alc, (MonoAssembly*)assembly); register_assembly (mono_object_domain (assemblyb), &assemblyb->assembly, &assembly->assembly); diff --git a/src/mono/mono/mini/aot-compiler.c b/src/mono/mono/mini/aot-compiler.c index f6c8df1ab9018..3ca94121b6c51 100644 --- a/src/mono/mono/mini/aot-compiler.c +++ b/src/mono/mono/mini/aot-compiler.c @@ -12825,7 +12825,7 @@ resolve_profile_data (MonoAotCompile *acfg, ProfileData *data, MonoAssembly* cur return; /* Images */ - GPtrArray *assemblies = mono_domain_get_assemblies (mono_get_root_domain ()); + GPtrArray *assemblies = mono_alc_get_all_loaded_assemblies (); g_hash_table_iter_init (&iter, data->images); while (g_hash_table_iter_next (&iter, &key, &value)) { ImageProfileData *idata = (ImageProfileData*)value; diff --git a/src/mono/mono/mini/debugger-agent.c b/src/mono/mono/mini/debugger-agent.c index db91f0ae8193f..24d9a8db52d12 100644 --- a/src/mono/mono/mini/debugger-agent.c +++ b/src/mono/mono/mini/debugger-agent.c @@ -3893,19 +3893,16 @@ send_types_for_domain (MonoDomain *domain, void *user_data) static void send_assemblies_for_domain (MonoDomain *domain, void *user_data) { - GSList *tmp; MonoDomain* old_domain; old_domain = mono_domain_get (); mono_domain_set_fast (domain, TRUE); - mono_domain_assemblies_lock (domain); - for (tmp = domain->domain_assemblies; tmp; tmp = tmp->next) { - MonoAssembly* ass = (MonoAssembly *)tmp->data; - emit_assembly_load (ass, NULL); - } - mono_domain_assemblies_unlock (domain); + GPtrArray *assemblies = mono_alc_get_all_loaded_assemblies (); + for (int i = 0; i < assemblies->len; ++i) + emit_assembly_load ((MonoAssembly*)g_ptr_array_index (assemblies, i), NULL); + g_ptr_array_free (assemblies, TRUE); mono_domain_set_fast (old_domain, TRUE); } @@ -6312,15 +6309,14 @@ get_types (gpointer key, gpointer value, gpointer user_data) MonoAssembly *ass; gboolean type_resolve; MonoType *t; - GSList *tmp; MonoDomain *domain = (MonoDomain*)key; MonoAssemblyLoadContext *alc = mono_alc_get_default (); GetTypesArgs *ud = (GetTypesArgs*)user_data; - mono_domain_assemblies_lock (domain); - for (tmp = domain->domain_assemblies; tmp; tmp = tmp->next) { - ass = (MonoAssembly *)tmp->data; + GPtrArray *assemblies = mono_alc_get_all_loaded_assemblies (); + for (int i = 0; i < assemblies->len; ++i) { + ass = (MonoAssembly*)g_ptr_array_index (assemblies, i); if (ass->image) { ERROR_DECL (probe_type_error); @@ -6333,7 +6329,7 @@ get_types (gpointer key, gpointer value, gpointer user_data) } } } - mono_domain_assemblies_unlock (domain); + g_ptr_array_free (assemblies, TRUE); } typedef struct { @@ -7099,7 +7095,7 @@ event_commands (int command, guint8 *p, guint8 *end, Buffer *buf) break; case EVENT_KIND_ASSEMBLY_LOAD: /* Emit load events for currently loaded assemblies */ - mono_domain_foreach (send_assemblies_for_domain, NULL); + send_assemblies_for_domain (mono_get_root_domain (), NULL); break; case EVENT_KIND_THREAD_START: /* Emit start events for currently started threads */ @@ -7107,7 +7103,7 @@ event_commands (int command, guint8 *p, guint8 *end, Buffer *buf) break; case EVENT_KIND_TYPE_LOAD: /* Emit type load events for currently loaded types */ - mono_domain_foreach (send_types_for_domain, NULL); + send_types_for_domain (mono_get_root_domain (), NULL); break; default: break; @@ -7174,24 +7170,17 @@ domain_commands (int command, guint8 *p, guint8 *end, Buffer *buf) break; } case CMD_APPDOMAIN_GET_ASSEMBLIES: { - GSList *tmp; - MonoAssembly *ass; - int count; - domain = decode_domainid (p, &p, end, NULL, &err); if (err != ERR_NONE) return err; - mono_domain_assemblies_lock (domain); - count = 0; - for (tmp = domain->domain_assemblies; tmp; tmp = tmp->next) { - count ++; - } - buffer_add_int (buf, count); - for (tmp = domain->domain_assemblies; tmp; tmp = tmp->next) { - ass = (MonoAssembly *)tmp->data; + + GPtrArray *assemblies = mono_alc_get_all_loaded_assemblies (); + buffer_add_int (buf, assemblies->len); + for (int i = 0; i < assemblies->len; ++i) { + MonoAssembly *ass = (MonoAssembly*)g_ptr_array_index (assemblies, i); buffer_add_assemblyid (buf, domain, ass); } - mono_domain_assemblies_unlock (domain); + g_ptr_array_free (assemblies, TRUE); break; } case CMD_APPDOMAIN_GET_ENTRY_ASSEMBLY: { diff --git a/src/mono/mono/mini/driver.c b/src/mono/mono/mini/driver.c index c0e3e99d7dabe..b5a9e823235f9 100644 --- a/src/mono/mono/mini/driver.c +++ b/src/mono/mono/mini/driver.c @@ -1414,7 +1414,7 @@ static void main_thread_handler (gpointer user_data) /* Treat the other arguments as assemblies to compile too */ for (i = 0; i < main_args->argc; ++i) { - assembly = mono_domain_assembly_open_internal (main_args->domain, mono_alc_get_default (), main_args->argv [i]); + assembly = mono_domain_assembly_open_internal (mono_alc_get_default (), main_args->argv [i]); if (!assembly) { fprintf (stderr, "Can not open image %s\n", main_args->argv [i]); exit (1); @@ -1444,7 +1444,7 @@ static void main_thread_handler (gpointer user_data) } } } else { - assembly = mono_domain_assembly_open_internal (main_args->domain, mono_alc_get_default (), main_args->file); + assembly = mono_domain_assembly_open_internal (mono_alc_get_default (), main_args->file); if (!assembly){ fprintf (stderr, "Can not open image %s\n", main_args->file); exit (1); diff --git a/src/mono/mono/mini/mini-wasm-debugger.c b/src/mono/mono/mini/mini-wasm-debugger.c index 1f2a52991f56f..2db5f7a5e0e6d 100644 --- a/src/mono/mono/mini/mini-wasm-debugger.c +++ b/src/mono/mono/mini/mini-wasm-debugger.c @@ -1632,14 +1632,12 @@ mono_wasm_set_is_debugger_attached (gboolean is_attached) mono_set_is_debugger_attached (is_attached); if (is_attached && has_pending_lazy_loaded_assemblies) { - MonoDomain* domain = mono_domain_get (); - mono_domain_assemblies_lock (domain); - GSList *tmp; - for (tmp = domain->domain_assemblies; tmp; tmp = tmp->next) { - MonoAssembly *ass = (MonoAssembly *)tmp->data; + GPtrArray *assemblies = mono_alc_get_all_loaded_assemblies (); + for (int i = 0; i < assemblies->len; ++i) { + MonoAssembly *ass = (MonoAssembly*)g_ptr_array_index (assemblies, i); assembly_loaded (NULL, ass); } - mono_domain_assemblies_unlock (domain); + g_ptr_array_free (assemblies, TRUE); has_pending_lazy_loaded_assemblies = FALSE; } } diff --git a/src/mono/mono/mini/mini.c b/src/mono/mono/mini/mini.c index 1937846018769..29bb69c0ba627 100644 --- a/src/mono/mono/mini/mini.c +++ b/src/mono/mono/mini/mini.c @@ -2056,7 +2056,7 @@ mono_codegen (MonoCompile *cfg) * overlapping address ranges, so allocate all code from the code manager * of the root domain. (#666152). */ - code_mem_manager = mono_domain_memory_manager (mono_get_root_domain ()); + code_mem_manager = get_default_mem_manager (); else code_mem_manager = cfg->mem_manager;