summaryrefslogtreecommitdiff
path: root/src/System.Private.CoreLib/src/System
diff options
context:
space:
mode:
authorJan Kotas <jkotas@microsoft.com>2019-01-20 08:16:44 -0800
committerGitHub <noreply@github.com>2019-01-20 08:16:44 -0800
commit170854b92017d709bc82d7631c6cb33dd7443078 (patch)
treee4d216f1b1be6d9207644e160f86af8846c02577 /src/System.Private.CoreLib/src/System
parent614966d1e179c32ce85df2791102847128390ca6 (diff)
downloadcoreclr-170854b92017d709bc82d7631c6cb33dd7443078.tar.gz
coreclr-170854b92017d709bc82d7631c6cb33dd7443078.tar.bz2
coreclr-170854b92017d709bc82d7631c6cb33dd7443078.zip
Cleanup array related FCalls (#22097)
* Cleanup Array FCalls * Disable outdated CoreFX tests https://github.com/dotnet/corefx/pull/34700
Diffstat (limited to 'src/System.Private.CoreLib/src/System')
-rw-r--r--src/System.Private.CoreLib/src/System/Array.cs5
-rw-r--r--src/System.Private.CoreLib/src/System/Buffer.cs27
-rw-r--r--src/System.Private.CoreLib/src/System/RtType.cs12
-rw-r--r--src/System.Private.CoreLib/src/System/Runtime/CompilerServices/jithelpers.cs4
-rw-r--r--src/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.cs68
5 files changed, 65 insertions, 51 deletions
diff --git a/src/System.Private.CoreLib/src/System/Array.cs b/src/System.Private.CoreLib/src/System/Array.cs
index 41e8d794f5..3192ba96e2 100644
--- a/src/System.Private.CoreLib/src/System/Array.cs
+++ b/src/System.Private.CoreLib/src/System/Array.cs
@@ -555,7 +555,10 @@ namespace System
public extern int GetLowerBound(int dimension);
[MethodImplAttribute(MethodImplOptions.InternalCall)]
- internal extern int GetDataPtrOffsetInternal();
+ internal extern ref byte GetRawArrayData();
+
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ internal extern int GetElementSize();
// Number of elements in the Array.
int ICollection.Count
diff --git a/src/System.Private.CoreLib/src/System/Buffer.cs b/src/System.Private.CoreLib/src/System/Buffer.cs
index 73e8bce7b8..af94e8e08d 100644
--- a/src/System.Private.CoreLib/src/System/Buffer.cs
+++ b/src/System.Private.CoreLib/src/System/Buffer.cs
@@ -60,15 +60,6 @@ namespace System
return _ByteLength(array);
}
- // Gets a particular byte out of the array. The array must be an
- // array of primitives.
- //
- // This essentially does the following:
- // return ((byte*)array) + index.
- //
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- private static extern byte _GetByte(Array array, int index);
-
public static byte GetByte(Array array, int index)
{
// Is the array present?
@@ -80,21 +71,12 @@ namespace System
throw new ArgumentException(SR.Arg_MustBePrimArray, nameof(array));
// Is the index in valid range of the array?
- if (index < 0 || index >= _ByteLength(array))
+ if ((uint)index >= (uint)_ByteLength(array))
throw new ArgumentOutOfRangeException(nameof(index));
- return _GetByte(array, index);
+ return Unsafe.Add<byte>(ref array.GetRawArrayData(), index);
}
- // Sets a particular byte in an the array. The array must be an
- // array of primitives.
- //
- // This essentially does the following:
- // *(((byte*)array) + index) = value.
- //
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- private static extern void _SetByte(Array array, int index, byte value);
-
public static void SetByte(Array array, int index, byte value)
{
// Is the array present?
@@ -106,11 +88,10 @@ namespace System
throw new ArgumentException(SR.Arg_MustBePrimArray, nameof(array));
// Is the index in valid range of the array?
- if (index < 0 || index >= _ByteLength(array))
+ if ((uint)index >= (uint)_ByteLength(array))
throw new ArgumentOutOfRangeException(nameof(index));
- // Make the FCall to do the work
- _SetByte(array, index, value);
+ Unsafe.Add<byte>(ref array.GetRawArrayData(), index) = value;
}
// This is currently used by System.IO.UnmanagedMemoryStream
diff --git a/src/System.Private.CoreLib/src/System/RtType.cs b/src/System.Private.CoreLib/src/System/RtType.cs
index c1ace86f6a..921c15e25b 100644
--- a/src/System.Private.CoreLib/src/System/RtType.cs
+++ b/src/System.Private.CoreLib/src/System/RtType.cs
@@ -2614,11 +2614,7 @@ namespace System
public override Type[] GetInterfaces()
{
RuntimeType[] candidates = Cache.GetInterfaceList(MemberListType.All, null);
- Type[] interfaces = new Type[candidates.Length];
- for (int i = 0; i < candidates.Length; i++)
- JitHelpers.UnsafeSetArrayElement(interfaces, i, candidates[i]);
-
- return interfaces;
+ return new ReadOnlySpan<Type>(candidates).ToArray();
}
public override Type[] GetNestedTypes(BindingFlags bindingAttr)
@@ -3430,11 +3426,7 @@ namespace System
string[] ret = Enum.InternalGetNames(this);
// Make a copy since we can't hand out the same array since users can modify them
- string[] retVal = new string[ret.Length];
-
- Array.Copy(ret, 0, retVal, 0, ret.Length);
-
- return retVal;
+ return new ReadOnlySpan<string>(ret).ToArray();
}
public override Array GetEnumValues()
diff --git a/src/System.Private.CoreLib/src/System/Runtime/CompilerServices/jithelpers.cs b/src/System.Private.CoreLib/src/System/Runtime/CompilerServices/jithelpers.cs
index b8bb7c4981..10808216b0 100644
--- a/src/System.Private.CoreLib/src/System/Runtime/CompilerServices/jithelpers.cs
+++ b/src/System.Private.CoreLib/src/System/Runtime/CompilerServices/jithelpers.cs
@@ -99,10 +99,6 @@ namespace System.Runtime.CompilerServices
return x.CompareTo(y);
}
- // Set the given element in the array without any type or range checks
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- internal static extern void UnsafeSetArrayElement(object[] target, int index, object element);
-
internal static ref byte GetRawData(this object obj) =>
ref Unsafe.As<RawData>(obj).Data;
diff --git a/src/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.cs b/src/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.cs
index 5e9fd31081..5e1396b670 100644
--- a/src/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.cs
+++ b/src/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.cs
@@ -4,16 +4,23 @@
using System.Collections.Generic;
using System.Reflection;
-using System.Reflection.Emit;
using System.Security;
using System.Text;
using System.Runtime.CompilerServices;
using System.Runtime.ConstrainedExecution;
-using Win32Native = Microsoft.Win32.Win32Native;
+using Microsoft.Win32;
using System.Diagnostics;
using System.Runtime.InteropServices.ComTypes;
using System.StubHelpers;
+using Internal.Runtime.CompilerServices;
+
+#if BIT64
+using nuint = System.UInt64;
+#else
+using nuint = System.UInt32;
+#endif // BIT64
+
namespace System.Runtime.InteropServices
{
/// <summary>
@@ -238,15 +245,25 @@ namespace System.Runtime.InteropServices
/// <summary>
/// IMPORTANT NOTICE: This method does not do any verification on the array.
- /// It must be used with EXTREME CAUTION since passing in an array that is
- /// not pinned or in the fixed heap can cause unexpected results.
+ /// It must be used with EXTREME CAUTION since passing in invalid index or
+ /// an array that is not pinned can cause unexpected results.
/// </summary>
- [MethodImpl(MethodImplOptions.InternalCall)]
- public static extern IntPtr UnsafeAddrOfPinnedArrayElement(Array arr, int index);
+ public static unsafe IntPtr UnsafeAddrOfPinnedArrayElement(Array arr, int index)
+ {
+ if (arr == null)
+ throw new ArgumentNullException(nameof(arr));
- public static IntPtr UnsafeAddrOfPinnedArrayElement<T>(T[] arr, int index)
+ void* pRawData = Unsafe.AsPointer(ref arr.GetRawArrayData());
+ return (IntPtr)((byte*)pRawData + (uint)index * (nuint)arr.GetElementSize());
+ }
+
+ public static unsafe IntPtr UnsafeAddrOfPinnedArrayElement<T>(T[] arr, int index)
{
- return UnsafeAddrOfPinnedArrayElement((Array)arr, index);
+ if (arr == null)
+ throw new ArgumentNullException(nameof(arr));
+
+ void* pRawData = Unsafe.AsPointer(ref arr.GetRawSzArrayData());
+ return (IntPtr)((byte*)pRawData + (uint)index * (nuint)Unsafe.SizeOf<T>());
}
public static void Copy(int[] source, int startIndex, IntPtr destination, int length)
@@ -289,8 +306,17 @@ namespace System.Runtime.InteropServices
CopyToNative(source, startIndex, destination, length);
}
- [MethodImpl(MethodImplOptions.InternalCall)]
- private static extern void CopyToNative(object source, int startIndex, IntPtr destination, int length);
+ private static unsafe void CopyToNative<T>(T[] source, int startIndex, IntPtr destination, int length)
+ {
+ if (source == null)
+ throw new ArgumentNullException(nameof(source));
+ if (destination == IntPtr.Zero)
+ throw new ArgumentNullException(nameof(destination));
+
+ // The rest of the argument validation is done by CopyTo
+
+ new Span<T>(source, startIndex, length).CopyTo(new Span<T>((void*)destination, length));
+ }
public static void Copy(IntPtr source, int[] destination, int startIndex, int length)
{
@@ -332,9 +358,22 @@ namespace System.Runtime.InteropServices
CopyToManaged(source, destination, startIndex, length);
}
- [MethodImpl(MethodImplOptions.InternalCall)]
- private static extern void CopyToManaged(IntPtr source, object destination, int startIndex, int length);
-
+ private static unsafe void CopyToManaged<T>(IntPtr source, T[] destination, int startIndex, int length)
+ {
+ if (source == IntPtr.Zero)
+ throw new ArgumentNullException(nameof(source));
+ if (destination == null)
+ throw new ArgumentNullException(nameof(destination));
+ if (startIndex < 0)
+ throw new ArgumentOutOfRangeException(nameof(startIndex), SR.ArgumentOutOfRange_StartIndex);
+ if (length < 0)
+ throw new ArgumentOutOfRangeException(nameof(length), SR.ArgumentOutOfRange_NeedNonNegNum);
+
+ // The rest of the argument validation is done by CopyTo
+
+ new Span<T>((void*)source, length).CopyTo(new Span<T>(destination, startIndex, length));
+ }
+
public static byte ReadByte(object ptr, int ofs)
{
return ReadValueSlow(ptr, ofs, (IntPtr nativeHome, int offset) => ReadByte(nativeHome, offset));
@@ -837,6 +876,9 @@ namespace System.Runtime.InteropServices
public static void DestroyStructure<T>(IntPtr ptr) => DestroyStructure(ptr, typeof(T));
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ internal static extern bool IsPinnable(object obj);
+
#if FEATURE_COMINTEROP
/// <summary>
/// Returns the HInstance for this module. Returns -1 if the module doesn't have