* Update libraries

* Fix library names on Unix

* CppCodeGen workaround

* Disabled outdated test
This commit is contained in:
Jan Kotas 2020-05-16 08:08:32 -07:00 коммит произвёл GitHub
Родитель 43e327cbc0
Коммит 06c964a218
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
286 изменённых файлов: 14291 добавлений и 4801 удалений

Просмотреть файл

@ -3,7 +3,7 @@
<RyuJITVersion Condition="'$(RyuJITVersion)' == ''">5.0.0-preview.5.20230.9</RyuJITVersion>
<ObjectWriterVersion Condition="'$(ObjectWriterVersion)' == ''">1.0.0-alpha-28820-01</ObjectWriterVersion>
<CoreDisToolsVersion Condition="'$(CoreDisToolsVersion)' == ''">1.0.1-prerelease-00005</CoreDisToolsVersion>
<RuntimeLibrariesVersion Condition="'$(RuntimeLibrariesVersion)' == ''">5.0.0-preview.2.20153.3</RuntimeLibrariesVersion>
<RuntimeLibrariesVersion Condition="'$(RuntimeLibrariesVersion)' == ''">5.0.0-preview.5.20263.12</RuntimeLibrariesVersion>
<CoreFxUapVersion Condition="'$(CoreFxUapVersion)' == ''">4.7.0-preview6.19265.2</CoreFxUapVersion>
<MicrosoftNETCoreAppPackageVersion Condition="'$(MicrosoftNETCoreAppPackageVersion)' == ''">2.1.14</MicrosoftNETCoreAppPackageVersion>
<MicrosoftDotNetTestSdkVersion Condition="'$(MicrosoftDotNetTestSdkVersion)' == ''">15.8.0</MicrosoftDotNetTestSdkVersion>

Просмотреть файл

@ -57,12 +57,12 @@ See the LICENSE file in the project root for more information.
<ItemGroup>
<NativeLibrary Include="$(IlcPath)/sdk/libSystem.Private.CoreLib.Native$(NativeLibraryExtension)" />
<NativeLibrary Condition="$(NativeCodeGen) == ''" Include="$(IlcPath)/sdk/libSystem.Private.TypeLoader.Native$(NativeLibraryExtension)" />
<NativeLibrary Include="$(IlcPath)/framework/System.Native$(NativeLibraryExtension)" />
<NativeLibrary Include="$(IlcPath)/framework/System.Globalization.Native$(NativeLibraryExtension)" />
<NativeLibrary Include="$(IlcPath)/framework/System.IO.Compression.Native$(NativeLibraryExtension)" />
<NativeLibrary Include="$(IlcPath)/framework/System.Net.Security.Native$(NativeLibraryExtension)" />
<NativeLibrary Include="$(IlcPath)/framework/System.Security.Cryptography.Native.Apple$(NativeLibraryExtension)" Condition="'$(TargetOS)' == 'OSX'"/>
<NativeLibrary Include="$(IlcPath)/framework/System.Security.Cryptography.Native.OpenSsl$(NativeLibraryExtension)" Condition="'$(TargetOS)' != 'OSX'"/>
<NativeLibrary Include="$(IlcPath)/framework/libSystem.Native$(NativeLibraryExtension)" />
<NativeLibrary Include="$(IlcPath)/framework/libSystem.Globalization.Native$(NativeLibraryExtension)" />
<NativeLibrary Include="$(IlcPath)/framework/libSystem.IO.Compression.Native$(NativeLibraryExtension)" />
<NativeLibrary Include="$(IlcPath)/framework/libSystem.Net.Security.Native$(NativeLibraryExtension)" />
<NativeLibrary Include="$(IlcPath)/framework/libSystem.Security.Cryptography.Native.Apple$(NativeLibraryExtension)" Condition="'$(TargetOS)' == 'OSX'"/>
<NativeLibrary Include="$(IlcPath)/framework/libSystem.Security.Cryptography.Native.OpenSsl$(NativeLibraryExtension)" Condition="'$(TargetOS)' != 'OSX'"/>
</ItemGroup>
<ItemGroup Condition="'$(TargetOS)' == 'OSX'">

Просмотреть файл

@ -5,7 +5,6 @@
using System;
using System.Globalization;
using System.Runtime.InteropServices;
using System.Text;
internal static partial class Interop
{

Просмотреть файл

@ -2,10 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Runtime.InteropServices;
using System.Security;
using System.Text;
internal static partial class Interop
{

Просмотреть файл

@ -5,7 +5,6 @@
using System;
using System.Globalization;
using System.Runtime.InteropServices;
using System.Security;
internal static partial class Interop
{
@ -24,7 +23,7 @@ internal static partial class Interop
internal static extern unsafe int IndexOf(IntPtr sortHandle, char* target, int cwTargetLength, char* pSource, int cwSourceLength, CompareOptions options, int* matchLengthPtr);
[DllImport(Libraries.GlobalizationNative, CharSet = CharSet.Unicode, EntryPoint = "GlobalizationNative_LastIndexOf")]
internal static extern unsafe int LastIndexOf(IntPtr sortHandle, char* target, int cwTargetLength, char* pSource, int cwSourceLength, CompareOptions options);
internal static extern unsafe int LastIndexOf(IntPtr sortHandle, char* target, int cwTargetLength, char* pSource, int cwSourceLength, CompareOptions options, int* matchLengthPtr);
[DllImport(Libraries.GlobalizationNative, CharSet = CharSet.Unicode, EntryPoint = "GlobalizationNative_IndexOfOrdinalIgnoreCase")]
internal static extern unsafe int IndexOfOrdinalIgnoreCase(string target, int cwTargetLength, char* pSource, int cwSourceLength, bool findLast);

Просмотреть файл

@ -2,9 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;
internal static partial class Interop
{

Просмотреть файл

@ -2,7 +2,6 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Runtime.InteropServices;
internal static partial class Interop

Просмотреть файл

@ -0,0 +1,11 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
internal static partial class Interop
{
internal static partial class Libraries
{
internal const string GlobalizationNative = "libSystem.Globalization.Native";
}
}

Просмотреть файл

@ -2,7 +2,6 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Runtime.InteropServices;
internal static partial class Interop

Просмотреть файл

@ -2,7 +2,6 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Runtime.InteropServices;
using System.Text;
@ -11,9 +10,9 @@ internal static partial class Interop
internal static partial class Globalization
{
[DllImport(Libraries.GlobalizationNative, CharSet = CharSet.Unicode, EntryPoint = "GlobalizationNative_IsNormalized")]
internal static extern int IsNormalized(NormalizationForm normalizationForm, string src, int srcLen);
internal static extern unsafe int IsNormalized(NormalizationForm normalizationForm, char* src, int srcLen);
[DllImport(Libraries.GlobalizationNative, CharSet = CharSet.Unicode, EntryPoint = "GlobalizationNative_NormalizeString")]
internal static extern int NormalizeString(NormalizationForm normalizationForm, string src, int srcLen, [Out] char[] dstBuffer, int dstBufferCapacity);
internal static extern unsafe int NormalizeString(NormalizationForm normalizationForm, char* src, int srcLen, char* dstBuffer, int dstBufferCapacity);
}
}

Просмотреть файл

@ -3,7 +3,6 @@
// See the LICENSE file in the project root for more information.
using System.Runtime.InteropServices;
using System.Text;
internal static partial class Interop
{

Просмотреть файл

@ -3,9 +3,7 @@
// See the LICENSE file in the project root for more information.
using System;
using System.Diagnostics;
using System.Buffers;
using System.Text;
internal static partial class Interop
{

Просмотреть файл

@ -115,7 +115,7 @@ internal static partial class Interop
// Represents a platform-agnostic Error and underlying platform-specific errno
internal struct ErrorInfo
{
private Error _error;
private readonly Error _error;
private int _rawErrno;
internal ErrorInfo(int errno)

Просмотреть файл

@ -7,12 +7,12 @@ internal static partial class Interop
internal static partial class Libraries
{
// Shims
internal const string SystemNative = "System.Native";
internal const string GlobalizationNative = "System.Globalization.Native";
internal const string NetSecurityNative = "System.Net.Security.Native";
internal const string CryptoNative = "System.Security.Cryptography.Native.OpenSsl";
internal const string CompressionNative = "System.IO.Compression.Native";
internal const string IOPortsNative = "System.IO.Ports.Native";
internal const string SystemNative = "libSystem.Native";
internal const string NetSecurityNative = "libSystem.Net.Security.Native";
internal const string CryptoNative = "libSystem.Security.Cryptography.Native.OpenSsl";
internal const string CompressionNative = "libSystem.IO.Compression.Native";
internal const string IOPortsNative = "libSystem.IO.Ports.Native";
internal const string Libdl = "libdl";
internal const string HostPolicy = "libhostpolicy";
}
}

Просмотреть файл

@ -2,7 +2,6 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Runtime.InteropServices;
internal static partial class Interop

Просмотреть файл

@ -2,7 +2,6 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Runtime.InteropServices;
internal static partial class Interop

Просмотреть файл

@ -51,8 +51,8 @@ internal static partial class Interop
[DllImport(Libraries.SystemNative, EntryPoint = "SystemNative_EnumerateInterfaceAddresses")]
public static extern int EnumerateInterfaceAddresses(
IPv4AddressDiscoveredCallback ipv4Found,
IPv6AddressDiscoveredCallback ipv6Found,
LinkLayerAddressDiscoveredCallback linkLayerFound);
IPv6AddressDiscoveredCallback? ipv6Found,
LinkLayerAddressDiscoveredCallback? linkLayerFound);
[DllImport(Libraries.SystemNative, EntryPoint = "SystemNative_EnumerateGatewayAddressesForInterface")]
public static extern int EnumerateGatewayAddressesForInterface(uint interfaceIndex, DnsAddessDiscoveredCallback onGatewayFound);

Просмотреть файл

@ -17,6 +17,9 @@ internal static partial class Interop
[DllImport(Libraries.SystemNative, EntryPoint = "SystemNative_FcntlSetIsNonBlocking", SetLastError=true)]
internal static extern int SetIsNonBlocking(SafeHandle fd, int isNonBlocking);
[DllImport(Libraries.SystemNative, EntryPoint = "SystemNative_FcntlGetIsNonBlocking", SetLastError = true)]
internal static extern int GetIsNonBlocking(SafeHandle fd, out bool isNonBlocking);
[DllImport(Libraries.SystemNative, EntryPoint = "SystemNative_FcntlSetFD", SetLastError=true)]
internal static extern int SetFD(SafeHandle fd, int flags);

Просмотреть файл

@ -2,8 +2,6 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
internal static partial class Interop

Просмотреть файл

@ -2,7 +2,6 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Runtime.InteropServices;
internal static partial class Interop

Просмотреть файл

@ -2,7 +2,6 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Runtime.InteropServices;
internal static partial class Interop

Просмотреть файл

@ -2,7 +2,6 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Runtime.InteropServices;
internal static partial class Interop

Просмотреть файл

@ -2,8 +2,6 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
internal static partial class Interop

Просмотреть файл

@ -15,5 +15,8 @@ internal static partial class Interop
[DllImport(Libraries.SystemNative, EntryPoint = "SystemNative_GetSockOpt")]
internal static extern unsafe Error GetSockOpt(IntPtr socket, SocketOptionLevel optionLevel, SocketOptionName optionName, byte* optionValue, int* optionLen);
[DllImport(Libraries.SystemNative, EntryPoint = "SystemNative_GetRawSockOpt")]
internal static extern unsafe Error GetRawSockOpt(SafeHandle socket, int optionLevel, int optionName, byte* optionValue, int* optionLen);
}
}

Просмотреть файл

@ -2,7 +2,6 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Runtime.InteropServices;
internal static partial class Interop

Просмотреть файл

@ -44,6 +44,7 @@ internal static partial class Interop
bdevfs = 0x62646576,
bfs = 0x1BADFACE,
binfmt_misc = 0x42494E4D,
bootfs = 0xA56D3FF9,
btrfs = 0x9123683E,
ceph = 0x00C36400,
cgroupfs = 0x0027E0EB,
@ -65,6 +66,7 @@ internal static partial class Interop
ext3 = 0xEF53,
ext4 = 0xEF53,
fat = 0x4006,
fd = 0xF00D1E,
fhgfs = 0x19830326,
fuse = 0x65735546,
fuseblk = 0x65735546,
@ -86,6 +88,7 @@ internal static partial class Interop
jffs2 = 0x72B6,
jfs = 0x3153464A,
kafs = 0x6B414653,
lofs = 0xEF53, /* loopback filesystem, magic same as ext2 */
logfs = 0xC97E8168,
lustre = 0x0BD00BD0,
minix_old = 0x137F, /* orig. minix */
@ -227,6 +230,7 @@ internal static partial class Interop
case "bdevfs":
case "befs":
case "bfs":
case "bootfs":
case "bpf_fs":
case "btrfs":
case "btrfs_test":
@ -261,6 +265,7 @@ internal static partial class Interop
case "jffs":
case "jffs2":
case "jfs":
case "lofs":
case "logfs":
case "lxfs":
case "minix (30 char.)":
@ -384,15 +389,18 @@ internal static partial class Interop
case "cgroupfs":
case "cgroup2fs":
case "configfs":
case "cpuset":
case "cramfs":
case "cramfs-wend":
case "cryptkeeper":
case "cpuset":
case "ctfs":
case "debugfs":
case "dev":
case "devfs":
case "devpts":
case "devtmpfs":
case "encfs":
case "fd":
case "fdesc":
case "fuse.gvfsd-fuse":
case "fusectl":
@ -400,9 +408,11 @@ internal static partial class Interop
case "hugetlbfs":
case "libpam-encfs":
case "ibpam-mount":
case "mntfs":
case "mqueue":
case "mtpfs":
case "mythtvfs":
case "mqueue":
case "objfs":
case "openprom":
case "openpromfs":
case "pipefs":
@ -417,6 +427,7 @@ internal static partial class Interop
case "securityfs":
case "selinux":
case "selinuxfs":
case "sharefs":
case "sockfs":
case "sysfs":
case "tmpfs":

Просмотреть файл

@ -3,7 +3,6 @@
// See the LICENSE file in the project root for more information.
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
internal static partial class Interop

Просмотреть файл

@ -2,7 +2,6 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Runtime.InteropServices;
internal static partial class Interop

Просмотреть файл

@ -3,7 +3,6 @@
// See the LICENSE file in the project root for more information.
using System.Runtime.InteropServices;
using Microsoft.Win32.SafeHandles;
internal static partial class Interop
{

Просмотреть файл

@ -15,5 +15,8 @@ internal static partial class Interop
[DllImport(Libraries.SystemNative, EntryPoint = "SystemNative_SetSockOpt")]
internal static extern unsafe Error SetSockOpt(IntPtr socket, SocketOptionLevel optionLevel, SocketOptionName optionName, byte* optionValue, int optionLen);
[DllImport(Libraries.SystemNative, EntryPoint = "SystemNative_SetRawSockOpt")]
internal static extern unsafe Error SetRawSockOpt(SafeHandle socket, int optionLevel, int optionName, byte* optionValue, int optionLen);
}
}

Просмотреть файл

@ -55,7 +55,7 @@ internal static partial class Interop
}
[DllImport(Libraries.SystemNative, EntryPoint = "SystemNative_FStat", SetLastError = true)]
internal static extern int FStat(SafeFileHandle fd, out FileStatus output);
internal static extern int FStat(SafeHandle fd, out FileStatus output);
[DllImport(Libraries.SystemNative, EntryPoint = "SystemNative_Stat", SetLastError = true)]
internal static extern int Stat(string path, out FileStatus output);

Просмотреть файл

@ -19,28 +19,6 @@ internal static partial class Interop
LOG_NOTICE = 5, /* normal but significant condition */
LOG_INFO = 6, /* informational */
LOG_DEBUG = 7, /* debug-level messages */
// Facilities
LOG_KERN = (0<<3), /* kernel messages */
LOG_USER = (1<<3), /* random user-level messages */
LOG_MAIL = (2<<3), /* mail system */
LOG_DAEMON = (3<<3), /* system daemons */
LOG_AUTH = (4<<3), /* authorization messages */
LOG_SYSLOG = (5<<3), /* messages generated internally by syslogd */
LOG_LPR = (6<<3), /* line printer subsystem */
LOG_NEWS = (7<<3), /* network news subsystem */
LOG_UUCP = (8<<3), /* UUCP subsystem */
LOG_CRON = (9<<3), /* clock daemon */
LOG_AUTHPRIV = (10<<3), /* authorization messages (private) */
LOG_FTP = (11<<3), /* ftp daemon */
// Between FTP and Local is reserved for system use
LOG_LOCAL0 = (16<<3), /* reserved for local use */
LOG_LOCAL1 = (17<<3), /* reserved for local use */
LOG_LOCAL2 = (18<<3), /* reserved for local use */
LOG_LOCAL3 = (19<<3), /* reserved for local use */
LOG_LOCAL4 = (20<<3), /* reserved for local use */
LOG_LOCAL5 = (21<<3), /* reserved for local use */
LOG_LOCAL6 = (22<<3), /* reserved for local use */
LOG_LOCAL7 = (23<<3), /* reserved for local use */
}
/// <summary>

Просмотреть файл

@ -2,8 +2,8 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Runtime.InteropServices;
using Microsoft.Win32.SafeHandles;
internal static partial class Interop
{
@ -22,6 +22,6 @@ internal static partial class Interop
internal static extern unsafe int Write(SafeHandle fd, byte* buffer, int bufferSize);
[DllImport(Libraries.SystemNative, EntryPoint = "SystemNative_Write", SetLastError = true)]
internal static extern unsafe int Write(int fd, byte* buffer, int bufferSize);
internal static extern unsafe int Write(IntPtr fd, byte* buffer, int bufferSize);
}
}

Просмотреть файл

@ -10,9 +10,9 @@ internal partial class Interop
internal partial class Advapi32
{
[DllImport(Libraries.Advapi32, CharSet = CharSet.Unicode, SetLastError = true)]
internal static extern bool CryptImportKey(
internal static extern unsafe bool CryptImportKey(
SafeProvHandle hProv,
byte[] pbData,
byte* pbData,
int dwDataLen,
SafeKeyHandle hPubKey,
int dwFlags,

Просмотреть файл

@ -39,5 +39,6 @@ internal static partial class Interop
internal const string CompressionNative = "clrcompression.dll";
internal const string CoreWinRT = "api-ms-win-core-winrt-l1-1-0.dll";
internal const string MsQuic = "msquic.dll";
internal const string HostPolicy = "hostpolicy.dll";
}
}

Просмотреть файл

@ -11,6 +11,6 @@ internal partial class Interop
internal partial class Kernel32
{
[DllImport(Libraries.Kernel32, CharSet = CharSet.Unicode, SetLastError = true, EntryPoint = "K32EnumProcessModules")]
internal static extern bool EnumProcessModules(SafeProcessHandle handle, IntPtr modules, int size, ref int needed);
internal static extern bool EnumProcessModules(SafeProcessHandle handle, IntPtr[]? modules, int size, out int needed);
}
}

Просмотреть файл

