@@ -225,13 +225,16 @@ public override string ToString()
225
225
[ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
226
226
public Memory < T > Slice ( int start )
227
227
{
228
- int actualLength = _length & RemoveFlagsBitMask ;
228
+ // Used to maintain the high-bit which indicates whether the Memory has been pre-pinned or not.
229
+ int capturedLength = _length ;
230
+ int actualLength = capturedLength & RemoveFlagsBitMask ;
229
231
if ( ( uint ) start > ( uint ) actualLength )
230
232
{
231
233
ThrowHelper . ThrowArgumentOutOfRangeException ( ExceptionArgument . start ) ;
232
234
}
233
235
234
- return new Memory < T > ( _object , _index + start , actualLength - start ) ;
236
+ // It is expected for (capturedLength - start) to be negative if the memory is already pre-pinned.
237
+ return new Memory < T > ( _object , _index + start , capturedLength - start ) ;
235
238
}
236
239
237
240
/// <summary>
@@ -245,13 +248,16 @@ public Memory<T> Slice(int start)
245
248
[ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
246
249
public Memory < T > Slice ( int start , int length )
247
250
{
248
- int actualLength = _length & RemoveFlagsBitMask ;
251
+ // Used to maintain the high-bit which indicates whether the Memory has been pre-pinned or not.
252
+ int capturedLength = _length ;
253
+ int actualLength = capturedLength & RemoveFlagsBitMask ;
249
254
if ( ( uint ) start > ( uint ) actualLength || ( uint ) length > ( uint ) ( actualLength - start ) )
250
255
{
251
256
ThrowHelper . ThrowArgumentOutOfRangeException ( ) ;
252
257
}
253
258
254
- return new Memory < T > ( _object , _index + start , length ) ;
259
+ // Set the high-bit to match the this._length high bit (1 for pre-pinned, 0 for unpinned).
260
+ return new Memory < T > ( _object , _index + start , length | ( capturedLength & ~ RemoveFlagsBitMask ) ) ;
255
261
}
256
262
257
263
/// <summary>
0 commit comments