summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Moseley <danmose@microsoft.com>2018-04-20 19:26:22 -0700
committerAhson Khan <ahkha@microsoft.com>2018-04-20 19:26:22 -0700
commit562bc0ab837994ae30581b94ed6805c83b090455 (patch)
tree0680ff4fb11496aa4ce7fd22fe21c8a1ebdfc8ef
parent10b2161a6f7f5ccb8dffde4c7c82c926447dbb0b (diff)
downloadcoreclr-562bc0ab837994ae30581b94ed6805c83b090455.tar.gz
coreclr-562bc0ab837994ae30581b94ed6805c83b090455.tar.bz2
coreclr-562bc0ab837994ae30581b94ed6805c83b090455.zip
Port two changes from CoreFX missed by mirror: (#17713)
commit b4d701a72c20b695715371a99b48473053b63250 Author: Ahson Khan <ahkha@microsoft.com> Date: Wed Apr 11 13:43:36 2018 -0700 Add CreateFromPinnedArray to System.Memory ref and add tests (#28992) * Fixing bug in Memory.Pin and adding API to uapaot baseline commit 76e01040fcfdb1c652ef1bf4e8e123c7db4e1be8 Author: Ahson Khan <ahkha@microsoft.com> Date: Mon Apr 16 01:54:54 2018 -0700 Update xml comment for {ReadOnly}Memory.Pin method (#29137)
-rw-r--r--src/mscorlib/shared/System/Memory.cs26
-rw-r--r--src/mscorlib/shared/System/ReadOnlyMemory.cs26
2 files changed, 42 insertions, 10 deletions
diff --git a/src/mscorlib/shared/System/Memory.cs b/src/mscorlib/shared/System/Memory.cs
index 26f4e4ce19..c06b1b4d9a 100644
--- a/src/mscorlib/shared/System/Memory.cs
+++ b/src/mscorlib/shared/System/Memory.cs
@@ -318,8 +318,11 @@ namespace System
/// <summary>
/// Creates a handle for the memory.
- /// The GC will not move the array until the returned <see cref="MemoryHandle"/>
+ /// The GC will not move the memory until the returned <see cref="MemoryHandle"/>
/// is disposed, enabling taking and using the memory's address.
+ /// <exception cref="System.ArgumentException">
+ /// An instance with nonprimitive (non-blittable) members cannot be pinned.
+ /// </exception>
/// </summary>
public unsafe MemoryHandle Pin()
{
@@ -345,13 +348,26 @@ namespace System
}
else if (_object is T[] array)
{
- GCHandle handle = _length < 0 ? default : GCHandle.Alloc(array, GCHandleType.Pinned);
+ // Array is already pre-pinned
+ if (_length < 0)
+ {
#if FEATURE_PORTABLE_SPAN
- void* pointer = Unsafe.Add<T>((void*)handle.AddrOfPinnedObject(), _index);
+ void* pointer = Unsafe.Add<T>(Unsafe.AsPointer(ref MemoryMarshal.GetReference<T>(array)), _index);
#else
- void* pointer = Unsafe.Add<T>(Unsafe.AsPointer(ref array.GetRawSzArrayData()), _index);
+ void* pointer = Unsafe.Add<T>(Unsafe.AsPointer(ref array.GetRawSzArrayData()), _index);
#endif // FEATURE_PORTABLE_SPAN
- return new MemoryHandle(pointer, handle);
+ return new MemoryHandle(pointer);
+ }
+ else
+ {
+ GCHandle handle = GCHandle.Alloc(array, GCHandleType.Pinned);
+#if FEATURE_PORTABLE_SPAN
+ void* pointer = Unsafe.Add<T>((void*)handle.AddrOfPinnedObject(), _index);
+#else
+ void* pointer = Unsafe.Add<T>(Unsafe.AsPointer(ref array.GetRawSzArrayData()), _index);
+#endif // FEATURE_PORTABLE_SPAN
+ return new MemoryHandle(pointer, handle);
+ }
}
return default;
}
diff --git a/src/mscorlib/shared/System/ReadOnlyMemory.cs b/src/mscorlib/shared/System/ReadOnlyMemory.cs
index 3e7884528e..91a35225a3 100644
--- a/src/mscorlib/shared/System/ReadOnlyMemory.cs
+++ b/src/mscorlib/shared/System/ReadOnlyMemory.cs
@@ -235,8 +235,11 @@ namespace System
/// <summary>
/// Creates a handle for the memory.
- /// The GC will not move the array until the returned <see cref="MemoryHandle"/>
+ /// The GC will not move the memory until the returned <see cref="MemoryHandle"/>
/// is disposed, enabling taking and using the memory's address.
+ /// <exception cref="System.ArgumentException">
+ /// An instance with nonprimitive (non-blittable) members cannot be pinned.
+ /// </exception>
/// </summary>
public unsafe MemoryHandle Pin()
{
@@ -257,13 +260,26 @@ namespace System
}
else if (_object is T[] array)
{
- GCHandle handle = _length < 0 ? default : GCHandle.Alloc(array, GCHandleType.Pinned);
+ // Array is already pre-pinned
+ if (_length < 0)
+ {
#if FEATURE_PORTABLE_SPAN
- void* pointer = Unsafe.Add<T>((void*)handle.AddrOfPinnedObject(), _index);
+ void* pointer = Unsafe.Add<T>(Unsafe.AsPointer(ref MemoryMarshal.GetReference<T>(array)), _index);
#else
- void* pointer = Unsafe.Add<T>(Unsafe.AsPointer(ref array.GetRawSzArrayData()), _index);
+ void* pointer = Unsafe.Add<T>(Unsafe.AsPointer(ref array.GetRawSzArrayData()), _index);
#endif // FEATURE_PORTABLE_SPAN
- return new MemoryHandle(pointer, handle);
+ return new MemoryHandle(pointer);
+ }
+ else
+ {
+ GCHandle handle = GCHandle.Alloc(array, GCHandleType.Pinned);
+#if FEATURE_PORTABLE_SPAN
+ void* pointer = Unsafe.Add<T>((void*)handle.AddrOfPinnedObject(), _index);
+#else
+ void* pointer = Unsafe.Add<T>(Unsafe.AsPointer(ref array.GetRawSzArrayData()), _index);
+#endif // FEATURE_PORTABLE_SPAN
+ return new MemoryHandle(pointer, handle);
+ }
}
return default;
}