Skip to content

Conversation

huoyaoyuan
Copy link
Member

No description provided.

@dotnet-policy-service dotnet-policy-service bot added the community-contribution Indicates that the PR has been added by a community member label Jun 10, 2025
Copy link
Contributor

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

…tadata/NativeFormat/Writer/NativeMetadataWriter.cs

Co-authored-by: Austin Wise <[email protected]>
using System.Reflection;
using Debug = System.Diagnostics.Debug;
using ConditionalAttribute = System.Diagnostics.ConditionalAttribute;
using Internal.LowLevelLinq;
Copy link
Member

Choose a reason for hiding this comment

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

What's the impact of switching away from Internal.LowLevelLinq on ilc compiler binary size? Could you please share ilc.exe binary size before/after this PR?

Copy link
Member Author

Choose a reason for hiding this comment

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

ilc is already using System.Linq in other components including object writer and dependency analysis. Will post the result later.

Copy link
Member Author

Choose a reason for hiding this comment

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

12685KB -> 12735KB, it seems that size-optimized LINQ is still larger than naive implementation?

Copy link
Member Author

Choose a reason for hiding this comment

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

It's now 12681KB in latest commit.

Copy link
Member

Choose a reason for hiding this comment

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

Yes, the size-optimized LINQ is still a ton of code. It just avoids non-linear code size growth.

What would it take to delete LowLevelLinq completely? I think we either want to keep it; or delete it completely and take some size hit. Deleting it partially is kind of the worst of both worlds.

Copy link
Member Author

Choose a reason for hiding this comment

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

What would it take to delete LowLevelLinq completely?

It could even improve size a bit. There are only a few use cases of it in both reflection runtime and ilc. Most of them are almost unnecessary and can be changed by exposing arrays instead of IEnumerable. Only very few cases need to be converted to manual for loops.

// The .NET Foundation licenses this file to you under the MIT license.

using Internal.LowLevelLinq;
using System.Linq;
Copy link
Member

Choose a reason for hiding this comment

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

We can avoid LINQ with a file local helper:

file static class FormatHelper
{
    public static string Get<T>(T[] values, string label)
    {
        if (values == null || values.Length == 0)
            return $"({label}[]) {{}}";

        var result = $"({label}[]) {{{values[0]}";
        for (int i = 1; i < values.Length; i++)
        {
            result += $", {values[i]}";
        }

        result += "}";

        return result;
    }
}

@huoyaoyuan
Copy link
Member Author

ILC size is 12685KB->12639KB for now. I think it's a reviewable state without too much change.

if ((value & SignatureCallingConvention.UnmanagedCallingConventionMask) != default)
{
value &= ~SignatureCallingConvention.UnmanagedCallingConventionMask;
values.Add((value & SignatureCallingConvention.UnmanagedCallingConventionMask).ToString());
Copy link
Member

Choose a reason for hiding this comment

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

If I am reading this correctly, the previous line is going to clean all bits in UnmanagedCallingConventionMask and so this line is always going to print 0 or nothing.

Copy link
Member Author

Choose a reason for hiding this comment

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

This is a copy-paste error. The string should be appended before clearing the flag.

values.Add((value & SignatureCallingConvention.UnmanagedCallingConventionMask).ToString());
}
values.Add(value.ToString());
return string.Join(" | ", values);
Copy link
Member

Choose a reason for hiding this comment

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

Nit: This was wrapped in [ and ] before. Does the output look better without it?

Copy link
Member Author

Choose a reason for hiding this comment

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

Well I totally missed that during refactor.

@jkotas
Copy link
Member

jkotas commented Jun 21, 2025

/azp run runtime-nativeaot-outerloop

Copy link

Azure Pipelines successfully started running 1 pipeline(s).

Copy link
Member

@jkotas jkotas left a comment

Choose a reason for hiding this comment

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

Thanks

@jkotas
Copy link
Member

jkotas commented Jun 22, 2025

/ba-g known issue #116897

@jkotas jkotas merged commit b584719 into dotnet:main Jun 22, 2025
107 of 117 checks passed
@huoyaoyuan huoyaoyuan deleted the ilc-unused branch June 22, 2025 07:05
@github-actions github-actions bot locked and limited conversation to collaborators Jul 22, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-NativeAOT-coreclr community-contribution Indicates that the PR has been added by a community member
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants