From 819d9e852583b97f4d6bd9ba99db0a4b24438537 Mon Sep 17 00:00:00 2001 From: Huo Yaoyuan Date: Mon, 7 Jul 2025 17:30:36 +0800 Subject: [PATCH 1/7] Use List for reference types --- .../Extensions/NonPortable/CustomAttributeSearcher.cs | 2 +- .../System/Reflection/Runtime/General/NamespaceChain.cs | 2 +- .../src/Internal/Runtime/TypeLoader/TypeBuilder.cs | 8 ++++---- .../src/Internal/TypeSystem/TypeSystemContext.Runtime.cs | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Reflection/Extensions/NonPortable/CustomAttributeSearcher.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Reflection/Extensions/NonPortable/CustomAttributeSearcher.cs index 8249b4c58a32d6..be481f70d12017 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Reflection/Extensions/NonPortable/CustomAttributeSearcher.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Reflection/Extensions/NonPortable/CustomAttributeSearcher.cs @@ -110,7 +110,7 @@ public virtual E GetParent(E e) // private IEnumerable GetMatchingCustomAttributesIterator(E element, Func passesFilter, bool inherit) { - LowLevelList immediateResults = new LowLevelList(); + List immediateResults = new List(); foreach (CustomAttributeData cad in GetDeclaredCustomAttributes(element)) { if (passesFilter(cad.AttributeType)) diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/General/NamespaceChain.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/General/NamespaceChain.cs index ff812387e04ddc..ce53181af13e72 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/General/NamespaceChain.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/General/NamespaceChain.cs @@ -22,7 +22,7 @@ internal NamespaceChain(MetadataReader reader, NamespaceDefinitionHandle innerMo NamespaceDefinition currentNamespaceDefinition = innerMostNamespaceHandle.GetNamespaceDefinition(reader); ConstantStringValueHandle currentNameHandle = currentNamespaceDefinition.Name; Handle currentNamespaceHandle; - LowLevelList names = new LowLevelList(); + List names = new List(); for (; ; ) { string name = currentNameHandle.GetStringOrNull(reader); diff --git a/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeBuilder.cs b/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeBuilder.cs index 6f8b02d93ead60..6bb1e2e3410191 100644 --- a/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeBuilder.cs +++ b/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeBuilder.cs @@ -26,11 +26,11 @@ public TypeBuilder() /// public static unsafe int ClassConstructorOffset => -sizeof(System.Runtime.CompilerServices.StaticClassConstructionContext); - private LowLevelList _typesThatNeedTypeHandles = new LowLevelList(); + private List _typesThatNeedTypeHandles = new List(); - private LowLevelList _methodsThatNeedDictionaries = new LowLevelList(); + private List _methodsThatNeedDictionaries = new List(); - private LowLevelList _typesThatNeedPreparation; + private List _typesThatNeedPreparation; #if DEBUG private bool _finalTypeBuilding; @@ -88,7 +88,7 @@ public void RegisterForPreparation(TypeDesc type) if (type.IsCanonicalSubtype(CanonicalFormKind.Any)) return; - _typesThatNeedPreparation ??= new LowLevelList(); + _typesThatNeedPreparation ??= new List(); _typesThatNeedPreparation.Add(type); } diff --git a/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/TypeSystem/TypeSystemContext.Runtime.cs b/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/TypeSystem/TypeSystemContext.Runtime.cs index 6391cf78abaa65..dd77b3e5ad6a5a 100644 --- a/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/TypeSystem/TypeSystemContext.Runtime.cs +++ b/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/TypeSystem/TypeSystemContext.Runtime.cs @@ -511,7 +511,7 @@ public virtual int LoadFactor } } - private LowLevelList _typesToFlushTypeSystemStateFrom; + private List _typesToFlushTypeSystemStateFrom; /// /// Register the types that will get their attached TypeSystemState flushed if the @@ -519,7 +519,7 @@ public virtual int LoadFactor /// internal void RegisterTypeForTypeSystemStateFlushing(TypeDesc type) { - _typesToFlushTypeSystemStateFrom ??= new LowLevelList(); + _typesToFlushTypeSystemStateFrom ??= new List(); _typesToFlushTypeSystemStateFrom.Add(type); } From 80f9229adeae569da24a021ae9dd083a9ff9c903 Mon Sep 17 00:00:00 2001 From: Huo Yaoyuan Date: Sun, 6 Jul 2025 11:39:52 +0800 Subject: [PATCH 2/7] Remove chunk allocation in FunctionPointerOps --- .../CompilerServices/FunctionPointerOps.cs | 36 ++++--------------- 1 file changed, 6 insertions(+), 30 deletions(-) diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/CompilerServices/FunctionPointerOps.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/CompilerServices/FunctionPointerOps.cs index c0bceb7963c8ad..e011a5fe6739d3 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/CompilerServices/FunctionPointerOps.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/CompilerServices/FunctionPointerOps.cs @@ -49,10 +49,7 @@ public override int GetHashCode() public IntPtr InstantiationArgument; } - private static uint s_genericFunctionPointerNextIndex; - private const uint c_genericDictionaryChunkSize = 1024; - private static LowLevelList s_genericFunctionPointerCollection = new LowLevelList(); - private static LowLevelDictionary s_genericFunctionPointerDictionary = new LowLevelDictionary(); + private static LowLevelDictionary s_genericFunctionPointerDictionary = new LowLevelDictionary(); public static unsafe IntPtr GetGenericMethodFunctionPointer(IntPtr canonFunctionPointer, IntPtr instantiationArgument) { @@ -69,38 +66,17 @@ public static unsafe IntPtr GetGenericMethodFunctionPointer(IntPtr canonFunction InstantiationArgument = instantiationArgument }; - uint index = 0; - if (!s_genericFunctionPointerDictionary.TryGetValue(key, out index)) + if (!s_genericFunctionPointerDictionary.TryGetValue(key, out IntPtr descriptor)) { - // Capture new index value - index = s_genericFunctionPointerNextIndex; + descriptor = (IntPtr)NativeMemory.Alloc((uint)sizeof(GenericMethodDescriptor)); - int newChunkIndex = (int)(index / c_genericDictionaryChunkSize); - uint newSubChunkIndex = index % c_genericDictionaryChunkSize; - - // Generate new chunk if existing chunks are insufficient - if (s_genericFunctionPointerCollection.Count <= newChunkIndex) - { - Debug.Assert(newSubChunkIndex == 0); - - // New generic descriptors are allocated on the native heap and not tracked in the GC. - IntPtr pNewMem = (IntPtr)NativeMemory.Alloc(c_genericDictionaryChunkSize, (nuint)sizeof(GenericMethodDescriptor)); - s_genericFunctionPointerCollection.Add(pNewMem); - } - - ((GenericMethodDescriptor*)s_genericFunctionPointerCollection[newChunkIndex])[newSubChunkIndex] = + *(GenericMethodDescriptor*)descriptor = new GenericMethodDescriptor(canonFunctionPointer, instantiationArgument); - s_genericFunctionPointerDictionary.LookupOrAdd(key, index); - - // Now that we can no longer have failed, update the next index. - s_genericFunctionPointerNextIndex++; + s_genericFunctionPointerDictionary.LookupOrAdd(key, descriptor); } - // Lookup within list - int chunkIndex = (int)(index / c_genericDictionaryChunkSize); - uint subChunkIndex = index % c_genericDictionaryChunkSize; - GenericMethodDescriptor* genericFunctionPointer = &((GenericMethodDescriptor*)s_genericFunctionPointerCollection[chunkIndex])[subChunkIndex]; + GenericMethodDescriptor* genericFunctionPointer = (GenericMethodDescriptor*)descriptor; Debug.Assert(canonFunctionPointer == genericFunctionPointer->MethodFunctionPointer); Debug.Assert(instantiationArgument == genericFunctionPointer->InstantiationArgument); From cb5ef4a8023982443846c6c57c9be080a15b4fbd Mon Sep 17 00:00:00 2001 From: Huo Yaoyuan Date: Wed, 13 Aug 2025 01:02:18 +0800 Subject: [PATCH 3/7] Remove LowLevelList --- .../Collections/Generic/LowLevelList.cs | 196 ------------------ .../src/System.Private.CoreLib.csproj | 3 - ...System.Private.Reflection.Execution.csproj | 5 +- .../src/System.Private.TypeLoader.csproj | 5 +- 4 files changed, 2 insertions(+), 207 deletions(-) delete mode 100644 src/coreclr/nativeaot/Common/src/System/Collections/Generic/LowLevelList.cs diff --git a/src/coreclr/nativeaot/Common/src/System/Collections/Generic/LowLevelList.cs b/src/coreclr/nativeaot/Common/src/System/Collections/Generic/LowLevelList.cs deleted file mode 100644 index fc068b9c31e009..00000000000000 --- a/src/coreclr/nativeaot/Common/src/System/Collections/Generic/LowLevelList.cs +++ /dev/null @@ -1,196 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -/*============================================================ -** -** -** Private version of List for internal System.Private.CoreLib use. This -** permits sharing more source between BCL and System.Private.CoreLib (as well as the -** fact that List is just a useful class in general.) -** -** This does not strive to implement the full api surface area -** (but any portion it does implement should match the real List's -** behavior.) -** -** This file is a subset of System.Collections\System\Collections\Generics\List.cs -** and should be kept in sync with that file. -** -===========================================================*/ - -using System; -using System.Diagnostics; - -namespace System.Collections.Generic -{ - // Implements a variable-size List that uses an array of objects to store the - // elements. A List has a capacity, which is the allocated length - // of the internal array. As elements are added to a List, the capacity - // of the List is automatically increased as required by reallocating the - // internal array. - // - // LowLevelList with no interface implementation minimizes both code and data size. - // Data size is smaller because there will be minimal virtual function table. - // Code size is smaller because only functions called will be in the binary. - [DebuggerDisplay("Count = {Count}")] - internal class LowLevelList - { - private const int _defaultCapacity = 4; - - protected T[] _items; - protected int _size; - protected int _version; - -#pragma warning disable CA1825 // avoid the extra generic instantiation for Array.Empty() - private static readonly T[] s_emptyArray = new T[0]; -#pragma warning restore CA1825 - - // Constructs a List. The list is initially empty and has a capacity - // of zero. Upon adding the first element to the list the capacity is - // increased to 4, and then increased in multiples of two as required. - public LowLevelList() - { - _items = s_emptyArray; - } - - // Constructs a List with a given initial capacity. The list is - // initially empty, but will have room for the given number of elements - // before any reallocations are required. - // - public LowLevelList(int capacity) - { - ArgumentOutOfRangeException.ThrowIfNegative(capacity); - - if (capacity == 0) - _items = s_emptyArray; - else - _items = new T[capacity]; - } - - // Constructs a List, copying the contents of the given collection. The - // size and capacity of the new list will both be equal to the size of the - // given collection. - // - public LowLevelList(IEnumerable collection) - { - ArgumentNullException.ThrowIfNull(collection); - - ICollection? c = collection as ICollection; - if (c != null) - { - int count = c.Count; - if (count == 0) - { - _items = s_emptyArray; - } - else - { - _items = new T[count]; - c.CopyTo(_items, 0); - _size = count; - } - } - else - { - _size = 0; - _items = s_emptyArray; - // This enumerable could be empty. Let Add allocate a new array, if needed. - // Note it will also go to _defaultCapacity first, not 1, then 2, etc. - - using (IEnumerator en = collection.GetEnumerator()) - { - while (en.MoveNext()) - { - Add(en.Current); - } - } - } - } - - // Gets and sets the capacity of this list. The capacity is the size of - // the internal array used to hold items. When set, the internal - // array of the list is reallocated to the given capacity. - // - public int Capacity - { - get - { - return _items.Length; - } - set - { - ArgumentOutOfRangeException.ThrowIfLessThan(value, _size); - - if (value != _items.Length) - { - if (value > 0) - { - T[] newItems = new T[value]; - Array.Copy(_items, 0, newItems, 0, _size); - _items = newItems; - } - else - { - _items = s_emptyArray; - } - } - } - } - - // Read-only property describing how many elements are in the List. - public int Count - { - get - { - return _size; - } - } - - // Sets or Gets the element at the given index. - // - public T this[int index] - { - get - { - // Following trick can reduce the range check by one - ArgumentOutOfRangeException.ThrowIfGreaterThanOrEqual((uint)index, (uint)_size, nameof(index)); - return _items[index]; - } - - set - { - ArgumentOutOfRangeException.ThrowIfGreaterThanOrEqual((uint)index, (uint)_size, nameof(index)); - _items[index] = value; - _version++; - } - } - - - // Adds the given object to the end of this list. The size of the list is - // increased by one. If required, the capacity of the list is doubled - // before adding the new element. - // - public void Add(T item) - { - if (_size == _items.Length) EnsureCapacity(_size + 1); - _items[_size++] = item; - _version++; - } - - // Ensures that the capacity of this list is at least the given minimum - // value. If the current capacity of the list is less than min, the - // capacity is increased to twice the current capacity or to min, - // whichever is larger. - private void EnsureCapacity(int min) - { - if (_items.Length < min) - { - int newCapacity = _items.Length == 0 ? _defaultCapacity : _items.Length * 2; - // Allow the list to grow to maximum possible capacity (~2G elements) before encountering overflow. - // Note that this check works even when _items.Length overflowed thanks to the (uint) cast - //if ((uint)newCapacity > Array.MaxLength) newCapacity = Array.MaxLength; - if (newCapacity < min) newCapacity = min; - Capacity = newCapacity; - } - } - } -} diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System.Private.CoreLib.csproj b/src/coreclr/nativeaot/System.Private.CoreLib/src/System.Private.CoreLib.csproj index 2c96332adf7d00..7bc062b816dc4d 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System.Private.CoreLib.csproj +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System.Private.CoreLib.csproj @@ -325,9 +325,6 @@ Utilities\TypeHashingAlgorithms.cs - - System\Collections\Generic\LowLevelList.cs - System\Collections\Generic\LowLevelDictionary.cs diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Execution/src/System.Private.Reflection.Execution.csproj b/src/coreclr/nativeaot/System.Private.Reflection.Execution/src/System.Private.Reflection.Execution.csproj index 86fb64fa51852c..1277108d457b42 100644 --- a/src/coreclr/nativeaot/System.Private.Reflection.Execution/src/System.Private.Reflection.Execution.csproj +++ b/src/coreclr/nativeaot/System.Private.Reflection.Execution/src/System.Private.Reflection.Execution.csproj @@ -1,4 +1,4 @@ - + @@ -56,9 +56,6 @@ System\NotImplemented.cs - - System\Collections\Generic\LowLevelList.cs - System\Collections\Generic\LowLevelDictionary.cs diff --git a/src/coreclr/nativeaot/System.Private.TypeLoader/src/System.Private.TypeLoader.csproj b/src/coreclr/nativeaot/System.Private.TypeLoader/src/System.Private.TypeLoader.csproj index 4599d9ea5fa789..b14c69d765daf6 100644 --- a/src/coreclr/nativeaot/System.Private.TypeLoader/src/System.Private.TypeLoader.csproj +++ b/src/coreclr/nativeaot/System.Private.TypeLoader/src/System.Private.TypeLoader.csproj @@ -1,4 +1,4 @@ - + disable TYPE_LOADER_IMPLEMENTATION;$(DefineConstants) @@ -35,9 +35,6 @@ TransitionBlock.cs - - LowLevelList.cs - MetadataBlob.cs From 5a7acc33bc8cb99b798fec9384b71e38f957fdb3 Mon Sep 17 00:00:00 2001 From: Huo Yaoyuan Date: Wed, 13 Aug 2025 01:04:01 +0800 Subject: [PATCH 4/7] Remove Empty.cs --- .../src/System/Collections/Generic/Empty.cs | 65 ------------------- ...System.Private.Reflection.Execution.csproj | 3 - 2 files changed, 68 deletions(-) delete mode 100644 src/coreclr/nativeaot/Common/src/System/Collections/Generic/Empty.cs diff --git a/src/coreclr/nativeaot/Common/src/System/Collections/Generic/Empty.cs b/src/coreclr/nativeaot/Common/src/System/Collections/Generic/Empty.cs deleted file mode 100644 index c2b9bbae1c6ea4..00000000000000 --- a/src/coreclr/nativeaot/Common/src/System/Collections/Generic/Empty.cs +++ /dev/null @@ -1,65 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using System.Collections; -using System.Collections.Generic; -using System.Diagnostics; - -namespace System.Collections.Generic -{ - // - // Helper class to store reusable empty IEnumerables. - // - internal static class Empty - { - // - // Returns a reusable empty IEnumerable (that does not secretly implement more advanced collection interfaces.) - // - public static IEnumerable Enumerable - { - get - { - return _enumerable; - } - } - - private sealed class EmptyEnumImpl : IEnumerable, IEnumerator - { - public IEnumerator GetEnumerator() - { - return this; - } - - IEnumerator IEnumerable.GetEnumerator() - { - return this; - } - - public T Current - { - get { throw new InvalidOperationException(); } - } - - object IEnumerator.Current - { - get { throw new InvalidOperationException(); } - } - - public bool MoveNext() - { - return false; - } - - public void Reset() - { - } - - public void Dispose() - { - } - } - - private static IEnumerable _enumerable = new EmptyEnumImpl(); - } -} diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Execution/src/System.Private.Reflection.Execution.csproj b/src/coreclr/nativeaot/System.Private.Reflection.Execution/src/System.Private.Reflection.Execution.csproj index 1277108d457b42..823a6e0564f095 100644 --- a/src/coreclr/nativeaot/System.Private.Reflection.Execution/src/System.Private.Reflection.Execution.csproj +++ b/src/coreclr/nativeaot/System.Private.Reflection.Execution/src/System.Private.Reflection.Execution.csproj @@ -71,8 +71,5 @@ System\Collections\HashHelpers.cs - - System\Collections\Generic\Empty.cs - From 1f22d521c4cea92b8ce5d5f6ca8cac1f31dd07a0 Mon Sep 17 00:00:00 2001 From: Huo Yaoyuan Date: Mon, 18 Aug 2025 01:04:23 +0800 Subject: [PATCH 5/7] Replace simple cases with ArrayBuilder --- .../NonPortable/CustomAttributeSearcher.cs | 2 +- .../src/Internal/Runtime/TypeLoader/TypeBuilder.cs | 12 +++++------- .../Internal/TypeSystem/TypeSystemContext.Runtime.cs | 12 ++++-------- 3 files changed, 10 insertions(+), 16 deletions(-) diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Reflection/Extensions/NonPortable/CustomAttributeSearcher.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Reflection/Extensions/NonPortable/CustomAttributeSearcher.cs index be481f70d12017..6295af39d1ebc7 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Reflection/Extensions/NonPortable/CustomAttributeSearcher.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Reflection/Extensions/NonPortable/CustomAttributeSearcher.cs @@ -110,7 +110,7 @@ public virtual E GetParent(E e) // private IEnumerable GetMatchingCustomAttributesIterator(E element, Func passesFilter, bool inherit) { - List immediateResults = new List(); + ArrayBuilder immediateResults = default; foreach (CustomAttributeData cad in GetDeclaredCustomAttributes(element)) { if (passesFilter(cad.AttributeType)) diff --git a/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeBuilder.cs b/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeBuilder.cs index 6bb1e2e3410191..50b0491f6b734f 100644 --- a/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeBuilder.cs +++ b/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeBuilder.cs @@ -26,11 +26,11 @@ public TypeBuilder() /// public static unsafe int ClassConstructorOffset => -sizeof(System.Runtime.CompilerServices.StaticClassConstructionContext); - private List _typesThatNeedTypeHandles = new List(); + private ArrayBuilder _typesThatNeedTypeHandles; - private List _methodsThatNeedDictionaries = new List(); + private ArrayBuilder _methodsThatNeedDictionaries; - private List _typesThatNeedPreparation; + private ArrayBuilder _typesThatNeedPreparation; #if DEBUG private bool _finalTypeBuilding; @@ -88,8 +88,6 @@ public void RegisterForPreparation(TypeDesc type) if (type.IsCanonicalSubtype(CanonicalFormKind.Any)) return; - _typesThatNeedPreparation ??= new List(); - _typesThatNeedPreparation.Add(type); } @@ -266,10 +264,10 @@ private void PrepareBaseTypeAndDictionaries(TypeDesc type) private void ProcessTypesNeedingPreparation() { // Process the pending types - while (_typesThatNeedPreparation != null) + while (_typesThatNeedPreparation.Count > 0) { var pendingTypes = _typesThatNeedPreparation; - _typesThatNeedPreparation = null; + _typesThatNeedPreparation = default; for (int i = 0; i < pendingTypes.Count; i++) PrepareType(pendingTypes[i]); diff --git a/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/TypeSystem/TypeSystemContext.Runtime.cs b/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/TypeSystem/TypeSystemContext.Runtime.cs index dd77b3e5ad6a5a..2cc527b21f4d31 100644 --- a/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/TypeSystem/TypeSystemContext.Runtime.cs +++ b/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/TypeSystem/TypeSystemContext.Runtime.cs @@ -511,7 +511,7 @@ public virtual int LoadFactor } } - private List _typesToFlushTypeSystemStateFrom; + private ArrayBuilder _typesToFlushTypeSystemStateFrom; /// /// Register the types that will get their attached TypeSystemState flushed if the @@ -519,7 +519,6 @@ public virtual int LoadFactor /// internal void RegisterTypeForTypeSystemStateFlushing(TypeDesc type) { - _typesToFlushTypeSystemStateFrom ??= new List(); _typesToFlushTypeSystemStateFrom.Add(type); } @@ -529,14 +528,11 @@ internal void RegisterTypeForTypeSystemStateFlushing(TypeDesc type) /// internal void FlushTypeBuilderStates() { - if (_typesToFlushTypeSystemStateFrom != null) + for (int i = 0; i < _typesToFlushTypeSystemStateFrom.Count; i++) { - for (int i = 0; i < _typesToFlushTypeSystemStateFrom.Count; i++) - { - _typesToFlushTypeSystemStateFrom[i].TypeBuilderState = null; - } + _typesToFlushTypeSystemStateFrom[i].TypeBuilderState = null; } - _typesToFlushTypeSystemStateFrom = null; + _typesToFlushTypeSystemStateFrom = default; } } From 4aca5b268080f0514cb31adc5837f54b574ead28 Mon Sep 17 00:00:00 2001 From: Huo Yaoyuan Date: Mon, 18 Aug 2025 12:46:34 +0800 Subject: [PATCH 6/7] Update CustomAttributeSearcher --- .../Extensions/NonPortable/CustomAttributeSearcher.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Reflection/Extensions/NonPortable/CustomAttributeSearcher.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Reflection/Extensions/NonPortable/CustomAttributeSearcher.cs index 6295af39d1ebc7..2e2e5ebdf95bd9 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Reflection/Extensions/NonPortable/CustomAttributeSearcher.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Reflection/Extensions/NonPortable/CustomAttributeSearcher.cs @@ -7,6 +7,7 @@ using System.Collections.ObjectModel; using System.Diagnostics; using System.Reflection; +using System.Reflection.Runtime.General; //================================================================================================================== // Dependency note: @@ -110,13 +111,15 @@ public virtual E GetParent(E e) // private IEnumerable GetMatchingCustomAttributesIterator(E element, Func passesFilter, bool inherit) { - ArrayBuilder immediateResults = default; + ListBuilder immediateResults = default; foreach (CustomAttributeData cad in GetDeclaredCustomAttributes(element)) { if (passesFilter(cad.AttributeType)) { yield return cad; - immediateResults.Add(cad); + + if (inherit) + immediateResults.Add(cad); } } if (inherit) From 79132b40a53cb5e927ad07684060842868c5b182 Mon Sep 17 00:00:00 2001 From: Jan Kotas Date: Mon, 18 Aug 2025 07:31:26 -0700 Subject: [PATCH 7/7] Update src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/General/NamespaceChain.cs --- .../src/System/Reflection/Runtime/General/NamespaceChain.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/General/NamespaceChain.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/General/NamespaceChain.cs index ce53181af13e72..66043999644081 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/General/NamespaceChain.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/General/NamespaceChain.cs @@ -22,7 +22,7 @@ internal NamespaceChain(MetadataReader reader, NamespaceDefinitionHandle innerMo NamespaceDefinition currentNamespaceDefinition = innerMostNamespaceHandle.GetNamespaceDefinition(reader); ConstantStringValueHandle currentNameHandle = currentNamespaceDefinition.Name; Handle currentNamespaceHandle; - List names = new List(); + ListBuilder names = default; for (; ; ) { string name = currentNameHandle.GetStringOrNull(reader);