Fix MemoryManager ctor and use internal span ctor to improve performance (#17452)
authorAhson Khan <ahkha@microsoft.com>
Mon, 9 Apr 2018 22:49:04 +0000 (15:49 -0700)
committerGitHub <noreply@github.com>
Mon, 9 Apr 2018 22:49:04 +0000 (15:49 -0700)
* Fix MemoryManager ctor, add unit and perf tests, and use internal span ctor.

* Address PR feedback (remove use of Unsafe.As and Dangerous Span Ctor)

src/mscorlib/shared/System/Memory.cs
src/mscorlib/shared/System/ReadOnlyMemory.cs
src/mscorlib/src/System/ThrowHelper.cs

index 6eb5af6..3ccb76b 100644 (file)
@@ -120,7 +120,9 @@ namespace System
         /// <param name="manager">The memory manager.</param>
         /// <param name="start">The index at which to begin the memory.</param>
         /// <param name="length">The number of items in the memory.</param>
-        /// <remarks>Returns default when <paramref name="manager"/> is null.</remarks>
+        /// <exception cref="System.ArgumentNullException">
+        /// Thrown when <paramref name="manager"/> is null.
+        /// </exception>
         /// <exception cref="System.ArgumentOutOfRangeException">
         /// Thrown when the specified <paramref name="start"/> or end index is not in the range (&lt;0 or &gt;=Length).
         /// </exception>
@@ -128,12 +130,7 @@ namespace System
         public Memory(MemoryManager<T> manager, int start, int length)
         {
             if (manager == null)
-            {
-                if (start != 0 || length != 0)
-                    ThrowHelper.ThrowArgumentOutOfRangeException();
-                this = default;
-                return; // returns default
-            }
+                ThrowHelper.ThrowArgumentNullException(ExceptionArgument.manager);
             if ((uint)start > (uint)manager.Length || (uint)length > (uint)(manager.Length - start))
                 ThrowHelper.ThrowArgumentOutOfRangeException();
 
@@ -276,6 +273,7 @@ namespace System
                 if (_index < 0)
                 {
                     Debug.Assert(_length >= 0);
+                    Debug.Assert(_object != null);
                     return ((MemoryManager<T>)_object).GetSpan().Slice(_index & RemoveFlagsBitMask, _length);
                 }
                 else if (typeof(T) == typeof(char) && _object is string s)
@@ -335,6 +333,7 @@ namespace System
         {
             if (_index < 0)
             {
+                Debug.Assert(_object != null);
                 return ((MemoryManager<T>)_object).Pin((_index & RemoveFlagsBitMask));
             }
             else if (typeof(T) == typeof(char) && _object is string s)
index ca0e7d8..3e78845 100644 (file)
@@ -187,6 +187,7 @@ namespace System
                 if (_index < 0)
                 {
                     Debug.Assert(_length >= 0);
+                    Debug.Assert(_object != null);
                     return ((MemoryManager<T>)_object).GetSpan().Slice(_index & RemoveFlagsBitMask, _length);
                 }
                 else if (typeof(T) == typeof(char) && _object is string s)
@@ -241,6 +242,7 @@ namespace System
         {
             if (_index < 0)
             {
+                Debug.Assert(_object != null);
                 return ((MemoryManager<T>)_object).Pin((_index & RemoveFlagsBitMask));
             }
             else if (typeof(T) == typeof(char) && _object is string s)
index eb6a638..b1a2fec 100644 (file)
@@ -479,7 +479,8 @@ namespace System
         comparable,
         source,
         state,
-        comparisonType
+        comparisonType,
+        manager
     }
 
     //