dotnet / runtime

.NET is a cross-platform runtime for cloud, mobile, desktop, and IoT apps.
https://docs.microsoft.com/dotnet/core/
MIT License
15.24k stars 4.73k forks source link

[question] bcl between different instruction package like Microsoft.NETCore.App.Runtime.Mono.win-x64 and Microsoft.NETCore.App.Runtime.Mono.win-x86 #62953

Open srxqds opened 2 years ago

srxqds commented 2 years ago

hi, the bcl except System.Private.CoreLib.dll have differences between different platforms and instructions, such as Microsoft.NETCore.App.Runtime.Mono.win-x64, Microsoft.NETCore.App.Runtime.Mono.win-x86 and Microsoft.NETCore.App.Runtime.Mono.android-arm64?

how can we know they are the same or different, we are embedding mono, if it is same between x64 and x86 we can use one library to share between different instructions to reduce app size and consistent assembly load code on different platforms.

for example, the System.Collections.dll library

if it is the same on all the platforms. I can use only one:

is there any tool to analyze them to check they are using the same code?

dotnet-issue-labeler[bot] commented 2 years ago

I couldn't figure out the best area label to add to this issue. If you have write-permissions please help me learn by adding exactly one area label.

akoeplinger commented 2 years ago

Unlike the legacy Mono from https://github.com/mono/mono the class libraries in dotnet/runtime can be OS and architecture specific, i.e. contain different IL between x86 and x64. Right now this is only the case for System.Private.Corelib.dll, though this is not guaranteed.

The Xamarin Android team ran into the same issue and came up with this solution to deduplicate assemblies: https://github.com/xamarin/xamarin-android/blob/e7722fb76f973101ec183549bbba402a60942db6/src/Xamarin.Android.Build.Tasks/Tasks/ProcessAssemblies.cs#L118-L168

It essentially groups assemblies by file name, looks at the MVID and if there's more than one MVID per assembly then the assembly is architecture-specific.

filipnavara commented 2 years ago

This was also encountered with the universal app support on macOS/iOS where Xamarin tries to merge the assemblies. Currently we end up with pretty long list of different per-platform assemblies (128 of those are from dotnet/runtime). Some of the differences are from PDB paths (eg. Xamarin.Mac.dll, already mentioned in https://github.com/xamarin/xamarin-macios/issues/12607) but it turns out that most actually are significantly different [at binary level].

For example, System.Collections.dll in osx-x64 is 267,368 bytes and osx-arm64 version is 308,848 bytes. Running dotnet ildiff on the two assemblies shows that the IL is essentially identical (only RVA offsets in the comments are different; assembly attributes and versions are identical). PE header has different architecture and timestamps (it's a hash, so that's kinda obvious). This leads me to believe that there is some more significant mix-up going on. Either the assemblies are really different and compiled with different options, or the SDK is pulling them from wrong packages.

filipnavara commented 2 years ago

Turns out that the assembly size/content difference we hit on osx-x64/osx-arm64 is from the R2R images used by CoreCLR and Crossgen2. It should not affect the Mono runtime packs but it's something interesting to keep in mind.