Skip to content

Commit 12edbc0

Browse files
authored
[mono] More domain cleanups (#50479)
* [mono] More domain cleanups. * [mono] Move the storage of the loaded assemblies list to assembly-load-context.c. Add a mono_alc_get_all_loaded_assemblies () helper function to return a array of all the loaded assemblies. Use this instead of accessing domain->loaded_assemblies directly. * [mono] Move externally called domain related API functions to external-only.c. * [mono] Simplify the domain creation code since there is only one domain. * Remove domain argument from mono_domain_assembly_open_internal (). * [mono] Make mono_domain_foreach () external only. * Fix the build. * [mono] Remove more unused 'domain' arguments. Move functions from appdomain.c to more assembly-load-context.c/ extern-only.c.
1 parent 856c879 commit 12edbc0

20 files changed

+637
-878
lines changed

src/mono/mono/metadata/appdomain.c

Lines changed: 4 additions & 347 deletions
Large diffs are not rendered by default.

src/mono/mono/metadata/appdomain.h

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -73,13 +73,13 @@ mono_domain_set_config (MonoDomain *domain, const char *base_dir, const char *co
7373
MONO_API MonoDomain *
7474
mono_domain_get (void);
7575

76-
MONO_API MonoDomain *
76+
MONO_API MONO_RT_EXTERNAL_ONLY MonoDomain *
7777
mono_domain_get_by_id (int32_t domainid);
7878

79-
MONO_API int32_t
79+
MONO_API MONO_RT_EXTERNAL_ONLY int32_t
8080
mono_domain_get_id (MonoDomain *domain);
8181

82-
MONO_API const char *
82+
MONO_API MONO_RT_EXTERNAL_ONLY const char *
8383
mono_domain_get_friendly_name (MonoDomain *domain);
8484

8585
MONO_API MONO_RT_EXTERNAL_ONLY mono_bool
@@ -91,16 +91,16 @@ mono_domain_set_internal (MonoDomain *domain);
9191
MONO_API MONO_RT_EXTERNAL_ONLY void
9292
mono_domain_unload (MonoDomain *domain);
9393

94-
MONO_API void
94+
MONO_API MONO_RT_EXTERNAL_ONLY void
9595
mono_domain_try_unload (MonoDomain *domain, MonoObject **exc);
9696

97-
MONO_API mono_bool
97+
MONO_API MONO_RT_EXTERNAL_ONLY mono_bool
9898
mono_domain_is_unloading (MonoDomain *domain);
9999

100100
MONO_API MONO_RT_EXTERNAL_ONLY MonoDomain *
101101
mono_domain_from_appdomain (MonoAppDomain *appdomain);
102102

103-
MONO_API void
103+
MONO_API MONO_RT_EXTERNAL_ONLY void
104104
mono_domain_foreach (MonoDomainFunc func, void* user_data);
105105

106106
MONO_API MONO_RT_EXTERNAL_ONLY MonoAssembly *
@@ -112,7 +112,7 @@ mono_domain_ensure_entry_assembly (MonoDomain *domain, MonoAssembly *assembly);
112112
MONO_API MONO_RT_EXTERNAL_ONLY mono_bool
113113
mono_domain_finalize (MonoDomain *domain, uint32_t timeout);
114114

115-
MONO_API void
115+
MONO_API MONO_RT_EXTERNAL_ONLY void
116116
mono_domain_free (MonoDomain *domain, mono_bool force);
117117

118118
MONO_API mono_bool
@@ -130,13 +130,13 @@ mono_context_init (MonoDomain *domain);
130130
MONO_API MONO_RT_EXTERNAL_ONLY void
131131
mono_context_set (MonoAppContext *new_context);
132132

133-
MONO_API MonoAppContext *
133+
MONO_API MONO_RT_EXTERNAL_ONLY MonoAppContext *
134134
mono_context_get (void);
135135

136-
MONO_API int32_t
136+
MONO_API MONO_RT_EXTERNAL_ONLY int32_t
137137
mono_context_get_id (MonoAppContext *context);
138138

139-
MONO_API int32_t
139+
MONO_API MONO_RT_EXTERNAL_ONLY int32_t
140140
mono_context_get_domain_id (MonoAppContext *context);
141141

142142
MONO_API MonoJitInfo *

src/mono/mono/metadata/assembly-load-context.c

Lines changed: 215 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,25 @@
22
#include "mono/utils/mono-compiler.h"
33

44
#include "mono/metadata/assembly.h"
5+
#include "mono/metadata/assembly-internals.h"
56
#include "mono/metadata/domain-internals.h"
67
#include "mono/metadata/exception-internals.h"
78
#include "mono/metadata/icall-decl.h"
89
#include "mono/metadata/loader-internals.h"
910
#include "mono/metadata/loaded-images-internals.h"
1011
#include "mono/metadata/mono-private-unstable.h"
12+
#include "mono/metadata/mono-debug.h"
1113
#include "mono/utils/mono-error-internals.h"
1214
#include "mono/utils/mono-logger-internals.h"
1315

1416
GENERATE_GET_CLASS_WITH_CACHE (assembly_load_context, "System.Runtime.Loader", "AssemblyLoadContext");
17+
static GENERATE_GET_CLASS_WITH_CACHE (assembly, "System.Reflection", "Assembly");
1518

1619
static GSList *alcs;
1720
static MonoAssemblyLoadContext *default_alc;
1821
static MonoCoopMutex alc_list_lock; /* Used when accessing 'alcs' */
22+
/* Protected by alc_list_lock */
23+
static GSList *loaded_assemblies;
1924

2025
static inline void
2126
alcs_lock (void)
@@ -92,17 +97,18 @@ mono_alc_cleanup_assemblies (MonoAssemblyLoadContext *alc)
9297
// The minimum refcount on assemblies is 2: one for the domain and one for the ALC.
9398
// The domain refcount might be less than optimal on netcore, but its removal is too likely to cause issues for now.
9499
GSList *tmp;
95-
MonoDomain *domain = mono_get_root_domain ();
96100

97-
// Remove the assemblies from domain_assemblies
98-
mono_domain_assemblies_lock (domain);
101+
// Remove the assemblies from loaded_assemblies
99102
for (tmp = alc->loaded_assemblies; tmp; tmp = tmp->next) {
100103
MonoAssembly *assembly = (MonoAssembly *)tmp->data;
101-
domain->domain_assemblies = g_slist_remove (domain->domain_assemblies, assembly);
104+
105+
alcs_lock ();
106+
loaded_assemblies = g_slist_remove (loaded_assemblies, assembly);
107+
alcs_unlock ();
108+
102109
mono_assembly_decref (assembly);
103-
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);
110+
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);
104111
}
105-
mono_domain_assemblies_unlock (domain);
106112

