Skip to content

Conversation

@jonathanpeppers
Copy link
Member

Context: dotnet/maui#31316 (comment)

In comparing apk sizes .NET 9 vs .NET 10, we found regressions in IL size, such as:

+      76,464 lib/x86_64/libaot-Mono.Android.dll.so

Comparing, just the MSIL (not AOT output) some examples are Java.IO.File constructors:

.NET 9:
    File()
    File(nint, JniHandleOwnership)
    File(string)
.NET 10:
    File()
    File(nint, JniHandleOwnership)
    File(File?, string)
    File(string?, string)
    File(string)
    File(URI)

When passing -p:LinkerDumpDependencies=true, we can get some output from ILLink:

<edge mark="1" b="MethodSpec:T Java.Lang.Object::GetObject&lt;Java.IO.File&gt;(System.IntPtr,Android.Runtime.JniHandleOwnership)" e="TypeDef:Java.IO.File" />
<edge mark="1" b="Method:Java.IO.File Android.Content.ContextInvoker::get_CacheDir()" e="Method:System.Void Java.IO.File::.ctor(System.IntPtr,Android.Runtime.JniHandleOwnership)" />
<edge mark="1" b="Method:Java.IO.File Android.Content.ContextInvoker::get_CacheDir()" e="Method:System.Void Java.IO.File::.cctor()" />
<edge mark="1" b="Method:Java.IO.File Android.Content.ContextInvoker::get_CacheDir()" e="Method:System.Void Java.IO.File::.ctor(Java.IO.File,System.String)" />
<edge mark="1" b="Method:Java.IO.File Android.Content.ContextInvoker::get_CacheDir()" e="Method:System.Void Java.IO.File::.ctor(System.String,System.String)" />
<edge mark="1" b="Method:Java.IO.File Android.Content.ContextInvoker::get_CacheDir()" e="Method:System.Void Java.IO.File::.ctor(System.String)" />
<edge mark="1" b="Method:Java.IO.File Android.Content.ContextInvoker::get_CacheDir()" e="Method:System.Void Java.IO.File::.ctor(Java.Net.URI)" />

Which leads me think this change is the cause:

Let's try just undoing the change and see if there is any impact on NativeAOT.

TODO: apk size difference

Context: dotnet/maui#31316 (comment)

In comparing apk sizes .NET 9 vs .NET 10, we found regressions in IL
size, such as:

    +      76,464 lib/x86_64/libaot-Mono.Android.dll.so

Comparing, just the MSIL (not AOT output) some examples are
`Java.IO.File` constructors:

    .NET 9:
        File()
        File(nint, JniHandleOwnership)
        File(string)
    .NET 10:
        File()
        File(nint, JniHandleOwnership)
        File(File?, string)
        File(string?, string)
        File(string)
        File(URI)

When passing `-p:LinkerDumpDependencies=true`, we can get some output
from `ILLink`:

    <edge mark="1" b="MethodSpec:T Java.Lang.Object::GetObject&lt;Java.IO.File&gt;(System.IntPtr,Android.Runtime.JniHandleOwnership)" e="TypeDef:Java.IO.File" />
    <edge mark="1" b="Method:Java.IO.File Android.Content.ContextInvoker::get_CacheDir()" e="Method:System.Void Java.IO.File::.ctor(System.IntPtr,Android.Runtime.JniHandleOwnership)" />
    <edge mark="1" b="Method:Java.IO.File Android.Content.ContextInvoker::get_CacheDir()" e="Method:System.Void Java.IO.File::.cctor()" />
    <edge mark="1" b="Method:Java.IO.File Android.Content.ContextInvoker::get_CacheDir()" e="Method:System.Void Java.IO.File::.ctor(Java.IO.File,System.String)" />
    <edge mark="1" b="Method:Java.IO.File Android.Content.ContextInvoker::get_CacheDir()" e="Method:System.Void Java.IO.File::.ctor(System.String,System.String)" />
    <edge mark="1" b="Method:Java.IO.File Android.Content.ContextInvoker::get_CacheDir()" e="Method:System.Void Java.IO.File::.ctor(System.String)" />
    <edge mark="1" b="Method:Java.IO.File Android.Content.ContextInvoker::get_CacheDir()" e="Method:System.Void Java.IO.File::.ctor(Java.Net.URI)" />

Which leads me think this change is the cause:

* f800c1a#diff-4d71f7134c2b6e3b0d272a17fc6c9261108c518ad039df1566b07205f6be06e9R146

Let's try just undoing the change and see if there is any impact on
NativeAOT.

TODO: apk size difference
@jonathanpeppers
Copy link
Member Author

jonathanpeppers commented Aug 27, 2025

This fixes those additional ctors:

image

Gets back some of the file size:

  -       5,392 lib/arm64-v8a/libaot-Mono.Android.dll.so
  -      33,800 lib/arm64-v8a/libassemblies.arm64-v8a.blob.so
  -     108,688 Shared libraries -0.49% (of 22,073,984)

@jonathanpeppers jonathanpeppers marked this pull request as ready for review August 27, 2025 21:31
@jonathanpeppers
Copy link
Member Author

Ok, here is the exact comparison of just this change:

> apkdiff -f C:\Users\jopepper\Desktop\android\before.apk C:\Users\jopepper\Desktop\android\after.apk
Size difference in bytes ([*1] apk1 only, [*2] apk2 only):
  -       2,096 lib/arm64-v8a/libxamarin-app.so
  -       3,512 classes2.dex
  -       5,256 lib/arm64-v8a/libaot-Mono.Android.dll.so
  -      24,872 lib/arm64-v8a/libassemblies.arm64-v8a.blob.so
Summary:
  +           0 Other entries 0.00% (of 3,639,177)
  -       3,512 Dalvik executables -0.02% (of 15,351,816)
  -      32,224 Shared libraries -0.15% (of 21,997,520)
  -      24,576 Package size difference -0.13% (of 18,677,842)

I think there are more regressions in IL size, I'll investigate next.

@grendello grendello merged commit c6f11bb into main Aug 28, 2025
59 checks passed
@grendello grendello deleted the dev/peppers/trimmer-attributes branch August 28, 2025 07:59
@github-actions github-actions bot locked and limited conversation to collaborators Sep 27, 2025
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.

4 participants