diff options
3 files changed, 274 insertions, 1 deletions
diff --git a/src/System.Runtime.CompilerServices.Unsafe/src/System.Runtime.CompilerServices.Unsafe.il b/src/System.Runtime.CompilerServices.Unsafe/src/System.Runtime.CompilerServices.Unsafe.il index 0f28a171bf..f1d96ad9e4 100644 --- a/src/System.Runtime.CompilerServices.Unsafe/src/System.Runtime.CompilerServices.Unsafe.il +++ b/src/System.Runtime.CompilerServices.Unsafe/src/System.Runtime.CompilerServices.Unsafe.il @@ -41,7 +41,7 @@ 01 00 00 00 00 ) // false .hash algorithm 0x00008004 - .ver 4:0:2:0 + .ver 4:0:3:0 } .module System.Runtime.CompilerServices.Unsafe.dll // MVID: {1E97D84A-565B-49C5-B60A-F31A1A4ACE13} @@ -130,6 +130,41 @@ ret } // end of method Unsafe::CopyBlock + .method public hidebysig static void CopyBlock(void* destination, void* source, native unsigned int byteCount) cil managed aggressiveinlining + { + .custom instance void System.Runtime.Versioning.NonVersionableAttribute::.ctor() = ( 01 00 00 00 ) + .maxstack 3 + ldarg.0 + ldarg.1 + ldarg.2 + cpblk + ret + } // end of method Unsafe::CopyBlock + + .method public hidebysig static void CopyBlockUnaligned(void* destination, void* source, uint32 byteCount) cil managed aggressiveinlining + { + .custom instance void System.Runtime.Versioning.NonVersionableAttribute::.ctor() = ( 01 00 00 00 ) + .maxstack 3 + ldarg.0 + ldarg.1 + ldarg.2 + unaligned. 0x1 + cpblk + ret + } // end of method Unsafe::CopyBlockUnaligned + + .method public hidebysig static void CopyBlockUnaligned(void* destination, void* source, native unsigned int byteCount) cil managed aggressiveinlining + { + .custom instance void System.Runtime.Versioning.NonVersionableAttribute::.ctor() = ( 01 00 00 00 ) + .maxstack 3 + ldarg.0 + ldarg.1 + ldarg.2 + unaligned. 0x1 + cpblk + ret + } // end of method Unsafe::CopyBlockUnaligned + .method public hidebysig static void InitBlock(void* startAddress, uint8 'value', uint32 byteCount) cil managed aggressiveinlining { .custom instance void System.Runtime.Versioning.NonVersionableAttribute::.ctor() = ( 01 00 00 00 ) @@ -141,6 +176,41 @@ ret } // end of method Unsafe::InitBlock + .method public hidebysig static void InitBlock(void* startAddress, uint8 'value', native unsigned int byteCount) cil managed aggressiveinlining + { + .custom instance void System.Runtime.Versioning.NonVersionableAttribute::.ctor() = ( 01 00 00 00 ) + .maxstack 3 + ldarg.0 + ldarg.1 + ldarg.2 + initblk + ret + } // end of method Unsafe::InitBlock + + .method public hidebysig static void InitBlockUnaligned(void* startAddress, uint8 'value', uint32 byteCount) cil managed aggressiveinlining + { + .custom instance void System.Runtime.Versioning.NonVersionableAttribute::.ctor() = ( 01 00 00 00 ) + .maxstack 3 + ldarg.0 + ldarg.1 + ldarg.2 + unaligned. 0x1 + initblk + ret + } // end of method Unsafe::InitBlockUnaligned + + .method public hidebysig static void InitBlockUnaligned(void* startAddress, uint8 'value', native unsigned int byteCount) cil managed aggressiveinlining + { + .custom instance void System.Runtime.Versioning.NonVersionableAttribute::.ctor() = ( 01 00 00 00 ) + .maxstack 3 + ldarg.0 + ldarg.1 + ldarg.2 + unaligned. 0x1 + initblk + ret + } // end of method Unsafe::InitBlockUnaligned + .method public hidebysig static !!T As<class T>(object o) cil managed aggressiveinlining { .custom instance void System.Runtime.Versioning.NonVersionableAttribute::.ctor() = ( 01 00 00 00 ) diff --git a/src/System.Runtime.CompilerServices.Unsafe/src/System.Runtime.CompilerServices.Unsafe.xml b/src/System.Runtime.CompilerServices.Unsafe/src/System.Runtime.CompilerServices.Unsafe.xml index f87e65d953..7f98bc9a46 100644 --- a/src/System.Runtime.CompilerServices.Unsafe/src/System.Runtime.CompilerServices.Unsafe.xml +++ b/src/System.Runtime.CompilerServices.Unsafe/src/System.Runtime.CompilerServices.Unsafe.xml @@ -115,6 +115,32 @@ <param name="source">The source address to copy from.</param> <param name="byteCount">The number of bytes to copy.</param> </member> + <member name="M:System.Runtime.CompilerServices.Unsafe.CopyBlock(System.Void*,System.Void*,System.UIntPtr)"> + <summary> + Copies bytes from the source address to the destination address. + </summary> + <param name="destination">The destination address to copy to.</param> + <param name="source">The source address to copy from.</param> + <param name="byteCount">The number of bytes to copy.</param> + </member> + <member name="M:System.Runtime.CompilerServices.Unsafe.CopyBlockUnaligned(System.Void*,System.Void*,System.UInt32)"> + <summary> + Copies bytes from the source address to the destination address + without assuming architecture dependent alignment of the addresses. + </summary> + <param name="destination">The destination address to copy to.</param> + <param name="source">The source address to copy from.</param> + <param name="byteCount">The number of bytes to copy.</param> + </member> + <member name="M:System.Runtime.CompilerServices.Unsafe.CopyBlockUnaligned(System.Void*,System.Void*,System.UIntPtr)"> + <summary> + Copies bytes from the source address to the destination address + without assuming architecture dependent alignment of the addresses. + </summary> + <param name="destination">The destination address to copy to.</param> + <param name="source">The source address to copy from.</param> + <param name="byteCount">The number of bytes to copy.</param> + </member> <member name="M:System.Runtime.CompilerServices.Unsafe.InitBlock(System.Void*,System.Byte,System.UInt32)"> <summary> Initializes a block of memory at the given location with a given initial value. @@ -123,5 +149,31 @@ <param name="value">The value to initialize the block to.</param> <param name="byteCount">The number of bytes to initialize.</param> </member> + <member name="M:System.Runtime.CompilerServices.Unsafe.InitBlock(System.Void*,System.Byte,System.UIntPtr)"> + <summary> + Initializes a block of memory at the given location with a given initial value. + </summary> + <param name="startAddress">The address of the start of the memory block to initialize.</param> + <param name="value">The value to initialize the block to.</param> + <param name="byteCount">The number of bytes to initialize.</param> + </member> + <member name="M:System.Runtime.CompilerServices.Unsafe.InitBlockUnaligned(System.Void*,System.Byte,System.UInt32)"> + <summary> + Initializes a block of memory at the given location with a given initial value + without assuming architecture dependent alignment of the address. + </summary> + <param name="startAddress">The address of the start of the memory block to initialize.</param> + <param name="value">The value to initialize the block to.</param> + <param name="byteCount">The number of bytes to initialize.</param> + </member> + <member name="M:System.Runtime.CompilerServices.Unsafe.InitBlockUnaligned(System.Void*,System.Byte,System.UIntPtr)"> + <summary> + Initializes a block of memory at the given location with a given initial value + without assuming architecture dependent alignment of the address. + </summary> + <param name="startAddress">The address of the start of the memory block to initialize.</param> + <param name="value">The value to initialize the block to.</param> + <param name="byteCount">The number of bytes to initialize.</param> + </member> </members> </doc> diff --git a/src/System.Runtime.CompilerServices.Unsafe/tests/UnsafeTests.cs b/src/System.Runtime.CompilerServices.Unsafe/tests/UnsafeTests.cs index 2cca63b8d6..ab8067c1d0 100644 --- a/src/System.Runtime.CompilerServices.Unsafe/tests/UnsafeTests.cs +++ b/src/System.Runtime.CompilerServices.Unsafe/tests/UnsafeTests.cs @@ -179,6 +179,83 @@ namespace System.Runtime.CompilerServices } } + [Theory] + [MemberData(nameof(InitBlockData))] + public static unsafe void InitBlockUIntPtrStack(int numBytes, byte value) + { + byte* stackPtr = stackalloc byte[numBytes]; + Unsafe.InitBlock(stackPtr, value, (UIntPtr)numBytes); + for (int i = 0; i < numBytes; i++) + { + Assert.Equal(stackPtr[i], value); + } + } + + [Theory] + [MemberData(nameof(InitBlockData))] + public static unsafe void InitBlockUIntPtrUnmanaged(int numBytes, byte value) + { + IntPtr allocatedMemory = Marshal.AllocCoTaskMem(numBytes); + byte* bytePtr = (byte*)allocatedMemory.ToPointer(); + Unsafe.InitBlock(bytePtr, value, (UIntPtr)numBytes); + for (int i = 0; i < numBytes; i++) + { + Assert.Equal(bytePtr[i], value); + } + } + + [Theory] + [MemberData(nameof(InitBlockData))] + public static unsafe void InitBlockUnalignedStack(int numBytes, byte value) + { + byte* stackPtr = stackalloc byte[numBytes + 1]; + stackPtr += 1; // +1 = make unaligned + Unsafe.InitBlockUnaligned(stackPtr, value, (uint)numBytes); + for (int i = 0; i < numBytes; i++) + { + Assert.Equal(stackPtr[i], value); + } + } + + [Theory] + [MemberData(nameof(InitBlockData))] + public static unsafe void InitBlockUnalignedUnmanaged(int numBytes, byte value) + { + IntPtr allocatedMemory = Marshal.AllocCoTaskMem(numBytes + 1); + byte* bytePtr = (byte*)allocatedMemory.ToPointer() + 1; // +1 = make unaligned + Unsafe.InitBlockUnaligned(bytePtr, value, (uint)numBytes); + for (int i = 0; i < numBytes; i++) + { + Assert.Equal(bytePtr[i], value); + } + } + + [Theory] + [MemberData(nameof(InitBlockData))] + public static unsafe void InitBlockUnalignedUIntPtrStack(int numBytes, byte value) + { + byte* stackPtr = stackalloc byte[numBytes + 1]; + stackPtr += 1; // +1 = make unaligned + Unsafe.InitBlockUnaligned(stackPtr, value, (UIntPtr)numBytes); + for (int i = 0; i < numBytes; i++) + { + Assert.Equal(stackPtr[i], value); + } + } + + [Theory] + [MemberData(nameof(InitBlockData))] + public static unsafe void InitBlockUnalignedUIntPtrUnmanaged(int numBytes, byte value) + { + IntPtr allocatedMemory = Marshal.AllocCoTaskMem(numBytes + 1); + byte* bytePtr = (byte*)allocatedMemory.ToPointer() + 1; // +1 = make unaligned + Unsafe.InitBlockUnaligned(bytePtr, value, (UIntPtr)numBytes); + for (int i = 0; i < numBytes; i++) + { + Assert.Equal(bytePtr[i], value); + } + } + public static IEnumerable<object[]> InitBlockData() { yield return new object[] { 0, 1 }; @@ -212,6 +289,80 @@ namespace System.Runtime.CompilerServices } } + [Theory] + [MemberData(nameof(CopyBlockData))] + public static unsafe void CopyBlockUIntPtr(int numBytes) + { + byte* source = stackalloc byte[numBytes]; + byte* destination = stackalloc byte[numBytes]; + + for (int i = 0; i < numBytes; i++) + { + byte value = (byte)(i % 255); + source[i] = value; + } + + Unsafe.CopyBlock(destination, source, (UIntPtr)numBytes); + + for (int i = 0; i < numBytes; i++) + { + byte value = (byte)(i % 255); + Assert.Equal(value, destination[i]); + Assert.Equal(source[i], destination[i]); + } + } + + [Theory] + [MemberData(nameof(CopyBlockData))] + public static unsafe void CopyBlockUnaligned(int numBytes) + { + byte* source = stackalloc byte[numBytes + 1]; + byte* destination = stackalloc byte[numBytes + 1]; + source += 1; // +1 = make unaligned + destination += 1; // +1 = make unaligned + + for (int i = 0; i < numBytes; i++) + { + byte value = (byte)(i % 255); + source[i] = value; + } + + Unsafe.CopyBlockUnaligned(destination, source, (uint)numBytes); + + for (int i = 0; i < numBytes; i++) + { + byte value = (byte)(i % 255); + Assert.Equal(value, destination[i]); + Assert.Equal(source[i], destination[i]); + } + } + + + [Theory] + [MemberData(nameof(CopyBlockData))] + public static unsafe void CopyBlockUnalignedUIntPtr(int numBytes) + { + byte* source = stackalloc byte[numBytes + 1]; + byte* destination = stackalloc byte[numBytes + 1]; + source += 1; // +1 = make unaligned + destination += 1; // +1 = make unaligned + + for (int i = 0; i < numBytes; i++) + { + byte value = (byte)(i % 255); + source[i] = value; + } + + Unsafe.CopyBlockUnaligned(destination, source, (UIntPtr)numBytes); + + for (int i = 0; i < numBytes; i++) + { + byte value = (byte)(i % 255); + Assert.Equal(value, destination[i]); + Assert.Equal(source[i], destination[i]); + } + } + public static IEnumerable<object[]> CopyBlockData() { yield return new object[] { 0 }; |