From 8bd9545d97a7e54880490f2a552d0972c0e9c629 Mon Sep 17 00:00:00 2001 From: Ben Adams Date: Sun, 12 Feb 2017 18:42:56 +0000 Subject: [PATCH 1/3] List Clear+Remove --- .../src/System/Collections/Generic/List.cs | 25 +++++++++++-------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/src/mscorlib/src/System/Collections/Generic/List.cs b/src/mscorlib/src/System/Collections/Generic/List.cs index 362e26599d09..8559fad00840 100644 --- a/src/mscorlib/src/System/Collections/Generic/List.cs +++ b/src/mscorlib/src/System/Collections/Generic/List.cs @@ -12,14 +12,13 @@ ** ** ===========================================================*/ -namespace System.Collections.Generic { - +namespace System.Collections.Generic +{ using System; - using System.Runtime; - using System.Runtime.Versioning; using System.Diagnostics; using System.Diagnostics.Contracts; using System.Collections.ObjectModel; + using Runtime.CompilerServices; // 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 @@ -291,12 +290,14 @@ public int BinarySearch(T item, IComparer comparer) // Clears the contents of List. - public void Clear() { - if (_size > 0) + public void Clear() + { + if (JitHelpers.ContainsReferences() && _size > 0) { - Array.Clear(_items, 0, _size); // Don't need to doc this but we clear the elements so that the gc can reclaim the references. - _size = 0; + Array.Clear(_items, 0, _size); // Clear the elements so that the gc can reclaim the references. } + + _size = 0; _version++; } @@ -870,10 +871,14 @@ public void RemoveAt(int index) { } Contract.EndContractBlock(); _size--; - if (index < _size) { + if (index < _size) + { Array.Copy(_items, index + 1, _items, index, _size - index); } - _items[_size] = default(T); + if (JitHelpers.ContainsReferences()) + { + _items[_size] = default(T); + } _version++; } From 8f00485418301284d8cb0c20716891c404379de9 Mon Sep 17 00:00:00 2001 From: Ben Adams Date: Sun, 12 Feb 2017 19:35:03 +0000 Subject: [PATCH 2/3] Tail call Array.Clear --- .../src/System/Collections/Generic/List.cs | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/src/mscorlib/src/System/Collections/Generic/List.cs b/src/mscorlib/src/System/Collections/Generic/List.cs index 8559fad00840..ff1939942107 100644 --- a/src/mscorlib/src/System/Collections/Generic/List.cs +++ b/src/mscorlib/src/System/Collections/Generic/List.cs @@ -292,13 +292,21 @@ public int BinarySearch(T item, IComparer comparer) // Clears the contents of List. public void Clear() { - if (JitHelpers.ContainsReferences() && _size > 0) + if (JitHelpers.ContainsReferences()) { - Array.Clear(_items, 0, _size); // Clear the elements so that the gc can reclaim the references. + int size = _size; + _size = 0; + _version++; + if (size > 0) + { + Array.Clear(_items, 0, size); // Clear the elements so that the gc can reclaim the references. + } + } + else + { + _size = 0; + _version++; } - - _size = 0; - _version++; } // Contains returns true if the specified element is in the List. From ac68ad345e9769844fd4d7af86cceb1bde9b3b30 Mon Sep 17 00:00:00 2001 From: Ben Adams Date: Sun, 12 Feb 2017 19:55:58 +0000 Subject: [PATCH 3/3] Only Array.Clear List for ref types --- .../src/System/Collections/Generic/List.cs | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/mscorlib/src/System/Collections/Generic/List.cs b/src/mscorlib/src/System/Collections/Generic/List.cs index ff1939942107..8e154d748f8c 100644 --- a/src/mscorlib/src/System/Collections/Generic/List.cs +++ b/src/mscorlib/src/System/Collections/Generic/List.cs @@ -861,9 +861,13 @@ public int RemoveAll(Predicate match) { // copy item to the free slot. _items[freeIndex++] = _items[current++]; } - } - - Array.Clear(_items, freeIndex, _size - freeIndex); + } + + if (JitHelpers.ContainsReferences()) + { + Array.Clear(_items, freeIndex, _size - freeIndex); // Clear the elements so that the gc can reclaim the references. + } + int result = _size - freeIndex; _size = freeIndex; _version++; @@ -911,8 +915,12 @@ public void RemoveRange(int index, int count) { if (index < _size) { Array.Copy(_items, index + count, _items, index, _size - index); } - Array.Clear(_items, _size, count); + _version++; + if (JitHelpers.ContainsReferences()) + { + Array.Clear(_items, _size, count); + } } }