diff --git a/DotnetCLIVersion.txt b/DotnetCLIVersion.txt index e2fe4a98d..2746432b1 100644 --- a/DotnetCLIVersion.txt +++ b/DotnetCLIVersion.txt @@ -1 +1 @@ -2.2.0-preview1-008003 +2.1.300-preview2-008018 diff --git a/SharedRuntimeVersion.txt b/SharedRuntimeVersion.txt index d788a2511..709d3e6f2 100644 --- a/SharedRuntimeVersion.txt +++ b/SharedRuntimeVersion.txt @@ -1 +1 @@ -2.1.0-preview1-26122-01 \ No newline at end of file +2.1.0-preview2-26124-05 \ No newline at end of file diff --git a/corefxlab.sln b/corefxlab.sln index 1c6f1910c..de1eb1b73 100644 --- a/corefxlab.sln +++ b/corefxlab.sln @@ -2,7 +2,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 15 VisualStudioVersion = 15.0.27130.2020 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "MultiSegmentBytesReaderNumbers", "MultiSegmentBytesReaderNumbers", "{5E7EB061-B9BC-4DA2-B5E5-859AA7C67695}" +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{5E7EB061-B9BC-4DA2-B5E5-859AA7C67695}" ProjectSection(SolutionItems) = preProject global.json = global.json NuGet.Config = NuGet.Config diff --git a/src/System.Buffers.Experimental/System/Buffers/Native/NativeMemoryPool.Memory.cs b/src/System.Buffers.Experimental/System/Buffers/Native/NativeMemoryPool.Memory.cs index 8aa560cce..93cb5c1e4 100644 --- a/src/System.Buffers.Experimental/System/Buffers/Native/NativeMemoryPool.Memory.cs +++ b/src/System.Buffers.Experimental/System/Buffers/Native/NativeMemoryPool.Memory.cs @@ -2,6 +2,7 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. using System.Buffers.Native; +using System.Runtime.CompilerServices; namespace System.Buffers.Native { @@ -41,10 +42,11 @@ namespace System.Buffers.Native return false; } - public override MemoryHandle Pin() + public override MemoryHandle Pin(int byteOffset = 0) { Retain(); - return new MemoryHandle(this, _pointer.ToPointer()); + if (byteOffset < 0 || byteOffset > _length) throw new ArgumentOutOfRangeException(nameof(byteOffset)); + return new MemoryHandle(this, Unsafe.Add(_pointer.ToPointer(), byteOffset)); } private readonly NativeMemoryPool _pool; diff --git a/src/System.Buffers.Experimental/System/Buffers/Native/OwnedNativeBuffer.cs b/src/System.Buffers.Experimental/System/Buffers/Native/OwnedNativeBuffer.cs index 3ec2a592f..525b55df2 100644 --- a/src/System.Buffers.Experimental/System/Buffers/Native/OwnedNativeBuffer.cs +++ b/src/System.Buffers.Experimental/System/Buffers/Native/OwnedNativeBuffer.cs @@ -1,6 +1,7 @@ // Copyright (c) Microsoft. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. +using System.Runtime.CompilerServices; using System.Runtime.InteropServices; namespace System.Buffers.Native @@ -36,12 +37,13 @@ namespace System.Buffers.Native _pointer = IntPtr.Zero; } - public override MemoryHandle Pin() + public override MemoryHandle Pin(int byteOffset = 0) { Retain(); + if (byteOffset < 0 || byteOffset > _length) throw new ArgumentOutOfRangeException(nameof(byteOffset)); unsafe { - return new MemoryHandle(this, _pointer.ToPointer()); + return new MemoryHandle(this, Unsafe.Add(_pointer.ToPointer(), byteOffset)); } } protected override bool TryGetArray(out ArraySegment arraySegment) diff --git a/src/System.Buffers.Experimental/System/Buffers/Native/OwnedPinnedBuffer.cs b/src/System.Buffers.Experimental/System/Buffers/Native/OwnedPinnedBuffer.cs index f0fcf28ce..e3c6047ed 100644 --- a/src/System.Buffers.Experimental/System/Buffers/Native/OwnedPinnedBuffer.cs +++ b/src/System.Buffers.Experimental/System/Buffers/Native/OwnedPinnedBuffer.cs @@ -59,9 +59,10 @@ namespace System.Buffers.Native base.Dispose(disposing); } - public unsafe override MemoryHandle Pin() + public unsafe override MemoryHandle Pin(int byteOffset = 0) { - return new MemoryHandle(this, _pointer.ToPointer()); + if (byteOffset < 0 || (byteOffset / Unsafe.SizeOf()) > _array.Length) throw new ArgumentOutOfRangeException(nameof(byteOffset)); + return new MemoryHandle(this, Unsafe.Add(_pointer.ToPointer(), byteOffset)); } protected override bool TryGetArray(out ArraySegment arraySegment) diff --git a/src/System.Buffers.Primitives/System/Buffers/OwnedArray.cs b/src/System.Buffers.Primitives/System/Buffers/OwnedArray.cs index fd7f4b2f1..61cde4962 100644 --- a/src/System.Buffers.Primitives/System/Buffers/OwnedArray.cs +++ b/src/System.Buffers.Primitives/System/Buffers/OwnedArray.cs @@ -20,7 +20,7 @@ namespace System.Buffers public OwnedArray(T[] array) { - if (array == null) ThrowArgumentNullException(nameof(array)); + if (array == null) ThrowArgumentNullException(nameof(array)); _array = array; } @@ -37,13 +37,15 @@ namespace System.Buffers } } - public override MemoryHandle Pin() + public override MemoryHandle Pin(int byteOffset = 0) { unsafe { Retain(); + if (byteOffset < 0 || (byteOffset / Unsafe.SizeOf()) > _array.Length) throw new ArgumentOutOfRangeException(nameof(byteOffset)); var handle = GCHandle.Alloc(_array, GCHandleType.Pinned); - return new MemoryHandle(this, (void*)handle.AddrOfPinnedObject(), handle); + void* pointer = Unsafe.Add((void*)handle.AddrOfPinnedObject(), byteOffset); + return new MemoryHandle(this, pointer, handle); } } @@ -68,7 +70,7 @@ namespace System.Buffers public override bool Release() { int newRefCount = Interlocked.Decrement(ref _referenceCount); - if (newRefCount < 0) ThrowInvalidOperationException(); + if (newRefCount < 0) ThrowInvalidOperationException(); if (newRefCount == 0) { OnNoReferences(); diff --git a/src/System.Buffers.Primitives/System/Buffers/Pooling/ArrayMemoryPool.cs b/src/System.Buffers.Primitives/System/Buffers/Pooling/ArrayMemoryPool.cs index 9418dfa97..11083fc62 100644 --- a/src/System.Buffers.Primitives/System/Buffers/Pooling/ArrayMemoryPool.cs +++ b/src/System.Buffers.Primitives/System/Buffers/Pooling/ArrayMemoryPool.cs @@ -33,7 +33,7 @@ namespace System.Buffers.Internal T[] _array; bool _disposed; int _referenceCount; - + public ArrayPoolMemory(int size) { _array = ArrayPool.Shared.Rent(size); @@ -57,7 +57,8 @@ namespace System.Buffers.Internal protected override void Dispose(bool disposing) { var array = Interlocked.Exchange(ref _array, null); - if (array != null) { + if (array != null) + { _disposed = true; ArrayPool.Shared.Return(array); } @@ -70,13 +71,15 @@ namespace System.Buffers.Internal return true; } - public override MemoryHandle Pin() + public override MemoryHandle Pin(int byteOffset = 0) { unsafe { Retain(); // this checks IsDisposed + if (byteOffset < 0 || (byteOffset / Unsafe.SizeOf()) > _array.Length) throw new ArgumentOutOfRangeException(nameof(byteOffset)); var handle = GCHandle.Alloc(_array, GCHandleType.Pinned); - return new MemoryHandle(this, (void*)handle.AddrOfPinnedObject(), handle); + void* pointer = Unsafe.Add((void*)handle.AddrOfPinnedObject(), byteOffset); + return new MemoryHandle(this, pointer, handle); } } @@ -90,7 +93,7 @@ namespace System.Buffers.Internal { int newRefCount = Interlocked.Decrement(ref _referenceCount); if (newRefCount < 0) throw new InvalidOperationException(); - if (newRefCount == 0) + if (newRefCount == 0) { Dispose(); return false; diff --git a/src/System.IO.Pipelines.Networking.Windows.RIO/Internal/Pool/MemoryPoolBlock.cs b/src/System.IO.Pipelines.Networking.Windows.RIO/Internal/Pool/MemoryPoolBlock.cs index 806aec388..12d28b77c 100644 --- a/src/System.IO.Pipelines.Networking.Windows.RIO/Internal/Pool/MemoryPoolBlock.cs +++ b/src/System.IO.Pipelines.Networking.Windows.RIO/Internal/Pool/MemoryPoolBlock.cs @@ -116,8 +116,8 @@ namespace System.Buffers if (newRefCount < 0) RioPipelinesThrowHelper.ThrowInvalidOperationException(ExceptionResource.ReferenceCountZero); if (newRefCount == 0) { - OnZeroReferences(); - return false; + OnZeroReferences(); + return false; } return true; } @@ -134,13 +134,13 @@ namespace System.Buffers return true; } - public override MemoryHandle Pin() + public override MemoryHandle Pin(int byteOffset = 0) { - if (IsDisposed) RioPipelinesThrowHelper.ThrowObjectDisposedException(nameof(RioMemoryPoolBlock)); - Retain(); + Retain(); // checks IsDisposed + if (byteOffset < 0 || byteOffset > _length) RioPipelinesThrowHelper.ThrowArgumentOutOfRangeException(_length, byteOffset); unsafe { - return new MemoryHandle(this, (Slab.NativePointer + _offset).ToPointer()); + return new MemoryHandle(this, (Slab.NativePointer + _offset + byteOffset).ToPointer()); } } } diff --git a/src/System.IO.Pipelines.Networking.Windows.RIO/Internal/Pool/PipelinesThrowHelper.cs b/src/System.IO.Pipelines.Networking.Windows.RIO/Internal/Pool/PipelinesThrowHelper.cs index c3028dbe8..bfe020cf6 100644 --- a/src/System.IO.Pipelines.Networking.Windows.RIO/Internal/Pool/PipelinesThrowHelper.cs +++ b/src/System.IO.Pipelines.Networking.Windows.RIO/Internal/Pool/PipelinesThrowHelper.cs @@ -7,12 +7,30 @@ using System.Runtime.CompilerServices; namespace System.IO.Pipelines { internal class RioPipelinesThrowHelper - { + { + public static void ThrowArgumentOutOfRangeException(int sourceLength, int offset) + { + throw GetArgumentOutOfRangeException(sourceLength, offset); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private static ArgumentOutOfRangeException GetArgumentOutOfRangeException(int sourceLength, int offset) + { + if ((uint)offset > (uint)sourceLength) + { + // Offset is negative or less than array length + return new ArgumentOutOfRangeException(GetArgumentName(ExceptionArgument.offset)); + } + + // The third parameter (not passed) length must be out of range + return new ArgumentOutOfRangeException(GetArgumentName(ExceptionArgument.length)); + } + public static void ThrowInvalidOperationException(ExceptionResource resource, string location = null) { throw GetInvalidOperationException(resource, location); } - + public static void ThrowArgumentOutOfRangeException_BufferRequestTooLarge(int maxSize) { throw GetArgumentOutOfRangeException_BufferRequestTooLarge(maxSize); @@ -28,7 +46,7 @@ namespace System.IO.Pipelines { return new InvalidOperationException(GetResourceString(resource, location)); } - + [MethodImpl(MethodImplOptions.NoInlining)] private static ArgumentOutOfRangeException GetArgumentOutOfRangeException_BufferRequestTooLarge(int maxSize) { diff --git a/src/System.IO.Pipelines/System/Buffers/MemoryPoolBlock.cs b/src/System.IO.Pipelines/System/Buffers/MemoryPoolBlock.cs index c9167f8b8..fc95dcb7c 100644 --- a/src/System.IO.Pipelines/System/Buffers/MemoryPoolBlock.cs +++ b/src/System.IO.Pipelines/System/Buffers/MemoryPoolBlock.cs @@ -116,8 +116,8 @@ namespace System.Buffers if (newRefCount < 0) PipelinesThrowHelper.ThrowInvalidOperationException(ExceptionResource.ReferenceCountZero); if (newRefCount == 0) { - OnZeroReferences(); - return false; + OnZeroReferences(); + return false; } return true; } @@ -134,13 +134,13 @@ namespace System.Buffers return true; } - public override MemoryHandle Pin() + public override MemoryHandle Pin(int byteOffset = 0) { - if (IsDisposed) PipelinesThrowHelper.ThrowObjectDisposedException(nameof(MemoryPoolBlock)); - Retain(); + Retain(); // checks IsDisposed + if (byteOffset < 0 || byteOffset > _length) PipelinesThrowHelper.ThrowArgumentOutOfRangeException(_length, byteOffset); unsafe { - return new MemoryHandle(this, (Slab.NativePointer + _offset).ToPointer()); + return new MemoryHandle(this, (Slab.NativePointer + _offset + byteOffset).ToPointer()); } } } diff --git a/tests/System.Buffers.Experimental.Tests/MemoryTests.cs b/tests/System.Buffers.Experimental.Tests/MemoryTests.cs index 8f1e96ace..f0776f4a8 100644 --- a/tests/System.Buffers.Experimental.Tests/MemoryTests.cs +++ b/tests/System.Buffers.Experimental.Tests/MemoryTests.cs @@ -1,6 +1,7 @@ // Copyright (c) Microsoft. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. using System.Buffers.Native; +using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Threading; using System.Threading.Tasks; @@ -12,8 +13,9 @@ namespace System.Buffers.Tests { [Fact] public void SimpleTests() - { - using(var owned = new OwnedNativeBuffer(1024)) { + { + using (var owned = new OwnedNativeBuffer(1024)) + { var span = owned.Span; span[10] = 10; unsafe { Assert.Equal(10, owned.Pointer[10]); } @@ -28,7 +30,8 @@ namespace System.Buffers.Tests Assert.Equal(10, copy[0]); } - using (OwnedPinnedBuffer owned = new byte[1024]) { + using (OwnedPinnedBuffer owned = new byte[1024]) + { var span = owned.Span; span[10] = 10; Assert.Equal(10, owned.Array[10]); @@ -57,33 +60,40 @@ namespace System.Buffers.Tests public unsafe void PinnedArrayMemoryLifetime() { var bytes = new byte[1024]; - fixed (byte* pBytes = bytes) { + fixed (byte* pBytes = bytes) + { var owner = new OwnedPinnedBuffer(bytes, pBytes); - TestLifetime(owner); + TestLifetime(owner); } } static void TestLifetime(OwnedMemory owned) { Memory copyStoredForLater; - try { + try + { Memory memory = owned.Memory; Memory memorySlice = memory.Slice(10); copyStoredForLater = memorySlice; var r = memorySlice.Retain(); - try { - Assert.Throws(() => { // memory is reserved; premature dispose check fires + try + { + Assert.Throws(() => + { // memory is reserved; premature dispose check fires owned.Dispose(); }); } - finally { + finally + { r.Dispose(); // release reservation } } - finally { + finally + { owned.Dispose(); // can finish dispose with no exception } - Assert.Throws(() => { + Assert.Throws(() => + { // memory is disposed; cannot use copy stored for later var span = copyStoredForLater.Span; }); @@ -110,7 +120,7 @@ namespace System.Buffers.Tests var owned = new CustomBuffer(255); var memory = owned.Memory; Assert.Equal(0, owned.OnNoRefencesCalledCount); - + using (memory.Retain()) { Assert.Equal(0, owned.OnNoRefencesCalledCount); @@ -136,7 +146,8 @@ namespace System.Buffers.Tests memories[i] = owners[i].Memory; } - var dispose_task = Task.Run(() => { + var dispose_task = Task.Run(() => + { for (int i = 0; i < owners.Length; i++) { try @@ -151,7 +162,8 @@ namespace System.Buffers.Tests } }); - var reserve_task = Task.Run(() => { + var reserve_task = Task.Run(() => + { for (int i = owners.Length - 1; i >= 0; i--) { try @@ -205,13 +217,15 @@ namespace System.Buffers.Tests } } - public override MemoryHandle Pin() + public override MemoryHandle Pin(int byteOffset = 0) { unsafe { Retain(); + if (byteOffset < 0 || (byteOffset / Unsafe.SizeOf()) > _array.Length) throw new ArgumentOutOfRangeException(nameof(byteOffset)); var handle = GCHandle.Alloc(_array, GCHandleType.Pinned); - return new MemoryHandle(this, (void*)handle.AddrOfPinnedObject(), handle); + void* pointer = Unsafe.Add((void*)handle.AddrOfPinnedObject(), byteOffset); + return new MemoryHandle(this, pointer, handle); } } @@ -240,8 +254,8 @@ namespace System.Buffers.Tests if (newRefCount < 0) throw new InvalidOperationException(); if (newRefCount == 0) { - _noReferencesCalledCount++; - return false; + _noReferencesCalledCount++; + return false; } return true; } @@ -283,13 +297,15 @@ namespace System.Buffers.Tests return true; } - public override MemoryHandle Pin() + public override MemoryHandle Pin(int byteOffset = 0) { unsafe { Retain(); + if (byteOffset < 0 || (byteOffset / Unsafe.SizeOf()) > _array.Length) throw new ArgumentOutOfRangeException(nameof(byteOffset)); var handle = GCHandle.Alloc(_array, GCHandleType.Pinned); - return new MemoryHandle(this, (void*)handle.AddrOfPinnedObject(), handle); + void* pointer = Unsafe.Add((void*)handle.AddrOfPinnedObject(), byteOffset); + return new MemoryHandle(this, pointer, handle); } } diff --git a/tests/System.Buffers.Primitives.Tests/CustomMemoryForTest.cs b/tests/System.Buffers.Primitives.Tests/CustomMemoryForTest.cs index 210fe77c7..1b759db57 100644 --- a/tests/System.Buffers.Primitives.Tests/CustomMemoryForTest.cs +++ b/tests/System.Buffers.Primitives.Tests/CustomMemoryForTest.cs @@ -3,6 +3,7 @@ // See the LICENSE file in the project root for more information. +using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Threading; @@ -38,13 +39,15 @@ namespace System.Buffers.Tests } } - public override MemoryHandle Pin() + public override MemoryHandle Pin(int byteOffset = 0) { unsafe { Retain(); + if (byteOffset < 0 || (byteOffset / Unsafe.SizeOf()) > _array.Length) throw new ArgumentOutOfRangeException(nameof(byteOffset)); var handle = GCHandle.Alloc(_array, GCHandleType.Pinned); - return new MemoryHandle(this, (void*)handle.AddrOfPinnedObject(), handle); + void* pointer = Unsafe.Add((void*)handle.AddrOfPinnedObject(), byteOffset); + return new MemoryHandle(this, pointer, handle); } } diff --git a/tests/System.IO.Pipelines.Tests/PipePoolTests.cs b/tests/System.IO.Pipelines.Tests/PipePoolTests.cs index f64f620d6..6fbb88631 100644 --- a/tests/System.IO.Pipelines.Tests/PipePoolTests.cs +++ b/tests/System.IO.Pipelines.Tests/PipePoolTests.cs @@ -151,7 +151,7 @@ namespace System.IO.Pipelines.Tests } } - public override MemoryHandle Pin() + public override MemoryHandle Pin(int byteOffset = 0) { throw new NotImplementedException(); } diff --git a/tests/System.Numerics.Tensors.Tests/NativeMemory.cs b/tests/System.Numerics.Tensors.Tests/NativeMemory.cs index f5d4554b1..809c59e63 100644 --- a/tests/System.Numerics.Tensors.Tests/NativeMemory.cs +++ b/tests/System.Numerics.Tensors.Tests/NativeMemory.cs @@ -44,12 +44,14 @@ namespace System.Numerics.Tensors.Tests protected override bool IsRetained => refCount > 0; - public override MemoryHandle Pin() + public override MemoryHandle Pin(int byteOffset = 0) { unsafe { Retain(); - return new MemoryHandle(this, (void*)memory); + if (byteOffset < 0 || (byteOffset / Marshal.SizeOf()) > length) throw new ArgumentOutOfRangeException(nameof(byteOffset)); + void* pointer = (void*)((byte*)memory + byteOffset); + return new MemoryHandle(this, pointer); } } diff --git a/tools/dependencies.props b/tools/dependencies.props index c47ac9d7b..f38d5bc49 100644 --- a/tools/dependencies.props +++ b/tools/dependencies.props @@ -1,11 +1,11 @@ - 2.1.0-preview1-26122-01 + 2.1.0-preview2-26124-05 4.3.0 2.6.0-beta3-62316-02 - 4.5.0-preview1-26122-01 - 4.5.0-preview1-26122-01 - 4.5.0-preview1-26122-01 + 4.5.0-preview2-26124-02 + 4.5.0-preview2-26124-02 + 4.5.0-preview2-26124-02 1.9.1 15.0.0 2.2.0