Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Clean up managed dependencies for Mono's domain/loader context #46323

Merged
merged 17 commits into from
Dec 27, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,14 @@ private enum InternalState
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;

Expand All @@ -54,17 +58,13 @@ private enum InternalState

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;

// Indicates the state of this ALC (Alive or in Unloading state)
private InternalState _state;

private readonly bool _isCollectible;
#endregion

protected AssemblyLoadContext() : this(false, false, null)
{
Expand Down Expand Up @@ -180,6 +180,9 @@ public IEnumerable<Assembly> Assemblies
// Returns: A handle to the loaded native library
public event Func<Assembly, string, IntPtr>? ResolvingUnmanagedDll
{
#if MONO
[DynamicDependency(nameof(MonoResolveUnmanagedDllUsingEvent))]
#endif
add
{
_resolvingUnmanagedDll += value;
Expand All @@ -198,6 +201,9 @@ public event Func<Assembly, string, IntPtr>? ResolvingUnmanagedDll
// Returns: The Loaded assembly object.
public event Func<AssemblyLoadContext, AssemblyName, Assembly?>? Resolving
{
#if MONO
[DynamicDependency(nameof(MonoResolveUsingResolvingEvent))]
#endif
add
{
_resolving += value;
Expand All @@ -222,16 +228,28 @@ public event Action<AssemblyLoadContext>? Unloading

#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

Expand Down
56 changes: 42 additions & 14 deletions src/mono/mono/metadata/appdomain.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -651,6 +656,8 @@ mono_domain_create_appdomain_checked (char *friendly_name, char *configuration_f
HANDLE_FUNCTION_RETURN_VAL (result);
}

#endif

/**
* mono_domain_set_config:
* \param domain \c MonoDomain initialized with the appdomain we want to change
Expand Down Expand Up @@ -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));
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -3524,4 +3553,3 @@ mono_runtime_install_appctx_properties (void)
}

#endif

15 changes: 10 additions & 5 deletions src/mono/mono/metadata/assembly-load-context.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down
2 changes: 2 additions & 0 deletions src/mono/mono/metadata/class-internals.h
Original file line number Diff line number Diff line change
Expand Up @@ -1003,7 +1003,9 @@ typedef struct {
MonoClass *iremotingtypeinfo_class;
#endif
MonoClass *mono_method_message_class;
#ifndef ENABLE_NETCORE
MonoClass *appdomain_class;
lambdageek marked this conversation as resolved.
Show resolved Hide resolved
#endif
MonoClass *field_info_class;
MonoClass *method_info_class;
MonoClass *stack_frame_class;
Expand Down
4 changes: 1 addition & 3 deletions src/mono/mono/metadata/domain.c
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
15 changes: 11 additions & 4 deletions src/mono/mono/metadata/icall.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
marek-safar marked this conversation as resolved.
Show resolved Hide resolved
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);
Expand Down
16 changes: 11 additions & 5 deletions src/mono/mono/metadata/native-library.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
8 changes: 0 additions & 8 deletions src/mono/mono/metadata/object-internals.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Comment on lines -1663 to -1671
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@CoffeeFlux are any of these fields going to be necessary for future collectible ALC work?

} MonoManagedAssemblyLoadContext;

TYPED_HANDLE_DECL (MonoManagedAssemblyLoadContext);
Expand Down
22 changes: 18 additions & 4 deletions src/mono/mono/metadata/object.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down Expand Up @@ -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);

Expand All @@ -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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,25 +9,13 @@

<!-- assembly-load-context.c: -->
<!-- object-internals.h: MonoManagedAssemblyLoadContext -->
<type fullname="System.Runtime.Loader.AssemblyLoadContext" preserve="fields">
<type fullname="System.Runtime.Loader.AssemblyLoadContext">
<!-- assembly-load-context.c: mono_alc_invoke_resolve_using_load -->
<method name="MonoResolveUsingLoad" />
<!-- assembly-load-context.c: mono_alc_invoke_resolve_using_resolving_event -->
<method name="MonoResolveUsingResolvingEvent" />
<!-- assembly-load-context.c: mono_alc_invoke_resolve_using_resolve_satellite -->
<method name="MonoResolveUsingResolveSatelliteAssembly" />
<!-- native-library.c: netcore_resolve_with_load () -->
<method name="MonoResolveUnmanagedDll" />
<!-- native-library.c: netcore_resolve_with_resolving_event () -->
<method name="MonoResolveUnmanagedDllUsingEvent" />
<!-- appdomain.c: mono_domain_fire_assembly_load_event -->
<method name="OnAssemblyLoad" />
<!-- appdomain.c: mono_try_assembly_resolve_handle () -->
<method name="OnAssemblyResolve" />
<!-- appdomain.c: mono_domain_try_type_resolve_name -->
<method name="OnTypeResolve" />
<!-- icall.c: try_resource_resolve_name -->
<method name="OnResourceResolve" />
</type>

<!-- exception.c (mono_get_exception_argument) -->
Expand Down Expand Up @@ -648,10 +636,6 @@
<method name="OnProcessExit"/>
<!-- appdomain.c: get_app_context_base_directory -->
<method name="get_BaseDirectory"/>
<!-- object.c: mono_unhandled_exception_checked -->
<field name="UnhandledException"/>
<!-- object.c: mono_first_chance_exception_checked -->
<field name="FirstChanceException"/>
</type>

<!-- mono_method_has_unmanaged_callers_only_attribute () -->
Expand Down
Loading