Skip to content

Commit

Permalink
Preserve pinned flag in {ReadOnly}Memory<T>.Slice (dotnet/corefxdotne…
Browse files Browse the repository at this point in the history
…t/coreclr#29246) (dotnet/coreclr#17712)

* Preserve pinned flag in {ReadOnly}Memory<T>.Slice

* Address PR feedback.

Signed-off-by: dotnet-bot-corefx-mirror <[email protected]>

Commit migrated from dotnet/coreclr@c14d048
  • Loading branch information
dotnet-bot authored and ahsonkhan committed Apr 21, 2018
1 parent eb0a997 commit d051850
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 7 deletions.
14 changes: 10 additions & 4 deletions src/coreclr/src/mscorlib/shared/System/Memory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -225,13 +225,16 @@ public override string ToString()
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Memory<T> Slice(int start)
{
int actualLength = _length & RemoveFlagsBitMask;
// Used to maintain the high-bit which indicates whether the Memory has been pre-pinned or not.
int capturedLength = _length;
int actualLength = capturedLength & RemoveFlagsBitMask;
if ((uint)start > (uint)actualLength)
{
ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.start);
}

return new Memory<T>(_object, _index + start, actualLength - start);
// It is expected for (capturedLength - start) to be negative if the memory is already pre-pinned.
return new Memory<T>(_object, _index + start, capturedLength - start);
}

/// <summary>
Expand All @@ -245,13 +248,16 @@ public Memory<T> Slice(int start)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Memory<T> Slice(int start, int length)
{
int actualLength = _length & RemoveFlagsBitMask;
// Used to maintain the high-bit which indicates whether the Memory has been pre-pinned or not.
int capturedLength = _length;
int actualLength = capturedLength & RemoveFlagsBitMask;
if ((uint)start > (uint)actualLength || (uint)length > (uint)(actualLength - start))
{
ThrowHelper.ThrowArgumentOutOfRangeException();
}

return new Memory<T>(_object, _index + start, length);
// Set the high-bit to match the this._length high bit (1 for pre-pinned, 0 for unpinned).
return new Memory<T>(_object, _index + start, length | (capturedLength & ~RemoveFlagsBitMask));
}

/// <summary>
Expand Down
12 changes: 9 additions & 3 deletions src/coreclr/src/mscorlib/shared/System/ReadOnlyMemory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -147,13 +147,16 @@ public override string ToString()
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public ReadOnlyMemory<T> Slice(int start)
{
int actualLength = _length & RemoveFlagsBitMask;
// Used to maintain the high-bit which indicates whether the Memory has been pre-pinned or not.
int capturedLength = _length;
int actualLength = capturedLength & RemoveFlagsBitMask;
if ((uint)start > (uint)actualLength)
{
ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.start);
}

return new ReadOnlyMemory<T>(_object, _index + start, actualLength - start);
// It is expected for (capturedLength - start) to be negative if the memory is already pre-pinned.
return new ReadOnlyMemory<T>(_object, _index + start, capturedLength - start);
}

/// <summary>
Expand All @@ -167,13 +170,16 @@ public ReadOnlyMemory<T> Slice(int start)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public ReadOnlyMemory<T> Slice(int start, int length)
{
// Used to maintain the high-bit which indicates whether the Memory has been pre-pinned or not.
int capturedLength = _length;
int actualLength = _length & RemoveFlagsBitMask;
if ((uint)start > (uint)actualLength || (uint)length > (uint)(actualLength - start))
{
ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.start);
}

return new ReadOnlyMemory<T>(_object, _index + start, length);
// Set the high-bit to match the this._length high bit (1 for pre-pinned, 0 for unpinned).
return new ReadOnlyMemory<T>(_object, _index + start, length | (capturedLength & ~RemoveFlagsBitMask));
}

/// <summary>
Expand Down

0 comments on commit d051850

Please sign in to comment.