@ -9,6 +9,15 @@ internal static partial class Interop
{
internal static unsafe partial class Kernel32
{
// Under debug mode only, we'll want to check the error codes
// of some of the p/invokes we make.
#if DEBUG
private const bool SetLastErrorForDebug = true;
#else
private const bool SetLastErrorForDebug = false;
#endif
internal const uint LOCALE_ALLOW_NEUTRAL_NAMES = 0x08000000; // Flag to allow returning neutral names/lcids for name conversion
internal const uint LOCALE_ILANGUAGE = 0x00000001;
internal const uint LOCALE_SUPPLEMENTAL = 0x00000002;
@ -31,6 +40,10 @@ internal static partial class Interop
internal const uint TIME_NOSECONDS = 0x00000002;
internal const int GEOCLASS_NATION = 16;
internal const int GEO_ISO2 = 4;
internal const int GEOID_NOT_AVAILABLE = -1;
internal const string LOCALE_NAME_USER_DEFAULT = null;
internal const string LOCALE_NAME_SYSTEM_DEFAULT = "!x-sys-default-locale";
@ -40,7 +53,7 @@ internal static partial class Interop
[DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
internal static extern int LocaleNameToLCID(string lpName, uint dwFlags);
[DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
internal static extern int LCMapStringEx(
string? lpLocaleName,
uint dwMapFlags,
@ -52,7 +65,7 @@ internal static partial class Interop
void* lpReserved,
IntPtr sortHandle);
[DllImport("kernel32.dll", EntryPoint = "FindNLSStringEx")]
[DllImport("kernel32.dll", EntryPoint = "FindNLSStringEx", SetLastError = SetLastErrorForDebug)]
internal static extern int FindNLSStringEx(
char* lpLocaleName,
uint dwFindNLSStringFlags,
@ -85,14 +98,14 @@ internal static partial class Interop
int cchCount2,
bool bIgnoreCase);
[DllImport("kernel32.dll", EntryPoint = "FindStringOrdinal")]
[DllImport("kernel32.dll", EntryPoint = "FindStringOrdinal", SetLastError = SetLastErrorForDebug)]
internal static extern int FindStringOrdinal(
uint dwFindStringOrdinalFlags,
char* lpStringSource,
int cchSource,
char* lpStringValue,
int cchValue,
int bIgnoreCase);
BOOL bIgnoreCase);
[DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
internal static extern bool IsNLSDefinedString(
@ -124,6 +137,12 @@ internal static partial class Interop
[DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
internal static extern int GetCalendarInfoEx(string? lpLocaleName, uint Calendar, IntPtr lpReserved, uint CalType, IntPtr lpCalData, int cchData, IntPtr lpValue);
[DllImport("kernel32.dll")]
internal static extern int GetUserGeoID(int geoClass);
[DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
internal static extern int GetGeoInfo(int location, int geoType, char* lpGeoData, int cchData, int LangId);
[DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
internal static extern bool EnumCalendarInfoExEx(EnumCalendarInfoProcExEx pCalInfoEnumProcExEx, string lpLocaleName, uint Calendar, string? lpReserved, uint CalType, void* lParam);

Просмотреть файл

@ -10,6 +10,6 @@ internal partial class Interop
internal partial class Kernel32
{
[DllImport(Libraries.Kernel32, SetLastError = true)]
internal static extern bool IsWow64Process(SafeProcessHandle hProcess, ref bool Wow64Process);
internal static extern bool IsWow64Process(SafeProcessHandle hProcess, out bool Wow64Process);
}
}

Просмотреть файл

@ -3,21 +3,21 @@
// See the LICENSE file in the project root for more information.
using System.Runtime.InteropServices;
using System.Text;
internal static partial class Interop
{
internal static partial class Normaliz
{
[DllImport("Normaliz.dll", CharSet = CharSet.Unicode, SetLastError = true)]
internal static extern bool IsNormalizedString(int normForm, string source, int length);
internal static extern unsafe BOOL IsNormalizedString(NormalizationForm normForm, char* source, int length);
[DllImport("Normaliz.dll", CharSet = CharSet.Unicode, SetLastError = true)]
internal static extern int NormalizeString(
int normForm,
string source,
internal static extern unsafe int NormalizeString(
NormalizationForm normForm,
char* source,
int sourceLength,
[System.Runtime.InteropServices.OutAttribute]
char[]? destination,
char* destination,
int destinationLength);
}
}

Просмотреть файл

@ -1,4 +1,4 @@
// Licensed to the .NET Foundation under one or more agreements.
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
@ -7,15 +7,16 @@ internal static partial class Interop
internal class StatusOptions
{
// Error codes from ntstatus.h
internal const uint STATUS_SUCCESS = 0x00000000;
internal const uint STATUS_SOME_NOT_MAPPED = 0x00000107;
internal const uint STATUS_NO_MORE_FILES = 0x80000006;
internal const uint STATUS_INVALID_PARAMETER = 0xC000000D;
internal const uint STATUS_NO_MEMORY = 0xC0000017;
internal const uint STATUS_OBJECT_NAME_NOT_FOUND = 0xC0000034;
internal const uint STATUS_NONE_MAPPED = 0xC0000073;
internal const uint STATUS_SUCCESS = 0x00000000;
internal const uint STATUS_SOME_NOT_MAPPED = 0x00000107;
internal const uint STATUS_NO_MORE_FILES = 0x80000006;
internal const uint STATUS_INVALID_PARAMETER = 0xC000000D;
internal const uint STATUS_FILE_NOT_FOUND = 0xC000000F;
internal const uint STATUS_NO_MEMORY = 0xC0000017;
internal const uint STATUS_ACCESS_DENIED = 0xC0000022;
internal const uint STATUS_OBJECT_NAME_NOT_FOUND = 0xC0000034;
internal const uint STATUS_ACCOUNT_RESTRICTION = 0xC000006E;
internal const uint STATUS_NONE_MAPPED = 0xC0000073;
internal const uint STATUS_INSUFFICIENT_RESOURCES = 0xC000009A;
internal const uint STATUS_ACCESS_DENIED = 0xC0000022;
internal const uint STATUS_ACCOUNT_RESTRICTION = 0xc000006e;
}
}

Просмотреть файл

@ -18,19 +18,15 @@ internal partial class Interop
return RtlGetVersion(ref osvi);
}
internal static unsafe string RtlGetVersion()
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
internal unsafe struct RTL_OSVERSIONINFOEX
{
const string Version = "Microsoft Windows";
if (RtlGetVersionEx(out RTL_OSVERSIONINFOEX osvi) == 0)
{
return osvi.szCSDVersion[0] != '\0' ?
string.Format("{0} {1}.{2}.{3} {4}", Version, osvi.dwMajorVersion, osvi.dwMinorVersion, osvi.dwBuildNumber, new string(&(osvi.szCSDVersion[0]))) :
string.Format("{0} {1}.{2}.{3}", Version, osvi.dwMajorVersion, osvi.dwMinorVersion, osvi.dwBuildNumber);
}
else
{
return Version;
}
internal uint dwOSVersionInfoSize;
internal uint dwMajorVersion;
internal uint dwMinorVersion;
internal uint dwBuildNumber;
internal uint dwPlatformId;
internal fixed char szCSDVersion[128];
}
}
}

Просмотреть файл

@ -220,7 +220,7 @@ namespace System.Diagnostics
StringBuilder installBuilder = new StringBuilder();
installBuilder.Append(installRoot);
if (!installRoot.EndsWith("\\", StringComparison.Ordinal))
installBuilder.Append("\\");
installBuilder.Append('\\');
installBuilder.Append(version);
dllDir = installBuilder.ToString();
}

Просмотреть файл

@ -2,11 +2,12 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#nullable enable
namespace System.Diagnostics
{
internal static partial class TraceListenerHelpers
{
private static volatile string s_processName;
private static volatile string? s_processName;
internal static int GetThreadId()
{

Просмотреть файл

@ -2,6 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#nullable enable
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;
@ -11,8 +12,8 @@ namespace System.IO
/// <summary>Provides an in-memory stream composed of non-contiguous chunks.</summary>
internal sealed class ChunkedMemoryStream : Stream
{
private MemoryChunk _headChunk;
private MemoryChunk _currentChunk;
private MemoryChunk? _headChunk;
private MemoryChunk? _currentChunk;
private const int InitialChunkDefaultSize = 1024;
private const int MaxChunkSize = 1024 * InitialChunkDefaultSize;
@ -24,7 +25,7 @@ namespace System.IO
{
byte[] result = new byte[_totalLength];
int offset = 0;
for (MemoryChunk chunk = _headChunk; chunk != null; chunk = chunk._next)
for (MemoryChunk? chunk = _headChunk; chunk != null; chunk = chunk._next)
{
Debug.Assert(chunk._next == null || chunk._freeOffset == chunk._buffer.Length);
Buffer.BlockCopy(chunk._buffer, 0, result, offset, chunk._freeOffset);
@ -109,7 +110,7 @@ namespace System.IO
{
internal readonly byte[] _buffer;
internal int _freeOffset;
internal MemoryChunk _next;
internal MemoryChunk? _next;
internal MemoryChunk(int bufferSize) { _buffer = new byte[bufferSize]; }
}

Просмотреть файл

@ -2,6 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#nullable enable
using System.Diagnostics;
using System.IO;
using System.Threading;
@ -113,7 +114,7 @@ namespace System.Net.Http
return _innerStream.ReadAsync(buffer, cancellationToken);
}
public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback callback, object state)
public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback? callback, object? state)
{
return _innerStream.BeginRead(buffer, offset, count, callback, state);
}
@ -167,7 +168,7 @@ namespace System.Net.Http
return _innerStream.WriteAsync(buffer, cancellationToken);
}
public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback callback, object state)
public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback? callback, object? state)
{
return _innerStream.BeginWrite(buffer, offset, count, callback, state);
}

Просмотреть файл

@ -81,7 +81,7 @@ namespace System.IO
)
{
// Assert so we can track down other cases (if any) to add to our test suite
Debug.Assert(errorCode == Interop.Errors.ERROR_ACCESS_DENIED || errorCode == Interop.Errors.ERROR_SHARING_VIOLATION,
Debug.Assert(errorCode == Interop.Errors.ERROR_ACCESS_DENIED || errorCode == Interop.Errors.ERROR_SHARING_VIOLATION || errorCode == Interop.Errors.ERROR_SEM_TIMEOUT,
$"Unexpected error code getting attributes {errorCode} from path {path}");
// Files that are marked for deletion will not let you GetFileAttributes,

Просмотреть файл

@ -105,7 +105,7 @@ namespace System.IO
new ValueTask<int>(Task.FromCanceled<int>(cancellationToken)) :
new ValueTask<int>(Read(buffer.Span));
public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback callback, object state) =>
public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback? callback, object? state) =>
TaskToApm.Begin(ReadAsync(buffer, offset, count), callback, state);
public override int EndRead(IAsyncResult asyncResult) =>

Просмотреть файл

@ -2,7 +2,9 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#nullable enable
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
namespace System.IO
@ -47,8 +49,7 @@ namespace System.IO
/// </summary>
public string GetNextValue(string key)
{
string value;
if (!TryGetNextValue(key, out value))
if (!TryGetNextValue(key, out string? value))
{
throw new InvalidOperationException("Couldn't get next value with key " + key);
}
@ -62,7 +63,7 @@ namespace System.IO
/// Tries to get the next occurrence of the given key from the current position of the reader.
/// If successful, returns true and stores the result in 'value'. Otherwise, returns false.
/// </summary>
public bool TryGetNextValue(string key, out string value)
public bool TryGetNextValue(string key, [NotNullWhen(true)] out string? value)
{
Debug.Assert(_buffer != null);
if (_currentIndex >= _buffer.Length)

Просмотреть файл

@ -2,6 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#nullable enable
using System.Diagnostics;
using System.Reflection;
@ -16,12 +17,12 @@ namespace System.Runtime.ExceptionServices
Debug.Assert(exception != null, "Expected non-null Exception");
const string ExceptionRemoteStackTraceStringName = "_remoteStackTraceString";
FieldInfo fi = typeof(Exception).GetField(ExceptionRemoteStackTraceStringName, BindingFlags.NonPublic | BindingFlags.Instance);
FieldInfo? fi = typeof(Exception).GetField(ExceptionRemoteStackTraceStringName, BindingFlags.NonPublic | BindingFlags.Instance);
if (fi != null)
{
string text =
(string)fi.GetValue(exception) +
(string?)fi.GetValue(exception) +
Environment.StackTrace + Environment.NewLine +
"--- End of stack trace from AddCurrentStack ---" + Environment.NewLine;
fi.SetValue(exception, text);

Просмотреть файл

@ -9,7 +9,7 @@ namespace System
/// <summary>Provides an object wrapper that can transition between strong and weak references to the object.</summary>
internal sealed class StrongToWeakReference<T> : WeakReference where T : class
{
private T _strongRef;
private T? _strongRef;
/// <summary>Initializes the instance with a strong reference to the specified object.</summary>
/// <param name="obj">The object to wrap.</param>
@ -30,9 +30,9 @@ namespace System
}
/// <summary>Gets the wrapped object.</summary>
public new T Target => _strongRef ?? WeakTarget;
public new T? Target => _strongRef ?? WeakTarget;
/// <summary>Gets the wrapped object via its weak reference.</summary>
private T WeakTarget => base.Target as T;
private T? WeakTarget => base.Target as T;
}
}

Просмотреть файл

@ -11,7 +11,7 @@ namespace System.Text
// The value 360 was chosen in discussion with performance experts as a compromise between using
// as litle memory per thread as possible and still covering a large part of short-lived
// StringBuilder creations on the startup path of VS designers.
private const int MaxBuilderSize = 360;
internal const int MaxBuilderSize = 360;
private const int DefaultCapacity = 16; // == StringBuilder.DefaultCapacity
// WARNING: We allow diagnostic tools to directly inspect this member (t_cachedInstance).

Просмотреть файл

@ -2,7 +2,9 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#nullable enable
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.CompilerServices;
using System.Runtime.ExceptionServices;
@ -19,11 +21,11 @@ namespace System.Threading.Tasks
/// The continuation to invoke when the operation completes, or <see cref="s_completionSentinel"/> if the operation
/// has completed before OnCompleted is called.
/// </summary>
private Action _continuation;
private Action? _continuation;
/// <summary>The exception representing the failed async operation, if it failed.</summary>
private ExceptionDispatchInfo _error;
private ExceptionDispatchInfo? _error;
/// <summary>The result of the async operation, if it succeeded.</summary>
private TResult _result;
[AllowNull] private TResult _result = default;
#if DEBUG
private bool _resultSet;
#endif
@ -39,7 +41,7 @@ namespace System.Threading.Tasks
{
get
{
Action c = Volatile.Read(ref _continuation);
Action? c = Volatile.Read(ref _continuation);
Debug.Assert(c == null || c == s_completionSentinel);
return c != null;
}
@ -55,7 +57,7 @@ namespace System.Threading.Tasks
// Propagate any error if there is one, clearing it out first to prepare for reuse.
// We don't need to clear a result, as result and error are mutually exclusive.
ExceptionDispatchInfo error = _error;
ExceptionDispatchInfo? error = _error;
if (error != null)
{
_error = null;
@ -101,7 +103,7 @@ namespace System.Threading.Tasks
/// <summary>Alerts any awaiter that the operation has completed.</summary>
private void NotifyAwaiter()
{
Action c = _continuation ?? Interlocked.CompareExchange(ref _continuation, s_completionSentinel, null);
Action? c = _continuation ?? Interlocked.CompareExchange(ref _continuation, s_completionSentinel, null);
if (c != null)
{
Debug.Assert(c != s_completionSentinel);
@ -122,7 +124,7 @@ namespace System.Threading.Tasks
{
Debug.Assert(continuation != null);
Action c = _continuation ?? Interlocked.CompareExchange(ref _continuation, continuation, null);
Action? c = _continuation ?? Interlocked.CompareExchange(ref _continuation, continuation, null);
if (c != null)
{
Debug.Assert(c == s_completionSentinel);

Просмотреть файл

@ -71,6 +71,8 @@
<_filteredNuGetDeployByFileName Include="@(_nuGetDeployByFileName)" Condition="'%(Identity)' == 'netstandard'" />
<_filteredNuGetDeployByFileName Include="@(_nuGetDeployByFileName)" Condition="'%(Identity)' == 'mscorlib'" />
<_filteredNuGetDeployByFileName Include="@(_nuGetDeployByFileName)" Condition="$([System.String]::new('%(Identity)').StartsWith('libSystem'))" />
<!-- TODO: https://github.com/dotnet/corert/issues/5496 -->
<_filteredNuGetDeployByFileName Include="@(_nuGetDeployByFileName)" Condition="'%(Identity)' == 'clrcompression'" />

Просмотреть файл

@ -589,6 +589,16 @@ namespace ILCompiler.CppCodeGen
sb.AppendLine();
AppendCppMethodDeclaration(sb, method, true);
sb.AppendLine();
// TODO: workaround unreachable globalization methods
string moduleName = method.GetPInvokeMethodMetadata().Module;
if (moduleName == (_compilation.TypeSystemContext.Target.IsWindows ? "libSystem.Globalization.Native" : "kernel32.dll"))
{
sb.Append("{ throw 0; }");
methodCodeNodeNeedingCode.SetCode(sb.ToString(), Array.Empty<Object>());
return;
}
sb.Append("{");
sb.Indent();

Просмотреть файл

@ -71,7 +71,7 @@ namespace ILCompiler
else
{
// Account for System.Private.CoreLib.Native / System.Globalization.Native / System.Native / etc
return importModule.StartsWith("System.");
return importModule.StartsWith("libSystem.");
}
}
}

Просмотреть файл

@ -12,7 +12,7 @@ namespace Internal.Resources
{
public abstract bool Initialize(string libpath, string reswFilename, out PRIExceptionInfo? exceptionInfo);
public abstract string GetString(string stringName, string? startingCulture, string? neutralResourcesCulture);
public abstract string? GetString(string stringName, string? startingCulture, string? neutralResourcesCulture);
public abstract CultureInfo? GlobalResourceContextBestFitCultureInfo
{

Просмотреть файл

@ -5,7 +5,6 @@
using System;
using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;
namespace Microsoft.Win32.SafeHandles
{

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -149,6 +149,7 @@
<Compile Include="$(MSBuildThisFileDirectory)System\Collections\Generic\IReadOnlyDictionary.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Collections\Generic\IReadOnlyList.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Collections\Generic\ISet.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Collections\Generic\IReadOnlySet.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Collections\Generic\KeyNotFoundException.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Collections\Generic\KeyValuePair.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Collections\Generic\List.cs" />
@ -239,16 +240,24 @@
<Compile Include="$(MSBuildThisFileDirectory)System\Globalization\Calendar.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Globalization\CalendarAlgorithmType.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Globalization\CalendarData.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Globalization\CalendarData.Icu.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Globalization\CalendarData.Nls.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Globalization\CalendarWeekRule.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Globalization\CalendricalCalculationsHelper.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Globalization\CharUnicodeInfo.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Globalization\CharUnicodeInfoData.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Globalization\ChineseLunisolarCalendar.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Globalization\CompareInfo.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Globalization\CompareInfo.Icu.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Globalization\CompareInfo.Invariant.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Globalization\CompareInfo.Nls.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Globalization\CompareOptions.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Globalization\CultureData.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Globalization\CultureData.Icu.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Globalization\CultureData.Nls.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Globalization\CultureInfo.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Globalization\CultureInfo.Icu.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Globalization\CultureInfo.Nls.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Globalization\CultureNotFoundException.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Globalization\CultureTypes.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Globalization\DateTimeFormat.cs" />
@ -266,14 +275,22 @@
<Compile Include="$(MSBuildThisFileDirectory)System\Globalization\HebrewCalendar.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Globalization\HebrewNumber.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Globalization\HijriCalendar.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Globalization\IcuLocaleData.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Globalization\IdnMapping.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Globalization\IdnMapping.Icu.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Globalization\IdnMapping.Nls.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Globalization\InternalGlobalizationHelper.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Globalization\ISOWeek.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Globalization\JapaneseCalendar.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Globalization\JapaneseCalendar.Icu.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Globalization\JapaneseCalendar.Nls.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Globalization\JapaneseLunisolarCalendar.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Globalization\JulianCalendar.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Globalization\KoreanCalendar.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Globalization\KoreanLunisolarCalendar.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Globalization\Normalization.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Globalization\Normalization.Icu.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Globalization\Normalization.Nls.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Globalization\NumberFormatInfo.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Globalization\NumberStyles.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Globalization\PersianCalendar.cs" />
@ -286,6 +303,8 @@
<Compile Include="$(MSBuildThisFileDirectory)System\Globalization\TaiwanLunisolarCalendar.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Globalization\TextElementEnumerator.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Globalization\TextInfo.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Globalization\TextInfo.Icu.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Globalization\TextInfo.Nls.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Globalization\ThaiBuddhistCalendar.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Globalization\TimeSpanFormat.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Globalization\TimeSpanParse.cs" />
@ -477,6 +496,7 @@
<Compile Include="$(MSBuildThisFileDirectory)System\Reflection\Emit\SignatureToken.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Reflection\Emit\StackBehaviour.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Reflection\Emit\StringToken.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Reflection\Emit\TypeNameBuilder.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Reflection\Emit\TypeToken.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Reflection\EventAttributes.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Reflection\EventInfo.cs" />
@ -735,7 +755,6 @@
<Compile Include="$(MSBuildThisFileDirectory)System\Runtime\Intrinsics\Vector64_1.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Runtime\Intrinsics\Vector64DebugView_1.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Runtime\Intrinsics\X86\Enums.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Runtime\Loader\AssemblyDependencyResolver.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Runtime\Loader\AssemblyLoadContext.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Runtime\Loader\LibraryNameVariation.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Runtime\MemoryFailPoint.cs" />
@ -859,7 +878,7 @@
<Compile Include="$(MSBuildThisFileDirectory)System\Text\Unicode\Utf8Utility.Helpers.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Text\Unicode\Utf8Utility.Transcoding.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Text\Unicode\Utf8Utility.Validation.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Text\Unicode\Utf8Utility.WhiteSpace.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Text\Unicode\Utf8Utility.WhiteSpace.CoreLib.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Text\UnicodeDebug.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Text\UnicodeEncoding.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Text\UnicodeUtility.cs" />
@ -967,12 +986,64 @@
<Compile Include="$(MSBuildThisFileDirectory)System\UnauthorizedAccessException.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\UnhandledExceptionEventArgs.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\UnhandledExceptionEventHandler.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\UnitySerializationHolder.cs"/>
<Compile Include="$(MSBuildThisFileDirectory)System\UnitySerializationHolder.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\ValueTuple.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Version.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Void.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\WeakReference.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\WeakReference.T.cs" />
<Compile Include="$(CommonPath)Interop\Interop.Libraries.cs">
<Link>Common\Interop\Interop.Libraries.cs</Link>
</Compile>
<Compile Include="$(CommonPath)Interop\Interop.Calendar.cs">
<Link>Common\Interop\Interop.Calendar.cs</Link>
</Compile>
<Compile Include="$(CommonPath)Interop\Interop.Casing.cs">
<Link>Common\Interop\Interop.Casing.cs</Link>
</Compile>
<Compile Include="$(CommonPath)Interop\Interop.Collation.cs">
<Link>Common\Interop\Interop.Collation.cs</Link>
</Compile>
<Compile Include="$(CommonPath)Interop\Interop.ICU.cs">
<Link>Common\Interop\Interop.ICU.cs</Link>
</Compile>
<Compile Include="$(CommonPath)Interop\Interop.Idna.cs">
<Link>Common\Interop\Interop.Idna.cs</Link>
</Compile>
<Compile Include="$(CommonPath)Interop\Interop.Locale.cs">
<Link>Common\Interop\Interop.Locale.cs</Link>
</Compile>
<Compile Include="$(CommonPath)Interop\Interop.Normalization.cs">
<Link>Common\Interop\Interop.Normalization.cs</Link>
</Compile>
<Compile Include="$(CommonPath)Interop\Interop.ResultCode.cs">
<Link>Common\Interop\Interop.ResultCode.cs</Link>
</Compile>
<Compile Include="$(CommonPath)Interop\Interop.TimeZoneInfo.cs">
<Link>Common\Interop\Interop.TimeZoneInfo.cs</Link>
</Compile>
<Compile Include="$(CommonPath)Interop\Interop.Utils.cs">
<Link>Common\Interop\Interop.Utils.cs</Link>
</Compile>
<Compile Include="$(CommonPath)Interop\Windows\Interop.Errors.cs">
<Link>Common\Interop\Interop.Errors.cs</Link>
</Compile>
<!-- The CLR internally uses a BOOL type analogous to the Windows BOOL type on Unix -->
<Compile Include="$(CommonPath)Interop\Windows\Interop.BOOL.cs">
<Link>Common\Interop\Windows\Interop.BOOL.cs</Link>
</Compile>
<Compile Include="$(CommonPath)Interop\Windows\Kernel32\Interop.Globalization.cs">
<Link>Common\Interop\Windows\Kernel32\Interop.Globalization.cs</Link>
</Compile>
<Compile Include="$(CommonPath)Interop\Windows\Kernel32\Interop.ResolveLocaleName.cs">
<Link>Common\Interop\Windows\Kernel32\Interop.ResolveLocaleName.cs</Link>
</Compile>
<Compile Include="$(CommonPath)Interop\Windows\Normaliz\Interop.Idna.cs">
<Link>Common\Interop\Windows\Normaliz\Interop.Idna.cs</Link>
</Compile>
<Compile Include="$(CommonPath)Interop\Windows\Normaliz\Interop.Normalization.cs">
<Link>Common\Interop\Windows\Normaliz\Interop.Normalization.cs</Link>
</Compile>
<Compile Include="$(CommonPath)System\HResults.cs">
<Link>Common\System\HResults.cs</Link>
</Compile>
@ -1018,6 +1089,11 @@
<Compile Include="$(MSBuildThisFileDirectory)System\Diagnostics\Tracing\EventActivityOptions.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Diagnostics\Tracing\EventCounter.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Diagnostics\Tracing\EventDescriptor.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Diagnostics\Tracing\EventPipe.cs" Condition="'$(FeaturePerfTracing)' == 'true'" />
<Compile Include="$(MSBuildThisFileDirectory)System\Diagnostics\Tracing\EventPipeEventDispatcher.cs" Condition="'$(FeaturePerfTracing)' == 'true'" />
<Compile Include="$(MSBuildThisFileDirectory)System\Diagnostics\Tracing\EventPipeEventProvider.cs" Condition="'$(FeaturePerfTracing)' == 'true'" />
<Compile Include="$(MSBuildThisFileDirectory)System\Diagnostics\Tracing\EventPipeMetadataGenerator.cs" Condition="'$(FeaturePerfTracing)' == 'true'" />
<Compile Include="$(MSBuildThisFileDirectory)System\Diagnostics\Tracing\EventPipePayloadDecoder.cs" Condition="'$(FeaturePerfTracing)' == 'true'" />
<Compile Include="$(MSBuildThisFileDirectory)System\Diagnostics\Tracing\EventProvider.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Diagnostics\Tracing\EventSource.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Diagnostics\Tracing\EventSourceException.cs" />
@ -1025,7 +1101,9 @@
<Compile Include="$(MSBuildThisFileDirectory)System\Diagnostics\Tracing\IEventProvider.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Diagnostics\Tracing\IncrementingEventCounter.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Diagnostics\Tracing\IncrementingPollingCounter.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Diagnostics\Tracing\NativeRuntimeEventSource.cs" Condition="'$(FeaturePerfTracing)' == 'true'" />
<Compile Include="$(MSBuildThisFileDirectory)System\Diagnostics\Tracing\PollingCounter.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Diagnostics\Tracing\RuntimeEventSource.cs" Condition="'$(FeaturePerfTracing)' == 'true'" />
<Compile Include="$(MSBuildThisFileDirectory)System\Diagnostics\Tracing\StubEnvironment.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Diagnostics\Tracing\Winmeta.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Diagnostics\Tracing\TraceLogging\ArrayTypeInfo.cs" />
@ -1052,12 +1130,14 @@
<Compile Include="$(MSBuildThisFileDirectory)System\Diagnostics\Tracing\TraceLogging\Statics.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Diagnostics\Tracing\TraceLogging\TraceLoggingDataCollector.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Diagnostics\Tracing\TraceLogging\TraceLoggingDataType.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Diagnostics\Tracing\TraceLogging\TraceLoggingEventHandleTable.cs" Condition="'$(FeaturePerfTracing)' == 'true'" />
<Compile Include="$(MSBuildThisFileDirectory)System\Diagnostics\Tracing\TraceLogging\TraceLoggingEventSource.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Diagnostics\Tracing\TraceLogging\TraceLoggingEventTraits.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Diagnostics\Tracing\TraceLogging\TraceLoggingEventTypes.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Diagnostics\Tracing\TraceLogging\TraceLoggingMetadataCollector.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Diagnostics\Tracing\TraceLogging\TraceLoggingTypeInfo.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Diagnostics\Tracing\TraceLogging\TypeAnalysis.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Diagnostics\Tracing\TraceLogging\XplatEventLogger.cs" Condition="'$(FeatureXplatEventSource)' == 'true'" />
</ItemGroup>
<ItemGroup>
<Compile Include="$(MSBuildThisFileDirectory)\..\..\Common\src\System\HexConverter.cs">
@ -1165,9 +1245,6 @@
<Compile Include="$(CommonPath)Interop\Windows\Crypt32\Interop.CryptProtectMemory.cs">
<Link>Common\Interop\Windows\Crypt32\Interop.CryptProtectMemory.cs</Link>
</Compile>
<Compile Include="$(CommonPath)Interop\Windows\Interop.BOOL.cs">
<Link>Common\Interop\Windows\Interop.BOOL.cs</Link>
</Compile>
<Compile Include="$(CommonPath)Interop\Windows\Interop.BOOLEAN.cs">
<Link>Common\Interop\Windows\Interop.BOOLEAN.cs</Link>
</Compile>
@ -1282,12 +1359,6 @@
<Compile Include="$(CommonPath)Interop\Windows\Kernel32\Interop.GetTempPathW.cs">
<Link>Common\Interop\Windows\Kernel32\Interop.GetTempPathW.cs</Link>
</Compile>
<Compile Include="$(CommonPath)Interop\Windows\Kernel32\Interop.GetVersionExW.cs">
<Link>Common\Interop\Windows\Kernel32\Interop.GetVersionExW.cs</Link>
</Compile>
<Compile Include="$(CommonPath)Interop\Windows\Kernel32\Interop.Globalization.cs">
<Link>Common\Interop\Windows\Kernel32\Interop.Globalization.cs</Link>
</Compile>
<Compile Include="$(CommonPath)Interop\Windows\Kernel32\Interop.GlobalMemoryStatusEx.cs">
<Link>Common\Interop\Windows\Kernel32\Interop.GlobalMemoryStatusEx.cs</Link>
</Compile>
@ -1336,9 +1407,6 @@
<Compile Include="$(CommonPath)Interop\Windows\Kernel32\Interop.ReadFile_SafeHandle_NativeOverlapped.cs">
<Link>Common\Interop\Windows\Kernel32\Interop.ReadFile_SafeHandle_NativeOverlapped.cs</Link>
</Compile>
<Compile Include="$(CommonPath)Interop\Windows\Kernel32\Interop.ResolveLocaleName.cs">
<Link>Common\Interop\Windows\Kernel32\Interop.ResolveLocaleName.cs</Link>
</Compile>
<Compile Include="$(CommonPath)Interop\Windows\Kernel32\Interop.SECURITY_ATTRIBUTES.cs">
<Link>Common\Interop\Windows\Kernel32\Interop.SECURITY_ATTRIBUTES.cs</Link>
</Compile>
@ -1399,18 +1467,15 @@
<Compile Include="$(CommonPath)Interop\Windows\Kernel32\Interop.WriteFile_SafeHandle_NativeOverlapped.cs">
<Link>Common\Interop\Windows\Kernel32\Interop.WriteFile_SafeHandle_NativeOverlapped.cs</Link>
</Compile>
<Compile Include="$(CommonPath)Interop\Windows\Normaliz\Interop.Idna.cs">
<Link>Common\Interop\Windows\Normaliz\Interop.Idna.cs</Link>
</Compile>
<Compile Include="$(CommonPath)Interop\Windows\Normaliz\Interop.Normalization.cs">
<Link>Common\Interop\Windows\Normaliz\Interop.Normalization.cs</Link>
</Compile>
<Compile Include="$(CommonPath)Interop\Windows\NtDll\Interop.NtQueryInformationFile.cs">
<Link>Common\Interop\Windows\NtDll\Interop.NtQueryInformationFile.cs</Link>
</Compile>
<Compile Include="$(CommonPath)Interop\Windows\NtDll\Interop.NtQuerySystemInformation.cs">
<Link>Common\Interop\Windows\NtDll\Interop.NtQuerySystemInformation.cs</Link>
</Compile>
<Compile Include="$(CommonPath)Interop\Windows\NtDll\Interop.RtlGetVersion.cs">
<Link>Common\Interop\Windows\NtDll\Interop.RtlGetVersion.cs</Link>
</Compile>
<Compile Include="$(CommonPath)Interop\Windows\NtDll\Interop.SYSTEM_LEAP_SECOND_INFORMATION.cs">
<Link>Common\Interop\Windows\NtDll\Interop.SYSTEM_LEAP_SECOND_INFORMATION.cs</Link>
</Compile>
@ -1455,15 +1520,8 @@
<Compile Include="$(MSBuildThisFileDirectory)System\Environment.Windows.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Diagnostics\DebugProvider.Windows.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Diagnostics\Stopwatch.Windows.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Globalization\CalendarData.Windows.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Globalization\CultureInfo.Windows.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Globalization\CompareInfo.Windows.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Globalization\CultureData.Windows.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Diagnostics\Tracing\RuntimeEventSourceHelper.Windows.cs" Condition="'$(FeaturePerfTracing)' == 'true'" />
<Compile Include="$(MSBuildThisFileDirectory)System\Globalization\HijriCalendar.Win32.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Globalization\IdnMapping.Windows.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Globalization\JapaneseCalendar.Win32.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Globalization\Normalization.Windows.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Globalization\TextInfo.Windows.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Guid.Windows.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\IO\DriveInfoInternal.Windows.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\IO\FileStream.Windows.cs" />
@ -1486,6 +1544,9 @@
<ItemGroup Condition="'$(FeatureAsyncCausalityTracer)' != 'true'">
<Compile Include="$(MSBuildThisFileDirectory)System\Threading\Tasks\AsyncCausalityTracer.Noop.cs" />
</ItemGroup>
<ItemGroup Condition="'$(FeatureComWrappers)' != 'true'">
<Compile Include="$(MSBuildThisFileDirectory)System\Runtime\InteropServices\ComWrappers.PlatformNotSupported.cs" />
</ItemGroup>
<ItemGroup Condition="'$(FeatureCominterop)' != 'true'">
<Compile Include="$(MSBuildThisFileDirectory)System\Runtime\InteropServices\Marshal.NoCom.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Runtime\InteropServices\ComEventsHelpers.NoCom.cs" />
@ -1500,7 +1561,6 @@
<!-- CoreCLR uses PAL layer that emulates Windows API on Unix. This is bridge for that PAL layer. See issue dotnet/runtime/#31721. -->
<ItemGroup Condition="'$(TargetsWindows)' == 'true' or '$(FeatureCoreCLR)'=='true'">
<Compile Include="$(MSBuildThisFileDirectory)Microsoft\Win32\SafeHandles\SafeWaitHandle.Windows.cs" />
<Compile Include="$(CommonPath)Interop\Windows\Interop.Errors.cs" />
<Compile Include="$(CommonPath)Interop\Windows\OleAut32\Interop.SysAllocStringLen.cs">
<Link>Common\Interop\Windows\OleAut32\Interop.SysAllocStringLen.cs</Link>
</Compile>
@ -1545,7 +1605,7 @@
</Compile>
<Compile Include="$(CommonPath)System\IO\Win32Marshal.cs">
<Link>Common\System\IO\Win32Marshal.cs</Link>
</Compile>
</Compile>
<Compile Include="$(MSBuildThisFileDirectory)System\Environment.Variables.Windows.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Threading\Mutex.Windows.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Threading\Semaphore.Windows.cs" />
@ -1566,36 +1626,6 @@
<Compile Include="$(CommonPath)Interop\Unix\Interop.Libraries.cs">
<Link>Common\Interop\Unix\Interop.Libraries.cs</Link>
</Compile>
<Compile Include="$(CommonPath)Interop\Unix\System.Globalization.Native\Interop.Calendar.cs">
<Link>Common\Interop\Unix\System.Globalization.Native\Interop.Calendar.cs</Link>
</Compile>
<Compile Include="$(CommonPath)Interop\Unix\System.Globalization.Native\Interop.Casing.cs">
<Link>Common\Interop\Unix\System.Globalization.Native\Interop.Casing.cs</Link>
</Compile>
<Compile Include="$(CommonPath)Interop\Unix\System.Globalization.Native\Interop.Collation.cs">
<Link>Common\Interop\Unix\System.Globalization.Native\Interop.Collation.cs</Link>
</Compile>
<Compile Include="$(CommonPath)Interop\Unix\System.Globalization.Native\Interop.ICU.cs">
<Link>Common\Interop\Unix\System.Globalization.Native\Interop.ICU.cs</Link>
</Compile>
<Compile Include="$(CommonPath)Interop\Unix\System.Globalization.Native\Interop.Idna.cs">
<Link>Common\Interop\Unix\System.Globalization.Native\Interop.Idna.cs</Link>
</Compile>
<Compile Include="$(CommonPath)Interop\Unix\System.Globalization.Native\Interop.Locale.cs">
<Link>Common\Interop\Unix\System.Globalization.Native\Interop.Locale.cs</Link>
</Compile>
<Compile Include="$(CommonPath)Interop\Unix\System.Globalization.Native\Interop.Normalization.cs">
<Link>Common\Interop\Unix\System.Globalization.Native\Interop.Normalization.cs</Link>
</Compile>
<Compile Include="$(CommonPath)Interop\Unix\System.Globalization.Native\Interop.ResultCode.cs">
<Link>Common\Interop\Unix\System.Globalization.Native\Interop.ResultCode.cs</Link>
</Compile>
<Compile Include="$(CommonPath)Interop\Unix\System.Globalization.Native\Interop.TimeZoneInfo.cs">
<Link>Common\Interop\Unix\System.Globalization.Native\Interop.TimeZoneInfo.cs</Link>
</Compile>
<Compile Include="$(CommonPath)Interop\Unix\System.Globalization.Native\Interop.Utils.cs">
<Link>Common\Interop\Unix\System.Globalization.Native\Interop.Utils.cs</Link>
</Compile>
<Compile Include="$(CommonPath)Interop\Unix\System.Native\Interop.Access.cs">
<Link>Common\Interop\Unix\System.Native\Interop.Access.cs</Link>
</Compile>
@ -1705,22 +1735,15 @@
<Compile Include="$(MSBuildThisFileDirectory)System\DateTime.Unix.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Diagnostics\DebugProvider.Unix.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Diagnostics\Stopwatch.Unix.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Diagnostics\Tracing\RuntimeEventSourceHelper.Unix.cs" Condition="'$(FeaturePerfTracing)' == 'true'" />
<Compile Include="$(MSBuildThisFileDirectory)System\Environment.NoRegistry.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Environment.Unix.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Globalization\CalendarData.Unix.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Globalization\CompareInfo.Unix.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Globalization\CultureData.Unix.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Globalization\CultureInfo.Unix.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Environment.Unix.GetFolderPathCore.cs" Condition="'$(TargetsiOS)' != 'true' and '$(TargetstvOS)' != 'true'" />
<Compile Include="$(MSBuildThisFileDirectory)System\Globalization\HijriCalendar.Unix.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Globalization\IdnMapping.Unix.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Globalization\JapaneseCalendar.Unix.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Globalization\LocaleData.Unix.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Globalization\Normalization.Unix.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Globalization\TextInfo.Unix.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Guid.Unix.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\IO\DriveInfoInternal.Unix.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\IO\FileStream.OSX.cs" Condition="'$(TargetsOSX)' == 'true'" />
<Compile Include="$(MSBuildThisFileDirectory)System\IO\FileStream.Linux.cs" Condition="'$(TargetsOSX)' != 'true'" />
<Compile Include="$(MSBuildThisFileDirectory)System\IO\FileStream.OSX.cs" Condition="'$(TargetsOSX)' == 'true' or '$(TargetsiOS)' == 'true' or '$(TargetstvOS)' == 'true'" />
<Compile Include="$(MSBuildThisFileDirectory)System\IO\FileStream.Linux.cs" Condition="'$(TargetsOSX)' != 'true' and '$(TargetsiOS)' != 'true' and '$(TargetstvOS)' != 'true'" />
<Compile Include="$(MSBuildThisFileDirectory)System\IO\FileStream.Unix.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\IO\Path.Unix.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\IO\PathInternal.Unix.cs" />

Просмотреть файл

@ -22,7 +22,7 @@ namespace System
public static string BaseDirectory =>
// The value of APP_CONTEXT_BASE_DIRECTORY key has to be a string and it is not allowed to be any other type.
// Otherwise the caller will get invalid cast exception
(string?)GetData("APP_CONTEXT_BASE_DIRECTORY") ??
GetData("APP_CONTEXT_BASE_DIRECTORY") as string ??
(s_defaultBaseDirectory ??= GetBaseDirectoryCore());
public static string? TargetFrameworkName =>

Просмотреть файл

@ -12,7 +12,7 @@ namespace System
{
try
{
object config = AppContext.GetData(configName);
object? config = AppContext.GetData(configName);
int result = defaultValue;
switch (config)
{
@ -54,7 +54,7 @@ namespace System
{
try
{
object config = AppContext.GetData(configName);
object? config = AppContext.GetData(configName);
short result = defaultValue;
switch (config)
{

Просмотреть файл

@ -149,8 +149,7 @@ namespace System
public bool? IsCompatibilitySwitchSet(string value)
{
bool result;
return AppContext.TryGetSwitch(value, out result) ? result : default(bool?);
return AppContext.TryGetSwitch(value, out bool result) ? result : default(bool?);
}
public bool IsDefaultAppDomain() => true;

Просмотреть файл

@ -7,6 +7,7 @@ using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Numerics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
@ -26,6 +27,11 @@ namespace System
internal const int MaxArrayLength = 0X7FEFFFFF;
internal const int MaxByteArrayLength = 0x7FFFFFC7;
// This is the threshold where Introspective sort switches to Insertion sort.
// Empirically, 16 seems to speed up most cases without slowing down others, at least for integers.
// Large value types may benefit from a smaller number.
internal const int IntrosortSizeThreshold = 16;
// This ctor exists solely to prevent C# from generating a protected .ctor that violates the surface area.
private protected Array() { }
@ -510,9 +516,7 @@ namespace System
if (comparer == Comparer.Default)
{
CorElementType et = array.GetCorElementTypeOfElementType();
if (et.IsPrimitiveType()
// IntPtr/UIntPtr does not implement IComparable
&& (et != CorElementType.ELEMENT_TYPE_I) && (et != CorElementType.ELEMENT_TYPE_U))
if (et.IsPrimitiveType())
{
if (value == null)
return ~index;
@ -538,15 +542,27 @@ namespace System
result = GenericBinarySearch<ushort>(array, adjustedIndex, length, value);
break;
case CorElementType.ELEMENT_TYPE_I4:
#if TARGET_32BIT
case CorElementType.ELEMENT_TYPE_I:
#endif
result = GenericBinarySearch<int>(array, adjustedIndex, length, value);
break;
case CorElementType.ELEMENT_TYPE_U4:
#if TARGET_32BIT
case CorElementType.ELEMENT_TYPE_U:
#endif
result = GenericBinarySearch<uint>(array, adjustedIndex, length, value);
break;
case CorElementType.ELEMENT_TYPE_I8:
#if TARGET_64BIT
case CorElementType.ELEMENT_TYPE_I:
#endif
result = GenericBinarySearch<long>(array, adjustedIndex, length, value);
break;
case CorElementType.ELEMENT_TYPE_U8:
#if TARGET_64BIT
case CorElementType.ELEMENT_TYPE_U:
#endif
result = GenericBinarySearch<ulong>(array, adjustedIndex, length, value);
break;
case CorElementType.ELEMENT_TYPE_R4:
@ -1674,15 +1690,27 @@ namespace System
GenericSort<ushort>(keys, items, adjustedIndex, length);
return;
case CorElementType.ELEMENT_TYPE_I4:
#if TARGET_32BIT
case CorElementType.ELEMENT_TYPE_I:
#endif
GenericSort<int>(keys, items, adjustedIndex, length);
return;
case CorElementType.ELEMENT_TYPE_U4:
#if TARGET_32BIT
case CorElementType.ELEMENT_TYPE_U:
#endif
GenericSort<uint>(keys, items, adjustedIndex, length);
return;
case CorElementType.ELEMENT_TYPE_I8:
#if TARGET_64BIT
case CorElementType.ELEMENT_TYPE_I:
#endif
GenericSort<long>(keys, items, adjustedIndex, length);
return;
case CorElementType.ELEMENT_TYPE_U8:
#if TARGET_64BIT
case CorElementType.ELEMENT_TYPE_U:
#endif
GenericSort<ulong>(keys, items, adjustedIndex, length);
return;
case CorElementType.ELEMENT_TYPE_R4:
@ -1691,10 +1719,6 @@ namespace System
case CorElementType.ELEMENT_TYPE_R8:
GenericSort<double>(keys, items, adjustedIndex, length);
return;
case CorElementType.ELEMENT_TYPE_I:
case CorElementType.ELEMENT_TYPE_U:
// IntPtr/UIntPtr does not implement IComparable
break;
}
static void GenericSort<T>(Array keys, Array? items, int adjustedIndex, int length) where T: struct
@ -1898,11 +1922,11 @@ namespace System
try
{
IntroSort(left, length + left - 1, 2 * IntrospectiveSortUtilities.FloorLog2PlusOne(length));
IntroSort(left, length + left - 1, 2 * (BitOperations.Log2((uint)length) + 1));
}
catch (IndexOutOfRangeException)
{
IntrospectiveSortUtilities.ThrowOrIgnoreBadComparer(comparer);
ThrowHelper.ThrowArgumentException_BadComparer(comparer);
}
catch (Exception e)
{
@ -1912,20 +1936,22 @@ namespace System
private void IntroSort(int lo, int hi, int depthLimit)
{
Debug.Assert(hi >= lo);
Debug.Assert(depthLimit >= 0);
while (hi > lo)
{
int partitionSize = hi - lo + 1;
if (partitionSize <= IntrospectiveSortUtilities.IntrosortSizeThreshold)
if (partitionSize <= IntrosortSizeThreshold)
{
if (partitionSize == 1)
{
return;
}
Debug.Assert(partitionSize >= 2);
if (partitionSize == 2)
{
SwapIfGreater(lo, hi);
return;
}
if (partitionSize == 3)
{
SwapIfGreater(lo, hi - 1);
@ -1953,8 +1979,11 @@ namespace System
private int PickPivotAndPartition(int lo, int hi)
{
Debug.Assert(hi - lo >= IntrosortSizeThreshold);
// Compute median-of-three. But also partition them, since we've done the comparison.
int mid = lo + (hi - lo) / 2;
// Sort lo, mid and hi appropriately, then pick mid as the pivot.
SwapIfGreater(lo, mid);
SwapIfGreater(lo, hi);
@ -1976,7 +2005,10 @@ namespace System
}
// Put pivot in the right location.
Swap(left, hi - 1);
if (left != hi - 1)
{
Swap(left, hi - 1);
}
return left;
}
@ -2104,11 +2136,11 @@ namespace System
try
{
IntroSort(left, length + left - 1, 2 * IntrospectiveSortUtilities.FloorLog2PlusOne(length));
IntroSort(left, length + left - 1, 2 * (BitOperations.Log2((uint)length) + 1));
}
catch (IndexOutOfRangeException)
{
IntrospectiveSortUtilities.ThrowOrIgnoreBadComparer(comparer);
ThrowHelper.ThrowArgumentException_BadComparer(comparer);
}
catch (Exception e)
{
@ -2118,20 +2150,22 @@ namespace System
private void IntroSort(int lo, int hi, int depthLimit)
{
Debug.Assert(hi >= lo);
Debug.Assert(depthLimit >= 0);
while (hi > lo)
{
int partitionSize = hi - lo + 1;
if (partitionSize <= IntrospectiveSortUtilities.IntrosortSizeThreshold)
if (partitionSize <= IntrosortSizeThreshold)
{
if (partitionSize == 1)
{
return;
}
Debug.Assert(partitionSize >= 2);
if (partitionSize == 2)
{
SwapIfGreater(lo, hi);
return;
}
if (partitionSize == 3)
{
SwapIfGreater(lo, hi - 1);
@ -2159,6 +2193,8 @@ namespace System
private int PickPivotAndPartition(int lo, int hi)
{
Debug.Assert(hi - lo >= IntrosortSizeThreshold);
// Compute median-of-three. But also partition them, since we've done the comparison.
int mid = lo + (hi - lo) / 2;
@ -2182,7 +2218,10 @@ namespace System
}
// Put pivot in the right location.
Swap(left, hi - 1);
if (left != hi - 1)
{
Swap(left, hi - 1);
}
return left;
}

Просмотреть файл

@ -4,6 +4,8 @@
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Intrinsics;
using System.Runtime.Intrinsics.X86;
using Internal.Runtime.CompilerServices;
@ -449,24 +451,52 @@ namespace System
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static unsafe long DoubleToInt64Bits(double value)
{
// Workaround for https://github.com/dotnet/runtime/issues/11413
if (Sse2.X64.IsSupported)
{
Vector128<long> vec = Vector128.CreateScalarUnsafe(value).AsInt64();
return Sse2.X64.ConvertToInt64(vec);
}
return *((long*)&value);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static unsafe double Int64BitsToDouble(long value)
{
// Workaround for https://github.com/dotnet/runtime/issues/11413
if (Sse2.X64.IsSupported)
{
Vector128<double> vec = Vector128.CreateScalarUnsafe(value).AsDouble();
return vec.ToScalar();
}
return *((double*)&value);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static unsafe int SingleToInt32Bits(float value)
{
// Workaround for https://github.com/dotnet/runtime/issues/11413
if (Sse2.IsSupported)
{
Vector128<int> vec = Vector128.CreateScalarUnsafe(value).AsInt32();
return Sse2.ConvertToInt32(vec);
}
return *((int*)&value);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static unsafe float Int32BitsToSingle(int value)
{
// Workaround for https://github.com/dotnet/runtime/issues/11413
if (Sse2.IsSupported)
{
Vector128<float> vec = Vector128.CreateScalarUnsafe(value).AsSingle();
return vec.ToScalar();
}
return *((float*)&value);
}
}

Просмотреть файл

@ -12,6 +12,7 @@
**
===========================================================*/
using System.Diagnostics.CodeAnalysis;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
@ -223,7 +224,7 @@ namespace System
// Determines whether a String represents true or false.
//
public static bool TryParse(string? value, out bool result)
public static bool TryParse([NotNullWhen(true)] string? value, out bool result)
{
if (value == null)
{

Просмотреть файл

@ -2,7 +2,10 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.CompilerServices;
using Internal.Runtime.CompilerServices;
namespace System.Buffers.Text
{
@ -70,5 +73,23 @@ namespace System.Buffers.Text
value = default;
return TryParseThrowFormatException(out bytesConsumed);
}
//
// Enable use of ThrowHelper from TryParse() routines without introducing dozens of non-code-coveraged "value= default; bytesConsumed = 0; return false" boilerplate.
//
[DoesNotReturn]
[StackTraceHidden]
public static bool TryParseThrowFormatException<T>(ReadOnlySpan<byte> source, out T value, out int bytesConsumed) where T : struct
{
// The parameters to this method are ordered the same as our callers' parameters
// allowing the JIT to avoid unnecessary register swapping or spilling.
Unsafe.SkipInit(out value); // bypass language initialization rules since we're about to throw
Unsafe.SkipInit(out bytesConsumed);
ThrowHelper.ThrowFormatException_BadFormatSpecifier();
Debug.Fail("Control should never reach this point.");
return false;
}
}
}

Просмотреть файл

@ -30,7 +30,7 @@ namespace System.Buffers.Text
public static bool TryParse(ReadOnlySpan<byte> source, out bool value, out int bytesConsumed, char standardFormat = default)
{
if (!(standardFormat == default(char) || standardFormat == 'G' || standardFormat == 'l'))
return ParserHelpers.TryParseThrowFormatException(out value, out bytesConsumed);
ThrowHelper.ThrowFormatException_BadFormatSpecifier();
if (source.Length >= 4)
{
@ -42,7 +42,7 @@ namespace System.Buffers.Text
return true;
}
if (source.Length >= 5)
if (4 < (uint)source.Length)
{
if (dw == 0x534c4146 /* 'SLAF' */ && (source[4] & ~0x20) == 'E')
{

Просмотреть файл

@ -29,19 +29,25 @@ namespace System.Buffers.Text
/// </exceptions>
public static bool TryParse(ReadOnlySpan<byte> source, out Guid value, out int bytesConsumed, char standardFormat = default)
{
FastPath:
if (standardFormat == default)
{
return TryParseGuidCore(source, out value, out bytesConsumed, ends: 0);
}
switch (standardFormat)
{
case default(char):
case 'D':
return TryParseGuidCore(source, false, ' ', ' ', out value, out bytesConsumed);
standardFormat = default;
goto FastPath;
case 'B':
return TryParseGuidCore(source, true, '{', '}', out value, out bytesConsumed);
return TryParseGuidCore(source, out value, out bytesConsumed, ends: '{' | ('}' << 8));
case 'P':
return TryParseGuidCore(source, true, '(', ')', out value, out bytesConsumed);
return TryParseGuidCore(source, out value, out bytesConsumed, ends: '(' | (')' << 8));
case 'N':
return TryParseGuidN(source, out value, out bytesConsumed);
default:
return ParserHelpers.TryParseThrowFormatException(out value, out bytesConsumed);
return ParserHelpers.TryParseThrowFormatException(source, out value, out bytesConsumed);
}
}
@ -97,9 +103,9 @@ namespace System.Buffers.Text
}
// {8-4-4-4-12}, where number is the number of hex digits, and {/} are ends.
private static bool TryParseGuidCore(ReadOnlySpan<byte> source, bool ends, char begin, char end, out Guid value, out int bytesConsumed)
private static bool TryParseGuidCore(ReadOnlySpan<byte> source, out Guid value, out int bytesConsumed, int ends)
{
int expectedCodingUnits = 36 + (ends ? 2 : 0); // 32 hex digits + 4 delimiters + 2 optional ends
int expectedCodingUnits = 36 + ((ends != 0) ? 2 : 0); // 32 hex digits + 4 delimiters + 2 optional ends
if (source.Length < expectedCodingUnits)
{
@ -108,9 +114,16 @@ namespace System.Buffers.Text
return false;
}
if (ends)
// The 'ends' parameter is a 16-bit value where the byte denoting the starting
// brace is at byte position 0 and the byte denoting the closing brace is at
// byte position 1. If no braces are expected, has value 0.
// Default: ends = 0
// Braces: ends = "}{"
// Parens: ends = ")("
if (ends != 0)
{
if (source[0] != begin)
if (source[0] != (byte)ends)
{
value = default;
bytesConsumed = 0;
@ -118,6 +131,7 @@ namespace System.Buffers.Text
}
source = source.Slice(1); // skip beginning
ends >>= 8; // shift the closing brace to byte position 0
}
if (!TryParseUInt32X(source, out uint i1, out int justConsumed))
@ -226,7 +240,7 @@ namespace System.Buffers.Text
return false; // 12 digits
}
if (ends && source[justConsumed] != end)
if (ends != 0 && source[justConsumed] != (byte)ends)
{
value = default;
bytesConsumed = 0;

Просмотреть файл

@ -35,26 +35,31 @@ namespace System.Buffers.Text
[CLSCompliant(false)]
public static bool TryParse(ReadOnlySpan<byte> source, out sbyte value, out int bytesConsumed, char standardFormat = default)
{
switch (standardFormat)
FastPath:
if (standardFormat == default)
{
return TryParseSByteD(source, out value, out bytesConsumed);
}
// There's small but measurable overhead when entering the switch block below.
// We optimize for the default case by hoisting it above the switch block.
switch (standardFormat | 0x20) // convert to lowercase
{
case default(char):
case 'g':
case 'G':
case 'd':
case 'D':
return TryParseSByteD(source, out value, out bytesConsumed);
standardFormat = default;
goto FastPath;
case 'n':
case 'N':
return TryParseSByteN(source, out value, out bytesConsumed);
case 'x':
case 'X':
value = default;
Unsafe.SkipInit(out value); // will be populated by TryParseByteX
return TryParseByteX(source, out Unsafe.As<sbyte, byte>(ref value), out bytesConsumed);
default:
return ParserHelpers.TryParseThrowFormatException(out value, out bytesConsumed);
return ParserHelpers.TryParseThrowFormatException(source, out value, out bytesConsumed);
}
}
@ -81,26 +86,31 @@ namespace System.Buffers.Text
/// </exceptions>
public static bool TryParse(ReadOnlySpan<byte> source, out short value, out int bytesConsumed, char standardFormat = default)
{
switch (standardFormat)
FastPath:
if (standardFormat == default)
{
return TryParseInt16D(source, out value, out bytesConsumed);
}
// There's small but measurable overhead when entering the switch block below.
// We optimize for the default case by hoisting it above the switch block.
switch (standardFormat | 0x20) // convert to lowercase
{
case default(char):
case 'g':
case 'G':
case 'd':
case 'D':
return TryParseInt16D(source, out value, out bytesConsumed);
standardFormat = default;
goto FastPath;
case 'n':
case 'N':
return TryParseInt16N(source, out value, out bytesConsumed);
case 'x':
case 'X':
value = default;
Unsafe.SkipInit(out value); // will be populated by TryParseUInt16X
return TryParseUInt16X(source, out Unsafe.As<short, ushort>(ref value), out bytesConsumed);
default:
return ParserHelpers.TryParseThrowFormatException(out value, out bytesConsumed);
return ParserHelpers.TryParseThrowFormatException(source, out value, out bytesConsumed);
}
}
@ -127,26 +137,31 @@ namespace System.Buffers.Text
/// </exceptions>
public static bool TryParse(ReadOnlySpan<byte> source, out int value, out int bytesConsumed, char standardFormat = default)
{
switch (standardFormat)
FastPath:
if (standardFormat == default)
{
return TryParseInt32D(source, out value, out bytesConsumed);
}
// There's small but measurable overhead when entering the switch block below.
// We optimize for the default case by hoisting it above the switch block.
switch (standardFormat | 0x20) // convert to lowercase
{
case default(char):
case 'g':
case 'G':
case 'd':
case 'D':
return TryParseInt32D(source, out value, out bytesConsumed);
standardFormat = default;
goto FastPath;
case 'n':
case 'N':
return TryParseInt32N(source, out value, out bytesConsumed);
case 'x':
case 'X':
value = default;
Unsafe.SkipInit(out value); // will be populated by TryParseUInt32X
return TryParseUInt32X(source, out Unsafe.As<int, uint>(ref value), out bytesConsumed);
default:
return ParserHelpers.TryParseThrowFormatException(out value, out bytesConsumed);
return ParserHelpers.TryParseThrowFormatException(source, out value, out bytesConsumed);
}
}
@ -173,26 +188,31 @@ namespace System.Buffers.Text
/// </exceptions>
public static bool TryParse(ReadOnlySpan<byte> source, out long value, out int bytesConsumed, char standardFormat = default)
{
switch (standardFormat)
FastPath:
if (standardFormat == default)
{
return TryParseInt64D(source, out value, out bytesConsumed);
}
// There's small but measurable overhead when entering the switch block below.
// We optimize for the default case by hoisting it above the switch block.
switch (standardFormat | 0x20) // convert to lowercase
{
case default(char):
case 'g':
case 'G':
case 'd':
case 'D':
return TryParseInt64D(source, out value, out bytesConsumed);
standardFormat = default;
goto FastPath;
case 'n':
case 'N':
return TryParseInt64N(source, out value, out bytesConsumed);
case 'x':
case 'X':
value = default;
Unsafe.SkipInit(out value); // will be populated by TryParseUInt64X
return TryParseUInt64X(source, out Unsafe.As<long, ulong>(ref value), out bytesConsumed);
default:
return ParserHelpers.TryParseThrowFormatException(out value, out bytesConsumed);
return ParserHelpers.TryParseThrowFormatException(source, out value, out bytesConsumed);
}
}
}

Просмотреть файл

@ -29,25 +29,30 @@ namespace System.Buffers.Text
/// </exceptions>
public static bool TryParse(ReadOnlySpan<byte> source, out byte value, out int bytesConsumed, char standardFormat = default)
{
switch (standardFormat)
FastPath:
if (standardFormat == default)
{
return TryParseByteD(source, out value, out bytesConsumed);
}
// There's small but measurable overhead when entering the switch block below.
// We optimize for the default case by hoisting it above the switch block.
switch (standardFormat | 0x20) // convert to lowercase
{
case default(char):
case 'g':
case 'G':
case 'd':
case 'D':
return TryParseByteD(source, out value, out bytesConsumed);
standardFormat = default;
goto FastPath;
case 'n':
case 'N':
return TryParseByteN(source, out value, out bytesConsumed);
case 'x':
case 'X':
return TryParseByteX(source, out value, out bytesConsumed);
default:
return ParserHelpers.TryParseThrowFormatException(out value, out bytesConsumed);
return ParserHelpers.TryParseThrowFormatException(source, out value, out bytesConsumed);
}
}
@ -75,25 +80,30 @@ namespace System.Buffers.Text
[CLSCompliant(false)]
public static bool TryParse(ReadOnlySpan<byte> source, out ushort value, out int bytesConsumed, char standardFormat = default)
{
switch (standardFormat)
FastPath:
if (standardFormat == default)
{
return TryParseUInt16D(source, out value, out bytesConsumed);
}
// There's small but measurable overhead when entering the switch block below.
// We optimize for the default case by hoisting it above the switch block.
switch (standardFormat | 0x20) // convert to lowercase
{
case default(char):
case 'g':
case 'G':
case 'd':
case 'D':
return TryParseUInt16D(source, out value, out bytesConsumed);
standardFormat = default;
goto FastPath;
case 'n':
case 'N':
return TryParseUInt16N(source, out value, out bytesConsumed);
case 'x':
case 'X':
return TryParseUInt16X(source, out value, out bytesConsumed);
default:
return ParserHelpers.TryParseThrowFormatException(out value, out bytesConsumed);
return ParserHelpers.TryParseThrowFormatException(source, out value, out bytesConsumed);
}
}
@ -121,25 +131,30 @@ namespace System.Buffers.Text
[CLSCompliant(false)]
public static bool TryParse(ReadOnlySpan<byte> source, out uint value, out int bytesConsumed, char standardFormat = default)
{
switch (standardFormat)
FastPath:
if (standardFormat == default)
{
return TryParseUInt32D(source, out value, out bytesConsumed);
}
// There's small but measurable overhead when entering the switch block below.
// We optimize for the default case by hoisting it above the switch block.
switch (standardFormat | 0x20) // convert to lowercase
{
case default(char):
case 'g':
case 'G':
case 'd':
case 'D':
return TryParseUInt32D(source, out value, out bytesConsumed);
standardFormat = default;
goto FastPath;
case 'n':
case 'N':
return TryParseUInt32N(source, out value, out bytesConsumed);
case 'x':
case 'X':
return TryParseUInt32X(source, out value, out bytesConsumed);
default:
return ParserHelpers.TryParseThrowFormatException(out value, out bytesConsumed);
return ParserHelpers.TryParseThrowFormatException(source, out value, out bytesConsumed);
}
}
@ -167,25 +182,30 @@ namespace System.Buffers.Text
[CLSCompliant(false)]
public static bool TryParse(ReadOnlySpan<byte> source, out ulong value, out int bytesConsumed, char standardFormat = default)
{
switch (standardFormat)
FastPath:
if (standardFormat == default)
{
return TryParseUInt64D(source, out value, out bytesConsumed);
}
// There's small but measurable overhead when entering the switch block below.
// We optimize for the default case by hoisting it above the switch block.
switch (standardFormat | 0x20) // convert to lowercase
{
case default(char):
case 'g':
case 'G':
case 'd':
case 'D':
return TryParseUInt64D(source, out value, out bytesConsumed);
standardFormat = default;
goto FastPath;
case 'n':
case 'N':
return TryParseUInt64N(source, out value, out bytesConsumed);
case 'x':
case 'X':
return TryParseUInt64X(source, out value, out bytesConsumed);
default:
return ParserHelpers.TryParseThrowFormatException(out value, out bytesConsumed);
return ParserHelpers.TryParseThrowFormatException(source, out value, out bytesConsumed);
}
}
}

Просмотреть файл

@ -2,6 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
@ -117,7 +118,7 @@ namespace System
return (byte)i;
}
public static bool TryParse(string? s, out byte result)
public static bool TryParse([NotNullWhen(true)] string? s, out byte result)
{
if (s == null)
{
@ -133,7 +134,7 @@ namespace System
return TryParse(s, NumberStyles.Integer, NumberFormatInfo.CurrentInfo, out result);
}
public static bool TryParse(string? s, NumberStyles style, IFormatProvider? provider, out byte result)
public static bool TryParse([NotNullWhen(true)] string? s, NumberStyles style, IFormatProvider? provider, out byte result)
{
NumberFormatInfo.ValidateParseStyleInteger(style);
@ -166,7 +167,7 @@ namespace System
public override string ToString()
{
return Number.UInt32ToDecStr(m_value, -1);
return Number.UInt32ToDecStr(m_value);
}
public string ToString(string? format)
@ -176,7 +177,7 @@ namespace System
public string ToString(IFormatProvider? provider)
{
return Number.FormatUInt32(m_value, null, provider);
return Number.UInt32ToDecStr(m_value);
}
public string ToString(string? format, IFormatProvider? provider)

Просмотреть файл

@ -13,6 +13,7 @@
===========================================================*/
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Runtime.InteropServices;
using System.Text;
@ -182,7 +183,7 @@ namespace System
return s[0];
}
public static bool TryParse(string? s, out char result)
public static bool TryParse([NotNullWhen(true)] string? s, out char result)
{
result = '\0';
if (s == null)
@ -353,10 +354,7 @@ namespace System
}
// Converts a character to upper-case for invariant culture.
public static char ToUpperInvariant(char c)
{
return TextInfo.Invariant.ToUpper(c);
}
public static char ToUpperInvariant(char c) => TextInfo.ToUpperInvariant(c);
/*===================================ToLower====================================
**
@ -382,10 +380,7 @@ namespace System
}
// Converts a character to lower-case for invariant culture.
public static char ToLowerInvariant(char c)
{
return TextInfo.Invariant.ToLower(c);
}
public static char ToLowerInvariant(char c) => TextInfo.ToLowerInvariant(c);
//
// IConvertible implementation

Просмотреть файл

@ -222,9 +222,7 @@ namespace System.Collections.Concurrent
public T[] ToArray()
{
// Snap the current contents for enumeration.
ConcurrentQueueSegment<T> head, tail;
int headHead, tailTail;
SnapForObservation(out head, out headHead, out tail, out tailTail);
SnapForObservation(out ConcurrentQueueSegment<T> head, out int headHead, out ConcurrentQueueSegment<T> tail, out int tailTail);
// Count the number of items in that snapped set, and use it to allocate an
// array of the right size.
@ -450,9 +448,7 @@ namespace System.Collections.Concurrent
}
// Snap for enumeration
ConcurrentQueueSegment<T> head, tail;
int headHead, tailTail;
SnapForObservation(out head, out headHead, out tail, out tailTail);
SnapForObservation(out ConcurrentQueueSegment<T> head, out int headHead, out ConcurrentQueueSegment<T> tail, out int tailTail);
// Get the number of items to be enumerated
long count = GetCount(head, headHead, tail, tailTail);
@ -484,9 +480,7 @@ namespace System.Collections.Concurrent
/// </remarks>
public IEnumerator<T> GetEnumerator()
{
ConcurrentQueueSegment<T> head, tail;
int headHead, tailTail;
SnapForObservation(out head, out headHead, out tail, out tailTail);
SnapForObservation(out ConcurrentQueueSegment<T> head, out int headHead, out ConcurrentQueueSegment<T> tail, out int tailTail);
return Enumerate(head, headHead, tail, tailTail);
}

Просмотреть файл

@ -2,50 +2,23 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
/*============================================================
**
**
**
**
**
** Purpose: class to sort arrays
**
**
===========================================================*/
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using Internal.Runtime.CompilerServices;
#pragma warning disable SA1121 // explicitly using type aliases instead of built-in types
#if TARGET_64BIT
using nint = System.Int64;
#else
using nint = System.Int32;
#endif
namespace System.Collections.Generic
{
#region ArraySortHelper for single arrays
internal static class IntrospectiveSortUtilities
{
// This is the threshold where Introspective sort switches to Insertion sort.
// Empirically, 16 seems to speed up most cases without slowing down others, at least for integers.
// Large value types may benefit from a smaller number.
internal const int IntrosortSizeThreshold = 16;
internal static int FloorLog2PlusOne(int n)
{
int result = 0;
while (n >= 1)
{
result++;
n /= 2;
}
return result;
}
[DoesNotReturn]
internal static void ThrowOrIgnoreBadComparer(object? comparer)
{
throw new ArgumentException(SR.Format(SR.Arg_BogusIComparer, comparer));
}
}
internal partial class ArraySortHelper<T>
{
#region IArraySortHelper<T> Members
@ -61,11 +34,11 @@ namespace System.Collections.Generic
}
catch (IndexOutOfRangeException)
{
IntrospectiveSortUtilities.ThrowOrIgnoreBadComparer(comparer);
ThrowHelper.ThrowArgumentException_BadComparer(comparer);
}
catch (Exception e)
{
throw new InvalidOperationException(SR.InvalidOperation_IComparerFailed, e);
ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_IComparerFailed, e);
}
}
@ -78,7 +51,8 @@ namespace System.Collections.Generic
}
catch (Exception e)
{
throw new InvalidOperationException(SR.InvalidOperation_IComparerFailed, e);
ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_IComparerFailed, e);
return 0;
}
}
@ -95,11 +69,11 @@ namespace System.Collections.Generic
}
catch (IndexOutOfRangeException)
{
IntrospectiveSortUtilities.ThrowOrIgnoreBadComparer(comparer);
ThrowHelper.ThrowArgumentException_BadComparer(comparer);
}
catch (Exception e)
{
throw new InvalidOperationException(SR.InvalidOperation_IComparerFailed, e);
ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_IComparerFailed, e);
}
}
@ -131,26 +105,24 @@ namespace System.Collections.Generic
private static void SwapIfGreater(Span<T> keys, Comparison<T> comparer, int i, int j)
{
if (i != j)
Debug.Assert(i != j);
if (comparer(keys[i], keys[j]) > 0)
{
if (comparer(keys[i], keys[j]) > 0)
{
T key = keys[i];
keys[i] = keys[j];
keys[j] = key;
}
T key = keys[i];
keys[i] = keys[j];
keys[j] = key;
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static void Swap(Span<T> a, int i, int j)
{
if (i != j)
{
T t = a[i];
a[i] = a[j];
a[j] = t;
}
Debug.Assert(i != j);
T t = a[i];
a[i] = a[j];
a[j] = t;
}
internal static void IntrospectiveSort(Span<T> keys, Comparison<T> comparer)
@ -159,53 +131,51 @@ namespace System.Collections.Generic
if (keys.Length > 1)
{
IntroSort(keys, 2 * IntrospectiveSortUtilities.FloorLog2PlusOne(keys.Length), comparer);
IntroSort(keys, 2 * (BitOperations.Log2((uint)keys.Length) + 1), comparer);
}
}
private static void IntroSort(Span<T> keys, int depthLimit, Comparison<T> comparer)
{
int lo = 0;
int hi = keys.Length - 1;
Debug.Assert(!keys.IsEmpty);
Debug.Assert(depthLimit >= 0);
Debug.Assert(comparer != null);
while (hi > lo)
int hi = keys.Length - 1;
while (hi > 0)
{
int partitionSize = hi - lo + 1;
if (partitionSize <= IntrospectiveSortUtilities.IntrosortSizeThreshold)
int partitionSize = hi + 1;
if (partitionSize <= Array.IntrosortSizeThreshold)
{
if (partitionSize == 1)
{
return;
}
Debug.Assert(partitionSize >= 2);
if (partitionSize == 2)
{
SwapIfGreater(keys, comparer, lo, hi);
SwapIfGreater(keys, comparer, 0, hi);
return;
}
if (partitionSize == 3)
{
SwapIfGreater(keys, comparer, lo, hi - 1);
SwapIfGreater(keys, comparer, lo, hi);
SwapIfGreater(keys, comparer, 0, hi - 1);
SwapIfGreater(keys, comparer, 0, hi);
SwapIfGreater(keys, comparer, hi - 1, hi);
return;
}
InsertionSort(keys[lo..(hi+1)], comparer);
InsertionSort(keys.Slice(0, hi+1), comparer);
return;
}
if (depthLimit == 0)
{
HeapSort(keys[lo..(hi+1)], comparer);
HeapSort(keys.Slice(0, hi+1), comparer);
return;
}
depthLimit--;
int p = PickPivotAndPartition(keys[lo..(hi+1)], comparer);
int p = PickPivotAndPartition(keys.Slice(0, hi+1), comparer);
// Note we've already partitioned around the pivot and do not have to move the pivot again.
IntroSort(keys[(p+1)..(hi+1)], depthLimit, comparer);
@ -215,23 +185,22 @@ namespace System.Collections.Generic
private static int PickPivotAndPartition(Span<T> keys, Comparison<T> comparer)
{
Debug.Assert(keys.Length >= Array.IntrosortSizeThreshold);
Debug.Assert(comparer != null);
Debug.Assert(!keys.IsEmpty);
int lo = 0;
int hi = keys.Length - 1;
// Compute median-of-three. But also partition them, since we've done the comparison.
int middle = lo + ((hi - lo) / 2);
int middle = hi >> 1;
// Sort lo, mid and hi appropriately, then pick mid as the pivot.
SwapIfGreater(keys, comparer, lo, middle); // swap the low with the mid point
SwapIfGreater(keys, comparer, lo, hi); // swap the low with the high
SwapIfGreater(keys, comparer, 0, middle); // swap the low with the mid point
SwapIfGreater(keys, comparer, 0, hi); // swap the low with the high
SwapIfGreater(keys, comparer, middle, hi); // swap the middle with the high
T pivot = keys[middle];
Swap(keys, middle, hi - 1);
int left = lo, right = hi - 1; // We already partitioned lo and hi and put the pivot in hi - 1. And we pre-increment & decrement below.
int left = 0, right = hi - 1; // We already partitioned lo and hi and put the pivot in hi - 1. And we pre-increment & decrement below.
while (left < right)
{
@ -245,7 +214,10 @@ namespace System.Collections.Generic
}
// Put pivot in the right location.
Swap(keys, left, hi - 1);
if (left != hi - 1)
{
Swap(keys, left, hi - 1);
}
return left;
}
@ -254,20 +226,16 @@ namespace System.Collections.Generic
Debug.Assert(comparer != null);
Debug.Assert(!keys.IsEmpty);
int lo = 0;
int hi = keys.Length - 1;
int n = hi - lo + 1;
for (int i = n / 2; i >= 1; i--)
int n = keys.Length;
for (int i = n >> 1; i >= 1; i--)
{
DownHeap(keys, i, n, lo, comparer);
DownHeap(keys, i, n, 0, comparer);
}
for (int i = n; i > 1; i--)
{
Swap(keys, lo, lo + i - 1);
DownHeap(keys, 1, i - 1, lo, comparer);
Swap(keys, 0, i - 1);
DownHeap(keys, 1, i - 1, 0, comparer);
}
}
@ -278,7 +246,7 @@ namespace System.Collections.Generic
Debug.Assert(lo < keys.Length);
T d = keys[lo + i - 1];
while (i <= n / 2)
while (i <= n >> 1)
{
int child = 2 * i;
if (child < n && comparer(keys[lo + child - 1], keys[lo + child]) < 0)
@ -327,7 +295,10 @@ namespace System.Collections.Generic
{
if (comparer == null || comparer == Comparer<T>.Default)
{
IntrospectiveSort(keys);
if (keys.Length > 1)
{
IntroSort(keys, 2 * (BitOperations.Log2((uint)keys.Length) + 1));
}
}
else
{
@ -336,11 +307,11 @@ namespace System.Collections.Generic
}
catch (IndexOutOfRangeException)
{
IntrospectiveSortUtilities.ThrowOrIgnoreBadComparer(comparer);
ThrowHelper.ThrowArgumentException_BadComparer(comparer);
}
catch (Exception e)
{
throw new InvalidOperationException(SR.InvalidOperation_IComparerFailed, e);
ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_IComparerFailed, e);
}
}
@ -362,7 +333,8 @@ namespace System.Collections.Generic
}
catch (Exception e)
{
throw new InvalidOperationException(SR.InvalidOperation_IComparerFailed, e);
ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_IComparerFailed, e);
return 0;
}
}
@ -406,147 +378,140 @@ namespace System.Collections.Generic
return ~lo;
}
private static void SwapIfGreater(Span<T> keys, int i, int j)
{
Debug.Assert(0 <= i && i < keys.Length);
Debug.Assert(0 <= j && j < keys.Length);
if (i != j)
{
if (keys[i] != null && keys[i].CompareTo(keys[j]) > 0)
{
T key = keys[i];
keys[i] = keys[j];
keys[j] = key;
}
}
}
/// <summary>Swaps the values in the two references if the first is greater than the second.</summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static void Swap(Span<T> a, int i, int j)
private static void SwapIfGreater(ref T i, ref T j)
{
if (i != j)
if (i != null && i.CompareTo(j) > 0)
{
T t = a[i];
a[i] = a[j];
a[j] = t;
Swap(ref i, ref j);
}
}
internal static void IntrospectiveSort(Span<T> keys)
/// <summary>Swaps the values in the two references, regardless of whether the two references are the same.</summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static void Swap(ref T i, ref T j)
{
if (keys.Length > 1)
{
IntroSort(keys, 2 * IntrospectiveSortUtilities.FloorLog2PlusOne(keys.Length));
}
Debug.Assert(!Unsafe.AreSame(ref i, ref j));
T t = i;
i = j;
j = t;
}
private static void IntroSort(Span<T> keys, int depthLimit)
{
int lo = 0;
int hi = keys.Length - 1;
Debug.Assert(!keys.IsEmpty);
Debug.Assert(depthLimit >= 0);
while (hi > lo)
int hi = keys.Length - 1;
while (hi > 0)
{
int partitionSize = hi - lo + 1;
if (partitionSize <= IntrospectiveSortUtilities.IntrosortSizeThreshold)
int partitionSize = hi + 1;
if (partitionSize <= Array.IntrosortSizeThreshold)
{
if (partitionSize == 1)
{
return;
}
Debug.Assert(partitionSize >= 2);
if (partitionSize == 2)
{
SwapIfGreater(keys, lo, hi);
return;
}
if (partitionSize == 3)
{
SwapIfGreater(keys, lo, hi - 1);
SwapIfGreater(keys, lo, hi);
SwapIfGreater(keys, hi - 1, hi);
SwapIfGreater(ref keys[0], ref keys[1]);
return;
}
InsertionSort(keys[lo..(hi+1)]);
if (partitionSize == 3)
{
ref T hiRef = ref keys[2];
ref T him1Ref = ref keys[1];
ref T loRef = ref keys[0];
SwapIfGreater(ref loRef, ref him1Ref);
SwapIfGreater(ref loRef, ref hiRef);
SwapIfGreater(ref him1Ref, ref hiRef);
return;
}
InsertionSort(keys.Slice(0, partitionSize));
return;
}
if (depthLimit == 0)
{
HeapSort(keys[lo..(hi+1)]);
HeapSort(keys.Slice(0, partitionSize));
return;
}
depthLimit--;
int p = PickPivotAndPartition(keys[lo..(hi+1)]);
int p = PickPivotAndPartition(keys.Slice(0, partitionSize));
// Note we've already partitioned around the pivot and do not have to move the pivot again.
IntroSort(keys[(p+1)..(hi+1)], depthLimit);
IntroSort(keys[(p+1)..partitionSize], depthLimit);
hi = p - 1;
}
}
private static int PickPivotAndPartition(Span<T> keys)
{
Debug.Assert(!keys.IsEmpty);
Debug.Assert(keys.Length >= Array.IntrosortSizeThreshold);
int lo = 0;
int hi = keys.Length - 1;
// Use median-of-three to select a pivot. Grab a reference to the 0th, Length-1th, and Length/2th elements, and sort them.
ref T zeroRef = ref MemoryMarshal.GetReference(keys);
ref T lastRef = ref Unsafe.Add(ref zeroRef, keys.Length - 1);
ref T middleRef = ref Unsafe.Add(ref zeroRef, (keys.Length - 1) >> 1);
SwapIfGreater(ref zeroRef, ref middleRef);
SwapIfGreater(ref zeroRef, ref lastRef);
SwapIfGreater(ref middleRef, ref lastRef);
// Compute median-of-three. But also partition them, since we've done the comparison.
int middle = lo + ((hi - lo) / 2);
// Select the middle value as the pivot, and move it to be just before the last element.
ref T nextToLastRef = ref Unsafe.Add(ref zeroRef, keys.Length - 2);
T pivot = middleRef;
Swap(ref middleRef, ref nextToLastRef);
// Sort lo, mid and hi appropriately, then pick mid as the pivot.
SwapIfGreater(keys, lo, middle); // swap the low with the mid point
SwapIfGreater(keys, lo, hi); // swap the low with the high
SwapIfGreater(keys, middle, hi); // swap the middle with the high
T pivot = keys[middle];
Swap(keys, middle, hi - 1);
int left = lo, right = hi - 1; // We already partitioned lo and hi and put the pivot in hi - 1. And we pre-increment & decrement below.
while (left < right)
// Walk the left and right pointers, swapping elements as necessary, until they cross.
ref T leftRef = ref zeroRef, rightRef = ref nextToLastRef;
while (Unsafe.IsAddressLessThan(ref leftRef, ref rightRef))
{
if (pivot == null)
{
while (left < (hi - 1) && keys[++left] == null) ;
while (right > lo && keys[--right] != null) ;
while (Unsafe.IsAddressLessThan(ref leftRef, ref nextToLastRef) && (leftRef = ref Unsafe.Add(ref leftRef, 1)) == null) ;
while (Unsafe.IsAddressGreaterThan(ref rightRef, ref zeroRef) && (rightRef = ref Unsafe.Add(ref rightRef, -1)) == null) ;
}
else
{
while (pivot.CompareTo(keys[++left]) > 0) ;
while (pivot.CompareTo(keys[--right]) < 0) ;
while (Unsafe.IsAddressLessThan(ref leftRef, ref nextToLastRef) && pivot.CompareTo(leftRef = ref Unsafe.Add(ref leftRef, 1)) > 0) ;
while (Unsafe.IsAddressGreaterThan(ref rightRef, ref zeroRef) && pivot.CompareTo(rightRef = ref Unsafe.Add(ref rightRef, -1)) < 0) ;
}
if (left >= right)
if (!Unsafe.IsAddressLessThan(ref leftRef, ref rightRef))
{
break;
}
Swap(keys, left, right);
Swap(ref leftRef, ref rightRef);
}
// Put pivot in the right location.
Swap(keys, left, hi - 1);
return left;
// Put the pivot in the correct location.
if (!Unsafe.AreSame(ref leftRef, ref nextToLastRef))
{
Swap(ref leftRef, ref nextToLastRef);
}
return (int)((nint)Unsafe.ByteOffset(ref zeroRef, ref leftRef) / Unsafe.SizeOf<T>());
}
private static void HeapSort(Span<T> keys)
{
Debug.Assert(!keys.IsEmpty);
int lo = 0;
int hi = keys.Length - 1;
int n = hi - lo + 1;
for (int i = n / 2; i >= 1; i = i - 1)
int n = keys.Length;
for (int i = n >> 1; i >= 1; i--)
{
DownHeap(keys, i, n, lo);
DownHeap(keys, i, n, 0);
}
for (int i = n; i > 1; i--)
{
Swap(keys, lo, lo + i - 1);
DownHeap(keys, 1, i - 1, lo);
Swap(ref keys[0], ref keys[i - 1]);
DownHeap(keys, 1, i - 1, 0);
}
}
@ -556,7 +521,7 @@ namespace System.Collections.Generic
Debug.Assert(lo < keys.Length);
T d = keys[lo + i - 1];
while (i <= n / 2)
while (i <= n >> 1)
{
int child = 2 * i;
if (child < n && (keys[lo + child - 1] == null || keys[lo + child - 1].CompareTo(keys[lo + child]) < 0))
@ -578,16 +543,16 @@ namespace System.Collections.Generic
{
for (int i = 0; i < keys.Length - 1; i++)
{
T t = keys[i + 1];
T t = Unsafe.Add(ref MemoryMarshal.GetReference(keys), i + 1);
int j = i;
while (j >= 0 && (t == null || t.CompareTo(keys[j]) < 0))
while (j >= 0 && (t == null || t.CompareTo(Unsafe.Add(ref MemoryMarshal.GetReference(keys), j)) < 0))
{
keys[j + 1] = keys[j];
Unsafe.Add(ref MemoryMarshal.GetReference(keys), j + 1) = Unsafe.Add(ref MemoryMarshal.GetReference(keys), j);
j--;
}
keys[j + 1] = t;
Unsafe.Add(ref MemoryMarshal.GetReference(keys), j + 1) = t;
}
}
}
@ -608,11 +573,11 @@ namespace System.Collections.Generic
}
catch (IndexOutOfRangeException)
{
IntrospectiveSortUtilities.ThrowOrIgnoreBadComparer(comparer);
ThrowHelper.ThrowArgumentException_BadComparer(comparer);
}
catch (Exception e)
{
throw new InvalidOperationException(SR.InvalidOperation_IComparerFailed, e);
ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_IComparerFailed, e);
}
}
@ -621,35 +586,32 @@ namespace System.Collections.Generic
Debug.Assert(comparer != null);
Debug.Assert(0 <= i && i < keys.Length && i < values.Length);
Debug.Assert(0 <= j && j < keys.Length && j < values.Length);
Debug.Assert(i != j);
if (i != j)
if (comparer.Compare(keys[i], keys[j]) > 0)
{
if (comparer.Compare(keys[i], keys[j]) > 0)
{
TKey key = keys[i];
keys[i] = keys[j];
keys[j] = key;
TKey key = keys[i];
keys[i] = keys[j];
keys[j] = key;
TValue value = values[i];
values[i] = values[j];
values[j] = value;
}
TValue value = values[i];
values[i] = values[j];
values[j] = value;
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static void Swap(Span<TKey> keys, Span<TValue> values, int i, int j)
{
if (i != j)
{
TKey k = keys[i];
keys[i] = keys[j];
keys[j] = k;
Debug.Assert(i != j);
TValue v = values[i];
values[i] = values[j];
values[j] = v;
}
TKey k = keys[i];
keys[i] = keys[j];
keys[j] = k;
TValue v = values[i];
values[i] = values[j];
values[j] = v;
}
internal static void IntrospectiveSort(Span<TKey> keys, Span<TValue> values, IComparer<TKey> comparer)
@ -659,79 +621,77 @@ namespace System.Collections.Generic
if (keys.Length > 1)
{
IntroSort(keys, values, 2 * IntrospectiveSortUtilities.FloorLog2PlusOne(keys.Length), comparer);
IntroSort(keys, values, 2 * (BitOperations.Log2((uint)keys.Length) + 1), comparer);
}
}
private static void IntroSort(Span<TKey> keys, Span<TValue> values, int depthLimit, IComparer<TKey> comparer)
{
Debug.Assert(!keys.IsEmpty);
Debug.Assert(values.Length == keys.Length);
Debug.Assert(depthLimit >= 0);
Debug.Assert(comparer != null);
int lo = 0;
int hi = keys.Length - 1;
while (hi > lo)
while (hi > 0)
{
int partitionSize = hi - lo + 1;
if (partitionSize <= IntrospectiveSortUtilities.IntrosortSizeThreshold)
int partitionSize = hi + 1;
if (partitionSize <= Array.IntrosortSizeThreshold)
{
if (partitionSize == 1)
{
return;
}
Debug.Assert(partitionSize >= 2);
if (partitionSize == 2)
{
SwapIfGreaterWithValues(keys, values, comparer, lo, hi);
SwapIfGreaterWithValues(keys, values, comparer, 0, hi);
return;
}
if (partitionSize == 3)
{
SwapIfGreaterWithValues(keys, values, comparer, lo, hi - 1);
SwapIfGreaterWithValues(keys, values, comparer, lo, hi);
SwapIfGreaterWithValues(keys, values, comparer, 0, hi - 1);
SwapIfGreaterWithValues(keys, values, comparer, 0, hi);
SwapIfGreaterWithValues(keys, values, comparer, hi - 1, hi);
return;
}
InsertionSort(keys[lo..(hi+1)], values[lo..(hi+1)], comparer);
InsertionSort(keys.Slice(0, partitionSize), values.Slice(0, partitionSize), comparer);
return;
}
if (depthLimit == 0)
{
HeapSort(keys[lo..(hi+1)], values[lo..(hi+1)], comparer);
HeapSort(keys.Slice(0, partitionSize), values.Slice(0, partitionSize), comparer);
return;
}
depthLimit--;
int p = PickPivotAndPartition(keys[lo..(hi+1)], values[lo..(hi+1)], comparer);
int p = PickPivotAndPartition(keys.Slice(0, partitionSize), values.Slice(0, partitionSize), comparer);
// Note we've already partitioned around the pivot and do not have to move the pivot again.
IntroSort(keys[(p+1)..(hi+1)], values[(p+1)..(hi+1)], depthLimit, comparer);
IntroSort(keys[(p+1)..partitionSize], values[(p+1)..partitionSize], depthLimit, comparer);
hi = p - 1;
}
}
private static int PickPivotAndPartition(Span<TKey> keys, Span<TValue> values, IComparer<TKey> comparer)
{
Debug.Assert(keys.Length >= Array.IntrosortSizeThreshold);
Debug.Assert(comparer != null);
Debug.Assert(!keys.IsEmpty);
int lo = 0;
int hi = keys.Length - 1;
// Compute median-of-three. But also partition them, since we've done the comparison.
int middle = lo + ((hi - lo) / 2);
int middle = hi >> 1;
// Sort lo, mid and hi appropriately, then pick mid as the pivot.
SwapIfGreaterWithValues(keys, values, comparer, lo, middle); // swap the low with the mid point
SwapIfGreaterWithValues(keys, values, comparer, lo, hi); // swap the low with the high
SwapIfGreaterWithValues(keys, values, comparer, 0, middle); // swap the low with the mid point
SwapIfGreaterWithValues(keys, values, comparer, 0, hi); // swap the low with the high
SwapIfGreaterWithValues(keys, values, comparer, middle, hi); // swap the middle with the high
TKey pivot = keys[middle];
Swap(keys, values, middle, hi - 1);
int left = lo, right = hi - 1; // We already partitioned lo and hi and put the pivot in hi - 1. And we pre-increment & decrement below.
int left = 0, right = hi - 1; // We already partitioned lo and hi and put the pivot in hi - 1. And we pre-increment & decrement below.
while (left < right)
{
@ -745,7 +705,10 @@ namespace System.Collections.Generic
}
// Put pivot in the right location.
Swap(keys, values, left, hi - 1);
if (left != hi - 1)
{
Swap(keys, values, left, hi - 1);
}
return left;
}
@ -754,19 +717,16 @@ namespace System.Collections.Generic
Debug.Assert(comparer != null);
Debug.Assert(!keys.IsEmpty);
int lo = 0;
int hi = keys.Length - 1;
int n = hi - lo + 1;
for (int i = n / 2; i >= 1; i--)
int n = keys.Length;
for (int i = n >> 1; i >= 1; i--)
{
DownHeap(keys, values, i, n, lo, comparer);
DownHeap(keys, values, i, n, 0, comparer);
}
for (int i = n; i > 1; i--)
{
Swap(keys, values, lo, lo + i - 1);
DownHeap(keys, values, 1, i - 1, lo, comparer);
Swap(keys, values, 0, i - 1);
DownHeap(keys, values, 1, i - 1, 0, comparer);
}
}
@ -779,7 +739,7 @@ namespace System.Collections.Generic
TKey d = keys[lo + i - 1];
TValue dValue = values[lo + i - 1];
while (i <= n / 2)
while (i <= n >> 1)
{
int child = 2 * i;
if (child < n && comparer.Compare(keys[lo + child - 1], keys[lo + child]) < 0)
@ -842,44 +802,42 @@ namespace System.Collections.Generic
}
catch (IndexOutOfRangeException)
{
IntrospectiveSortUtilities.ThrowOrIgnoreBadComparer(comparer);
ThrowHelper.ThrowArgumentException_BadComparer(comparer);
}
catch (Exception e)
{
throw new InvalidOperationException(SR.InvalidOperation_IComparerFailed, e);
ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_IComparerFailed, e);
}
}
private static void SwapIfGreaterWithValues(Span<TKey> keys, Span<TValue> values, int i, int j)
{
if (i != j)
{
if (keys[i] != null && keys[i].CompareTo(keys[j]) > 0)
{
TKey key = keys[i];
keys[i] = keys[j];
keys[j] = key;
Debug.Assert(i != j);
TValue value = values[i];
values[i] = values[j];
values[j] = value;
}
if (keys[i] != null && keys[i].CompareTo(keys[j]) > 0)
{
TKey key = keys[i];
keys[i] = keys[j];
keys[j] = key;
TValue value = values[i];
values[i] = values[j];
values[j] = value;
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static void Swap(Span<TKey> keys, Span<TValue> values, int i, int j)
{
if (i != j)
{
TKey k = keys[i];
keys[i] = keys[j];
keys[j] = k;
Debug.Assert(i != j);
TValue v = values[i];
values[i] = values[j];
values[j] = v;
}
TKey k = keys[i];
keys[i] = keys[j];
keys[j] = k;
TValue v = values[i];
values[i] = values[j];
values[j] = v;
}
internal static void IntrospectiveSort(Span<TKey> keys, Span<TValue> values)
@ -888,83 +846,82 @@ namespace System.Collections.Generic
if (keys.Length > 1)
{
IntroSort(keys, values, 2 * IntrospectiveSortUtilities.FloorLog2PlusOne(keys.Length));
IntroSort(keys, values, 2 * (BitOperations.Log2((uint)keys.Length) + 1));
}
}
private static void IntroSort(Span<TKey> keys, Span<TValue> values, int depthLimit)
{
int lo = 0;
int hi = keys.Length - 1;
Debug.Assert(!keys.IsEmpty);
Debug.Assert(values.Length == keys.Length);
Debug.Assert(depthLimit >= 0);
while (hi > lo)
int hi = keys.Length - 1;
while (hi > 0)
{
int partitionSize = hi - lo + 1;
if (partitionSize <= IntrospectiveSortUtilities.IntrosortSizeThreshold)
int partitionSize = hi + 1;
if (partitionSize <= Array.IntrosortSizeThreshold)
{
if (partitionSize == 1)
{
return;
}
Debug.Assert(partitionSize >= 2);
if (partitionSize == 2)
{
SwapIfGreaterWithValues(keys, values, lo, hi);
SwapIfGreaterWithValues(keys, values, 0, hi);
return;
}
if (partitionSize == 3)
{
SwapIfGreaterWithValues(keys, values, lo, hi - 1);
SwapIfGreaterWithValues(keys, values, lo, hi);
SwapIfGreaterWithValues(keys, values, 0, hi - 1);
SwapIfGreaterWithValues(keys, values, 0, hi);
SwapIfGreaterWithValues(keys, values, hi - 1, hi);
return;
}
InsertionSort(keys[lo..(hi+1)], values[lo..(hi+1)]);
InsertionSort(keys.Slice(0, partitionSize), values.Slice(0, partitionSize));
return;
}
if (depthLimit == 0)
{
HeapSort(keys[lo..(hi+1)], values[lo..(hi+1)]);
HeapSort(keys.Slice(0, partitionSize), values.Slice(0, partitionSize));
return;
}
depthLimit--;
int p = PickPivotAndPartition(keys[lo..(hi+1)], values[lo..(hi+1)]);
int p = PickPivotAndPartition(keys.Slice(0, partitionSize), values.Slice(0, partitionSize));
// Note we've already partitioned around the pivot and do not have to move the pivot again.
IntroSort(keys[(p+1)..(hi+1)], values[(p+1)..(hi+1)], depthLimit);
IntroSort(keys[(p+1)..partitionSize], values[(p+1)..partitionSize], depthLimit);
hi = p - 1;
}
}
private static int PickPivotAndPartition(Span<TKey> keys, Span<TValue> values)
{
Debug.Assert(!keys.IsEmpty);
Debug.Assert(keys.Length >= Array.IntrosortSizeThreshold);
int lo = 0;
int hi = keys.Length - 1;
// Compute median-of-three. But also partition them, since we've done the comparison.
int middle = lo + ((hi - lo) / 2);
int middle = hi >> 1;
// Sort lo, mid and hi appropriately, then pick mid as the pivot.
SwapIfGreaterWithValues(keys, values, lo, middle); // swap the low with the mid point
SwapIfGreaterWithValues(keys, values, lo, hi); // swap the low with the high
SwapIfGreaterWithValues(keys, values, 0, middle); // swap the low with the mid point
SwapIfGreaterWithValues(keys, values, 0, hi); // swap the low with the high
SwapIfGreaterWithValues(keys, values, middle, hi); // swap the middle with the high
TKey pivot = keys[middle];
Swap(keys, values, middle, hi - 1);
int left = lo, right = hi - 1; // We already partitioned lo and hi and put the pivot in hi - 1. And we pre-increment & decrement below.
int left = 0, right = hi - 1; // We already partitioned lo and hi and put the pivot in hi - 1. And we pre-increment & decrement below.
while (left < right)
{
if (pivot == null)
{
while (left < (hi - 1) && keys[++left] == null) ;
while (right > lo && keys[--right] != null) ;
while (right > 0 && keys[--right] != null) ;
}
else
{
@ -979,7 +936,10 @@ namespace System.Collections.Generic
}
// Put pivot in the right location.
Swap(keys, values, left, hi - 1);
if (left != hi - 1)
{
Swap(keys, values, left, hi - 1);
}
return left;
}
@ -987,19 +947,16 @@ namespace System.Collections.Generic
{
Debug.Assert(!keys.IsEmpty);
int lo = 0;
int hi = keys.Length - 1;
int n = hi - lo + 1;
for (int i = n / 2; i >= 1; i--)
int n = keys.Length;
for (int i = n >> 1; i >= 1; i--)
{
DownHeap(keys, values, i, n, lo);
DownHeap(keys, values, i, n, 0);
}
for (int i = n; i > 1; i--)
{
Swap(keys, values, lo, lo + i - 1);
DownHeap(keys, values, 1, i - 1, lo);
Swap(keys, values, 0, i - 1);
DownHeap(keys, values, 1, i - 1, 0);
}
}
@ -1011,7 +968,7 @@ namespace System.Collections.Generic
TKey d = keys[lo + i - 1];
TValue dValue = values[lo + i - 1];
while (i <= n / 2)
while (i <= n >> 1)
{
int child = 2 * i;
if (child < n && (keys[lo + child - 1] == null || keys[lo + child - 1].CompareTo(keys[lo + child]) < 0))

Просмотреть файл

@ -512,7 +512,6 @@ namespace System.Collections.Generic
if (behavior == InsertionBehavior.OverwriteExisting)
{
entries[i].value = value;
_version++;
return true;
}
@ -555,7 +554,6 @@ namespace System.Collections.Generic
if (behavior == InsertionBehavior.OverwriteExisting)
{
entries[i].value = value;
_version++;
return true;
}
@ -595,7 +593,6 @@ namespace System.Collections.Generic
if (behavior == InsertionBehavior.OverwriteExisting)
{
entries[i].value = value;
_version++;
return true;
}

Просмотреть файл

@ -0,0 +1,62 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
namespace System.Collections.Generic
{
/// <summary>
/// Provides a readonly abstraction of a set.
/// </summary>
/// <typeparam name="T">The type of elements in the set.</typeparam>
public interface IReadOnlySet<T> : IReadOnlyCollection<T>
{
/// <summary>
/// Determines if the set contains a specific item
/// </summary>
/// <param name="item">The item to check if the set contains.</param>
/// <returns><see langword="true" /> if found; otherwise <see langword="false" />.</returns>
bool Contains(T item);
/// <summary>
/// Determines whether the current set is a proper (strict) subset of a specified collection.
/// </summary>
/// <param name="other">The collection to compare to the current set.</param>
/// <returns><see langword="true" /> if the current set is a proper subset of other; otherwise <see langword="false" />.</returns>
/// <exception cref="ArgumentNullException">other is <see langword="null" />.</exception>
bool IsProperSubsetOf(IEnumerable<T> other);
/// <summary>
/// Determines whether the current set is a proper (strict) superset of a specified collection.
/// </summary>
/// <param name="other">The collection to compare to the current set.</param>
/// <returns><see langword="true" /> if the collection is a proper superset of other; otherwise <see langword="false" />.</returns>
/// <exception cref="ArgumentNullException">other is <see langword="null" />.</exception>
bool IsProperSupersetOf(IEnumerable<T> other);
/// <summary>
/// Determine whether the current set is a subset of a specified collection.
/// </summary>
/// <param name="other">The collection to compare to the current set.</param>
/// <returns><see langword="true" /> if the current set is a subset of other; otherwise <see langword="false" />.</returns>
/// <exception cref="ArgumentNullException">other is <see langword="null" />.</exception>
bool IsSubsetOf(IEnumerable<T> other);
/// <summary>
/// Determine whether the current set is a super set of a specified collection.
/// </summary>
/// <param name="other">The collection to compare to the current set</param>
/// <returns><see langword="true" /> if the current set is a subset of other; otherwise <see langword="false" />.</returns>
/// <exception cref="ArgumentNullException">other is <see langword="null" />.</exception>
bool IsSupersetOf(IEnumerable<T> other);
/// <summary>
/// Determines whether the current set overlaps with the specified collection.
/// </summary>
/// <param name="other">The collection to compare to the current set.</param>
/// <returns><see langword="true" />if the current set and other share at least one common element; otherwise, <see langword="false" />.</returns>
/// <exception cref="ArgumentNullException">other is <see langword="null" />.</exception>
bool Overlaps(IEnumerable<T> other);
/// <summary>
/// Determines whether the current set and the specified collection contain the same elements.
/// </summary>
/// <param name="other">The collection to compare to the current set.</param>
/// <returns><see langword="true" /> if the current set is equal to other; otherwise, <see langword="false" />.</returns>
/// <exception cref="ArgumentNullException">other is <see langword="null" />.</exception>
bool SetEquals(IEnumerable<T> other);
}
}

Просмотреть файл

@ -2,8 +2,6 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.Runtime.CompilerServices;
namespace System.Collections.Generic
{
/// <summary>

Просмотреть файл

@ -480,11 +480,9 @@ namespace System.Collections
throw new ArgumentNullException(nameof(key), SR.ArgumentNull_Key);
}
uint seed;
uint incr;
// Take a snapshot of buckets, in case another thread resizes table
bucket[] lbuckets = _buckets;
uint hashcode = InitHash(key, lbuckets.Length, out seed, out incr);
uint hashcode = InitHash(key, lbuckets.Length, out uint seed, out uint incr);
int ntry = 0;
bucket b;
@ -639,12 +637,10 @@ namespace System.Collections
throw new ArgumentNullException(nameof(key), SR.ArgumentNull_Key);
}
uint seed;
uint incr;
// Take a snapshot of buckets, in case another thread does a resize
bucket[] lbuckets = _buckets;
uint hashcode = InitHash(key, lbuckets.Length, out seed, out incr);
uint hashcode = InitHash(key, lbuckets.Length, out uint seed, out uint incr);
int ntry = 0;
bucket b;
@ -858,11 +854,9 @@ namespace System.Collections
rehash();
}
uint seed;
uint incr;
// Assume we only have one thread writing concurrently. Modify
// buckets to contain new data, as long as we insert in the right order.
uint hashcode = InitHash(key, _buckets.Length, out seed, out incr);
uint hashcode = InitHash(key, _buckets.Length, out uint seed, out uint incr);
int ntry = 0;
int emptySlotNumber = -1; // We use the empty slot number to cache the first empty slot. We chose to reuse slots
// create by remove that have the collision bit set over using up new slots.
@ -994,10 +988,8 @@ namespace System.Collections
Debug.Assert(!_isWriterInProgress, "Race condition detected in usages of Hashtable - multiple threads appear to be writing to a Hashtable instance simultaneously! Don't do that - use Hashtable.Synchronized.");
uint seed;
uint incr;
// Assuming only one concurrent writer, write directly into buckets.
uint hashcode = InitHash(key, _buckets.Length, out seed, out incr);
uint hashcode = InitHash(key, _buckets.Length, out uint seed, out uint incr);
int ntry = 0;
bucket b;
@ -1116,8 +1108,7 @@ namespace System.Collections
return;
}
SerializationInfo? siInfo;
HashHelpers.SerializationInfoTable.TryGetValue(this, out siInfo);
HashHelpers.SerializationInfoTable.TryGetValue(this, out SerializationInfo? siInfo);
if (siInfo == null)
{

Просмотреть файл

@ -528,11 +528,7 @@ namespace System
return (char)value;
}
public static char ToChar(int value)
{
if (value < 0 || value > char.MaxValue) ThrowCharOverflowException();
return (char)value;
}
public static char ToChar(int value) => ToChar((uint)value);
[CLSCompliant(false)]
public static char ToChar(uint value)
@ -541,11 +537,7 @@ namespace System
return (char)value;
}
public static char ToChar(long value)
{
if (value < 0 || value > char.MaxValue) ThrowCharOverflowException();
return (char)value;
}
public static char ToChar(long value) => ToChar((ulong)value);
[CLSCompliant(false)]
public static char ToChar(ulong value)
@ -667,7 +659,7 @@ namespace System
[CLSCompliant(false)]
public static sbyte ToSByte(uint value)
{
if (value > sbyte.MaxValue) ThrowSByteOverflowException();
if (value > (uint)sbyte.MaxValue) ThrowSByteOverflowException();
return (sbyte)value;
}
@ -708,13 +700,13 @@ namespace System
{
if (value == null)
return 0;
return sbyte.Parse(value, CultureInfo.CurrentCulture);
return sbyte.Parse(value);
}
[CLSCompliant(false)]
public static sbyte ToSByte(string value, IFormatProvider? provider)
{
return sbyte.Parse(value, NumberStyles.Integer, provider);
return sbyte.Parse(value, provider);
}
[CLSCompliant(false)]
@ -757,13 +749,13 @@ namespace System
[CLSCompliant(false)]
public static byte ToByte(sbyte value)
{
if (value < byte.MinValue) ThrowByteOverflowException();
if (value < 0) ThrowByteOverflowException();
return (byte)value;
}
public static byte ToByte(short value)
{
if (value < byte.MinValue || value > byte.MaxValue) ThrowByteOverflowException();
if ((uint)value > byte.MaxValue) ThrowByteOverflowException();
return (byte)value;
}
@ -774,11 +766,7 @@ namespace System
return (byte)value;
}
public static byte ToByte(int value)
{
if (value < byte.MinValue || value > byte.MaxValue) ThrowByteOverflowException();
return (byte)value;
}
public static byte ToByte(int value) => ToByte((uint)value);
[CLSCompliant(false)]
public static byte ToByte(uint value)
@ -787,11 +775,7 @@ namespace System
return (byte)value;
}
public static byte ToByte(long value)
{
if (value < byte.MinValue || value > byte.MaxValue) ThrowByteOverflowException();
return (byte)value;
}
public static byte ToByte(long value) => ToByte((ulong)value);
[CLSCompliant(false)]
public static byte ToByte(ulong value)
@ -819,14 +803,14 @@ namespace System
{
if (value == null)
return 0;
return byte.Parse(value, CultureInfo.CurrentCulture);
return byte.Parse(value);
}
public static byte ToByte(string? value, IFormatProvider? provider)
{
if (value == null)
return 0;
return byte.Parse(value, NumberStyles.Integer, provider);
return byte.Parse(value, provider);
}
public static byte ToByte(DateTime value)
@ -887,7 +871,7 @@ namespace System
[CLSCompliant(false)]
public static short ToInt16(uint value)
{
if (value > short.MaxValue) ThrowInt16OverflowException();
if (value > (uint)short.MaxValue) ThrowInt16OverflowException();
return (short)value;
}
@ -928,14 +912,14 @@ namespace System
{
if (value == null)
return 0;
return short.Parse(value, CultureInfo.CurrentCulture);
return short.Parse(value);
}
public static short ToInt16(string? value, IFormatProvider? provider)
{
if (value == null)
return 0;
return short.Parse(value, NumberStyles.Integer, provider);
return short.Parse(value, provider);
}
public static short ToInt16(DateTime value)
@ -993,11 +977,7 @@ namespace System
}
[CLSCompliant(false)]
public static ushort ToUInt16(int value)
{
if (value < 0 || value > ushort.MaxValue) ThrowUInt16OverflowException();
return (ushort)value;
}
public static ushort ToUInt16(int value) => ToUInt16((uint)value);
[CLSCompliant(false)]
public static ushort ToUInt16(ushort value)
@ -1013,11 +993,7 @@ namespace System
}
[CLSCompliant(false)]
public static ushort ToUInt16(long value)
{
if (value < 0 || value > ushort.MaxValue) ThrowUInt16OverflowException();
return (ushort)value;
}
public static ushort ToUInt16(long value) => ToUInt16((ulong)value);
[CLSCompliant(false)]
public static ushort ToUInt16(ulong value)
@ -1049,7 +1025,7 @@ namespace System
{
if (value == null)
return 0;
return ushort.Parse(value, CultureInfo.CurrentCulture);
return ushort.Parse(value);
}
[CLSCompliant(false)]
@ -1057,7 +1033,7 @@ namespace System
{
if (value == null)
return 0;
return ushort.Parse(value, NumberStyles.Integer, provider);
return ushort.Parse(value, provider);
}
[CLSCompliant(false)]
@ -1116,7 +1092,7 @@ namespace System
[CLSCompliant(false)]
public static int ToInt32(uint value)
{
if (value > int.MaxValue) ThrowInt32OverflowException();
if ((int)value < 0) ThrowInt32OverflowException();
return (int)value;
}
@ -1177,14 +1153,14 @@ namespace System
{
if (value == null)
return 0;
return int.Parse(value, CultureInfo.CurrentCulture);
return int.Parse(value);
}
public static int ToInt32(string? value, IFormatProvider? provider)
{
if (value == null)
return 0;
return int.Parse(value, NumberStyles.Integer, provider);
return int.Parse(value, provider);
}
public static int ToInt32(DateTime value)
@ -1261,11 +1237,7 @@ namespace System
}
[CLSCompliant(false)]
public static uint ToUInt32(long value)
{
if (value < 0 || value > uint.MaxValue) ThrowUInt32OverflowException();
return (uint)value;
}
public static uint ToUInt32(long value) => ToUInt32((ulong)value);
[CLSCompliant(false)]
public static uint ToUInt32(ulong value)
@ -1304,7 +1276,7 @@ namespace System
{
if (value == null)
return 0;
return uint.Parse(value, CultureInfo.CurrentCulture);
return uint.Parse(value);
}
[CLSCompliant(false)]
@ -1312,7 +1284,7 @@ namespace System
{
if (value == null)
return 0;
return uint.Parse(value, NumberStyles.Integer, provider);
return uint.Parse(value, provider);
}
[CLSCompliant(false)]
@ -1382,7 +1354,7 @@ namespace System
[CLSCompliant(false)]
public static long ToInt64(ulong value)
{
if (value > long.MaxValue) ThrowInt64OverflowException();
if ((long)value < 0) ThrowInt64OverflowException();
return (long)value;
}
@ -1410,14 +1382,14 @@ namespace System
{
if (value == null)
return 0;
return long.Parse(value, CultureInfo.CurrentCulture);
return long.Parse(value);
}
public static long ToInt64(string? value, IFormatProvider? provider)
{
if (value == null)
return 0;
return long.Parse(value, NumberStyles.Integer, provider);
return long.Parse(value, provider);
}
public static long ToInt64(DateTime value)
@ -1529,7 +1501,7 @@ namespace System
{
if (value == null)
return 0;
return ulong.Parse(value, CultureInfo.CurrentCulture);
return ulong.Parse(value);
}
[CLSCompliant(false)]
@ -1537,7 +1509,7 @@ namespace System
{
if (value == null)
return 0;
return ulong.Parse(value, NumberStyles.Integer, provider);
return ulong.Parse(value, provider);
}
[CLSCompliant(false)]
@ -1629,14 +1601,14 @@ namespace System
{
if (value == null)
return 0;
return float.Parse(value, CultureInfo.CurrentCulture);
return float.Parse(value);
}
public static float ToSingle(string? value, IFormatProvider? provider)
{
if (value == null)
return 0;
return float.Parse(value, NumberStyles.Float | NumberStyles.AllowThousands, provider);
return float.Parse(value, provider);
}
public static float ToSingle(bool value)
@ -1732,14 +1704,14 @@ namespace System
{
if (value == null)
return 0;
return double.Parse(value, CultureInfo.CurrentCulture);
return double.Parse(value);
}
public static double ToDouble(string? value, IFormatProvider? provider)
{
if (value == null)
return 0;
return double.Parse(value, NumberStyles.Float | NumberStyles.AllowThousands, provider);
return double.Parse(value, provider);
}
public static double ToDouble(bool value)
@ -1830,14 +1802,14 @@ namespace System
{
if (value == null)
return 0m;
return decimal.Parse(value, CultureInfo.CurrentCulture);
return decimal.Parse(value);
}
public static decimal ToDecimal(string? value, IFormatProvider? provider)
{
if (value == null)
return 0m;
return decimal.Parse(value, NumberStyles.Number, provider);
return decimal.Parse(value, provider);
}
public static decimal ToDecimal(decimal value)
@ -1879,7 +1851,7 @@ namespace System
{
if (value == null)
return new DateTime(0);
return DateTime.Parse(value, CultureInfo.CurrentCulture);
return DateTime.Parse(value);
}
public static DateTime ToDateTime(string? value, IFormatProvider? provider)
@ -2000,7 +1972,7 @@ namespace System
[CLSCompliant(false)]
public static string ToString(sbyte value)
{
return value.ToString(CultureInfo.CurrentCulture);
return value.ToString();
}
[CLSCompliant(false)]
@ -2011,7 +1983,7 @@ namespace System
public static string ToString(byte value)
{
return value.ToString(CultureInfo.CurrentCulture);
return value.ToString();
}
public static string ToString(byte value, IFormatProvider? provider)
@ -2021,7 +1993,7 @@ namespace System
public static string ToString(short value)
{
return value.ToString(CultureInfo.CurrentCulture);
return value.ToString();
}
public static string ToString(short value, IFormatProvider? provider)
@ -2032,7 +2004,7 @@ namespace System
[CLSCompliant(false)]
public static string ToString(ushort value)
{
return value.ToString(CultureInfo.CurrentCulture);
return value.ToString();
}
[CLSCompliant(false)]
@ -2043,7 +2015,7 @@ namespace System
public static string ToString(int value)
{
return value.ToString(CultureInfo.CurrentCulture);
return value.ToString();
}
public static string ToString(int value, IFormatProvider? provider)
@ -2054,7 +2026,7 @@ namespace System
[CLSCompliant(false)]
public static string ToString(uint value)
{
return value.ToString(CultureInfo.CurrentCulture);
return value.ToString();
}
[CLSCompliant(false)]
@ -2065,7 +2037,7 @@ namespace System
public static string ToString(long value)
{
return value.ToString(CultureInfo.CurrentCulture);
return value.ToString();
}
public static string ToString(long value, IFormatProvider? provider)
@ -2076,7 +2048,7 @@ namespace System
[CLSCompliant(false)]
public static string ToString(ulong value)
{
return value.ToString(CultureInfo.CurrentCulture);
return value.ToString();
}
[CLSCompliant(false)]
@ -2087,7 +2059,7 @@ namespace System
public static string ToString(float value)
{
return value.ToString(CultureInfo.CurrentCulture);
return value.ToString();
}
public static string ToString(float value, IFormatProvider? provider)
@ -2097,7 +2069,7 @@ namespace System
public static string ToString(double value)
{
return value.ToString(CultureInfo.CurrentCulture);
return value.ToString();
}
public static string ToString(double value, IFormatProvider? provider)
@ -2107,7 +2079,7 @@ namespace System
public static string ToString(decimal value)
{
return value.ToString(CultureInfo.CurrentCulture);
return value.ToString();
}
public static string ToString(decimal value, IFormatProvider? provider)
@ -2157,7 +2129,7 @@ namespace System
}
int r = ParseNumbers.StringToInt(value.AsSpan(), fromBase, ParseNumbers.IsTight | ParseNumbers.TreatAsUnsigned);
if (r < byte.MinValue || r > byte.MaxValue)
if ((uint)r > byte.MaxValue)
ThrowByteOverflowException();
return (byte)r;
}
@ -2231,7 +2203,7 @@ namespace System
}
int r = ParseNumbers.StringToInt(value.AsSpan(), fromBase, ParseNumbers.IsTight | ParseNumbers.TreatAsUnsigned);
if (r < ushort.MinValue || r > ushort.MaxValue)
if ((uint)r > ushort.MaxValue)
ThrowUInt16OverflowException();
return (ushort)r;
}

Просмотреть файл

@ -3,6 +3,7 @@
// See the LICENSE file in the project root for more information.
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;
@ -751,8 +752,7 @@ namespace System
// Because the ticks conversion between UTC and local is lossy, we need to capture whether the
// time is in a repeated hour so that it can be passed to the DateTime constructor.
DateTime utcDt = new DateTime(ticks, DateTimeKind.Utc);
bool isDaylightSavings = false;
offsetTicks = TimeZoneInfo.GetUtcOffsetFromUtc(utcDt, TimeZoneInfo.Local, out isDaylightSavings, out isAmbiguousLocalDst).Ticks;
offsetTicks = TimeZoneInfo.GetUtcOffsetFromUtc(utcDt, TimeZoneInfo.Local, out bool isDaylightSavings, out isAmbiguousLocalDst).Ticks;
}
ticks += offsetTicks;
// Another behaviour of parsing is to cause small times to wrap around, so that they can be used
@ -1079,8 +1079,7 @@ namespace System
get
{
DateTime utc = UtcNow;
bool isAmbiguousLocalDst;
long offset = TimeZoneInfo.GetDateTimeNowUtcOffsetFromUtc(utc, out isAmbiguousLocalDst).Ticks;
long offset = TimeZoneInfo.GetDateTimeNowUtcOffsetFromUtc(utc, out bool isAmbiguousLocalDst).Ticks;
long tick = utc.Ticks + offset;
if (tick > DateTime.MaxTicks)
{
@ -1290,9 +1289,7 @@ namespace System
{
return this;
}
bool isDaylightSavings = false;
bool isAmbiguousLocalDst = false;
long offset = TimeZoneInfo.GetUtcOffsetFromUtc(this, TimeZoneInfo.Local, out isDaylightSavings, out isAmbiguousLocalDst).Ticks;
long offset = TimeZoneInfo.GetUtcOffsetFromUtc(this, TimeZoneInfo.Local, out bool isDaylightSavings, out bool isAmbiguousLocalDst).Ticks;
long tick = Ticks + offset;
if (tick > DateTime.MaxTicks)
{
@ -1359,7 +1356,7 @@ namespace System
return TimeZoneInfo.ConvertTimeToUtc(this, TimeZoneInfoOptions.NoThrowOnInvalidTime);
}
public static bool TryParse(string? s, out DateTime result)
public static bool TryParse([NotNullWhen(true)] string? s, out DateTime result)
{
if (s == null)
{
@ -1374,7 +1371,7 @@ namespace System
return DateTimeParse.TryParse(s, DateTimeFormatInfo.CurrentInfo, DateTimeStyles.None, out result);
}
public static bool TryParse(string? s, IFormatProvider? provider, DateTimeStyles styles, out DateTime result)
public static bool TryParse([NotNullWhen(true)] string? s, IFormatProvider? provider, DateTimeStyles styles, out DateTime result)
{
DateTimeFormatInfo.ValidateStyles(styles, nameof(styles));
@ -1393,7 +1390,7 @@ namespace System
return DateTimeParse.TryParse(s, DateTimeFormatInfo.GetInstance(provider), styles, out result);
}
public static bool TryParseExact(string? s, string? format, IFormatProvider? provider, DateTimeStyles style, out DateTime result)
public static bool TryParseExact([NotNullWhen(true)] string? s, [NotNullWhen(true)] string? format, IFormatProvider? provider, DateTimeStyles style, out DateTime result)
{
DateTimeFormatInfo.ValidateStyles(style, nameof(style));
@ -1412,7 +1409,7 @@ namespace System
return DateTimeParse.TryParseExact(s, format, DateTimeFormatInfo.GetInstance(provider), style, out result);
}
public static bool TryParseExact(string? s, string?[]? formats, IFormatProvider? provider, DateTimeStyles style, out DateTime result)
public static bool TryParseExact([NotNullWhen(true)] string? s, [NotNullWhen(true)] string?[]? formats, IFormatProvider? provider, DateTimeStyles style, out DateTime result)
{
DateTimeFormatInfo.ValidateStyles(style, nameof(style));
@ -1425,7 +1422,7 @@ namespace System
return DateTimeParse.TryParseExactMultiple(s, formats, DateTimeFormatInfo.GetInstance(provider), style, out result);
}
public static bool TryParseExact(ReadOnlySpan<char> s, string?[]? formats, IFormatProvider? provider, DateTimeStyles style, out DateTime result)
public static bool TryParseExact(ReadOnlySpan<char> s, [NotNullWhen(true)] string?[]? formats, IFormatProvider? provider, DateTimeStyles style, out DateTime result)
{
DateTimeFormatInfo.ValidateStyles(style, nameof(style));
return DateTimeParse.TryParseExactMultiple(s, formats, DateTimeFormatInfo.GetInstance(provider), style, out result);

Просмотреть файл

@ -3,6 +3,7 @@
// See the LICENSE file in the project root for more information.
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
@ -479,11 +480,10 @@ namespace System
{
if (input == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.input);
TimeSpan offset;
DateTime dateResult = DateTimeParse.Parse(input,
DateTimeFormatInfo.CurrentInfo,
DateTimeStyles.None,
out offset);
out TimeSpan offset);
return new DateTimeOffset(dateResult.Ticks, offset);
}
@ -502,11 +502,10 @@ namespace System
styles = ValidateStyles(styles, nameof(styles));
if (input == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.input);
TimeSpan offset;
DateTime dateResult = DateTimeParse.Parse(input,
DateTimeFormatInfo.GetInstance(formatProvider),
styles,
out offset);
out TimeSpan offset);
return new DateTimeOffset(dateResult.Ticks, offset);
}
@ -538,12 +537,11 @@ namespace System
if (input == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.input);
if (format == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.format);
TimeSpan offset;
DateTime dateResult = DateTimeParse.ParseExact(input,
format,
DateTimeFormatInfo.GetInstance(formatProvider),
styles,
out offset);
out TimeSpan offset);
return new DateTimeOffset(dateResult.Ticks, offset);
}
@ -559,12 +557,11 @@ namespace System
styles = ValidateStyles(styles, nameof(styles));
if (input == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.input);
TimeSpan offset;
DateTime dateResult = DateTimeParse.ParseExactMultiple(input,
formats,
DateTimeFormatInfo.GetInstance(formatProvider),
styles,
out offset);
out TimeSpan offset);
return new DateTimeOffset(dateResult.Ticks, offset);
}
@ -652,15 +649,13 @@ namespace System
public DateTimeOffset ToUniversalTime() =>
new DateTimeOffset(UtcDateTime);
public static bool TryParse(string? input, out DateTimeOffset result)
public static bool TryParse([NotNullWhen(true)] string? input, out DateTimeOffset result)
{
TimeSpan offset;
DateTime dateResult;
bool parsed = DateTimeParse.TryParse(input,
DateTimeFormatInfo.CurrentInfo,
DateTimeStyles.None,
out dateResult,
out offset);
out DateTime dateResult,
out TimeSpan offset);
result = new DateTimeOffset(dateResult.Ticks, offset);
return parsed;
}
@ -672,7 +667,7 @@ namespace System
return parsed;
}
public static bool TryParse(string? input, IFormatProvider? formatProvider, DateTimeStyles styles, out DateTimeOffset result)
public static bool TryParse([NotNullWhen(true)] string? input, IFormatProvider? formatProvider, DateTimeStyles styles, out DateTimeOffset result)
{
styles = ValidateStyles(styles, nameof(styles));
if (input == null)
@ -681,13 +676,11 @@ namespace System
return false;
}
TimeSpan offset;
DateTime dateResult;
bool parsed = DateTimeParse.TryParse(input,
DateTimeFormatInfo.GetInstance(formatProvider),
styles,
out dateResult,
out offset);
out DateTime dateResult,
out TimeSpan offset);
result = new DateTimeOffset(dateResult.Ticks, offset);
return parsed;
}
@ -700,7 +693,7 @@ namespace System
return parsed;
}
public static bool TryParseExact(string? input, string? format, IFormatProvider? formatProvider, DateTimeStyles styles,
public static bool TryParseExact([NotNullWhen(true)] string? input, [NotNullWhen(true)] string? format, IFormatProvider? formatProvider, DateTimeStyles styles,
out DateTimeOffset result)
{
styles = ValidateStyles(styles, nameof(styles));
@ -710,14 +703,12 @@ namespace System
return false;
}
TimeSpan offset;
DateTime dateResult;
bool parsed = DateTimeParse.TryParseExact(input,
format,
DateTimeFormatInfo.GetInstance(formatProvider),
styles,
out dateResult,
out offset);
out DateTime dateResult,
out TimeSpan offset);
result = new DateTimeOffset(dateResult.Ticks, offset);
return parsed;
}
@ -731,7 +722,7 @@ namespace System
return parsed;
}
public static bool TryParseExact(string? input, string?[]? formats, IFormatProvider? formatProvider, DateTimeStyles styles,
public static bool TryParseExact([NotNullWhen(true)] string? input, [NotNullWhen(true)] string?[]? formats, IFormatProvider? formatProvider, DateTimeStyles styles,
out DateTimeOffset result)
{
styles = ValidateStyles(styles, nameof(styles));
@ -741,20 +732,18 @@ namespace System
return false;
}
TimeSpan offset;
DateTime dateResult;
bool parsed = DateTimeParse.TryParseExactMultiple(input,
formats,
DateTimeFormatInfo.GetInstance(formatProvider),
styles,
out dateResult,
out offset);
out DateTime dateResult,
out TimeSpan offset);
result = new DateTimeOffset(dateResult.Ticks, offset);
return parsed;
}
public static bool TryParseExact(
ReadOnlySpan<char> input, string?[]? formats, IFormatProvider? formatProvider, DateTimeStyles styles, out DateTimeOffset result)
ReadOnlySpan<char> input, [NotNullWhen(true)] string?[]? formats, IFormatProvider? formatProvider, DateTimeStyles styles, out DateTimeOffset result)
{
styles = ValidateStyles(styles, nameof(styles));
bool parsed = DateTimeParse.TryParseExactMultiple(input, formats, DateTimeFormatInfo.GetInstance(formatProvider), styles, out DateTime dateResult, out TimeSpan offset);

Просмотреть файл

@ -4,6 +4,7 @@
using System.Buffers.Binary;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
@ -480,7 +481,7 @@ namespace System
return Number.ParseDecimal(s, style, NumberFormatInfo.GetInstance(provider));
}
public static bool TryParse(string? s, out decimal result)
public static bool TryParse([NotNullWhen(true)] string? s, out decimal result)
{
if (s == null)
{
@ -496,7 +497,7 @@ namespace System
return Number.TryParseDecimal(s, NumberStyles.Number, NumberFormatInfo.CurrentInfo, out result) == Number.ParsingStatus.OK;
}
public static bool TryParse(string? s, NumberStyles style, IFormatProvider? provider, out decimal result)
public static bool TryParse([NotNullWhen(true)] string? s, NumberStyles style, IFormatProvider? provider, out decimal result)
{
NumberFormatInfo.ValidateParseStyleFloatingPoint(style);
@ -936,9 +937,9 @@ namespace System
[CLSCompliant(false)]
public static explicit operator ulong(decimal value) => ToUInt64(value);
public static explicit operator float(decimal value) => ToSingle(value);
public static explicit operator float(decimal value) => DecCalc.VarR4FromDec(in value);
public static explicit operator double(decimal value) => ToDouble(value);
public static explicit operator double(decimal value) => DecCalc.VarR8FromDec(in value);
public static decimal operator +(decimal d) => d;
@ -1051,12 +1052,12 @@ namespace System
float IConvertible.ToSingle(IFormatProvider? provider)
{
return Convert.ToSingle(this);
return DecCalc.VarR4FromDec(in this);
}
double IConvertible.ToDouble(IFormatProvider? provider)
{
return Convert.ToDouble(this);
return DecCalc.VarR8FromDec(in this);
}
decimal IConvertible.ToDecimal(IFormatProvider? provider)

Просмотреть файл

@ -600,7 +600,6 @@ namespace System
{
if (newMin == 2)
{
currentMin = i;
ambig = false;
currentMin = i;
}

Просмотреть файл

@ -125,4 +125,71 @@ namespace System.Diagnostics.CodeAnalysis
/// <summary>Gets the condition parameter value.</summary>
public bool ParameterValue { get; }
}
/// <summary>Specifies that the method or property will ensure that the listed field and property members have not-null values.</summary>
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)]
#if INTERNAL_NULLABLE_ATTRIBUTES
internal
#else
public
#endif
sealed class MemberNotNullAttribute : Attribute
{
/// <summary>Initializes the attribute with a field or property member.</summary>
/// <param name="member">
/// The field or property member that is promised to be not-null.
/// </param>
public MemberNotNullAttribute(string member) => Members = new[] { member };
/// <summary>Initializes the attribute with the list of field and property members.</summary>
/// <param name="members">
/// The list of field and property members that are promised to be not-null.
/// </param>
public MemberNotNullAttribute(params string[] members) => Members = members;
/// <summary>Gets field or property member names.</summary>
public string[] Members { get; }
}
/// <summary>Specifies that the method or property will ensure that the listed field and property members have not-null values when returning with the specified return value condition.</summary>
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)]
#if INTERNAL_NULLABLE_ATTRIBUTES
internal
#else
public
#endif
sealed class MemberNotNullWhenAttribute : Attribute
{
/// <summary>Initializes the attribute with the specified return value condition and a field or property member.</summary>
/// <param name="returnValue">
/// The return value condition. If the method returns this value, the associated parameter will not be null.
/// </param>
/// <param name="member">
/// The field or property member that is promised to be not-null.
/// </param>
public MemberNotNullWhenAttribute(bool returnValue, string member)
{
ReturnValue = returnValue;
Members = new[] { member };
}
/// <summary>Initializes the attribute with the specified return value condition and list of field and property members.</summary>
/// <param name="returnValue">
/// The return value condition. If the method returns this value, the associated parameter will not be null.
/// </param>
/// <param name="members">
/// The list of field and property members that are promised to be not-null.
/// </param>
public MemberNotNullWhenAttribute(bool returnValue, params string[] members)
{
ReturnValue = returnValue;
Members = members;
}
/// <summary>Gets the return value condition.</summary>
public bool ReturnValue { get; }
/// <summary>Gets field or property member names.</summary>
public string[] Members { get; }
}
}

