Skip to content

Commit

Permalink
Merge pull request #502 from CommunityToolkit/dev/drop-netcoreapp3.1
Browse files Browse the repository at this point in the history
Drop .NET Core 3.1 TFM
  • Loading branch information
Sergio0694 authored Nov 16, 2022
2 parents adfc48c + ba425c8 commit a3bce08
Show file tree
Hide file tree
Showing 35 changed files with 54 additions and 187 deletions.
8 changes: 4 additions & 4 deletions CommunityToolkit.HighPerformance/Buffers/MemoryOwner{T}.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
using System.Buffers;
using System.Diagnostics;
using System.Runtime.CompilerServices;
#if NETCOREAPP3_1_OR_GREATER
#if NET6_0_OR_GREATER
using System.Runtime.InteropServices;
#endif
using CommunityToolkit.HighPerformance.Buffers.Views;
Expand Down Expand Up @@ -171,13 +171,13 @@ public Span<T> Span
ThrowObjectDisposedException();
}

#if NETCOREAPP3_1_OR_GREATER
#if NET6_0_OR_GREATER
ref T r0 = ref array!.DangerousGetReferenceAt(this.start);

// On .NET Core runtimes, we can manually create a span from the starting reference to
// On .NET 6+ runtimes, we can manually create a span from the starting reference to
// skip the argument validations, which include an explicit null check, covariance check
// for the array and the actual validation for the starting offset and target length. We
// only do this on .NET Core as we can leverage the runtime-specific array layout to get
// only do this on .NET 6+ as we can leverage the runtime-specific array layout to get
// a fast access to the initial element, which makes this trick worth it. Otherwise, on
// runtimes where we would need to at least access a static field to retrieve the base
// byte offset within an SZ array object, we can get better performance by just using the
Expand Down
4 changes: 2 additions & 2 deletions CommunityToolkit.HighPerformance/Buffers/SpanOwner{T}.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
using System.Buffers;
using System.Diagnostics;
using System.Runtime.CompilerServices;
#if NETCOREAPP3_1_OR_GREATER
#if NET6_0_OR_GREATER
using System.Runtime.InteropServices;
#endif
using CommunityToolkit.HighPerformance.Buffers.Views;
Expand Down Expand Up @@ -141,7 +141,7 @@ public Span<T> Span
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get
{
#if NETCOREAPP3_1_OR_GREATER
#if NET6_0_OR_GREATER
ref T r0 = ref this.array!.DangerousGetReference();

return MemoryMarshal.CreateSpan(ref r0, this.length);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>netstandard2.0;netstandard2.1;netcoreapp3.1;net6.0;net7.0</TargetFrameworks>
<TargetFrameworks>netstandard2.0;netstandard2.1;net6.0;net7.0</TargetFrameworks>
</PropertyGroup>

<PropertyGroup>
Expand Down Expand Up @@ -47,23 +47,11 @@

<When Condition="'$(TargetFramework)' == 'net6.0' OR '$(TargetFramework)' == 'net7.0'">

<!-- NETSTANDARD2_1_OR_GREATER: includes both .NET Standard 2.1, .NET Core 3.1 and .NET 6.
Additionally, also enable trimming support on .NET 6. -->
<!-- NETSTANDARD2_1_OR_GREATER: includes both .NET Standard 2.1 and .NET 6 and above -->
<PropertyGroup>
<DefineConstants>NETSTANDARD2_1_OR_GREATER</DefineConstants>
</PropertyGroup>
</When>

<When Condition="'$(TargetFramework)' == 'netcoreapp3.1'">
<PropertyGroup>
<DefineConstants>NETSTANDARD2_1_OR_GREATER</DefineConstants>
</PropertyGroup>

<!-- .NET Core 3.1 has the Unsafe type, but the version it ships with lacks Unsafe.IsNullRef<T> -->
<ItemGroup>
<PackageReference Include="System.Runtime.CompilerServices.Unsafe" Version="6.0.0" />
</ItemGroup>
</When>
</Choose>

</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

using System;
using System.Runtime.CompilerServices;
#if NETCOREAPP3_1_OR_GREATER
#if NET6_0_OR_GREATER
using System.Runtime.InteropServices;
#endif
using CommunityToolkit.HighPerformance.Enumerables;
Expand Down Expand Up @@ -33,11 +33,6 @@ public static ref T DangerousGetReference<T>(this T[] array)
{
#if NET6_0_OR_GREATER
return ref MemoryMarshal.GetArrayDataReference(array);
#elif NETCOREAPP3_1
RawArrayData? arrayData = Unsafe.As<RawArrayData>(array)!;
ref T r0 = ref Unsafe.As<byte, T>(ref arrayData.Data);

return ref r0;
#else
IntPtr offset = RuntimeHelpers.GetArrayDataByteOffset<T>();

Expand All @@ -60,12 +55,6 @@ public static ref T DangerousGetReferenceAt<T>(this T[] array, int i)
ref T r0 = ref MemoryMarshal.GetArrayDataReference(array);
ref T ri = ref Unsafe.Add(ref r0, (nint)(uint)i);

return ref ri;
#elif NETCOREAPP3_1
RawArrayData? arrayData = Unsafe.As<RawArrayData>(array)!;
ref T r0 = ref Unsafe.As<byte, T>(ref arrayData.Data);
ref T ri = ref Unsafe.Add(ref r0, (nint)(uint)i);

return ref ri;
#else
IntPtr offset = RuntimeHelpers.GetArrayDataByteOffset<T>();
Expand All @@ -76,26 +65,6 @@ public static ref T DangerousGetReferenceAt<T>(this T[] array, int i)
#endif
}

#if NETCOREAPP3_1
// Description taken from CoreCLR: see https://source.dot.net/#System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.CoreCLR.cs,285.
// CLR arrays are laid out in memory as follows (multidimensional array bounds are optional):
// [ sync block || pMethodTable || num components || MD array bounds || array data .. ]
// ^ ^ ^ returned reference
// | \-- ref Unsafe.As<RawArrayData>(array).Data
// \-- array
// The base size of an array includes all the fields before the array data,
// including the sync block and method table. The reference to RawData.Data
// points at the number of components, skipping over these two pointer-sized fields.
[StructLayout(LayoutKind.Sequential)]
private sealed class RawArrayData
{
#pragma warning disable CS0649 // Unassigned fields
public IntPtr Length;
public byte Data;
#pragma warning restore CS0649
}
#endif

/// <summary>
/// Counts the number of occurrences of a given value into a target <typeparamref name="T"/> array instance.
/// </summary>
Expand Down
35 changes: 0 additions & 35 deletions CommunityToolkit.HighPerformance/Extensions/ArrayExtensions.2D.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,6 @@ public static ref T DangerousGetReference<T>(this T[,] array)
{
#if NET6_0_OR_GREATER
return ref Unsafe.As<byte, T>(ref MemoryMarshal.GetArrayDataReference(array));
#elif NETCOREAPP3_1
RawArray2DData? arrayData = Unsafe.As<RawArray2DData>(array)!;
ref T r0 = ref Unsafe.As<byte, T>(ref arrayData.Data);

return ref r0;
#else
IntPtr offset = RuntimeHelpers.GetArray2DDataByteOffset<T>();

Expand Down Expand Up @@ -65,13 +60,6 @@ public static ref T DangerousGetReferenceAt<T>(this T[,] array, int i, int j)
ref T r0 = ref Unsafe.As<byte, T>(ref MemoryMarshal.GetArrayDataReference(array));
ref T ri = ref Unsafe.Add(ref r0, index);

return ref ri;
#elif NETCOREAPP3_1
RawArray2DData? arrayData = Unsafe.As<RawArray2DData>(array)!;
nint offset = ((nint)(uint)i * (nint)(uint)arrayData.Width) + (nint)(uint)j;
ref T r0 = ref Unsafe.As<byte, T>(ref arrayData.Data);
ref T ri = ref Unsafe.Add(ref r0, offset);

return ref ri;
#else
int width = array.GetLength(1);
Expand All @@ -84,29 +72,6 @@ public static ref T DangerousGetReferenceAt<T>(this T[,] array, int i, int j)
#endif
}

#if NETCOREAPP3_1
// Description adapted from CoreCLR: see https://source.dot.net/#System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.CoreCLR.cs,285.
// CLR 2D arrays are laid out in memory as follows:
// [ sync block || pMethodTable || Length (padded to IntPtr) || HxW || HxW bounds || array data .. ]
// ^ ^
// | \-- ref Unsafe.As<RawArray2DData>(array).Data
// \-- array
// The length is always padded to IntPtr just like with SZ arrays.
// The total data padding is therefore 20 bytes on x86 (4 + 4 + 4 + 4 + 4), or 24 bytes on x64.
[StructLayout(LayoutKind.Sequential)]
private sealed class RawArray2DData
{
#pragma warning disable CS0649 // Unassigned fields
public IntPtr Length;
public int Height;
public int Width;
public int HeightLowerBound;
public int WidthLowerBound;
public byte Data;
#pragma warning restore CS0649
}
#endif

/// <summary>
/// Returns a <see cref="RefEnumerable{T}"/> over a row in a given 2D <typeparamref name="T"/> array instance.
/// </summary>
Expand Down
33 changes: 0 additions & 33 deletions CommunityToolkit.HighPerformance/Extensions/ArrayExtensions.3D.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,6 @@ public static ref T DangerousGetReference<T>(this T[,,] array)
{
#if NET6_0_OR_GREATER
return ref Unsafe.As<byte, T>(ref MemoryMarshal.GetArrayDataReference(array));
#elif NETCOREAPP3_1
RawArray3DData? arrayData = Unsafe.As<RawArray3DData>(array)!;
ref T r0 = ref Unsafe.As<byte, T>(ref arrayData.Data);

return ref r0;
#else
IntPtr offset = RuntimeHelpers.GetArray3DDataByteOffset<T>();

Expand Down Expand Up @@ -68,15 +63,6 @@ public static ref T DangerousGetReferenceAt<T>(this T[,,] array, int i, int j, i
ref T r0 = ref Unsafe.As<byte, T>(ref MemoryMarshal.GetArrayDataReference(array));
ref T ri = ref Unsafe.Add(ref r0, index);

return ref ri;
#elif NETCOREAPP3_1
RawArray3DData? arrayData = Unsafe.As<RawArray3DData>(array)!;
nint offset =
((nint)(uint)i * (nint)(uint)arrayData.Height * (nint)(uint)arrayData.Width) +
((nint)(uint)j * (nint)(uint)arrayData.Width) + (nint)(uint)k;
ref T r0 = ref Unsafe.As<byte, T>(ref arrayData.Data);
ref T ri = ref Unsafe.Add(ref r0, offset);

return ref ri;
#else
int height = array.GetLength(1);
Expand All @@ -92,25 +78,6 @@ public static ref T DangerousGetReferenceAt<T>(this T[,,] array, int i, int j, i
#endif
}

#if NETCOREAPP3_1
// See description for this in the 2D partial file.
// Using the CHW naming scheme here (like with RGB images).
[StructLayout(LayoutKind.Sequential)]
private sealed class RawArray3DData
{
#pragma warning disable CS0649 // Unassigned fields
public IntPtr Length;
public int Channel;
public int Height;
public int Width;
public int ChannelLowerBound;
public int HeightLowerBound;
public int WidthLowerBound;
public byte Data;
#pragma warning restore CS0649
}
#endif

#if NETSTANDARD2_1_OR_GREATER
/// <summary>
/// Creates a new <see cref="Memory{T}"/> over an input 3D <typeparamref name="T"/> array.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public static class StringExtensions
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ref char DangerousGetReference(this string text)
{
#if NETCOREAPP3_1_OR_GREATER
#if NET6_0_OR_GREATER
return ref Unsafe.AsRef(text.GetPinnableReference());
#else
return ref MemoryMarshal.GetReference(text.AsSpan());
Expand All @@ -43,7 +43,7 @@ public static ref char DangerousGetReference(this string text)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ref char DangerousGetReferenceAt(this string text, int i)
{
#if NETCOREAPP3_1_OR_GREATER
#if NET6_0_OR_GREATER
ref char r0 = ref Unsafe.AsRef(text.GetPinnableReference());
#else
ref char r0 = ref MemoryMarshal.GetReference(text.AsSpan());
Expand Down
10 changes: 5 additions & 5 deletions CommunityToolkit.HighPerformance/Helpers/BitHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
// See the LICENSE file in the project root for more information.

using System.Runtime.CompilerServices;
#if NETCOREAPP3_1_OR_GREATER
#if NET6_0_OR_GREATER
using System.Runtime.Intrinsics.X86;
#endif

Expand Down Expand Up @@ -224,7 +224,7 @@ public static unsafe uint SetFlag(uint value, int n, bool flag)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static uint ExtractRange(uint value, byte start, byte length)
{
#if NETCOREAPP3_1_OR_GREATER
#if NET6_0_OR_GREATER
if (Bmi1.IsSupported)
{
return Bmi1.BitFieldExtract(value, start, length);
Expand Down Expand Up @@ -270,7 +270,7 @@ public static uint SetRange(uint value, byte start, byte length, uint flags)
uint loadMask = highBits << start;
uint storeMask = (flags & highBits) << start;

#if NETCOREAPP3_1_OR_GREATER
#if NET6_0_OR_GREATER
if (Bmi1.IsSupported)
{
return Bmi1.AndNot(loadMask, value) | storeMask;
Expand Down Expand Up @@ -386,7 +386,7 @@ public static unsafe ulong SetFlag(ulong value, int n, bool flag)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ulong ExtractRange(ulong value, byte start, byte length)
{
#if NETCOREAPP3_1_OR_GREATER
#if NET6_0_OR_GREATER
if (Bmi1.X64.IsSupported)
{
return Bmi1.X64.BitFieldExtract(value, start, length);
Expand Down Expand Up @@ -432,7 +432,7 @@ public static ulong SetRange(ulong value, byte start, byte length, ulong flags)
ulong loadMask = highBits << start;
ulong storeMask = (flags & highBits) << start;

#if NETCOREAPP3_1_OR_GREATER
#if NET6_0_OR_GREATER
if (Bmi1.X64.IsSupported)
{
return Bmi1.X64.AndNot(loadMask, value) | storeMask;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,6 @@
#if !NET6_0_OR_GREATER

using System.Runtime.CompilerServices;
#if NETCOREAPP3_1
using System.Runtime.Intrinsics.X86;
using static System.Numerics.BitOperations;
#endif

namespace CommunityToolkit.HighPerformance.Helpers.Internals;

Expand All @@ -29,22 +25,6 @@ internal static class BitOperations
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static unsafe uint RoundUpToPowerOf2(uint value)
{
#if NETCOREAPP3_1
if (Lzcnt.IsSupported)
{
if (sizeof(nint) == 8)
{
return (uint)(0x1_0000_0000ul >> LeadingZeroCount(value - 1));
}
else
{
int shift = 32 - LeadingZeroCount(value - 1);

return (1u ^ (uint)(shift >> 5)) << shift;
}
}
#endif

// Based on https://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2
--value;
value |= value >> 1;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ public static nint GetArrayNativeLength(Array array)
return (nint)array.LongLength;
}

#if !NETCOREAPP3_1_OR_GREATER
#if !NET6_0_OR_GREATER
/// <summary>
/// Gets the byte offset to the first <typeparamref name="T"/> element in a SZ array.
/// </summary>
Expand Down
8 changes: 4 additions & 4 deletions azure-pipelines.yml
Original file line number Diff line number Diff line change
Expand Up @@ -53,14 +53,14 @@ jobs:

# Test solution #

# Run .NET 7 unit tests
- script: dotnet test --no-build -c $(Build.Configuration) -f net7.0 -l "trx;LogFileName=VSTestResults_net7.0.trx"
displayName: Run .NET 7 unit tests

# Run .NET 6 unit tests
- script: dotnet test --no-build -c $(Build.Configuration) -f net6.0 -l "trx;LogFileName=VSTestResults_net6.0.trx"
displayName: Run .NET 6 unit tests

# Run .NET Core 3.1 unit tests
- script: dotnet test --no-build -c $(Build.Configuration) -f netcoreapp3.1 -l "trx;LogFileName=VSTestResults_netcoreapp3.1.trx"
displayName: Run .NET Core 3.1 unit tests

# Run .NET Framework 4.7.2 unit tests
- script: dotnet test --no-build -c $(Build.Configuration) -f net472 -l "trx;LogFileName=VSTestResults_net472.trx"
displayName: Run .NET Framework 4.7.2 unit tests
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>net472;netcoreapp3.1;net6.0</TargetFrameworks>
<TargetFrameworks>net472;net6.0;net7.0</TargetFrameworks>
</PropertyGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>net472;netcoreapp3.1;net6.0</TargetFrameworks>
<TargetFrameworks>net472;net6.0;net7.0</TargetFrameworks>
</PropertyGroup>

<ItemGroup>
Expand Down
Loading

0 comments on commit a3bce08

Please sign in to comment.