Avoid Unsafe.AsRef in Span<T> implementation (#8657)
authorJan Kotas <jkotas@microsoft.com>
Fri, 16 Dec 2016 21:45:48 +0000 (13:45 -0800)
committerGitHub <noreply@github.com>
Fri, 16 Dec 2016 21:45:48 +0000 (13:45 -0800)
The JIT is not able to inline the current implementation of Unsafe.AsRef because of it has type mismatch on return. Change the the corelib Span to call Unsafe.As instead since fixing the type mismatch is not easy in the internal corelib version of Unsafe.AsRef.

src/mscorlib/src/System/ReadOnlySpan.cs
src/mscorlib/src/System/Runtime/CompilerServices/Unsafe.cs
src/mscorlib/src/System/Span.cs
src/vm/jitinterface.cpp
src/vm/mscorlib.h

index 762a39b6518337cac591690595e3c954acfbba07..b0919d3208ae4286b58ab48ee95c8c0675b93d06 100644 (file)
@@ -104,7 +104,7 @@ namespace System
             if (length < 0)
                 ThrowHelper.ThrowArgumentOutOfRangeException();
 
-            _pointer = new ByReference<T>(ref Unsafe.AsRef<T>(pointer));
+            _pointer = new ByReference<T>(ref Unsafe.As<byte, T>(ref *(byte*)pointer));
             _length = length;
         }
 
index db3b2f28b74779be7dfb07df11006f44c746bfc9..b212f4555b26e026866ff30060b98c4610c59384 100644 (file)
@@ -40,18 +40,6 @@ namespace System.Runtime.CompilerServices
             throw new InvalidOperationException();
         }
 
-        /// <summary>
-        /// Reinterprets the given location as a reference to a value of type<typeparamref name="T"/>.
-        /// </summary>
-        [NonVersionable]
-        [MethodImpl(MethodImplOptions.AggressiveInlining)]
-        public static ref T AsRef<T>(void * source)
-        {
-            // The body of this function will be replaced by the EE with unsafe code!!!
-            // See getILIntrinsicImplementationForUnsafe for how this happens.  
-            throw new InvalidOperationException();
-        }
-
         /// <summary>
         /// Reinterprets the given reference as a reference to a value of type <typeparamref name="TTo"/>.
         /// </summary>
index 17d41116e0cd35ae6070b4eec2f0be12011e4000..9fa55c63d791500c4e9d4f0af8bf4e679e047b9c 100644 (file)
@@ -119,7 +119,7 @@ namespace System
             if (length < 0)
                 ThrowHelper.ThrowArgumentOutOfRangeException();
 
-            _pointer = new ByReference<T>(ref Unsafe.AsRef<T>(pointer));
+            _pointer = new ByReference<T>(ref Unsafe.As<byte, T>(ref *(byte*)pointer));
             _length = length;
         }
 
index cebd410347c2509363f9c2559894d7a91fa2753b..2f9db3d5969739d189ffca64aceb5507f226cac3 100644 (file)
@@ -7033,9 +7033,7 @@ bool getILIntrinsicImplementationForUnsafe(MethodDesc * ftn,
         methInfo->options = (CorInfoOptions)0;
         return true;
     }
-    else if ((tk == MscorlibBinder::GetMethod(METHOD__UNSAFE__AS_REF)->GetMemberDef()) ||
-             (tk == MscorlibBinder::GetMethod(METHOD__UNSAFE__BYREF_AS)->GetMemberDef()))
-             
+    else if (tk == MscorlibBinder::GetMethod(METHOD__UNSAFE__BYREF_AS)->GetMemberDef())
     {
         // Return the argument that was passed in.
         static const BYTE ilcode[] = { CEE_LDARG_0, CEE_RET };
index 7a0b1a04f1448d64be1b3b36630a994cffab0986..20d658b2e185cd9602c53ca6aa9e26ce3c9af4a0 100644 (file)
@@ -1353,7 +1353,6 @@ DEFINE_METHOD(JIT_HELPERS,          CONTAINSREFERENCES,     ContainsReferences,
 DEFINE_CLASS(UNSAFE,                CompilerServices,       Unsafe)
 DEFINE_METHOD(UNSAFE,               AS_POINTER,             AsPointer, NoSig)
 DEFINE_METHOD(UNSAFE,               SIZEOF,                 SizeOf, NoSig)
-DEFINE_METHOD(UNSAFE,               AS_REF,                 AsRef, NoSig)
 DEFINE_METHOD(UNSAFE,               BYREF_AS,               As, NoSig)
 DEFINE_METHOD(UNSAFE,               BYREF_ADD,              Add, NoSig)
 DEFINE_METHOD(UNSAFE,               BYREF_ARE_SAME,         AreSame, NoSig)