Просмотреть файл

@ -2,8 +2,6 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using Microsoft.Win32.SafeHandles;
namespace System.Diagnostics
{
public partial class DebugProvider
@ -56,7 +54,7 @@ namespace System.Diagnostics
}
else
{
Interop.Sys.SysLog(Interop.Sys.SysLogPriority.LOG_USER | Interop.Sys.SysLogPriority.LOG_DEBUG, "%s", message);
Interop.Sys.SysLog(Interop.Sys.SysLogPriority.LOG_DEBUG, "%s", message);
}
}
@ -89,7 +87,7 @@ namespace System.Diagnostics
int totalBytesWritten = 0;
while (bufCount > 0)
{
int bytesWritten = Interop.Sys.Write(2 /* stderr */, buf + totalBytesWritten, bufCount);
int bytesWritten = Interop.Sys.Write((IntPtr)2 /* stderr */, buf + totalBytesWritten, bufCount);
if (bytesWritten < 0)
{
// On error, simply stop writing the debug output. This could commonly happen if stderr

Просмотреть файл

@ -102,8 +102,7 @@ namespace System.Diagnostics.Tracing
EnsureEventSourceIndexAvailable(eventSourceIndex);
Debug.Assert(s_counterGroups != null);
WeakReference<CounterGroup> weakRef = CounterGroup.s_counterGroups[eventSourceIndex];
CounterGroup? ret = null;
if (weakRef == null || !weakRef.TryGetTarget(out ret))
if (weakRef == null || !weakRef.TryGetTarget(out CounterGroup? ret))
{
ret = new CounterGroup(eventSource);
CounterGroup.s_counterGroups[eventSourceIndex] = new WeakReference<CounterGroup>(ret);

Просмотреть файл

@ -0,0 +1,277 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Threading;
#if FEATURE_PERFTRACING
namespace System.Diagnostics.Tracing
{
[StructLayout(LayoutKind.Sequential)]
internal struct EventPipeEventInstanceData
{
internal IntPtr ProviderID;
internal uint EventID;
internal uint ThreadID;
internal long TimeStamp;
internal Guid ActivityId;
internal Guid ChildActivityId;
internal IntPtr Payload;
internal uint PayloadLength;
}
[StructLayout(LayoutKind.Sequential)]
internal struct EventPipeSessionInfo
{
internal long StartTimeAsUTCFileTime;
internal long StartTimeStamp;
internal long TimeStampFrequency;
}
[StructLayout(LayoutKind.Sequential)]
internal struct EventPipeProviderConfiguration
{
[MarshalAs(UnmanagedType.LPWStr)]
private readonly string m_providerName;
private readonly ulong m_keywords;
private readonly uint m_loggingLevel;
[MarshalAs(UnmanagedType.LPWStr)]
private readonly string? m_filterData;
internal EventPipeProviderConfiguration(
string providerName,
ulong keywords,
uint loggingLevel,
string? filterData)
{
if (string.IsNullOrEmpty(providerName))
{
throw new ArgumentNullException(nameof(providerName));
}
if (loggingLevel > 5) // 5 == Verbose, the highest value in EventPipeLoggingLevel.
{
throw new ArgumentOutOfRangeException(nameof(loggingLevel));
}
m_providerName = providerName;
m_keywords = keywords;
m_loggingLevel = loggingLevel;
m_filterData = filterData;
}
internal string ProviderName
{
get { return m_providerName; }
}
internal ulong Keywords
{
get { return m_keywords; }
}
internal uint LoggingLevel
{
get { return m_loggingLevel; }
}
internal string? FilterData => m_filterData;
}
internal enum EventPipeSerializationFormat
{
NetPerf,
NetTrace
}
internal sealed class EventPipeWaitHandle : WaitHandle
{
}
internal sealed class EventPipeConfiguration
{
private readonly string m_outputFile;
private readonly EventPipeSerializationFormat m_format;
private readonly uint m_circularBufferSizeInMB;
private readonly List<EventPipeProviderConfiguration> m_providers;
private TimeSpan m_minTimeBetweenSamples = TimeSpan.FromMilliseconds(1);
internal EventPipeConfiguration(
string outputFile,
EventPipeSerializationFormat format,
uint circularBufferSizeInMB)
{
if (string.IsNullOrEmpty(outputFile))
{
throw new ArgumentNullException(nameof(outputFile));
}
if (circularBufferSizeInMB == 0)
{
throw new ArgumentOutOfRangeException(nameof(circularBufferSizeInMB));
}
m_outputFile = outputFile;
m_format = format;
m_circularBufferSizeInMB = circularBufferSizeInMB;
m_providers = new List<EventPipeProviderConfiguration>();
}
internal string OutputFile
{
get { return m_outputFile; }
}
internal EventPipeSerializationFormat Format
{
get { return m_format; }
}
internal uint CircularBufferSizeInMB
{
get { return m_circularBufferSizeInMB; }
}
internal EventPipeProviderConfiguration[] Providers
{
get { return m_providers.ToArray(); }
}
internal void EnableProvider(string providerName, ulong keywords, uint loggingLevel)
{
EnableProviderWithFilter(providerName, keywords, loggingLevel, null);
}
internal void EnableProviderWithFilter(string providerName, ulong keywords, uint loggingLevel, string? filterData)
{
m_providers.Add(new EventPipeProviderConfiguration(
providerName,
keywords,
loggingLevel,
filterData));
}
private void EnableProviderConfiguration(EventPipeProviderConfiguration providerConfig)
{
m_providers.Add(providerConfig);
}
internal void EnableProviderRange(EventPipeProviderConfiguration[] providerConfigs)
{
foreach (EventPipeProviderConfiguration config in providerConfigs)
{
EnableProviderConfiguration(config);
}
}
internal void SetProfilerSamplingRate(TimeSpan minTimeBetweenSamples)
{
if (minTimeBetweenSamples.Ticks <= 0)
{
throw new ArgumentOutOfRangeException(nameof(minTimeBetweenSamples));
}
m_minTimeBetweenSamples = minTimeBetweenSamples;
}
}
internal static class EventPipe
{
private static ulong s_sessionID = 0;
internal static void Enable(EventPipeConfiguration configuration)
{
if (configuration == null)
{
throw new ArgumentNullException(nameof(configuration));
}
if (configuration.Providers == null)
{
throw new ArgumentNullException(nameof(configuration.Providers));
}
EventPipeProviderConfiguration[] providers = configuration.Providers;
s_sessionID = EventPipeInternal.Enable(
configuration.OutputFile,
configuration.Format,
configuration.CircularBufferSizeInMB,
providers);
}
internal static void Disable()
{
EventPipeInternal.Disable(s_sessionID);
}
}
internal static partial class EventPipeInternal
{
private unsafe struct EventPipeProviderConfigurationNative
{
private char* m_pProviderName;
private ulong m_keywords;
private uint m_loggingLevel;
private char* m_pFilterData;
internal static void MarshalToNative(EventPipeProviderConfiguration managed, ref EventPipeProviderConfigurationNative native)
{
native.m_pProviderName = (char*)Marshal.StringToCoTaskMemUni(managed.ProviderName);
native.m_keywords = managed.Keywords;
native.m_loggingLevel = managed.LoggingLevel;
native.m_pFilterData = (char*)Marshal.StringToCoTaskMemUni(managed.FilterData);
}
internal void Release()
{
if (m_pProviderName != null)
{
Marshal.FreeCoTaskMem((IntPtr)m_pProviderName);
}
if (m_pFilterData != null)
{
Marshal.FreeCoTaskMem((IntPtr)m_pFilterData);
}
}
}
internal static unsafe ulong Enable(
string? outputFile,
EventPipeSerializationFormat format,
uint circularBufferSizeInMB,
EventPipeProviderConfiguration[] providers)
{
Span<EventPipeProviderConfigurationNative> providersNative = new Span<EventPipeProviderConfigurationNative>((void*)Marshal.AllocCoTaskMem(sizeof(EventPipeProviderConfigurationNative) * providers.Length), providers.Length);
providersNative.Clear();
try
{
for (int i = 0; i < providers.Length; i++)
{
EventPipeProviderConfigurationNative.MarshalToNative(providers[i], ref providersNative[i]);
}
fixed (char* outputFilePath = outputFile)
fixed (EventPipeProviderConfigurationNative* providersNativePointer = providersNative)
{
return Enable(outputFilePath, format, circularBufferSizeInMB, providersNativePointer, (uint)providersNative.Length);
}
}
finally
{
for (int i = 0; i < providers.Length; i++)
{
providersNative[i].Release();
}
fixed (EventPipeProviderConfigurationNative* providersNativePointer = providersNative)
{
Marshal.FreeCoTaskMem((IntPtr)providersNativePointer);
}
}
}
}
}
#endif // FEATURE_PERFTRACING

Просмотреть файл

@ -0,0 +1,226 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Win32.SafeHandles;
namespace System.Diagnostics.Tracing
{
#if FEATURE_PERFTRACING
internal sealed class EventPipeEventDispatcher
{
internal sealed class EventListenerSubscription
{
internal EventKeywords MatchAnyKeywords { get; private set; }
internal EventLevel Level { get; private set; }
internal EventListenerSubscription(EventKeywords matchAnyKeywords, EventLevel level)
{
MatchAnyKeywords = matchAnyKeywords;
Level = level;
}
}
internal static readonly EventPipeEventDispatcher Instance = new EventPipeEventDispatcher();
private readonly IntPtr m_RuntimeProviderID;
private ulong m_sessionID = 0;
private DateTime m_syncTimeUtc;
private long m_syncTimeQPC;
private long m_timeQPCFrequency;
private bool m_stopDispatchTask;
private readonly EventPipeWaitHandle m_dispatchTaskWaitHandle = new EventPipeWaitHandle();
private Task? m_dispatchTask = null;
private readonly object m_dispatchControlLock = new object();
private readonly Dictionary<EventListener, EventListenerSubscription> m_subscriptions = new Dictionary<EventListener, EventListenerSubscription>();
private const uint DefaultEventListenerCircularMBSize = 10;
private EventPipeEventDispatcher()
{
// Get the ID of the runtime provider so that it can be used as a filter when processing events.
m_RuntimeProviderID = EventPipeInternal.GetProvider(NativeRuntimeEventSource.EventSourceName);
m_dispatchTaskWaitHandle.SafeWaitHandle = new SafeWaitHandle(IntPtr.Zero, false);
}
internal void SendCommand(EventListener eventListener, EventCommand command, bool enable, EventLevel level, EventKeywords matchAnyKeywords)
{
if (command == EventCommand.Update && enable)
{
lock (m_dispatchControlLock)
{
// Add the new subscription. This will overwrite an existing subscription for the listener if one exists.
m_subscriptions[eventListener] = new EventListenerSubscription(matchAnyKeywords, level);
// Commit the configuration change.
CommitDispatchConfiguration();
}
}
else if (command == EventCommand.Update && !enable)
{
RemoveEventListener(eventListener);
}
}
internal void RemoveEventListener(EventListener listener)
{
lock (m_dispatchControlLock)
{
// Remove the event listener from the list of subscribers.
if (m_subscriptions.ContainsKey(listener))
{
m_subscriptions.Remove(listener);
}
// Commit the configuration change.
CommitDispatchConfiguration();
}
}
private void CommitDispatchConfiguration()
{
Debug.Assert(Monitor.IsEntered(m_dispatchControlLock));
// Ensure that the dispatch task is stopped.
// This is a no-op if the task is already stopped.
StopDispatchTask();
// Stop tracing.
// This is a no-op if it's already disabled.
EventPipeInternal.Disable(m_sessionID);
// Check to see if tracing should be enabled.
if (m_subscriptions.Count <= 0)
{
return;
}
// Determine the keywords and level that should be used based on the set of enabled EventListeners.
EventKeywords aggregatedKeywords = EventKeywords.None;
EventLevel highestLevel = EventLevel.LogAlways;
foreach (EventListenerSubscription subscription in m_subscriptions.Values)
{
aggregatedKeywords |= subscription.MatchAnyKeywords;
highestLevel = (subscription.Level > highestLevel) ? subscription.Level : highestLevel;
}
// Enable the EventPipe session.
EventPipeProviderConfiguration[] providerConfiguration = new EventPipeProviderConfiguration[]
{
new EventPipeProviderConfiguration(NativeRuntimeEventSource.EventSourceName, (ulong)aggregatedKeywords, (uint)highestLevel, null)
};
m_sessionID = EventPipeInternal.Enable(null, EventPipeSerializationFormat.NetTrace, DefaultEventListenerCircularMBSize, providerConfiguration);
Debug.Assert(m_sessionID != 0);
// Get the session information that is required to properly dispatch events.
EventPipeSessionInfo sessionInfo;
unsafe
{
if (!EventPipeInternal.GetSessionInfo(m_sessionID, &sessionInfo))
{
Debug.Fail("GetSessionInfo returned false.");
}
}
m_syncTimeUtc = DateTime.FromFileTimeUtc(sessionInfo.StartTimeAsUTCFileTime);
m_syncTimeQPC = sessionInfo.StartTimeStamp;
m_timeQPCFrequency = sessionInfo.TimeStampFrequency;
// Start the dispatch task.
StartDispatchTask();
}
private void StartDispatchTask()
{
Debug.Assert(Monitor.IsEntered(m_dispatchControlLock));
if (m_dispatchTask == null)
{
m_stopDispatchTask = false;
// Create a SafeWaitHandle that won't release the handle when done
m_dispatchTaskWaitHandle.SafeWaitHandle = new SafeWaitHandle(EventPipeInternal.GetWaitHandle(m_sessionID), false);
m_dispatchTask = Task.Factory.StartNew(DispatchEventsToEventListeners, CancellationToken.None, TaskCreationOptions.LongRunning, TaskScheduler.Default);
}
}
private void StopDispatchTask()
{
Debug.Assert(Monitor.IsEntered(m_dispatchControlLock));
if (m_dispatchTask != null)
{
m_stopDispatchTask = true;
Debug.Assert(!m_dispatchTaskWaitHandle.SafeWaitHandle.IsInvalid);
EventWaitHandle.Set(m_dispatchTaskWaitHandle.SafeWaitHandle);
m_dispatchTask.Wait();
m_dispatchTask = null;
}
}
private unsafe void DispatchEventsToEventListeners()
{
// Struct to fill with the call to GetNextEvent.
EventPipeEventInstanceData instanceData;
while (!m_stopDispatchTask)
{
bool eventsReceived = false;
// Get the next event.
while (!m_stopDispatchTask && EventPipeInternal.GetNextEvent(m_sessionID, &instanceData))
{
eventsReceived = true;
// Filter based on provider.
if (instanceData.ProviderID == m_RuntimeProviderID)
{
// Dispatch the event.
ReadOnlySpan<byte> payload = new ReadOnlySpan<byte>((void*)instanceData.Payload, (int)instanceData.PayloadLength);
DateTime dateTimeStamp = TimeStampToDateTime(instanceData.TimeStamp);
NativeRuntimeEventSource.Log.ProcessEvent(instanceData.EventID, instanceData.ThreadID, dateTimeStamp, instanceData.ActivityId, instanceData.ChildActivityId, payload);
}
}
// Wait for more events.
if (!m_stopDispatchTask)
{
if (!eventsReceived)
{
// Future TODO: this would make more sense to handle in EventPipeSession/EventPipe native code.
Debug.Assert(!m_dispatchTaskWaitHandle.SafeWaitHandle.IsInvalid);
m_dispatchTaskWaitHandle.WaitOne();
}
Thread.Sleep(10);
}
}
}
/// <summary>
/// Converts a QueryPerformanceCounter (QPC) timestamp to a UTC DateTime.
/// </summary>
private DateTime TimeStampToDateTime(long timeStamp)
{
if (timeStamp == long.MaxValue)
{
return DateTime.MaxValue;
}
Debug.Assert((m_syncTimeUtc.Ticks != 0) && (m_syncTimeQPC != 0) && (m_timeQPCFrequency != 0));
long inTicks = (long)((timeStamp - m_syncTimeQPC) * 10000000.0 / m_timeQPCFrequency) + m_syncTimeUtc.Ticks;
if ((inTicks < 0) || (DateTime.MaxTicks < inTicks))
{
inTicks = DateTime.MaxTicks;
}
return new DateTime(inTicks, DateTimeKind.Utc);
}
}
#endif // FEATURE_PERFTRACING
}

Просмотреть файл

@ -0,0 +1,89 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
namespace System.Diagnostics.Tracing
{
internal sealed class EventPipeEventProvider : IEventProvider
{
// The EventPipeProvider handle.
private IntPtr m_provHandle = IntPtr.Zero;
// Register an event provider.
unsafe uint IEventProvider.EventRegister(
EventSource eventSource,
Interop.Advapi32.EtwEnableCallback enableCallback,
void* callbackContext,
ref long registrationHandle)
{
uint returnStatus = 0;
m_provHandle = EventPipeInternal.CreateProvider(eventSource.Name, enableCallback);
if (m_provHandle != IntPtr.Zero)
{
// Fixed registration handle because a new EventPipeEventProvider
// will be created for each new EventSource.
registrationHandle = 1;
}
else
{
// Unable to create the provider.
returnStatus = 1;
}
return returnStatus;
}
// Unregister an event provider.
uint IEventProvider.EventUnregister(long registrationHandle)
{
EventPipeInternal.DeleteProvider(m_provHandle);
return 0;
}
// Write an event.
unsafe EventProvider.WriteEventErrorCode IEventProvider.EventWriteTransfer(
long registrationHandle,
in EventDescriptor eventDescriptor,
IntPtr eventHandle,
Guid* activityId,
Guid* relatedActivityId,
int userDataCount,
EventProvider.EventData* userData)
{
if (eventHandle != IntPtr.Zero)
{
if (userDataCount == 0)
{
EventPipeInternal.WriteEventData(eventHandle, null, 0, activityId, relatedActivityId);
return EventProvider.WriteEventErrorCode.NoError;
}
// If Channel == 11, this is a TraceLogging event.
// The first 3 descriptors contain event metadata that is emitted for ETW and should be discarded on EventPipe.
// EventPipe metadata is provided via the EventPipeEventProvider.DefineEventHandle.
if (eventDescriptor.Channel == 11)
{
userData += 3;
userDataCount -= 3;
Debug.Assert(userDataCount >= 0);
}
EventPipeInternal.WriteEventData(eventHandle, userData, (uint)userDataCount, activityId, relatedActivityId);
}
return EventProvider.WriteEventErrorCode.NoError;
}
// Get or set the per-thread activity ID.
int IEventProvider.EventActivityIdControl(Interop.Advapi32.ActivityControl ControlCode, ref Guid ActivityId)
{
return EventPipeInternal.EventActivityIdControl((uint)ControlCode, ref ActivityId);
}
// Define an EventPipeEvent handle.
unsafe IntPtr IEventProvider.DefineEventHandle(uint eventID, string eventName, long keywords, uint eventVersion, uint level, byte* pMetadata, uint metadataLength)
{
IntPtr eventHandlePtr = EventPipeInternal.DefineEvent(m_provHandle, eventID, keywords, eventVersion, level, pMetadata, metadataLength);
return eventHandlePtr;
}
}
}

Просмотреть файл

@ -0,0 +1,412 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.Reflection;
using EventMetadata = System.Diagnostics.Tracing.EventSource.EventMetadata;
namespace System.Diagnostics.Tracing
{
#if FEATURE_PERFTRACING
internal sealed class EventPipeMetadataGenerator
{
public static EventPipeMetadataGenerator Instance = new EventPipeMetadataGenerator();
private EventPipeMetadataGenerator() { }
public byte[]? GenerateEventMetadata(EventMetadata eventMetadata)
{
ParameterInfo[] parameters = eventMetadata.Parameters;
EventParameterInfo[] eventParams = new EventParameterInfo[parameters.Length];
for (int i = 0; i < parameters.Length; i++)
{
eventParams[i].SetInfo(parameters[i].Name!, parameters[i].ParameterType);
}
return GenerateMetadata(
eventMetadata.Descriptor.EventId,
eventMetadata.Name,
eventMetadata.Descriptor.Keywords,
eventMetadata.Descriptor.Level,
eventMetadata.Descriptor.Version,
eventParams);
}
public byte[]? GenerateEventMetadata(
int eventId,
string eventName,
EventKeywords keywords,
EventLevel level,
uint version,
TraceLoggingEventTypes eventTypes)
{
TraceLoggingTypeInfo[] typeInfos = eventTypes.typeInfos;
string[]? paramNames = eventTypes.paramNames;
EventParameterInfo[] eventParams = new EventParameterInfo[typeInfos.Length];
for (int i = 0; i < typeInfos.Length; i++)
{
string paramName = string.Empty;
if (paramNames != null)
{
paramName = paramNames[i];
}
eventParams[i].SetInfo(paramName, typeInfos[i].DataType, typeInfos[i]);
}
return GenerateMetadata(eventId, eventName, (long)keywords, (uint)level, version, eventParams);
}
internal unsafe byte[]? GenerateMetadata(
int eventId,
string eventName,
long keywords,
uint level,
uint version,
EventParameterInfo[] parameters)
{
byte[]? metadata = null;
try
{
// eventID : 4 bytes
// eventName : (eventName.Length + 1) * 2 bytes
// keywords : 8 bytes
// eventVersion : 4 bytes
// level : 4 bytes
// parameterCount : 4 bytes
uint metadataLength = 24 + ((uint)eventName.Length + 1) * 2;
uint defaultMetadataLength = metadataLength;
// Check for an empty payload.
// Write<T> calls with no arguments by convention have a parameter of
// type NullTypeInfo which is serialized as nothing.
if ((parameters.Length == 1) && (parameters[0].ParameterType == typeof(EmptyStruct)))
{
parameters = Array.Empty<EventParameterInfo>();
}
// Increase the metadataLength for parameters.
foreach (EventParameterInfo parameter in parameters)
{
int pMetadataLength = parameter.GetMetadataLength();
// The call above may return -1 which means we failed to get the metadata length.
// We then return a default metadata blob (with parameterCount of 0) to prevent it from generating malformed metadata.
if (pMetadataLength < 0)
{
parameters = Array.Empty<EventParameterInfo>();
metadataLength = defaultMetadataLength;
break;
}
metadataLength += (uint)pMetadataLength;
}
metadata = new byte[metadataLength];
// Write metadata: eventID, eventName, keywords, eventVersion, level, parameterCount, param1 type, param1 name...
fixed (byte* pMetadata = metadata)
{
uint offset = 0;
WriteToBuffer(pMetadata, metadataLength, ref offset, (uint)eventId);
fixed (char* pEventName = eventName)
{
WriteToBuffer(pMetadata, metadataLength, ref offset, (byte*)pEventName, ((uint)eventName.Length + 1) * 2);
}
WriteToBuffer(pMetadata, metadataLength, ref offset, keywords);
WriteToBuffer(pMetadata, metadataLength, ref offset, version);
WriteToBuffer(pMetadata, metadataLength, ref offset, level);
WriteToBuffer(pMetadata, metadataLength, ref offset, (uint)parameters.Length);
foreach (EventParameterInfo parameter in parameters)
{
if (!parameter.GenerateMetadata(pMetadata, ref offset, metadataLength))
{
// If we fail to generate metadata for any parameter, we should return the "default" metadata without any parameters
return GenerateMetadata(eventId, eventName, keywords, level, version, Array.Empty<EventParameterInfo>());
}
}
Debug.Assert(metadataLength == offset);
}
}
catch
{
// If a failure occurs during metadata generation, make sure that we don't return
// malformed metadata. Instead, return a null metadata blob.
// Consumers can either build in knowledge of the event or skip it entirely.
metadata = null;
}
return metadata;
}
// Copy src to buffer and modify the offset.
// Note: We know the buffer size ahead of time to make sure no buffer overflow.
internal static unsafe void WriteToBuffer(byte* buffer, uint bufferLength, ref uint offset, byte* src, uint srcLength)
{
Debug.Assert(bufferLength >= (offset + srcLength));
for (int i = 0; i < srcLength; i++)
{
*(byte*)(buffer + offset + i) = *(byte*)(src + i);
}
offset += srcLength;
}
// Copy uint value to buffer.
internal static unsafe void WriteToBuffer(byte* buffer, uint bufferLength, ref uint offset, uint value)
{
Debug.Assert(bufferLength >= (offset + 4));
*(uint*)(buffer + offset) = value;
offset += 4;
}
// Copy long value to buffer.
internal static unsafe void WriteToBuffer(byte* buffer, uint bufferLength, ref uint offset, long value)
{
Debug.Assert(bufferLength >= (offset + 8));
*(long*)(buffer + offset) = value;
offset += 8;
}
// Copy char value to buffer.
internal static unsafe void WriteToBuffer(byte* buffer, uint bufferLength, ref uint offset, char value)
{
Debug.Assert(bufferLength >= (offset + 2));
*(char*)(buffer + offset) = value;
offset += 2;
}
}
internal struct EventParameterInfo
{
internal string ParameterName;
internal Type ParameterType;
internal TraceLoggingTypeInfo? TypeInfo;
internal void SetInfo(string name, Type type, TraceLoggingTypeInfo? typeInfo = null)
{
ParameterName = name;
ParameterType = type;
TypeInfo = typeInfo;
}
internal unsafe bool GenerateMetadata(byte* pMetadataBlob, ref uint offset, uint blobSize)
{
TypeCode typeCode = GetTypeCodeExtended(ParameterType);
if (typeCode == TypeCode.Object)
{
// Each nested struct is serialized as:
// TypeCode.Object : 4 bytes
// Number of properties : 4 bytes
// Property description 0...N
// Nested struct property name : NULL-terminated string.
EventPipeMetadataGenerator.WriteToBuffer(pMetadataBlob, blobSize, ref offset, (uint)TypeCode.Object);
if (!(TypeInfo is InvokeTypeInfo invokeTypeInfo))
{
return false;
}
// Get the set of properties to be serialized.
PropertyAnalysis[]? properties = invokeTypeInfo.properties;
if (properties != null)
{
// Write the count of serializable properties.
EventPipeMetadataGenerator.WriteToBuffer(pMetadataBlob, blobSize, ref offset, (uint)properties.Length);
foreach (PropertyAnalysis prop in properties)
{
if (!GenerateMetadataForProperty(prop, pMetadataBlob, ref offset, blobSize))
{
return false;
}
}
}
else
{
// This struct has zero serializable properties so we just write the property count.
EventPipeMetadataGenerator.WriteToBuffer(pMetadataBlob, blobSize, ref offset, (uint)0);
}
// Top-level structs don't have a property name, but for simplicity we write a NULL-char to represent the name.
EventPipeMetadataGenerator.WriteToBuffer(pMetadataBlob, blobSize, ref offset, '\0');
}
else
{
// Write parameter type.
EventPipeMetadataGenerator.WriteToBuffer(pMetadataBlob, blobSize, ref offset, (uint)typeCode);
// Write parameter name.
fixed (char* pParameterName = ParameterName)
{
EventPipeMetadataGenerator.WriteToBuffer(pMetadataBlob, blobSize, ref offset, (byte*)pParameterName, ((uint)ParameterName.Length + 1) * 2);
}
}
return true;
}
private static unsafe bool GenerateMetadataForProperty(PropertyAnalysis property, byte* pMetadataBlob, ref uint offset, uint blobSize)
{
Debug.Assert(property != null);
Debug.Assert(pMetadataBlob != null);
// Check if this property is a nested struct.
if (property.typeInfo is InvokeTypeInfo invokeTypeInfo)
{
// Each nested struct is serialized as:
// TypeCode.Object : 4 bytes
// Number of properties : 4 bytes
// Property description 0...N
// Nested struct property name : NULL-terminated string.
EventPipeMetadataGenerator.WriteToBuffer(pMetadataBlob, blobSize, ref offset, (uint)TypeCode.Object);
// Get the set of properties to be serialized.
PropertyAnalysis[]? properties = invokeTypeInfo.properties;
if (properties != null)
{
// Write the count of serializable properties.
EventPipeMetadataGenerator.WriteToBuffer(pMetadataBlob, blobSize, ref offset, (uint)properties.Length);
foreach (PropertyAnalysis prop in properties)
{
if (!GenerateMetadataForProperty(prop, pMetadataBlob, ref offset, blobSize))
{
return false;
}
}
}
else
{
// This struct has zero serializable properties so we just write the property count.
EventPipeMetadataGenerator.WriteToBuffer(pMetadataBlob, blobSize, ref offset, (uint)0);
}
// Write the property name.
fixed (char* pPropertyName = property.name)
{
EventPipeMetadataGenerator.WriteToBuffer(pMetadataBlob, blobSize, ref offset, (byte*)pPropertyName, ((uint)property.name.Length + 1) * 2);
}
}
else
{
// Each primitive type is serialized as:
// TypeCode : 4 bytes
// PropertyName : NULL-terminated string
TypeCode typeCode = GetTypeCodeExtended(property.typeInfo.DataType);
// EventPipe does not support this type. Throw, which will cause no metadata to be registered for this event.
if (typeCode == TypeCode.Object)
{
return false;
}
// Write the type code.
EventPipeMetadataGenerator.WriteToBuffer(pMetadataBlob, blobSize, ref offset, (uint)typeCode);
// Write the property name.
fixed (char* pPropertyName = property.name)
{
EventPipeMetadataGenerator.WriteToBuffer(pMetadataBlob, blobSize, ref offset, (byte*)pPropertyName, ((uint)property.name.Length + 1) * 2);
}
}
return true;
}
internal int GetMetadataLength()
{
int ret = 0;
TypeCode typeCode = GetTypeCodeExtended(ParameterType);
if (typeCode == TypeCode.Object)
{
if (!(TypeInfo is InvokeTypeInfo typeInfo))
{
return -1;
}
// Each nested struct is serialized as:
// TypeCode.Object : 4 bytes
// Number of properties : 4 bytes
// Property description 0...N
// Nested struct property name : NULL-terminated string.
ret += sizeof(uint) // TypeCode
+ sizeof(uint); // Property count
// Get the set of properties to be serialized.
PropertyAnalysis[]? properties = typeInfo.properties;
if (properties != null)
{
foreach (PropertyAnalysis prop in properties)
{
ret += (int)GetMetadataLengthForProperty(prop);
}
}
// For simplicity when writing a reader, we write a NULL char
// after the metadata for a top-level struct (for its name) so that
// readers don't have do special case the outer-most struct.
ret += sizeof(char);
}
else
{
ret += (int)(sizeof(uint) + ((ParameterName.Length + 1) * 2));
}
return ret;
}
private static uint GetMetadataLengthForProperty(PropertyAnalysis property)
{
Debug.Assert(property != null);
uint ret = 0;
// Check if this property is a nested struct.
if (property.typeInfo is InvokeTypeInfo invokeTypeInfo)
{
// Each nested struct is serialized as:
// TypeCode.Object : 4 bytes
// Number of properties : 4 bytes
// Property description 0...N
// Nested struct property name : NULL-terminated string.
ret += sizeof(uint) // TypeCode
+ sizeof(uint); // Property count
// Get the set of properties to be serialized.
PropertyAnalysis[]? properties = invokeTypeInfo.properties;
if (properties != null)
{
foreach (PropertyAnalysis prop in properties)
{
ret += GetMetadataLengthForProperty(prop);
}
}
// Add the size of the property name.
ret += (uint)((property.name.Length + 1) * 2);
}
else
{
ret += (uint)(sizeof(uint) + ((property.name.Length + 1) * 2));
}
return ret;
}
private static TypeCode GetTypeCodeExtended(Type parameterType)
{
// Guid is not part of TypeCode, we decided to use 17 to represent it, as it's the "free slot"
// see https://github.com/dotnet/coreclr/issues/16105#issuecomment-361749750 for more
const TypeCode GuidTypeCode = (TypeCode)17;
if (parameterType == typeof(Guid)) // Guid is not a part of TypeCode enum
return GuidTypeCode;
// IntPtr and UIntPtr are converted to their non-pointer types.
if (parameterType == typeof(IntPtr))
return IntPtr.Size == 4 ? TypeCode.Int32 : TypeCode.Int64;
if (parameterType == typeof(UIntPtr))
return UIntPtr.Size == 4 ? TypeCode.UInt32 : TypeCode.UInt64;
return Type.GetTypeCode(parameterType);
}
}
#endif // FEATURE_PERFTRACING
}

Просмотреть файл

@ -0,0 +1,149 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.Buffers.Binary;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
namespace System.Diagnostics.Tracing
{
#if FEATURE_PERFTRACING
internal static class EventPipePayloadDecoder
{
/// <summary>
/// Given the metadata for an event and an event payload, decode and deserialize the event payload.
/// </summary>
internal static object[] DecodePayload(ref EventSource.EventMetadata metadata, ReadOnlySpan<byte> payload)
{
ParameterInfo[] parameters = metadata.Parameters;
object[] decodedFields = new object[parameters.Length];
for (int i = 0; i < parameters.Length; i++)
{
// It is possible that an older version of the event was emitted.
// If this happens, the payload might be missing arguments at the end.
// We can just leave these unset.
if (payload.Length <= 0)
{
break;
}
Type parameterType = parameters[i].ParameterType;
if (parameterType == typeof(IntPtr))
{
if (IntPtr.Size == 8)
{
decodedFields[i] = (IntPtr)BinaryPrimitives.ReadInt64LittleEndian(payload);
}
else
{
decodedFields[i] = (IntPtr)BinaryPrimitives.ReadInt32LittleEndian(payload);
}
payload = payload.Slice(IntPtr.Size);
}
else if (parameterType == typeof(int))
{
decodedFields[i] = BinaryPrimitives.ReadInt32LittleEndian(payload);
payload = payload.Slice(sizeof(int));
}
else if (parameterType == typeof(uint))
{
decodedFields[i] = BinaryPrimitives.ReadUInt32LittleEndian(payload);
payload = payload.Slice(sizeof(uint));
}
else if (parameterType == typeof(long))
{
decodedFields[i] = BinaryPrimitives.ReadInt64LittleEndian(payload);
payload = payload.Slice(sizeof(long));
}
else if (parameterType == typeof(ulong))
{
decodedFields[i] = BinaryPrimitives.ReadUInt64LittleEndian(payload);
payload = payload.Slice(sizeof(ulong));
}
else if (parameterType == typeof(byte))
{
decodedFields[i] = MemoryMarshal.Read<byte>(payload);
payload = payload.Slice(sizeof(byte));
}
else if (parameterType == typeof(sbyte))
{
decodedFields[i] = MemoryMarshal.Read<sbyte>(payload);
payload = payload.Slice(sizeof(sbyte));
}
else if (parameterType == typeof(short))
{
decodedFields[i] = BinaryPrimitives.ReadInt16LittleEndian(payload);
payload = payload.Slice(sizeof(short));
}
else if (parameterType == typeof(ushort))
{
decodedFields[i] = BinaryPrimitives.ReadUInt16LittleEndian(payload);
payload = payload.Slice(sizeof(ushort));
}
else if (parameterType == typeof(float))
{
decodedFields[i] = BitConverter.Int32BitsToSingle(BinaryPrimitives.ReadInt32LittleEndian(payload));
payload = payload.Slice(sizeof(float));
}
else if (parameterType == typeof(double))
{
decodedFields[i] = BitConverter.Int64BitsToDouble(BinaryPrimitives.ReadInt64LittleEndian(payload));
payload = payload.Slice(sizeof(double));
}
else if (parameterType == typeof(bool))
{
// The manifest defines a bool as a 32bit type (WIN32 BOOL), not 1 bit as CLR Does.
decodedFields[i] = (BinaryPrimitives.ReadInt32LittleEndian(payload) == 1);
payload = payload.Slice(sizeof(int));
}
else if (parameterType == typeof(Guid))
{
const int sizeOfGuid = 16;
decodedFields[i] = new Guid(payload.Slice(0, sizeOfGuid));
payload = payload.Slice(sizeOfGuid);
}
else if (parameterType == typeof(char))
{
decodedFields[i] = (char)BinaryPrimitives.ReadUInt16LittleEndian(payload);
payload = payload.Slice(sizeof(char));
}
else if (parameterType == typeof(string))
{
// Try to find null terminator (0x00) from the byte span
// NOTE: we do this by hand instead of using IndexOf because payload may be unaligned due to
// mixture of different types being stored in the same buffer. (see eventpipe.cpp:CopyData)
int byteCount = -1;
for (int j = 1; j < payload.Length; j += 2)
{
if (payload[j - 1] == (byte)(0) && payload[j] == (byte)(0))
{
byteCount = j + 1;
break;
}
}
ReadOnlySpan<char> charPayload;
if (byteCount < 0)
{
charPayload = MemoryMarshal.Cast<byte, char>(payload);
payload = default;
}
else
{
charPayload = MemoryMarshal.Cast<byte, char>(payload.Slice(0, byteCount - 2));
payload = payload.Slice(byteCount);
}
decodedFields[i] = BitConverter.IsLittleEndian ? new string(charPayload) : Encoding.Unicode.GetString(MemoryMarshal.Cast<char, byte>(charPayload));
}
else
{
Debug.Fail("Unsupported type encountered.");
}
}
return decodedFields;
}
}
#endif // FEATURE_PERFTRACING
}

Просмотреть файл

@ -13,7 +13,7 @@ using System.Collections.Generic;
using System.Globalization;
using System.Numerics;
using System.Runtime.InteropServices;
#if CORECLR && TARGET_WINDOWS
#if (CORECLR || MONO) && TARGET_WINDOWS
using Internal.Win32;
#endif
#if ES_BUILD_AGAINST_DOTNET_V35
@ -288,10 +288,8 @@ namespace System.Diagnostics.Tracing
filterData = null;
// read filter data only when a session is being *added*
byte[]? data;
int keyIndex;
if (bEnabling &&
GetDataFromController(etwSessionId, filterData, out command, out data, out keyIndex))
GetDataFromController(etwSessionId, filterData, out command, out byte[]? data, out int keyIndex))
{
args = new Dictionary<string, string?>(4);
// data can be null if the filterArgs had a very large size which failed our sanity check
@ -469,42 +467,59 @@ namespace System.Diagnostics.Tracing
// does not have this issue.
#if (TARGET_WINDOWS && (ES_SESSION_INFO || !ES_BUILD_STANDALONE))
int buffSize = 256; // An initial guess that probably works most of the time.
byte* buffer;
while (true)
byte* stackSpace = stackalloc byte[buffSize];
byte* buffer = stackSpace;
try
{
byte* space = stackalloc byte[buffSize];
buffer = space;
int hr = 0;
fixed (Guid* provider = &m_providerId)
while (true)
{
hr = Interop.Advapi32.EnumerateTraceGuidsEx(Interop.Advapi32.TRACE_QUERY_INFO_CLASS.TraceGuidQueryInfo,
provider, sizeof(Guid), buffer, buffSize, out buffSize);
int hr = 0;
fixed (Guid* provider = &m_providerId)
{
hr = Interop.Advapi32.EnumerateTraceGuidsEx(Interop.Advapi32.TRACE_QUERY_INFO_CLASS.TraceGuidQueryInfo,
provider, sizeof(Guid), buffer, buffSize, out buffSize);
}
if (hr == 0)
break;
if (hr != Interop.Errors.ERROR_INSUFFICIENT_BUFFER)
return;
if (buffer != stackSpace)
{
byte* toFree = buffer;
buffer = null;
Marshal.FreeHGlobal((IntPtr)toFree);
}
buffer = (byte*)Marshal.AllocHGlobal(buffSize);
}
var providerInfos = (Interop.Advapi32.TRACE_GUID_INFO*)buffer;
var providerInstance = (Interop.Advapi32.TRACE_PROVIDER_INSTANCE_INFO*)&providerInfos[1];
int processId = unchecked((int)Interop.Kernel32.GetCurrentProcessId());
// iterate over the instances of the EventProvider in all processes
for (int i = 0; i < providerInfos->InstanceCount; i++)
{
if (providerInstance->Pid == processId)
{
var enabledInfos = (Interop.Advapi32.TRACE_ENABLE_INFO*)&providerInstance[1];
// iterate over the list of active ETW sessions "listening" to the current provider
for (int j = 0; j < providerInstance->EnableCount; j++)
action(enabledInfos[j].LoggerId, enabledInfos[j].MatchAllKeyword, ref sessionList);
}
if (providerInstance->NextOffset == 0)
break;
Debug.Assert(0 <= providerInstance->NextOffset && providerInstance->NextOffset < buffSize);
byte* structBase = (byte*)providerInstance;
providerInstance = (Interop.Advapi32.TRACE_PROVIDER_INSTANCE_INFO*)&structBase[providerInstance->NextOffset];
}
if (hr == 0)
break;
if (hr != Interop.Errors.ERROR_INSUFFICIENT_BUFFER)
return;
}
var providerInfos = (Interop.Advapi32.TRACE_GUID_INFO*)buffer;
var providerInstance = (Interop.Advapi32.TRACE_PROVIDER_INSTANCE_INFO*)&providerInfos[1];
int processId = unchecked((int)Interop.Kernel32.GetCurrentProcessId());
// iterate over the instances of the EventProvider in all processes
for (int i = 0; i < providerInfos->InstanceCount; i++)
finally
{
if (providerInstance->Pid == processId)
if (buffer != null && buffer != stackSpace)
{
var enabledInfos = (Interop.Advapi32.TRACE_ENABLE_INFO*)&providerInstance[1];
// iterate over the list of active ETW sessions "listening" to the current provider
for (int j = 0; j < providerInstance->EnableCount; j++)
action(enabledInfos[j].LoggerId, enabledInfos[j].MatchAllKeyword, ref sessionList);
Marshal.FreeHGlobal((IntPtr)buffer);
}
if (providerInstance->NextOffset == 0)
break;
Debug.Assert(0 <= providerInstance->NextOffset && providerInstance->NextOffset < buffSize);
byte* structBase = (byte*)providerInstance;
providerInstance = (Interop.Advapi32.TRACE_PROVIDER_INSTANCE_INFO*)&structBase[providerInstance->NextOffset];
}
#else
#if !ES_BUILD_PCL && TARGET_WINDOWS // TODO command arguments don't work on PCL builds...

Просмотреть файл

@ -649,10 +649,8 @@ namespace System.Diagnostics.Tracing
{
m_config = ValidateSettings(settings);
Guid eventSourceGuid;
string? eventSourceName;
GetMetadata(out eventSourceGuid, out eventSourceName, out _, out _);
GetMetadata(out Guid eventSourceGuid, out string? eventSourceName, out _, out _);
if (eventSourceGuid.Equals(Guid.Empty) || eventSourceName == null)
{
@ -1373,28 +1371,29 @@ namespace System.Diagnostics.Tracing
int dataCount,
IntPtr data)
{
#if FEATURE_MANAGED_ETW || FEATURE_PERFTRACING
bool allAreNull = true;
#if FEATURE_MANAGED_ETW
if (m_etwProvider == null)
allAreNull &= (m_etwProvider == null);
if (m_etwProvider != null
&& !m_etwProvider.WriteEventRaw(ref eventDescriptor, eventHandle, activityID, relatedActivityID, dataCount, data))
{
ThrowEventSourceException(eventName);
}
else
{
if (!m_etwProvider.WriteEventRaw(ref eventDescriptor, eventHandle, activityID, relatedActivityID, dataCount, data))
ThrowEventSourceException(eventName);
}
#endif // FEATURE_MANAGED_ETW
#if FEATURE_PERFTRACING
if (m_eventPipeProvider == null)
allAreNull &= (m_eventPipeProvider == null);
if (m_eventPipeProvider != null
&& !m_eventPipeProvider.WriteEventRaw(ref eventDescriptor, eventHandle, activityID, relatedActivityID, dataCount, data))
{
ThrowEventSourceException(eventName);
}
else
{
if (!m_eventPipeProvider.WriteEventRaw(ref eventDescriptor, eventHandle, activityID, relatedActivityID, dataCount, data))
ThrowEventSourceException(eventName);
}
#endif // FEATURE_PERFTRACING
if (allAreNull)
{
ThrowEventSourceException(eventName);
}
#endif // FEATURE_MANAGED_ETW || FEATURE_PERFTRACING
}
// FrameworkEventSource is on the startup path for the framework, so we have this internal overload that it can use
@ -2150,49 +2149,95 @@ namespace System.Diagnostics.Tracing
}
}
private unsafe void WriteEventString(EventLevel level, long keywords, string msgString)
// WriteEventString is used for logging an error message (or similar) to
// ETW and EventPipe providers. It is not a general purpose API, it will
// log the message with Level=LogAlways and Keywords=All to make sure whoever
// is listening gets the message.
private unsafe void WriteEventString(string msgString)
{
#if FEATURE_MANAGED_ETW || FEATURE_PERFTRACING
bool allAreNull = true;
#if FEATURE_MANAGED_ETW
if (m_etwProvider != null)
allAreNull &= (m_etwProvider == null);
#endif // FEATURE_MANAGED_ETW
#if FEATURE_PERFTRACING
allAreNull &= (m_eventPipeProvider == null);
#endif // FEATURE_PERFTRACING
if (allAreNull)
{
const string EventName = "EventSourceMessage";
if (SelfDescribingEvents)
{
EventSourceOptions opt = new EventSourceOptions
{
Keywords = (EventKeywords)unchecked(keywords),
Level = level
};
var msg = new { message = msgString };
var tlet = new TraceLoggingEventTypes(EventName, EventTags.None, new Type[] { msg.GetType() });
WriteMultiMergeInner(EventName, ref opt, tlet, null, null, msg);
}
else
{
// We want the name of the provider to show up so if we don't have a manifest we create
// on that at least has the provider name (I don't define any events).
if (m_rawManifest == null && m_outOfBandMessageCount == 1)
{
ManifestBuilder manifestBuilder = new ManifestBuilder(Name, Guid, Name, null, EventManifestOptions.None);
manifestBuilder.StartEvent(EventName, new EventAttribute(0) { Level = EventLevel.LogAlways, Task = (EventTask)0xFFFE });
manifestBuilder.AddEventParameter(typeof(string), "message");
manifestBuilder.EndEvent();
SendManifest(manifestBuilder.CreateManifest());
}
return;
}
// We use this low level routine to bypass the enabled checking, since the eventSource itself is only partially inited.
fixed (char* msgStringPtr = msgString)
EventLevel level = EventLevel.LogAlways;
long keywords = -1;
const string EventName = "EventSourceMessage";
if (SelfDescribingEvents)
{
EventSourceOptions opt = new EventSourceOptions
{
Keywords = (EventKeywords)unchecked(keywords),
Level = level
};
var msg = new { message = msgString };
var tlet = new TraceLoggingEventTypes(EventName, EventTags.None, new Type[] { msg.GetType() });
WriteMultiMergeInner(EventName, ref opt, tlet, null, null, msg);
}
else
{
// We want the name of the provider to show up so if we don't have a manifest we create
// on that at least has the provider name (I don't define any events).
if (m_rawManifest == null && m_outOfBandMessageCount == 1)
{
ManifestBuilder manifestBuilder = new ManifestBuilder(Name, Guid, Name, null, EventManifestOptions.None);
manifestBuilder.StartEvent(EventName, new EventAttribute(0) { Level = level, Task = (EventTask)0xFFFE });
manifestBuilder.AddEventParameter(typeof(string), "message");
manifestBuilder.EndEvent();
SendManifest(manifestBuilder.CreateManifest());
}
// We use this low level routine to bypass the enabled checking, since the eventSource itself is only partially inited.
fixed (char* msgStringPtr = msgString)
{
EventDescriptor descr = new EventDescriptor(0, 0, 0, (byte)level, 0, 0, keywords);
EventProvider.EventData data = default;
data.Ptr = (ulong)msgStringPtr;
data.Size = (uint)(2 * (msgString.Length + 1));
data.Reserved = 0;
#if FEATURE_MANAGED_ETW
if (m_etwProvider != null)
{
EventDescriptor descr = new EventDescriptor(0, 0, 0, (byte)level, 0, 0, keywords);
EventProvider.EventData data = default;
data.Ptr = (ulong)msgStringPtr;
data.Size = (uint)(2 * (msgString.Length + 1));
data.Reserved = 0;
m_etwProvider.WriteEvent(ref descr, IntPtr.Zero, null, null, 1, (IntPtr)((void*)&data));
}
#endif // FEATURE_MANAGED_ETW
#if FEATURE_PERFTRACING
if (m_eventPipeProvider != null)
{
if (m_writeEventStringEventHandle == IntPtr.Zero)
{
lock (m_createEventLock)
{
if (m_writeEventStringEventHandle == IntPtr.Zero)
{
string eventName = "EventSourceMessage";
EventParameterInfo paramInfo = default(EventParameterInfo);
paramInfo.SetInfo("message", typeof(string));
byte[]? metadata = EventPipeMetadataGenerator.Instance.GenerateMetadata(0, eventName, keywords, (uint)level, 0, new EventParameterInfo[] { paramInfo });
uint metadataLength = (metadata != null) ? (uint)metadata.Length : 0;
fixed (byte* pMetadata = metadata)
{
m_writeEventStringEventHandle = m_eventPipeProvider.m_eventProvider.DefineEventHandle(0, eventName, keywords, 0, (uint)level, pMetadata, metadataLength);
}
}
}
}
m_eventPipeProvider.WriteEvent(ref descr, m_writeEventStringEventHandle, null, null, 1, (IntPtr)((void*)&data));
}
#endif // FEATURE_PERFTRACING
}
}
#endif // FEATURE_MANAGED_ETW
#endif // FEATURE_MANAGED_ETW || FEATURE_PERFTRACING
}
/// <summary>
@ -2871,13 +2916,10 @@ namespace System.Diagnostics.Tracing
if (m_eventData == null)
{
Guid eventSourceGuid = Guid.Empty;
string? eventSourceName = null;
EventMetadata[]? eventData = null;
byte[]? manifest = null;
// Try the GetMetadata provided by the ILTransform in ProjectN. The default sets all to null, and in that case we fall back
// to the reflection approach.
GetMetadata(out eventSourceGuid, out eventSourceName, out eventData, out manifest);
GetMetadata(out eventSourceGuid, out string? eventSourceName, out EventMetadata[]? eventData, out byte[]? manifest);
if (eventSourceGuid.Equals(Guid.Empty) || eventSourceName == null || eventData == null || manifest == null)
{
@ -3808,7 +3850,7 @@ namespace System.Diagnostics.Tracing
msg = "Reached message limit. End of EventSource error messages.";
}
WriteEventString(EventLevel.LogAlways, -1, msg);
WriteEventString(msg);
WriteStringToAllListeners("EventSourceMessage", msg);
}
catch { } // If we fail during last chance logging, well, we have to give up....
@ -3865,6 +3907,8 @@ namespace System.Diagnostics.Tracing
private volatile OverideEventProvider m_etwProvider = null!; // This hooks up ETW commands to our 'OnEventCommand' callback
#endif
#if FEATURE_PERFTRACING
private object m_createEventLock = new object();
private IntPtr m_writeEventStringEventHandle = IntPtr.Zero;
private volatile OverideEventProvider m_eventPipeProvider = null!;
#endif
private bool m_completelyInited; // The EventSource constructor has returned without exception.
@ -5551,8 +5595,7 @@ namespace System.Diagnostics.Tracing
if (channelTab.Count == MaxCountChannels)
ManifestError(SR.EventSource_MaxChannelExceeded);
ChannelInfo? info;
if (!channelTab.TryGetValue((int)channel, out info))
if (!channelTab.TryGetValue((int)channel, out ChannelInfo? info))
{
// If we were not given an explicit channel, allocate one.
if (channelKeyword != 0)
@ -5876,8 +5919,7 @@ namespace System.Diagnostics.Tracing
#if FEATURE_MANAGED_ETW_CHANNELS
private string? GetChannelName(EventChannel channel, string eventName, string? eventMessage)
{
ChannelInfo? info = null;
if (channelTab == null || !channelTab.TryGetValue((int)channel, out info))
if (channelTab == null || !channelTab.TryGetValue((int)channel, out ChannelInfo? info))
{
if (channel < EventChannel.Admin) // || channel > EventChannel.Debug)
ManifestError(SR.Format(SR.EventSource_UndefinedChannel, channel, eventName));
@ -5909,9 +5951,8 @@ namespace System.Diagnostics.Tracing
if (task == EventTask.None)
return "";
string? ret;
taskTab ??= new Dictionary<int, string>();
if (!taskTab.TryGetValue((int)task, out ret))
if (!taskTab.TryGetValue((int)task, out string? ret))
ret = taskTab[(int)task] = eventName;
return ret;
}
@ -5944,8 +5985,7 @@ namespace System.Diagnostics.Tracing
return "win:Receive";
}
string? ret;
if (opcodeTab == null || !opcodeTab.TryGetValue((int)opcode, out ret))
if (opcodeTab == null || !opcodeTab.TryGetValue((int)opcode, out string? ret))
{
ManifestError(SR.Format(SR.EventSource_UndefinedOpcode, opcode, eventName), true);
ret = null;
@ -6052,7 +6092,6 @@ namespace System.Diagnostics.Tracing
{
StringBuilder? stringBuilder = null; // We lazily create this
int writtenSoFar = 0;
int chIdx = -1;
for (int i = 0; ;)
{
if (i >= eventMessage.Length)
@ -6063,6 +6102,7 @@ namespace System.Diagnostics.Tracing
return stringBuilder.ToString();
}
int chIdx;
if (eventMessage[i] == '%')
{
// handle format message escaping character '%' by escaping it
@ -6125,8 +6165,7 @@ namespace System.Diagnostics.Tracing
private int TranslateIndexToManifestConvention(int idx, string evtName)
{
List<int>? byteArrArgIndices;
if (perEventByteArrayArgIndices.TryGetValue(evtName, out byteArrArgIndices))
if (perEventByteArrayArgIndices.TryGetValue(evtName, out List<int>? byteArrArgIndices))
{
foreach (int byArrIdx in byteArrArgIndices)
{

Просмотреть файл

@ -0,0 +1,49 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
namespace System.Diagnostics.Tracing
{
/// <summary>
/// NativeRuntimeEventSource is an EventSource that represents the ETW/EventPipe events emitted by the native runtime.
/// Most of NativeRuntimeEventSource is auto-generated by scripts/genRuntimeEventSources.py based on the contents of the Microsoft-Windows-DotNETRuntime provider.
/// </summary>
[EventSource(Guid = "5E5BB766-BBFC-5662-0548-1D44FAD9BB56", Name = "Microsoft-Windows-DotNETRuntime")]
internal sealed partial class NativeRuntimeEventSource : EventSource
{
internal const string EventSourceName = "Microsoft-Windows-DotNETRuntime";
internal static NativeRuntimeEventSource Log = new NativeRuntimeEventSource();
// The NativeRuntimeEventSource GUID is {5e5bb766-bbfc-5662-0548-1d44fad9bb56}
private NativeRuntimeEventSource() : base(new Guid(0x5e5bb766, 0xbbfc, 0x5662, 0x05, 0x48, 0x1d, 0x44, 0xfa, 0xd9, 0xbb, 0x56), EventSourceName) { }
/// <summary>
/// Dispatch a single event with the specified event ID and payload.
/// </summary>
/// <param name="eventID">The eventID corresponding to the event as defined in the auto-generated portion of the NativeRuntimeEventSource class.</param>
/// <param name="osThreadID">The thread ID of the operating system thread.</param>
/// <param name="timeStamp">The current timestamp.</param>
/// <param name="activityId">The ID of the current activity.</param>
/// <param name="childActivityId">The ID of the current child activity.</param>
/// <param name="payload">A span pointing to the data payload for the event.</param>
[NonEvent]
internal unsafe void ProcessEvent(uint eventID, uint osThreadID, DateTime timeStamp, Guid activityId, Guid childActivityId, ReadOnlySpan<byte> payload)
{
// Make sure the eventID is valid.
if (eventID >= m_eventData!.Length)
{
return;
}
// Decode the payload.
object[] decodedPayloadFields = EventPipePayloadDecoder.DecodePayload(ref m_eventData[eventID], payload);
WriteToAllListeners(
eventId: (int)eventID,
osThreadId: &osThreadID,
timeStamp: &timeStamp,
activityID: &activityId,
childActivityID: &childActivityId,
args: decodedPayloadFields);
}
}
}

Просмотреть файл

@ -0,0 +1,85 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.Threading;
namespace System.Diagnostics.Tracing
{
/// <summary>
/// RuntimeEventSource is an EventSource that represents events emitted by the managed runtime.
/// </summary>
[EventSource(Guid = "49592C0F-5A05-516D-AA4B-A64E02026C89", Name = "System.Runtime")]
internal sealed class RuntimeEventSource : EventSource
{
internal const string EventSourceName = "System.Runtime";
private static RuntimeEventSource? s_RuntimeEventSource;
private PollingCounter? _gcHeapSizeCounter;
private IncrementingPollingCounter? _gen0GCCounter;
private IncrementingPollingCounter? _gen1GCCounter;
private IncrementingPollingCounter? _gen2GCCounter;
private PollingCounter? _cpuTimeCounter;
private PollingCounter? _workingSetCounter;
private PollingCounter? _threadPoolThreadCounter;
private IncrementingPollingCounter? _monitorContentionCounter;
private PollingCounter? _threadPoolQueueCounter;
private IncrementingPollingCounter? _completedItemsCounter;
private IncrementingPollingCounter? _allocRateCounter;
private PollingCounter? _timerCounter;
#if !MONO
private IncrementingPollingCounter? _exceptionCounter;
private PollingCounter? _gcTimeCounter;
private PollingCounter? _gen0SizeCounter;
private PollingCounter? _gen1SizeCounter;
private PollingCounter? _gen2SizeCounter;
private PollingCounter? _lohSizeCounter;
private PollingCounter? _assemblyCounter;
#endif
public static void Initialize()
{
s_RuntimeEventSource = new RuntimeEventSource();
}
private RuntimeEventSource() : base(new Guid(0x49592C0F, 0x5A05, 0x516D, 0xAA, 0x4B, 0xA6, 0x4E, 0x02, 0x02, 0x6C, 0x89), EventSourceName, EventSourceSettings.EtwSelfDescribingEventFormat)
{
}
protected override void OnEventCommand(EventCommandEventArgs command)
{
if (command.Command == EventCommand.Enable)
{
// NOTE: These counters will NOT be disposed on disable command because we may be introducing
// a race condition by doing that. We still want to create these lazily so that we aren't adding
// overhead by at all times even when counters aren't enabled.
// On disable, PollingCounters will stop polling for values so it should be fine to leave them around.
_cpuTimeCounter ??= new PollingCounter("cpu-usage", this, () => RuntimeEventSourceHelper.GetCpuUsage()) { DisplayName = "CPU Usage", DisplayUnits = "%" };
_workingSetCounter ??= new PollingCounter("working-set", this, () => (double)(Environment.WorkingSet / 1000000)) { DisplayName = "Working Set", DisplayUnits = "MB" };
_gcHeapSizeCounter ??= new PollingCounter("gc-heap-size", this, () => (double)(GC.GetTotalMemory(false) / 1000000)) { DisplayName = "GC Heap Size", DisplayUnits = "MB" };
_gen0GCCounter ??= new IncrementingPollingCounter("gen-0-gc-count", this, () => GC.CollectionCount(0)) { DisplayName = "Gen 0 GC Count", DisplayRateTimeScale = new TimeSpan(0, 1, 0) };
_gen1GCCounter ??= new IncrementingPollingCounter("gen-1-gc-count", this, () => GC.CollectionCount(1)) { DisplayName = "Gen 1 GC Count", DisplayRateTimeScale = new TimeSpan(0, 1, 0) };
_gen2GCCounter ??= new IncrementingPollingCounter("gen-2-gc-count", this, () => GC.CollectionCount(2)) { DisplayName = "Gen 2 GC Count", DisplayRateTimeScale = new TimeSpan(0, 1, 0) };
_threadPoolThreadCounter ??= new PollingCounter("threadpool-thread-count", this, () => ThreadPool.ThreadCount) { DisplayName = "ThreadPool Thread Count" };
_monitorContentionCounter ??= new IncrementingPollingCounter("monitor-lock-contention-count", this, () => Monitor.LockContentionCount) { DisplayName = "Monitor Lock Contention Count", DisplayRateTimeScale = new TimeSpan(0, 0, 1) };
_threadPoolQueueCounter ??= new PollingCounter("threadpool-queue-length", this, () => ThreadPool.PendingWorkItemCount) { DisplayName = "ThreadPool Queue Length" };
_completedItemsCounter ??= new IncrementingPollingCounter("threadpool-completed-items-count", this, () => ThreadPool.CompletedWorkItemCount) { DisplayName = "ThreadPool Completed Work Item Count", DisplayRateTimeScale = new TimeSpan(0, 0, 1) };
_allocRateCounter ??= new IncrementingPollingCounter("alloc-rate", this, () => GC.GetTotalAllocatedBytes()) { DisplayName = "Allocation Rate", DisplayUnits = "B", DisplayRateTimeScale = new TimeSpan(0, 0, 1) };
_timerCounter ??= new PollingCounter("active-timer-count", this, () => Timer.ActiveCount) { DisplayName = "Number of Active Timers" };
#if !MONO
_exceptionCounter ??= new IncrementingPollingCounter("exception-count", this, () => Exception.GetExceptionCount()) { DisplayName = "Exception Count", DisplayRateTimeScale = new TimeSpan(0, 0, 1) };
_gcTimeCounter ??= new PollingCounter("time-in-gc", this, () => GC.GetLastGCPercentTimeInGC()) { DisplayName = "% Time in GC since last GC", DisplayUnits = "%" };
_gen0SizeCounter ??= new PollingCounter("gen-0-size", this, () => GC.GetGenerationSize(0)) { DisplayName = "Gen 0 Size", DisplayUnits = "B" };
_gen1SizeCounter ??= new PollingCounter("gen-1-size", this, () => GC.GetGenerationSize(1)) { DisplayName = "Gen 1 Size", DisplayUnits = "B" };
_gen2SizeCounter ??= new PollingCounter("gen-2-size", this, () => GC.GetGenerationSize(2)) { DisplayName = "Gen 2 Size", DisplayUnits = "B" };
_lohSizeCounter ??= new PollingCounter("loh-size", this, () => GC.GetGenerationSize(3)) { DisplayName = "LOH Size", DisplayUnits = "B" };
_assemblyCounter ??= new PollingCounter("assembly-count", this, () => System.Reflection.Assembly.GetAssemblyCount()) { DisplayName = "Number of Assemblies Loaded" };
#endif
}
}
}
}

Просмотреть файл

@ -0,0 +1,14 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
namespace System.Diagnostics.Tracing
{
internal static class RuntimeEventSourceHelper
{
private static Interop.Sys.ProcessCpuInformation s_cpuInfo;
internal static int GetCpuUsage() =>
Interop.Sys.GetCpuUtilization(ref s_cpuInfo) / Environment.ProcessorCount;
}
}

Просмотреть файл

@ -0,0 +1,49 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
namespace System.Diagnostics.Tracing
{
internal static class RuntimeEventSourceHelper
{
private static long s_prevProcUserTime = 0;
private static long s_prevProcKernelTime = 0;
private static long s_prevSystemUserTime = 0;
private static long s_prevSystemKernelTime = 0;
internal static int GetCpuUsage()
{
// Returns the current process' CPU usage as a percentage
int cpuUsage;
if (!Interop.Kernel32.GetProcessTimes(Interop.Kernel32.GetCurrentProcess(), out _, out _, out long procKernelTime, out long procUserTime))
{
return 0;
}
if (!Interop.Kernel32.GetSystemTimes(out _, out long systemUserTime, out long systemKernelTime))
{
return 0;
}
if (s_prevSystemUserTime == 0 && s_prevSystemKernelTime == 0) // These may be 0 when we report CPU usage for the first time, in which case we should just return 0.
{
cpuUsage = 0;
}
else
{
long totalProcTime = (procUserTime - s_prevProcUserTime) + (procKernelTime - s_prevProcKernelTime);
long totalSystemTime = (systemUserTime - s_prevSystemUserTime) + (systemKernelTime - s_prevSystemKernelTime);
cpuUsage = (int)(totalProcTime * 100 / totalSystemTime);
}
s_prevProcUserTime = procUserTime;
s_prevProcKernelTime = procKernelTime;
s_prevSystemUserTime = systemUserTime;
s_prevSystemKernelTime = systemKernelTime;
return cpuUsage;
}
}
}

Просмотреть файл

@ -0,0 +1,61 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.Threading;
namespace System.Diagnostics.Tracing
{
#if FEATURE_PERFTRACING
/// <summary>
/// Per-EventSource data structure for caching EventPipe EventHandles associated with TraceLogging events.
/// </summary>
internal sealed class TraceLoggingEventHandleTable
{
private const int DefaultLength = 10;
private IntPtr[] m_innerTable;
internal TraceLoggingEventHandleTable()
{
m_innerTable = new IntPtr[DefaultLength];
}
internal IntPtr this[int eventID]
{
get
{
IntPtr ret = IntPtr.Zero;
IntPtr[] innerTable = Volatile.Read(ref m_innerTable);
if (eventID >= 0 && eventID < innerTable.Length)
{
ret = innerTable[eventID];
}
return ret;
}
}
internal void SetEventHandle(int eventID, IntPtr eventHandle)
{
// Set operations must be serialized to ensure that re-size operations don't lose concurrent writes.
Debug.Assert(Monitor.IsEntered(this));
if (eventID >= m_innerTable.Length)
{
int newSize = m_innerTable.Length * 2;
if (newSize <= eventID)
{
newSize = eventID + 1;
}
IntPtr[] newTable = new IntPtr[newSize];
Array.Copy(m_innerTable, newTable, m_innerTable.Length);
Volatile.Write(ref m_innerTable, newTable);
}
m_innerTable[eventID] = eventHandle;
}
}
#endif
}

Просмотреть файл

@ -523,8 +523,7 @@ namespace System.Diagnostics.Tracing
fixed (EventSourceOptions* pOptions = &options)
{
EventDescriptor descriptor;
NameInfo? nameInfo = this.UpdateDescriptor(eventName, eventTypes, ref options, out descriptor);
NameInfo? nameInfo = this.UpdateDescriptor(eventName, eventTypes, ref options, out EventDescriptor descriptor);
if (nameInfo == null)
{
return;
@ -591,9 +590,8 @@ namespace System.Diagnostics.Tracing
{
fixed (EventSourceOptions* pOptions = &options)
{
EventDescriptor descriptor;
options.Opcode = options.IsOpcodeSet ? options.Opcode : GetOpcodeWithDefault(options.Opcode, eventName);
NameInfo? nameInfo = this.UpdateDescriptor(eventName, eventTypes, ref options, out descriptor);
NameInfo? nameInfo = this.UpdateDescriptor(eventName, eventTypes, ref options, out EventDescriptor descriptor);
if (nameInfo == null)
{
return;
@ -764,8 +762,7 @@ namespace System.Diagnostics.Tracing
if (m_traits[i].StartsWith("ETW_", StringComparison.Ordinal))
{
string etwTrait = m_traits[i].Substring(4);
byte traitNum;
if (!byte.TryParse(etwTrait, out traitNum))
if (!byte.TryParse(etwTrait, out byte traitNum))
{
if (etwTrait == "GROUP")
{

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше