Adding Unsafe.Add that takes nuint instead of int32
authorahsonkhan <ahson_ahmedk@yahoo.com>
Wed, 22 Feb 2017 02:33:56 +0000 (18:33 -0800)
committerahsonkhan <ahson_ahmedk@yahoo.com>
Wed, 22 Feb 2017 02:33:56 +0000 (18:33 -0800)
src/mscorlib/src/System/Runtime/CompilerServices/Unsafe.cs
src/mscorlib/src/System/Span.cs
src/vm/jitinterface.cpp
src/vm/mscorlib.h

index adfa015..571d097 100644 (file)
@@ -4,6 +4,12 @@
 
 using System.Runtime.Versioning;
 
+#if BIT64
+using nuint = System.UInt64;
+#else
+using nuint = System.UInt32;
+#endif
+
 namespace System.Runtime.CompilerServices
 {
     //
@@ -66,6 +72,19 @@ namespace System.Runtime.CompilerServices
         }
 
         /// <summary>
+        /// Adds an element offset to the given reference.
+        /// </summary>
+        [NonVersionable]
+        [MethodImpl(MethodImplOptions.AggressiveInlining)]
+        public static ref T AddNative<T>(ref T source, nuint elementOffset)
+        {
+            // The body of this function will be replaced by the EE with unsafe code!!!
+            // See getILIntrinsicImplementationForUnsafe for how this happens.
+            typeof(T).ToString(); // Type used by the actual method body
+            throw new InvalidOperationException();
+        }
+
+        /// <summary>
         /// Determines whether the specified references point to the same location.
         /// </summary>
         [NonVersionable]
index 7435a93..0c548a9 100644 (file)
@@ -752,11 +752,7 @@ namespace System
             }
 
             // P/Invoke into the native version for large lengths
-            if (byteLength >= 512)
-            {
-                RuntimeImports.RhZeroMemory(ref b, byteLength);
-                return;
-            }
+            if (byteLength >= 512) goto PInvoke;
 
             nuint i = 0; // byte offset at which we're copying
 
@@ -844,6 +840,11 @@ namespace System
                 // We're not using i after this, so not needed
                 // i += 1;
             }
+
+            return;
+            
+            PInvoke:
+            RuntimeImports.RhZeroMemory(ref b, byteLength);
         }
 
         internal static unsafe void ClearWithReferences(ref IntPtr ip, nuint pointerSizeLength)
@@ -857,41 +858,34 @@ namespace System
             nuint n = 0;
             while ((n = i + 8) <= (pointerSizeLength))
             {
-                Unsafe.Add<IntPtr>(ref ip, (int)i + 0) = default(IntPtr);
-                Unsafe.Add<IntPtr>(ref ip, (int)i + 1) = default(IntPtr);
-                Unsafe.Add<IntPtr>(ref ip, (int)i + 2) = default(IntPtr);
-                Unsafe.Add<IntPtr>(ref ip, (int)i + 3) = default(IntPtr);
-                Unsafe.Add<IntPtr>(ref ip, (int)i + 4) = default(IntPtr);
-                Unsafe.Add<IntPtr>(ref ip, (int)i + 5) = default(IntPtr);
-                Unsafe.Add<IntPtr>(ref ip, (int)i + 6) = default(IntPtr);
-                Unsafe.Add<IntPtr>(ref ip, (int)i + 7) = default(IntPtr);
+                Unsafe.AddNative<IntPtr>(ref ip, i + 0) = default(IntPtr);
+                Unsafe.AddNative<IntPtr>(ref ip, i + 1) = default(IntPtr);
+                Unsafe.AddNative<IntPtr>(ref ip, i + 2) = default(IntPtr);
+                Unsafe.AddNative<IntPtr>(ref ip, i + 3) = default(IntPtr);
+                Unsafe.AddNative<IntPtr>(ref ip, i + 4) = default(IntPtr);
+                Unsafe.AddNative<IntPtr>(ref ip, i + 5) = default(IntPtr);
+                Unsafe.AddNative<IntPtr>(ref ip, i + 6) = default(IntPtr);
+                Unsafe.AddNative<IntPtr>(ref ip, i + 7) = default(IntPtr);
                 i = n;
             }
             if ((n = i + 4) <= (pointerSizeLength))
             {
-                Unsafe.Add<IntPtr>(ref ip, (int)i + 0) = default(IntPtr);
-                Unsafe.Add<IntPtr>(ref ip, (int)i + 1) = default(IntPtr);
-                Unsafe.Add<IntPtr>(ref ip, (int)i + 2) = default(IntPtr);
-                Unsafe.Add<IntPtr>(ref ip, (int)i + 3) = default(IntPtr);
+                Unsafe.AddNative<IntPtr>(ref ip, i + 0) = default(IntPtr);
+                Unsafe.AddNative<IntPtr>(ref ip, i + 1) = default(IntPtr);
+                Unsafe.AddNative<IntPtr>(ref ip, i + 2) = default(IntPtr);
+                Unsafe.AddNative<IntPtr>(ref ip, i + 3) = default(IntPtr);
                 i = n;
             }
             if ((n = i + 2) <= (pointerSizeLength))
             {
-                Unsafe.Add<IntPtr>(ref ip, (int)i + 0) = default(IntPtr);
-                Unsafe.Add<IntPtr>(ref ip, (int)i + 1) = default(IntPtr);
+                Unsafe.AddNative<IntPtr>(ref ip, i + 0) = default(IntPtr);
+                Unsafe.AddNative<IntPtr>(ref ip, i + 1) = default(IntPtr);
                 i = n;
             }
             if ((i + 1) <= (pointerSizeLength))
             {
-                Unsafe.Add<IntPtr>(ref ip, (int)i) = default(IntPtr);
+                Unsafe.AddNative<IntPtr>(ref ip, i) = default(IntPtr);
             }
         }
