From 3eca894deca3d72a5b0f8139caa624c7376301f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20S=C3=A1nchez=20L=C3=B3pez?= <1175054+carlossanlop@users.noreply.github.com> Date: Fri, 20 Oct 2023 16:22:43 -0700 Subject: [PATCH 01/13] [release/8.0] Stable branding for .NET 8 GA --- eng/Versions.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eng/Versions.props b/eng/Versions.props index 189fb6671d44b9..bb58d6b88e9e7c 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -13,7 +13,7 @@ - false + true release -$(PreReleaseVersionLabel) -$(PreReleaseVersionLabel).$(PreReleaseVersionIteration) From d14b1e81e19d44b6ab1ec7f672478a91607d0886 Mon Sep 17 00:00:00 2001 From: Larry Ewing Date: Fri, 20 Oct 2023 21:40:23 -0500 Subject: [PATCH 02/13] Handle an empty bandPreleaseVersion --- src/tasks/WorkloadBuildTasks/InstallWorkloadFromArtifacts.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tasks/WorkloadBuildTasks/InstallWorkloadFromArtifacts.cs b/src/tasks/WorkloadBuildTasks/InstallWorkloadFromArtifacts.cs index 62817719af0a14..21170ea2152843 100644 --- a/src/tasks/WorkloadBuildTasks/InstallWorkloadFromArtifacts.cs +++ b/src/tasks/WorkloadBuildTasks/InstallWorkloadFromArtifacts.cs @@ -301,8 +301,8 @@ private bool InstallWorkloadManifest(ITaskItem workloadId, string name, string v string packagePreleaseVersion = bandVersionRegex().Match(version).Groups[1].Value; string bandPreleaseVersion = bandVersionRegex().Match(bandVersion).Groups[1].Value; - if (packagePreleaseVersion != bandPreleaseVersion && packagePreleaseVersion != "-dev" && packagePreleaseVersion != "-ci") - bandVersion = bandVersion.Replace (bandPreleaseVersion, packagePreleaseVersion); + if (packagePreleaseVersion != bandPreleaseVersion && packagePreleaseVersion != "-dev" && packagePreleaseVersion != "-ci" && bandPreleaseVersion != "") + bandVersion = bandVersion.Replace(bandPreleaseVersion, packagePreleaseVersion); PackageReference pkgRef = new(Name: $"{name}.Manifest-{bandVersion}", Version: version, From 14a0bbcdedf2440fbeb67c670e9c30d1e22cccef Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Mon, 23 Oct 2023 06:26:29 -0500 Subject: [PATCH 03/13] [release/8.0] Update dependencies from dotnet/emsdk (#93801) * Update dependencies from https://github.com/dotnet/emsdk build 20231020.2 Microsoft.NET.Workload.Emscripten.Current.Manifest-8.0.100.Transport From Version 8.0.0-rtm.23511.3 -> To Version 8.0.0-rtm.23520.2 * switch to the stable version now * Update dependencies * Also fix the trigger * pin the wbt sdk to avoid the latest analizer nonsense * Use source generation for the serializer * Try to make sourcebuild happy * Try again to make sourcebuild happy * Use reflection and suppress trim analysis instead This reverts commit 768b65bab585f303bca6e0e9a36cf06d59e90387. * Fix reverting too much --------- Co-authored-by: dotnet-maestro[bot] Co-authored-by: Larry Ewing --- NuGet.config | 5 ++ eng/Version.Details.xml | 68 ++++++++++--------- eng/Versions.props | 6 +- eng/pipelines/common/xplat-setup.yml | 2 +- .../WasmBasicTestApp/WasmBasicTestApp.csproj | 1 + 5 files changed, 46 insertions(+), 36 deletions(-) diff --git a/NuGet.config b/NuGet.config index 80dd215a4bf01b..423372ca9017d9 100644 --- a/NuGet.config +++ b/NuGet.config @@ -7,6 +7,11 @@ + + + + + - 8.0.0-rtm.23511.3 - $(MicrosoftNETWorkloadEmscriptenCurrentManifest80100TransportVersion) + 8.0.0 + $(MicrosoftNETWorkloadEmscriptenCurrentManifest80100Version) 1.1.87-gba258badda 1.0.0-v3.14.0.5722 @@ -258,7 +258,7 @@ 3.1.7 1.0.406601 - 8.0.100-rtm.23478.7 + 8.0.100-rtm.23506.1 diff --git a/eng/pipelines/common/xplat-setup.yml b/eng/pipelines/common/xplat-setup.yml index 28257b05265ba0..eb19570aeecac2 100644 --- a/eng/pipelines/common/xplat-setup.yml +++ b/eng/pipelines/common/xplat-setup.yml @@ -108,7 +108,7 @@ jobs: - ${{ if eq(parameters.archType, 'wasm') }}: - name: wasmDarcDependenciesChanged value: $[ or( - eq(dependencies.evaluate_paths.outputs['DarcDependenciesChanged.Microsoft_NET_Workload_Emscripten_Current_Manifest-8_0_100_Transport'], true), + eq(dependencies.evaluate_paths.outputs['DarcDependenciesChanged.Microsoft_NET_Workload_Emscripten_Current_Manifest-8_0_100'], true), eq(dependencies.evaluate_paths.outputs['DarcDependenciesChanged.Microsoft_DotNet_Build_Tasks_Workloads'], true), eq(dependencies.evaluate_paths.outputs['DarcDependenciesChanged.System_Runtime_TimeZoneData'], true), eq(dependencies.evaluate_paths.outputs['DarcDependenciesChanged.Microsoft_Net_Compilers_Toolset'], true), diff --git a/src/mono/wasm/testassets/WasmBasicTestApp/WasmBasicTestApp.csproj b/src/mono/wasm/testassets/WasmBasicTestApp/WasmBasicTestApp.csproj index 33858b9a6a755f..761ac6354ce861 100644 --- a/src/mono/wasm/testassets/WasmBasicTestApp/WasmBasicTestApp.csproj +++ b/src/mono/wasm/testassets/WasmBasicTestApp/WasmBasicTestApp.csproj @@ -4,6 +4,7 @@ browser-wasm Exe true + true From e1da68dcd2ac0df0f861e2b3443de0539e34ea48 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 23 Oct 2023 17:22:57 +0200 Subject: [PATCH 04/13] [release/8.0] Update APICompat settings under source build (#93865) * Update APICompat settings under source build * Update resolveContract.targets --------- Co-authored-by: Viktor Hofer --- eng/resolveContract.targets | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/eng/resolveContract.targets b/eng/resolveContract.targets index 6d414f46f93e6b..3454d7064739a8 100644 --- a/eng/resolveContract.targets +++ b/eng/resolveContract.targets @@ -73,8 +73,9 @@ That is necessary as APICompat is invoked twice, once for the ref <-> src comparision and then again for the package validation (which doesn't include reference assemblies). As both operations don't have all the inputs available, some suppressions might only apply to one or the other and hence unnecessary - suppressions can't be determined. --> - + suppressions can't be determined. + Disable the validation under source build as that might use an out-of-date SDK and not the ApiCompat.Task package. --> + true true From 1c9b5ee4cb7a45affb2b47bff7f9c2d7be26ac15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20K=C3=B6plinger?= Date: Mon, 23 Oct 2023 19:48:04 +0200 Subject: [PATCH 05/13] Override InformationalVersion for NativeAOT corelib too --- src/coreclr/nativeaot/Directory.Build.props | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/coreclr/nativeaot/Directory.Build.props b/src/coreclr/nativeaot/Directory.Build.props index ebfa725e4efd2c..005d6ae997adab 100644 --- a/src/coreclr/nativeaot/Directory.Build.props +++ b/src/coreclr/nativeaot/Directory.Build.props @@ -25,6 +25,9 @@ false v4.0.30319 + + $(ProductVersion) + $(ProductVersion) $(NoWarn),0419,0649,CA2249,CA1830 From d8d69276650adcc2549804d053a0145763d39765 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 23 Oct 2023 13:34:35 -0700 Subject: [PATCH 06/13] [release/8.0] Improve performance of UnmanagedMemoryStream (#93812) * Improve performance of UnmanagedMemoryStream UnmanagedMemoryStream used Interlocked operations to update its state to prevent tearing of 64-bit values on 32-bit platforms. This pattern is expensive in general and it was found to be prohibitively expensive on recent hardware.. This change removes the expensive Interlocked operations and addresses the tearing issues in alternative way: - The _length field is converted to nuint that is guaranteed to be updated atomically. - Writes to _length field are volatile to guaranteed the unininitialized memory cannot be read. - The _position field remains long and it has a risk of tearing. It is not a problem since tearing of this field cannot lead to buffer overruns. Fixes #93624 * Add comment --------- Co-authored-by: Jan Kotas --- .../src/System/IO/UnmanagedMemoryStream.cs | 126 +++++++++--------- 1 file changed, 63 insertions(+), 63 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/IO/UnmanagedMemoryStream.cs b/src/libraries/System.Private.CoreLib/src/System/IO/UnmanagedMemoryStream.cs index 5f049e69445381..b2a3134ae7501a 100644 --- a/src/libraries/System.Private.CoreLib/src/System/IO/UnmanagedMemoryStream.cs +++ b/src/libraries/System.Private.CoreLib/src/System/IO/UnmanagedMemoryStream.cs @@ -23,14 +23,9 @@ namespace System.IO * of the UnmanagedMemoryStream. * 3) You clean up the memory when appropriate. The UnmanagedMemoryStream * currently will do NOTHING to free this memory. - * 4) All calls to Write and WriteByte may not be threadsafe currently. - * - * It may become necessary to add in some sort of - * DeallocationMode enum, specifying whether we unmap a section of memory, - * call free, run a user-provided delegate to free the memory, etc. - * We'll suggest user write a subclass of UnmanagedMemoryStream that uses - * a SafeHandle subclass to hold onto the memory. - * + * 4) This type is not thread safe. However, the implementation should prevent buffer + * overruns or returning uninitialized memory when Reads and Writes are called + * concurrently in thread unsafe manner. */ /// @@ -40,10 +35,10 @@ public class UnmanagedMemoryStream : Stream { private SafeBuffer? _buffer; private unsafe byte* _mem; - private long _length; - private long _capacity; - private long _position; - private long _offset; + private nuint _capacity; + private nuint _offset; + private nuint _length; // nuint to guarantee atomic access on 32-bit platforms + private long _position; // long to allow seeking to any location beyond the length of the stream. private FileAccess _access; private bool _isOpen; private CachedCompletedInt32Task _lastReadTask; // The last successful task returned from ReadAsync @@ -123,10 +118,10 @@ protected void Initialize(SafeBuffer buffer, long offset, long length, FileAcces } } - _offset = offset; + _offset = (nuint)offset; _buffer = buffer; - _length = length; - _capacity = length; + _length = (nuint)length; + _capacity = (nuint)length; _access = access; _isOpen = true; } @@ -171,8 +166,8 @@ protected unsafe void Initialize(byte* pointer, long length, long capacity, File _mem = pointer; _offset = 0; - _length = length; - _capacity = capacity; + _length = (nuint)length; + _capacity = (nuint)capacity; _access = access; _isOpen = true; } @@ -259,7 +254,7 @@ public override long Length get { EnsureNotClosed(); - return Interlocked.Read(ref _length); + return (long)_length; } } @@ -271,7 +266,7 @@ public long Capacity get { EnsureNotClosed(); - return _capacity; + return (long)_capacity; } } @@ -283,14 +278,14 @@ public override long Position get { if (!CanSeek) ThrowHelper.ThrowObjectDisposedException_StreamClosed(null); - return Interlocked.Read(ref _position); + return _position; } set { ArgumentOutOfRangeException.ThrowIfNegative(value); if (!CanSeek) ThrowHelper.ThrowObjectDisposedException_StreamClosed(null); - Interlocked.Exchange(ref _position, value); + _position = value; } } @@ -308,11 +303,10 @@ public unsafe byte* PositionPointer EnsureNotClosed(); // Use a temp to avoid a race - long pos = Interlocked.Read(ref _position); - if (pos > _capacity) + long pos = _position; + if (pos > (long)_capacity) throw new IndexOutOfRangeException(SR.IndexOutOfRange_UMSPosition); - byte* ptr = _mem + pos; - return ptr; + return _mem + pos; } set { @@ -327,7 +321,7 @@ public unsafe byte* PositionPointer if (newPosition < 0) throw new ArgumentOutOfRangeException(nameof(value), SR.ArgumentOutOfRange_UnmanagedMemStreamLength); - Interlocked.Exchange(ref _position, newPosition); + _position = newPosition; } } @@ -367,8 +361,13 @@ internal int ReadCore(Span buffer) // Use a local variable to avoid a race where another thread // changes our position after we decide we can read some bytes. - long pos = Interlocked.Read(ref _position); - long len = Interlocked.Read(ref _length); + long pos = _position; + + // Use a volatile read to prevent reading of the uninitialized memory. This volatile read + // and matching volatile write that set _length avoids reordering of NativeMemory.Clear + // operations with reading of the buffer below. + long len = (long)Volatile.Read(ref _length); + long n = Math.Min(len - pos, buffer.Length); if (n <= 0) { @@ -407,7 +406,7 @@ internal int ReadCore(Span buffer) } } - Interlocked.Exchange(ref _position, pos + n); + _position = pos + n; return nInt; } @@ -484,11 +483,16 @@ public override int ReadByte() EnsureNotClosed(); EnsureReadable(); - long pos = Interlocked.Read(ref _position); // Use a local to avoid a race condition - long len = Interlocked.Read(ref _length); + long pos = _position; // Use a local to avoid a race condition + + // Use a volatile read to prevent reading of the uninitialized memory. This volatile read + // and matching volatile write that set _length avoids reordering of NativeMemory.Clear + // operations with reading of the buffer below. + long len = (long)Volatile.Read(ref _length); + if (pos >= len) return -1; - Interlocked.Exchange(ref _position, pos + 1); + _position = pos + 1; int result; if (_buffer != null) { @@ -529,35 +533,33 @@ public override long Seek(long offset, SeekOrigin loc) { EnsureNotClosed(); + long newPosition; switch (loc) { case SeekOrigin.Begin: - if (offset < 0) + newPosition = offset; + if (newPosition < 0) throw new IOException(SR.IO_SeekBeforeBegin); - Interlocked.Exchange(ref _position, offset); break; case SeekOrigin.Current: - long pos = Interlocked.Read(ref _position); - if (offset + pos < 0) + newPosition = _position + offset; + if (newPosition < 0) throw new IOException(SR.IO_SeekBeforeBegin); - Interlocked.Exchange(ref _position, offset + pos); break; case SeekOrigin.End: - long len = Interlocked.Read(ref _length); - if (len + offset < 0) + newPosition = (long)_length + offset; + if (newPosition < 0) throw new IOException(SR.IO_SeekBeforeBegin); - Interlocked.Exchange(ref _position, len + offset); break; default: throw new ArgumentException(SR.Argument_InvalidSeekOrigin); } - long finalPos = Interlocked.Read(ref _position); - Debug.Assert(finalPos >= 0, "_position >= 0"); - return finalPos; + _position = newPosition; + return newPosition; } /// @@ -573,11 +575,10 @@ public override void SetLength(long value) EnsureNotClosed(); EnsureWriteable(); - if (value > _capacity) + if (value > (long)_capacity) throw new IOException(SR.IO_FixedCapacity); - long pos = Interlocked.Read(ref _position); - long len = Interlocked.Read(ref _length); + long len = (long)_length; if (value > len) { unsafe @@ -585,10 +586,11 @@ public override void SetLength(long value) NativeMemory.Clear(_mem + len, (nuint)(value - len)); } } - Interlocked.Exchange(ref _length, value); - if (pos > value) + Volatile.Write(ref _length, (nuint)value); // volatile to prevent reading of uninitialized memory + + if (_position > value) { - Interlocked.Exchange(ref _position, value); + _position = value; } } @@ -625,8 +627,8 @@ internal unsafe void WriteCore(ReadOnlySpan buffer) EnsureNotClosed(); EnsureWriteable(); - long pos = Interlocked.Read(ref _position); // Use a local to avoid a race condition - long len = Interlocked.Read(ref _length); + long pos = _position; // Use a local to avoid a race condition + long len = (long)_length; long n = pos + buffer.Length; // Check for overflow if (n < 0) @@ -634,7 +636,7 @@ internal unsafe void WriteCore(ReadOnlySpan buffer) throw new IOException(SR.IO_StreamTooLong); } - if (n > _capacity) + if (n > (long)_capacity) { throw new NotSupportedException(SR.IO_FixedCapacity); } @@ -648,16 +650,16 @@ internal unsafe void WriteCore(ReadOnlySpan buffer) NativeMemory.Clear(_mem + len, (nuint)(pos - len)); } - // set length after zeroing memory to avoid race condition of accessing unzeroed memory + // set length after zeroing memory to avoid race condition of accessing uninitialized memory if (n > len) { - Interlocked.Exchange(ref _length, n); + Volatile.Write(ref _length, (nuint)n); // volatile to prevent reading of uninitialized memory } } if (_buffer != null) { - long bytesLeft = _capacity - pos; + long bytesLeft = (long)_capacity - pos; if (bytesLeft < buffer.Length) { throw new ArgumentException(SR.Arg_BufferTooSmall); @@ -682,8 +684,7 @@ internal unsafe void WriteCore(ReadOnlySpan buffer) Buffer.Memmove(ref *(_mem + pos), ref MemoryMarshal.GetReference(buffer), (nuint)buffer.Length); } - Interlocked.Exchange(ref _position, n); - return; + _position = n; } /// @@ -754,8 +755,8 @@ public override void WriteByte(byte value) EnsureNotClosed(); EnsureWriteable(); - long pos = Interlocked.Read(ref _position); // Use a local to avoid a race condition - long len = Interlocked.Read(ref _length); + long pos = _position; // Use a local to avoid a race condition + long len = (long)_length; long n = pos + 1; if (pos >= len) { @@ -763,7 +764,7 @@ public override void WriteByte(byte value) if (n < 0) throw new IOException(SR.IO_StreamTooLong); - if (n > _capacity) + if (n > (long)_capacity) throw new NotSupportedException(SR.IO_FixedCapacity); // Check to see whether we are now expanding the stream and must @@ -779,8 +780,7 @@ public override void WriteByte(byte value) } } - // set length after zeroing memory to avoid race condition of accessing unzeroed memory - Interlocked.Exchange(ref _length, n); + Volatile.Write(ref _length, (nuint)n); // volatile to prevent reading of uninitialized memory } } @@ -810,7 +810,7 @@ public override void WriteByte(byte value) _mem[pos] = value; } } - Interlocked.Exchange(ref _position, n); + _position = n; } } } From b1abc322c7be91f14aaa27e992511c3e22a51c3c Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Mon, 23 Oct 2023 13:36:15 -0700 Subject: [PATCH 07/13] Update dependencies from https://github.com/dotnet/emsdk build 20231023.2 (#93881) Microsoft.SourceBuild.Intermediate.emsdk , Microsoft.NET.Workload.Emscripten.Current.Manifest-8.0.100 From Version 8.0.0-rtm.23520.2 -> To Version 8.0.0-rtm.23523.2 Co-authored-by: dotnet-maestro[bot] --- NuGet.config | 2 +- eng/Version.Details.xml | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/NuGet.config b/NuGet.config index 423372ca9017d9..29f8225aac34fb 100644 --- a/NuGet.config +++ b/NuGet.config @@ -9,7 +9,7 @@ - + diff --git a/eng/Versions.props b/eng/Versions.props index 7bca669addc848..6fef84713ea81c 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -158,12 +158,12 @@ 8.0.0-beta.23421.1 8.0.0-beta.23421.1 - 1.0.0-prerelease.23519.5 - 1.0.0-prerelease.23519.5 - 1.0.0-prerelease.23519.5 - 1.0.0-prerelease.23519.5 - 1.0.0-prerelease.23519.5 - 1.0.0-prerelease.23519.5 + 1.0.0-prerelease.23521.3 + 1.0.0-prerelease.23521.3 + 1.0.0-prerelease.23521.3 + 1.0.0-prerelease.23521.3 + 1.0.0-prerelease.23521.3 + 1.0.0-prerelease.23521.3 16.11.29-beta1.23404.4 2.0.0-beta4.23307.1 From 488a8a3521610422e8fbe22d5cc66127f3dce3dc Mon Sep 17 00:00:00 2001 From: Ankit Jain Date: Mon, 23 Oct 2023 22:26:57 -0400 Subject: [PATCH 09/13] [release/8.0][wasm] Fix perf pipeline runs (#93888) * Remove --experimental-wasm-eh argument from the wasm_args used for wasm performance runs. (#93357) (cherry picked from commit a770017fea3549e0bf88f7c619b79a731271e305) * performance-setup.sh: Use `release/8.0` as the default channel * performance-setup.ps1: use release/8.0 as the default channel * Fix passing wasmArgs for bdn --------- Co-authored-by: Parker Bibus --- eng/testing/performance/performance-setup.ps1 | 2 +- eng/testing/performance/performance-setup.sh | 9 +++------ 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/eng/testing/performance/performance-setup.ps1 b/eng/testing/performance/performance-setup.ps1 index 8caea345a893dc..8a8cd269dbe454 100644 --- a/eng/testing/performance/performance-setup.ps1 +++ b/eng/testing/performance/performance-setup.ps1 @@ -101,7 +101,7 @@ if ($iOSNativeAOT) { } # FIX ME: This is a workaround until we get this from the actual pipeline -$CleanedBranchName = "main" +$CleanedBranchName = "release/8.0" if($Branch.Contains("refs/heads/release")) { $CleanedBranchName = $Branch.replace('refs/heads/', '') diff --git a/eng/testing/performance/performance-setup.sh b/eng/testing/performance/performance-setup.sh index 9a1c95ec730820..c53ca6924b97b4 100755 --- a/eng/testing/performance/performance-setup.sh +++ b/eng/testing/performance/performance-setup.sh @@ -358,9 +358,7 @@ if [[ "$physicalpromotion" == "true" ]]; then configurations="$configurations PhysicalPromotionType=physicalpromotion" fi - - -cleaned_branch_name="main" +cleaned_branch_name="release/8.0" if [[ $branch == *"refs/heads/release"* ]]; then cleaned_branch_name=${branch/refs\/heads\//} fi @@ -404,15 +402,14 @@ if [[ -n "$wasm_bundle_directory" ]]; then using_wasm=true wasm_bundle_directory_path=$payload_directory mv $wasm_bundle_directory/* $wasm_bundle_directory_path - find $wasm_bundle_directory_path -type d - wasm_args="--experimental-wasm-eh --expose_wasm" + wasm_args="--expose_wasm" if [ "$javascript_engine" == "v8" ]; then # for es6 module support wasm_args="$wasm_args --module" fi # Workaround: escaping the quotes around `--wasmArgs=..` so they get retained for the actual command line - extra_benchmark_dotnet_arguments="$extra_benchmark_dotnet_arguments --wasmEngine /home/helixbot/.jsvu/bin/$javascript_engine --wasmArgs \\\"$wasm_args\\\" --cli \$HELIX_CORRELATION_PAYLOAD/dotnet/dotnet --wasmDataDir \$HELIX_CORRELATION_PAYLOAD/wasm-data" + extra_benchmark_dotnet_arguments="$extra_benchmark_dotnet_arguments --wasmEngine /home/helixbot/.jsvu/bin/$javascript_engine \\\"--wasmArgs=$wasm_args\\\" --cli \$HELIX_CORRELATION_PAYLOAD/dotnet/dotnet --wasmDataDir \$HELIX_CORRELATION_PAYLOAD/wasm-data" if [[ "$wasmaot" == "true" ]]; then extra_benchmark_dotnet_arguments="$extra_benchmark_dotnet_arguments --aotcompilermode wasm --buildTimeout 3600" fi From 59edaad404d1b8e47080015ae8d0787f94c970df Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 24 Oct 2023 13:21:59 -0700 Subject: [PATCH 10/13] [release/8.0] Honor JsonSerializerOptions.PropertyNameCaseInsensitive in property name conflict resolution. (#93935) * Honor JsonSerializerOptions.PropertyNameCaseInsensitive in property name conflict resolution. * Update src/libraries/System.Text.Json/tests/Common/PropertyNameTests.cs Co-authored-by: Jeff Handley * Address feedback --------- Co-authored-by: Eirik Tsarpalis Co-authored-by: Jeff Handley --- .../gen/JsonSourceGenerator.Parser.cs | 7 ++--- .../DefaultJsonTypeInfoResolver.Helpers.cs | 2 +- .../Metadata/JsonMetadataServices.Helpers.cs | 2 +- .../Serialization/Metadata/JsonTypeInfo.cs | 5 ++-- .../tests/Common/PropertyNameTests.cs | 29 +++++++++++++++++++ .../Serialization/PropertyNameTests.cs | 2 ++ 6 files changed, 38 insertions(+), 9 deletions(-) diff --git a/src/libraries/System.Text.Json/gen/JsonSourceGenerator.Parser.cs b/src/libraries/System.Text.Json/gen/JsonSourceGenerator.Parser.cs index e0dac6a9ad82ce..594f7ad9770c3c 100644 --- a/src/libraries/System.Text.Json/gen/JsonSourceGenerator.Parser.cs +++ b/src/libraries/System.Text.Json/gen/JsonSourceGenerator.Parser.cs @@ -863,7 +863,7 @@ private List ParsePropertyGenerationSpecs( { Location? typeLocation = typeToGenerate.Location; List properties = new(); - PropertyHierarchyResolutionState state = new(); + PropertyHierarchyResolutionState state = new(options); hasExtensionDataProperty = false; // Walk the type hierarchy starting from the current type up to the base type(s) @@ -970,11 +970,10 @@ bool PropertyIsOverriddenAndIgnored(IPropertySymbol property, Dictionary Properties = new(); - public Dictionary AddedProperties = new(); + public Dictionary AddedProperties = new(options?.PropertyNameCaseInsensitive == true ? StringComparer.OrdinalIgnoreCase : StringComparer.Ordinal); public Dictionary? IgnoredMembers; public bool IsPropertyOrderSpecified; public bool HasInvalidConfigurationForFastPath; diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/DefaultJsonTypeInfoResolver.Helpers.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/DefaultJsonTypeInfoResolver.Helpers.cs index c654a920f8ff6e..3f929d87378485 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/DefaultJsonTypeInfoResolver.Helpers.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/DefaultJsonTypeInfoResolver.Helpers.cs @@ -88,7 +88,7 @@ private static void PopulateProperties(JsonTypeInfo typeInfo) bool constructorHasSetsRequiredMembersAttribute = typeInfo.Converter.ConstructorInfo?.HasSetsRequiredMembersAttribute() ?? false; - JsonTypeInfo.PropertyHierarchyResolutionState state = new(); + JsonTypeInfo.PropertyHierarchyResolutionState state = new(typeInfo.Options); // Walk the type hierarchy starting from the current type up to the base type(s) foreach (Type currentType in typeInfo.Type.GetSortedTypeHierarchy()) diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/JsonMetadataServices.Helpers.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/JsonMetadataServices.Helpers.cs index 1b7113f9dd758a..965b4cea39570a 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/JsonMetadataServices.Helpers.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/JsonMetadataServices.Helpers.cs @@ -137,7 +137,7 @@ internal static void PopulateProperties(JsonTypeInfo typeInfo, JsonTypeInfo.Json // Regardless of the source generator we need to re-run the naming conflict resolution algorithm // at run time since it is possible that the naming policy or other configs can be different then. - JsonTypeInfo.PropertyHierarchyResolutionState state = new(); + JsonTypeInfo.PropertyHierarchyResolutionState state = new(typeInfo.Options); foreach (JsonPropertyInfo jsonPropertyInfo in properties) { diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/JsonTypeInfo.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/JsonTypeInfo.cs index a1a184f6059d2b..668e0c7b15e1a1 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/JsonTypeInfo.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/JsonTypeInfo.cs @@ -992,10 +992,9 @@ public JsonPropertyInfo CreateJsonPropertyInfo(Type propertyType, string name) internal abstract ValueTask DeserializeAsObjectAsync(Stream utf8Json, CancellationToken cancellationToken); internal abstract object? DeserializeAsObject(Stream utf8Json); - internal ref struct PropertyHierarchyResolutionState + internal ref struct PropertyHierarchyResolutionState(JsonSerializerOptions options) { - public PropertyHierarchyResolutionState() { } - public Dictionary AddedProperties = new(); + public Dictionary AddedProperties = new(options.PropertyNameCaseInsensitive ? StringComparer.OrdinalIgnoreCase : StringComparer.Ordinal); public Dictionary? IgnoredProperties; public bool IsPropertyOrderSpecified; } diff --git a/src/libraries/System.Text.Json/tests/Common/PropertyNameTests.cs b/src/libraries/System.Text.Json/tests/Common/PropertyNameTests.cs index 4295359c6f0380..021481ae5a1362 100644 --- a/src/libraries/System.Text.Json/tests/Common/PropertyNameTests.cs +++ b/src/libraries/System.Text.Json/tests/Common/PropertyNameTests.cs @@ -494,5 +494,34 @@ public class ClassWithSpecialCharacters [JsonPropertyName("\uA000_2")] // Valid C# property name: \uA000_2 public int YiIt_2 { get; set; } } + + [Theory] + [InlineData(false)] + [InlineData(true)] + public async Task ClassWithIgnoredCaseInsensitiveConflict_RespectsIgnoredMember(bool propertyNameCaseInsensitive) + { + // Regression test for https://github.com/dotnet/runtime/issues/93903 + // specifically for propertyNameCaseInsensitive := true + + JsonSerializerOptions options = Serializer.CreateOptions(makeReadOnly: false); + options.PropertyNameCaseInsensitive = propertyNameCaseInsensitive; + + var value = new ClassWithIgnoredCaseInsensitiveConflict { name = "lowercase", Name = "uppercase" }; + string json = await Serializer.SerializeWrapper(value, options); + + Assert.Equal("""{"name":"lowercase"}""", json); + + value = await Serializer.DeserializeWrapper(json, options); + Assert.Equal("lowercase", value.name); + Assert.Null(value.Name); + } + + public class ClassWithIgnoredCaseInsensitiveConflict + { + public string name { get; set; } + + [JsonIgnore] + public string Name { get; set; } + } } } diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/Serialization/PropertyNameTests.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/Serialization/PropertyNameTests.cs index 82566bf7123ce7..e512451eed72bc 100644 --- a/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/Serialization/PropertyNameTests.cs +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/Serialization/PropertyNameTests.cs @@ -28,6 +28,7 @@ public PropertyNameTests_Metadata() [JsonSerializable(typeof(ObjectPropertyNamesDifferentByCaseOnly_TestClass))] [JsonSerializable(typeof(OverridePropertyNameDesignTime_TestClass))] [JsonSerializable(typeof(SimpleTestClass))] + [JsonSerializable(typeof(ClassWithIgnoredCaseInsensitiveConflict))] internal sealed partial class PropertyNameTestsContext_Metadata : JsonSerializerContext { } @@ -53,6 +54,7 @@ public PropertyNameTests_Default() [JsonSerializable(typeof(ObjectPropertyNamesDifferentByCaseOnly_TestClass))] [JsonSerializable(typeof(OverridePropertyNameDesignTime_TestClass))] [JsonSerializable(typeof(SimpleTestClass))] + [JsonSerializable(typeof(ClassWithIgnoredCaseInsensitiveConflict))] internal sealed partial class PropertyNameTestsContext_Default : JsonSerializerContext { } From 7331dcb60e0fd7c74a6f7216d61819c9f57a1ade Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20S=C3=A1nchez=20L=C3=B3pez?= <1175054+carlossanlop@users.noreply.github.com> Date: Wed, 25 Oct 2023 14:34:17 -0600 Subject: [PATCH 11/13] [8.0] Update MsQuic (#93979) --- eng/Versions.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eng/Versions.props b/eng/Versions.props index 4d15f289d8eba8..ed16dbfe0a219a 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -219,7 +219,7 @@ 8.0.0-rtm.23511.1 - 2.2.2 + 2.2.3 8.0.0-alpha.1.23468.1 16.0.5-alpha.1.23478.1 From 0f65b75d2512cd51e599604c271b86c43d7c2820 Mon Sep 17 00:00:00 2001 From: Larry Ewing Date: Fri, 27 Oct 2023 13:02:50 -0500 Subject: [PATCH 12/13] Try pinning the installer version to a 8.01xx sdk --- eng/Versions.props | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/eng/Versions.props b/eng/Versions.props index ed16dbfe0a219a..788b7c1ab4ea96 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -258,7 +258,7 @@ 3.1.7 1.0.406601 - 8.0.100-rtm.23506.1 - + 8.0.100-rtm.23527.6 + $(MicrosoftDotnetSdkInternalVersion) From b8263b8bced91ed994d6f1a4a51a09bf7ce715f1 Mon Sep 17 00:00:00 2001 From: Larry Ewing Date: Fri, 27 Oct 2023 18:47:40 -0500 Subject: [PATCH 13/13] Target net8.0 in SatelliteAssemblyFromProjectRef --- .../LibraryWithResources/LibraryWithResources.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mono/wasm/testassets/SatelliteAssemblyFromProjectRef/LibraryWithResources/LibraryWithResources.csproj b/src/mono/wasm/testassets/SatelliteAssemblyFromProjectRef/LibraryWithResources/LibraryWithResources.csproj index c6c44c64130006..ec2cce14320ca5 100644 --- a/src/mono/wasm/testassets/SatelliteAssemblyFromProjectRef/LibraryWithResources/LibraryWithResources.csproj +++ b/src/mono/wasm/testassets/SatelliteAssemblyFromProjectRef/LibraryWithResources/LibraryWithResources.csproj @@ -1,5 +1,5 @@ - net7.0 + net8.0