Skip to content

Commit 9248da8

Browse files
huoyaoyuandirecthex
authored andcommitted
Clean up some usages of LowLevelList<T> (#105407)
1 parent d111595 commit 9248da8

14 files changed

Lines changed: 69 additions & 401 deletions

File tree

src/coreclr/nativeaot/Common/src/System/Collections/Generic/LowLevelList.cs

Lines changed: 0 additions & 352 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ namespace System.Collections.Generic
3131
// LowLevelList with no interface implementation minimizes both code and data size.
3232
// Data size is smaller because there will be minimal virtual function table.
3333
// Code size is smaller because only functions called will be in the binary.
34-
// Use LowLevelListWithIList<T> for IList support
3534
[DebuggerDisplay("Count = {Count}")]
3635
#if TYPE_LOADER_IMPLEMENTATION
3736
[System.Runtime.CompilerServices.ForceDictionaryLookups]
@@ -196,356 +195,5 @@ private void EnsureCapacity(int min)
196195
Capacity = newCapacity;
197196
}
198197
}
199-
200-
#if !TYPE_LOADER_IMPLEMENTATION
201-
// Adds the elements of the given collection to the end of this list. If
202-
// required, the capacity of the list is increased to twice the previous
203-
// capacity or the new size, whichever is larger.
204-
//
205-
public void AddRange(IEnumerable<T> collection)
206-
{
207-
208-
InsertRange(_size, collection);
209-
}
210-
211-
// Clears the contents of List.
212-
public void Clear()
213-
{
214-
if (_size > 0)
215-
{
216-
Array.Clear(_items, 0, _size); // Don't need to doc this but we clear the elements so that the gc can reclaim the references.
217-
_size = 0;
218-
}
219-
_version++;
220-
}
221-
222-
// Contains returns true if the specified element is in the List.
223-
// It does a linear, O(n) search. Equality is determined by calling
224-
// item.Equals().
225-
//
226-
public bool Contains(T item)
227-
{
228-
if ((object?)item == null)
229-
{
230-
for (int i = 0; i < _size; i++)
231-
if ((object?)_items[i] == null)
232-
return true;
233-
return false;
234-
}
235-
else
236-
{
237-
int index = IndexOf(item);
238-
if (index >= 0)
239-
return true;
240-
return false;
241-
}
242-
}
243-
244-
245-
// Copies a section of this list to the given array at the given index.
246-
//
247-
// The method uses the Array.Copy method to copy the elements.
248-
//
249-
public void CopyTo(int index, T[] array, int arrayIndex, int count)
250-
{
251-
if (_size - index < count)
252-
{
253-
throw new ArgumentException();
254-
}
255-
256-
// Delegate rest of error checking to Array.Copy.
257-
Array.Copy(_items, index, array, arrayIndex, count);
258-
}
259-
260-
public void CopyTo(T[] array, int arrayIndex)
261-
{
262-
// Delegate rest of error checking to Array.Copy.
263-
Array.Copy(_items, 0, array, arrayIndex, _size);
264-
}
265-
266-
// Returns the index of the first occurrence of a given value in a range of
267-
// this list. The list is searched forwards from beginning to end.
268-
// The elements of the list are compared to the given value using the
269-
// Object.Equals method.
270-
//
271-
// This method uses the Array.IndexOf method to perform the
272-
// search.
273-
//
274-
public int IndexOf(T item)
275-
{
276-
return Array.IndexOf(_items, item, 0, _size);
277-
}
278-
279-
280-
// Returns the index of the first occurrence of a given value in a range of
281-
// this list. The list is searched forwards, starting at index
282-
// index and ending at count number of elements. The
283-
// elements of the list are compared to the given value using the
284-
// Object.Equals method.
285-
//
286-
// This method uses the Array.IndexOf method to perform the
287-
// search.
288-
//
289-
public int IndexOf(T item, int index)
290-
{
291-
ArgumentOutOfRangeException.ThrowIfGreaterThan(index, _size);
292-
return Array.IndexOf(_items, item, index, _size - index);
293-
}
294-
295-
// Inserts an element into this list at a given index. The size of the list
296-
// is increased by one. If required, the capacity of the list is doubled
297-
// before inserting the new element.
298-
//
299-
public void Insert(int index, T item)
300-
{
301-
// Note that insertions at the end are legal.
302-
ArgumentOutOfRangeException.ThrowIfGreaterThan((uint)index, (uint)_size, nameof(index));
303-
304-
if (_size == _items.Length) EnsureCapacity(_size + 1);
305-
if (index < _size)
306-
{
307-
Array.Copy(_items, index, _items, index + 1, _size - index);
308-
}
309-
_items[index] = item;
310-
_size++;
311-
_version++;
312-
}
313-
314-
// Inserts the elements of the given collection at a given index. If
315-
// required, the capacity of the list is increased to twice the previous
316-
// capacity or the new size, whichever is larger. Ranges may be added
317-
// to the end of the list by setting index to the List's size.
318-
//
319-
public void InsertRange(int index, IEnumerable<T> collection)
320-
{
321-
ArgumentNullException.ThrowIfNull(collection);
322-
ArgumentOutOfRangeException.ThrowIfGreaterThan((uint)index, (uint)_size, nameof(index));
323-
324-
ICollection<T>? c = collection as ICollection<T>;
325-
if (c != null)
326-
{ // if collection is ICollection<T>
327-
int count = c.Count;
328-
if (count > 0)
329-
{
330-
EnsureCapacity(_size + count);
331-
if (index < _size)
332-
{
333-
Array.Copy(_items, index, _items, index + count, _size - index);
334-
}
335-
336-
// If we're inserting a List into itself, we want to be able to deal with that.
337-
if (this == c)
338-
{
339-
// Copy first part of _items to insert location
340-
Array.Copy(_items, 0, _items, index, index);
341-
// Copy last part of _items back to inserted location
342-
Array.Copy(_items, index + count, _items, index * 2, _size - index);
343-
}
344-
else
345-
{
346-
T[] itemsToInsert = new T[count];
347-
c.CopyTo(itemsToInsert, 0);
348-
Array.Copy(itemsToInsert, 0, _items, index, count);
349-
}
350-
_size += count;
351-
}
352-
}
353-
else
354-
{
355-
using (IEnumerator<T> en = collection.GetEnumerator())
356-
{
357-
while (en.MoveNext())
358-
{
359-
Insert(index++, en.Current);
360-
}
361-
}
362-
}
363-
_version++;
364-
}
365-
366-
// Removes the element at the given index. The size of the list is
367-
// decreased by one.
368-
//
369-
public bool Remove(T item)
370-
{
371-
int index = IndexOf(item);
372-
if (index >= 0)
373-
{
374-
RemoveAt(index);
375-
return true;
376-
}
377-
378-
return false;
379-
}
380-
381-
// This method removes all items which matches the predicate.
382-
// The complexity is O(n).
383-
public int RemoveAll(Predicate<T> match)
384-
{
385-
ArgumentNullException.ThrowIfNull(match);
386-
387-
int freeIndex = 0; // the first free slot in items array
388-
389-
// Find the first item which needs to be removed.
390-
while (freeIndex < _size && !match(_items[freeIndex]!)) freeIndex++;
391-
if (freeIndex >= _size) return 0;
392-
393-
int current = freeIndex + 1;
394-
while (current < _size)
395-
{
396-
// Find the first item which needs to be kept.
397-
while (current < _size && match(_items[current]!)) current++;
398-
399-
if (current < _size)
400-
{
401-
// copy item to the free slot.
402-
_items[freeIndex++] = _items[current++];
403-
}
404-
}
405-
406-
Array.Clear(_items, freeIndex, _size - freeIndex);
407-
int result = _size - freeIndex;
408-
_size = freeIndex;
409-
_version++;
410-
return result;
411-
}
412-
413-
// Removes the element at the given index. The size of the list is
414-
// decreased by one.
415-
//
416-
public void RemoveAt(int index)
417-
{
418-
ArgumentOutOfRangeException.ThrowIfGreaterThanOrEqual((uint)index, (uint)_size, nameof(index));
419-
_size--;
420-
if (index < _size)
421-
{
422-
Array.Copy(_items, index + 1, _items, index, _size - index);
423-
}
424-
_items[_size] = default!;
425-
_version++;
426-
}
427-
428-
// ToArray returns a new Object array containing the contents of the List.
429-
// This requires copying the List, which is an O(n) operation.
430-
public T[] ToArray()
431-
{
432-
T[] array = new T[_size];
433-
Array.Copy(_items, 0, array, 0, _size);
434-
return array;
435-
}
436-
#endif
437-
}
438-
439-
#if !TYPE_LOADER_IMPLEMENTATION
440-
// LowLevelList<T> with full IList<T> implementation
441-
internal sealed class LowLevelListWithIList<T> : LowLevelList<T>, IList<T>
442-
{
443-
public LowLevelListWithIList()
444-
{
445-
}
446-
447-
public LowLevelListWithIList(int capacity)
448-
: base(capacity)
449-
{
450-
}
451-
452-
public LowLevelListWithIList(IEnumerable<T> collection)
453-
: base(collection)
454-
{
455-
}
456-
457-
// Is this List read-only?
458-
bool ICollection<T>.IsReadOnly
459-
{
460-
get { return false; }
461-
}
462-
463-
/// <internalonly/>
464-
IEnumerator<T> IEnumerable<T>.GetEnumerator()
465-
{
466-
return new Enumerator(this);
467-
}
468-
469-
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
470-
{
471-
return new Enumerator(this);
472-
}
473-
474-
private struct Enumerator : IEnumerator<T>, System.Collections.IEnumerator
475-
{
476-
private LowLevelListWithIList<T> _list;
477-
private int _index;
478-
private int _version;
479-
private T? _current;
480-
481-
internal Enumerator(LowLevelListWithIList<T> list)
482-
{
483-
_list = list;
484-
_index = 0;
485-
_version = list._version;
486-
_current = default(T);
487-
}
488-
489-
public void Dispose()
490-
{
491-
}
492-
493-
public bool MoveNext()
494-
{
495-
LowLevelListWithIList<T> localList = _list;
496-
497-
if (_version == localList._version && ((uint)_index < (uint)localList._size))
498-
{
499-
_current = localList._items[_index];
500-
_index++;
501-
return true;
502-
}
503-
return MoveNextRare();
504-
}
505-
506-
private bool MoveNextRare()
507-
{
508-
if (_version != _list._version)
509-
{
510-
throw new InvalidOperationException();
511-
}
512-
513-
_index = _list._size + 1;
514-
_current = default(T);
515-
return false;
516-
}
517-
518-
public T Current
519-
{
520-
get
521-
{
522-
return _current!;
523-
}
524-
}
525-
526-
object? System.Collections.IEnumerator.Current
527-
{
528-
get
529-
{
530-
if (_index == 0 || _index == _list._size + 1)
531-
{
532-
throw new InvalidOperationException();
533-
}
534-
return Current;
535-
}
536-
}
537-
538-
void System.Collections.IEnumerator.Reset()
539-
{
540-
if (_version != _list._version)
541-
{
542-
throw new InvalidOperationException();
543-
}
544-
545-
_index = 0;
546-
_current = default(T);
547-
}
548-
}
549198
}
550-
#endif // !TYPE_LOADER_IMPLEMENTATION
551199
}