107113
// Release the GC roots
108114
for (tmp = alc->loaded_assemblies; tmp; tmp = tmp->next) {
@@ -262,6 +268,135 @@ ves_icall_System_Runtime_Loader_AssemblyLoadContext_GetLoadContextForAssembly (M
262268
return (gpointer)alc->gchandle;
263269
}
264270

271+
static gboolean
272+
add_assembly_to_array (MonoArrayHandle dest, int dest_idx, MonoAssembly* assm, MonoError *error)
273+
{
274+
HANDLE_FUNCTION_ENTER ();
275+
error_init (error);
276+
MonoReflectionAssemblyHandle assm_obj = mono_assembly_get_object_handle (assm, error);
277+
goto_if_nok (error, leave);
278+
MONO_HANDLE_ARRAY_SETREF (dest, dest_idx, assm_obj);
279+
leave:
280+
HANDLE_FUNCTION_RETURN_VAL (is_ok (error));
281+
}
282+
283+
MonoArrayHandle
284+
ves_icall_System_Runtime_Loader_AssemblyLoadContext_InternalGetLoadedAssemblies (MonoError *error)
285+
{
286+
GPtrArray *assemblies = mono_alc_get_all_loaded_assemblies ();
287+
288+
MonoArrayHandle res = mono_array_new_handle (mono_class_get_assembly_class (), assemblies->len, error);
289+
goto_if_nok (error, leave);
290+
for (int i = 0; i < assemblies->len; ++i) {
291+
if (!add_assembly_to_array (res, i, (MonoAssembly *)g_ptr_array_index (assemblies, i), error))
292+
goto leave;
293+
}
294+
295+
leave:
296+
g_ptr_array_free (assemblies, TRUE);
297+
return res;
298+
}
299+
300+
static
301+
MonoAssembly *
302+
mono_alc_load_file (MonoAssemblyLoadContext *alc, MonoStringHandle fname, MonoAssembly *executing_assembly, MonoAssemblyContextKind asmctx, MonoError *error)
303+
{
304+
MonoAssembly *ass = NULL;
305+
HANDLE_FUNCTION_ENTER ();
306+
char *filename = NULL;
307+
if (MONO_HANDLE_IS_NULL (fname)) {
308+
mono_error_set_argument_null (error, "assemblyFile", "");
309+
goto leave;
310+
}
311+
312+
filename = mono_string_handle_to_utf8 (fname, error);
313+
goto_if_nok (error, leave);
314+
315+
if (!g_path_is_absolute (filename)) {
316+
mono_error_set_argument (error, "assemblyFile", "Absolute path information is required.");
317+
goto leave;
318+
}
319+
320+
MonoImageOpenStatus status;
321+
MonoAssemblyOpenRequest req;
322+
mono_assembly_request_prepare_open (&req, asmctx, alc);
323+
req.requesting_assembly = executing_assembly;
324+
ass = mono_assembly_request_open (filename, &req, &status);
325+
if (!ass) {
326+
if (status == MONO_IMAGE_IMAGE_INVALID)
327+
mono_error_set_bad_image_by_name (error, filename, "Invalid Image: %s", filename);
328+
else
329+
mono_error_set_simple_file_not_found (error, filename);
330+
}
331+
332+
leave:
333+
g_free (filename);
334+
HANDLE_FUNCTION_RETURN_VAL (ass);
335+
}
336+
337+
MonoReflectionAssemblyHandle
338+
ves_icall_System_Runtime_Loader_AssemblyLoadContext_InternalLoadFile (gpointer alc_ptr, MonoStringHandle fname, MonoStackCrawlMark *stack_mark, MonoError *error)
339+
{
340+
MonoReflectionAssemblyHandle result = MONO_HANDLE_CAST (MonoReflectionAssembly, NULL_HANDLE);
341+
MonoAssemblyLoadContext *alc = (MonoAssemblyLoadContext *)alc_ptr;
342+
343+
MonoAssembly *executing_assembly;
344+
executing_assembly = mono_runtime_get_caller_from_stack_mark (stack_mark);
345+
MonoAssembly *ass = mono_alc_load_file (alc, fname, executing_assembly, mono_alc_is_default (alc) ? MONO_ASMCTX_LOADFROM : MONO_ASMCTX_INDIVIDUAL, error);
346+
goto_if_nok (error, leave);
347+
348+
result = mono_assembly_get_object_handle (ass, error);
349+
350+
leave:
351+
return result;
352+
}
353+
354+
static MonoAssembly*
355+
mono_alc_load_raw_bytes (MonoAssemblyLoadContext *alc, guint8 *assembly_data, guint32 raw_assembly_len, guint8 *raw_symbol_data, guint32 raw_symbol_len, MonoError *error)
356+
{
357+
MonoAssembly *ass = NULL;
358+
MonoImageOpenStatus status;
359+
MonoImage *image = mono_image_open_from_data_internal (alc, (char*)assembly_data, raw_assembly_len, TRUE, NULL, FALSE, NULL, NULL);
360+
361+
if (!image) {
362+
mono_error_set_bad_image_by_name (error, "In memory assembly", "0x%p", assembly_data);
363+
return ass;
364+
}
365+
366+
if (raw_symbol_data)
367+
mono_debug_open_image_from_memory (image, raw_symbol_data, raw_symbol_len);
368+
369+
MonoAssemblyLoadRequest req;
370+
mono_assembly_request_prepare_load (&req, MONO_ASMCTX_INDIVIDUAL, alc);
371+
ass = mono_assembly_request_load_from (image, "", &req, &status);
372+
373+
if (!ass) {
374+
mono_image_close (image);
375+
mono_error_set_bad_image_by_name (error, "In Memory assembly", "0x%p", assembly_data);
376+
return ass;
377+
}
378+
379+
/* Clear the reference added by mono_image_open_from_data_internal above */
380+
mono_image_close (image);
381+
382+
return ass;
383+
}
384+
385+
MonoReflectionAssemblyHandle
386+
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)
387+
{
388+
MonoAssemblyLoadContext *alc = (MonoAssemblyLoadContext *)native_alc;
389+
MonoReflectionAssemblyHandle result = MONO_HANDLE_CAST (MonoReflectionAssembly, NULL_HANDLE);
390+
MonoAssembly *assm = NULL;
391+
assm = mono_alc_load_raw_bytes (alc, (guint8 *)raw_assembly_ptr, raw_assembly_len, (guint8 *)raw_symbols_ptr, raw_symbols_len, error);
392+
goto_if_nok (error, leave);
393+
394+
result = mono_assembly_get_object_handle (assm, error);
395+
396+
leave:
397+
return result;
398+
}
399+
265400
gboolean
266401
mono_alc_is_default (MonoAssemblyLoadContext *alc)
267402
{
@@ -420,3 +555,77 @@ mono_alc_invoke_resolve_using_resolve_satellite_nofail (MonoAssemblyLoadContext
420555

421556
return result;
422557
}
558+
559+
void
560+
mono_alc_add_assembly (MonoAssemblyLoadContext *alc, MonoAssembly *ass)
561+
{
562+
GSList *tmp;
563+
564+
g_assert (ass);
565+
566+
if (!ass->aname.name)
567+
return;
568+
569+
mono_alc_assemblies_lock (alc);
570+
for (tmp = alc->loaded_assemblies; tmp; tmp = tmp->next) {
571+
if (tmp->data == ass) {
572+
mono_alc_assemblies_unlock (alc);
573+
return;
574+
}
575+
}
576+
577+
mono_assembly_addref (ass);
578+
// Prepending here will break the test suite with frequent InvalidCastExceptions, so we have to append
579+
alc->loaded_assemblies = g_slist_append (alc->loaded_assemblies, ass);
580+
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);
581+
mono_alc_assemblies_unlock (alc);
582+
583+
alcs_lock ();
584+
loaded_assemblies = g_slist_append (loaded_assemblies, ass);
585+
alcs_unlock ();
586+
}
587+
588+
MonoAssembly*
589+
mono_alc_find_assembly (MonoAssemblyLoadContext *alc, MonoAssemblyName *aname)
590+
{
591+
GSList *tmp;
592+
MonoAssembly *ass;
593+
594+
const MonoAssemblyNameEqFlags eq_flags = MONO_ANAME_EQ_IGNORE_PUBKEY | MONO_ANAME_EQ_IGNORE_VERSION | MONO_ANAME_EQ_IGNORE_CASE;
595+
596+
mono_alc_assemblies_lock (alc);
597+
for (tmp = alc->loaded_assemblies; tmp; tmp = tmp->next) {
598+
ass = (MonoAssembly *)tmp->data;
599+
g_assert (ass != NULL);
600+
// FIXME: Can dynamic assemblies match here for netcore?
601+
if (assembly_is_dynamic (ass) || !mono_assembly_names_equal_flags (aname, &ass->aname, eq_flags))
602+
continue;
603+
604+
mono_alc_assemblies_unlock (alc);
605+
return ass;
606+
}
607+
mono_alc_assemblies_unlock (alc);
608+
return NULL;
609+
}
610+
611+
/*
612+
* mono_alc_get_all_loaded_assemblies:
613+
*
614+
* Return a list of loaded assemblies in all appdomains.
615+
*/
616+
GPtrArray*
617+
mono_alc_get_all_loaded_assemblies (void)
618+
{
619+
GSList *tmp;
620+
GPtrArray *assemblies;
621+
MonoAssembly *ass;
622+
623+
assemblies = g_ptr_array_new ();
624+
alcs_lock ();
625+
for (tmp = loaded_assemblies; tmp; tmp = tmp->next) {
626+
ass = (MonoAssembly *)tmp->data;
627+
g_ptr_array_add (assemblies, ass);
628+
}
629+
alcs_unlock ();
630+
return assemblies;
631+
}

src/mono/mono/metadata/class-internals.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1536,6 +1536,13 @@ m_field_get_offset (MonoClassField *field)
15361536
* the lifetime of the image/class/method.
15371537
*/
15381538

1539+
static inline MonoMemoryManager*
1540+
mono_mem_manager_get_ambient (void)
1541+
{
1542+
// FIXME: All callers should get a MemoryManager from their callers or context
1543+
return (MonoMemoryManager *)mono_alc_get_default ()->memory_manager;
1544+
}
1545+
15391546
static inline MonoMemoryManager*
15401547
m_image_get_mem_manager (MonoImage *image)
15411548
{
@@ -1582,7 +1589,7 @@ static inline MonoMemoryManager*
15821589
m_method_get_mem_manager (MonoMethod *method)
15831590
{
15841591
// FIXME:
1585-
return mono_domain_memory_manager (mono_get_root_domain ());
1592+
return (MonoMemoryManager *)mono_alc_get_default ()->memory_manager;
15861593
}
15871594

15881595
static inline void *

0 commit comments

Comments
 (0)