From bb43d0b6460d2d197fa3609bcc37d99cbefbb6c8 Mon Sep 17 00:00:00 2001 From: Tanner Gooding Date: Tue, 19 Jan 2021 09:51:16 -0800 Subject: [PATCH 1/8] Changing List to internally use GC.AllocateUninitializedArray --- .../src/System/Collections/Generic/List.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/List.cs b/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/List.cs index 6da36e0f57bf4f..819486eb30970f 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/List.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/List.cs @@ -51,7 +51,7 @@ public List(int capacity) if (capacity == 0) _items = s_emptyArray; else - _items = new T[capacity]; + _items = GC.AllocateUninitializedArray(capacity); } // Constructs a List, copying the contents of the given collection. The @@ -72,7 +72,7 @@ public List(IEnumerable collection) } else { - _items = new T[count]; + _items = GC.AllocateUninitializedArray(count); c.CopyTo(_items, 0); _size = count; } @@ -108,7 +108,7 @@ public int Capacity { if (value > 0) { - T[] newItems = new T[value]; + T[] newItems = GC.AllocateUninitializedArray(value); if (_size > 0) { Array.Copy(_items, newItems, _size); @@ -1030,7 +1030,7 @@ public T[] ToArray() return s_emptyArray; } - T[] array = new T[_size]; + T[] array = GC.AllocateUninitializedArray(_size); Array.Copy(_items, array, _size); return array; } From a0fa53054d689b3243524dd3cfb8b5609cbc616f Mon Sep 17 00:00:00 2001 From: Tanner Gooding Date: Tue, 19 Jan 2021 10:46:53 -0800 Subject: [PATCH 2/8] Changing HashSet to internally use GC.AllocateUninitializedArray --- .../src/System/Collections/Generic/HashSet.cs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/HashSet.cs b/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/HashSet.cs index 394b0ff6fa625b..6dba61b7990d39 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/HashSet.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/HashSet.cs @@ -399,7 +399,7 @@ public virtual void GetObjectData(SerializationInfo info, StreamingContext conte if (_buckets != null) { - var array = new T[Count]; + var array = GC.AllocateUninitializedArray(Count); CopyTo(array); info.AddValue(ElementsName, array, typeof(T[])); } @@ -426,8 +426,8 @@ public virtual void OnDeserialization(object? sender) if (capacity != 0) { - _buckets = new int[capacity]; - _entries = new Entry[capacity]; + _buckets = GC.AllocateUninitializedArray(capacity); + _entries = GC.AllocateUninitializedArray(capacity); #if TARGET_64BIT _fastModMultiplier = HashHelpers.GetFastModMultiplier((uint)capacity); #endif @@ -974,7 +974,7 @@ private void Resize(int newSize, bool forceNewHashCodes) Debug.Assert(_entries != null, "_entries should be non-null"); Debug.Assert(newSize >= _entries.Length); - var entries = new Entry[newSize]; + var entries = GC.AllocateUninitializedArray(newSize); int count = _count; Array.Copy(_entries, entries, count); @@ -1000,7 +1000,7 @@ private void Resize(int newSize, bool forceNewHashCodes) } // Assign member variables after both arrays allocated to guard against corruption from OOM if second fails - _buckets = new int[newSize]; + _buckets = GC.AllocateUninitializedArray(newSize); #if TARGET_64BIT _fastModMultiplier = HashHelpers.GetFastModMultiplier((uint)newSize); #endif @@ -1071,8 +1071,8 @@ public void TrimExcess() private int Initialize(int capacity) { int size = HashHelpers.GetPrime(capacity); - var buckets = new int[size]; - var entries = new Entry[size]; + var buckets = GC.AllocateUninitializedArray(size); + var entries = GC.AllocateUninitializedArray(size); // Assign member variables after both arrays are allocated to guard against corruption from OOM if second fails. _freeList = -1; From b8dda907450fd77b9b0bd9eaa295077813dfa6d6 Mon Sep 17 00:00:00 2001 From: Tanner Gooding Date: Tue, 19 Jan 2021 10:48:39 -0800 Subject: [PATCH 3/8] Changing Dictionary to internally use GC.AllocateUninitializedArray --- .../src/System/Collections/Generic/Dictionary.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/Dictionary.cs b/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/Dictionary.cs index 798b3d08c94535..a4feac3d78fc2a 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/Dictionary.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/Dictionary.cs @@ -354,7 +354,7 @@ public virtual void GetObjectData(SerializationInfo info, StreamingContext conte if (_buckets != null) { - var array = new KeyValuePair[Count]; + var array = GC.AllocateUninitializedArray>(Count); CopyTo(array, 0); info.AddValue(KeyValuePairsName, array, typeof(KeyValuePair[])); } @@ -489,8 +489,8 @@ private ref TValue FindValue(TKey key) private int Initialize(int capacity) { int size = HashHelpers.GetPrime(capacity); - int[] buckets = new int[size]; - Entry[] entries = new Entry[size]; + int[] buckets = GC.AllocateUninitializedArray(size); + Entry[] entries = GC.AllocateUninitializedArray(size); // Assign member variables after both arrays allocated to guard against corruption from OOM if second fails _freeList = -1; @@ -744,7 +744,7 @@ private void Resize(int newSize, bool forceNewHashCodes) Debug.Assert(_entries != null, "_entries should be non-null"); Debug.Assert(newSize >= _entries.Length); - Entry[] entries = new Entry[newSize]; + Entry[] entries = GC.AllocateUninitializedArray(newSize); int count = _count; Array.Copy(_entries, entries, count); @@ -769,7 +769,7 @@ private void Resize(int newSize, bool forceNewHashCodes) } // Assign member variables after both arrays allocated to guard against corruption from OOM if second fails - _buckets = new int[newSize]; + _buckets = GC.AllocateUninitializedArray(newSize); #if TARGET_64BIT _fastModMultiplier = HashHelpers.GetFastModMultiplier((uint)newSize); #endif From c38577934536bf272254273255d2d00da0c61dbf Mon Sep 17 00:00:00 2001 From: Tanner Gooding Date: Tue, 19 Jan 2021 10:50:01 -0800 Subject: [PATCH 4/8] Changing LinkedList to internally use GC.AllocateUninitializedArray --- .../src/System/Collections/Generic/LinkedList.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/System.Collections/src/System/Collections/Generic/LinkedList.cs b/src/libraries/System.Collections/src/System/Collections/Generic/LinkedList.cs index cd2718696213ac..85037771cc3c77 100644 --- a/src/libraries/System.Collections/src/System/Collections/Generic/LinkedList.cs +++ b/src/libraries/System.Collections/src/System/Collections/Generic/LinkedList.cs @@ -346,7 +346,7 @@ public virtual void GetObjectData(SerializationInfo info, StreamingContext conte if (count != 0) { - T[] array = new T[count]; + T[] array = GC.AllocateUninitializedArray(count); CopyTo(array, 0); info.AddValue(ValuesName, array, typeof(T[])); } From eb29dd9cbc5d5ba0c34f30c17ffda786a39c492d Mon Sep 17 00:00:00 2001 From: Tanner Gooding Date: Tue, 19 Jan 2021 10:50:34 -0800 Subject: [PATCH 5/8] Changing Queue to internally use GC.AllocateUninitializedArray --- .../src/System/Collections/Generic/Queue.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libraries/System.Collections/src/System/Collections/Generic/Queue.cs b/src/libraries/System.Collections/src/System/Collections/Generic/Queue.cs index 1581a8713de4ad..e7326792211444 100644 --- a/src/libraries/System.Collections/src/System/Collections/Generic/Queue.cs +++ b/src/libraries/System.Collections/src/System/Collections/Generic/Queue.cs @@ -47,7 +47,7 @@ public Queue(int capacity) { if (capacity < 0) throw new ArgumentOutOfRangeException(nameof(capacity), capacity, SR.ArgumentOutOfRange_NeedNonNegNum); - _array = new T[capacity]; + _array = GC.AllocateUninitializedArray(capacity); } // Fills a Queue with the elements of an ICollection. Uses the enumerator @@ -317,7 +317,7 @@ public T[] ToArray() return Array.Empty(); } - T[] arr = new T[_size]; + T[] arr = GC.AllocateUninitializedArray(_size); if (_head < _tail) { @@ -336,7 +336,7 @@ public T[] ToArray() // must be >= _size. private void SetCapacity(int capacity) { - T[] newarray = new T[capacity]; + T[] newarray = GC.AllocateUninitializedArray(capacity); if (_size > 0) { if (_head < _tail) From 214d7bdae8ac5c36b04c3c0972122c7f55e6557f Mon Sep 17 00:00:00 2001 From: Tanner Gooding Date: Tue, 19 Jan 2021 10:51:34 -0800 Subject: [PATCH 6/8] Changing SortedList to internally use GC.AllocateUninitializedArray --- .../src/System/Collections/Generic/SortedList.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libraries/System.Collections/src/System/Collections/Generic/SortedList.cs b/src/libraries/System.Collections/src/System/Collections/Generic/SortedList.cs index 8a07c4188cb5f2..6cabaeb670f148 100644 --- a/src/libraries/System.Collections/src/System/Collections/Generic/SortedList.cs +++ b/src/libraries/System.Collections/src/System/Collections/Generic/SortedList.cs @@ -89,8 +89,8 @@ public SortedList(int capacity) { if (capacity < 0) throw new ArgumentOutOfRangeException(nameof(capacity), capacity, SR.ArgumentOutOfRange_NeedNonNegNum); - keys = new TKey[capacity]; - values = new TValue[capacity]; + keys = GC.AllocateUninitializedArray(capacity); + values = GC.AllocateUninitializedArray(capacity); comparer = Comparer.Default; } @@ -238,8 +238,8 @@ public int Capacity if (value > 0) { - TKey[] newKeys = new TKey[value]; - TValue[] newValues = new TValue[value]; + TKey[] newKeys = GC.AllocateUninitializedArray(value); + TValue[] newValues = GC.AllocateUninitializedArray(value); if (_size > 0) { Array.Copy(keys, newKeys, _size); From bae26f13c086051f33816f06196ea76973ba967b Mon Sep 17 00:00:00 2001 From: Tanner Gooding Date: Tue, 19 Jan 2021 10:52:46 -0800 Subject: [PATCH 7/8] Changing SortedSet to internally use GC.AllocateUninitializedArray --- .../src/System/Collections/Generic/SortedSet.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libraries/System.Collections/src/System/Collections/Generic/SortedSet.cs b/src/libraries/System.Collections/src/System/Collections/Generic/SortedSet.cs index cccbe5338de3c1..c88661bbd9e619 100644 --- a/src/libraries/System.Collections/src/System/Collections/Generic/SortedSet.cs +++ b/src/libraries/System.Collections/src/System/Collections/Generic/SortedSet.cs @@ -884,7 +884,7 @@ public void UnionWith(IEnumerable other) if (asSorted != null && treeSubset == null && HasEqualComparer(asSorted) && (asSorted.Count > this.Count / 2)) { // First do a merge sort to an array. - T[] merged = new T[asSorted.Count + this.Count]; + T[] merged = GC.AllocateUninitializedArray(asSorted.Count + this.Count); int c = 0; Enumerator mine = this.GetEnumerator(); Enumerator theirs = asSorted.GetEnumerator(); @@ -1026,7 +1026,7 @@ public virtual void IntersectWith(IEnumerable other) if (asSorted != null && treeSubset == null && HasEqualComparer(asSorted)) { // First do a merge sort to an array. - T[] merged = new T[this.Count]; + T[] merged = GC.AllocateUninitializedArray(this.Count); int c = 0; Enumerator mine = this.GetEnumerator(); Enumerator theirs = asSorted.GetEnumerator(); @@ -1590,7 +1590,7 @@ protected virtual void GetObjectData(SerializationInfo info, StreamingContext co if (root != null) { - T[] items = new T[Count]; + T[] items = GC.AllocateUninitializedArray(Count); CopyTo(items, 0); info.AddValue(ItemsName, items, typeof(T[])); } From 833c04503ed2945fb4c34826c818bc3d66145d3b Mon Sep 17 00:00:00 2001 From: Tanner Gooding Date: Tue, 19 Jan 2021 10:53:10 -0800 Subject: [PATCH 8/8] Changing Stack to internally use GC.AllocateUninitializedArray --- .../src/System/Collections/Generic/Stack.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libraries/System.Collections/src/System/Collections/Generic/Stack.cs b/src/libraries/System.Collections/src/System/Collections/Generic/Stack.cs index 03e4282546be8a..8292ccf3d59497 100644 --- a/src/libraries/System.Collections/src/System/Collections/Generic/Stack.cs +++ b/src/libraries/System.Collections/src/System/Collections/Generic/Stack.cs @@ -43,7 +43,7 @@ public Stack(int capacity) { if (capacity < 0) throw new ArgumentOutOfRangeException(nameof(capacity), capacity, SR.ArgumentOutOfRange_NeedNonNegNum); - _array = new T[capacity]; + _array = GC.AllocateUninitializedArray(capacity); } // Fills a Stack with the contents of a particular collection. The items are @@ -294,7 +294,7 @@ public T[] ToArray() if (_size == 0) return Array.Empty(); - T[] objArray = new T[_size]; + T[] objArray = GC.AllocateUninitializedArray(_size); int i = 0; while (i < _size) {