From 5274cf147f45833936b728b4d27db0f6eda595dd Mon Sep 17 00:00:00 2001 From: Ryan Lucia Date: Wed, 26 May 2021 15:25:25 -0400 Subject: [PATCH] Add GCHandle in native default ALC at creation This lets embedders have a handle to fetch and pass before the runtime is properly started up and the managed default ALC is not yet created. Once the managed counterpart is initialized, the handle's target is changed, but the handle stays the same. --- src/mono/mono/metadata/assembly-load-context.c | 13 +++++++++++-- src/mono/mono/metadata/mono-private-unstable.h | 1 + src/mono/mono/metadata/native-library.c | 6 ++++++ 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/mono/mono/metadata/assembly-load-context.c b/src/mono/mono/metadata/assembly-load-context.c index 6550920e15306..85c9b3313bf75 100644 --- a/src/mono/mono/metadata/assembly-load-context.c +++ b/src/mono/mono/metadata/assembly-load-context.c @@ -72,6 +72,7 @@ mono_alcs_init (void) mono_coop_mutex_init (&alc_list_lock); default_alc = mono_alc_create (FALSE); + default_alc->gchandle = mono_gchandle_new_internal (NULL, FALSE); } MonoAssemblyLoadContext * @@ -237,8 +238,10 @@ ves_icall_System_Runtime_Loader_AssemblyLoadContext_InternalInitializeNativeALC if (is_default_alc) { alc = default_alc; g_assert (alc); - if (!alc->gchandle) - alc->gchandle = this_gchandle; + + // Change target of the existing GCHandle + mono_gchandle_set_target (alc->gchandle, mono_gchandle_get_target_internal (this_gchandle)); + mono_gchandle_free_internal (this_gchandle); } else { alc = mono_alc_create_individual (this_gchandle, collectible, error); } @@ -416,6 +419,9 @@ mono_alc_is_default (MonoAssemblyLoadContext *alc) MonoAssemblyLoadContext * mono_alc_from_gchandle (MonoGCHandle alc_gchandle) { + if (alc_gchandle == default_alc->gchandle) + return default_alc; + HANDLE_FUNCTION_ENTER (); MonoManagedAssemblyLoadContextHandle managed_alc = MONO_HANDLE_CAST (MonoManagedAssemblyLoadContext, mono_gchandle_get_target_handle (alc_gchandle)); MonoAssemblyLoadContext *alc = MONO_HANDLE_GETVAL (managed_alc, native_assembly_load_context); @@ -438,6 +444,9 @@ invoke_resolve_method (MonoMethod *resolve_method, MonoAssemblyLoadContext *alc, if (mono_runtime_get_no_exec ()) return NULL; + if (!mono_gchandle_get_target_internal (alc->gchandle)) + return NULL; + HANDLE_FUNCTION_ENTER (); aname_str = mono_stringify_assembly_name (aname); diff --git a/src/mono/mono/metadata/mono-private-unstable.h b/src/mono/mono/metadata/mono-private-unstable.h index 6585c2e575aed..4618c8fe08bc9 100644 --- a/src/mono/mono/metadata/mono-private-unstable.h +++ b/src/mono/mono/metadata/mono-private-unstable.h @@ -28,6 +28,7 @@ typedef MonoAssembly * (*MonoAssemblyPreLoadFuncV3) (MonoAssemblyLoadContextGCHa MONO_API MONO_RT_EXTERNAL_ONLY void mono_install_assembly_preload_hook_v3 (MonoAssemblyPreLoadFuncV3 func, void *user_data, mono_bool append); +// This can point at NULL before the default ALC is initialized MONO_API MONO_RT_EXTERNAL_ONLY MonoAssemblyLoadContextGCHandle mono_alc_get_default_gchandle (void); diff --git a/src/mono/mono/metadata/native-library.c b/src/mono/mono/metadata/native-library.c index 252f6d32f8a38..10808d2144b13 100644 --- a/src/mono/mono/metadata/native-library.c +++ b/src/mono/mono/metadata/native-library.c @@ -630,6 +630,9 @@ netcore_resolve_with_load (MonoAssemblyLoadContext *alc, const char *scope, Mono if (mono_runtime_get_no_exec ()) return NULL; + if (!mono_gchandle_get_target_internal (alc->gchandle)) + return NULL; + HANDLE_FUNCTION_ENTER (); MonoStringHandle scope_handle; @@ -693,6 +696,9 @@ netcore_resolve_with_resolving_event (MonoAssemblyLoadContext *alc, MonoAssembly if (mono_runtime_get_no_exec ()) return NULL; + if (!mono_gchandle_get_target_internal (alc->gchandle)) + return NULL; + HANDLE_FUNCTION_ENTER (); MonoStringHandle scope_handle;