From 5078dd61a81c88dbdd131a77b8148b4dee3803fa Mon Sep 17 00:00:00 2001 From: Marek Safar Date: Sun, 27 Dec 2020 09:10:59 +0100 Subject: [PATCH] Clean up managed dependencies for Mono's domain/loader context (#46323) MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Co-authored-by: Aleksey Kliger (λgeek) --- .../System/Runtime/Loader/AssemblyLoadContext.cs | 28 +++++++++-- src/mono/mono/metadata/appdomain.c | 56 ++++++++++++++++------ src/mono/mono/metadata/assembly-load-context.c | 15 ++++-- src/mono/mono/metadata/class-internals.h | 2 + src/mono/mono/metadata/domain.c | 4 +- src/mono/mono/metadata/icall.c | 15 ++++-- src/mono/mono/metadata/native-library.c | 16 +++++-- src/mono/mono/metadata/object-internals.h | 8 ---- src/mono/mono/metadata/object.c | 22 +++++++-- .../src/ILLink/ILLink.Descriptors.xml | 18 +------ .../Runtime/Loader/AssemblyLoadContext.Mono.cs | 2 +- 11 files changed, 120 insertions(+), 66 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Loader/AssemblyLoadContext.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Loader/AssemblyLoadContext.cs index 6e6fec0..7ef3051 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Loader/AssemblyLoadContext.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Loader/AssemblyLoadContext.cs @@ -39,10 +39,14 @@ namespace System.Runtime.Loader s_allContexts; #region private data members - // If you modify any of these fields, you must also update the + // If you modify this field, you must also update the // AssemblyLoadContextBaseObject structure in object.h // and MonoManagedAssemblyLoadContext in object-internals.h + // Contains the reference to VM's representation of the AssemblyLoadContext + private readonly IntPtr _nativeAssemblyLoadContext; +#endregion + // synchronization primitive to protect against usage of this instance while unloading private readonly object _unloadLock; @@ -54,9 +58,6 @@ namespace System.Runtime.Loader private readonly string? _name; - // Contains the reference to VM's representation of the AssemblyLoadContext - private readonly IntPtr _nativeAssemblyLoadContext; - // Id used by s_allContexts private readonly long _id; @@ -64,7 +65,6 @@ namespace System.Runtime.Loader private InternalState _state; private readonly bool _isCollectible; -#endregion protected AssemblyLoadContext() : this(false, false, null) { @@ -180,6 +180,9 @@ namespace System.Runtime.Loader // Returns: A handle to the loaded native library public event Func? ResolvingUnmanagedDll { +#if MONO + [DynamicDependency(nameof(MonoResolveUnmanagedDllUsingEvent))] +#endif add { _resolvingUnmanagedDll += value; @@ -198,6 +201,9 @@ namespace System.Runtime.Loader // Returns: The Loaded assembly object. public event Func? Resolving { +#if MONO + [DynamicDependency(nameof(MonoResolveUsingResolvingEvent))] +#endif add { _resolving += value; @@ -222,16 +228,28 @@ namespace System.Runtime.Loader #region AppDomainEvents // Occurs when an Assembly is loaded +#if MONO + [method: DynamicDependency(nameof(OnAssemblyLoad))] +#endif internal static event AssemblyLoadEventHandler? AssemblyLoad; // Occurs when resolution of type fails +#if MONO + [method: DynamicDependency(nameof(OnTypeResolve))] +#endif internal static event ResolveEventHandler? TypeResolve; // Occurs when resolution of resource fails +#if MONO + [method: DynamicDependency(nameof(OnResourceResolve))] +#endif internal static event ResolveEventHandler? ResourceResolve; // Occurs when resolution of assembly fails // This event is fired after resolve events of AssemblyLoadContext fails +#if MONO + [method: DynamicDependency(nameof(OnAssemblyResolve))] +#endif internal static event ResolveEventHandler? AssemblyResolve; #endregion diff --git a/src/mono/mono/metadata/appdomain.c b/src/mono/mono/metadata/appdomain.c index 8638fba..6523f11 100644 --- a/src/mono/mono/metadata/appdomain.c +++ b/src/mono/mono/metadata/appdomain.c @@ -142,12 +142,15 @@ add_assembly_to_alc (MonoAssemblyLoadContext *alc, MonoAssembly *ass); #endif +#ifndef ENABLE_NETCORE + static MonoAppDomainHandle mono_domain_create_appdomain_internal (char *friendly_name, MonoAppDomainSetupHandle setup, MonoError *error); static MonoDomain * mono_domain_create_appdomain_checked (char *friendly_name, char *configuration_file, MonoError *error); +#endif static void mono_context_set_default_context (MonoDomain *domain); @@ -596,6 +599,8 @@ mono_runtime_quit_internal (void) quit_function (mono_get_root_domain (), NULL); } +#ifndef ENABLE_NETCORE + /** * mono_domain_create_appdomain: * \param friendly_name The friendly name of the appdomain to create @@ -651,6 +656,8 @@ leave: HANDLE_FUNCTION_RETURN_VAL (result); } +#endif + /** * mono_domain_set_config: * \param domain \c MonoDomain initialized with the appdomain we want to change @@ -913,13 +920,21 @@ mono_domain_try_type_resolve_name (MonoDomain *domain, MonoAssembly *assembly, M MONO_STATIC_POINTER_INIT (MonoMethod, method) - MonoClass *alc_class = mono_class_get_assembly_load_context_class (); - g_assert (alc_class); - method = mono_class_get_method_from_name_checked (alc_class, "OnTypeResolve", -1, 0, error); + static gboolean inited; + // avoid repeatedly calling mono_class_get_method_from_name_checked + if (!inited) { + ERROR_DECL (local_error); + MonoClass *alc_class = mono_class_get_assembly_load_context_class (); + g_assert (alc_class); + method = mono_class_get_method_from_name_checked (alc_class, "OnTypeResolve", -1, 0, local_error); + mono_error_cleanup (local_error); + inited = TRUE; + } MONO_STATIC_POINTER_INIT_END (MonoMethod, method) - goto_if_nok (error, return_null); + if (!method) + goto return_null; g_assert (domain); g_assert (MONO_HANDLE_BOOL (name)); @@ -1489,14 +1504,21 @@ mono_try_assembly_resolve_handle (MonoAssemblyLoadContext *alc, MonoStringHandle MONO_STATIC_POINTER_INIT (MonoMethod, method) ERROR_DECL (local_error); - MonoClass *alc_class = mono_class_get_assembly_load_context_class (); - g_assert (alc_class); - method = mono_class_get_method_from_name_checked (alc_class, "OnAssemblyResolve", -1, 0, local_error); - mono_error_assert_ok (local_error); + static gboolean inited; + if (!inited) { + MonoClass *alc_class = mono_class_get_assembly_load_context_class (); + g_assert (alc_class); + method = mono_class_get_method_from_name_checked (alc_class, "OnAssemblyResolve", -1, 0, local_error); + inited = TRUE; + } + mono_error_cleanup (local_error); MONO_STATIC_POINTER_INIT_END (MonoMethod, method) - g_assert (method); + if (!method) { + ret = NULL; + goto leave; + } MonoReflectionAssemblyHandle requesting_handle; if (requesting) { @@ -1626,12 +1648,19 @@ mono_domain_fire_assembly_load_event (MonoDomain *domain, MonoAssembly *assembly #ifdef ENABLE_NETCORE MONO_STATIC_POINTER_INIT (MonoMethod, method) - MonoClass *alc_class = mono_class_get_assembly_load_context_class (); - g_assert (alc_class); - method = mono_class_get_method_from_name_checked (alc_class, "OnAssemblyLoad", -1, 0, error); + static gboolean inited; + if (!inited) { + ERROR_DECL (local_error); + MonoClass *alc_class = mono_class_get_assembly_load_context_class (); + g_assert (alc_class); + method = mono_class_get_method_from_name_checked (alc_class, "OnAssemblyLoad", -1, 0, local_error); + mono_error_cleanup (local_error); + inited = TRUE; + } MONO_STATIC_POINTER_INIT_END (MonoMethod, method) - goto_if_nok (error, exit); + if (!method) + goto exit; MonoReflectionAssemblyHandle assembly_handle; assembly_handle = mono_assembly_get_object_handle (domain, assembly, error); @@ -3524,4 +3553,3 @@ mono_runtime_install_appctx_properties (void) } #endif - diff --git a/src/mono/mono/metadata/assembly-load-context.c b/src/mono/mono/metadata/assembly-load-context.c index 90b8d5e..3f5066d 100644 --- a/src/mono/mono/metadata/assembly-load-context.c +++ b/src/mono/mono/metadata/assembly-load-context.c @@ -346,14 +346,19 @@ mono_alc_invoke_resolve_using_resolving_event (MonoAssemblyLoadContext *alc, Mon MONO_STATIC_POINTER_INIT (MonoMethod, resolve) ERROR_DECL (local_error); - MonoClass *alc_class = mono_class_get_assembly_load_context_class (); - g_assert (alc_class); - resolve = mono_class_get_method_from_name_checked (alc_class, "MonoResolveUsingResolvingEvent", -1, 0, local_error); - mono_error_assert_ok (local_error); + static gboolean inited; + if (!inited) { + MonoClass *alc_class = mono_class_get_assembly_load_context_class (); + g_assert (alc_class); + resolve = mono_class_get_method_from_name_checked (alc_class, "MonoResolveUsingResolvingEvent", -1, 0, local_error); + inited = TRUE; + } + mono_error_cleanup (local_error); MONO_STATIC_POINTER_INIT_END (MonoMethod, resolve) - g_assert (resolve); + if (!resolve) + return NULL; return invoke_resolve_method (resolve, alc, aname, error); } diff --git a/src/mono/mono/metadata/class-internals.h b/src/mono/mono/metadata/class-internals.h index 1b21404..6556558 100644 --- a/src/mono/mono/metadata/class-internals.h +++ b/src/mono/mono/metadata/class-internals.h @@ -1003,7 +1003,9 @@ typedef struct { MonoClass *iremotingtypeinfo_class; #endif MonoClass *mono_method_message_class; +#ifndef ENABLE_NETCORE MonoClass *appdomain_class; +#endif MonoClass *field_info_class; MonoClass *method_info_class; MonoClass *stack_frame_class; diff --git a/src/mono/mono/metadata/domain.c b/src/mono/mono/metadata/domain.c index d63217a..f92ab22 100644 --- a/src/mono/mono/metadata/domain.c +++ b/src/mono/mono/metadata/domain.c @@ -735,9 +735,7 @@ mono_init_internal (const char *filename, const char *exe_filename, const char * mono_defaults.corlib, "System.Threading", "ThreadAbortException"); #endif -#ifdef ENABLE_NETCORE - mono_defaults.appdomain_class = mono_defaults.object_class; -#else +#ifndef ENABLE_NETCORE mono_defaults.appdomain_class = mono_class_get_appdomain_class (); #endif diff --git a/src/mono/mono/metadata/icall.c b/src/mono/mono/metadata/icall.c index dbb4000..1a5e4e5 100644 --- a/src/mono/mono/metadata/icall.c +++ b/src/mono/mono/metadata/icall.c @@ -5566,13 +5566,20 @@ try_resource_resolve_name (MonoReflectionAssemblyHandle assembly_handle, MonoStr MONO_STATIC_POINTER_INIT (MonoMethod, resolve_method) - MonoClass *alc_class = mono_class_get_assembly_load_context_class (); - g_assert (alc_class); - resolve_method = mono_class_get_method_from_name_checked (alc_class, "OnResourceResolve", -1, 0, error); + static gboolean inited; + if (!inited) { + MonoClass *alc_class = mono_class_get_assembly_load_context_class (); + g_assert (alc_class); + resolve_method = mono_class_get_method_from_name_checked (alc_class, "OnResourceResolve", -1, 0, error); + inited = TRUE; + } + mono_error_cleanup (error); + error_init_reuse (error); MONO_STATIC_POINTER_INIT_END (MonoMethod, resolve_method) - goto_if_nok (error, return_null); + if (!resolve_method) + goto return_null; gpointer args [2]; args [0] = MONO_HANDLE_RAW (assembly_handle); diff --git a/src/mono/mono/metadata/native-library.c b/src/mono/mono/metadata/native-library.c index 2592373..4b5d4e8 100644 --- a/src/mono/mono/metadata/native-library.c +++ b/src/mono/mono/metadata/native-library.c @@ -568,13 +568,19 @@ netcore_resolve_with_dll_import_resolver (MonoAssemblyLoadContext *alc, MonoAsse MONO_STATIC_POINTER_INIT (MonoMethod, resolve) ERROR_DECL (local_error); - MonoClass *native_lib_class = mono_class_get_native_library_class (); - g_assert (native_lib_class); - resolve = mono_class_get_method_from_name_checked (native_lib_class, "MonoLoadLibraryCallbackStub", -1, 0, local_error); - mono_error_assert_ok (local_error); + static gboolean inited; + if (!inited) { + MonoClass *native_lib_class = mono_class_get_native_library_class (); + g_assert (native_lib_class); + resolve = mono_class_get_method_from_name_checked (native_lib_class, "MonoLoadLibraryCallbackStub", -1, 0, local_error); + inited = TRUE; + } + mono_error_cleanup (local_error); MONO_STATIC_POINTER_INIT_END (MonoMethod, resolve) - g_assert (resolve); + + if (!resolve) + return NULL; if (mono_runtime_get_no_exec ()) return NULL; diff --git a/src/mono/mono/metadata/object-internals.h b/src/mono/mono/metadata/object-internals.h index dc6126d..307c73b 100644 --- a/src/mono/mono/metadata/object-internals.h +++ b/src/mono/mono/metadata/object-internals.h @@ -1660,15 +1660,7 @@ typedef enum { // Keep in sync with System.Runtime.Loader.AssemblyLoadContext typedef struct { MonoObject object; - MonoObject *unload_lock; - MonoEvent *resolving_unmaned_dll; - MonoEvent *resolving; - MonoEvent *unloading; - MonoString *name; MonoAssemblyLoadContext *native_assembly_load_context; - gint64 id; - gint32 internal_state; - MonoBoolean is_collectible; } MonoManagedAssemblyLoadContext; TYPED_HANDLE_DECL (MonoManagedAssemblyLoadContext); diff --git a/src/mono/mono/metadata/object.c b/src/mono/mono/metadata/object.c index ac2fe4e..bed293e 100644 --- a/src/mono/mono/metadata/object.c +++ b/src/mono/mono/metadata/object.c @@ -5080,11 +5080,17 @@ mono_first_chance_exception_checked (MonoObjectHandle exc, MonoError *error) MONO_STATIC_POINTER_INIT (MonoClassField, field) - field = mono_class_get_field_from_name_full (mono_defaults.appcontext_class, "FirstChanceException", NULL); - g_assert (field); + static gboolean inited; + if (!inited) { + field = mono_class_get_field_from_name_full (mono_defaults.appcontext_class, "FirstChanceException", NULL); + inited = TRUE; + } MONO_STATIC_POINTER_INIT_END (MonoClassField, field) + if (!field) + return; + MonoVTable *vt = mono_class_vtable_checked (domain, mono_defaults.appcontext_class, error); return_if_nok (error); @@ -5141,13 +5147,18 @@ mono_unhandled_exception_checked (MonoObjectHandle exc, MonoError *error) #ifndef ENABLE_NETCORE field = mono_class_get_field_from_name_full (mono_defaults.appdomain_class, "UnhandledException", NULL); #else - field = mono_class_get_field_from_name_full (mono_defaults.appcontext_class, "UnhandledException", NULL); + static gboolean inited; + if (!inited) { + field = mono_class_get_field_from_name_full (mono_defaults.appcontext_class, "UnhandledException", NULL); + inited = TRUE; + } #endif - g_assert (field); MONO_STATIC_POINTER_INIT_END (MonoClassField, field) #ifndef ENABLE_NETCORE + g_assert (field); + MonoDomain *root_domain; MonoObjectHandle current_appdomain_delegate = MONO_HANDLE_NEW (MonoObject, NULL); @@ -5172,6 +5183,9 @@ mono_unhandled_exception_checked (MonoObjectHandle exc, MonoError *error) mono_threads_end_abort_protected_block (); } #else + if (!field) + goto leave; + MonoObject *delegate = NULL; MonoObjectHandle delegate_handle; MonoVTable *vt = mono_class_vtable_checked (current_domain, mono_defaults.appcontext_class, error); diff --git a/src/mono/netcore/System.Private.CoreLib/src/ILLink/ILLink.Descriptors.xml b/src/mono/netcore/System.Private.CoreLib/src/ILLink/ILLink.Descriptors.xml index cf4742d..2399aea 100644 --- a/src/mono/netcore/System.Private.CoreLib/src/ILLink/ILLink.Descriptors.xml +++ b/src/mono/netcore/System.Private.CoreLib/src/ILLink/ILLink.Descriptors.xml @@ -9,25 +9,13 @@ - + - - - - - - - - - - - - @@ -643,10 +631,6 @@ - - - - diff --git a/src/mono/netcore/System.Private.CoreLib/src/System/Runtime/Loader/AssemblyLoadContext.Mono.cs b/src/mono/netcore/System.Private.CoreLib/src/System/Runtime/Loader/AssemblyLoadContext.Mono.cs index a2dbfc9..164e61e 100644 --- a/src/mono/netcore/System.Private.CoreLib/src/System/Runtime/Loader/AssemblyLoadContext.Mono.cs +++ b/src/mono/netcore/System.Private.CoreLib/src/System/Runtime/Loader/AssemblyLoadContext.Mono.cs @@ -11,7 +11,6 @@ using Internal.Runtime.CompilerServices; namespace System.Runtime.Loader { - [StructLayout(LayoutKind.Sequential)] public partial class AssemblyLoadContext { internal IntPtr NativeALC @@ -22,6 +21,7 @@ namespace System.Runtime.Loader } } + [DynamicDependency(nameof(_nativeAssemblyLoadContext))] private static IntPtr InitializeAssemblyLoadContext(IntPtr thisHandlePtr, bool representsTPALoadContext, bool isCollectible) { return InternalInitializeNativeALC(thisHandlePtr, representsTPALoadContext, isCollectible); -- 2.7.4