diff options
author | Ahson Khan <ahkha@microsoft.com> | 2018-04-10 20:35:00 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-04-10 20:35:00 -0700 |
commit | 2ffcdd00249fd37e3c0d823df79ff19579028d66 (patch) | |
tree | ee29693e4d9db60a4af95f413c87f784ed16599a /src/mscorlib/shared | |
parent | f76a563888f60798dc136b7d21c5be7440d78474 (diff) | |
download | coreclr-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.cs | 2 | ||||
-rw-r--r-- | src/mscorlib/shared/System/Runtime/InteropServices/MemoryMarshal.cs | 33 |
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 (<0 or >=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)); + } } } |