src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Attribute.NativeAot.cs

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -135,18 +135,23 @@ private static Attribute OneOrNull(IEnumerable<CustomAttributeData> results)
135135
Justification = "Arrays of reference types are safe to create.")]
136136
private static Attribute[] Instantiate(IEnumerable<CustomAttributeData> cads, Type actualElementType)
137137
{
138-
LowLevelList<Attribute> attributes = new LowLevelList<Attribute>();
138+
ArrayBuilder<Attribute> attributes = default;
139139
foreach (CustomAttributeData cad in cads)
140140
{
141141
Attribute instantiatedAttribute = cad.Instantiate();
142142
attributes.Add(instantiatedAttribute);
143143
}
144-
int count = attributes.Count;
145-
Attribute[] result = actualElementType.ContainsGenericParameters
146-
? new Attribute[count]
147-
: (Attribute[])Array.CreateInstance(actualElementType, count);
148-
attributes.CopyTo(result, 0);
149-
return result;
144+
145+
if (actualElementType.ContainsGenericParameters)
146+
{
147+
return attributes.ToArray();
148+
}
149+
else
150+
{
151+
Attribute[] result = (Attribute[])Array.CreateInstance(actualElementType, attributes.Count);
152+
attributes.CopyTo(result);
153+
return result;
154+
}
150155
}
151156
}
152157
}

0 commit comments

Comments
 (0)