Skip to content

Commit

Permalink
Mirror changes from dotnet/coreclr (dotnet/corefx#28384)
Browse files Browse the repository at this point in the history
* Small tweaks to Dict asm size (dotnet/coreclrdotnet/corefx#17096)

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

* Moving Span APIs that allow skipping visibility checks to MemoryMarshal (dotnet/corefx#17087)

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

* Improve DateTime{Offset} "r" and "o" formatting performance (dotnet/corefx#17092)

Two main changes:
1. Rewrote the formatting to use span, only to then discover that we already had almost exactly the same implementation in Utf8Formatter.  As that one had some extra optimizations around JIT behaviors, I ported that over instead.
2. Avoided [ThreadStatic] lookups unless necessary.

ToString/TryFormat for "o"/"O" improve by ~2.5x.

ToString/TryFormat for "r"/"R" improve by ~3x.

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

* Rename {Try}Read/WriteMachineEndian to just {Try}Read/Write (dotnet/corefx#17106)

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

* Fix incorrect array dereference. (dotnet/coreclrdotnet/corefx#17113)

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

* Move Span APIs that allow skipping visibility checks to MemoryMarshal

* Rename {Try}Read/WriteMachineEndian to just {Try}Read/Write

* Update calls to BinaryPrimitives.ReadMachineEndian

* Rename calls to ReadMachineEndian in System.Memory perf tests.

* Add ApiCompatBaseline for UWP NETNative

* Add to ApiCompatBaseline for UWP NETNative netstandard20


Commit migrated from dotnet/corefx@3767d30
  • Loading branch information
dotnet-bot authored and ahsonkhan committed Mar 23, 2018
1 parent 45a871e commit a8da86d
Show file tree
Hide file tree
Showing 23 changed files with 241 additions and 321 deletions.
10 changes: 6 additions & 4 deletions src/libraries/System.Memory/ref/System.Memory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -366,7 +366,6 @@ public static partial class BinaryPrimitives
public static int ReadInt32LittleEndian(System.ReadOnlySpan<byte> source) { throw null; }
public static long ReadInt64BigEndian(System.ReadOnlySpan<byte> source) { throw null; }
public static long ReadInt64LittleEndian(System.ReadOnlySpan<byte> source) { throw null; }
public static T ReadMachineEndian<T>(System.ReadOnlySpan<byte> source) where T : struct { throw null; }
[System.CLSCompliantAttribute(false)]
public static ushort ReadUInt16BigEndian(System.ReadOnlySpan<byte> source) { throw null; }
[System.CLSCompliantAttribute(false)]
Expand Down Expand Up @@ -397,7 +396,6 @@ public static partial class BinaryPrimitives
public static bool TryReadInt32LittleEndian(System.ReadOnlySpan<byte> source, out int value) { throw null; }
public static bool TryReadInt64BigEndian(System.ReadOnlySpan<byte> source, out long value) { throw null; }
public static bool TryReadInt64LittleEndian(System.ReadOnlySpan<byte> source, out long value) { throw null; }
public static bool TryReadMachineEndian<T>(System.ReadOnlySpan<byte> source, out T value) where T : struct { throw null; }
[System.CLSCompliantAttribute(false)]
public static bool TryReadUInt16BigEndian(System.ReadOnlySpan<byte> source, out ushort value) { throw null; }
[System.CLSCompliantAttribute(false)]
Expand All @@ -416,7 +414,6 @@ public static partial class BinaryPrimitives
public static bool TryWriteInt32LittleEndian(System.Span<byte> destination, int value) { throw null; }
public static bool TryWriteInt64BigEndian(System.Span<byte> destination, long value) { throw null; }
public static bool TryWriteInt64LittleEndian(System.Span<byte> destination, long value) { throw null; }
public static bool TryWriteMachineEndian<T>(System.Span<byte> destination, ref T value) where T : struct { throw null; }
[System.CLSCompliantAttribute(false)]
public static bool TryWriteUInt16BigEndian(System.Span<byte> destination, ushort value) { throw null; }
[System.CLSCompliantAttribute(false)]
Expand All @@ -435,7 +432,6 @@ public static void WriteInt32BigEndian(System.Span<byte> destination, int value)
public static void WriteInt32LittleEndian(System.Span<byte> destination, int value) { }
public static void WriteInt64BigEndian(System.Span<byte> destination, long value) { }
public static void WriteInt64LittleEndian(System.Span<byte> destination, long value) { }
public static void WriteMachineEndian<T>(System.Span<byte> destination, ref T value) where T : struct { }
[System.CLSCompliantAttribute(false)]
public static void WriteUInt16BigEndian(System.Span<byte> destination, ushort value) { }
[System.CLSCompliantAttribute(false)]
Expand Down Expand Up @@ -512,6 +508,8 @@ namespace System.Runtime.InteropServices
{
public static partial class MemoryMarshal
{
public static System.ReadOnlySpan<byte> AsBytes<T>(System.ReadOnlySpan<T> span) where T : struct { throw null; }
public static System.Span<byte> AsBytes<T>(System.Span<T> span) where T : struct { throw null; }
public static System.Memory<T> AsMemory<T>(System.ReadOnlyMemory<T> memory) { throw null; }
public static System.ReadOnlySpan<TTo> Cast<TFrom, TTo>(System.ReadOnlySpan<TFrom> span) where TFrom : struct where TTo : struct { throw null; }
public static System.Span<TTo> Cast<TFrom, TTo>(System.Span<TFrom> span) where TFrom : struct where TTo : struct { throw null; }
Expand All @@ -521,13 +519,17 @@ public static partial class MemoryMarshal
#endif
public static ref T GetReference<T>(System.ReadOnlySpan<T> span) { throw null; }
public static ref T GetReference<T>(System.Span<T> span) { throw null; }
public static T Read<T>(System.ReadOnlySpan<byte> source) where T : struct { throw null; }
public static System.Collections.Generic.IEnumerable<T> ToEnumerable<T>(System.ReadOnlyMemory<T> memory) { throw null; }
public static bool TryGetArray<T>(System.ReadOnlyMemory<T> memory, out System.ArraySegment<T> segment) { throw null; }
public static bool TryGetOwnedMemory<T, TOwner>(ReadOnlyMemory<T> memory, out TOwner owner)
where TOwner : System.Buffers.OwnedMemory<T> { throw null; }
public static bool TryGetOwnedMemory<T, TOwner>(ReadOnlyMemory<T> memory, out TOwner owner, out int start, out int length)
where TOwner : System.Buffers.OwnedMemory<T> { throw null; }
public static bool TryGetString(System.ReadOnlyMemory<char> memory, out string text, out int start, out int length) { throw null; }
public static bool TryRead<T>(System.ReadOnlySpan<byte> source, out T value) where T : struct { throw null; }
public static bool TryWrite<T>(System.Span<byte> destination, ref T value) where T : struct { throw null; }
public static void Write<T>(System.Span<byte> destination, ref T value) where T : struct { }
}

public static partial class SequenceMarshal
Expand Down
1 change: 0 additions & 1 deletion src/libraries/System.Memory/src/System.Memory.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@
<Compile Include="System\Buffers\Binary\Reader.cs" />
<Compile Include="System\Buffers\Binary\ReaderBigEndian.cs" />
<Compile Include="System\Buffers\Binary\ReaderLittleEndian.cs" />
<Compile Include="System\Buffers\Binary\Writer.cs" />
<Compile Include="System\Buffers\Binary\WriterBigEndian.cs" />
<Compile Include="System\Buffers\Binary\WriterLittleEndian.cs" />
<Compile Include="System\Buffers\Text\Base64Decoder.cs" />
Expand Down
58 changes: 0 additions & 58 deletions src/libraries/System.Memory/src/System/Buffers/Binary/Reader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,6 @@
// See the LICENSE file in the project root for more information.

using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

#if !netstandard
using Internal.Runtime.CompilerServices;
#endif

namespace System.Buffers.Binary
{
Expand Down Expand Up @@ -127,58 +122,5 @@ public static ulong ReverseEndianness(ulong value)
return ((ulong)ReverseEndianness((uint)value) << 32)
+ ReverseEndianness((uint)(value >> 32));
}

/// <summary>
/// Reads a structure of type T out of a read-only span of bytes.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static T ReadMachineEndian<T>(ReadOnlySpan<byte> source)
where T : struct
{
#if netstandard
if (SpanHelpers.IsReferenceOrContainsReferences<T>())
{
ThrowHelper.ThrowArgumentException_InvalidTypeWithPointersNotSupported(typeof(T));
}
#else
if (RuntimeHelpers.IsReferenceOrContainsReferences<T>())
{
ThrowHelper.ThrowArgumentException_InvalidTypeWithPointersNotSupported(typeof(T));
}
#endif
if (Unsafe.SizeOf<T>() > source.Length)
{
ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.length);
}
return Unsafe.ReadUnaligned<T>(ref MemoryMarshal.GetReference(source));
}

/// <summary>
/// Reads a structure of type T out of a span of bytes.
/// <returns>If the span is too small to contain the type T, return false.</returns>
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool TryReadMachineEndian<T>(ReadOnlySpan<byte> source, out T value)
where T : struct
{
#if netstandard
if (SpanHelpers.IsReferenceOrContainsReferences<T>())
{
ThrowHelper.ThrowArgumentException_InvalidTypeWithPointersNotSupported(typeof(T));
}
#else
if (RuntimeHelpers.IsReferenceOrContainsReferences<T>())
{
ThrowHelper.ThrowArgumentException_InvalidTypeWithPointersNotSupported(typeof(T));
}
#endif
if (Unsafe.SizeOf<T>() > (uint)source.Length)
{
value = default;
return false;
}
value = Unsafe.ReadUnaligned<T>(ref MemoryMarshal.GetReference(source));
return true;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
// See the LICENSE file in the project root for more information.

using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

namespace System.Buffers.Binary
{
Expand All @@ -14,7 +15,7 @@ public static partial class BinaryPrimitives
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static short ReadInt16BigEndian(ReadOnlySpan<byte> source)
{
short result = ReadMachineEndian<short>(source);
short result = MemoryMarshal.Read<short>(source);
if (BitConverter.IsLittleEndian)
{
result = ReverseEndianness(result);
Expand All @@ -28,7 +29,7 @@ public static short ReadInt16BigEndian(ReadOnlySpan<byte> source)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static int ReadInt32BigEndian(ReadOnlySpan<byte> source)
{
int result = ReadMachineEndian<int>(source);
int result = MemoryMarshal.Read<int>(source);
if (BitConverter.IsLittleEndian)
{
result = ReverseEndianness(result);
Expand All @@ -42,7 +43,7 @@ public static int ReadInt32BigEndian(ReadOnlySpan<byte> source)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static long ReadInt64BigEndian(ReadOnlySpan<byte> source)
{
long result = ReadMachineEndian<long>(source);
long result = MemoryMarshal.Read<long>(source);
if (BitConverter.IsLittleEndian)
{
result = ReverseEndianness(result);
Expand All @@ -57,7 +58,7 @@ public static long ReadInt64BigEndian(ReadOnlySpan<byte> source)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ushort ReadUInt16BigEndian(ReadOnlySpan<byte> source)
{
ushort result = ReadMachineEndian<ushort>(source);
ushort result = MemoryMarshal.Read<ushort>(source);
if (BitConverter.IsLittleEndian)
{
result = ReverseEndianness(result);
Expand All @@ -72,7 +73,7 @@ public static ushort ReadUInt16BigEndian(ReadOnlySpan<byte> source)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static uint ReadUInt32BigEndian(ReadOnlySpan<byte> source)
{
uint result = ReadMachineEndian<uint>(source);
uint result = MemoryMarshal.Read<uint>(source);
if (BitConverter.IsLittleEndian)
{
result = ReverseEndianness(result);
Expand All @@ -87,7 +88,7 @@ public static uint ReadUInt32BigEndian(ReadOnlySpan<byte> source)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ulong ReadUInt64BigEndian(ReadOnlySpan<byte> source)
{
ulong result = ReadMachineEndian<ulong>(source);
ulong result = MemoryMarshal.Read<ulong>(source);
if (BitConverter.IsLittleEndian)
{
result = ReverseEndianness(result);
Expand All @@ -102,7 +103,7 @@ public static ulong ReadUInt64BigEndian(ReadOnlySpan<byte> source)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool TryReadInt16BigEndian(ReadOnlySpan<byte> source, out short value)
{
bool success = TryReadMachineEndian(source, out value);
bool success = MemoryMarshal.TryRead(source, out value);
if (BitConverter.IsLittleEndian)
{
value = ReverseEndianness(value);
Expand All @@ -117,7 +118,7 @@ public static bool TryReadInt16BigEndian(ReadOnlySpan<byte> source, out short va
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool TryReadInt32BigEndian(ReadOnlySpan<byte> source, out int value)
{
bool success = TryReadMachineEndian(source, out value);
bool success = MemoryMarshal.TryRead(source, out value);
if (BitConverter.IsLittleEndian)
{
value = ReverseEndianness(value);
Expand All @@ -132,7 +133,7 @@ public static bool TryReadInt32BigEndian(ReadOnlySpan<byte> source, out int valu
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool TryReadInt64BigEndian(ReadOnlySpan<byte> source, out long value)
{
bool success = TryReadMachineEndian(source, out value);
bool success = MemoryMarshal.TryRead(source, out value);
if (BitConverter.IsLittleEndian)
{
value = ReverseEndianness(value);
Expand All @@ -148,7 +149,7 @@ public static bool TryReadInt64BigEndian(ReadOnlySpan<byte> source, out long val
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool TryReadUInt16BigEndian(ReadOnlySpan<byte> source, out ushort value)
{
bool success = TryReadMachineEndian(source, out value);
bool success = MemoryMarshal.TryRead(source, out value);
if (BitConverter.IsLittleEndian)
{
value = ReverseEndianness(value);
Expand All @@ -164,7 +165,7 @@ public static bool TryReadUInt16BigEndian(ReadOnlySpan<byte> source, out ushort
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool TryReadUInt32BigEndian(ReadOnlySpan<byte> source, out uint value)
{
bool success = TryReadMachineEndian(source, out value);
bool success = MemoryMarshal.TryRead(source, out value);
if (BitConverter.IsLittleEndian)
{
value = ReverseEndianness(value);
Expand All @@ -180,7 +181,7 @@ public static bool TryReadUInt32BigEndian(ReadOnlySpan<byte> source, out uint va
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool TryReadUInt64BigEndian(ReadOnlySpan<byte> source, out ulong value)
{
bool success = TryReadMachineEndian(source, out value);
bool success = MemoryMarshal.TryRead(source, out value);
if (BitConverter.IsLittleEndian)
{
value = ReverseEndianness(value);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
// See the LICENSE file in the project root for more information.

using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

namespace System.Buffers.Binary
{
Expand All @@ -14,7 +15,7 @@ public static partial class BinaryPrimitives
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static short ReadInt16LittleEndian(ReadOnlySpan<byte> source)
{
short result = ReadMachineEndian<short>(source);
short result = MemoryMarshal.Read<short>(source);
if (!BitConverter.IsLittleEndian)
{
result = ReverseEndianness(result);
Expand All @@ -28,7 +29,7 @@ public static short ReadInt16LittleEndian(ReadOnlySpan<byte> source)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static int ReadInt32LittleEndian(ReadOnlySpan<byte> source)
{
int result = ReadMachineEndian<int>(source);
int result = MemoryMarshal.Read<int>(source);
if (!BitConverter.IsLittleEndian)
{
result = ReverseEndianness(result);
Expand All @@ -42,7 +43,7 @@ public static int ReadInt32LittleEndian(ReadOnlySpan<byte> source)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static long ReadInt64LittleEndian(ReadOnlySpan<byte> source)
{
long result = ReadMachineEndian<long>(source);
long result = MemoryMarshal.Read<long>(source);
if (!BitConverter.IsLittleEndian)
{
result = ReverseEndianness(result);
Expand All @@ -57,7 +58,7 @@ public static long ReadInt64LittleEndian(ReadOnlySpan<byte> source)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ushort ReadUInt16LittleEndian(ReadOnlySpan<byte> source)
{
ushort result = ReadMachineEndian<ushort>(source);
ushort result = MemoryMarshal.Read<ushort>(source);
if (!BitConverter.IsLittleEndian)
{
result = ReverseEndianness(result);
Expand All @@ -72,7 +73,7 @@ public static ushort ReadUInt16LittleEndian(ReadOnlySpan<byte> source)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static uint ReadUInt32LittleEndian(ReadOnlySpan<byte> source)
{
uint result = ReadMachineEndian<uint>(source);
uint result = MemoryMarshal.Read<uint>(source);
if (!BitConverter.IsLittleEndian)
{
result = ReverseEndianness(result);
Expand All @@ -87,7 +88,7 @@ public static uint ReadUInt32LittleEndian(ReadOnlySpan<byte> source)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ulong ReadUInt64LittleEndian(ReadOnlySpan<byte> source)
{
ulong result = ReadMachineEndian<ulong>(source);
ulong result = MemoryMarshal.Read<ulong>(source);
if (!BitConverter.IsLittleEndian)
{
result = ReverseEndianness(result);
Expand All @@ -102,7 +103,7 @@ public static ulong ReadUInt64LittleEndian(ReadOnlySpan<byte> source)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool TryReadInt16LittleEndian(ReadOnlySpan<byte> source, out short value)
{
bool success = TryReadMachineEndian(source, out value);
bool success = MemoryMarshal.TryRead(source, out value);
if (!BitConverter.IsLittleEndian)
{
value = ReverseEndianness(value);
Expand All @@ -117,7 +118,7 @@ public static bool TryReadInt16LittleEndian(ReadOnlySpan<byte> source, out short
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool TryReadInt32LittleEndian(ReadOnlySpan<byte> source, out int value)
{
bool success = TryReadMachineEndian(source, out value);
bool success = MemoryMarshal.TryRead(source, out value);
if (!BitConverter.IsLittleEndian)
{
value = ReverseEndianness(value);
Expand All @@ -132,7 +133,7 @@ public static bool TryReadInt32LittleEndian(ReadOnlySpan<byte> source, out int v
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool TryReadInt64LittleEndian(ReadOnlySpan<byte> source, out long value)
{
bool success = TryReadMachineEndian(source, out value);
bool success = MemoryMarshal.TryRead(source, out value);
if (!BitConverter.IsLittleEndian)
{
value = ReverseEndianness(value);
Expand All @@ -148,7 +149,7 @@ public static bool TryReadInt64LittleEndian(ReadOnlySpan<byte> source, out long
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool TryReadUInt16LittleEndian(ReadOnlySpan<byte> source, out ushort value)
{
bool success = TryReadMachineEndian(source, out value);
bool success = MemoryMarshal.TryRead(source, out value);
if (!BitConverter.IsLittleEndian)
{
value = ReverseEndianness(value);
Expand All @@ -164,7 +165,7 @@ public static bool TryReadUInt16LittleEndian(ReadOnlySpan<byte> source, out usho
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool TryReadUInt32LittleEndian(ReadOnlySpan<byte> source, out uint value)
{
bool success = TryReadMachineEndian(source, out value);
bool success = MemoryMarshal.TryRead(source, out value);
if (!BitConverter.IsLittleEndian)
{
value = ReverseEndianness(value);
Expand All @@ -180,7 +181,7 @@ public static bool TryReadUInt32LittleEndian(ReadOnlySpan<byte> source, out uint
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool TryReadUInt64LittleEndian(ReadOnlySpan<byte> source, out ulong value)
{
bool success = TryReadMachineEndian(source, out value);
bool success = MemoryMarshal.TryRead(source, out value);
if (!BitConverter.IsLittleEndian)
{
value = ReverseEndianness(value);
Expand Down
Loading

0 comments on commit a8da86d

Please sign in to comment.