Make DangerousGetPinnableReference internal and remove DangerousTryGetArray (#15557)
authorAhson Khan <ahkha@microsoft.com>
Sun, 24 Dec 2017 01:43:26 +0000 (17:43 -0800)
committerGitHub <noreply@github.com>
Sun, 24 Dec 2017 01:43:26 +0000 (17:43 -0800)
* Make DangerousGetPinnableReference internal and remove DangerousTryGetArray

* Change DangerousGetPinnableReference to return ref readonly

src/mscorlib/shared/System/ReadOnlyMemory.cs
src/mscorlib/shared/System/ReadOnlySpan.cs
src/mscorlib/shared/System/Span.NonGeneric.cs
src/mscorlib/shared/System/Span.cs
tests/src/JIT/Performance/CodeQuality/Span/SpanBench.cs

index 12fdaf9..5d8f00f 100644 (file)
@@ -244,31 +244,6 @@ namespace System
         }
 
         /// <summary>
-        /// Get an array segment from the underlying memory. 
-        /// If unable to get the array segment, return false with a default array segment.
-        /// </summary>
-        [EditorBrowsable(EditorBrowsableState.Never)]
-        public bool DangerousTryGetArray(out ArraySegment<T> arraySegment)
-        {
-            if (_index < 0)
-            {
-                if (((OwnedMemory<T>)_object).TryGetArray(out var segment))
-                {
-                    arraySegment = new ArraySegment<T>(segment.Array, segment.Offset + (_index & RemoveOwnedFlagBitMask), _length);
-                    return true;
-                }
-            }
-            else if (_object is T[] arr)
-            {
-                arraySegment = new ArraySegment<T>(arr, _index, _length);
-                return true;
-            }
-
-            arraySegment = default;
-            return false;
-        }
-
-        /// <summary>
         /// Copies the contents from the memory into a new array.  This heap
         /// allocates, so should generally be avoided, however it is sometimes
         /// necessary to bridge the gap with APIs written in terms of arrays.
index f8fb7b6..dac8069 100644 (file)
@@ -128,7 +128,7 @@ namespace System
         /// </summary>
         [MethodImpl(MethodImplOptions.AggressiveInlining)]
         [EditorBrowsable(EditorBrowsableState.Never)]
-        public ref T DangerousGetPinnableReference()
+        internal ref readonly T DangerousGetPinnableReference()
         {
             return ref _pointer.Value;
         }
@@ -362,20 +362,7 @@ namespace System
             public ref readonly T Current
             {
                 [MethodImpl(MethodImplOptions.AggressiveInlining)]
-                get
-                {
-                    // TODO https://github.com/dotnet/coreclr/pull/14727:
-                    // Change this to simply be:
-                    //     get => ref readonly _span[_index];
-                    // once ReadOnlySpan<T>'s indexer returns ref readonly.
-
-                    if ((uint)_index >= (uint)_span.Length)
-                    {
-                        ThrowHelper.ThrowIndexOutOfRangeException();
-                    }
-
-                    return ref Unsafe.Add(ref _span.DangerousGetPinnableReference(), _index);
-                }
+                get => ref _span[_index];
             }
         }
     }
index 6136fe0..775426f 100644 (file)
@@ -5,6 +5,8 @@
 using System.Diagnostics;
 using System.Runtime;
 using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
 using Internal.Runtime.CompilerServices;
 
 #if BIT64
@@ -73,7 +75,7 @@ namespace System
                 ThrowHelper.ThrowInvalidTypeWithPointersNotSupported(typeof(T));
 
             return new Span<byte>(
-                ref Unsafe.As<T, byte>(ref source.DangerousGetPinnableReference()),
+                ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(source)),
                 checked(source.Length * Unsafe.SizeOf<T>()));
         }
 
@@ -93,7 +95,7 @@ namespace System
                 ThrowHelper.ThrowInvalidTypeWithPointersNotSupported(typeof(T));
 
             return new ReadOnlySpan<byte>(
-                ref Unsafe.As<T, byte>(ref source.DangerousGetPinnableReference()),
+                ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(source)),
                 checked(source.Length * Unsafe.SizeOf<T>()));
         }
 
@@ -145,7 +147,7 @@ namespace System
                 ThrowHelper.ThrowInvalidTypeWithPointersNotSupported(typeof(TTo));
 
             return new ReadOnlySpan<TTo>(
-                ref Unsafe.As<TFrom, TTo>(ref source.DangerousGetPinnableReference()),
+                ref Unsafe.As<TFrom, TTo>(ref MemoryMarshal.GetReference(source)),
                 checked((int)((long)source.Length * Unsafe.SizeOf<TFrom>() / Unsafe.SizeOf<TTo>())));
         }
 
index 3dd9dca..5a81317 100644 (file)
@@ -140,7 +140,7 @@ namespace System
         /// </summary>
         [MethodImpl(MethodImplOptions.AggressiveInlining)]
         [EditorBrowsable(EditorBrowsableState.Never)]
-        public ref T DangerousGetPinnableReference()
+        internal ref T DangerousGetPinnableReference()
         {
             return ref _pointer.Value;
         }
index d0ccbc5..5bf5a2f 100644 (file)
@@ -515,38 +515,38 @@ namespace Span
         }
         #endregion
 
-        #region TestSpanDangerousGetPinnableReference<T>
+        #region TestMemoryMarshalGetReference<T>
         [Benchmark(InnerIterationCount = BaseIterations)]
         [InlineData(100)]
-        public static void TestSpanDangerousGetPinnableReferenceByte(int length)
+        public static void TestMemoryMarshalGetReferenceByte(int length)
         {
-            InvokeTestSpanDangerousGetPinnableReference<byte>(length);
+            InvokeTestMemoryMarshalGetReference<byte>(length);
         }
 
         [Benchmark(InnerIterationCount = BaseIterations)]
         [InlineData(100)]
-        public static void TestSpanDangerousGetPinnableReferenceString(int length)
+        public static void TestMemoryMarshalGetReferenceString(int length)
         {
-            InvokeTestSpanDangerousGetPinnableReference<string>(length);
+            InvokeTestMemoryMarshalGetReference<string>(length);
         }
 
-        static void InvokeTestSpanDangerousGetPinnableReference<T>(int length)
+        static void InvokeTestMemoryMarshalGetReference<T>(int length)
         {
             var array = new T[length];
 
-            Invoke((int innerIterationCount) => TestSpanDangerousGetPinnableReference<T>(array, innerIterationCount),
-                "TestSpanDangerousGetPinnableReference<{0}>({1})", typeof(T).Name, length);
+            Invoke((int innerIterationCount) => TestMemoryMarshalGetReference<T>(array, innerIterationCount),
+                "TestMemoryMarshalGetReference<{0}>({1})", typeof(T).Name, length);
         }
 
         [MethodImpl(MethodImplOptions.NoInlining)]
-        static void TestSpanDangerousGetPinnableReference<T>(T[] array, int iterationCount)
+        static void TestMemoryMarshalGetReference<T>(T[] array, int iterationCount)
         {
             var sink = Sink<T>.Instance;
             var span = new Span<T>(array);
 
             for (int i = 0; i < iterationCount; i++)
             {
-                ref T temp = ref span.DangerousGetPinnableReference();
+                ref T temp = ref MemoryMarshal.GetReference(span);
                 sink.Data = temp;
             }
         }