-
Notifications
You must be signed in to change notification settings - Fork 4.8k
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
Create a managed implementation of assembly binder #91400
Conversation
Tagging subscribers to this area: @vitek-karas, @agocke, @VSadov Issue Details
I've ported the types under The logic is ported closely from C++ and aims line-to-line match, to keep the behavior. Initially I want to convert all the HRESULTs to exceptions, but it's not practical to use exception in control logic of binder, so I kept HRESULTs in AssemblyBinderCommon. /cc @jkotas Is this in the desired direction? I haven't do anything around managed/unmanaged boundary. I think code should be ported to managed, until something we don't want.
|
This is good raw material. Creating a clean managed/unmanaged boundary is probably going to be the harder part. Some thoughts:
|
src/coreclr/System.Private.CoreLib/src/Internal/Runtime/Binder/AssemblyName.cs
Outdated
Show resolved
Hide resolved
src/coreclr/System.Private.CoreLib/src/Internal/Runtime/Binder/ApplicationContext.cs
Outdated
Show resolved
Hide resolved
int* dwPAFlags = stackalloc int[2]; | ||
using IMdInternalImport pIMetaDataAssemblyImport = BinderAcquireImport(pPEImage, dwPAFlags); | ||
|
||
Architecture = AssemblyBinderCommon.TranslatePEToArchitectureType(dwPAFlags); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The managed binder should not need to deal with image architectures. The unmanaged runtime should validate very early whether the image is good for current architecture (and reject it if it is not). By the time we get to the managed binder, we should know that the image architecture is good.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I started with focusing the data structures, and did not look at the caller. Leaving the cleanup later should be fine, since cleaning managed code is easy.
@elinor-fung FYI |
Good points for the behaviors that we don't need in managed binder. I'm aiming for a working POC first, and not tweaking yet. Records are just simplification since I don't want to write GetHashCode etc. first. Rough thought of steps:
Questions:
|
I've done some measurement about working set: It's about 3.5MB of total regression comparing to main for a given run. Break down by vmmap: So one obvious conclusion is that some globalization related code are touched unintentionally. Setting globalization invariant mode doesn't change the regression though. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are multiple cases in the code that might trigger globalization code
src/coreclr/System.Private.CoreLib/src/System/Runtime/Loader/ApplicationContext.cs
Outdated
Show resolved
Hide resolved
src/coreclr/System.Private.CoreLib/src/System/Runtime/Loader/AssemblyName.cs
Outdated
Show resolved
Hide resolved
src/coreclr/System.Private.CoreLib/src/System/Runtime/Loader/AssemblyName.cs
Outdated
Show resolved
Hide resolved
src/coreclr/System.Private.CoreLib/src/System/Runtime/Loader/AssemblyName.cs
Outdated
Show resolved
Hide resolved
Draft Pull Request was automatically closed for 30 days of inactivity. Please let us know if you'd like to reopen it. |
Keep open since it's functionally complete. |
Draft Pull Request was automatically closed for 30 days of inactivity. Please let us know if you'd like to reopen it. |
Status report:Working Set:About 15.2 MB -> 16.3 MB under default configuration. Start time:Measured with File size:-39KB in coreclr.dll, +92KB in CoreLib (R2R). There are still some space of dead code for optimization, but I kept this PR as close to native code as possible to help reviewing. |
if (outPath.EndsWith(".ni.dll", StringComparison.OrdinalIgnoreCase) | ||
|| outPath.EndsWith(".ni.exe", StringComparison.OrdinalIgnoreCase)) | ||
{ | ||
simpleName = outPath[iSimpleNameStart..^7]; | ||
isNativeImage = true; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is ni.dll
still a thing? I remember it's output of NGen.
Even if it's still a thing, we should probably remove this too because the shared framework (TPA) does not contain any ni files.
The performance difference is negligible though.
I'm going to abandon this for now. Per offline discussion with @jkotas , there's no net improvement for this PR. The newly created managed-native boundaries are quite a lot. It's not easy to eliminate them since many of the native components are used by diagnostics interfaces like DAC, or bootstrap path for executing managed application. There's also duplications between managed and native code, and potential discrepancies with CoreLib loading. If anyone want to revisit this in the future, consider to create a branch in runtimelab. There are also improvable small points discovered during this. Although not a successful experiment, still great thanks to @jkotas for assisting on this! |
@huoyaoyuan thanks for your effort! I’m sure it will be useful for the next changes in this area. |
#85558 (comment)
I've ported the types under
BINDER_SPACE::
, and a large portion of binding logic in assemblybindercommon.cpp. I also created a disabled feature switch to guard the code.The logic is ported closely from C++ and aims line-to-line match, to keep the behavior. Initially I want to convert all the HRESULTs to exceptions, but it's not practical to use exception in control logic of binder, so I kept HRESULTs in AssemblyBinderCommon.
/cc @jkotas
Is this in the desired direction? I haven't do anything around managed/unmanaged boundary. I think code should be ported to managed, until something we don't want.