Skip to content

Conversation

grendello
Copy link
Contributor

@grendello grendello commented May 19, 2021

Context: https://docs.microsoft.com/en-us/dotnet/api/system.runtime.loader.assemblyloadcontext?view=net-5.0

dotnet 6 removes support for AppDomains (technically, there still exists
a single AppDomain, but creation of new ones is no longer possible),
replacing them (in a way) with AssemblyLoadContext, which enables scoped
loading of managed assemblies.

Part of the change is the new set of MonoVM functions we need to call in
order to load an assembly into either the default AssemblyLoadContext
(early in the startup process) or into the application-created context
later on during application run time. MonoVM also adds new preload
hooks which work with the ALC instead of the older AppDomains.

This commit adds support for ALC preload callbacks and the new
assembly load functions.

@srxqds
Copy link

srxqds commented May 28, 2021

the alc support unload?

@grendello
Copy link
Contributor Author

ALC isn't supported at all yet, waiting for this dotnet/runtime PR to land

@grendello grendello changed the title Net6 alc [NET6] Enable support for AssemblyLoadContext Jun 29, 2021
@grendello grendello marked this pull request as ready for review June 29, 2021 08:16
@grendello grendello requested a review from jonpryor as a code owner June 29, 2021 08:16
@grendello grendello force-pushed the net6-alc branch 2 times, most recently from 853fd1b to 5046ce5 Compare July 1, 2021 07:13

#if defined (NET6)
MonoAssembly*
Util::monodroid_load_assembly (MonoAssemblyLoadContextGCHandle alc_handle, const char *basename)
Copy link
Contributor

Choose a reason for hiding this comment

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

Why does this member function exist when it doesn't appear to be used from anywhere? Dead code?

Copy link
Contributor Author

@grendello grendello Jul 2, 2021

Choose a reason for hiding this comment

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

No, I planned to start using it in another PR, one which would review all the usage of AppDomains across the code. I don't want to do it in this PR to keep it more focused. However, since this method will be called from few places, I'll add the calls to this PR.


void
EmbeddedAssemblies::install_preload_hooks ()
EmbeddedAssemblies::install_preload_hooks (bool early)
Copy link
Contributor

Choose a reason for hiding this comment

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

This somewhat "irks" me in that "early" doesn't mean anything. The fact that it's bool implies that install_preload_hooks() is called twice -- which it is -- but why it's called twice, or how the two call-sites differ, isn't fully implied. (One is "early", presumably; but what does that mean?)

Additionally, given that I can't see any code share between the early and !early blocks, I think it would be more understandable if we split this up into two separately named methods, which would allow us to use a more "meaningful" adjective than "early".

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I will split the method into two separate ones.

Context: https://docs.microsoft.com/en-us/dotnet/api/system.runtime.loader.assemblyloadcontext?view=net-5.0

dotnet 6 removes support for AppDomains (technically, there still exists
a single AppDomain, but creation of new ones is no longer possible),
replacing them (in a way) with AssemblyLoadContext, which enables scoped
loading of managed assemblies.

Part of the change is the new set of MonoVM functions we need to call in
order to load an assembly into either the default AssemblyLoadContext
(early in the startup process) or into the application-created context
later on during application run time.  MonoVM also adds new preload
hooks which work with the `ALC` instead of the older AppDomains.

This commit adds support for `ALC` preload callbacks and the new
assembly load functions.
@jonpryor
Copy link
Contributor

jonpryor commented Jul 2, 2021

@srxqds: in all likelihood, for .NET 6 we won't support unloading binding assemblies. Other usage of AssemblyLoadContext should work.

@jonpryor
Copy link
Contributor

jonpryor commented Jul 2, 2021

Other related discussion links of interest which came up recently:

https://discord.com/channels/732297728826277939/732297965019988138/860536362351329320

(not entirely true: there is "contextual reflection" https://github.com/dotnet/coreclr/blob/master/Documentation/design-docs/AssemblyLoadContext.ContextualReflection.md which lets code using ALCs to affect how Assembly.Load and Type.GetType behave with respect to loading)

https://discord.com/channels/732297728826277939/732297965019988138/860541671933214780

I think you're basically in this situation like Type.GetType where you just don't have enough arguments
https://github.com/dotnet/coreclr/blob/master/Documentation/design-docs/AssemblyLoadContext.ContextualReflection.md

https://discord.com/channels/732297728826277939/732297965019988138/860544431986966548

so the problem is you want lookups and registration to go from "assembly qualified type name" to "type". but I am telling you that that is ambiguous. When you register the type, if you want the name-based lookup to be unique, you need to either also use the ALC as a key. or you need to say the type can be registered from at most one ALC - which ever one runs the registration code first

https://discord.com/channels/732297728826277939/732297965019988138/860549366263578624

but I need to call the above static method from native to get it

@jonpryor
Copy link
Contributor

jonpryor commented Jul 2, 2021

Context: https://docs.microsoft.com/dotnet/api/system.runtime.loader.assemblyloadcontext?view=net-5.0

.NET Core -- and thus, .NET 5+ -- removed support for
`System.AppDomain` -- technically, there still exists
a single `AppDomain`, but creation of new ones is no longer possible
-- with [`System.Runtime.Loader.AssemblyLoadContext`][0] acting as
the replacement for *some* previous `AppDomain` functionality.

TL;DR: `AssemblyLoadContext` allows (potentially) loading and
unloading assemblies, but *doesn't* allow creating an in-process
"sandbox" like `AppDomain`s originally did (though Code-Access-Security
was deprecated by .NET Framework 4; use as a sandbox was, in
retrospect, rarely a good idea).

Commit 0cd890bd introduced partial support for using
`AssemblyLoadContext`, but it was necessarily incomplete until after
[dotnet/runtime#53308][1] and other fixes landed.

Add support for calling the new `AssemblyLoadContext`-oriented
MonoVM embedding APIs to load assemblies, instead of the legacy
`MonoDomain`-oriented APIs.

Add support for calling the new `AssemblyLoadContext`-oriented MonoVM
functions to load an assembly into either the default
`AssemblyLoadContext` (early in the startup process) or into the
application-created context later on during application run time.
MonoVM also adds new preload hooks which work with the
`AssemblyLoadContext` instead of the older AppDomains.

Also add support for `AssemblyLoadContext` preload callbacks and the
new assembly load functions.

[0]: https://docs.microsoft.com/dotnet/api/system.runtime.loader.assemblyloadcontext?view=net-5.0
[1]: https://github.com/dotnet/runtime/pull/53308

@jonpryor
Copy link
Contributor

jonpryor commented Jul 2, 2021

@grendello: should the commit message also explicitly note that all binding assemblies will be loaded into the default AssemblyLoadContext, and that there's no way to not do that? Or will that be part of a subsequent commit?

@grendello
Copy link
Contributor Author

@grendello: should the commit message also explicitly note that all binding assemblies will be loaded into the default AssemblyLoadContext, and that there's no way to not do that? Or will that be part of a subsequent commit?

Let's leave it till a subsequent commit, there's more work to be done in related areas, maybe I'll figure something out.

@jonpryor jonpryor merged commit b7224e5 into dotnet:main Jul 2, 2021
@grendello grendello deleted the net6-alc branch July 2, 2021 22:23
@srxqds
Copy link

srxqds commented Jul 5, 2021

@srxqds: in all likelihood, for .NET 6 we won't support unloading binding assemblies. Other usage of AssemblyLoadContext should work.

ok, thank you, I will try to support unloadable alcs later, hope it get well.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants