Minor SpanHelpers cleanup (#259)
authorJan Kotas <jkotas@microsoft.com>
Tue, 26 Nov 2019 15:04:02 +0000 (07:04 -0800)
committerGitHub <noreply@github.com>
Tue, 26 Nov 2019 15:04:02 +0000 (07:04 -0800)
- Use ifdef instead of runtime condition
- Use explicit signature for Unsafe.AddByteOffset in VM. We were getting lucky that the right overload of Unsafe.AddByteOffset was choosen by the VM.

src/coreclr/src/vm/mscorlib.h
src/libraries/System.Private.CoreLib/src/Internal/Runtime/CompilerServices/Unsafe.cs
src/libraries/System.Private.CoreLib/src/System/SpanHelpers.Char.cs

index 575d92c..ce78a3f 100644 (file)
@@ -731,7 +731,7 @@ DEFINE_METHOD(UNSAFE,               BYREF_ADD,              Add, GM_RefT_Int_Ret
 DEFINE_METHOD(UNSAFE,               BYREF_INTPTR_ADD,       Add, GM_RefT_IntPtr_RetRefT)
 DEFINE_METHOD(UNSAFE,               PTR_ADD,                Add, GM_PtrVoid_Int_RetPtrVoid)
 DEFINE_METHOD(UNSAFE,               BYREF_BYTE_OFFSET,      ByteOffset, NoSig)
-DEFINE_METHOD(UNSAFE,               BYREF_ADD_BYTE_OFFSET,  AddByteOffset, NoSig)
+DEFINE_METHOD(UNSAFE,               BYREF_ADD_BYTE_OFFSET,  AddByteOffset, GM_RefT_IntPtr_RetRefT)
 DEFINE_METHOD(UNSAFE,               BYREF_ARE_SAME,         AreSame, NoSig)
 DEFINE_METHOD(UNSAFE,               BYREF_IS_ADDRESS_GREATER_THAN, IsAddressGreaterThan, NoSig)
 DEFINE_METHOD(UNSAFE,               BYREF_IS_ADDRESS_LESS_THAN, IsAddressLessThan, NoSig)
index 7c5f9f7..32ceaf8 100644 (file)
@@ -11,16 +11,11 @@ using System.Runtime.Versioning;
 #pragma warning disable SA1121 // explicitly using type aliases instead of built-in types
 #if BIT64
 using nuint = System.UInt64;
-#else
-using nuint = System.UInt32;
-#endif
-#if !CORECLR
-#if BIT64
 using nint = System.Int64;
 #else
+using nuint = System.UInt32;
 using nint = System.Int32;
 #endif
-#endif
 
 //
 // The implementations of most the methods in this file are provided as intrinsics.
@@ -150,12 +145,25 @@ namespace Internal.Runtime.CompilerServices
 #endif
         }
 
+#if BIT64
         /// <summary>
         /// Adds an element offset to the given reference.
         /// </summary>
         [Intrinsic]
         [NonVersionable]
         [MethodImpl(MethodImplOptions.AggressiveInlining)]
+        internal static ref T Add<T>(ref T source, nint elementOffset)
+        {
+            return ref Unsafe.Add(ref source, (IntPtr)(void*)elementOffset);
+        }
+#endif
+
+        /// <summary>
+        /// Adds an byte offset to the given reference.
+        /// </summary>
+        [Intrinsic]
+        [NonVersionable]
+        [MethodImpl(MethodImplOptions.AggressiveInlining)]
         internal static ref T AddByteOffset<T>(ref T source, nuint byteOffset)
         {
             return ref AddByteOffset(ref source, (IntPtr)(void*)byteOffset);
@@ -295,7 +303,7 @@ namespace Internal.Runtime.CompilerServices
         }
 
         /// <summary>
-        /// Adds an element offset to the given reference.
+        /// Adds an byte offset to the given reference.
         /// </summary>
         [Intrinsic]
         [NonVersionable]
index 7d4d27a..25dc8f6 100644 (file)
@@ -107,7 +107,8 @@ namespace System
                 }
             }
 
-            if (sizeof(UIntPtr) > sizeof(int) && (byte*)minLength >= (byte*)(i + sizeof(int) / sizeof(char)))
+#if BIT64
+            if ((byte*)minLength >= (byte*)(i + sizeof(int) / sizeof(char)))
             {
                 if (Unsafe.ReadUnaligned<int>(ref Unsafe.As<char, byte>(ref Unsafe.Add(ref first, i))) ==
                     Unsafe.ReadUnaligned<int>(ref Unsafe.As<char, byte>(ref Unsafe.Add(ref second, i))))
@@ -115,6 +116,7 @@ namespace System
                     i += sizeof(int) / sizeof(char);
                 }
             }
+#endif
 
             while ((byte*)i < (byte*)minLength)
             {
@@ -254,15 +256,15 @@ namespace System
             // remaining data that is shorter than a Vector length.
             while (lengthToExamine >= 4)
             {
-                ref char current = ref Add(ref searchSpace, offset);
+                ref char current = ref Unsafe.Add(ref searchSpace, offset);
 
                 if (value == current)
                     goto Found;
-                if (value == Add(ref current, 1))
+                if (value == Unsafe.Add(ref current, 1))
                     goto Found1;
-                if (value == Add(ref current, 2))
+                if (value == Unsafe.Add(ref current, 2))
                     goto Found2;
-                if (value == Add(ref current, 3))
+                if (value == Unsafe.Add(ref current, 3))
                     goto Found3;
 
                 offset += 4;
@@ -271,7 +273,7 @@ namespace System
 
             while (lengthToExamine > 0)
             {
-                if (value == Add(ref searchSpace, offset))
+                if (value == Unsafe.Add(ref searchSpace, offset))
                     goto Found;
 
                 offset++;
@@ -1032,10 +1034,6 @@ namespace System
         }
 
         [MethodImpl(MethodImplOptions.AggressiveInlining)]
-        public static ref char Add(ref char source, nint elementOffset)
-            => ref Unsafe.Add(ref source, (IntPtr)elementOffset);
-
-        [MethodImpl(MethodImplOptions.AggressiveInlining)]
         private static unsafe Vector<ushort> LoadVector(ref char start, nint offset)
             => Unsafe.ReadUnaligned<Vector<ushort>>(ref Unsafe.As<char, byte>(ref Unsafe.Add(ref start, (IntPtr)offset)));