summaryrefslogtreecommitdiff
path: root/src/mscorlib/shared
diff options
context:
space:
mode:
authorAhson Khan <ahkha@microsoft.com>2018-04-10 20:35:00 -0700
committerGitHub <noreply@github.com>2018-04-10 20:35:00 -0700
commit2ffcdd00249fd37e3c0d823df79ff19579028d66 (patch)
treeee29693e4d9db60a4af95f413c87f784ed16599a /src/mscorlib/shared
parentf76a563888f60798dc136b7d21c5be7440d78474 (diff)
downloadcoreclr-2ffcdd00249fd37e3c0d823df79ff19579028d66.tar.gz
coreclr-2ffcdd00249fd37e3c0d823df79ff19579028d66.tar.bz2
coreclr-2ffcdd00249fd37e3c0d823df79ff19579028d66.zip
Add CreateFromPinnedArray to MemoryMarshal (#17500)
* Add CreateFromPinnedArray to MemoryMarshal * Address PR feedback: Add a warning remark to CreateFromPinnedArray
Diffstat (limited to 'src/mscorlib/shared')
-rw-r--r--src/mscorlib/shared/System/Memory.cs2
-rw-r--r--src/mscorlib/shared/System/Runtime/InteropServices/MemoryMarshal.cs33
2 files changed, 34 insertions, 1 deletions
diff --git a/src/mscorlib/shared/System/Memory.cs b/src/mscorlib/shared/System/Memory.cs
index 3ccb76b2e5..c3affff17d 100644
--- a/src/mscorlib/shared/System/Memory.cs
+++ b/src/mscorlib/shared/System/Memory.cs
@@ -171,7 +171,7 @@ namespace System
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- private Memory(object obj, int start, int length)
+ internal Memory(object obj, int start, int length)
{
// No validation performed; caller must provide any necessary validation.
_object = obj;
diff --git a/src/mscorlib/shared/System/Runtime/InteropServices/MemoryMarshal.cs b/src/mscorlib/shared/System/Runtime/InteropServices/MemoryMarshal.cs
index 073dd76cdc..8eec0fd07c 100644
--- a/src/mscorlib/shared/System/Runtime/InteropServices/MemoryMarshal.cs
+++ b/src/mscorlib/shared/System/Runtime/InteropServices/MemoryMarshal.cs
@@ -244,5 +244,38 @@ namespace System.Runtime.InteropServices
Unsafe.WriteUnaligned<T>(ref GetReference(destination), value);
return true;
}
+
+ /// <summary>
+ /// Creates a new memory over the portion of the pre-pinned target array beginning
+ /// at 'start' index and ending at 'end' index (exclusive).
+ /// </summary>
+ /// <param name="array">The pre-pinned target array.</param>
+ /// <param name="start">The index at which to begin the memory.</param>
+ /// <param name="length">The number of items in the memory.</param>
+ /// <remarks>This method should only be called on an array that is already pinned and
+ /// that array should not be unpinned while the returned Memory<typeparamref name="T"/> is still in use.
+ /// Calling this method on an unpinned array could result in memory corruption.</remarks>
+ /// <remarks>Returns default when <paramref name="array"/> is null.</remarks>
+ /// <exception cref="System.ArrayTypeMismatchException">Thrown when <paramref name="array"/> is covariant and array's type is not exactly T[].</exception>
+ /// <exception cref="System.ArgumentOutOfRangeException">
+ /// Thrown when the specified <paramref name="start"/> or end index is not in the range (&lt;0 or &gt;=Length).
+ /// </exception>
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static Memory<T> CreateFromPinnedArray<T>(T[] array, int start, int length)
+ {
+ if (array == null)
+ {
+ if (start != 0 || length != 0)
+ ThrowHelper.ThrowArgumentOutOfRangeException();
+ return default;
+ }
+ if (default(T) == null && array.GetType() != typeof(T[]))
+ ThrowHelper.ThrowArrayTypeMismatchException();
+ if ((uint)start > (uint)array.Length || (uint)length > (uint)(array.Length - start))
+ ThrowHelper.ThrowArgumentOutOfRangeException();
+
+ // Before using _length, check if _length < 0, then 'and' it with RemoveFlagsBitMask
+ return new Memory<T>((object)array, start, length | (1 << 31));
+ }
}
}