@@ -235,8 +235,11 @@ public ReadOnlySpan<T> Span
235
235
236
236
/// <summary>
237
237
/// 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"/>
239
239
/// 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>
240
243
/// </summary>
241
244
public unsafe MemoryHandle Pin ( )
242
245
{
@@ -257,13 +260,26 @@ public unsafe MemoryHandle Pin()
257
260
}
258
261
else if ( _object is T [ ] array )
259
262
{
260
- GCHandle handle = _length < 0 ? default : GCHandle . Alloc ( array , GCHandleType . Pinned ) ;
263
+ // Array is already pre-pinned
264
+ if ( _length < 0 )
265
+ {
261
266
#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 ) ;
263
268
#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 ) ;
265
270
#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
+ }
267
283
}
268
284
return default ;
269
285
}
0 commit comments