Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Commit 562bc0a

Browse files
danmoseleyahsonkhan
authored andcommitted
Port two changes from CoreFX missed by mirror: (#17713)
commit b4d701a Author: Ahson Khan <[email protected]> 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 76e0104 Author: Ahson Khan <[email protected]> Date: Mon Apr 16 01:54:54 2018 -0700 Update xml comment for {ReadOnly}Memory.Pin method (#29137)
1 parent 10b2161 commit 562bc0a

File tree

2 files changed

+42
-10
lines changed

2 files changed

+42
-10
lines changed

src/mscorlib/shared/System/Memory.cs

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -318,8 +318,11 @@ public Span<T> Span
318318

319319
/// <summary>
320320
/// Creates a handle for the memory.
321-
/// The GC will not move the array until the returned <see cref="MemoryHandle"/>
321+
/// The GC will not move the memory until the returned <see cref="MemoryHandle"/>
322322
/// is disposed, enabling taking and using the memory's address.
323+
/// <exception cref="System.ArgumentException">
324+
/// An instance with nonprimitive (non-blittable) members cannot be pinned.
325+
/// </exception>
323326
/// </summary>
324327
public unsafe MemoryHandle Pin()
325328
{
@@ -345,13 +348,26 @@ public unsafe MemoryHandle Pin()
345348
}
346349
else if (_object is T[] array)
347350
{
348-
GCHandle handle = _length < 0 ? default : GCHandle.Alloc(array, GCHandleType.Pinned);
351+
// Array is already pre-pinned
352+
if (_length < 0)
353+
{
349354
#if FEATURE_PORTABLE_SPAN
350-
void* pointer = Unsafe.Add<T>((void*)handle.AddrOfPinnedObject(), _index);
355+
void* pointer = Unsafe.Add<T>(Unsafe.AsPointer(ref MemoryMarshal.GetReference<T>(array)), _index);
351356
#else
352-
void* pointer = Unsafe.Add<T>(Unsafe.AsPointer(ref array.GetRawSzArrayData()), _index);
357+
void* pointer = Unsafe.Add<T>(Unsafe.AsPointer(ref array.GetRawSzArrayData()), _index);
353358
#endif // FEATURE_PORTABLE_SPAN
354-
return new MemoryHandle(pointer, handle);
359+
return new MemoryHandle(pointer);
360+
}
361+
else
362+
{
363+
GCHandle handle = GCHandle.Alloc(array, GCHandleType.Pinned);
364+
#if FEATURE_PORTABLE_SPAN
365+
void* pointer = Unsafe.Add<T>((void*)handle.AddrOfPinnedObject(), _index);
366+
#else
367+
void* pointer = Unsafe.Add<T>(Unsafe.AsPointer(ref array.GetRawSzArrayData()), _index);
368+
#endif // FEATURE_PORTABLE_SPAN
369+
return new MemoryHandle(pointer, handle);
370+
}
355371
}
356372
return default;
357373
}

src/mscorlib/shared/System/ReadOnlyMemory.cs

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -235,8 +235,11 @@ public ReadOnlySpan<T> Span
235235

236236
/// <summary>
237237
/// Creates a handle for the memory.
238-
/// The GC will not move the array until the returned <see cref="MemoryHandle"/>
238+
/// The GC will not move the memory until the returned <see cref="MemoryHandle"/>
239239
/// is disposed, enabling taking and using the memory's address.
240+
/// <exception cref="System.ArgumentException">
241+
/// An instance with nonprimitive (non-blittable) members cannot be pinned.
242+
/// </exception>
240243
/// </summary>
241244
public unsafe MemoryHandle Pin()
242245
{
@@ -257,13 +260,26 @@ public unsafe MemoryHandle Pin()
257260
}
258261
else if (_object is T[] array)
259262
{
260-
GCHandle handle = _length < 0 ? default : GCHandle.Alloc(array, GCHandleType.Pinned);
263+
// Array is already pre-pinned
264+
if (_length < 0)
265+
{
261266
#if FEATURE_PORTABLE_SPAN
262-
void* pointer = Unsafe.Add<T>((void*)handle.AddrOfPinnedObject(), _index);
267+
void* pointer = Unsafe.Add<T>(Unsafe.AsPointer(ref MemoryMarshal.GetReference<T>(array)), _index);
263268
#else
264-
void* pointer = Unsafe.Add<T>(Unsafe.AsPointer(ref array.GetRawSzArrayData()), _index);
269+
void* pointer = Unsafe.Add<T>(Unsafe.AsPointer(ref array.GetRawSzArrayData()), _index);
265270
#endif // FEATURE_PORTABLE_SPAN
266-
return new MemoryHandle(pointer, handle);
271+
return new MemoryHandle(pointer);
272+
}
273+
else
274+
{
275+
GCHandle handle = GCHandle.Alloc(array, GCHandleType.Pinned);
276+
#if FEATURE_PORTABLE_SPAN
277+
void* pointer = Unsafe.Add<T>((void*)handle.AddrOfPinnedObject(), _index);
278+
#else
279+
void* pointer = Unsafe.Add<T>(Unsafe.AsPointer(ref array.GetRawSzArrayData()), _index);
280+
#endif // FEATURE_PORTABLE_SPAN
281+
return new MemoryHandle(pointer, handle);
282+
}
267283
}
268284
return default;
269285
}

0 commit comments

Comments
 (0)