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

More cleanups in assembly loader area #63157

Merged
merged 25 commits into from
Jan 29, 2022
Merged

More cleanups in assembly loader area #63157

merged 25 commits into from
Jan 29, 2022

Conversation

VSadov
Copy link
Member

@VSadov VSadov commented Dec 27, 2021

The goal is to simplify DomainFile/DomainAssembly and merge them into a single entity.
Coreclr does not have multimodule assemblies. With such assumption things can be simpler.

@ghost
Copy link

ghost commented Dec 27, 2021

Tagging subscribers to this area: @vitek-karas, @agocke, @VSadov
See info in area-owners.md if you want to be subscribed.

Issue Details

In progress.

The goal is to simplify DomainFile/DomainAssembly and merge them into a single entity.
Coreclr does not have multimodule assemblies. With such assumption things can be simpler.

Author: VSadov
Assignees: VSadov
Labels:

area-AssemblyLoader-coreclr

Milestone: -

@@ -3284,7 +3264,7 @@ Module::GetAssemblyIfLoaded(
}

if (pDomainAssembly && pDomainAssembly->IsLoaded())
pAssembly = pDomainAssembly->GetCurrentAssembly(); // <NOTE> Do not use GetAssembly - that may force the completion of a load
pAssembly = pDomainAssembly->GetAssembly(); // <NOTE> Do not use GetAssembly - that may force the completion of a load
Copy link
Member

Choose a reason for hiding this comment

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

The comment now contradicts the code... ?

Copy link
Member Author

Choose a reason for hiding this comment

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

Right. I think the comment was not correct for quite a while. There were no sideeffects with GetCurrentAssembly either. Perhaps some time ago there was a distinction.

@vitek-karas
Copy link
Member

I haven't looked through everything fully yet, but I'm wondering - can you point me to the place where we already have a check which fails to load assemblies with multiple modules?

I'm also wondering if we should somehow adapt managed reflection APIs accordingly - like obsolete some of the APIs which handle multi-module assemblies and such.
Also - what about Mono?

@VSadov
Copy link
Member Author

VSadov commented Jan 3, 2022

LoadModule never returns an actual value -

DomainFile *Module::LoadModule(AppDomain *pDomain, mdFile kFile)

All code paths throw some kind of exception. The most "normal" outcome is COR_E_MULTIMODULEASSEMBLIESDIALLOWED

@vitek-karas
Copy link
Member

It's interesting that we go through the trouble of trying to load it - only to get a name to include in the exception. For another time 😄

@VSadov
Copy link
Member Author

VSadov commented Jan 3, 2022

Adapting managed API would be an interesting task. The abstraction of a module kind of still exists. Assembly has identity and module contain implementation. It is just that we allow only one module per assembly now, which means assembly and module are always the same file.

In some reflection APIs like in dynamic codegen the layering is very clear - an assembly contains modules (only one now, I assume) and that contains code.
We will need to be careful with what scenarios would be deprecated, since from API perspective modules are not completely dead.

@vitek-karas
Copy link
Member

Maybe there is nothing to do on the managed APIs (other than updating docs)... I was just thinking about all of the other things this may impact.

@VSadov
Copy link
Member Author

VSadov commented Jan 3, 2022

BTW DomainAssembly here is not the best name IMO, but the least confusing for now. The thing roughly represents a "module for a given assembly when [being] loaded into a domain". We have another thing called Module, which also represents a loaded module.

It feels like the responsibilities of Assembly/ DomainAssembly/ Module could be rearranged a bit and maybe even fit into fewer classes and then renamed appropriately. If we do that, it would not be in this PR.

@VSadov
Copy link
Member Author

VSadov commented Jan 11, 2022

I think the PR is at the logical point where it makes sense to review/merge.
@elinor-fung @vitek-karas - please take a look. Thanks!!

@VSadov
Copy link
Member Author

VSadov commented Jan 21, 2022

Rebased onto recent main and fixed accumulated merge conflicts.

@VSadov
Copy link
Member Author

VSadov commented Jan 24, 2022

I think the PR is at the logical point where it makes sense to review/merge.
@elinor-fung @vitek-karas - please take a look. Thanks!!

Copy link
Member

@elinor-fung elinor-fung left a comment

