Skip to content

Conversation

@huoyaoyuan
Copy link
Member

Extracted from #109114

The merging and _isReferenceTypeGCLayout paths looks unused. Not sure whether I missed anything.

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

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

// Sentinel static to allow us to initialize _instanceLayout to something
// and then detect that InstanceGCLayout should return null
private static LowLevelList<bool> s_emptyLayout = new LowLevelList<bool>();
#pragma warning disable CA1825 // Can't use generic Array.Empty<T> within type loader
Copy link
Member

Choose a reason for hiding this comment

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

This is not the case anymore. It is fine use Array.Empty here.

@huoyaoyuan
Copy link
Member Author

Test failure is #116261

// Sentinel static to allow us to initialize _instanceLayout to something
// and then detect that InstanceGCLayout should return null
private static LowLevelList<bool> s_emptyLayout = new LowLevelList<bool>();
internal static readonly bool[] s_emptyLayout = [];
Copy link
Member

Choose a reason for hiding this comment

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

You should not need to cache in a static field - it is a deoptimization to cache 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.

The empty array instance is used as a sentinel and compared in reference. If WriteGCDescToBitfield produces empty layout, it may be treated differently. Comparing to the collection literal expression looks weird here.

}

/// <summary>
/// Writes this layout to the given bitfield.
Copy link
Member

Choose a reason for hiding this comment

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

There is no "given bitfield" anymore. This comment should be updated.

Also, should the method be renamed to GetBitField? It is not necessarily "writing to" anything.


if (IsNone)
return;
return TypeBuilderState.s_emptyLayout;
Copy link
Member

Choose a reason for hiding this comment

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

I think this sentinel should be kelp private to TypeBuilderState. This check can deleted here - the one place that calls this method does this only when IsNone returns false.

}

private static unsafe int CreateGCDesc(LowLevelList<bool> bitfield, int size, bool isValueType, bool isStatic, void* gcdesc)
private static unsafe int CreateGCDesc(bool[] bitfield, int size, bool isValueType, bool isStatic, void* gcdesc)
Copy link
Member

Choose a reason for hiding this comment

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

This method looks unreachable given that InstanceGCLayout only returns non-null layout for arrays. Delete 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.

It's also called in EETypeCreator.CreateEETypeWorker, which should be reachable.

Copy link
Member

Choose a reason for hiding this comment

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

I believe that the other call is unreachable as well. One of them computes just the size, the other one (that you have deleted here) fills in the memory that was allocated based the size returned from the first call.

Copy link
Member Author

Choose a reason for hiding this comment

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

CreateEETypeWorker calls GetInstanceGCDescSize for size and CreateInstanceGCDesc for content. Both methods are called once now.

Copy link
Member

@jkotas jkotas Jun 7, 2025

Choose a reason for hiding this comment

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

There is only one place in GetInstanceGCDescSize that calls CreateGCDesc. My point is that that codepath is unreachable and it can be deleted, in similar way how you deleted it CreateGCDesc from CreateInstanceGCDesc.

If I am missing something and CreateGCDesc is still reachable, it would be useful to find a test that hits 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.

Yes, the code within GetInstanceGCDescSize also has a dead path. Now the control flow should be the same with CreateInstanceGCDesc.

@jkotas
Copy link
Member

jkotas commented Jun 7, 2025

/azp run runtime-nativeaot-outerloop

@azure-pipelines
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 8, 2025

/ba-g deadletter

@jkotas jkotas merged commit 0f2bfae into dotnet:main Jun 8, 2025
111 of 117 checks passed
@huoyaoyuan huoyaoyuan deleted the gclayout branch June 8, 2025 02:37
@github-actions github-actions bot locked and limited conversation to collaborators Jul 8, 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.

2 participants