-
-        [StructLayout(LayoutKind.Sequential, Size = 64)]
-        private struct Reg64 { }
-        [StructLayout(LayoutKind.Sequential, Size = 32)]
-        private struct Reg32 { }
-        [StructLayout(LayoutKind.Sequential, Size = 16)]
-        private struct Reg16 { }
     }
 }
index b05b891..6f69003 100644 (file)
@@ -7060,6 +7060,28 @@ bool getILIntrinsicImplementationForUnsafe(MethodDesc * ftn,
         methInfo->options = (CorInfoOptions)0;
         return true;
     }
+    else if (tk == MscorlibBinder::GetMethod(METHOD__UNSAFE__BYREF_ADD_NATIVE)->GetMemberDef())
+    {
+        mdToken tokGenericArg = FindGenericMethodArgTypeSpec(MscorlibBinder::GetModule()->GetMDImport());
+        
+        static BYTE ilcode[] = { CEE_LDARG_0, CEE_LDARG_1,
+            CEE_PREFIX1, (CEE_SIZEOF & 0xFF), 0,0,0,0,
+            CEE_MUL,
+            CEE_ADD,
+            CEE_RET };
+
+        ilcode[4] = (BYTE)(tokGenericArg);
+        ilcode[5] = (BYTE)(tokGenericArg >> 8);
+        ilcode[6] = (BYTE)(tokGenericArg >> 16);
+        ilcode[7] = (BYTE)(tokGenericArg >> 24);
+
+        methInfo->ILCode = const_cast<BYTE*>(ilcode);
+        methInfo->ILCodeSize = sizeof(ilcode);
+        methInfo->maxStack = 3;
+        methInfo->EHcount = 0;
+        methInfo->options = (CorInfoOptions)0;
+        return true;
+    }
     else if (tk == MscorlibBinder::GetMethod(METHOD__UNSAFE__BYREF_ARE_SAME)->GetMemberDef())
     {
         // Compare the two arguments
index f466c2f..023ecd9 100644 (file)
@@ -1109,6 +1109,7 @@ DEFINE_METHOD(UNSAFE,               AS_POINTER,             AsPointer, NoSig)
 DEFINE_METHOD(UNSAFE,               SIZEOF,                 SizeOf, NoSig)
 DEFINE_METHOD(UNSAFE,               BYREF_AS,               As, NoSig)
 DEFINE_METHOD(UNSAFE,               BYREF_ADD,              Add, NoSig)
+DEFINE_METHOD(UNSAFE,               BYREF_ADD_NATIVE,              AddNative, NoSig)
 DEFINE_METHOD(UNSAFE,               BYREF_ARE_SAME,         AreSame, NoSig)
 DEFINE_METHOD(UNSAFE,               BYREF_INIT_BLOCK_UNALIGNED, InitBlockUnaligned, NoSig)