Choose a reason for hiding this comment

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

where we already have a check which fails to load assemblies with multiple modules

Do we have tests for this? Haven't made it through everything yet, but if we don't have existing tests, it might be good to add something to verify the expected (failure) behaviour.

Maybe there is nothing to do on the managed APIs (other than updating docs)... I was just thinking about all of the other things this may impact.

+1 for updating docs. I think the APIs should behave the same before/after this PR (right?), but it is a good opportunity to think through what docs might need updating. Some possible non-documented cases that I believe are not supported and will error:

  • AssemblyBuilder.DefineDynamicModule: if a module is already defined (even if it is a different name)
  • Assembly.GetModules: if not reflection-only and has multiple modules
  • DllImportAttribute: using assembly display name as part of DLL name per remarks

src/coreclr/vm/methoditer.h Outdated Show resolved Hide resolved
src/coreclr/vm/appdomain.hpp Outdated Show resolved Hide resolved
src/coreclr/vm/assembly.hpp Outdated Show resolved Hide resolved
src/coreclr/vm/assembly.hpp Show resolved Hide resolved
src/coreclr/vm/appdomain.cpp Outdated Show resolved Hide resolved
src/coreclr/vm/appdomain.hpp Outdated Show resolved Hide resolved
src/coreclr/nativeaot/Runtime/eventtrace.cpp Outdated Show resolved Hide resolved
src/coreclr/vm/appdomain.cpp Outdated Show resolved Hide resolved
src/coreclr/debug/inc/dbgipcevents.h Outdated Show resolved Hide resolved
src/coreclr/debug/inc/dbgipcevents.h Outdated Show resolved Hide resolved
src/coreclr/debug/daccess/dacimpl.h Show resolved Hide resolved
Comment on lines +507 to 511
// The runtime has the notion of "DomainAssembly", which is 1:1 with DebuggerModule
// and thus 1:1 with CordbModule. The CordbModule hash table on the RS now uses
// the DomainFile as the key instead of DebuggerModule. This is a temporary
// the DomainAssembly as the key instead of DebuggerModule. This is a temporary
// workaround to facilitate the removal of DebuggerModule.
// </TODO>
Copy link
Member

Choose a reason for hiding this comment

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

Does this TODO still make sense now that we don't have shared/multiple domains?
cc @dotnet/dotnet-diag

Copy link
Member Author

Choose a reason for hiding this comment

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

A TODO from 2002 is most certainly obsolete. I would not know what needs to be done here though. I just tried not to mention things that no longer exist.

I like the part that TODO is tagged by a date. :-)

Copy link
Member

Choose a reason for hiding this comment

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

DebuggerModule has had a few more things that started hanging off it. It'd be nice to clean but it hasn't happened. I think this crumble is a good hint of what to update in the case of such a transition.

src/coreclr/debug/ee/debugger.cpp Outdated Show resolved Hide resolved
@VSadov
Copy link
Member Author

VSadov commented Jan 27, 2022

+1 for updating docs. I think the APIs should behave the same before/after this PR (right?), but it is a good opportunity to think through what docs might need updating. Some possible non-documented cases that I believe are not supported and will error:

AssemblyBuilder.DefineDynamicModule: if a module is already defined (even if it is a different name)
Assembly.GetModules: if not reflection-only and has multiple modules
DllImportAttribute: using assembly display name as part of DLL name per remarks

I think this is better handled as a separate workitem just to separate it from mostly mechanical refactoring.

I think this change does not change any behavior. It is a halting problem to prove that, but from the nature of the changes the chances are relatively low.
That is not to say we do not have bugs or behavior is indeed as we think it is. It would definitely make sense to review scenarios related to multimodule assemblies, fix documentation, write some tests, fix bugs.

@VSadov
Copy link
Member Author

VSadov commented Jan 27, 2022

I have added a workitem #64367 to track reviewing behaviors related to multimodule assemblies.

@VSadov
Copy link
Member Author

VSadov commented Jan 29, 2022

Thanks!!!

@VSadov VSadov merged commit d603356 into dotnet:main Jan 29, 2022
@VSadov VSadov deleted the aloader06 branch January 29, 2022 01:00
@ghost ghost locked as resolved and limited conversation to collaborators Feb 28, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants