diff options
author | Jan Kotas <jkotas@microsoft.com> | 2017-09-29 23:33:52 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-09-29 23:33:52 +0300 |
commit | 545d068c455e3def526cdac9d05354b5c3b0e84c (patch) | |
tree | e5223980e4a35cd1255e8705edfac7476e413677 | |
parent | a7f5b61879cb628980dac894a9c88217309c0e8c (diff) | |
parent | d354a5fabb06cfeacb9c4bccc77c67ee15ec144f (diff) |
Merge pull request #4638 from dotnet/master
Merge master to nmirror
157 files changed, 3964 insertions, 3350 deletions
@@ -1,10 +1,14 @@ # .NET Core Runtime (CoreRT) This repo contains the .NET Core runtime optimized for AOT compilation -| |Ubuntu 14.04 |Windows |Mac OS X | -|---------|:------:|:------:|:------:| -|**Debug**|[![Build status](https://ci.dot.net/job/dotnet_corert/job/master/job/debug_ubuntu/badge/icon)](https://ci.dot.net/job/dotnet_corert/job/master/job/debug_ubuntu/)|[![Build status](https://ci.dot.net/job/dotnet_corert/job/master/job/debug_windows_nt/badge/icon)](https://ci.dot.net/job/dotnet_corert/job/master/job/debug_windows_nt/)|[![Build Status](https://ci.dot.net/job/dotnet_corert/job/master/job/debug_osx10.12/badge/icon)](https://ci.dot.net/job/dotnet_corert/job/master/job/debug_osx10.12/)| -|**Release**|[![Build status](https://ci.dot.net/job/dotnet_corert/job/master/job/release_ubuntu/badge/icon)](https://ci.dot.net/job/dotnet_corert/job/master/job/release_ubuntu/)|[![Build status](https://ci.dot.net/job/dotnet_corert/job/master/job/release_windows_nt/badge/icon)](https://ci.dot.net/job/dotnet_corert/job/master/job/release_windows_nt/)|[![Build Status](https://ci.dot.net/job/dotnet_corert/job/master/job/release_osx10.12/badge/icon)](https://ci.dot.net/job/dotnet_corert/job/master/job/release_osx10.12/)| +## Platform Support + +This is a work in progress. The current state of platform support: +- Windows x64 w/ RyuJIT codegen: Simple ASP.NET apps compile and run with some [workarounds](https://github.com/dotnet/corert/issues/4444#issuecomment-328206168) +- MacOS and Linux x64 w/ RyuJIT codegen: Same as Windows, the libraries are less complete. +- Linux ARM w/ RyuJIT codegen: ["Hello world"](https://github.com/dotnet/coreclr/pull/14090#issuecomment-330933768) +- CppCodeGen (targets all platforms that support C++): Simple C# programs. The big missing features are [reflection](https://github.com/dotnet/corert/issues/2035), [garbage collection](https://github.com/dotnet/corert/issues/2033) and [exception handling](https://github.com/dotnet/corert/issues/910). +- WebAssembly: Early prototype that compiles and runs very trivial programs only. Many features are [not yet implemented](https://github.com/dotnet/corert/issues?q=is%3Aissue+is%3Aopen+label%3Aarch-wasm). ## How to Engage, Contribute and Provide Feedback Some of the best ways to contribute are to try things out, file bugs, and join in design conversations. @@ -35,6 +39,11 @@ This project has adopted the code of conduct defined by the [Contributor Covenan ## Related Projects There are many .NET related projects on GitHub. - The [.NET home repo](https://github.com/Microsoft/dotnet) links to 100s of .NET projects, from Microsoft and the community. -- The [.NET Core repo](https://github.com/dotnet/core) links to .NET Core related projects from Microsoft. - The [ASP.NET home repo](https://github.com/aspnet/home) is the best place to start learning about [ASP.NET Core](http://www.asp.net). -- dotnet.github.io is a good place to discover .NET Foundation projects. + +## Build Status + +| |Ubuntu 14.04 |Windows |Mac OS X | +|---------|:------:|:------:|:------:| +|**Debug**|[![Build status](https://ci.dot.net/job/dotnet_corert/job/master/job/debug_ubuntu/badge/icon)](https://ci.dot.net/job/dotnet_corert/job/master/job/debug_ubuntu/)|[![Build status](https://ci.dot.net/job/dotnet_corert/job/master/job/debug_windows_nt/badge/icon)](https://ci.dot.net/job/dotnet_corert/job/master/job/debug_windows_nt/)|[![Build Status](https://ci.dot.net/job/dotnet_corert/job/master/job/debug_osx10.12/badge/icon)](https://ci.dot.net/job/dotnet_corert/job/master/job/debug_osx10.12/)| +|**Release**|[![Build status](https://ci.dot.net/job/dotnet_corert/job/master/job/release_ubuntu/badge/icon)](https://ci.dot.net/job/dotnet_corert/job/master/job/release_ubuntu/)|[![Build status](https://ci.dot.net/job/dotnet_corert/job/master/job/release_windows_nt/badge/icon)](https://ci.dot.net/job/dotnet_corert/job/master/job/release_windows_nt/)|[![Build Status](https://ci.dot.net/job/dotnet_corert/job/master/job/release_osx10.12/badge/icon)](https://ci.dot.net/job/dotnet_corert/job/master/job/release_osx10.12/)| diff --git a/dependencies.props b/dependencies.props index 9a604db97..f9f3f1984 100644 --- a/dependencies.props +++ b/dependencies.props @@ -1,8 +1,9 @@ <Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <PropertyGroup> - <RyuJITVersion>2.1.0-preview2-25711-02</RyuJITVersion> + <RyuJITVersion>2.1.0-preview1-25727-05</RyuJITVersion> <ObjectWriterVersion>1.0.19-prerelease-00001</ObjectWriterVersion> - <CoreFXVersion>4.5.0-preview2-25621-02</CoreFXVersion> + <CoreFxVersion>4.5.0-preview1-25729-01</CoreFxVersion> + <CoreFxUapVersion>4.6.0-preview1-25729-01</CoreFxUapVersion> <MicrosoftNETCoreNativeVersion>2.0.0-beta-25021-03</MicrosoftNETCoreNativeVersion> <MicrosoftNETCoreAppPackageVersion>2.0.0-preview2-25312-01</MicrosoftNETCoreAppPackageVersion> <XunitNetcoreExtensionsVersion>1.0.1-prerelease-01616-05</XunitNetcoreExtensionsVersion> diff --git a/src/AotPackageReference/AotPackageReference.depproj b/src/AotPackageReference/AotPackageReference.depproj index c092478ac..883ebef82 100644 --- a/src/AotPackageReference/AotPackageReference.depproj +++ b/src/AotPackageReference/AotPackageReference.depproj @@ -19,7 +19,7 @@ <ItemGroup> <PackageReference Include="Microsoft.Private.CoreFx.UAP"> - <Version>$(CoreFxVersion)</Version> + <Version>$(CoreFxUapVersion)</Version> </PackageReference> </ItemGroup> diff --git a/src/Common/src/Interop/Windows/kernel32/Interop.CompletionPort.cs b/src/Common/src/Interop/Windows/kernel32/Interop.CompletionPort.cs new file mode 100644 index 000000000..326f0e9df --- /dev/null +++ b/src/Common/src/Interop/Windows/kernel32/Interop.CompletionPort.cs @@ -0,0 +1,23 @@ +// 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; +using System.Runtime.InteropServices; + +internal partial class Interop +{ + internal partial class Kernel32 + { + [DllImport(Libraries.Kernel32, SetLastError = true)] + internal static extern IntPtr CreateIoCompletionPort(IntPtr FileHandle, IntPtr ExistingCompletionPort, UIntPtr CompletionKey, int NumberOfConcurrentThreads); + + [DllImport(Libraries.Kernel32, SetLastError = true)] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool PostQueuedCompletionStatus(IntPtr CompletionPort, int dwNumberOfBytesTransferred, UIntPtr CompletionKey, IntPtr lpOverlapped); + + [DllImport(Libraries.Kernel32, SetLastError = true)] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool GetQueuedCompletionStatus(IntPtr CompletionPort, out int lpNumberOfBytes, out UIntPtr CompletionKey, out IntPtr lpOverlapped, int dwMilliseconds); + } +} diff --git a/src/Common/src/Interop/Windows/kernel32/Interop.ConditionVariable.cs b/src/Common/src/Interop/Windows/kernel32/Interop.ConditionVariable.cs new file mode 100644 index 000000000..0dcb7c094 --- /dev/null +++ b/src/Common/src/Interop/Windows/kernel32/Interop.ConditionVariable.cs @@ -0,0 +1,28 @@ +// 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; +using System.Runtime.InteropServices; + +internal partial class Interop +{ + internal partial class Kernel32 + { + [StructLayout(LayoutKind.Sequential)] + internal struct CONDITION_VARIABLE + { + private IntPtr Ptr; + } + + [DllImport(Libraries.Kernel32)] + internal static extern void InitializeConditionVariable(out CONDITION_VARIABLE ConditionVariable); + + [DllImport(Libraries.Kernel32, SetLastError = true)] + internal static extern void WakeConditionVariable(ref CONDITION_VARIABLE ConditionVariable); + + [DllImport(Libraries.Kernel32, SetLastError = true)] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool SleepConditionVariableCS(ref CONDITION_VARIABLE ConditionVariable, ref CRITICAL_SECTION CriticalSection, int dwMilliseconds); + } +} diff --git a/src/Common/src/Interop/Windows/kernel32/Interop.CriticalSection.cs b/src/Common/src/Interop/Windows/kernel32/Interop.CriticalSection.cs new file mode 100644 index 000000000..56278fba1 --- /dev/null +++ b/src/Common/src/Interop/Windows/kernel32/Interop.CriticalSection.cs @@ -0,0 +1,35 @@ +// 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; +using System.Runtime.InteropServices; + +internal partial class Interop +{ + internal partial class Kernel32 + { + [StructLayout(LayoutKind.Sequential)] + internal struct CRITICAL_SECTION + { + private IntPtr DebugInfo; + private int LockCount; + private int RecursionCount; + private IntPtr OwningThread; + private IntPtr LockSemaphore; + private UIntPtr SpinCount; + } + + [DllImport(Libraries.Kernel32)] + internal static extern void InitializeCriticalSection(out CRITICAL_SECTION lpCriticalSection); + + [DllImport(Libraries.Kernel32)] + internal static extern void EnterCriticalSection(ref CRITICAL_SECTION lpCriticalSection); + + [DllImport(Libraries.Kernel32)] + internal static extern void LeaveCriticalSection(ref CRITICAL_SECTION lpCriticalSection); + + [DllImport(Libraries.Kernel32)] + internal static extern void DeleteCriticalSection(ref CRITICAL_SECTION lpCriticalSection); + } +} diff --git a/src/Common/src/Interop/Windows/kernel32/Interop.GetSystemTimes.cs b/src/Common/src/Interop/Windows/kernel32/Interop.GetSystemTimes.cs new file mode 100644 index 000000000..892948dd1 --- /dev/null +++ b/src/Common/src/Interop/Windows/kernel32/Interop.GetSystemTimes.cs @@ -0,0 +1,16 @@ +// 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; +using System.Runtime.InteropServices; + +internal partial class Interop +{ + internal partial class Kernel32 + { + [DllImport(Libraries.Kernel32, SetLastError = true)] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool GetSystemTimes(out ulong idleTime, out ulong kernelTime, out ulong userTime); + } +} diff --git a/src/Common/src/Interop/Windows/kernel32/Interop.QueryPerformance.cs b/src/Common/src/Interop/Windows/kernel32/Interop.QueryPerformance.cs new file mode 100644 index 000000000..8486c65fb --- /dev/null +++ b/src/Common/src/Interop/Windows/kernel32/Interop.QueryPerformance.cs @@ -0,0 +1,17 @@ +// 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.Runtime.InteropServices; + +internal partial class Interop +{ + internal partial class Kernel32 + { + [DllImport(Libraries.Kernel32)] + internal static extern bool QueryPerformanceCounter(out ulong value); + + [DllImport(Libraries.Kernel32)] + internal static extern bool QueryPerformanceFrequency(out ulong value); + } +}
\ No newline at end of file diff --git a/src/Framework/Framework-uapaot.depproj b/src/Framework/Framework-uapaot.depproj index 7488de4de..ce5b36640 100644 --- a/src/Framework/Framework-uapaot.depproj +++ b/src/Framework/Framework-uapaot.depproj @@ -14,7 +14,7 @@ <ItemGroup> <PackageReference Include="Microsoft.Private.CoreFx.UAP"> - <Version>$(CoreFxVersion)</Version> + <Version>$(CoreFxUapVersion)</Version> </PackageReference> </ItemGroup> diff --git a/src/Framework/Framework.depproj b/src/Framework/Framework.depproj index 4d03e4fc0..48cb735c4 100644 --- a/src/Framework/Framework.depproj +++ b/src/Framework/Framework.depproj @@ -26,14 +26,6 @@ <PackageReference Include="Microsoft.Private.CoreFx.NETCoreApp"> <Version>$(CoreFxVersion)</Version> </PackageReference> - - <!-- TODO: These packages should be comming via regular references --> - <PackageReference Include="System.Memory"> - <Version>$(CoreFxVersion)</Version> - </PackageReference> - <PackageReference Include="System.Runtime.CompilerServices.Unsafe"> - <Version>$(CoreFxVersion)</Version> - </PackageReference> </ItemGroup> <ItemGroup> diff --git a/src/ILCompiler.WebAssembly/src/CodeGen/EvaluationStack.cs b/src/ILCompiler.WebAssembly/src/CodeGen/EvaluationStack.cs index d0dafa190..3a6267d96 100644 --- a/src/ILCompiler.WebAssembly/src/CodeGen/EvaluationStack.cs +++ b/src/ILCompiler.WebAssembly/src/CodeGen/EvaluationStack.cs @@ -135,7 +135,11 @@ namespace Internal.IL /// <returns>Element formerly at the top of the stack</returns> public T Pop() { - Debug.Assert(_top > 0, "Stack is not empty"); +#if DEBUG // This should eventually be an assert, but while many opcodes are unimplemented, we can just throw to avoid + // killing the process + if(_top <= 0) + throw new Exception("Stack is not empty"); +#endif //DEBUG return _stack[--_top]; } diff --git a/src/ILCompiler.WebAssembly/src/CodeGen/ILToWebAssemblyImporter.cs b/src/ILCompiler.WebAssembly/src/CodeGen/ILToWebAssemblyImporter.cs index 502dd0a15..6ac20b86a 100644 --- a/src/ILCompiler.WebAssembly/src/CodeGen/ILToWebAssemblyImporter.cs +++ b/src/ILCompiler.WebAssembly/src/CodeGen/ILToWebAssemblyImporter.cs @@ -92,7 +92,31 @@ namespace Internal.IL public void Import() { FindBasicBlocks(); - ImportBasicBlocks(); + + try + { + ImportBasicBlocks(); + } + catch + { + // Change the function body to trap + foreach (BasicBlock block in _basicBlocks) + { + if (block != null && block.Block.Pointer != IntPtr.Zero) + { + LLVM.DeleteBasicBlock(block.Block); + } + } + LLVMBasicBlockRef trapBlock = LLVM.AppendBasicBlock(_llvmFunction, "Trap"); + LLVM.PositionBuilderAtEnd(_builder, trapBlock); + if (TrapFunction.Pointer == IntPtr.Zero) + { + TrapFunction = LLVM.AddFunction(Module, "llvm.trap", LLVM.FunctionType(LLVM.VoidType(), Array.Empty<LLVMTypeRef>(), false)); + } + LLVM.BuildCall(_builder, TrapFunction, Array.Empty<LLVMValueRef>(), String.Empty); + LLVM.BuildRetVoid(_builder); + throw; + } } private void GenerateProlog() @@ -243,7 +267,7 @@ namespace Internal.IL isFirstBlock = true; } _curBasicBlock = GetLLVMBasicBlockForBlock(basicBlock); - + LLVM.PositionBuilderAtEnd(_builder, _curBasicBlock); if(isFirstBlock) @@ -304,7 +328,7 @@ namespace Internal.IL new LLVMValueRef[] { LLVM.ConstInt(LLVM.Int32Type(), (uint)(varBase + varOffset), LLVMMisc.False) }, String.Empty); var typedLoadLocation = LLVM.BuildPointerCast(_builder, loadLocation, LLVM.PointerType(valueType, 0), String.Empty); - var loadResult = LLVM.BuildLoad(_builder, typedLoadLocation, String.Empty); + var loadResult = LLVM.BuildLoad(_builder, typedLoadLocation, "ld" + (argument ? "arg" : "loc") + index + "_"); PushExpression(GetStackValueKind(type), String.Empty, loadResult, type); } @@ -368,7 +392,28 @@ namespace Internal.IL private void ImportStoreHelper(LLVMValueRef toStore, LLVMTypeRef valueType, LLVMValueRef basePtr, uint offset) { - var typedToStore = LLVM.BuildIntCast(_builder, toStore, valueType, String.Empty); + LLVMTypeKind toStoreKind = LLVM.GetTypeKind(LLVM.TypeOf(toStore)); + LLVMTypeKind valueTypeKind = LLVM.GetTypeKind(valueType); + + LLVMValueRef typedToStore = toStore; + if(toStoreKind == LLVMTypeKind.LLVMPointerTypeKind && valueTypeKind == LLVMTypeKind.LLVMPointerTypeKind) + { + typedToStore = LLVM.BuildPointerCast(_builder, toStore, valueType, "storePtrCast"); + } + else if(toStoreKind == LLVMTypeKind.LLVMPointerTypeKind && valueTypeKind != LLVMTypeKind.LLVMPointerTypeKind) + { + typedToStore = LLVM.BuildPtrToInt(_builder, toStore, valueType, "storeIntCast"); + } + else if (toStoreKind != LLVMTypeKind.LLVMPointerTypeKind && valueTypeKind == LLVMTypeKind.LLVMPointerTypeKind) + { + typedToStore = LLVM.BuildIntToPtr(_builder, toStore, valueType, "storePtrCast"); + } + else + { + Debug.Assert(toStoreKind != LLVMTypeKind.LLVMPointerTypeKind && valueTypeKind != LLVMTypeKind.LLVMPointerTypeKind); + typedToStore = LLVM.BuildIntCast(_builder, toStore, valueType, "storeIntCast"); + } + var storeLocation = LLVM.BuildGEP(_builder, basePtr, new LLVMValueRef[] { LLVM.ConstInt(LLVM.Int32Type(), offset, LLVMMisc.False) }, String.Empty); @@ -516,6 +561,7 @@ namespace Internal.IL private void ImportLoadNull() { + _stack.Push(new ExpressionEntry(StackValueKind.ObjRef, "null", LLVM.ConstInt(LLVM.Int32Type(), 0, LLVMMisc.False))); } private void ImportReturn() @@ -534,6 +580,15 @@ namespace Internal.IL private void ImportCall(ILOpcode opcode, int token) { MethodDesc callee = (MethodDesc)_methodIL.GetObject(token); + + if (callee.IsIntrinsic) + { + if (ImportIntrinsicCall(callee)) + { + return; + } + } + if (callee.IsPInvoke) { ImportRawPInvoke(callee); @@ -548,6 +603,35 @@ namespace Internal.IL HandleCall(callee); } + /// <summary> + /// Implements intrinsic methods instread of calling them + /// </summary> + /// <returns>True if the method was implemented</returns> + private bool ImportIntrinsicCall(MethodDesc method) + { + Debug.Assert(method.IsIntrinsic); + + if (!(method.OwningType is MetadataType metadataType)) + { + return false; + } + + switch (method.Name) + { + // Workaround for not being able to build a WASM version of CoreLib. This method + // would return the x64 size, which is too large for WASM + case "get_OffsetToStringData": + if (metadataType.Name == "RuntimeHelpers" && metadataType.Namespace == "System.Runtime.CompilerServices") + { + _stack.Push(new Int32ConstantEntry(8, _method.Context.GetWellKnownType(WellKnownType.Int32))); + return true; + } + break; + } + + return false; + } + private void HandleCall(MethodDesc callee) { AddMethodReference(callee); @@ -570,9 +654,16 @@ namespace Internal.IL // argument offset uint argOffset = 0; - for (int index = callee.Signature.Length -1; index >=0; index--) + // The last argument is the top of the stack. We need to reverse them and store starting at the first argument + LLVMValueRef[] argumentValues = new LLVMValueRef[callee.Signature.Length]; + for(int i = 0; i < argumentValues.Length; i++) { - LLVMValueRef toStore = _stack.Pop().LLVMValue; + argumentValues[argumentValues.Length - i - 1] = _stack.Pop().LLVMValue; + } + + for (int index = 0; index < argumentValues.Length; index++) + { + LLVMValueRef toStore = argumentValues[index]; LLVMTypeRef valueType = GetLLVMTypeForTypeDesc(callee.Signature[index]); @@ -585,11 +676,12 @@ namespace Internal.IL castShadowStack, castReturnAddress}, string.Empty); - - var loadResult = LLVM.BuildLoad(_builder, castReturnAddress, String.Empty); if (!callee.Signature.ReturnType.IsVoid) { + LLVMTypeRef returnLLVMType = GetLLVMTypeForTypeDesc(callee.Signature.ReturnType); + LLVMValueRef returnLLVMPointer = LLVM.BuildPointerCast(_builder, returnAddress, LLVM.PointerType(returnLLVMType, 0), String.Empty); + LLVMValueRef loadResult = LLVM.BuildLoad(_builder, returnLLVMPointer, String.Empty); PushExpression(GetStackValueKind(callee.Signature.ReturnType), String.Empty, loadResult, callee.Signature.ReturnType); } } @@ -623,13 +715,23 @@ namespace Internal.IL LLVMValueRef[] arguments = new LLVMValueRef[method.Signature.Length]; for(int i = 0; i < arguments.Length; i++) { + LLVMValueRef argValue = _stack.Pop().LLVMValue; + // Arguments are reversed on the stack - arguments[arguments.Length - i - 1] =_stack.Pop().LLVMValue; + // Coerce pointers to the native type + TypeDesc signatureType = method.Signature[arguments.Length - i - 1]; + LLVMValueRef typedValue = argValue; + if (signatureType.IsPointer) + { + LLVMTypeRef signatureLlvmType = GetLLVMTypeForTypeDesc(signatureType); + typedValue = LLVM.BuildPointerCast(_builder, argValue, signatureLlvmType, String.Empty); + } + arguments[arguments.Length - i - 1] = typedValue; } var returnValue = LLVM.BuildCall(_builder, nativeFunc, arguments, "call"); - // todo void returns + // TODO: void returns PushExpression(GetStackValueKind(method.Signature.ReturnType), String.Empty, returnValue, method.Signature.ReturnType); } @@ -675,15 +777,23 @@ namespace Internal.IL { LLVMValueRef condition; - if (opcode == ILOpcode.brfalse) + if (opcode == ILOpcode.brfalse || opcode == ILOpcode.brtrue) { var op = _stack.Pop(); - condition = LLVM.BuildICmp(_builder, LLVMIntPredicate.LLVMIntEQ, op.LLVMValue, LLVM.ConstInt(LLVM.Int32Type(), 0, LLVMMisc.False), "brfalse"); - } - else if (opcode == ILOpcode.brtrue) - { - var op = _stack.Pop(); - condition = LLVM.BuildICmp(_builder, LLVMIntPredicate.LLVMIntNE, op.LLVMValue, LLVM.ConstInt(LLVM.Int32Type(), 0, LLVMMisc.False), "brfalse"); + LLVMValueRef value = op.LLVMValue; + if (LLVM.GetTypeKind(LLVM.TypeOf(value)) == LLVMTypeKind.LLVMPointerTypeKind) + { + value = LLVM.BuildPtrToInt(_builder, value, LLVM.Int32Type(), String.Empty); + } + + if (opcode == ILOpcode.brfalse) + { + condition = LLVM.BuildICmp(_builder, LLVMIntPredicate.LLVMIntEQ, value, LLVM.ConstInt(LLVM.TypeOf(value), 0, LLVMMisc.False), "brfalse"); + } + else + { + condition = LLVM.BuildICmp(_builder, LLVMIntPredicate.LLVMIntNE, value, LLVM.ConstInt(LLVM.TypeOf(value), 0, LLVMMisc.False), "brtrue"); + } } else { @@ -758,6 +868,22 @@ namespace Internal.IL private void ImportLoadIndirect(TypeDesc type) { + StackEntry pointer = _stack.Pop(); + LLVMTypeRef loadType = GetLLVMTypeForTypeDesc(type); + LLVMTypeRef pointerType = LLVM.PointerType(loadType, 0); + + LLVMValueRef typedPointer; + if (LLVM.GetTypeKind(LLVM.TypeOf(pointer.LLVMValue)) != LLVMTypeKind.LLVMPointerTypeKind) + { + typedPointer = LLVM.BuildIntToPtr(_builder, pointer.LLVMValue, pointerType, "ldindintptrcast"); + } + else + { + typedPointer = LLVM.BuildPointerCast(_builder, pointer.LLVMValue, pointerType, "ldindptrcast"); + } + + LLVMValueRef load = LLVM.BuildLoad(_builder, typedPointer, "ldind"); + PushExpression(GetStackValueKind(type), "ldlind", load, type); } private void ImportStoreIndirect(int token) @@ -800,7 +926,22 @@ namespace Internal.IL switch (opcode) { case ILOpcode.add: - result = LLVM.BuildAdd(_builder, op1.LLVMValue, op2.LLVMValue, "add"); + // TODO: converting these to ints should also happen for sub and some other operations + LLVMValueRef left = op1.LLVMValue; + LLVMValueRef right = op2.LLVMValue; + + if (kind == StackValueKind.NativeInt || kind == StackValueKind.ObjRef || kind == StackValueKind.ByRef) + { + if(LLVM.GetTypeKind(LLVM.TypeOf(left)) == LLVMTypeKind.LLVMPointerTypeKind) + { + left = LLVM.BuildPtrToInt(_builder, left, LLVM.Int32Type(), "lptrasint"); + } + if (LLVM.GetTypeKind(LLVM.TypeOf(right)) == LLVMTypeKind.LLVMPointerTypeKind) + { + right = LLVM.BuildPtrToInt(_builder, right, LLVM.Int32Type(), "rptrasint"); + } + } + result = LLVM.BuildAdd(_builder, left, right, "add"); break; case ILOpcode.sub: result = LLVM.BuildSub(_builder, op1.LLVMValue, op2.LLVMValue, "sub"); @@ -876,19 +1017,19 @@ namespace Internal.IL switch (opcode) { case ILOpcode.ceq: - result = LLVM.BuildICmp(_builder, LLVMIntPredicate.LLVMIntEQ, op1.LLVMValue, op2.LLVMValue, "ceq"); + result = LLVM.BuildICmp(_builder, LLVMIntPredicate.LLVMIntEQ, op2.LLVMValue, op1.LLVMValue, "ceq"); break; case ILOpcode.cgt: - result = LLVM.BuildICmp(_builder, LLVMIntPredicate.LLVMIntSGT, op1.LLVMValue, op2.LLVMValue, "cgt"); + result = LLVM.BuildICmp(_builder, LLVMIntPredicate.LLVMIntSGT, op2.LLVMValue, op1.LLVMValue, "cgt"); break; case ILOpcode.clt: - result = LLVM.BuildICmp(_builder, LLVMIntPredicate.LLVMIntSLT, op1.LLVMValue, op2.LLVMValue, "clt"); + result = LLVM.BuildICmp(_builder, LLVMIntPredicate.LLVMIntSLT, op2.LLVMValue, op1.LLVMValue, "clt"); break; case ILOpcode.cgt_un: - result = LLVM.BuildICmp(_builder, LLVMIntPredicate.LLVMIntUGT, op1.LLVMValue, op2.LLVMValue, "cgt_un"); + result = LLVM.BuildICmp(_builder, LLVMIntPredicate.LLVMIntUGT, op2.LLVMValue, op1.LLVMValue, "cgt_un"); break; case ILOpcode.clt_un: - result = LLVM.BuildICmp(_builder, LLVMIntPredicate.LLVMIntULT, op1.LLVMValue, op2.LLVMValue, "clt_un"); + result = LLVM.BuildICmp(_builder, LLVMIntPredicate.LLVMIntULT, op2.LLVMValue, op1.LLVMValue, "clt_un"); break; default: throw new NotSupportedException(); // unreachable @@ -1053,11 +1194,19 @@ namespace Internal.IL StackEntry valueEntry = _stack.Pop(); StackEntry objectEntry = _stack.Pop(); + LLVMValueRef value = valueEntry.LLVMValue; + + // All integers are int32 on the stack, but need to be resized to fit fields + if(valueEntry.Kind == StackValueKind.Int32) + { + value = LLVM.BuildIntCast(_builder, value, GetLLVMTypeForTypeDesc(field.FieldType), "intfieldcast"); + } + var untypedObjectPointer = LLVM.BuildPointerCast(_builder, objectEntry.LLVMValue, LLVM.PointerType(LLVMTypeRef.Int8Type(), 0), "stfld"); var storeLocation = LLVM.BuildGEP(_builder, untypedObjectPointer, new LLVMValueRef[] { LLVM.ConstInt(LLVM.Int32Type(), (ulong)field.Offset.AsInt, LLVMMisc.False) }, "stfld"); - var typedStoreLocation = LLVM.BuildPointerCast(_builder, storeLocation, LLVM.PointerType(GetLLVMTypeForTypeDesc(valueEntry.Type), 0), "stfld"); - LLVM.BuildStore(_builder, valueEntry.LLVMValue, typedStoreLocation); + var typedStoreLocation = LLVM.BuildPointerCast(_builder, storeLocation, LLVM.PointerType(GetLLVMTypeForTypeDesc(field.FieldType), 0), "stfld"); + LLVM.BuildStore(_builder, value, typedStoreLocation); } // Loads symbol address. Address is represented as a i32* diff --git a/src/ILCompiler.WebAssembly/src/CodeGen/ILToWebAssemblyImporter_Statics.cs b/src/ILCompiler.WebAssembly/src/CodeGen/ILToWebAssemblyImporter_Statics.cs index b26b0de0d..32961282e 100644 --- a/src/ILCompiler.WebAssembly/src/CodeGen/ILToWebAssemblyImporter_Statics.cs +++ b/src/ILCompiler.WebAssembly/src/CodeGen/ILToWebAssemblyImporter_Statics.cs @@ -13,6 +13,7 @@ using ILCompiler; using ILCompiler.Compiler.CppCodeGen; using ILCompiler.DependencyAnalysis; +using LLVMSharp; namespace Internal.IL { @@ -66,7 +67,6 @@ namespace Internal.IL ilImporter.Import(); methodCodeNodeNeedingCode.CompilationCompleted = true; - methodCodeNodeNeedingCode.SetDependencies(ilImporter.GetDependencies()); } catch (Exception e) { @@ -77,8 +77,13 @@ namespace Internal.IL //throw new NotImplementedException(); //methodCodeNodeNeedingCode.SetCode(sb.ToString(), Array.Empty<Object>()); } + + // Ensure dependencies show up regardless of exceptions to avoid breaking LLVM + methodCodeNodeNeedingCode.SetDependencies(ilImporter.GetDependencies()); } + static LLVMValueRef TrapFunction = default(LLVMValueRef); + private static IEnumerable<string> GetParameterNamesForMethod(MethodDesc method) { // TODO: The uses of this method need revision. The right way to get to this info is from diff --git a/src/ILCompiler.WebAssembly/src/CodeGen/WebAssemblyObjectWriter.cs b/src/ILCompiler.WebAssembly/src/CodeGen/WebAssemblyObjectWriter.cs index 004f25bae..2d707cf3c 100644 --- a/src/ILCompiler.WebAssembly/src/CodeGen/WebAssemblyObjectWriter.cs +++ b/src/ILCompiler.WebAssembly/src/CodeGen/WebAssemblyObjectWriter.cs @@ -178,9 +178,12 @@ namespace ILCompiler.DependencyAnalysis } EmitNativeMain(); - LLVM.VerifyModule(Module, LLVMVerifierFailureAction.LLVMPrintMessageAction, out IntPtr unused); LLVM.WriteBitcodeToFile(Module, _objectFilePath); - LLVM.DumpModule(Module); +#if DEBUG + LLVM.PrintModuleToFile(Module, Path.ChangeExtension(_objectFilePath, ".txt"), out IntPtr unused2); +#endif //DEBUG + LLVM.VerifyModule(Module, LLVMVerifierFailureAction.LLVMAbortProcessAction, out IntPtr unused); + //throw new NotImplementedException(); // This function isn't complete } @@ -416,7 +419,6 @@ namespace ILCompiler.DependencyAnalysis EmitBlob(new byte[this._nodeFactory.Target.PointerSize]); if (relocType == RelocType.IMAGE_REL_BASED_REL32) { - Console.WriteLine("REL BASED RELOC"); return this._nodeFactory.Target.PointerSize; } diff --git a/src/ILVerify/src/ILImporter.Verify.cs b/src/ILVerify/src/ILImporter.Verify.cs index 3b94fd25c..fd8d8e3e1 100644 --- a/src/ILVerify/src/ILImporter.Verify.cs +++ b/src/ILVerify/src/ILImporter.Verify.cs @@ -393,18 +393,28 @@ namespace Internal.IL VerificationError(VerifierError.StackUnexpected, src, dst); } - void CheckIsValidBranchTarget(BasicBlock src, BasicBlock target) + bool IsValidBranchTarget(BasicBlock src, BasicBlock target, bool reportErrors = true) { + bool isValid = true; + if (src.TryIndex != target.TryIndex) { if (src.TryIndex == null) { // Branching to first instruction of try-block is valid if (target.StartOffset != _exceptionRegions[(int)target.TryIndex].ILRegion.TryOffset || !IsDirectChildRegion(src, target)) - VerificationError(VerifierError.BranchIntoTry); + { + if (reportErrors) + VerificationError(VerifierError.BranchIntoTry); + isValid = false; + } } else if (target.TryIndex == null) - VerificationError(VerifierError.BranchOutOfTry); + { + if (reportErrors) + VerificationError(VerifierError.BranchOutOfTry); + isValid = false; + } else { ref var srcRegion = ref _exceptionRegions[(int)src.TryIndex].ILRegion; @@ -415,46 +425,88 @@ namespace Internal.IL { // Only branching to first instruction of try-block is valid if (target.StartOffset != targetRegion.TryOffset || !IsDirectChildRegion(src, target)) - VerificationError(VerifierError.BranchIntoTry); + { + if (reportErrors) + VerificationError(VerifierError.BranchIntoTry); + isValid = false; + } } else - VerificationError(VerifierError.BranchOutOfTry); + { + if (reportErrors) + VerificationError(VerifierError.BranchOutOfTry); + isValid = false; + } } } if (src.FilterIndex != target.FilterIndex) { if (src.FilterIndex == null) - VerificationError(VerifierError.BranchIntoFilter); + { + if (reportErrors) + VerificationError(VerifierError.BranchIntoFilter); + isValid = false; + } else if (target.HandlerIndex == null) - VerificationError(VerifierError.BranchOutOfFilter); + { + if (reportErrors) + VerificationError(VerifierError.BranchOutOfFilter); + isValid = false; + } else { ref var srcRegion = ref _exceptionRegions[(int)src.FilterIndex].ILRegion; ref var targetRegion = ref _exceptionRegions[(int)target.FilterIndex].ILRegion; if (srcRegion.FilterOffset <= targetRegion.FilterOffset) - VerificationError(VerifierError.BranchIntoFilter); + { + if (reportErrors) + VerificationError(VerifierError.BranchIntoFilter); + isValid = false; + } else - VerificationError(VerifierError.BranchOutOfFilter); + { + if (reportErrors) + VerificationError(VerifierError.BranchOutOfFilter); + isValid = false; + } } } if (src.HandlerIndex != target.HandlerIndex) { if (src.HandlerIndex == null) - VerificationError(VerifierError.BranchIntoHandler); + { + if (reportErrors) + VerificationError(VerifierError.BranchIntoHandler); + isValid = false; + } else if (target.HandlerIndex == null) - VerificationError(VerifierError.BranchOutOfHandler); + { + if (reportErrors) + VerificationError(VerifierError.BranchOutOfHandler); + isValid = false; + } else { ref var srcRegion = ref _exceptionRegions[(int)src.HandlerIndex].ILRegion; ref var targetRegion = ref _exceptionRegions[(int)target.HandlerIndex].ILRegion; if (srcRegion.HandlerOffset <= targetRegion.HandlerOffset) - VerificationError(VerifierError.BranchIntoHandler); + { + if (reportErrors) + VerificationError(VerifierError.BranchIntoHandler); + isValid = false; + } else - VerificationError(VerifierError.BranchOutOfHandler); + { + if (reportErrors) + VerificationError(VerifierError.BranchOutOfHandler); + isValid = false; + } } } + + return isValid; } /// <summary> @@ -1210,6 +1262,9 @@ namespace Internal.IL void ImportFallthrough(BasicBlock next) { + if (!IsValidBranchTarget(_currentBasicBlock, next)) + return; + StackValue[] entryStack = next.EntryStack; if (entryStack != null) @@ -1262,7 +1317,6 @@ namespace Internal.IL for (int i = 0; i < jmpDelta.Length; i++) { BasicBlock target = _basicBlocks[jmpBase + jmpDelta[i]]; - CheckIsValidBranchTarget(_currentBasicBlock, target); ImportFallthrough(target); } @@ -1272,8 +1326,6 @@ namespace Internal.IL void ImportBranch(ILOpcode opcode, BasicBlock target, BasicBlock fallthrough) { - CheckIsValidBranchTarget(_currentBasicBlock, target); - switch (opcode) { case ILOpcode.br: diff --git a/src/ILVerify/tests/ILTests/BranchingTests.il b/src/ILVerify/tests/ILTests/BranchingTests.il index 199ffae88..abd4b7ba7 100644 --- a/src/ILVerify/tests/ILTests/BranchingTests.il +++ b/src/ILVerify/tests/ILTests/BranchingTests.il @@ -571,8 +571,7 @@ lbl_ret: ret } - /* These tests currently yield an assert (see issue #4537), due to a non-null entry stack to a catch/finally block; uncomment once fixed - .method static public hidebysig void Branching.FromTryIntoCatch_Invalid_BranchOutOfTry.BranchIntoFilter() cil managed + .method static public hidebysig void Branching.FromTryIntoCatch_Invalid_BranchOutOfTry.BranchIntoHandler() cil managed { .maxstack 2 @@ -594,8 +593,27 @@ lbl_ret: ret } - */ - /* + + .method static public hidebysig void Branching.FromTryIntoFilter_Invalid_BranchOutOfTry.BranchIntoFilter() cil managed + { + .try + { + br.s lbl_filter + } + filter + { + lbl_filter: pop + ldc.i4.0 + endfilter + } + { + pop + leave.s lbl_ret + } + + lbl_ret: ret + } + .method static public hidebysig void Branching.FromTryIntoFinally_Invalid_BranchOutOfTry.BranchIntoHandler() cil managed { .maxstack 2 @@ -617,7 +635,6 @@ lbl_ret: ret } - */ .method static public hidebysig void Branching.FromTryIntoOtherTryStart_Invalid_BranchOutOfTry() cil managed { diff --git a/src/JitInterface/src/CorInfoBase.cs b/src/JitInterface/src/CorInfoBase.cs index dd63457c6..d44d0599c 100644 --- a/src/JitInterface/src/CorInfoBase.cs +++ b/src/JitInterface/src/CorInfoBase.cs @@ -38,6 +38,8 @@ namespace Internal.JitInterface [UnmanagedFunctionPointerAttribute(CallingConvention.StdCall)] delegate CORINFO_METHOD_STRUCT_* __resolveVirtualMethod(IntPtr _this, IntPtr* ppException, CORINFO_METHOD_STRUCT_* virtualMethod, CORINFO_CLASS_STRUCT_* implementingClass, CORINFO_CONTEXT_STRUCT* ownerType); [UnmanagedFunctionPointerAttribute(CallingConvention.StdCall)] + delegate CORINFO_CLASS_STRUCT_* __getDefaultEqualityComparerClass(IntPtr _this, IntPtr* ppException, CORINFO_CLASS_STRUCT_* elemType); + [UnmanagedFunctionPointerAttribute(CallingConvention.StdCall)] delegate void __expandRawHandleIntrinsic(IntPtr _this, IntPtr* ppException, ref CORINFO_RESOLVED_TOKEN pResolvedToken, ref CORINFO_GENERICHANDLE_RESULT pResult); [UnmanagedFunctionPointerAttribute(CallingConvention.StdCall)] delegate CorInfoIntrinsics __getIntrinsicID(IntPtr _this, IntPtr* ppException, CORINFO_METHOD_STRUCT_* method, [MarshalAs(UnmanagedType.U1)] ref bool pMustExpand); @@ -520,6 +522,20 @@ namespace Internal.JitInterface } } + static CORINFO_CLASS_STRUCT_* _getDefaultEqualityComparerClass(IntPtr thisHandle, IntPtr* ppException, CORINFO_CLASS_STRUCT_* elemType) + { + var _this = GetThis(thisHandle); + try + { + return _this.getDefaultEqualityComparerClass(elemType); + } + catch (Exception ex) + { + *ppException = _this.AllocException(ex); + return default(CORINFO_CLASS_STRUCT_*); + } + } + static void _expandRawHandleIntrinsic(IntPtr thisHandle, IntPtr* ppException, ref CORINFO_RESOLVED_TOKEN pResolvedToken, ref CORINFO_GENERICHANDLE_RESULT pResult) { var _this = GetThis(thisHandle); @@ -2625,8 +2641,8 @@ namespace Internal.JitInterface static IntPtr GetUnmanagedCallbacks(out Object keepAlive) { - IntPtr * callbacks = (IntPtr *)Marshal.AllocCoTaskMem(sizeof(IntPtr) * 166); - Object[] delegates = new Object[166]; + IntPtr * callbacks = (IntPtr *)Marshal.AllocCoTaskMem(sizeof(IntPtr) * 167); + Object[] delegates = new Object[167]; var d0 = new __getMethodAttribs(_getMethodAttribs); callbacks[0] = Marshal.GetFunctionPointerForDelegate(d0); @@ -2667,465 +2683,468 @@ namespace Internal.JitInterface var d12 = new __resolveVirtualMethod(_resolveVirtualMethod); callbacks[12] = Marshal.GetFunctionPointerForDelegate(d12); delegates[12] = d12; - var d13 = new __expandRawHandleIntrinsic(_expandRawHandleIntrinsic); + var d13 = new __getDefaultEqualityComparerClass(_getDefaultEqualityComparerClass); callbacks[13] = Marshal.GetFunctionPointerForDelegate(d13); delegates[13] = d13; - var d14 = new __getIntrinsicID(_getIntrinsicID); + var d14 = new __expandRawHandleIntrinsic(_expandRawHandleIntrinsic); callbacks[14] = Marshal.GetFunctionPointerForDelegate(d14); delegates[14] = d14; - var d15 = new __isInSIMDModule(_isInSIMDModule); + var d15 = new __getIntrinsicID(_getIntrinsicID); callbacks[15] = Marshal.GetFunctionPointerForDelegate(d15); delegates[15] = d15; - var d16 = new __getUnmanagedCallConv(_getUnmanagedCallConv); + var d16 = new __isInSIMDModule(_isInSIMDModule); callbacks[16] = Marshal.GetFunctionPointerForDelegate(d16); delegates[16] = d16; - var d17 = new __pInvokeMarshalingRequired(_pInvokeMarshalingRequired); + var d17 = new __getUnmanagedCallConv(_getUnmanagedCallConv); callbacks[17] = Marshal.GetFunctionPointerForDelegate(d17); delegates[17] = d17; - var d18 = new __satisfiesMethodConstraints(_satisfiesMethodConstraints); + var d18 = new __pInvokeMarshalingRequired(_pInvokeMarshalingRequired); callbacks[18] = Marshal.GetFunctionPointerForDelegate(d18); delegates[18] = d18; - var d19 = new __isCompatibleDelegate(_isCompatibleDelegate); + var d19 = new __satisfiesMethodConstraints(_satisfiesMethodConstraints); callbacks[19] = Marshal.GetFunctionPointerForDelegate(d19); delegates[19] = d19; - var d20 = new __isInstantiationOfVerifiedGeneric(_isInstantiationOfVerifiedGeneric); + var d20 = new __isCompatibleDelegate(_isCompatibleDelegate); callbacks[20] = Marshal.GetFunctionPointerForDelegate(d20); delegates[20] = d20; - var d21 = new __initConstraintsForVerification(_initConstraintsForVerification); + var d21 = new __isInstantiationOfVerifiedGeneric(_isInstantiationOfVerifiedGeneric); callbacks[21] = Marshal.GetFunctionPointerForDelegate(d21); delegates[21] = d21; - var d22 = new __canSkipMethodVerification(_canSkipMethodVerification); + var d22 = new __initConstraintsForVerification(_initConstraintsForVerification); callbacks[22] = Marshal.GetFunctionPointerForDelegate(d22); delegates[22] = d22; - var d23 = new __methodMustBeLoadedBeforeCodeIsRun(_methodMustBeLoadedBeforeCodeIsRun); + var d23 = new __canSkipMethodVerification(_canSkipMethodVerification); callbacks[23] = Marshal.GetFunctionPointerForDelegate(d23); delegates[23] = d23; - var d24 = new __mapMethodDeclToMethodImpl(_mapMethodDeclToMethodImpl); + var d24 = new __methodMustBeLoadedBeforeCodeIsRun(_methodMustBeLoadedBeforeCodeIsRun); callbacks[24] = Marshal.GetFunctionPointerForDelegate(d24); delegates[24] = d24; - var d25 = new __getGSCookie(_getGSCookie); + var d25 = new __mapMethodDeclToMethodImpl(_mapMethodDeclToMethodImpl); callbacks[25] = Marshal.GetFunctionPointerForDelegate(d25); delegates[25] = d25; - var d26 = new __resolveToken(_resolveToken); + var d26 = new __getGSCookie(_getGSCookie); callbacks[26] = Marshal.GetFunctionPointerForDelegate(d26); delegates[26] = d26; - var d27 = new __tryResolveToken(_tryResolveToken); + var d27 = new __resolveToken(_resolveToken); callbacks[27] = Marshal.GetFunctionPointerForDelegate(d27); delegates[27] = d27; - var d28 = new __findSig(_findSig); + var d28 = new __tryResolveToken(_tryResolveToken); callbacks[28] = Marshal.GetFunctionPointerForDelegate(d28); delegates[28] = d28; - var d29 = new __findCallSiteSig(_findCallSiteSig); + var d29 = new __findSig(_findSig); callbacks[29] = Marshal.GetFunctionPointerForDelegate(d29); delegates[29] = d29; - var d30 = new __getTokenTypeAsHandle(_getTokenTypeAsHandle); + var d30 = new __findCallSiteSig(_findCallSiteSig); callbacks[30] = Marshal.GetFunctionPointerForDelegate(d30); delegates[30] = d30; - var d31 = new __canSkipVerification(_canSkipVerification); + var d31 = new __getTokenTypeAsHandle(_getTokenTypeAsHandle); callbacks[31] = Marshal.GetFunctionPointerForDelegate(d31); delegates[31] = d31; - var d32 = new __isValidToken(_isValidToken); + var d32 = new __canSkipVerification(_canSkipVerification); callbacks[32] = Marshal.GetFunctionPointerForDelegate(d32); delegates[32] = d32; - var d33 = new __isValidStringRef(_isValidStringRef); + var d33 = new __isValidToken(_isValidToken); callbacks[33] = Marshal.GetFunctionPointerForDelegate(d33); delegates[33] = d33; - var d34 = new __shouldEnforceCallvirtRestriction(_shouldEnforceCallvirtRestriction); + var d34 = new __isValidStringRef(_isValidStringRef); callbacks[34] = Marshal.GetFunctionPointerForDelegate(d34); delegates[34] = d34; - var d35 = new __asCorInfoType(_asCorInfoType); + var d35 = new __shouldEnforceCallvirtRestriction(_shouldEnforceCallvirtRestriction); callbacks[35] = Marshal.GetFunctionPointerForDelegate(d35); delegates[35] = d35; - var d36 = new __getClassName(_getClassName); + var d36 = new __asCorInfoType(_asCorInfoType); callbacks[36] = Marshal.GetFunctionPointerForDelegate(d36); delegates[36] = d36; - var d37 = new __appendClassName(_appendClassName); + var d37 = new __getClassName(_getClassName); callbacks[37] = Marshal.GetFunctionPointerForDelegate(d37); delegates[37] = d37; - var d38 = new __isValueClass(_isValueClass); + var d38 = new __appendClassName(_appendClassName); callbacks[38] = Marshal.GetFunctionPointerForDelegate(d38); delegates[38] = d38; - var d39 = new __canInlineTypeCheckWithObjectVTable(_canInlineTypeCheckWithObjectVTable); + var d39 = new __isValueClass(_isValueClass); callbacks[39] = Marshal.GetFunctionPointerForDelegate(d39); delegates[39] = d39; - var d40 = new __getClassAttribs(_getClassAttribs); + var d40 = new __canInlineTypeCheckWithObjectVTable(_canInlineTypeCheckWithObjectVTable); callbacks[40] = Marshal.GetFunctionPointerForDelegate(d40); delegates[40] = d40; - var d41 = new __isStructRequiringStackAllocRetBuf(_isStructRequiringStackAllocRetBuf); + var d41 = new __getClassAttribs(_getClassAttribs); callbacks[41] = Marshal.GetFunctionPointerForDelegate(d41); delegates[41] = d41; - var d42 = new __getClassModule(_getClassModule); + var d42 = new __isStructRequiringStackAllocRetBuf(_isStructRequiringStackAllocRetBuf); callbacks[42] = Marshal.GetFunctionPointerForDelegate(d42); delegates[42] = d42; - var d43 = new __getModuleAssembly(_getModuleAssembly); + var d43 = new __getClassModule(_getClassModule); callbacks[43] = Marshal.GetFunctionPointerForDelegate(d43); delegates[43] = d43; - var d44 = new __getAssemblyName(_getAssemblyName); + var d44 = new __getModuleAssembly(_getModuleAssembly); callbacks[44] = Marshal.GetFunctionPointerForDelegate(d44); delegates[44] = d44; - var d45 = new __LongLifetimeMalloc(_LongLifetimeMalloc); + var d45 = new __getAssemblyName(_getAssemblyName); callbacks[45] = Marshal.GetFunctionPointerForDelegate(d45); delegates[45] = d45; - var d46 = new __LongLifetimeFree(_LongLifetimeFree); + var d46 = new __LongLifetimeMalloc(_LongLifetimeMalloc); callbacks[46] = Marshal.GetFunctionPointerForDelegate(d46); delegates[46] = d46; - var d47 = new __getClassModuleIdForStatics(_getClassModuleIdForStatics); + var d47 = new __LongLifetimeFree(_LongLifetimeFree); callbacks[47] = Marshal.GetFunctionPointerForDelegate(d47); delegates[47] = d47; - var d48 = new __getClassSize(_getClassSize); + var d48 = new __getClassModuleIdForStatics(_getClassModuleIdForStatics); callbacks[48] = Marshal.GetFunctionPointerForDelegate(d48); delegates[48] = d48; - var d49 = new __getClassAlignmentRequirement(_getClassAlignmentRequirement); + var d49 = new __getClassSize(_getClassSize); callbacks[49] = Marshal.GetFunctionPointerForDelegate(d49); delegates[49] = d49; - var d50 = new __getClassGClayout(_getClassGClayout); + var d50 = new __getClassAlignmentRequirement(_getClassAlignmentRequirement); callbacks[50] = Marshal.GetFunctionPointerForDelegate(d50); delegates[50] = d50; - var d51 = new __getClassNumInstanceFields(_getClassNumInstanceFields); + var d51 = new __getClassGClayout(_getClassGClayout); callbacks[51] = Marshal.GetFunctionPointerForDelegate(d51); delegates[51] = d51; - var d52 = new __getFieldInClass(_getFieldInClass); + var d52 = new __getClassNumInstanceFields(_getClassNumInstanceFields); callbacks[52] = Marshal.GetFunctionPointerForDelegate(d52); delegates[52] = d52; - var d53 = new __checkMethodModifier(_checkMethodModifier); + var d53 = new __getFieldInClass(_getFieldInClass); callbacks[53] = Marshal.GetFunctionPointerForDelegate(d53); delegates[53] = d53; - var d54 = new __getNewHelper(_getNewHelper); + var d54 = new __checkMethodModifier(_checkMethodModifier); callbacks[54] = Marshal.GetFunctionPointerForDelegate(d54); delegates[54] = d54; - var d55 = new __getNewArrHelper(_getNewArrHelper); + var d55 = new __getNewHelper(_getNewHelper); callbacks[55] = Marshal.GetFunctionPointerForDelegate(d55); delegates[55] = d55; - var d56 = new __getCastingHelper(_getCastingHelper); + var d56 = new __getNewArrHelper(_getNewArrHelper); callbacks[56] = Marshal.GetFunctionPointerForDelegate(d56); delegates[56] = d56; - var d57 = new __getSharedCCtorHelper(_getSharedCCtorHelper); + var d57 = new __getCastingHelper(_getCastingHelper); callbacks[57] = Marshal.GetFunctionPointerForDelegate(d57); delegates[57] = d57; - var d58 = new __getSecurityPrologHelper(_getSecurityPrologHelper); + var d58 = new __getSharedCCtorHelper(_getSharedCCtorHelper); callbacks[58] = Marshal.GetFunctionPointerForDelegate(d58); delegates[58] = d58; - var d59 = new __getTypeForBox(_getTypeForBox); + var d59 = new __getSecurityPrologHelper(_getSecurityPrologHelper); callbacks[59] = Marshal.GetFunctionPointerForDelegate(d59); delegates[59] = d59; - var d60 = new __getBoxHelper(_getBoxHelper); + var d60 = new __getTypeForBox(_getTypeForBox); callbacks[60] = Marshal.GetFunctionPointerForDelegate(d60); delegates[60] = d60; - var d61 = new __getUnBoxHelper(_getUnBoxHelper); + var d61 = new __getBoxHelper(_getBoxHelper); callbacks[61] = Marshal.GetFunctionPointerForDelegate(d61); delegates[61] = d61; - var d62 = new __getReadyToRunHelper(_getReadyToRunHelper); + var d62 = new __getUnBoxHelper(_getUnBoxHelper); callbacks[62] = Marshal.GetFunctionPointerForDelegate(d62); delegates[62] = d62; - var d63 = new __getReadyToRunDelegateCtorHelper(_getReadyToRunDelegateCtorHelper); + var d63 = new __getReadyToRunHelper(_getReadyToRunHelper); callbacks[63] = Marshal.GetFunctionPointerForDelegate(d63); delegates[63] = d63; - var d64 = new __getHelperName(_getHelperName); + var d64 = new __getReadyToRunDelegateCtorHelper(_getReadyToRunDelegateCtorHelper); callbacks[64] = Marshal.GetFunctionPointerForDelegate(d64); delegates[64] = d64; - var d65 = new __initClass(_initClass); + var d65 = new __getHelperName(_getHelperName); callbacks[65] = Marshal.GetFunctionPointerForDelegate(d65); delegates[65] = d65; - var d66 = new __classMustBeLoadedBeforeCodeIsRun(_classMustBeLoadedBeforeCodeIsRun); + var d66 = new __initClass(_initClass); callbacks[66] = Marshal.GetFunctionPointerForDelegate(d66); delegates[66] = d66; - var d67 = new __getBuiltinClass(_getBuiltinClass); + var d67 = new __classMustBeLoadedBeforeCodeIsRun(_classMustBeLoadedBeforeCodeIsRun); callbacks[67] = Marshal.GetFunctionPointerForDelegate(d67); delegates[67] = d67; - var d68 = new __getTypeForPrimitiveValueClass(_getTypeForPrimitiveValueClass); + var d68 = new __getBuiltinClass(_getBuiltinClass); callbacks[68] = Marshal.GetFunctionPointerForDelegate(d68); delegates[68] = d68; - var d69 = new __canCast(_canCast); + var d69 = new __getTypeForPrimitiveValueClass(_getTypeForPrimitiveValueClass); callbacks[69] = Marshal.GetFunctionPointerForDelegate(d69); delegates[69] = d69; - var d70 = new __areTypesEquivalent(_areTypesEquivalent); + var d70 = new __canCast(_canCast); callbacks[70] = Marshal.GetFunctionPointerForDelegate(d70); delegates[70] = d70; - var d71 = new __mergeClasses(_mergeClasses); + var d71 = new __areTypesEquivalent(_areTypesEquivalent); callbacks[71] = Marshal.GetFunctionPointerForDelegate(d71); delegates[71] = d71; - var d72 = new __getParentType(_getParentType); + var d72 = new __mergeClasses(_mergeClasses); callbacks[72] = Marshal.GetFunctionPointerForDelegate(d72); delegates[72] = d72; - var d73 = new __getChildType(_getChildType); + var d73 = new __getParentType(_getParentType); callbacks[73] = Marshal.GetFunctionPointerForDelegate(d73); delegates[73] = d73; - var d74 = new __satisfiesClassConstraints(_satisfiesClassConstraints); + var d74 = new __getChildType(_getChildType); callbacks[74] = Marshal.GetFunctionPointerForDelegate(d74); delegates[74] = d74; - var d75 = new __isSDArray(_isSDArray); + var d75 = new __satisfiesClassConstraints(_satisfiesClassConstraints); callbacks[75] = Marshal.GetFunctionPointerForDelegate(d75); delegates[75] = d75; - var d76 = new __getArrayRank(_getArrayRank); + var d76 = new __isSDArray(_isSDArray); callbacks[76] = Marshal.GetFunctionPointerForDelegate(d76); delegates[76] = d76; - var d77 = new __getArrayInitializationData(_getArrayInitializationData); + var d77 = new __getArrayRank(_getArrayRank); callbacks[77] = Marshal.GetFunctionPointerForDelegate(d77); delegates[77] = d77; - var d78 = new __canAccessClass(_canAccessClass); + var d78 = new __getArrayInitializationData(_getArrayInitializationData); callbacks[78] = Marshal.GetFunctionPointerForDelegate(d78); delegates[78] = d78; - var d79 = new __getFieldName(_getFieldName); + var d79 = new __canAccessClass(_canAccessClass); callbacks[79] = Marshal.GetFunctionPointerForDelegate(d79); delegates[79] = d79; - var d80 = new __getFieldClass(_getFieldClass); + var d80 = new __getFieldName(_getFieldName); callbacks[80] = Marshal.GetFunctionPointerForDelegate(d80); delegates[80] = d80; - var d81 = new __getFieldType(_getFieldType); + var d81 = new __getFieldClass(_getFieldClass); callbacks[81] = Marshal.GetFunctionPointerForDelegate(d81); delegates[81] = d81; - var d82 = new __getFieldOffset(_getFieldOffset); + var d82 = new __getFieldType(_getFieldType); callbacks[82] = Marshal.GetFunctionPointerForDelegate(d82); delegates[82] = d82; - var d83 = new __isWriteBarrierHelperRequired(_isWriteBarrierHelperRequired); + var d83 = new __getFieldOffset(_getFieldOffset); callbacks[83] = Marshal.GetFunctionPointerForDelegate(d83); delegates[83] = d83; - var d84 = new __getFieldInfo(_getFieldInfo); + var d84 = new __isWriteBarrierHelperRequired(_isWriteBarrierHelperRequired); callbacks[84] = Marshal.GetFunctionPointerForDelegate(d84); delegates[84] = d84; - var d85 = new __isFieldStatic(_isFieldStatic); + var d85 = new __getFieldInfo(_getFieldInfo); callbacks[85] = Marshal.GetFunctionPointerForDelegate(d85); delegates[85] = d85; - var d86 = new __getBoundaries(_getBoundaries); + var d86 = new __isFieldStatic(_isFieldStatic); callbacks[86] = Marshal.GetFunctionPointerForDelegate(d86); delegates[86] = d86; - var d87 = new __setBoundaries(_setBoundaries); + var d87 = new __getBoundaries(_getBoundaries); callbacks[87] = Marshal.GetFunctionPointerForDelegate(d87); delegates[87] = d87; - var d88 = new __getVars(_getVars); + var d88 = new __setBoundaries(_setBoundaries); callbacks[88] = Marshal.GetFunctionPointerForDelegate(d88); delegates[88] = d88; - var d89 = new __setVars(_setVars); + var d89 = new __getVars(_getVars); callbacks[89] = Marshal.GetFunctionPointerForDelegate(d89); delegates[89] = d89; - var d90 = new __allocateArray(_allocateArray); + var d90 = new __setVars(_setVars); callbacks[90] = Marshal.GetFunctionPointerForDelegate(d90); delegates[90] = d90; - var d91 = new __freeArray(_freeArray); + var d91 = new __allocateArray(_allocateArray); callbacks[91] = Marshal.GetFunctionPointerForDelegate(d91); delegates[91] = d91; - var d92 = new __getArgNext(_getArgNext); + var d92 = new __freeArray(_freeArray); callbacks[92] = Marshal.GetFunctionPointerForDelegate(d92); delegates[92] = d92; - var d93 = new __getArgType(_getArgType); + var d93 = new __getArgNext(_getArgNext); callbacks[93] = Marshal.GetFunctionPointerForDelegate(d93); delegates[93] = d93; - var d94 = new __getArgClass(_getArgClass); + var d94 = new __getArgType(_getArgType); callbacks[94] = Marshal.GetFunctionPointerForDelegate(d94); delegates[94] = d94; - var d95 = new __getHFAType(_getHFAType); + var d95 = new __getArgClass(_getArgClass); callbacks[95] = Marshal.GetFunctionPointerForDelegate(d95); delegates[95] = d95; - var d96 = new __GetErrorHRESULT(_GetErrorHRESULT); + var d96 = new __getHFAType(_getHFAType); callbacks[96] = Marshal.GetFunctionPointerForDelegate(d96); delegates[96] = d96; - var d97 = new __GetErrorMessage(_GetErrorMessage); + var d97 = new __GetErrorHRESULT(_GetErrorHRESULT); callbacks[97] = Marshal.GetFunctionPointerForDelegate(d97); delegates[97] = d97; - var d98 = new __FilterException(_FilterException); + var d98 = new __GetErrorMessage(_GetErrorMessage); callbacks[98] = Marshal.GetFunctionPointerForDelegate(d98); delegates[98] = d98; - var d99 = new __HandleException(_HandleException); + var d99 = new __FilterException(_FilterException); callbacks[99] = Marshal.GetFunctionPointerForDelegate(d99); delegates[99] = d99; - var d100 = new __ThrowExceptionForJitResult(_ThrowExceptionForJitResult); + var d100 = new __HandleException(_HandleException); callbacks[100] = Marshal.GetFunctionPointerForDelegate(d100); delegates[100] = d100; - var d101 = new __ThrowExceptionForHelper(_ThrowExceptionForHelper); + var d101 = new __ThrowExceptionForJitResult(_ThrowExceptionForJitResult); callbacks[101] = Marshal.GetFunctionPointerForDelegate(d101); delegates[101] = d101; - var d102 = new __runWithErrorTrap(_runWithErrorTrap); + var d102 = new __ThrowExceptionForHelper(_ThrowExceptionForHelper); callbacks[102] = Marshal.GetFunctionPointerForDelegate(d102); delegates[102] = d102; - var d103 = new __getEEInfo(_getEEInfo); + var d103 = new __runWithErrorTrap(_runWithErrorTrap); callbacks[103] = Marshal.GetFunctionPointerForDelegate(d103); delegates[103] = d103; - var d104 = new __getJitTimeLogFilename(_getJitTimeLogFilename); + var d104 = new __getEEInfo(_getEEInfo); callbacks[104] = Marshal.GetFunctionPointerForDelegate(d104); delegates[104] = d104; - var d105 = new __getMethodDefFromMethod(_getMethodDefFromMethod); + var d105 = new __getJitTimeLogFilename(_getJitTimeLogFilename); callbacks[105] = Marshal.GetFunctionPointerForDelegate(d105); delegates[105] = d105; - var d106 = new __getMethodName(_getMethodName); + var d106 = new __getMethodDefFromMethod(_getMethodDefFromMethod); callbacks[106] = Marshal.GetFunctionPointerForDelegate(d106); delegates[106] = d106; - var d107 = new __getMethodNameFromMetadata(_getMethodNameFromMetadata); + var d107 = new __getMethodName(_getMethodName); callbacks[107] = Marshal.GetFunctionPointerForDelegate(d107); delegates[107] = d107; - var d108 = new __getMethodHash(_getMethodHash); + var d108 = new __getMethodNameFromMetadata(_getMethodNameFromMetadata); callbacks[108] = Marshal.GetFunctionPointerForDelegate(d108); delegates[108] = d108; - var d109 = new __findNameOfToken(_findNameOfToken); + var d109 = new __getMethodHash(_getMethodHash); callbacks[109] = Marshal.GetFunctionPointerForDelegate(d109); delegates[109] = d109; - var d110 = new __getSystemVAmd64PassStructInRegisterDescriptor(_getSystemVAmd64PassStructInRegisterDescriptor); + var d110 = new __findNameOfToken(_findNameOfToken); callbacks[110] = Marshal.GetFunctionPointerForDelegate(d110); delegates[110] = d110; - var d111 = new __getThreadTLSIndex(_getThreadTLSIndex); + var d111 = new __getSystemVAmd64PassStructInRegisterDescriptor(_getSystemVAmd64PassStructInRegisterDescriptor); callbacks[111] = Marshal.GetFunctionPointerForDelegate(d111); delegates[111] = d111; - var d112 = new __getInlinedCallFrameVptr(_getInlinedCallFrameVptr); + var d112 = new __getThreadTLSIndex(_getThreadTLSIndex); callbacks[112] = Marshal.GetFunctionPointerForDelegate(d112); delegates[112] = d112; - var d113 = new __getAddrOfCaptureThreadGlobal(_getAddrOfCaptureThreadGlobal); + var d113 = new __getInlinedCallFrameVptr(_getInlinedCallFrameVptr); callbacks[113] = Marshal.GetFunctionPointerForDelegate(d113); delegates[113] = d113; - var d114 = new __getHelperFtn(_getHelperFtn); + var d114 = new __getAddrOfCaptureThreadGlobal(_getAddrOfCaptureThreadGlobal); callbacks[114] = Marshal.GetFunctionPointerForDelegate(d114); delegates[114] = d114; - var d115 = new __getFunctionEntryPoint(_getFunctionEntryPoint); + var d115 = new __getHelperFtn(_getHelperFtn); callbacks[115] = Marshal.GetFunctionPointerForDelegate(d115); delegates[115] = d115; - var d116 = new __getFunctionFixedEntryPoint(_getFunctionFixedEntryPoint); + var d116 = new __getFunctionEntryPoint(_getFunctionEntryPoint); callbacks[116] = Marshal.GetFunctionPointerForDelegate(d116); delegates[116] = d116; - var d117 = new __getMethodSync(_getMethodSync); + var d117 = new __getFunctionFixedEntryPoint(_getFunctionFixedEntryPoint); callbacks[117] = Marshal.GetFunctionPointerForDelegate(d117); delegates[117] = d117; - var d118 = new __getLazyStringLiteralHelper(_getLazyStringLiteralHelper); + var d118 = new __getMethodSync(_getMethodSync); callbacks[118] = Marshal.GetFunctionPointerForDelegate(d118); delegates[118] = d118; - var d119 = new __embedModuleHandle(_embedModuleHandle); + var d119 = new __getLazyStringLiteralHelper(_getLazyStringLiteralHelper); callbacks[119] = Marshal.GetFunctionPointerForDelegate(d119); delegates[119] = d119; - var d120 = new __embedClassHandle(_embedClassHandle); + var d120 = new __embedModuleHandle(_embedModuleHandle); callbacks[120] = Marshal.GetFunctionPointerForDelegate(d120); delegates[120] = d120; - var d121 = new __embedMethodHandle(_embedMethodHandle); + var d121 = new __embedClassHandle(_embedClassHandle); callbacks[121] = Marshal.GetFunctionPointerForDelegate(d121); delegates[121] = d121; - var d122 = new __embedFieldHandle(_embedFieldHandle); + var d122 = new __embedMethodHandle(_embedMethodHandle); callbacks[122] = Marshal.GetFunctionPointerForDelegate(d122); delegates[122] = d122; - var d123 = new __embedGenericHandle(_embedGenericHandle); + var d123 = new __embedFieldHandle(_embedFieldHandle); callbacks[123] = Marshal.GetFunctionPointerForDelegate(d123); delegates[123] = d123; - var d124 = new __getLocationOfThisType(_getLocationOfThisType); + var d124 = new __embedGenericHandle(_embedGenericHandle); callbacks[124] = Marshal.GetFunctionPointerForDelegate(d124); delegates[124] = d124; - var d125 = new __getPInvokeUnmanagedTarget(_getPInvokeUnmanagedTarget); + var d125 = new __getLocationOfThisType(_getLocationOfThisType); callbacks[125] = Marshal.GetFunctionPointerForDelegate(d125); delegates[125] = d125; - var d126 = new __getAddressOfPInvokeFixup(_getAddressOfPInvokeFixup); + var d126 = new __getPInvokeUnmanagedTarget(_getPInvokeUnmanagedTarget); callbacks[126] = Marshal.GetFunctionPointerForDelegate(d126); delegates[126] = d126; - var d127 = new __getAddressOfPInvokeTarget(_getAddressOfPInvokeTarget); + var d127 = new __getAddressOfPInvokeFixup(_getAddressOfPInvokeFixup); callbacks[127] = Marshal.GetFunctionPointerForDelegate(d127); delegates[127] = d127; - var d128 = new __GetCookieForPInvokeCalliSig(_GetCookieForPInvokeCalliSig); + var d128 = new __getAddressOfPInvokeTarget(_getAddressOfPInvokeTarget); callbacks[128] = Marshal.GetFunctionPointerForDelegate(d128); delegates[128] = d128; - var d129 = new __canGetCookieForPInvokeCalliSig(_canGetCookieForPInvokeCalliSig); + var d129 = new __GetCookieForPInvokeCalliSig(_GetCookieForPInvokeCalliSig); callbacks[129] = Marshal.GetFunctionPointerForDelegate(d129); delegates[129] = d129; - var d130 = new __getJustMyCodeHandle(_getJustMyCodeHandle); + var d130 = new __canGetCookieForPInvokeCalliSig(_canGetCookieForPInvokeCalliSig); callbacks[130] = Marshal.GetFunctionPointerForDelegate(d130); delegates[130] = d130; - var d131 = new __GetProfilingHandle(_GetProfilingHandle); + var d131 = new __getJustMyCodeHandle(_getJustMyCodeHandle); callbacks[131] = Marshal.GetFunctionPointerForDelegate(d131); delegates[131] = d131; - var d132 = new __getCallInfo(_getCallInfo); + var d132 = new __GetProfilingHandle(_GetProfilingHandle); callbacks[132] = Marshal.GetFunctionPointerForDelegate(d132); delegates[132] = d132; - var d133 = new __canAccessFamily(_canAccessFamily); + var d133 = new __getCallInfo(_getCallInfo); callbacks[133] = Marshal.GetFunctionPointerForDelegate(d133); delegates[133] = d133; - var d134 = new __isRIDClassDomainID(_isRIDClassDomainID); + var d134 = new __canAccessFamily(_canAccessFamily); callbacks[134] = Marshal.GetFunctionPointerForDelegate(d134); delegates[134] = d134; - var d135 = new __getClassDomainID(_getClassDomainID); + var d135 = new __isRIDClassDomainID(_isRIDClassDomainID); callbacks[135] = Marshal.GetFunctionPointerForDelegate(d135); delegates[135] = d135; - var d136 = new __getFieldAddress(_getFieldAddress); + var d136 = new __getClassDomainID(_getClassDomainID); callbacks[136] = Marshal.GetFunctionPointerForDelegate(d136); delegates[136] = d136; - var d137 = new __getVarArgsHandle(_getVarArgsHandle); + var d137 = new __getFieldAddress(_getFieldAddress); callbacks[137] = Marshal.GetFunctionPointerForDelegate(d137); delegates[137] = d137; - var d138 = new __canGetVarArgsHandle(_canGetVarArgsHandle); + var d138 = new __getVarArgsHandle(_getVarArgsHandle); callbacks[138] = Marshal.GetFunctionPointerForDelegate(d138); delegates[138] = d138; - var d139 = new __constructStringLiteral(_constructStringLiteral); + var d139 = new __canGetVarArgsHandle(_canGetVarArgsHandle); callbacks[139] = Marshal.GetFunctionPointerForDelegate(d139); delegates[139] = d139; - var d140 = new __emptyStringLiteral(_emptyStringLiteral); + var d140 = new __constructStringLiteral(_constructStringLiteral); callbacks[140] = Marshal.GetFunctionPointerForDelegate(d140); delegates[140] = d140; - var d141 = new __getFieldThreadLocalStoreID(_getFieldThreadLocalStoreID); + var d141 = new __emptyStringLiteral(_emptyStringLiteral); callbacks[141] = Marshal.GetFunctionPointerForDelegate(d141); delegates[141] = d141; - var d142 = new __setOverride(_setOverride); + var d142 = new __getFieldThreadLocalStoreID(_getFieldThreadLocalStoreID); callbacks[142] = Marshal.GetFunctionPointerForDelegate(d142); delegates[142] = d142; - var d143 = new __addActiveDependency(_addActiveDependency); + var d143 = new __setOverride(_setOverride); callbacks[143] = Marshal.GetFunctionPointerForDelegate(d143); delegates[143] = d143; - var d144 = new __GetDelegateCtor(_GetDelegateCtor); + var d144 = new __addActiveDependency(_addActiveDependency); callbacks[144] = Marshal.GetFunctionPointerForDelegate(d144); delegates[144] = d144; - var d145 = new __MethodCompileComplete(_MethodCompileComplete); + var d145 = new __GetDelegateCtor(_GetDelegateCtor); callbacks[145] = Marshal.GetFunctionPointerForDelegate(d145); delegates[145] = d145; - var d146 = new __getTailCallCopyArgsThunk(_getTailCallCopyArgsThunk); + var d146 = new __MethodCompileComplete(_MethodCompileComplete); callbacks[146] = Marshal.GetFunctionPointerForDelegate(d146); delegates[146] = d146; - var d147 = new __getMemoryManager(_getMemoryManager); + var d147 = new __getTailCallCopyArgsThunk(_getTailCallCopyArgsThunk); callbacks[147] = Marshal.GetFunctionPointerForDelegate(d147); delegates[147] = d147; - var d148 = new __allocMem(_allocMem); + var d148 = new __getMemoryManager(_getMemoryManager); callbacks[148] = Marshal.GetFunctionPointerForDelegate(d148); delegates[148] = d148; - var d149 = new __reserveUnwindInfo(_reserveUnwindInfo); + var d149 = new __allocMem(_allocMem); callbacks[149] = Marshal.GetFunctionPointerForDelegate(d149); delegates[149] = d149; - var d150 = new __allocUnwindInfo(_allocUnwindInfo); + var d150 = new __reserveUnwindInfo(_reserveUnwindInfo); callbacks[150] = Marshal.GetFunctionPointerForDelegate(d150); delegates[150] = d150; - var d151 = new __allocGCInfo(_allocGCInfo); + var d151 = new __allocUnwindInfo(_allocUnwindInfo); callbacks[151] = Marshal.GetFunctionPointerForDelegate(d151); delegates[151] = d151; - var d152 = new __yieldExecution(_yieldExecution); + var d152 = new __allocGCInfo(_allocGCInfo); callbacks[152] = Marshal.GetFunctionPointerForDelegate(d152); delegates[152] = d152; - var d153 = new __setEHcount(_setEHcount); + var d153 = new __yieldExecution(_yieldExecution); callbacks[153] = Marshal.GetFunctionPointerForDelegate(d153); delegates[153] = d153; - var d154 = new __setEHinfo(_setEHinfo); + var d154 = new __setEHcount(_setEHcount); callbacks[154] = Marshal.GetFunctionPointerForDelegate(d154); delegates[154] = d154; - var d155 = new __logMsg(_logMsg); + var d155 = new __setEHinfo(_setEHinfo); callbacks[155] = Marshal.GetFunctionPointerForDelegate(d155); delegates[155] = d155; - var d156 = new __doAssert(_doAssert); + var d156 = new __logMsg(_logMsg); callbacks[156] = Marshal.GetFunctionPointerForDelegate(d156); delegates[156] = d156; - var d157 = new __reportFatalError(_reportFatalError); + var d157 = new __doAssert(_doAssert); callbacks[157] = Marshal.GetFunctionPointerForDelegate(d157); delegates[157] = d157; - var d158 = new __allocBBProfileBuffer(_allocBBProfileBuffer); + var d158 = new __reportFatalError(_reportFatalError); callbacks[158] = Marshal.GetFunctionPointerForDelegate(d158); delegates[158] = d158; - var d159 = new __getBBProfileData(_getBBProfileData); + var d159 = new __allocBBProfileBuffer(_allocBBProfileBuffer); callbacks[159] = Marshal.GetFunctionPointerForDelegate(d159); delegates[159] = d159; - var d160 = new __recordCallSite(_recordCallSite); + var d160 = new __getBBProfileData(_getBBProfileData); callbacks[160] = Marshal.GetFunctionPointerForDelegate(d160); delegates[160] = d160; - var d161 = new __recordRelocation(_recordRelocation); + var d161 = new __recordCallSite(_recordCallSite); callbacks[161] = Marshal.GetFunctionPointerForDelegate(d161); delegates[161] = d161; - var d162 = new __getRelocTypeHint(_getRelocTypeHint); + var d162 = new __recordRelocation(_recordRelocation); callbacks[162] = Marshal.GetFunctionPointerForDelegate(d162); delegates[162] = d162; - var d163 = new __getModuleNativeEntryPointRange(_getModuleNativeEntryPointRange); + var d163 = new __getRelocTypeHint(_getRelocTypeHint); callbacks[163] = Marshal.GetFunctionPointerForDelegate(d163); delegates[163] = d163; - var d164 = new __getExpectedTargetArchitecture(_getExpectedTargetArchitecture); + var d164 = new __getModuleNativeEntryPointRange(_getModuleNativeEntryPointRange); callbacks[164] = Marshal.GetFunctionPointerForDelegate(d164); delegates[164] = d164; - var d165 = new __getJitFlags(_getJitFlags); + var d165 = new __getExpectedTargetArchitecture(_getExpectedTargetArchitecture); callbacks[165] = Marshal.GetFunctionPointerForDelegate(d165); delegates[165] = d165; + var d166 = new __getJitFlags(_getJitFlags); + callbacks[166] = Marshal.GetFunctionPointerForDelegate(d166); + delegates[166] = d166; keepAlive = delegates; return (IntPtr)callbacks; diff --git a/src/JitInterface/src/CorInfoImpl.cs b/src/JitInterface/src/CorInfoImpl.cs index bba34c544..021531fd6 100644 --- a/src/JitInterface/src/CorInfoImpl.cs +++ b/src/JitInterface/src/CorInfoImpl.cs @@ -946,6 +946,13 @@ namespace Internal.JitInterface } } + private CORINFO_CLASS_STRUCT_* getDefaultEqualityComparerClass(CORINFO_CLASS_STRUCT_* elemType) + { + // TODO: EqualityComparer optimizations + // https://github.com/dotnet/corert/issues/763 + return null; + } + private void expandRawHandleIntrinsic(ref CORINFO_RESOLVED_TOKEN pResolvedToken, ref CORINFO_GENERICHANDLE_RESULT pResult) { // Resolved token as a potentially RuntimeDetermined object. diff --git a/src/JitInterface/src/ThunkGenerator/ThunkInput.txt b/src/JitInterface/src/ThunkGenerator/ThunkInput.txt index 3be2b9935..fc2304191 100644 --- a/src/JitInterface/src/ThunkGenerator/ThunkInput.txt +++ b/src/JitInterface/src/ThunkGenerator/ThunkInput.txt @@ -171,6 +171,7 @@ FUNCTIONS CORINFO_MODULE_HANDLE getMethodModule( CORINFO_METHOD_HANDLE method ); void getMethodVTableOffset( CORINFO_METHOD_HANDLE method, unsigned* offsetOfIndirection, unsigned* offsetAfterIndirection, bool* isRelative); CORINFO_METHOD_HANDLE resolveVirtualMethod( CORINFO_METHOD_HANDLE virtualMethod, CORINFO_CLASS_HANDLE implementingClass, CORINFO_CONTEXT_HANDLE ownerType); + CORINFO_CLASS_HANDLE getDefaultEqualityComparerClass(CORINFO_CLASS_HANDLE elemType); void expandRawHandleIntrinsic(CORINFO_RESOLVED_TOKEN * pResolvedToken, CORINFO_GENERICHANDLE_RESULT * pResult); CorInfoIntrinsics getIntrinsicID( CORINFO_METHOD_HANDLE method , bool * pMustExpand); bool isInSIMDModule( CORINFO_CLASS_HANDLE classHnd ); diff --git a/src/JitInterface/src/ThunkGenerator/corinfo.h b/src/JitInterface/src/ThunkGenerator/corinfo.h index 3171d6b00..aa024e054 100644 --- a/src/JitInterface/src/ThunkGenerator/corinfo.h +++ b/src/JitInterface/src/ThunkGenerator/corinfo.h @@ -213,11 +213,11 @@ TODO: Talk about initializing strutures before use #define SELECTANY extern __declspec(selectany) #endif -SELECTANY const GUID JITEEVersionIdentifier = { /* 7f70c266-eada-427b-be8a-be1260e34b1b */ - 0x7f70c266, - 0xeada, - 0x427b, - {0xbe, 0x8a, 0xbe, 0x12, 0x60, 0xe3, 0x4b, 0x1b} +SELECTANY const GUID JITEEVersionIdentifier = { /* 76a743cd-8a07-471e-9ac4-cd5806a8ffac */ + 0x76a743cd, + 0x8a07, + 0x471e, + {0x9a, 0xc4, 0xcd, 0x58, 0x06, 0xa8, 0xff, 0xac} }; ////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -2085,6 +2085,12 @@ public: CORINFO_CONTEXT_HANDLE ownerType = NULL /* IN */ ) = 0; + // Given T, return the type of the default EqualityComparer<T>. + // Returns null if the type can't be determined exactly. + virtual CORINFO_CLASS_HANDLE getDefaultEqualityComparerClass( + CORINFO_CLASS_HANDLE elemType + ) = 0; + // Given resolved token that corresponds to an intrinsic classified as // a CORINFO_INTRINSIC_GetRawHandle intrinsic, fetch the handle associated // with the token. If this is not possible at compile-time (because the current method's diff --git a/src/Native/gc/gc.cpp b/src/Native/gc/gc.cpp index e95ac1f93..5618c0b7d 100644 --- a/src/Native/gc/gc.cpp +++ b/src/Native/gc/gc.cpp @@ -15752,46 +15752,72 @@ start_no_gc_region_status gc_heap::prepare_for_no_gc_region (uint64_t total_size save_data_for_no_gc(); settings.pause_mode = pause_no_gc; current_no_gc_region_info.start_status = start_no_gc_success; - - size_t allocation_no_gc_loh = 0; - size_t allocation_no_gc_soh = 0; - size_t size_per_heap = 0; - total_size = (size_t)((float)total_size * 1.05); + uint64_t allocation_no_gc_loh = 0; + uint64_t allocation_no_gc_soh = 0; + assert(total_size != 0); if (loh_size_known) { - loh_size = (size_t)((float)loh_size * 1.05); - allocation_no_gc_loh = (size_t)loh_size; - allocation_no_gc_soh = (size_t)(total_size - loh_size); + assert(loh_size != 0); + assert(loh_size <= total_size); + allocation_no_gc_loh = loh_size; + allocation_no_gc_soh = total_size - loh_size; } else { - allocation_no_gc_soh = (size_t)total_size; - allocation_no_gc_loh = (size_t)total_size; + allocation_no_gc_soh = total_size; + allocation_no_gc_loh = total_size; } size_t soh_segment_size = get_valid_segment_size(); int soh_align_const = get_alignment_constant (TRUE); - size_t max_soh_allocated = (soh_segment_size - OS_PAGE_SIZE - eph_gen_starts_size); + size_t max_soh_allocated = soh_segment_size - OS_PAGE_SIZE - eph_gen_starts_size; + size_t size_per_heap = 0; + const double scale_factor = 1.05; int num_heaps = 1; #ifdef MULTIPLE_HEAPS num_heaps = n_heaps; -#endif //MULTIPLE_HEAPS - size_t total_allowed_soh_allocation = max_soh_allocated * num_heaps; +#endif // MULTIPLE_HEAPS - if (allocation_no_gc_soh > total_allowed_soh_allocation) + uint64_t total_allowed_soh_allocation = (uint64_t)max_soh_allocated * num_heaps; + // [LOCALGC TODO] + // In theory, the upper limit here is the physical memory of the machine, not + // SIZE_T_MAX. This is not true today because total_physical_mem can be + // larger than SIZE_T_MAX if running in wow64 on a machine with more than + // 4GB of RAM. Once Local GC code divergence is resolved and code is flowing + // more freely between branches, it would be good to clean this up to use + // total_physical_mem instead of SIZE_T_MAX. + assert(total_allowed_soh_allocation <= SIZE_T_MAX); + uint64_t total_allowed_loh_allocation = SIZE_T_MAX; + uint64_t total_allowed_soh_alloc_scaled = allocation_no_gc_soh > 0 ? static_cast<uint64_t>(total_allowed_soh_allocation / scale_factor) : 0; + uint64_t total_allowed_loh_alloc_scaled = allocation_no_gc_loh > 0 ? static_cast<uint64_t>(total_allowed_loh_allocation / scale_factor) : 0; + + if (allocation_no_gc_soh > total_allowed_soh_alloc_scaled || + allocation_no_gc_loh > total_allowed_loh_alloc_scaled) { status = start_no_gc_too_large; goto done; } + if (allocation_no_gc_soh > 0) + { + allocation_no_gc_soh = static_cast<uint64_t>(allocation_no_gc_soh * scale_factor); + allocation_no_gc_soh = min (allocation_no_gc_soh, total_allowed_soh_alloc_scaled); + } + + if (allocation_no_gc_loh > 0) + { + allocation_no_gc_loh = static_cast<uint64_t>(allocation_no_gc_loh * scale_factor); + allocation_no_gc_loh = min (allocation_no_gc_loh, total_allowed_loh_alloc_scaled); + } + if (disallow_full_blocking) current_no_gc_region_info.minimal_gc_p = TRUE; if (allocation_no_gc_soh != 0) { - current_no_gc_region_info.soh_allocation_size = allocation_no_gc_soh; + current_no_gc_region_info.soh_allocation_size = (size_t)allocation_no_gc_soh; size_per_heap = current_no_gc_region_info.soh_allocation_size; #ifdef MULTIPLE_HEAPS size_per_heap /= n_heaps; @@ -15807,7 +15833,7 @@ start_no_gc_region_status gc_heap::prepare_for_no_gc_region (uint64_t total_size if (allocation_no_gc_loh != 0) { - current_no_gc_region_info.loh_allocation_size = allocation_no_gc_loh; + current_no_gc_region_info.loh_allocation_size = (size_t)allocation_no_gc_loh; size_per_heap = current_no_gc_region_info.loh_allocation_size; #ifdef MULTIPLE_HEAPS size_per_heap /= n_heaps; diff --git a/src/Native/jitinterface/jitinterface.h b/src/Native/jitinterface/jitinterface.h index 366d87544..b2e498283 100644 --- a/src/Native/jitinterface/jitinterface.h +++ b/src/Native/jitinterface/jitinterface.h @@ -23,6 +23,7 @@ struct JitInterfaceCallbacks void* (__stdcall * getMethodModule)(void * thisHandle, CorInfoException** ppException, void* method); void (__stdcall * getMethodVTableOffset)(void * thisHandle, CorInfoException** ppException, void* method, unsigned* offsetOfIndirection, unsigned* offsetAfterIndirection, bool* isRelative); void* (__stdcall * resolveVirtualMethod)(void * thisHandle, CorInfoException** ppException, void* virtualMethod, void* implementingClass, void* ownerType); + void* (__stdcall * getDefaultEqualityComparerClass)(void * thisHandle, CorInfoException** ppException, void* elemType); void (__stdcall * expandRawHandleIntrinsic)(void * thisHandle, CorInfoException** ppException, void* pResolvedToken, void* pResult); int (__stdcall * getIntrinsicID)(void * thisHandle, CorInfoException** ppException, void* method, bool* pMustExpand); bool (__stdcall * isInSIMDModule)(void * thisHandle, CorInfoException** ppException, void* classHnd); @@ -301,6 +302,15 @@ public: return _ret; } + virtual void* getDefaultEqualityComparerClass(void* elemType) + { + CorInfoException* pException = nullptr; + void* _ret = _callbacks->getDefaultEqualityComparerClass(_thisHandle, &pException, elemType); + if (pException != nullptr) + throw pException; + return _ret; + } + virtual void expandRawHandleIntrinsic(void* pResolvedToken, void* pResult) { CorInfoException* pException = nullptr; diff --git a/src/Native/jitinterface/jitwrapper.cpp b/src/Native/jitinterface/jitwrapper.cpp index 925395497..ba5f23279 100644 --- a/src/Native/jitinterface/jitwrapper.cpp +++ b/src/Native/jitinterface/jitwrapper.cpp @@ -27,11 +27,11 @@ private: unsigned __int64 corJitFlags; }; -static const GUID JITEEVersionIdentifier = { /* 7f70c266-eada-427b-be8a-be1260e34b1b */ - 0x7f70c266, - 0xeada, - 0x427b, - { 0xbe, 0x8a, 0xbe, 0x12, 0x60, 0xe3, 0x4b, 0x1b } +static const GUID JITEEVersionIdentifier = { /* 76a743cd-8a07-471e-9ac4-cd5806a8ffac */ + 0x76a743cd, + 0x8a07, + 0x471e, + { 0x9a, 0xc4, 0xcd, 0x58, 0x06, 0xa8, 0xff, 0xac } }; class Jit diff --git a/src/System.Private.CoreLib/shared/Interop/Windows/Interop.Errors.cs b/src/System.Private.CoreLib/shared/Interop/Windows/Interop.Errors.cs index ff2653765..ec52a81bf 100644 --- a/src/System.Private.CoreLib/shared/Interop/Windows/Interop.Errors.cs +++ b/src/System.Private.CoreLib/shared/Interop/Windows/Interop.Errors.cs @@ -40,5 +40,6 @@ internal partial class Interop internal const int ERROR_NOT_FOUND = 0x490; internal const int ERROR_BAD_IMPERSONATION_LEVEL = 0x542; internal const int E_FILENOTFOUND = unchecked((int)0x80070002); + internal const int ERROR_TIMEOUT = 0x000005B4; } } diff --git a/src/System.Private.CoreLib/shared/System.Private.CoreLib.Shared.projitems b/src/System.Private.CoreLib/shared/System.Private.CoreLib.Shared.projitems index 095d80963..9dcde8243 100644 --- a/src/System.Private.CoreLib/shared/System.Private.CoreLib.Shared.projitems +++ b/src/System.Private.CoreLib/shared/System.Private.CoreLib.Shared.projitems @@ -198,6 +198,8 @@ <Compile Include="$(MSBuildThisFileDirectory)System\Int32.cs" /> <Compile Include="$(MSBuildThisFileDirectory)System\Int64.cs" /> <Compile Include="$(MSBuildThisFileDirectory)System\Lazy.cs" /> + <Compile Include="$(MSBuildThisFileDirectory)System\Math.cs" /> + <Compile Include="$(MSBuildThisFileDirectory)System\MathF.cs" /> <Compile Include="$(MSBuildThisFileDirectory)System\MarshalByRefObject.cs" /> <Compile Include="$(MSBuildThisFileDirectory)System\MemberAccessException.cs" /> <Compile Include="$(MSBuildThisFileDirectory)System\Memory.cs" /> diff --git a/src/System.Private.CoreLib/shared/System/Boolean.cs b/src/System.Private.CoreLib/shared/System/Boolean.cs index a6ffb6de8..70edd94e3 100644 --- a/src/System.Private.CoreLib/shared/System/Boolean.cs +++ b/src/System.Private.CoreLib/shared/System/Boolean.cs @@ -12,7 +12,6 @@ ** ===========================================================*/ -using System.Diagnostics.Contracts; using System.Globalization; using System.Runtime.CompilerServices; using System.Runtime.Versioning; diff --git a/src/System.Private.CoreLib/shared/System/Byte.cs b/src/System.Private.CoreLib/shared/System/Byte.cs index a0f8ff8c2..e087bd4a4 100644 --- a/src/System.Private.CoreLib/shared/System/Byte.cs +++ b/src/System.Private.CoreLib/shared/System/Byte.cs @@ -185,28 +185,24 @@ namespace System [Pure] public override String ToString() { - Contract.Ensures(Contract.Result<String>() != null); return Number.FormatInt32(m_value, null, NumberFormatInfo.CurrentInfo); } [Pure] public String ToString(String format) { - Contract.Ensures(Contract.Result<String>() != null); return Number.FormatInt32(m_value, format, NumberFormatInfo.CurrentInfo); } [Pure] public String ToString(IFormatProvider provider) { - Contract.Ensures(Contract.Result<String>() != null); return Number.FormatInt32(m_value, null, NumberFormatInfo.GetInstance(provider)); } [Pure] public String ToString(String format, IFormatProvider provider) { - Contract.Ensures(Contract.Result<String>() != null); return Number.FormatInt32(m_value, format, NumberFormatInfo.GetInstance(provider)); } diff --git a/src/System.Private.CoreLib/shared/System/Char.cs b/src/System.Private.CoreLib/shared/System/Char.cs index bce271406..115236986 100644 --- a/src/System.Private.CoreLib/shared/System/Char.cs +++ b/src/System.Private.CoreLib/shared/System/Char.cs @@ -154,14 +154,12 @@ namespace System [Pure] public override String ToString() { - Contract.Ensures(Contract.Result<String>() != null); return Char.ToString(m_value); } [Pure] public String ToString(IFormatProvider provider) { - Contract.Ensures(Contract.Result<String>() != null); return Char.ToString(m_value); } @@ -182,7 +180,6 @@ namespace System { throw new ArgumentNullException(nameof(s)); } - Contract.EndContractBlock(); if (s.Length != 1) { @@ -405,7 +402,6 @@ namespace System { if (culture == null) throw new ArgumentNullException(nameof(culture)); - Contract.EndContractBlock(); return culture.TextInfo.ToUpper(c); } @@ -438,7 +434,6 @@ namespace System { if (culture == null) throw new ArgumentNullException(nameof(culture)); - Contract.EndContractBlock(); return culture.TextInfo.ToLower(c); } @@ -562,7 +557,6 @@ namespace System { throw new ArgumentOutOfRangeException(nameof(index)); } - Contract.EndContractBlock(); char c = s[index]; if (IsLatin1(c)) { @@ -580,7 +574,6 @@ namespace System { throw new ArgumentOutOfRangeException(nameof(index)); } - Contract.EndContractBlock(); char c = s[index]; if (IsLatin1(c)) { @@ -597,7 +590,6 @@ namespace System { throw new ArgumentOutOfRangeException(nameof(index)); } - Contract.EndContractBlock(); char c = s[index]; if (IsLatin1(c)) { @@ -619,7 +611,6 @@ namespace System { throw new ArgumentOutOfRangeException(nameof(index)); } - Contract.EndContractBlock(); char c = s[index]; if (IsLatin1(c)) { @@ -636,7 +627,6 @@ namespace System { throw new ArgumentOutOfRangeException(nameof(index)); } - Contract.EndContractBlock(); char c = s[index]; if (IsLatin1(c)) { @@ -687,7 +677,6 @@ namespace System { throw new ArgumentOutOfRangeException(nameof(index)); } - Contract.EndContractBlock(); char c = s[index]; if (IsLatin1(c)) { @@ -716,7 +705,6 @@ namespace System { throw new ArgumentOutOfRangeException(nameof(index)); } - Contract.EndContractBlock(); char c = s[index]; if (IsLatin1(c)) { @@ -766,7 +754,6 @@ namespace System { throw new ArgumentOutOfRangeException(nameof(index)); } - Contract.EndContractBlock(); char c = s[index]; if (IsLatin1(c)) { @@ -792,7 +779,6 @@ namespace System { throw new ArgumentOutOfRangeException(nameof(index)); } - Contract.EndContractBlock(); return (IsSurrogate(s[index])); } @@ -830,7 +816,6 @@ namespace System { throw new ArgumentOutOfRangeException(nameof(index)); } - Contract.EndContractBlock(); char c = s[index]; if (IsLatin1(c)) { @@ -848,7 +833,6 @@ namespace System { throw new ArgumentOutOfRangeException(nameof(index)); } - Contract.EndContractBlock(); char c = s[index]; if (IsLatin1(c)) { @@ -870,7 +854,6 @@ namespace System { throw new ArgumentOutOfRangeException(nameof(index)); } - Contract.EndContractBlock(); if (IsLatin1(s[index])) { @@ -897,7 +880,6 @@ namespace System { throw new ArgumentOutOfRangeException(nameof(index)); } - Contract.EndContractBlock(); if (IsLatin1(s[index])) { return (GetLatin1UnicodeCategory(s[index])); @@ -918,7 +900,6 @@ namespace System { throw new ArgumentOutOfRangeException(nameof(index)); } - Contract.EndContractBlock(); return CharUnicodeInfo.GetNumericValue(s, index); } @@ -943,7 +924,6 @@ namespace System { throw new ArgumentOutOfRangeException(nameof(index)); } - Contract.EndContractBlock(); return (IsHighSurrogate(s[index])); } @@ -967,7 +947,6 @@ namespace System { throw new ArgumentOutOfRangeException(nameof(index)); } - Contract.EndContractBlock(); return (IsLowSurrogate(s[index])); } @@ -985,7 +964,6 @@ namespace System { throw new ArgumentOutOfRangeException(nameof(index)); } - Contract.EndContractBlock(); if (index + 1 < s.Length) { return (IsSurrogatePair(s[index], s[index + 1])); @@ -1024,7 +1002,6 @@ namespace System { throw new ArgumentOutOfRangeException(nameof(utf32), SR.ArgumentOutOfRange_InvalidUTF32); } - Contract.EndContractBlock(); if (utf32 < UNICODE_PLANE01_START) { @@ -1059,7 +1036,6 @@ namespace System { throw new ArgumentOutOfRangeException(nameof(lowSurrogate), SR.ArgumentOutOfRange_InvalidLowSurrogate); } - Contract.EndContractBlock(); return (((highSurrogate - CharUnicodeInfo.HIGH_SURROGATE_START) * 0x400) + (lowSurrogate - CharUnicodeInfo.LOW_SURROGATE_START) + UNICODE_PLANE01_START); } @@ -1082,7 +1058,6 @@ namespace System { throw new ArgumentOutOfRangeException(nameof(index), SR.ArgumentOutOfRange_Index); } - Contract.EndContractBlock(); // Check if the character at index is a high surrogate. int temp1 = (int)s[index] - CharUnicodeInfo.HIGH_SURROGATE_START; if (temp1 >= 0 && temp1 <= 0x7ff) diff --git a/src/System.Private.CoreLib/shared/System/Collections/Generic/ICollection.cs b/src/System.Private.CoreLib/shared/System/Collections/Generic/ICollection.cs index 52852aa1f..78ee5cb1f 100644 --- a/src/System.Private.CoreLib/shared/System/Collections/Generic/ICollection.cs +++ b/src/System.Private.CoreLib/shared/System/Collections/Generic/ICollection.cs @@ -4,7 +4,6 @@ using System; using System.Runtime.CompilerServices; -using System.Diagnostics.Contracts; namespace System.Collections.Generic { diff --git a/src/System.Private.CoreLib/shared/System/Collections/Generic/IDictionary.cs b/src/System.Private.CoreLib/shared/System/Collections/Generic/IDictionary.cs index a73a2f55b..05677da3b 100644 --- a/src/System.Private.CoreLib/shared/System/Collections/Generic/IDictionary.cs +++ b/src/System.Private.CoreLib/shared/System/Collections/Generic/IDictionary.cs @@ -3,7 +3,6 @@ // See the LICENSE file in the project root for more information. using System; -using System.Diagnostics.Contracts; namespace System.Collections.Generic { diff --git a/src/System.Private.CoreLib/shared/System/Collections/Generic/IEnumerable.cs b/src/System.Private.CoreLib/shared/System/Collections/Generic/IEnumerable.cs index 84264d5cf..ddb798e8a 100644 --- a/src/System.Private.CoreLib/shared/System/Collections/Generic/IEnumerable.cs +++ b/src/System.Private.CoreLib/shared/System/Collections/Generic/IEnumerable.cs @@ -6,7 +6,6 @@ using System; using System.Collections; using System.Runtime.InteropServices; using System.Runtime.CompilerServices; -using System.Diagnostics.Contracts; namespace System.Collections.Generic { diff --git a/src/System.Private.CoreLib/shared/System/Collections/Generic/IList.cs b/src/System.Private.CoreLib/shared/System/Collections/Generic/IList.cs index 43d6659da..2abc7b914 100644 --- a/src/System.Private.CoreLib/shared/System/Collections/Generic/IList.cs +++ b/src/System.Private.CoreLib/shared/System/Collections/Generic/IList.cs @@ -5,7 +5,6 @@ using System; using System.Collections; using System.Runtime.CompilerServices; -using System.Diagnostics.Contracts; namespace System.Collections.Generic { diff --git a/src/System.Private.CoreLib/shared/System/Collections/Generic/IReadOnlyCollection.cs b/src/System.Private.CoreLib/shared/System/Collections/Generic/IReadOnlyCollection.cs index 09ee89f03..9eea39de2 100644 --- a/src/System.Private.CoreLib/shared/System/Collections/Generic/IReadOnlyCollection.cs +++ b/src/System.Private.CoreLib/shared/System/Collections/Generic/IReadOnlyCollection.cs @@ -3,7 +3,6 @@ // See the LICENSE file in the project root for more information. using System; -using System.Diagnostics.Contracts; using System.Runtime.CompilerServices; namespace System.Collections.Generic diff --git a/src/System.Private.CoreLib/shared/System/Collections/Generic/IReadOnlyDictionary.cs b/src/System.Private.CoreLib/shared/System/Collections/Generic/IReadOnlyDictionary.cs index 169e2958b..300b99661 100644 --- a/src/System.Private.CoreLib/shared/System/Collections/Generic/IReadOnlyDictionary.cs +++ b/src/System.Private.CoreLib/shared/System/Collections/Generic/IReadOnlyDictionary.cs @@ -3,7 +3,6 @@ // See the LICENSE file in the project root for more information. using System; -using System.Diagnostics.Contracts; namespace System.Collections.Generic { diff --git a/src/System.Private.CoreLib/shared/System/Collections/Generic/IReadOnlyList.cs b/src/System.Private.CoreLib/shared/System/Collections/Generic/IReadOnlyList.cs index 00b5be65f..7193805b0 100644 --- a/src/System.Private.CoreLib/shared/System/Collections/Generic/IReadOnlyList.cs +++ b/src/System.Private.CoreLib/shared/System/Collections/Generic/IReadOnlyList.cs @@ -3,7 +3,6 @@ // See the LICENSE file in the project root for more information. using System; -using System.Diagnostics.Contracts; using System.Runtime.CompilerServices; namespace System.Collections.Generic diff --git a/src/System.Private.CoreLib/shared/System/Collections/Generic/List.cs b/src/System.Private.CoreLib/shared/System/Collections/Generic/List.cs index f548f8d1b..56bbea895 100644 --- a/src/System.Private.CoreLib/shared/System/Collections/Generic/List.cs +++ b/src/System.Private.CoreLib/shared/System/Collections/Generic/List.cs @@ -4,7 +4,6 @@ using System.Collections.ObjectModel; using System.Diagnostics; -using System.Diagnostics.Contracts; using System.Runtime.CompilerServices; namespace System.Collections.Generic @@ -24,7 +23,6 @@ namespace System.Collections.Generic private const int DefaultCapacity = 4; private T[] _items; // Do not rename (binary serialization) - [ContractPublicPropertyName("Count")] private int _size; // Do not rename (binary serialization) private int _version; // Do not rename (binary serialization) [NonSerialized] @@ -49,7 +47,6 @@ namespace System.Collections.Generic { if (capacity < 0) ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.capacity, ExceptionResource.ArgumentOutOfRange_NeedNonNegNum); - Contract.EndContractBlock(); if (capacity == 0) _items = s_emptyArray; @@ -65,7 +62,6 @@ namespace System.Collections.Generic { if (collection == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.collection); - Contract.EndContractBlock(); ICollection<T> c = collection as ICollection<T>; if (c != null) @@ -98,7 +94,6 @@ namespace System.Collections.Generic { get { - Contract.Ensures(Contract.Result<int>() >= 0); return _items.Length; } set @@ -107,7 +102,6 @@ namespace System.Collections.Generic { ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.value, ExceptionResource.ArgumentOutOfRange_SmallCapacity); } - Contract.EndContractBlock(); if (value != _items.Length) { @@ -133,7 +127,6 @@ namespace System.Collections.Generic { get { - Contract.Ensures(Contract.Result<int>() >= 0); return _size; } } @@ -183,7 +176,6 @@ namespace System.Collections.Generic { ThrowHelper.ThrowArgumentOutOfRange_IndexException(); } - Contract.EndContractBlock(); return _items[index]; } @@ -193,7 +185,6 @@ namespace System.Collections.Generic { ThrowHelper.ThrowArgumentOutOfRange_IndexException(); } - Contract.EndContractBlock(); _items[index] = value; _version++; } @@ -280,14 +271,11 @@ namespace System.Collections.Generic // public void AddRange(IEnumerable<T> collection) { - Contract.Ensures(Count >= Contract.OldValue(Count)); - InsertRange(_size, collection); } public ReadOnlyCollection<T> AsReadOnly() { - Contract.Ensures(Contract.Result<ReadOnlyCollection<T>>() != null); return new ReadOnlyCollection<T>(this); } @@ -319,21 +307,17 @@ namespace System.Collections.Generic ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.count, ExceptionResource.ArgumentOutOfRange_NeedNonNegNum); if (_size - index < count) ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_InvalidOffLen); - Contract.Ensures(Contract.Result<int>() <= index + count); - Contract.EndContractBlock(); return Array.BinarySearch<T>(_items, index, count, item, comparer); } public int BinarySearch(T item) { - Contract.Ensures(Contract.Result<int>() <= Count); return BinarySearch(0, Count, item, null); } public int BinarySearch(T item, IComparer<T> comparer) { - Contract.Ensures(Contract.Result<int>() <= Count); return BinarySearch(0, Count, item, comparer); } @@ -391,7 +375,6 @@ namespace System.Collections.Generic { ThrowHelper.ThrowArgumentNullException(ExceptionArgument.converter); } - Contract.EndContractBlock(); List<TOutput> list = new List<TOutput>(_size); for (int i = 0; i < _size; i++) @@ -417,7 +400,6 @@ namespace System.Collections.Generic { ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_RankMultiDimNotSupported); } - Contract.EndContractBlock(); try { @@ -440,7 +422,6 @@ namespace System.Collections.Generic { ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_InvalidOffLen); } - Contract.EndContractBlock(); // Delegate rest of error checking to Array.Copy. Array.Copy(_items, index, array, arrayIndex, count); @@ -481,7 +462,6 @@ namespace System.Collections.Generic { ThrowHelper.ThrowArgumentNullException(ExceptionArgument.match); } - Contract.EndContractBlock(); for (int i = 0; i < _size; i++) { @@ -499,7 +479,6 @@ namespace System.Collections.Generic { ThrowHelper.ThrowArgumentNullException(ExceptionArgument.match); } - Contract.EndContractBlock(); List<T> list = new List<T>(); for (int i = 0; i < _size; i++) @@ -514,15 +493,11 @@ namespace System.Collections.Generic public int FindIndex(Predicate<T> match) { - Contract.Ensures(Contract.Result<int>() >= -1); - Contract.Ensures(Contract.Result<int>() < Count); return FindIndex(0, _size, match); } public int FindIndex(int startIndex, Predicate<T> match) { - Contract.Ensures(Contract.Result<int>() >= -1); - Contract.Ensures(Contract.Result<int>() < startIndex + Count); return FindIndex(startIndex, _size - startIndex, match); } @@ -542,9 +517,6 @@ namespace System.Collections.Generic { ThrowHelper.ThrowArgumentNullException(ExceptionArgument.match); } - Contract.Ensures(Contract.Result<int>() >= -1); - Contract.Ensures(Contract.Result<int>() < startIndex + count); - Contract.EndContractBlock(); int endIndex = startIndex + count; for (int i = startIndex; i < endIndex; i++) @@ -560,7 +532,6 @@ namespace System.Collections.Generic { ThrowHelper.ThrowArgumentNullException(ExceptionArgument.match); } - Contract.EndContractBlock(); for (int i = _size - 1; i >= 0; i--) { @@ -574,15 +545,11 @@ namespace System.Collections.Generic public int FindLastIndex(Predicate<T> match) { - Contract.Ensures(Contract.Result<int>() >= -1); - Contract.Ensures(Contract.Result<int>() < Count); return FindLastIndex(_size - 1, _size, match); } public int FindLastIndex(int startIndex, Predicate<T> match) { - Contract.Ensures(Contract.Result<int>() >= -1); - Contract.Ensures(Contract.Result<int>() <= startIndex); return FindLastIndex(startIndex, startIndex + 1, match); } @@ -592,9 +559,6 @@ namespace System.Collections.Generic { ThrowHelper.ThrowArgumentNullException(ExceptionArgument.match); } - Contract.Ensures(Contract.Result<int>() >= -1); - Contract.Ensures(Contract.Result<int>() <= startIndex); - Contract.EndContractBlock(); if (_size == 0) { @@ -636,7 +600,6 @@ namespace System.Collections.Generic { ThrowHelper.ThrowArgumentNullException(ExceptionArgument.action); } - Contract.EndContractBlock(); int version = _version; @@ -689,8 +652,6 @@ namespace System.Collections.Generic { ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_InvalidOffLen); } - Contract.Ensures(Contract.Result<List<T>>() != null); - Contract.EndContractBlock(); List<T> list = new List<T>(count); Array.Copy(_items, index, list._items, 0, count); @@ -709,8 +670,6 @@ namespace System.Collections.Generic // public int IndexOf(T item) { - Contract.Ensures(Contract.Result<int>() >= -1); - Contract.Ensures(Contract.Result<int>() < Count); return Array.IndexOf(_items, item, 0, _size); } @@ -736,9 +695,6 @@ namespace System.Collections.Generic { if (index > _size) ThrowHelper.ThrowArgumentOutOfRange_IndexException(); - Contract.Ensures(Contract.Result<int>() >= -1); - Contract.Ensures(Contract.Result<int>() < Count); - Contract.EndContractBlock(); return Array.IndexOf(_items, item, index, _size - index); } @@ -758,9 +714,6 @@ namespace System.Collections.Generic if (count < 0 || index > _size - count) ThrowHelper.ThrowCountArgumentOutOfRange_ArgumentOutOfRange_Count(); - Contract.Ensures(Contract.Result<int>() >= -1); - Contract.Ensures(Contract.Result<int>() < Count); - Contract.EndContractBlock(); return Array.IndexOf(_items, item, index, count); } @@ -776,7 +729,6 @@ namespace System.Collections.Generic { ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.index, ExceptionResource.ArgumentOutOfRange_ListInsert); } - Contract.EndContractBlock(); if (_size == _items.Length) EnsureCapacity(_size + 1); if (index < _size) { @@ -817,7 +769,6 @@ namespace System.Collections.Generic { ThrowHelper.ThrowArgumentOutOfRange_IndexException(); } - Contract.EndContractBlock(); ICollection<T> c = collection as ICollection<T>; if (c != null) @@ -875,8 +826,6 @@ namespace System.Collections.Generic // public int LastIndexOf(T item) { - Contract.Ensures(Contract.Result<int>() >= -1); - Contract.Ensures(Contract.Result<int>() < Count); if (_size == 0) { // Special case for empty list return -1; @@ -900,9 +849,6 @@ namespace System.Collections.Generic { if (index >= _size) ThrowHelper.ThrowArgumentOutOfRange_IndexException(); - Contract.Ensures(Contract.Result<int>() >= -1); - Contract.Ensures(((Count == 0) && (Contract.Result<int>() == -1)) || ((Count > 0) && (Contract.Result<int>() <= index))); - Contract.EndContractBlock(); return LastIndexOf(item, index, index + 1); } @@ -926,9 +872,6 @@ namespace System.Collections.Generic { ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.count, ExceptionResource.ArgumentOutOfRange_NeedNonNegNum); } - Contract.Ensures(Contract.Result<int>() >= -1); - Contract.Ensures(((Count == 0) && (Contract.Result<int>() == -1)) || ((Count > 0) && (Contract.Result<int>() <= index))); - Contract.EndContractBlock(); if (_size == 0) { // Special case for empty list @@ -978,9 +921,6 @@ namespace System.Collections.Generic { ThrowHelper.ThrowArgumentNullException(ExceptionArgument.match); } - Contract.Ensures(Contract.Result<int>() >= 0); - Contract.Ensures(Contract.Result<int>() <= Contract.OldValue(Count)); - Contract.EndContractBlock(); int freeIndex = 0; // the first free slot in items array @@ -1020,7 +960,6 @@ namespace System.Collections.Generic { ThrowHelper.ThrowArgumentOutOfRange_IndexException(); } - Contract.EndContractBlock(); _size--; if (index < _size) { @@ -1048,7 +987,6 @@ namespace System.Collections.Generic if (_size - index < count) ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_InvalidOffLen); - Contract.EndContractBlock(); if (count > 0) { @@ -1092,7 +1030,6 @@ namespace System.Collections.Generic if (_size - index < count) ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_InvalidOffLen); - Contract.EndContractBlock(); if (count > 1) { @@ -1137,7 +1074,6 @@ namespace System.Collections.Generic if (_size - index < count) ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_InvalidOffLen); - Contract.EndContractBlock(); if (count > 1) { @@ -1152,7 +1088,6 @@ namespace System.Collections.Generic { ThrowHelper.ThrowArgumentNullException(ExceptionArgument.comparison); } - Contract.EndContractBlock(); if (_size > 1) { @@ -1165,9 +1100,6 @@ namespace System.Collections.Generic // This requires copying the List, which is an O(n) operation. public T[] ToArray() { - Contract.Ensures(Contract.Result<T[]>() != null); - Contract.Ensures(Contract.Result<T[]>().Length == Count); - if (_size == 0) { return s_emptyArray; @@ -1202,7 +1134,6 @@ namespace System.Collections.Generic { ThrowHelper.ThrowArgumentNullException(ExceptionArgument.match); } - Contract.EndContractBlock(); for (int i = 0; i < _size; i++) { diff --git a/src/System.Private.CoreLib/shared/System/Collections/ICollection.cs b/src/System.Private.CoreLib/shared/System/Collections/ICollection.cs index 8fd6a96b4..f0149020d 100644 --- a/src/System.Private.CoreLib/shared/System/Collections/ICollection.cs +++ b/src/System.Private.CoreLib/shared/System/Collections/ICollection.cs @@ -3,7 +3,6 @@ // See the LICENSE file in the project root for more information. using System; -using System.Diagnostics.Contracts; namespace System.Collections { diff --git a/src/System.Private.CoreLib/shared/System/Collections/IDictionary.cs b/src/System.Private.CoreLib/shared/System/Collections/IDictionary.cs index 8bc7fcf12..b934c2399 100644 --- a/src/System.Private.CoreLib/shared/System/Collections/IDictionary.cs +++ b/src/System.Private.CoreLib/shared/System/Collections/IDictionary.cs @@ -3,7 +3,6 @@ // See the LICENSE file in the project root for more information. using System; -using System.Diagnostics.Contracts; namespace System.Collections { diff --git a/src/System.Private.CoreLib/shared/System/Collections/IEnumerable.cs b/src/System.Private.CoreLib/shared/System/Collections/IEnumerable.cs index 91aec6242..e5edeff26 100644 --- a/src/System.Private.CoreLib/shared/System/Collections/IEnumerable.cs +++ b/src/System.Private.CoreLib/shared/System/Collections/IEnumerable.cs @@ -3,7 +3,6 @@ // See the LICENSE file in the project root for more information. using System; -using System.Diagnostics.Contracts; using System.Runtime.InteropServices; namespace System.Collections @@ -12,7 +11,6 @@ namespace System.Collections { // Returns an IEnumerator for this enumerable Object. The enumerator provides // a simple way to access all the contents of a collection. - [Pure] IEnumerator GetEnumerator(); } } diff --git a/src/System.Private.CoreLib/shared/System/Collections/IList.cs b/src/System.Private.CoreLib/shared/System/Collections/IList.cs index bb2e221cc..0110eca1f 100644 --- a/src/System.Private.CoreLib/shared/System/Collections/IList.cs +++ b/src/System.Private.CoreLib/shared/System/Collections/IList.cs @@ -3,7 +3,6 @@ // See the LICENSE file in the project root for more information. using System; -using System.Diagnostics.Contracts; namespace System.Collections { diff --git a/src/System.Private.CoreLib/shared/System/Collections/ListDictionaryInternal.cs b/src/System.Private.CoreLib/shared/System/Collections/ListDictionaryInternal.cs index 681e51a32..28593d3c8 100644 --- a/src/System.Private.CoreLib/shared/System/Collections/ListDictionaryInternal.cs +++ b/src/System.Private.CoreLib/shared/System/Collections/ListDictionaryInternal.cs @@ -12,7 +12,6 @@ ** ===========================================================*/ -using System.Diagnostics.Contracts; namespace System.Collections { @@ -46,7 +45,6 @@ namespace System.Collections { throw new ArgumentNullException(nameof(key), SR.ArgumentNull_Key); } - Contract.EndContractBlock(); DictionaryNode node = head; while (node != null) @@ -65,7 +63,6 @@ namespace System.Collections { throw new ArgumentNullException(nameof(key), SR.ArgumentNull_Key); } - Contract.EndContractBlock(); version++; @@ -167,7 +164,6 @@ namespace System.Collections { throw new ArgumentNullException(nameof(key), SR.ArgumentNull_Key); } - Contract.EndContractBlock(); version++; @@ -215,7 +211,6 @@ namespace System.Collections { throw new ArgumentNullException(nameof(key), SR.ArgumentNull_Key); } - Contract.EndContractBlock(); for (DictionaryNode node = head; node != null; node = node.next) { if (node.key.Equals(key)) @@ -239,7 +234,6 @@ namespace System.Collections if (array.Length - index < this.Count) throw new ArgumentException(SR.ArgumentOutOfRange_Index, nameof(index)); - Contract.EndContractBlock(); for (DictionaryNode node = head; node != null; node = node.next) { @@ -264,7 +258,6 @@ namespace System.Collections { throw new ArgumentNullException(nameof(key), SR.ArgumentNull_Key); } - Contract.EndContractBlock(); version++; DictionaryNode last = null; DictionaryNode node; @@ -403,7 +396,6 @@ namespace System.Collections throw new ArgumentException(SR.Arg_RankMultiDimNotSupported); if (index < 0) throw new ArgumentOutOfRangeException(nameof(index), SR.ArgumentOutOfRange_NeedNonNegNum); - Contract.EndContractBlock(); if (array.Length - index < list.Count) throw new ArgumentException(SR.ArgumentOutOfRange_Index, nameof(index)); for (DictionaryNode node = list.head; node != null; node = node.next) diff --git a/src/System.Private.CoreLib/shared/System/Convert.cs b/src/System.Private.CoreLib/shared/System/Convert.cs index b16eb7bf2..4a60164f9 100644 --- a/src/System.Private.CoreLib/shared/System/Convert.cs +++ b/src/System.Private.CoreLib/shared/System/Convert.cs @@ -11,7 +11,6 @@ using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Diagnostics; -using System.Diagnostics.Contracts; namespace System { @@ -158,7 +157,6 @@ namespace System // the object does not implement IConvertible), the result is TypeCode.Object. // Otherwise, the result is the type code of the object, as determined by // the object's implementation of IConvertible. - [Pure] public static TypeCode GetTypeCode(object value) { if (value == null) return TypeCode.Empty; @@ -172,7 +170,6 @@ namespace System // Returns true if the given object is a database null. This operation // corresponds to "value.GetTypeCode() == TypeCode.DBNull". - [Pure] public static bool IsDBNull(object value) { if (value == System.DBNull.Value) return true; @@ -263,7 +260,6 @@ namespace System { throw new ArgumentNullException(nameof(targetType)); } - Contract.EndContractBlock(); if (ReferenceEquals(value.GetType(), targetType)) { @@ -324,7 +320,6 @@ namespace System { throw new ArgumentNullException(nameof(conversionType)); } - Contract.EndContractBlock(); if (value == null) { @@ -541,7 +536,6 @@ namespace System public static char ToChar(sbyte value) { if (value < 0) ThrowCharOverflowException(); - Contract.EndContractBlock(); return (char)value; } @@ -553,7 +547,6 @@ namespace System public static char ToChar(short value) { if (value < 0) ThrowCharOverflowException(); - Contract.EndContractBlock(); return (char)value; } @@ -566,7 +559,6 @@ namespace System public static char ToChar(int value) { if (value < 0 || value > Char.MaxValue) ThrowCharOverflowException(); - Contract.EndContractBlock(); return (char)value; } @@ -574,14 +566,12 @@ namespace System public static char ToChar(uint value) { if (value > Char.MaxValue) ThrowCharOverflowException(); - Contract.EndContractBlock(); return (char)value; } public static char ToChar(long value) { if (value < 0 || value > Char.MaxValue) ThrowCharOverflowException(); - Contract.EndContractBlock(); return (char)value; } @@ -589,7 +579,6 @@ namespace System public static char ToChar(ulong value) { if (value > Char.MaxValue) ThrowCharOverflowException(); - Contract.EndContractBlock(); return (char)value; } @@ -606,7 +595,6 @@ namespace System { if (value == null) throw new ArgumentNullException(nameof(value)); - Contract.EndContractBlock(); if (value.Length != 1) throw new FormatException(SR.Format_NeedSingleChar); @@ -674,7 +662,6 @@ namespace System public static sbyte ToSByte(char value) { if (value > SByte.MaxValue) ThrowSByteOverflowException(); - Contract.EndContractBlock(); return (sbyte)value; } @@ -682,7 +669,6 @@ namespace System public static sbyte ToSByte(byte value) { if (value > SByte.MaxValue) ThrowSByteOverflowException(); - Contract.EndContractBlock(); return (sbyte)value; } @@ -690,7 +676,6 @@ namespace System public static sbyte ToSByte(short value) { if (value < SByte.MinValue || value > SByte.MaxValue) ThrowSByteOverflowException(); - Contract.EndContractBlock(); return (sbyte)value; } @@ -698,7 +683,6 @@ namespace System public static sbyte ToSByte(ushort value) { if (value > SByte.MaxValue) ThrowSByteOverflowException(); - Contract.EndContractBlock(); return (sbyte)value; } @@ -706,7 +690,6 @@ namespace System public static sbyte ToSByte(int value) { if (value < SByte.MinValue || value > SByte.MaxValue) ThrowSByteOverflowException(); - Contract.EndContractBlock(); return (sbyte)value; } @@ -714,7 +697,6 @@ namespace System public static sbyte ToSByte(uint value) { if (value > SByte.MaxValue) ThrowSByteOverflowException(); - Contract.EndContractBlock(); return (sbyte)value; } @@ -722,7 +704,6 @@ namespace System public static sbyte ToSByte(long value) { if (value < SByte.MinValue || value > SByte.MaxValue) ThrowSByteOverflowException(); - Contract.EndContractBlock(); return (sbyte)value; } @@ -730,7 +711,6 @@ namespace System public static sbyte ToSByte(ulong value) { if (value > (ulong)SByte.MaxValue) ThrowSByteOverflowException(); - Contract.EndContractBlock(); return (sbyte)value; } @@ -800,7 +780,6 @@ namespace System public static byte ToByte(char value) { if (value > Byte.MaxValue) ThrowByteOverflowException(); - Contract.EndContractBlock(); return (byte)value; } @@ -808,14 +787,12 @@ namespace System public static byte ToByte(sbyte value) { if (value < Byte.MinValue) ThrowByteOverflowException(); - Contract.EndContractBlock(); return (byte)value; } public static byte ToByte(short value) { if (value < Byte.MinValue || value > Byte.MaxValue) ThrowByteOverflowException(); - Contract.EndContractBlock(); return (byte)value; } @@ -823,14 +800,12 @@ namespace System public static byte ToByte(ushort value) { if (value > Byte.MaxValue) ThrowByteOverflowException(); - Contract.EndContractBlock(); return (byte)value; } public static byte ToByte(int value) { if (value < Byte.MinValue || value > Byte.MaxValue) ThrowByteOverflowException(); - Contract.EndContractBlock(); return (byte)value; } @@ -838,14 +813,12 @@ namespace System public static byte ToByte(uint value) { if (value > Byte.MaxValue) ThrowByteOverflowException(); - Contract.EndContractBlock(); return (byte)value; } public static byte ToByte(long value) { if (value < Byte.MinValue || value > Byte.MaxValue) ThrowByteOverflowException(); - Contract.EndContractBlock(); return (byte)value; } @@ -853,7 +826,6 @@ namespace System public static byte ToByte(ulong value) { if (value > Byte.MaxValue) ThrowByteOverflowException(); - Contract.EndContractBlock(); return (byte)value; } @@ -915,7 +887,6 @@ namespace System public static short ToInt16(char value) { if (value > Int16.MaxValue) ThrowInt16OverflowException(); - Contract.EndContractBlock(); return (short)value; } @@ -934,14 +905,12 @@ namespace System public static short ToInt16(ushort value) { if (value > Int16.MaxValue) ThrowInt16OverflowException(); - Contract.EndContractBlock(); return (short)value; } public static short ToInt16(int value) { if (value < Int16.MinValue || value > Int16.MaxValue) ThrowInt16OverflowException(); - Contract.EndContractBlock(); return (short)value; } @@ -949,7 +918,6 @@ namespace System public static short ToInt16(uint value) { if (value > Int16.MaxValue) ThrowInt16OverflowException(); - Contract.EndContractBlock(); return (short)value; } @@ -961,7 +929,6 @@ namespace System public static short ToInt16(long value) { if (value < Int16.MinValue || value > Int16.MaxValue) ThrowInt16OverflowException(); - Contract.EndContractBlock(); return (short)value; } @@ -969,7 +936,6 @@ namespace System public static short ToInt16(ulong value) { if (value > (ulong)Int16.MaxValue) ThrowInt16OverflowException(); - Contract.EndContractBlock(); return (short)value; } @@ -1042,7 +1008,6 @@ namespace System public static ushort ToUInt16(sbyte value) { if (value < 0) ThrowUInt16OverflowException(); - Contract.EndContractBlock(); return (ushort)value; } @@ -1056,7 +1021,6 @@ namespace System public static ushort ToUInt16(short value) { if (value < 0) ThrowUInt16OverflowException(); - Contract.EndContractBlock(); return (ushort)value; } @@ -1064,7 +1028,6 @@ namespace System public static ushort ToUInt16(int value) { if (value < 0 || value > UInt16.MaxValue) ThrowUInt16OverflowException(); - Contract.EndContractBlock(); return (ushort)value; } @@ -1078,7 +1041,6 @@ namespace System public static ushort ToUInt16(uint value) { if (value > UInt16.MaxValue) ThrowUInt16OverflowException(); - Contract.EndContractBlock(); return (ushort)value; } @@ -1087,7 +1049,6 @@ namespace System public static ushort ToUInt16(long value) { if (value < 0 || value > UInt16.MaxValue) ThrowUInt16OverflowException(); - Contract.EndContractBlock(); return (ushort)value; } @@ -1095,7 +1056,6 @@ namespace System public static ushort ToUInt16(ulong value) { if (value > UInt16.MaxValue) ThrowUInt16OverflowException(); - Contract.EndContractBlock(); return (ushort)value; } @@ -1191,7 +1151,6 @@ namespace System public static int ToInt32(uint value) { if (value > Int32.MaxValue) ThrowInt32OverflowException(); - Contract.EndContractBlock(); return (int)value; } @@ -1203,7 +1162,6 @@ namespace System public static int ToInt32(long value) { if (value < Int32.MinValue || value > Int32.MaxValue) ThrowInt32OverflowException(); - Contract.EndContractBlock(); return (int)value; } @@ -1211,7 +1169,6 @@ namespace System public static int ToInt32(ulong value) { if (value > Int32.MaxValue) ThrowInt32OverflowException(); - Contract.EndContractBlock(); return (int)value; } @@ -1304,7 +1261,6 @@ namespace System public static uint ToUInt32(sbyte value) { if (value < 0) ThrowUInt32OverflowException(); - Contract.EndContractBlock(); return (uint)value; } @@ -1318,7 +1274,6 @@ namespace System public static uint ToUInt32(short value) { if (value < 0) ThrowUInt32OverflowException(); - Contract.EndContractBlock(); return (uint)value; } @@ -1332,7 +1287,6 @@ namespace System public static uint ToUInt32(int value) { if (value < 0) ThrowUInt32OverflowException(); - Contract.EndContractBlock(); return (uint)value; } @@ -1346,7 +1300,6 @@ namespace System public static uint ToUInt32(long value) { if (value < 0 || value > UInt32.MaxValue) ThrowUInt32OverflowException(); - Contract.EndContractBlock(); return (uint)value; } @@ -1354,7 +1307,6 @@ namespace System public static uint ToUInt32(ulong value) { if (value > UInt32.MaxValue) ThrowUInt32OverflowException(); - Contract.EndContractBlock(); return (uint)value; } @@ -1468,7 +1420,6 @@ namespace System public static long ToInt64(ulong value) { if (value > Int64.MaxValue) ThrowInt64OverflowException(); - Contract.EndContractBlock(); return (long)value; } @@ -1546,7 +1497,6 @@ namespace System public static ulong ToUInt64(sbyte value) { if (value < 0) ThrowUInt64OverflowException(); - Contract.EndContractBlock(); return (ulong)value; } @@ -1560,7 +1510,6 @@ namespace System public static ulong ToUInt64(short value) { if (value < 0) ThrowUInt64OverflowException(); - Contract.EndContractBlock(); return (ulong)value; } @@ -1574,7 +1523,6 @@ namespace System public static ulong ToUInt64(int value) { if (value < 0) ThrowUInt64OverflowException(); - Contract.EndContractBlock(); return (ulong)value; } @@ -1588,7 +1536,6 @@ namespace System public static ulong ToUInt64(long value) { if (value < 0) ThrowUInt64OverflowException(); - Contract.EndContractBlock(); return (ulong)value; } @@ -2075,189 +2022,159 @@ namespace System public static string ToString(bool value) { - Contract.Ensures(Contract.Result<string>() != null); return value.ToString(); } public static string ToString(bool value, IFormatProvider provider) { - Contract.Ensures(Contract.Result<string>() != null); return value.ToString(); } public static string ToString(char value) { - Contract.Ensures(Contract.Result<string>() != null); return Char.ToString(value); } public static string ToString(char value, IFormatProvider provider) { - Contract.Ensures(Contract.Result<string>() != null); return value.ToString(); } [CLSCompliant(false)] public static string ToString(sbyte value) { - Contract.Ensures(Contract.Result<string>() != null); return value.ToString(CultureInfo.CurrentCulture); } [CLSCompliant(false)] public static string ToString(sbyte value, IFormatProvider provider) { - Contract.Ensures(Contract.Result<string>() != null); return value.ToString(provider); } public static string ToString(byte value) { - Contract.Ensures(Contract.Result<string>() != null); return value.ToString(CultureInfo.CurrentCulture); } public static string ToString(byte value, IFormatProvider provider) { - Contract.Ensures(Contract.Result<string>() != null); return value.ToString(provider); } public static string ToString(short value) { - Contract.Ensures(Contract.Result<string>() != null); return value.ToString(CultureInfo.CurrentCulture); } public static string ToString(short value, IFormatProvider provider) { - Contract.Ensures(Contract.Result<string>() != null); return value.ToString(provider); } [CLSCompliant(false)] public static string ToString(ushort value) { - Contract.Ensures(Contract.Result<string>() != null); return value.ToString(CultureInfo.CurrentCulture); } [CLSCompliant(false)] public static string ToString(ushort value, IFormatProvider provider) { - Contract.Ensures(Contract.Result<string>() != null); return value.ToString(provider); } public static string ToString(int value) { - Contract.Ensures(Contract.Result<string>() != null); return value.ToString(CultureInfo.CurrentCulture); } public static string ToString(int value, IFormatProvider provider) { - Contract.Ensures(Contract.Result<string>() != null); return value.ToString(provider); } [CLSCompliant(false)] public static string ToString(uint value) { - Contract.Ensures(Contract.Result<string>() != null); return value.ToString(CultureInfo.CurrentCulture); } [CLSCompliant(false)] public static string ToString(uint value, IFormatProvider provider) { - Contract.Ensures(Contract.Result<string>() != null); return value.ToString(provider); } public static string ToString(long value) { - Contract.Ensures(Contract.Result<string>() != null); return value.ToString(CultureInfo.CurrentCulture); } public static string ToString(long value, IFormatProvider provider) { - Contract.Ensures(Contract.Result<string>() != null); return value.ToString(provider); } [CLSCompliant(false)] public static string ToString(ulong value) { - Contract.Ensures(Contract.Result<string>() != null); return value.ToString(CultureInfo.CurrentCulture); } [CLSCompliant(false)] public static string ToString(ulong value, IFormatProvider provider) { - Contract.Ensures(Contract.Result<string>() != null); return value.ToString(provider); } public static string ToString(float value) { - Contract.Ensures(Contract.Result<string>() != null); return value.ToString(CultureInfo.CurrentCulture); } public static string ToString(float value, IFormatProvider provider) { - Contract.Ensures(Contract.Result<string>() != null); return value.ToString(provider); } public static string ToString(double value) { - Contract.Ensures(Contract.Result<string>() != null); return value.ToString(CultureInfo.CurrentCulture); } public static string ToString(double value, IFormatProvider provider) { - Contract.Ensures(Contract.Result<string>() != null); return value.ToString(provider); } public static string ToString(decimal value) { - Contract.Ensures(Contract.Result<string>() != null); return value.ToString(CultureInfo.CurrentCulture); } public static string ToString(Decimal value, IFormatProvider provider) { - Contract.Ensures(Contract.Result<string>() != null); return value.ToString(provider); } public static string ToString(DateTime value) { - Contract.Ensures(Contract.Result<string>() != null); return value.ToString(); } public static string ToString(DateTime value, IFormatProvider provider) { - Contract.Ensures(Contract.Result<string>() != null); return value.ToString(provider); } public static String ToString(String value) { - Contract.Ensures(Contract.Result<string>() == value); // We were always skipping the null check here. return value; } public static String ToString(String value, IFormatProvider provider) { - Contract.Ensures(Contract.Result<string>() == value); // We were always skipping the null check here. return value; // avoid the null check } @@ -2275,7 +2192,6 @@ namespace System { throw new ArgumentException(SR.Arg_InvalidBase); } - Contract.EndContractBlock(); if (value == null) { @@ -2299,7 +2215,6 @@ namespace System { throw new ArgumentException(SR.Arg_InvalidBase); } - Contract.EndContractBlock(); if (value == null) { @@ -2325,7 +2240,6 @@ namespace System { throw new ArgumentException(SR.Arg_InvalidBase); } - Contract.EndContractBlock(); if (value == null) { @@ -2352,7 +2266,6 @@ namespace System { throw new ArgumentException(SR.Arg_InvalidBase); } - Contract.EndContractBlock(); if (value == null) { @@ -2375,7 +2288,6 @@ namespace System { throw new ArgumentException(SR.Arg_InvalidBase); } - Contract.EndContractBlock(); return value != null ? ParseNumbers.StringToInt(value.AsReadOnlySpan(), fromBase, ParseNumbers.IsTight) : 0; @@ -2392,7 +2304,6 @@ namespace System { throw new ArgumentException(SR.Arg_InvalidBase); } - Contract.EndContractBlock(); return value != null ? (uint)ParseNumbers.StringToInt(value.AsReadOnlySpan(), fromBase, ParseNumbers.TreatAsUnsigned | ParseNumbers.IsTight) : 0; @@ -2408,7 +2319,6 @@ namespace System { throw new ArgumentException(SR.Arg_InvalidBase); } - Contract.EndContractBlock(); return value != null ? ParseNumbers.StringToLong(value.AsReadOnlySpan(), fromBase, ParseNumbers.IsTight) : 0; @@ -2425,7 +2335,6 @@ namespace System { throw new ArgumentException(SR.Arg_InvalidBase); } - Contract.EndContractBlock(); return value != null ? (ulong)ParseNumbers.StringToLong(value.AsReadOnlySpan(), fromBase, ParseNumbers.TreatAsUnsigned | ParseNumbers.IsTight) : 0; @@ -2438,7 +2347,6 @@ namespace System { throw new ArgumentException(SR.Arg_InvalidBase); } - Contract.EndContractBlock(); return ParseNumbers.IntToString((int)value, toBase, -1, ' ', ParseNumbers.PrintAsI1); } @@ -2449,7 +2357,6 @@ namespace System { throw new ArgumentException(SR.Arg_InvalidBase); } - Contract.EndContractBlock(); return ParseNumbers.IntToString((int)value, toBase, -1, ' ', ParseNumbers.PrintAsI2); } @@ -2460,7 +2367,6 @@ namespace System { throw new ArgumentException(SR.Arg_InvalidBase); } - Contract.EndContractBlock(); return ParseNumbers.IntToString(value, toBase, -1, ' ', 0); } @@ -2471,7 +2377,6 @@ namespace System { throw new ArgumentException(SR.Arg_InvalidBase); } - Contract.EndContractBlock(); return ParseNumbers.LongToString(value, toBase, -1, ' ', 0); } @@ -2481,8 +2386,6 @@ namespace System { throw new ArgumentNullException(nameof(inArray)); } - Contract.Ensures(Contract.Result<string>() != null); - Contract.EndContractBlock(); return ToBase64String(inArray, 0, inArray.Length, Base64FormattingOptions.None); } @@ -2492,8 +2395,6 @@ namespace System { throw new ArgumentNullException(nameof(inArray)); } - Contract.Ensures(Contract.Result<string>() != null); - Contract.EndContractBlock(); return ToBase64String(inArray, 0, inArray.Length, options); } @@ -2513,8 +2414,6 @@ namespace System throw new ArgumentOutOfRangeException(nameof(offset), SR.ArgumentOutOfRange_GenericPositive); if (options < Base64FormattingOptions.None || options > Base64FormattingOptions.InsertLineBreaks) throw new ArgumentException(string.Format(SR.Arg_EnumIllegalVal, (int)options)); - Contract.Ensures(Contract.Result<string>() != null); - Contract.EndContractBlock(); int inArrayLength; int stringLength; @@ -2544,10 +2443,6 @@ namespace System public static int ToBase64CharArray(byte[] inArray, int offsetIn, int length, char[] outArray, int offsetOut) { - Contract.Ensures(Contract.Result<int>() >= 0); - Contract.Ensures(Contract.Result<int>() <= outArray.Length); - Contract.EndContractBlock(); - return ToBase64CharArray(inArray, offsetIn, length, outArray, offsetOut, Base64FormattingOptions.None); } @@ -2569,9 +2464,6 @@ namespace System { throw new ArgumentException(string.Format(SR.Arg_EnumIllegalVal, (int)options)); } - Contract.Ensures(Contract.Result<int>() >= 0); - Contract.Ensures(Contract.Result<int>() <= outArray.Length); - Contract.EndContractBlock(); int retVal; @@ -2710,7 +2602,6 @@ namespace System if (s == null) throw new ArgumentNullException(nameof(s)); - Contract.EndContractBlock(); unsafe { @@ -2743,7 +2634,6 @@ namespace System if (offset > inArray.Length - length) throw new ArgumentOutOfRangeException(nameof(offset), SR.ArgumentOutOfRange_OffsetLength); - Contract.EndContractBlock(); if (inArray.Length == 0) { diff --git a/src/System.Private.CoreLib/shared/System/CurrentSystemTimeZone.cs b/src/System.Private.CoreLib/shared/System/CurrentSystemTimeZone.cs index 3f17d6f37..bab6a92bf 100644 --- a/src/System.Private.CoreLib/shared/System/CurrentSystemTimeZone.cs +++ b/src/System.Private.CoreLib/shared/System/CurrentSystemTimeZone.cs @@ -18,7 +18,6 @@ ============================================================*/ using System; -using System.Diagnostics.Contracts; using System.Text; using System.Collections; using System.Globalization; diff --git a/src/System.Private.CoreLib/shared/System/DateTime.cs b/src/System.Private.CoreLib/shared/System/DateTime.cs index e72654a8d..99a444d5e 100644 --- a/src/System.Private.CoreLib/shared/System/DateTime.cs +++ b/src/System.Private.CoreLib/shared/System/DateTime.cs @@ -4,7 +4,6 @@ using System; using System.Diagnostics; -using System.Diagnostics.Contracts; using System.Threading; using System.Globalization; using System.Runtime; @@ -18,7 +17,6 @@ using Calendar = System.Globalization.Calendar; namespace System { - // This value type represents a date and time. Every DateTime // object has a private field (Ticks) of type Int64 that stores the // date and time as the number of 100 nanosecond intervals since @@ -147,7 +145,6 @@ namespace System { if (ticks < MinTicks || ticks > MaxTicks) throw new ArgumentOutOfRangeException(nameof(ticks), SR.ArgumentOutOfRange_DateTimeBadTicks); - Contract.EndContractBlock(); _dateData = (UInt64)ticks; } @@ -166,7 +163,6 @@ namespace System { throw new ArgumentException(SR.Argument_InvalidDateTimeKind, nameof(kind)); } - Contract.EndContractBlock(); _dateData = ((UInt64)ticks | ((UInt64)kind << KindShift)); } @@ -177,7 +173,6 @@ namespace System throw new ArgumentOutOfRangeException(nameof(ticks), SR.ArgumentOutOfRange_DateTimeBadTicks); } Debug.Assert(kind == DateTimeKind.Local, "Internal Constructor is for local times only"); - Contract.EndContractBlock(); _dateData = ((UInt64)ticks | (isAmbiguousDst ? KindLocalAmbiguousDst : KindLocal)); } @@ -212,7 +207,6 @@ namespace System { throw new ArgumentException(SR.Argument_InvalidDateTimeKind, nameof(kind)); } - Contract.EndContractBlock(); Int64 ticks = DateToTicks(year, month, day) + TimeToTicks(hour, minute, second); _dateData = ((UInt64)ticks | ((UInt64)kind << KindShift)); } @@ -224,7 +218,6 @@ namespace System { if (calendar == null) throw new ArgumentNullException(nameof(calendar)); - Contract.EndContractBlock(); _dateData = (UInt64)calendar.ToDateTime(year, month, day, hour, minute, second, 0).Ticks; } @@ -237,7 +230,6 @@ namespace System { throw new ArgumentOutOfRangeException(nameof(millisecond), SR.Format(SR.ArgumentOutOfRange_Range, 0, MillisPerSecond - 1)); } - Contract.EndContractBlock(); Int64 ticks = DateToTicks(year, month, day) + TimeToTicks(hour, minute, second); ticks += millisecond * TicksPerMillisecond; if (ticks < MinTicks || ticks > MaxTicks) @@ -255,7 +247,6 @@ namespace System { throw new ArgumentException(SR.Argument_InvalidDateTimeKind, nameof(kind)); } - Contract.EndContractBlock(); Int64 ticks = DateToTicks(year, month, day) + TimeToTicks(hour, minute, second); ticks += millisecond * TicksPerMillisecond; if (ticks < MinTicks || ticks > MaxTicks) @@ -274,7 +265,6 @@ namespace System { throw new ArgumentOutOfRangeException(nameof(millisecond), SR.Format(SR.ArgumentOutOfRange_Range, 0, MillisPerSecond - 1)); } - Contract.EndContractBlock(); Int64 ticks = calendar.ToDateTime(year, month, day, hour, minute, second, 0).Ticks; ticks += millisecond * TicksPerMillisecond; if (ticks < MinTicks || ticks > MaxTicks) @@ -294,7 +284,6 @@ namespace System { throw new ArgumentException(SR.Argument_InvalidDateTimeKind, nameof(kind)); } - Contract.EndContractBlock(); Int64 ticks = calendar.ToDateTime(year, month, day, hour, minute, second, 0).Ticks; ticks += millisecond * TicksPerMillisecond; if (ticks < MinTicks || ticks > MaxTicks) @@ -306,7 +295,6 @@ namespace System { if (info == null) throw new ArgumentNullException(nameof(info)); - Contract.EndContractBlock(); Boolean foundTicks = false; Boolean foundDateData = false; @@ -452,7 +440,6 @@ namespace System public DateTime AddMonths(int months) { if (months < -120000 || months > 120000) throw new ArgumentOutOfRangeException(nameof(months), SR.ArgumentOutOfRange_DateTimeBadMonths); - Contract.EndContractBlock(); GetDatePart(out int y, out int m, out int d); int i = m - 1 + months; if (i >= 0) @@ -515,7 +502,6 @@ namespace System // parameter name out of the two for the exception. throw new ArgumentOutOfRangeException("years", SR.ArgumentOutOfRange_DateTimeBadYears); } - Contract.EndContractBlock(); return AddMonths(value * 12); } @@ -589,7 +575,6 @@ namespace System public static int DaysInMonth(int year, int month) { if (month < 1 || month > 12) throw new ArgumentOutOfRangeException(nameof(month), SR.ArgumentOutOfRange_Month); - Contract.EndContractBlock(); // IsLeapYear checks the year argument int[] days = IsLeapYear(year) ? s_daysToMonth366 : s_daysToMonth365; return days[month] - days[month - 1]; @@ -725,7 +710,6 @@ namespace System { throw new ArgumentOutOfRangeException(nameof(fileTime), SR.ArgumentOutOfRange_FileTimeInvalid); } - Contract.EndContractBlock(); // This is the ticks in Universal time for this fileTime. long universalTicks = fileTime + FileTimeOffset; @@ -745,7 +729,6 @@ namespace System { throw new ArgumentNullException(nameof(info)); } - Contract.EndContractBlock(); // Serialize both the old and the new format info.AddValue(TicksField, InternalTicks); @@ -909,8 +892,6 @@ namespace System { get { - Contract.Ensures(Contract.Result<int>() >= 1); - Contract.Ensures(Contract.Result<int>() <= 31); return GetDatePart(DatePartDay); } } @@ -924,8 +905,6 @@ namespace System { get { - Contract.Ensures(Contract.Result<DayOfWeek>() >= DayOfWeek.Sunday); - Contract.Ensures(Contract.Result<DayOfWeek>() <= DayOfWeek.Saturday); return (DayOfWeek)((InternalTicks / TicksPerDay + 1) % 7); } } @@ -937,8 +916,6 @@ namespace System { get { - Contract.Ensures(Contract.Result<int>() >= 1); - Contract.Ensures(Contract.Result<int>() <= 366); // leap year return GetDatePart(DatePartDayOfYear); } } @@ -958,8 +935,6 @@ namespace System { get { - Contract.Ensures(Contract.Result<int>() >= 0); - Contract.Ensures(Contract.Result<int>() < 24); return (int)((InternalTicks / TicksPerHour) % 24); } } @@ -969,7 +944,6 @@ namespace System return (InternalKind == KindLocalAmbiguousDst); } - [Pure] public DateTimeKind Kind { get @@ -993,8 +967,6 @@ namespace System { get { - Contract.Ensures(Contract.Result<int>() >= 0); - Contract.Ensures(Contract.Result<int>() < 1000); return (int)((InternalTicks / TicksPerMillisecond) % 1000); } } @@ -1006,8 +978,6 @@ namespace System { get { - Contract.Ensures(Contract.Result<int>() >= 0); - Contract.Ensures(Contract.Result<int>() < 60); return (int)((InternalTicks / TicksPerMinute) % 60); } } @@ -1019,7 +989,6 @@ namespace System { get { - Contract.Ensures(Contract.Result<int>() >= 1); return GetDatePart(DatePartMonth); } } @@ -1030,8 +999,6 @@ namespace System { get { - Contract.Ensures(Contract.Result<DateTime>().Kind == DateTimeKind.Local); - DateTime utc = UtcNow; Boolean isAmbiguousLocalDst = false; Int64 offset = TimeZoneInfo.GetDateTimeNowUtcOffsetFromUtc(utc, out isAmbiguousLocalDst).Ticks; @@ -1055,8 +1022,6 @@ namespace System { get { - Contract.Ensures(Contract.Result<int>() >= 0); - Contract.Ensures(Contract.Result<int>() < 60); return (int)((InternalTicks / TicksPerSecond) % 60); } } @@ -1103,7 +1068,6 @@ namespace System { get { - Contract.Ensures(Contract.Result<int>() >= 1 && Contract.Result<int>() <= 9999); return GetDatePart(DatePartYear); } } @@ -1117,7 +1081,6 @@ namespace System { throw new ArgumentOutOfRangeException(nameof(year), SR.ArgumentOutOfRange_Year); } - Contract.EndContractBlock(); return year % 4 == 0 && (year % 100 != 0 || year % 400 == 0); } @@ -1265,49 +1228,41 @@ namespace System public String ToLongDateString() { - Contract.Ensures(Contract.Result<String>() != null); return DateTimeFormat.Format(this, "D", DateTimeFormatInfo.CurrentInfo); } public String ToLongTimeString() { - Contract.Ensures(Contract.Result<String>() != null); return DateTimeFormat.Format(this, "T", DateTimeFormatInfo.CurrentInfo); } public String ToShortDateString() { - Contract.Ensures(Contract.Result<String>() != null); return DateTimeFormat.Format(this, "d", DateTimeFormatInfo.CurrentInfo); } public String ToShortTimeString() { - Contract.Ensures(Contract.Result<String>() != null); return DateTimeFormat.Format(this, "t", DateTimeFormatInfo.CurrentInfo); } public override String ToString() { - Contract.Ensures(Contract.Result<String>() != null); return DateTimeFormat.Format(this, null, DateTimeFormatInfo.CurrentInfo); } public String ToString(String format) { - Contract.Ensures(Contract.Result<String>() != null); return DateTimeFormat.Format(this, format, DateTimeFormatInfo.CurrentInfo); } public String ToString(IFormatProvider provider) { - Contract.Ensures(Contract.Result<String>() != null); return DateTimeFormat.Format(this, null, DateTimeFormatInfo.GetInstance(provider)); } public String ToString(String format, IFormatProvider provider) { - Contract.Ensures(Contract.Result<String>() != null); return DateTimeFormat.Format(this, format, DateTimeFormatInfo.GetInstance(provider)); } @@ -1402,7 +1357,6 @@ namespace System // time strings for the current instance of DateTime. public String[] GetDateTimeFormats() { - Contract.Ensures(Contract.Result<String[]>() != null); return (GetDateTimeFormats(CultureInfo.CurrentCulture)); } @@ -1411,7 +1365,6 @@ namespace System // time strings for the current instance of DateTime. public String[] GetDateTimeFormats(IFormatProvider provider) { - Contract.Ensures(Contract.Result<String[]>() != null); return (DateTimeFormat.GetAllDateTimes(this, DateTimeFormatInfo.GetInstance(provider))); } @@ -1421,7 +1374,6 @@ namespace System // time strings for the current instance of DateTime. public String[] GetDateTimeFormats(char format) { - Contract.Ensures(Contract.Result<String[]>() != null); return (GetDateTimeFormats(format, CultureInfo.CurrentCulture)); } @@ -1430,7 +1382,6 @@ namespace System // time strings for the current instance of DateTime. public String[] GetDateTimeFormats(char format, IFormatProvider provider) { - Contract.Ensures(Contract.Result<String[]>() != null); return (DateTimeFormat.GetAllDateTimes(this, format, DateTimeFormatInfo.GetInstance(provider))); } diff --git a/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/ActivityTracker.cs b/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/ActivityTracker.cs index bb52a9bb9..cb0526c1c 100644 --- a/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/ActivityTracker.cs +++ b/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/ActivityTracker.cs @@ -5,12 +5,6 @@ using System; using System.Diagnostics; using System.Threading; -#if !ES_BUILD_AGAINST_DOTNET_V35 -using Contract = System.Diagnostics.Contracts.Contract; -#else -using Contract = Microsoft.Diagnostics.Contracts.Internal.Contract; -#endif - #if ES_BUILD_STANDALONE namespace Microsoft.Diagnostics.Tracing #else @@ -43,7 +37,6 @@ namespace System.Diagnostics.Tracing /// </summary> internal class ActivityTracker { - /// <summary> /// Called on work item begins. The activity name = providerName + activityName without 'Start' suffix. /// It updates CurrentActivityId to track. diff --git a/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/EventDescriptor.cs b/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/EventDescriptor.cs index 8fb471a99..6dce32ce9 100644 --- a/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/EventDescriptor.cs +++ b/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/EventDescriptor.cs @@ -9,12 +9,6 @@ using System.Runtime.InteropServices; using Environment = Microsoft.Diagnostics.Tracing.Internal.Environment; #endif -#if !ES_BUILD_AGAINST_DOTNET_V35 -using Contract = System.Diagnostics.Contracts.Contract; -#else -using Contract = Microsoft.Diagnostics.Contracts.Internal.Contract; -#endif - #if ES_BUILD_STANDALONE namespace Microsoft.Diagnostics.Tracing #else diff --git a/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/EventProvider.cs b/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/EventProvider.cs index a74125a35..d9f174713 100644 --- a/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/EventProvider.cs +++ b/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/EventProvider.cs @@ -14,12 +14,6 @@ using System.Security.Permissions; using System.Threading; using System; -#if !ES_BUILD_AGAINST_DOTNET_V35 -using Contract = System.Diagnostics.Contracts.Contract; -#else -using Contract = Microsoft.Diagnostics.Contracts.Internal.Contract; -#endif - #if ES_BUILD_AGAINST_DOTNET_V35 using Microsoft.Internal; // for Tuple (can't define alias for open generic types so we "use" the whole namespace) #endif @@ -634,7 +628,6 @@ namespace System.Diagnostics.Tracing if ((level <= m_level) || (m_level == 0)) { - // // Check if Keyword is enabled // diff --git a/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/EventSource.cs b/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/EventSource.cs index 4e436e7ba..fb1521398 100644 --- a/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/EventSource.cs +++ b/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/EventSource.cs @@ -197,12 +197,6 @@ using System.Threading.Tasks; using Microsoft.Reflection; -#if !ES_BUILD_AGAINST_DOTNET_V35 -using Contract = System.Diagnostics.Contracts.Contract; -#else -using Contract = Microsoft.Diagnostics.Contracts.Internal.Contract; -#endif - #if CORECLR || ES_BUILD_PN using Internal.Runtime.Augments; #endif @@ -250,7 +244,6 @@ namespace System.Diagnostics.Tracing /// </remarks> public partial class EventSource : IDisposable { - #if FEATURE_EVENTSOURCE_XPLAT private static readonly EventListener persistent_Xplat_Listener = XplatEventLogger.InitializePersistentListener(); #endif //FEATURE_EVENTSOURCE_XPLAT @@ -405,7 +398,6 @@ namespace System.Diagnostics.Tracing { if (eventSourceType == null) throw new ArgumentNullException(nameof(eventSourceType)); - Contract.EndContractBlock(); EventSourceAttribute attrib = (EventSourceAttribute)GetCustomAttributeHelper(eventSourceType, typeof(EventSourceAttribute)); string name = eventSourceType.Name; @@ -473,7 +465,6 @@ namespace System.Diagnostics.Tracing { if (eventSourceType == null) throw new ArgumentNullException(nameof(eventSourceType)); - Contract.EndContractBlock(); byte[] manifestBytes = EventSource.CreateManifestAndDescriptors(eventSourceType, assemblyPathToIncludeInManifest, null, flags); return (manifestBytes == null) ? null : Encoding.UTF8.GetString(manifestBytes, 0, manifestBytes.Length); @@ -1259,7 +1250,6 @@ namespace System.Diagnostics.Tracing #if FEATURE_MANAGED_ETW if (m_eventData[eventId].EnabledForETW) { - #if FEATURE_ACTIVITYSAMPLING // this code should be kept in sync with WriteEventVarargs(). SessionMask etwSessions = SessionMask.All; @@ -1623,7 +1613,6 @@ namespace System.Diagnostics.Tracing { if (eventSourceType == null) throw new ArgumentNullException(nameof(eventSourceType)); - Contract.EndContractBlock(); EventSourceAttribute attrib = (EventSourceAttribute)GetCustomAttributeHelper(eventSourceType, typeof(EventSourceAttribute), flags); if (attrib != null && attrib.Name != null) @@ -3599,7 +3588,6 @@ namespace System.Diagnostics.Tracing string.Compare(startEventMetadata.Name, 0, taskName, 0, taskName.Length) == 0 && string.Compare(startEventMetadata.Name, taskName.Length, s_ActivityStartSuffix, 0, Math.Max(startEventMetadata.Name.Length - taskName.Length, s_ActivityStartSuffix.Length)) == 0) { - // Make the stop event match the start event eventAttribute.Task = (EventTask)startEventMetadata.Descriptor.Task; noTask = false; @@ -4455,7 +4443,6 @@ namespace System.Diagnostics.Tracing { throw new ArgumentNullException(nameof(eventSource)); } - Contract.EndContractBlock(); eventSource.SendCommand(this, 0, 0, EventCommand.Update, true, level, matchAnyKeyword, arguments); } @@ -4470,7 +4457,6 @@ namespace System.Diagnostics.Tracing { throw new ArgumentNullException(nameof(eventSource)); } - Contract.EndContractBlock(); eventSource.SendCommand(this, 0, 0, EventCommand.Update, false, EventLevel.LogAlways, EventKeywords.None, null); } @@ -4946,7 +4932,6 @@ namespace System.Diagnostics.Tracing // do the lazy init if you know it is contract based (EventID >= 0) if (EventId >= 0 && m_payloadNames == null) { - var names = new List<string>(); foreach (var parameter in m_eventSource.m_eventData[EventId].Parameters) { @@ -6461,7 +6446,6 @@ namespace System.Diagnostics.Tracing private string CreateManifestString() { - #if FEATURE_MANAGED_ETW_CHANNELS // Write out the channels if (channelTab != null) @@ -6529,7 +6513,6 @@ namespace System.Diagnostics.Tracing // Write out the tasks if (taskTab != null) { - sb.Append(" <tasks>").AppendLine(); var sortedTasks = new List<int>(taskTab.Keys); sortedTasks.Sort(); diff --git a/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/StubEnvironment.cs b/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/StubEnvironment.cs index b365841d5..5797d4d09 100644 --- a/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/StubEnvironment.cs +++ b/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/StubEnvironment.cs @@ -52,29 +52,6 @@ namespace System.Diagnostics.Tracing.Internal #if ES_BUILD_AGAINST_DOTNET_V35 -namespace Microsoft.Diagnostics.Contracts.Internal -{ - internal class Contract - { - public static void Assert(bool invariant) - { - Assert(invariant, string.Empty); - } - public static void Assert(bool invariant, string message) - { - if (!invariant) - { - if (System.Diagnostics.Debugger.IsAttached) - System.Diagnostics.Debugger.Break(); - throw new Exception("Assertion failed: " + message); - } - } - public static void EndContractBlock() - { } - } -} - - namespace Microsoft.Internal { using System.Text; diff --git a/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/EventPayload.cs b/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/EventPayload.cs index 5967ad6ab..abe9ece13 100644 --- a/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/EventPayload.cs +++ b/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/EventPayload.cs @@ -6,12 +6,6 @@ using System.Collections.Generic; using System.Collections; using System.Diagnostics; -#if !ES_BUILD_AGAINST_DOTNET_V35 -using Contract = System.Diagnostics.Contracts.Contract; -#else -using Contract = Microsoft.Diagnostics.Contracts.Internal.Contract; -#endif - #if ES_BUILD_STANDALONE namespace Microsoft.Diagnostics.Tracing #else diff --git a/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/EventSourceActivity.cs b/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/EventSourceActivity.cs index acc3eeb23..ef2ec4715 100644 --- a/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/EventSourceActivity.cs +++ b/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/EventSourceActivity.cs @@ -4,12 +4,6 @@ using System; -#if !ES_BUILD_AGAINST_DOTNET_V35 -using Contract = System.Diagnostics.Contracts.Contract; -#else -using Contract = Microsoft.Diagnostics.Contracts.Internal.Contract; -#endif - #if ES_BUILD_STANDALONE namespace Microsoft.Diagnostics.Tracing #else @@ -36,7 +30,6 @@ namespace System.Diagnostics.Tracing { if (eventSource == null) throw new ArgumentNullException(nameof(eventSource)); - Contract.EndContractBlock(); this.eventSource = eventSource; } diff --git a/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/PropertyValue.cs b/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/PropertyValue.cs index aeee3ad9e..d74494bc8 100644 --- a/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/PropertyValue.cs +++ b/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/PropertyValue.cs @@ -2,12 +2,6 @@ using System.Runtime.InteropServices; using System.Diagnostics; -#if !ES_BUILD_AGAINST_DOTNET_V35 -using Contract = System.Diagnostics.Contracts.Contract; -#else -using Contract = Microsoft.Diagnostics.Contracts.Internal.Contract; -#endif - namespace System.Diagnostics.Tracing { /// <summary> diff --git a/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/SimpleTypeInfos.cs b/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/SimpleTypeInfos.cs index 901a0ed1a..61cb92ffa 100644 --- a/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/SimpleTypeInfos.cs +++ b/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/SimpleTypeInfos.cs @@ -7,12 +7,6 @@ using System.Collections.Generic; using System.Reflection; using System.Diagnostics; -#if !ES_BUILD_AGAINST_DOTNET_V35 -using Contract = System.Diagnostics.Contracts.Contract; -#else -using Contract = Microsoft.Diagnostics.Contracts.Internal.Contract; -#endif - #if ES_BUILD_STANDALONE namespace Microsoft.Diagnostics.Tracing #else diff --git a/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/TraceLoggingEventSource.cs b/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/TraceLoggingEventSource.cs index a1218d1a7..8d12b64a0 100644 --- a/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/TraceLoggingEventSource.cs +++ b/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/TraceLoggingEventSource.cs @@ -29,11 +29,9 @@ using System.Security; using System.Collections.ObjectModel; #if !ES_BUILD_AGAINST_DOTNET_V35 -using Contract = System.Diagnostics.Contracts.Contract; using System.Collections.Generic; using System.Text; #else -using Contract = Microsoft.Diagnostics.Contracts.Internal.Contract; using System.Collections.Generic; using System.Text; #endif @@ -102,7 +100,6 @@ namespace System.Diagnostics.Tracing { throw new ArgumentNullException(nameof(eventSourceName)); } - Contract.EndContractBlock(); } /// <summary> @@ -117,7 +114,6 @@ namespace System.Diagnostics.Tracing throw new ArgumentNullException(nameof(eventName)); } - Contract.EndContractBlock(); if (!this.IsEnabled()) { @@ -144,7 +140,6 @@ namespace System.Diagnostics.Tracing throw new ArgumentNullException(nameof(eventName)); } - Contract.EndContractBlock(); if (!this.IsEnabled()) { diff --git a/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/TraceLoggingEventTypes.cs b/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/TraceLoggingEventTypes.cs index c2239671b..d024b218d 100644 --- a/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/TraceLoggingEventTypes.cs +++ b/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/TraceLoggingEventTypes.cs @@ -6,12 +6,6 @@ using System; using System.Collections.Generic; using Interlocked = System.Threading.Interlocked; -#if !ES_BUILD_AGAINST_DOTNET_V35 -using Contract = System.Diagnostics.Contracts.Contract; -#else -using Contract = Microsoft.Diagnostics.Contracts.Internal.Contract; -#endif - #if ES_BUILD_STANDALONE namespace Microsoft.Diagnostics.Tracing #else @@ -97,7 +91,6 @@ namespace System.Diagnostics.Tracing throw new ArgumentNullException(nameof(name)); } - Contract.EndContractBlock(); this.typeInfos = MakeArray(paramInfos); this.name = name; @@ -135,7 +128,6 @@ namespace System.Diagnostics.Tracing throw new ArgumentNullException(nameof(defaultName)); } - Contract.EndContractBlock(); this.typeInfos = typeInfos; this.name = defaultName; @@ -215,7 +207,6 @@ namespace System.Diagnostics.Tracing throw new ArgumentNullException(nameof(paramInfos)); } - Contract.EndContractBlock(); var recursionCheck = new List<Type>(paramInfos.Length); var result = new TraceLoggingTypeInfo[paramInfos.Length]; @@ -234,7 +225,6 @@ namespace System.Diagnostics.Tracing throw new ArgumentNullException(nameof(types)); } - Contract.EndContractBlock(); var recursionCheck = new List<Type>(types.Length); var result = new TraceLoggingTypeInfo[types.Length]; @@ -254,7 +244,6 @@ namespace System.Diagnostics.Tracing throw new ArgumentNullException(nameof(typeInfos)); } - Contract.EndContractBlock(); return (TraceLoggingTypeInfo[])typeInfos.Clone(); ; } diff --git a/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/TraceLoggingTypeInfo.cs b/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/TraceLoggingTypeInfo.cs index d68e106b0..81f80c63f 100644 --- a/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/TraceLoggingTypeInfo.cs +++ b/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/TraceLoggingTypeInfo.cs @@ -5,12 +5,6 @@ using System; using System.Collections.Generic; -#if !ES_BUILD_AGAINST_DOTNET_V35 -using Contract = System.Diagnostics.Contracts.Contract; -#else -using Contract = Microsoft.Diagnostics.Contracts.Internal.Contract; -#endif - #if ES_BUILD_STANDALONE namespace Microsoft.Diagnostics.Tracing #else @@ -39,7 +33,6 @@ namespace System.Diagnostics.Tracing throw new ArgumentNullException(nameof(dataType)); } - Contract.EndContractBlock(); this.name = dataType.Name; this.dataType = dataType; @@ -64,7 +57,6 @@ namespace System.Diagnostics.Tracing throw new ArgumentNullException(nameof(name)); } - Contract.EndContractBlock(); Statics.CheckName(name); diff --git a/src/System.Private.CoreLib/shared/System/Double.cs b/src/System.Private.CoreLib/shared/System/Double.cs index 7ee52027f..363c896fa 100644 --- a/src/System.Private.CoreLib/shared/System/Double.cs +++ b/src/System.Private.CoreLib/shared/System/Double.cs @@ -12,7 +12,6 @@ ** ===========================================================*/ -using System.Diagnostics.Contracts; using System.Globalization; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; @@ -44,7 +43,6 @@ namespace System internal const double NegativeZero = -0.0; /// <summary>Determines whether the specified value is finite (zero, subnormal, or normal).</summary> - [Pure] [NonVersionable] [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static bool IsFinite(double d) @@ -54,7 +52,6 @@ namespace System } /// <summary>Determines whether the specified value is infinite.</summary> - [Pure] [NonVersionable] [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static bool IsInfinity(double d) @@ -64,7 +61,6 @@ namespace System } /// <summary>Determines whether the specified value is NaN.</summary> - [Pure] [NonVersionable] [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static bool IsNaN(double d) @@ -74,7 +70,6 @@ namespace System } /// <summary>Determines whether the specified value is negative.</summary> - [Pure] [NonVersionable] [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static bool IsNegative(double d) @@ -84,7 +79,6 @@ namespace System } /// <summary>Determines whether the specified value is negative infinity.</summary> - [Pure] [NonVersionable] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool IsNegativeInfinity(double d) @@ -93,7 +87,6 @@ namespace System } /// <summary>Determines whether the specified value is normal.</summary> - [Pure] [NonVersionable] // This is probably not worth inlining, it has branches and should be rarely called public unsafe static bool IsNormal(double d) @@ -104,7 +97,6 @@ namespace System } /// <summary>Determines whether the specified value is positive infinity.</summary> - [Pure] [NonVersionable] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool IsPositiveInfinity(double d) @@ -113,7 +105,6 @@ namespace System } /// <summary>Determines whether the specified value is subnormal.</summary> - [Pure] [NonVersionable] // This is probably not worth inlining, it has branches and should be rarely called public unsafe static bool IsSubnormal(double d) @@ -244,25 +235,21 @@ namespace System public override String ToString() { - Contract.Ensures(Contract.Result<String>() != null); return Number.FormatDouble(m_value, null, NumberFormatInfo.CurrentInfo); } public String ToString(String format) { - Contract.Ensures(Contract.Result<String>() != null); return Number.FormatDouble(m_value, format, NumberFormatInfo.CurrentInfo); } public String ToString(IFormatProvider provider) { - Contract.Ensures(Contract.Result<String>() != null); return Number.FormatDouble(m_value, null, NumberFormatInfo.GetInstance(provider)); } public String ToString(String format, IFormatProvider provider) { - Contract.Ensures(Contract.Result<String>() != null); return Number.FormatDouble(m_value, format, NumberFormatInfo.GetInstance(provider)); } diff --git a/src/System.Private.CoreLib/shared/System/Globalization/Calendar.cs b/src/System.Private.CoreLib/shared/System/Globalization/Calendar.cs index e6ab2477d..49ad597ce 100644 --- a/src/System.Private.CoreLib/shared/System/Globalization/Calendar.cs +++ b/src/System.Private.CoreLib/shared/System/Globalization/Calendar.cs @@ -3,7 +3,6 @@ // See the LICENSE file in the project root for more information. using System.Diagnostics; -using System.Diagnostics.Contracts; using System.Runtime.Serialization; namespace System.Globalization @@ -151,7 +150,6 @@ namespace System.Globalization public static Calendar ReadOnly(Calendar calendar) { if (calendar == null) { throw new ArgumentNullException(nameof(calendar)); } - Contract.EndContractBlock(); if (calendar.IsReadOnly) { return (calendar); } Calendar clonedCalendar = (Calendar)(calendar.MemberwiseClone()); @@ -211,7 +209,6 @@ namespace System.Globalization String.Format(CultureInfo.InvariantCulture, SR.Format(SR.Argument_ResultCalendarRange, minValue, maxValue))); } - Contract.EndContractBlock(); } internal DateTime Add(DateTime time, double value, int scale) @@ -633,7 +630,6 @@ namespace System.Globalization nameof(firstDayOfWeek), SR.Format(SR.ArgumentOutOfRange_Range, DayOfWeek.Sunday, DayOfWeek.Saturday)); } - Contract.EndContractBlock(); switch (rule) { case CalendarWeekRule.FirstDay: @@ -803,7 +799,6 @@ namespace System.Globalization throw new ArgumentOutOfRangeException(nameof(year), SR.ArgumentOutOfRange_NeedNonNegNum); } - Contract.EndContractBlock(); if (year < 100) { return ((TwoDigitYearMax / 100 - (year > TwoDigitYearMax % 100 ? 1 : 0)) * 100 + year); diff --git a/src/System.Private.CoreLib/shared/System/Globalization/CalendarData.Unix.cs b/src/System.Private.CoreLib/shared/System/Globalization/CalendarData.Unix.cs index a2ceeb1e6..35ee82d3c 100644 --- a/src/System.Private.CoreLib/shared/System/Globalization/CalendarData.Unix.cs +++ b/src/System.Private.CoreLib/shared/System/Globalization/CalendarData.Unix.cs @@ -4,7 +4,6 @@ using System.Collections.Generic; using System.Diagnostics; -using System.Diagnostics.Contracts; using System.Runtime.InteropServices; using System.Security; using System.Text; diff --git a/src/System.Private.CoreLib/shared/System/Globalization/ChineseLunisolarCalendar.cs b/src/System.Private.CoreLib/shared/System/Globalization/ChineseLunisolarCalendar.cs index e09011a9d..d2b52b97b 100644 --- a/src/System.Private.CoreLib/shared/System/Globalization/ChineseLunisolarCalendar.cs +++ b/src/System.Private.CoreLib/shared/System/Globalization/ChineseLunisolarCalendar.cs @@ -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.Diagnostics.Contracts; namespace System.Globalization { @@ -320,7 +319,6 @@ namespace System.Globalization CultureInfo.CurrentCulture, SR.ArgumentOutOfRange_Range, MIN_LUNISOLAR_YEAR, MAX_LUNISOLAR_YEAR)); } - Contract.EndContractBlock(); return s_yinfo[lunarYear - MIN_LUNISOLAR_YEAR, index]; } @@ -345,7 +343,6 @@ namespace System.Globalization CultureInfo.CurrentCulture, SR.ArgumentOutOfRange_Range, MIN_LUNISOLAR_YEAR, MAX_LUNISOLAR_YEAR)); } - Contract.EndContractBlock(); return year; } diff --git a/src/System.Private.CoreLib/shared/System/Globalization/CultureData.Unix.cs b/src/System.Private.CoreLib/shared/System/Globalization/CultureData.Unix.cs index 4f685de58..c21d8c3f2 100644 --- a/src/System.Private.CoreLib/shared/System/Globalization/CultureData.Unix.cs +++ b/src/System.Private.CoreLib/shared/System/Globalization/CultureData.Unix.cs @@ -5,7 +5,6 @@ using System; using System.Collections.Generic; using System.Diagnostics; -using System.Diagnostics.Contracts; using System.Runtime.InteropServices; using System.Security; using System.Text; diff --git a/src/System.Private.CoreLib/shared/System/Globalization/DateTimeFormat.cs b/src/System.Private.CoreLib/shared/System/Globalization/DateTimeFormat.cs index d6afc1b09..f129f7313 100644 --- a/src/System.Private.CoreLib/shared/System/Globalization/DateTimeFormat.cs +++ b/src/System.Private.CoreLib/shared/System/Globalization/DateTimeFormat.cs @@ -4,7 +4,6 @@ using System.Collections.Generic; using System.Diagnostics; -using System.Diagnostics.Contracts; using System.Globalization; using System.Text; @@ -970,7 +969,7 @@ namespace System internal static String Format(DateTime dateTime, String format, DateTimeFormatInfo dtfi, TimeSpan offset) { - Contract.Requires(dtfi != null); + Debug.Assert(dtfi != null); if (format == null || format.Length == 0) { Boolean timeOnlySpecialCase = false; @@ -1130,7 +1129,7 @@ namespace System internal static String[] GetAllDateTimes(DateTime dateTime, char format, DateTimeFormatInfo dtfi) { - Contract.Requires(dtfi != null); + Debug.Assert(dtfi != null); String[] allFormats = null; String[] results = null; diff --git a/src/System.Private.CoreLib/shared/System/Globalization/DateTimeFormatInfo.cs b/src/System.Private.CoreLib/shared/System/Globalization/DateTimeFormatInfo.cs index 9f8c072c9..7c4200af7 100644 --- a/src/System.Private.CoreLib/shared/System/Globalization/DateTimeFormatInfo.cs +++ b/src/System.Private.CoreLib/shared/System/Globalization/DateTimeFormatInfo.cs @@ -4,7 +4,6 @@ using System.Collections.Generic; using System.Diagnostics; -using System.Diagnostics.Contracts; using System.Runtime.Serialization; namespace System.Globalization @@ -430,7 +429,6 @@ namespace System.Globalization { get { - Contract.Ensures(Contract.Result<DateTimeFormatInfo>() != null); if (s_invariantInfo == null) { DateTimeFormatInfo info = new DateTimeFormatInfo(); @@ -449,7 +447,6 @@ namespace System.Globalization { get { - Contract.Ensures(Contract.Result<DateTimeFormatInfo>() != null); System.Globalization.CultureInfo culture = System.Globalization.CultureInfo.CurrentCulture; if (!culture._isInherited) { @@ -531,7 +528,6 @@ namespace System.Globalization throw new ArgumentNullException(nameof(value), SR.ArgumentNull_String); } - Contract.EndContractBlock(); ClearTokenHashTable(); amDesignator = value; } @@ -542,8 +538,6 @@ namespace System.Globalization { get { - Contract.Ensures(Contract.Result<Calendar>() != null); - Debug.Assert(this.calendar != null, "DateTimeFormatInfo.Calendar: calendar != null"); return (this.calendar); } @@ -556,7 +550,6 @@ namespace System.Globalization { throw new ArgumentNullException(nameof(value), SR.ArgumentNull_Obj); } - Contract.EndContractBlock(); if (value == calendar) { return; @@ -664,7 +657,6 @@ namespace System.Globalization throw new ArgumentNullException(nameof(eraName), SR.ArgumentNull_String); } - Contract.EndContractBlock(); // The Era Name and Abbreviated Era Name // for Taiwan Calendar on non-Taiwan SKU returns empty string (which @@ -820,7 +812,6 @@ namespace System.Globalization { throw new ArgumentNullException(nameof(value), SR.ArgumentNull_String); } - Contract.EndContractBlock(); ClearTokenHashTable(); dateSeparator = value; } @@ -905,7 +896,6 @@ namespace System.Globalization throw new ArgumentNullException(nameof(value), SR.ArgumentNull_String); } - Contract.EndContractBlock(); fullDateTimePattern = value; } } @@ -939,7 +929,6 @@ namespace System.Globalization throw new ArgumentNullException(nameof(value), SR.ArgumentNull_String); } - Contract.EndContractBlock(); // Remember the new string this.longDatePattern = value; @@ -980,7 +969,6 @@ namespace System.Globalization throw new ArgumentNullException(nameof(value), SR.ArgumentNull_String); } - Contract.EndContractBlock(); // Remember the new string this.longTimePattern = value; @@ -1019,7 +1007,6 @@ namespace System.Globalization throw new ArgumentNullException(nameof(value), SR.ArgumentNull_String); } - Contract.EndContractBlock(); this.monthDayPattern = value; } @@ -1047,7 +1034,6 @@ namespace System.Globalization throw new ArgumentNullException(nameof(value), SR.ArgumentNull_String); } - Contract.EndContractBlock(); ClearTokenHashTable(); pmDesignator = value; @@ -1089,7 +1075,6 @@ namespace System.Globalization if (value == null) throw new ArgumentNullException(nameof(value), SR.ArgumentNull_String); - Contract.EndContractBlock(); // Remember the new string this.shortDatePattern = value; @@ -1132,7 +1117,6 @@ namespace System.Globalization throw new ArgumentNullException(nameof(value), SR.ArgumentNull_String); } - Contract.EndContractBlock(); // Remember the new string this.shortTimePattern = value; @@ -1289,7 +1273,6 @@ namespace System.Globalization throw new ArgumentNullException(nameof(value), SR.ArgumentNull_String); } - Contract.EndContractBlock(); ClearTokenHashTable(); timeSeparator = value; @@ -1331,7 +1314,6 @@ namespace System.Globalization throw new ArgumentNullException(nameof(value), SR.ArgumentNull_String); } - Contract.EndContractBlock(); // Remember the new string this.yearMonthPattern = value; @@ -1379,7 +1361,6 @@ namespace System.Globalization { throw new ArgumentException(SR.Format(SR.Argument_InvalidArrayLength, 7), nameof(value)); } - Contract.EndContractBlock(); CheckNullValue(value, value.Length); ClearTokenHashTable(); @@ -1408,7 +1389,6 @@ namespace System.Globalization { throw new ArgumentException(SR.Format(SR.Argument_InvalidArrayLength, 7), nameof(value)); } - Contract.EndContractBlock(); CheckNullValue(value, value.Length); this.m_superShortDayNames = value; } @@ -1435,7 +1415,6 @@ namespace System.Globalization { throw new ArgumentException(SR.Format(SR.Argument_InvalidArrayLength, 7), nameof(value)); } - Contract.EndContractBlock(); CheckNullValue(value, value.Length); ClearTokenHashTable(); @@ -1464,7 +1443,6 @@ namespace System.Globalization { throw new ArgumentException(SR.Format(SR.Argument_InvalidArrayLength, 13), nameof(value)); } - Contract.EndContractBlock(); CheckNullValue(value, value.Length - 1); ClearTokenHashTable(); abbreviatedMonthNames = value; @@ -1492,7 +1470,6 @@ namespace System.Globalization { throw new ArgumentException(SR.Format(SR.Argument_InvalidArrayLength, 13), nameof(value)); } - Contract.EndContractBlock(); CheckNullValue(value, value.Length - 1); monthNames = value; ClearTokenHashTable(); @@ -1620,7 +1597,6 @@ namespace System.Globalization nameof(dayofweek), SR.Format(SR.ArgumentOutOfRange_Range, DayOfWeek.Sunday, DayOfWeek.Saturday)); } - Contract.EndContractBlock(); // // Don't call the public property AbbreviatedDayNames here since a clone is needed in that // property, so it will be slower. Instead, use GetAbbreviatedDayOfWeekNames() directly. @@ -1637,7 +1613,6 @@ namespace System.Globalization nameof(dayOfWeek), SR.Format(SR.ArgumentOutOfRange_Range, DayOfWeek.Sunday, DayOfWeek.Saturday)); } - Contract.EndContractBlock(); // // Don't call the public property SuperShortDayNames here since a clone is needed in that // property, so it will be slower. Instead, use internalGetSuperShortDayNames() directly. @@ -1686,7 +1661,6 @@ namespace System.Globalization public string[] GetAllDateTimePatterns(char format) { - Contract.Ensures(Contract.Result<String[]>() != null); String[] result = null; switch (format) @@ -1753,7 +1727,6 @@ namespace System.Globalization nameof(dayofweek), SR.Format(SR.ArgumentOutOfRange_Range, DayOfWeek.Sunday, DayOfWeek.Saturday)); } - Contract.EndContractBlock(); // Use the internal one so that we don't clone the array unnecessarily return (internalGetDayOfWeekNames()[(int)dayofweek]); @@ -1769,7 +1742,6 @@ namespace System.Globalization nameof(month), SR.Format(SR.ArgumentOutOfRange_Range, 1, 13)); } - Contract.EndContractBlock(); // Use the internal one so we don't clone the array unnecessarily return (internalGetAbbreviatedMonthNames()[month - 1]); } @@ -1783,7 +1755,6 @@ namespace System.Globalization nameof(month), SR.Format(SR.ArgumentOutOfRange_Range, 1, 13)); } - Contract.EndContractBlock(); // Use the internal one so we don't clone the array unnecessarily return (internalGetMonthNames()[month - 1]); } @@ -1988,7 +1959,6 @@ namespace System.Globalization throw new ArgumentNullException(nameof(dtfi), SR.ArgumentNull_Obj); } - Contract.EndContractBlock(); if (dtfi.IsReadOnly) { return (dtfi); @@ -2055,7 +2025,6 @@ namespace System.Globalization throw new ArgumentException(SR.Arg_ArrayZeroError, nameof(patterns)); } - Contract.EndContractBlock(); for (int i = 0; i < patterns.Length; i++) { @@ -2122,7 +2091,6 @@ namespace System.Globalization { throw new ArgumentException(SR.Format(SR.Argument_InvalidArrayLength, 13), nameof(value)); } - Contract.EndContractBlock(); CheckNullValue(value, value.Length - 1); ClearTokenHashTable(); this.m_genitiveAbbreviatedMonthNames = value; @@ -2149,7 +2117,6 @@ namespace System.Globalization { throw new ArgumentException(SR.Format(SR.Argument_InvalidArrayLength, 13), nameof(value)); } - Contract.EndContractBlock(); CheckNullValue(value, value.Length - 1); genitiveMonthNames = value; ClearTokenHashTable(); @@ -2229,7 +2196,6 @@ namespace System.Globalization { throw new ArgumentException(SR.Argument_ConflictingDateTimeStyles, parameterName); } - Contract.EndContractBlock(); if (((style & DateTimeStyles.RoundtripKind) != 0) && ((style & (DateTimeStyles.AssumeLocal | DateTimeStyles.AssumeUniversal | DateTimeStyles.AdjustToUniversal)) != 0)) { diff --git a/src/System.Private.CoreLib/shared/System/Globalization/DateTimeFormatInfoScanner.cs b/src/System.Private.CoreLib/shared/System/Globalization/DateTimeFormatInfoScanner.cs index 15af1b7d8..c38e7a26b 100644 --- a/src/System.Private.CoreLib/shared/System/Globalization/DateTimeFormatInfoScanner.cs +++ b/src/System.Private.CoreLib/shared/System/Globalization/DateTimeFormatInfoScanner.cs @@ -24,7 +24,6 @@ using System.Text; namespace System.Globalization { - #if CORECLR using StringStringDictionary = Dictionary<string, string>; using StringList = List<string>; diff --git a/src/System.Private.CoreLib/shared/System/Globalization/DateTimeParse.cs b/src/System.Private.CoreLib/shared/System/Globalization/DateTimeParse.cs index f821a9541..2825f0107 100644 --- a/src/System.Private.CoreLib/shared/System/Globalization/DateTimeParse.cs +++ b/src/System.Private.CoreLib/shared/System/Globalization/DateTimeParse.cs @@ -3,7 +3,6 @@ // See the LICENSE file in the project root for more information. using System.Diagnostics; -using System.Diagnostics.Contracts; using System.Globalization; using System.Text; @@ -4678,7 +4677,6 @@ new DS[] { DS.ERROR, DS.TX_NNN, DS.TX_NNN, DS.TX_NNN, DS.ERROR, DS.ERROR, // COMPlus_LogToConsole=1 // COMPlus_LogLevel=9 // COMPlus_ManagedLogFacility=0x00001000 - [Pure] [Conditional("_LOGGING")] internal static void LexTraceExit(string message, DS dps) { @@ -4688,7 +4686,6 @@ new DS[] { DS.ERROR, DS.TX_NNN, DS.TX_NNN, DS.TX_NNN, DS.ERROR, DS.ERROR, BCLDebug.Trace("DATETIME", "[DATETIME] Lex return {0}, DS.{1}", message, dps); #endif // _LOGGING } - [Pure] [Conditional("_LOGGING")] internal static void PTSTraceExit(DS dps, bool passed) { @@ -4698,7 +4695,6 @@ new DS[] { DS.ERROR, DS.TX_NNN, DS.TX_NNN, DS.TX_NNN, DS.ERROR, DS.ERROR, BCLDebug.Trace("DATETIME", "[DATETIME] ProcessTerminalState {0} @ DS.{1}", passed ? "passed" : "failed", dps); #endif // _LOGGING } - [Pure] [Conditional("_LOGGING")] internal static void TPTraceExit(string message, DS dps) { @@ -4708,7 +4704,6 @@ new DS[] { DS.ERROR, DS.TX_NNN, DS.TX_NNN, DS.TX_NNN, DS.ERROR, DS.ERROR, BCLDebug.Trace("DATETIME", "[DATETIME] TryParse return {0}, DS.{1}", message, dps); #endif // _LOGGING } - [Pure] [Conditional("_LOGGING")] internal static void DTFITrace(DateTimeFormatInfo dtfi) { @@ -4733,7 +4728,6 @@ new DS[] { DS.ERROR, DS.TX_NNN, DS.TX_NNN, DS.TX_NNN, DS.ERROR, DS.ERROR, #endif // _LOGGING } #if _LOGGING - [Pure] // return a string in the form: "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" internal static string Hex(string[] strs) { @@ -4787,7 +4781,6 @@ new DS[] { DS.ERROR, DS.TX_NNN, DS.TX_NNN, DS.TX_NNN, DS.ERROR, DS.ERROR, buffer.Append(s); return buffer.ToString(); } - [Pure] // return a string in the form: "Sun" internal static string Hex(string str) { @@ -4803,7 +4796,6 @@ new DS[] { DS.ERROR, DS.TX_NNN, DS.TX_NNN, DS.TX_NNN, DS.ERROR, DS.ERROR, buffer.Append("\""); return buffer.ToString(); } - [Pure] // return an unicode escaped string form of char c internal static String Hex(char c) { diff --git a/src/System.Private.CoreLib/shared/System/Globalization/EastAsianLunisolarCalendar.cs b/src/System.Private.CoreLib/shared/System/Globalization/EastAsianLunisolarCalendar.cs index 383e0cd17..358f4df18 100644 --- a/src/System.Private.CoreLib/shared/System/Globalization/EastAsianLunisolarCalendar.cs +++ b/src/System.Private.CoreLib/shared/System/Globalization/EastAsianLunisolarCalendar.cs @@ -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.Diagnostics.Contracts; namespace System.Globalization { @@ -62,7 +61,6 @@ namespace System.Globalization nameof(sexagenaryYear), SR.Format(SR.ArgumentOutOfRange_Range, 1, 60)); } - Contract.EndContractBlock(); return ((sexagenaryYear - 1) % 10) + 1; } @@ -79,7 +77,6 @@ namespace System.Globalization nameof(sexagenaryYear), SR.Format(SR.ArgumentOutOfRange_Range, 1, 60)); } - Contract.EndContractBlock(); return ((sexagenaryYear - 1) % 12) + 1; } @@ -168,7 +165,6 @@ namespace System.Globalization String.Format(CultureInfo.InvariantCulture, SR.ArgumentOutOfRange_CalendarRange, MinSupportedDateTime, MaxSupportedDateTime)); } - Contract.EndContractBlock(); } internal void CheckEraRange(int era) @@ -440,7 +436,6 @@ namespace System.Globalization nameof(months), SR.Format(SR.ArgumentOutOfRange_Range, -120000, 120000)); } - Contract.EndContractBlock(); CheckTicksRange(time.Ticks); @@ -699,7 +694,6 @@ namespace System.Globalization throw new ArgumentOutOfRangeException(nameof(year), SR.ArgumentOutOfRange_NeedNonNegNum); } - Contract.EndContractBlock(); year = base.ToFourDigitYear(year); CheckYearRange(year, CurrentEra); diff --git a/src/System.Private.CoreLib/shared/System/Globalization/GregorianCalendar.cs b/src/System.Private.CoreLib/shared/System/Globalization/GregorianCalendar.cs index 65041af15..81058ff66 100644 --- a/src/System.Private.CoreLib/shared/System/Globalization/GregorianCalendar.cs +++ b/src/System.Private.CoreLib/shared/System/Globalization/GregorianCalendar.cs @@ -4,7 +4,6 @@ using System; using System.Globalization; -using System.Diagnostics.Contracts; using System.Threading; namespace System.Globalization @@ -99,7 +98,6 @@ namespace System.Globalization SR.Format(SR.ArgumentOutOfRange_Range, GregorianCalendarTypes.Localized, GregorianCalendarTypes.TransliteratedFrench)); } - Contract.EndContractBlock(); this.m_type = type; } @@ -214,7 +212,6 @@ namespace System.Globalization -120000, 120000)); } - Contract.EndContractBlock(); time.GetDatePart(out int y, out int m, out int d); int i = m - 1 + months; if (i >= 0) @@ -396,7 +393,6 @@ namespace System.Globalization throw new ArgumentOutOfRangeException(nameof(month), SR.Format(SR.ArgumentOutOfRange_Range, 1, 12)); } - Contract.EndContractBlock(); if (era != CurrentEra && era != ADEra) { @@ -443,7 +439,6 @@ namespace System.Globalization CultureInfo.CurrentCulture, SR.ArgumentOutOfRange_Range, 1, MaxYear)); } - Contract.EndContractBlock(); return (0); } @@ -472,7 +467,6 @@ namespace System.Globalization throw new ArgumentOutOfRangeException(nameof(month), SR.Format(SR.ArgumentOutOfRange_Range, 1, 12)); } - Contract.EndContractBlock(); return (false); } @@ -573,7 +567,6 @@ namespace System.Globalization throw new ArgumentOutOfRangeException(nameof(year), SR.ArgumentOutOfRange_NeedNonNegNum); } - Contract.EndContractBlock(); if (year > MaxYear) { diff --git a/src/System.Private.CoreLib/shared/System/Globalization/GregorianCalendarHelper.cs b/src/System.Private.CoreLib/shared/System/Globalization/GregorianCalendarHelper.cs index d694202ed..2842bd3a1 100644 --- a/src/System.Private.CoreLib/shared/System/Globalization/GregorianCalendarHelper.cs +++ b/src/System.Private.CoreLib/shared/System/Globalization/GregorianCalendarHelper.cs @@ -3,7 +3,6 @@ // See the LICENSE file in the project root for more information. using System; -using System.Diagnostics.Contracts; using System.Threading; namespace System.Globalization @@ -141,7 +140,6 @@ namespace System.Globalization throw new ArgumentOutOfRangeException(nameof(year), SR.ArgumentOutOfRange_NeedNonNegNum); } - Contract.EndContractBlock(); if (era == Calendar.CurrentEra) { @@ -323,7 +321,6 @@ namespace System.Globalization m_Cal.MinSupportedDateTime, m_Cal.MaxSupportedDateTime)); } - Contract.EndContractBlock(); } // Returns the DateTime resulting from adding the given number of @@ -355,7 +352,6 @@ namespace System.Globalization -120000, 120000)); } - Contract.EndContractBlock(); CheckTicksRange(time.Ticks); int y = GetDatePart(time.Ticks, DatePartYear); @@ -427,7 +423,6 @@ namespace System.Globalization // Returns the number of days in the month given by the year and // month arguments. // - [Pure] public int GetDaysInMonth(int year, int month, int era) { // @@ -555,7 +550,6 @@ namespace System.Globalization 1, GetDaysInMonth(year, month, era))); } - Contract.EndContractBlock(); if (!IsLeapYear(year, era)) { @@ -633,7 +627,6 @@ namespace System.Globalization throw new ArgumentOutOfRangeException(nameof(year), SR.ArgumentOutOfRange_NeedPosNum); } - Contract.EndContractBlock(); if (year < 100) { diff --git a/src/System.Private.CoreLib/shared/System/Globalization/HebrewCalendar.cs b/src/System.Private.CoreLib/shared/System/Globalization/HebrewCalendar.cs index 92f4cab4b..533d3831b 100644 --- a/src/System.Private.CoreLib/shared/System/Globalization/HebrewCalendar.cs +++ b/src/System.Private.CoreLib/shared/System/Globalization/HebrewCalendar.cs @@ -3,7 +3,6 @@ // See the LICENSE file in the project root for more information. using System.Diagnostics; -using System.Diagnostics.Contracts; namespace System.Globalization { @@ -1095,7 +1094,6 @@ namespace System.Globalization throw new ArgumentOutOfRangeException(nameof(year), SR.ArgumentOutOfRange_NeedNonNegNum); } - Contract.EndContractBlock(); if (year < 100) { diff --git a/src/System.Private.CoreLib/shared/System/Globalization/HijriCalendar.cs b/src/System.Private.CoreLib/shared/System/Globalization/HijriCalendar.cs index 59b354f53..675584462 100644 --- a/src/System.Private.CoreLib/shared/System/Globalization/HijriCalendar.cs +++ b/src/System.Private.CoreLib/shared/System/Globalization/HijriCalendar.cs @@ -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.Diagnostics.Contracts; namespace System.Globalization { @@ -198,7 +197,6 @@ namespace System.Globalization MinAdvancedHijri, MaxAdvancedHijri)); } - Contract.EndContractBlock(); VerifyWritable(); _hijriAdvance = value; @@ -395,7 +393,6 @@ namespace System.Globalization -120000, 120000)); } - Contract.EndContractBlock(); // Get the date in Hijri calendar. int y = GetDatePart(time.Ticks, DatePartYear); int m = GetDatePart(time.Ticks, DatePartMonth); @@ -467,7 +464,6 @@ namespace System.Globalization // Returns the number of days in the month given by the year and // month arguments. // - [Pure] public override int GetDaysInMonth(int year, int month, int era) { CheckYearMonthRange(year, month, era); @@ -653,7 +649,6 @@ namespace System.Globalization throw new ArgumentOutOfRangeException(nameof(year), SR.ArgumentOutOfRange_NeedNonNegNum); } - Contract.EndContractBlock(); if (year < 100) { diff --git a/src/System.Private.CoreLib/shared/System/Globalization/JapaneseCalendar.cs b/src/System.Private.CoreLib/shared/System/Globalization/JapaneseCalendar.cs index 0db1e6517..50195d7f1 100644 --- a/src/System.Private.CoreLib/shared/System/Globalization/JapaneseCalendar.cs +++ b/src/System.Private.CoreLib/shared/System/Globalization/JapaneseCalendar.cs @@ -3,7 +3,6 @@ // See the LICENSE file in the project root for more information. using System.Diagnostics.CodeAnalysis; -using System.Diagnostics.Contracts; namespace System.Globalization { @@ -225,7 +224,6 @@ namespace System.Globalization } - [SuppressMessage("Microsoft.Contracts", "CC1055")] // Skip extra error checking to avoid *potential* AppCompat problems. public override int GetWeekOfYear(DateTime time, CalendarWeekRule rule, DayOfWeek firstDayOfWeek) { return (helper.GetWeekOfYear(time, rule, firstDayOfWeek)); @@ -300,7 +298,6 @@ namespace System.Globalization throw new ArgumentOutOfRangeException(nameof(year), SR.ArgumentOutOfRange_NeedPosNum); } - Contract.EndContractBlock(); if (year > helper.MaxYear) { diff --git a/src/System.Private.CoreLib/shared/System/Globalization/JapaneseLunisolarCalendar.cs b/src/System.Private.CoreLib/shared/System/Globalization/JapaneseLunisolarCalendar.cs index a90c4e8f2..e8a2dcd63 100644 --- a/src/System.Private.CoreLib/shared/System/Globalization/JapaneseLunisolarCalendar.cs +++ b/src/System.Private.CoreLib/shared/System/Globalization/JapaneseLunisolarCalendar.cs @@ -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.Diagnostics.Contracts; namespace System.Globalization { @@ -211,7 +210,6 @@ namespace System.Globalization MIN_LUNISOLAR_YEAR, MAX_LUNISOLAR_YEAR)); } - Contract.EndContractBlock(); return s_yinfo[lunarYear - MIN_LUNISOLAR_YEAR, index]; } diff --git a/src/System.Private.CoreLib/shared/System/Globalization/JulianCalendar.cs b/src/System.Private.CoreLib/shared/System/Globalization/JulianCalendar.cs index 8d9429054..82e4d589d 100644 --- a/src/System.Private.CoreLib/shared/System/Globalization/JulianCalendar.cs +++ b/src/System.Private.CoreLib/shared/System/Globalization/JulianCalendar.cs @@ -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.Diagnostics.Contracts; namespace System.Globalization { @@ -221,7 +220,6 @@ namespace System.Globalization -120000, 120000)); } - Contract.EndContractBlock(); int y = GetDatePart(time.Ticks, DatePartYear); int m = GetDatePart(time.Ticks, DatePartMonth); int d = GetDatePart(time.Ticks, DatePartDay); @@ -424,7 +422,6 @@ namespace System.Globalization throw new ArgumentOutOfRangeException(nameof(year), SR.ArgumentOutOfRange_NeedNonNegNum); } - Contract.EndContractBlock(); if (year > MaxYear) { diff --git a/src/System.Private.CoreLib/shared/System/Globalization/KoreanCalendar.cs b/src/System.Private.CoreLib/shared/System/Globalization/KoreanCalendar.cs index ef7495f07..9168b664e 100644 --- a/src/System.Private.CoreLib/shared/System/Globalization/KoreanCalendar.cs +++ b/src/System.Private.CoreLib/shared/System/Globalization/KoreanCalendar.cs @@ -3,7 +3,6 @@ // See the LICENSE file in the project root for more information. using System.Diagnostics.CodeAnalysis; -using System.Diagnostics.Contracts; namespace System.Globalization { @@ -153,7 +152,6 @@ namespace System.Globalization } - [SuppressMessage("Microsoft.Contracts", "CC1055")] // Skip extra error checking to avoid *potential* AppCompat problems. public override int GetWeekOfYear(DateTime time, CalendarWeekRule rule, DayOfWeek firstDayOfWeek) { return (helper.GetWeekOfYear(time, rule, firstDayOfWeek)); @@ -257,7 +255,6 @@ namespace System.Globalization throw new ArgumentOutOfRangeException(nameof(year), SR.ArgumentOutOfRange_NeedNonNegNum); } - Contract.EndContractBlock(); return (helper.ToFourDigitYear(year, this.TwoDigitYearMax)); } diff --git a/src/System.Private.CoreLib/shared/System/Globalization/KoreanLunisolarCalendar.cs b/src/System.Private.CoreLib/shared/System/Globalization/KoreanLunisolarCalendar.cs index 8364532c9..8cdade866 100644 --- a/src/System.Private.CoreLib/shared/System/Globalization/KoreanLunisolarCalendar.cs +++ b/src/System.Private.CoreLib/shared/System/Globalization/KoreanLunisolarCalendar.cs @@ -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.Diagnostics.Contracts; namespace System.Globalization { @@ -1256,7 +1255,6 @@ namespace System.Globalization MIN_LUNISOLAR_YEAR, MAX_LUNISOLAR_YEAR)); } - Contract.EndContractBlock(); return s_yinfo[lunarYear - MIN_LUNISOLAR_YEAR, index]; } @@ -1278,7 +1276,6 @@ namespace System.Globalization CultureInfo.CurrentCulture, SR.ArgumentOutOfRange_Range, MIN_LUNISOLAR_YEAR, MAX_LUNISOLAR_YEAR)); } - Contract.EndContractBlock(); return year; } diff --git a/src/System.Private.CoreLib/shared/System/Globalization/LocaleData.Unix.cs b/src/System.Private.CoreLib/shared/System/Globalization/LocaleData.Unix.cs index d4c58d8a3..ccf1078ac 100644 --- a/src/System.Private.CoreLib/shared/System/Globalization/LocaleData.Unix.cs +++ b/src/System.Private.CoreLib/shared/System/Globalization/LocaleData.Unix.cs @@ -3,7 +3,6 @@ // See the LICENSE file in the project root for more information. using System.Diagnostics; -using System.Diagnostics.Contracts; // This file contains the handling of Windows OS specific culture features. diff --git a/src/System.Private.CoreLib/shared/System/Globalization/NumberFormatInfo.cs b/src/System.Private.CoreLib/shared/System/Globalization/NumberFormatInfo.cs index d7412bfcf..787e36433 100644 --- a/src/System.Private.CoreLib/shared/System/Globalization/NumberFormatInfo.cs +++ b/src/System.Private.CoreLib/shared/System/Globalization/NumberFormatInfo.cs @@ -3,7 +3,6 @@ // See the LICENSE file in the project root for more information. using System; -using System.Diagnostics.Contracts; using System.Runtime.Serialization; using System.Text; @@ -117,7 +116,6 @@ namespace System.Globalization { throw new ArgumentException(SR.Argument_EmptyDecString); } - Contract.EndContractBlock(); } private static void VerifyGroupSeparator(String groupSep, String propertyName) @@ -127,7 +125,6 @@ namespace System.Globalization throw new ArgumentNullException(propertyName, SR.ArgumentNull_String); } - Contract.EndContractBlock(); } private static void VerifyNativeDigits(string[] nativeDig, string propertyName) @@ -141,7 +138,6 @@ namespace System.Globalization { throw new ArgumentException(SR.Argument_InvalidNativeDigitCount, propertyName); } - Contract.EndContractBlock(); for (int i = 0; i < nativeDig.Length; i++) { @@ -205,14 +201,12 @@ namespace System.Globalization } } - [Pure] private void VerifyWritable() { if (isReadOnly) { throw new InvalidOperationException(SR.InvalidOperation_ReadOnly); } - Contract.EndContractBlock(); } // Returns a default NumberFormatInfo that will be universally @@ -290,7 +284,6 @@ namespace System.Globalization 0, 99)); } - Contract.EndContractBlock(); VerifyWritable(); currencyDecimalDigits = value; } @@ -354,7 +347,6 @@ namespace System.Globalization throw new ArgumentNullException(nameof(CurrencyGroupSizes), SR.ArgumentNull_Obj); } - Contract.EndContractBlock(); VerifyWritable(); Int32[] inputSizes = (Int32[])value.Clone(); @@ -378,7 +370,6 @@ namespace System.Globalization throw new ArgumentNullException(nameof(NumberGroupSizes), SR.ArgumentNull_Obj); } - Contract.EndContractBlock(); VerifyWritable(); Int32[] inputSizes = (Int32[])value.Clone(); @@ -401,7 +392,6 @@ namespace System.Globalization throw new ArgumentNullException(nameof(PercentGroupSizes), SR.ArgumentNull_Obj); } - Contract.EndContractBlock(); VerifyWritable(); Int32[] inputSizes = (Int32[])value.Clone(); CheckGroupSize(nameof(PercentGroupSizes), inputSizes); @@ -432,7 +422,6 @@ namespace System.Globalization throw new ArgumentNullException(nameof(CurrencySymbol), SR.ArgumentNull_String); } - Contract.EndContractBlock(); VerifyWritable(); currencySymbol = value; } @@ -472,7 +461,6 @@ namespace System.Globalization throw new ArgumentNullException(nameof(NaNSymbol), SR.ArgumentNull_String); } - Contract.EndContractBlock(); VerifyWritable(); nanSymbol = value; } @@ -495,7 +483,6 @@ namespace System.Globalization 0, 15)); } - Contract.EndContractBlock(); VerifyWritable(); currencyNegativePattern = value; } @@ -520,7 +507,6 @@ namespace System.Globalization 0, 4)); } - Contract.EndContractBlock(); VerifyWritable(); numberNegativePattern = value; } @@ -545,7 +531,6 @@ namespace System.Globalization 0, 3)); } - Contract.EndContractBlock(); VerifyWritable(); percentPositivePattern = value; } @@ -570,7 +555,6 @@ namespace System.Globalization 0, 11)); } - Contract.EndContractBlock(); VerifyWritable(); percentNegativePattern = value; } @@ -590,7 +574,6 @@ namespace System.Globalization throw new ArgumentNullException(nameof(NegativeInfinitySymbol), SR.ArgumentNull_String); } - Contract.EndContractBlock(); VerifyWritable(); negativeInfinitySymbol = value; } @@ -607,7 +590,6 @@ namespace System.Globalization throw new ArgumentNullException(nameof(NegativeSign), SR.ArgumentNull_String); } - Contract.EndContractBlock(); VerifyWritable(); negativeSign = value; } @@ -629,7 +611,6 @@ namespace System.Globalization 0, 99)); } - Contract.EndContractBlock(); VerifyWritable(); numberDecimalDigits = value; } @@ -675,7 +656,6 @@ namespace System.Globalization 0, 3)); } - Contract.EndContractBlock(); VerifyWritable(); currencyPositivePattern = value; } @@ -695,7 +675,6 @@ namespace System.Globalization throw new ArgumentNullException(nameof(PositiveInfinitySymbol), SR.ArgumentNull_String); } - Contract.EndContractBlock(); VerifyWritable(); positiveInfinitySymbol = value; } @@ -712,7 +691,6 @@ namespace System.Globalization throw new ArgumentNullException(nameof(PositiveSign), SR.ArgumentNull_String); } - Contract.EndContractBlock(); VerifyWritable(); positiveSign = value; } @@ -734,7 +712,6 @@ namespace System.Globalization 0, 99)); } - Contract.EndContractBlock(); VerifyWritable(); percentDecimalDigits = value; } @@ -778,7 +755,6 @@ namespace System.Globalization throw new ArgumentNullException(nameof(PercentSymbol), SR.ArgumentNull_String); } - Contract.EndContractBlock(); VerifyWritable(); percentSymbol = value; } @@ -795,7 +771,6 @@ namespace System.Globalization throw new ArgumentNullException(nameof(PerMilleSymbol), SR.ArgumentNull_String); } - Contract.EndContractBlock(); VerifyWritable(); perMilleSymbol = value; } @@ -834,7 +809,6 @@ namespace System.Globalization { throw new ArgumentNullException(nameof(nfi)); } - Contract.EndContractBlock(); if (nfi.IsReadOnly) { return (nfi); @@ -858,7 +832,6 @@ namespace System.Globalization { throw new ArgumentException(SR.Argument_InvalidNumberStyles, nameof(style)); } - Contract.EndContractBlock(); if ((style & NumberStyles.AllowHexSpecifier) != 0) { // Check for hex number if ((style & ~NumberStyles.HexNumber) != 0) @@ -875,7 +848,6 @@ namespace System.Globalization { throw new ArgumentException(SR.Argument_InvalidNumberStyles, nameof(style)); } - Contract.EndContractBlock(); if ((style & NumberStyles.AllowHexSpecifier) != 0) { // Check for hex number throw new ArgumentException(SR.Arg_HexStyleNotSupported); diff --git a/src/System.Private.CoreLib/shared/System/Globalization/PersianCalendar.cs b/src/System.Private.CoreLib/shared/System/Globalization/PersianCalendar.cs index 78a081e1b..a80c6ece5 100644 --- a/src/System.Private.CoreLib/shared/System/Globalization/PersianCalendar.cs +++ b/src/System.Private.CoreLib/shared/System/Globalization/PersianCalendar.cs @@ -3,7 +3,6 @@ // See the LICENSE file in the project root for more information. using System.Diagnostics; -using System.Diagnostics.Contracts; namespace System.Globalization { @@ -289,7 +288,6 @@ namespace System.Globalization -120000, 120000)); } - Contract.EndContractBlock(); // Get the date in Persian calendar. int y = GetDatePart(time.Ticks, DatePartYear); int m = GetDatePart(time.Ticks, DatePartMonth); @@ -582,7 +580,6 @@ namespace System.Globalization throw new ArgumentOutOfRangeException(nameof(year), SR.ArgumentOutOfRange_NeedNonNegNum); } - Contract.EndContractBlock(); if (year < 100) { diff --git a/src/System.Private.CoreLib/shared/System/Globalization/SortKey.cs b/src/System.Private.CoreLib/shared/System/Globalization/SortKey.cs index d65e097cb..9b706fdad 100644 --- a/src/System.Private.CoreLib/shared/System/Globalization/SortKey.cs +++ b/src/System.Private.CoreLib/shared/System/Globalization/SortKey.cs @@ -15,7 +15,6 @@ using System; using System.Runtime.CompilerServices; using System.Runtime.Serialization; using System.Diagnostics; -using System.Diagnostics.Contracts; namespace System.Globalization { @@ -114,7 +113,6 @@ namespace System.Globalization { throw new ArgumentNullException((sortkey1 == null ? nameof(sortkey1) : nameof(sortkey2))); } - Contract.EndContractBlock(); byte[] key1Data = sortkey1._keyData; byte[] key2Data = sortkey2._keyData; diff --git a/src/System.Private.CoreLib/shared/System/Globalization/StringInfo.cs b/src/System.Private.CoreLib/shared/System/Globalization/StringInfo.cs index 87d1b9f68..c2fbe5a1d 100644 --- a/src/System.Private.CoreLib/shared/System/Globalization/StringInfo.cs +++ b/src/System.Private.CoreLib/shared/System/Globalization/StringInfo.cs @@ -14,7 +14,6 @@ using System; using System.Diagnostics; -using System.Diagnostics.Contracts; using System.Runtime.Serialization; namespace System.Globalization @@ -95,7 +94,6 @@ namespace System.Globalization throw new ArgumentNullException(nameof(String), SR.ArgumentNull_String); } - Contract.EndContractBlock(); _str = value; _indexes = null; @@ -280,7 +278,6 @@ namespace System.Globalization { throw new ArgumentNullException(nameof(str)); } - Contract.EndContractBlock(); int len = str.Length; if (index < 0 || index >= len) @@ -311,7 +308,6 @@ namespace System.Globalization { throw new ArgumentNullException(nameof(str)); } - Contract.EndContractBlock(); int len = str.Length; if (index < 0 || (index > len)) @@ -340,7 +336,6 @@ namespace System.Globalization { throw new ArgumentNullException(nameof(str)); } - Contract.EndContractBlock(); int len = str.Length; int[] result = new int[len]; diff --git a/src/System.Private.CoreLib/shared/System/Globalization/TaiwanCalendar.cs b/src/System.Private.CoreLib/shared/System/Globalization/TaiwanCalendar.cs index ec4188161..c5161138d 100644 --- a/src/System.Private.CoreLib/shared/System/Globalization/TaiwanCalendar.cs +++ b/src/System.Private.CoreLib/shared/System/Globalization/TaiwanCalendar.cs @@ -4,7 +4,6 @@ using System; using System.Diagnostics.CodeAnalysis; -using System.Diagnostics.Contracts; namespace System.Globalization { @@ -160,7 +159,6 @@ namespace System.Globalization } - [SuppressMessage("Microsoft.Contracts", "CC1055")] // Skip extra error checking to avoid *potential* AppCompat problems. public override int GetWeekOfYear(DateTime time, CalendarWeekRule rule, DayOfWeek firstDayOfWeek) { return (helper.GetWeekOfYear(time, rule, firstDayOfWeek)); @@ -265,7 +263,6 @@ namespace System.Globalization throw new ArgumentOutOfRangeException(nameof(year), SR.ArgumentOutOfRange_NeedPosNum); } - Contract.EndContractBlock(); if (year > helper.MaxYear) { diff --git a/src/System.Private.CoreLib/shared/System/Globalization/TaiwanLunisolarCalendar.cs b/src/System.Private.CoreLib/shared/System/Globalization/TaiwanLunisolarCalendar.cs index 1e2ec62a7..60e84f7f3 100644 --- a/src/System.Private.CoreLib/shared/System/Globalization/TaiwanLunisolarCalendar.cs +++ b/src/System.Private.CoreLib/shared/System/Globalization/TaiwanLunisolarCalendar.cs @@ -3,7 +3,6 @@ // See the LICENSE file in the project root for more information. using System; -using System.Diagnostics.Contracts; namespace System.Globalization { @@ -270,7 +269,6 @@ namespace System.Globalization MIN_LUNISOLAR_YEAR, MAX_LUNISOLAR_YEAR)); } - Contract.EndContractBlock(); return s_yinfo[lunarYear - MIN_LUNISOLAR_YEAR, index]; } diff --git a/src/System.Private.CoreLib/shared/System/Globalization/ThaiBuddhistCalendar.cs b/src/System.Private.CoreLib/shared/System/Globalization/ThaiBuddhistCalendar.cs index e1646bfa8..4f8fd8f01 100644 --- a/src/System.Private.CoreLib/shared/System/Globalization/ThaiBuddhistCalendar.cs +++ b/src/System.Private.CoreLib/shared/System/Globalization/ThaiBuddhistCalendar.cs @@ -4,7 +4,6 @@ using System; using System.Diagnostics.CodeAnalysis; -using System.Diagnostics.Contracts; namespace System.Globalization { @@ -122,7 +121,6 @@ namespace System.Globalization } - [SuppressMessage("Microsoft.Contracts", "CC1055")] // Skip extra error checking to avoid *potential* AppCompat problems. public override int GetWeekOfYear(DateTime time, CalendarWeekRule rule, DayOfWeek firstDayOfWeek) { return (helper.GetWeekOfYear(time, rule, firstDayOfWeek)); @@ -226,7 +224,6 @@ namespace System.Globalization throw new ArgumentOutOfRangeException(nameof(year), SR.ArgumentOutOfRange_NeedNonNegNum); } - Contract.EndContractBlock(); return (helper.ToFourDigitYear(year, this.TwoDigitYearMax)); } diff --git a/src/System.Private.CoreLib/shared/System/Globalization/UmAlQuraCalendar.cs b/src/System.Private.CoreLib/shared/System/Globalization/UmAlQuraCalendar.cs index 99b99d67c..21a938f8f 100644 --- a/src/System.Private.CoreLib/shared/System/Globalization/UmAlQuraCalendar.cs +++ b/src/System.Private.CoreLib/shared/System/Globalization/UmAlQuraCalendar.cs @@ -3,7 +3,6 @@ // See the LICENSE file in the project root for more information. using System.Diagnostics; -using System.Diagnostics.Contracts; namespace System.Globalization { @@ -517,7 +516,6 @@ namespace System.Globalization -120000, 120000)); } - Contract.EndContractBlock(); // Get the date in UmAlQura calendar. int y = GetDatePart(time, DatePartYear); int m = GetDatePart(time, DatePartMonth); @@ -822,7 +820,6 @@ namespace System.Globalization MinCalendarYear, MaxCalendarYear)); } - Contract.EndContractBlock(); VerifyWritable(); // We allow year 99 to be set so that one can make ToFourDigitYearMax a no-op by setting TwoDigitYearMax to 99. twoDigitYearMax = value; @@ -838,7 +835,6 @@ namespace System.Globalization throw new ArgumentOutOfRangeException(nameof(year), SR.ArgumentOutOfRange_NeedNonNegNum); } - Contract.EndContractBlock(); if (year < 100) { diff --git a/src/System.Private.CoreLib/shared/System/Guid.cs b/src/System.Private.CoreLib/shared/System/Guid.cs index 4a3855b10..496bc3532 100644 --- a/src/System.Private.CoreLib/shared/System/Guid.cs +++ b/src/System.Private.CoreLib/shared/System/Guid.cs @@ -3,7 +3,6 @@ // See the LICENSE file in the project root for more information. using System.Diagnostics; -using System.Diagnostics.Contracts; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; @@ -87,7 +86,6 @@ namespace System // Check that array is not too big if (d.Length != 8) throw new ArgumentException(SR.Format(SR.Arg_GuidArrayCtor, "8"), nameof(d)); - Contract.EndContractBlock(); _a = a; _b = b; @@ -245,7 +243,6 @@ namespace System { throw new ArgumentNullException(nameof(g)); } - Contract.EndContractBlock(); GuidResult result = new GuidResult(); result.Init(GuidParseThrowStyle.All); diff --git a/src/System.Private.CoreLib/shared/System/IFormattable.cs b/src/System.Private.CoreLib/shared/System/IFormattable.cs index 28a7d7057..1f2f7022c 100644 --- a/src/System.Private.CoreLib/shared/System/IFormattable.cs +++ b/src/System.Private.CoreLib/shared/System/IFormattable.cs @@ -3,13 +3,11 @@ // See the LICENSE file in the project root for more information. using System; -using System.Diagnostics.Contracts; namespace System { public interface IFormattable { - [Pure] String ToString(String format, IFormatProvider formatProvider); } } diff --git a/src/System.Private.CoreLib/shared/System/IO/Error.cs b/src/System.Private.CoreLib/shared/System/IO/Error.cs index 2aef89518..1e319a068 100644 --- a/src/System.Private.CoreLib/shared/System/IO/Error.cs +++ b/src/System.Private.CoreLib/shared/System/IO/Error.cs @@ -6,14 +6,12 @@ using System; using System.Runtime.InteropServices; using System.Text; using System.Globalization; -using System.Diagnostics.Contracts; namespace System.IO { /// <summary> /// Provides centralized methods for creating exceptions for System.IO.FileSystem. /// </summary> - [Pure] internal static class Error { internal static Exception GetStreamIsClosed() diff --git a/src/System.Private.CoreLib/shared/System/IO/FileStream.Unix.cs b/src/System.Private.CoreLib/shared/System/IO/FileStream.Unix.cs index 849959536..99a337728 100644 --- a/src/System.Private.CoreLib/shared/System/IO/FileStream.Unix.cs +++ b/src/System.Private.CoreLib/shared/System/IO/FileStream.Unix.cs @@ -97,11 +97,17 @@ namespace System.IO ignoreNotSupported: true); // just a hint. } - // Jump to the end of the file if opened as Append. if (_mode == FileMode.Append) { + // Jump to the end of the file if opened as Append. _appendStart = SeekCore(_fileHandle, 0, SeekOrigin.End); } + else if (mode == FileMode.Create || mode == FileMode.Truncate) + { + // Truncate the file now if the file mode requires it. This ensures that the file only will be truncated + // if opened successfully. + CheckFileCall(Interop.Sys.FTruncate(_fileHandle, 0)); + } } /// <summary>Initializes a stream from an already open file handle (file descriptor).</summary> @@ -128,24 +134,18 @@ namespace System.IO { default: case FileMode.Open: // Open maps to the default behavior for open(...). No flags needed. + case FileMode.Truncate: // We truncate the file after getting the lock break; case FileMode.Append: // Append is the same as OpenOrCreate, except that we'll also separately jump to the end later case FileMode.OpenOrCreate: + case FileMode.Create: // We truncate the file after getting the lock flags |= Interop.Sys.OpenFlags.O_CREAT; break; - case FileMode.Create: - flags |= (Interop.Sys.OpenFlags.O_CREAT | Interop.Sys.OpenFlags.O_TRUNC); - break; - case FileMode.CreateNew: flags |= (Interop.Sys.OpenFlags.O_CREAT | Interop.Sys.OpenFlags.O_EXCL); break; - - case FileMode.Truncate: - flags |= Interop.Sys.OpenFlags.O_TRUNC; - break; } // Translate FileAccess. All possible values map cleanly to corresponding values for open. diff --git a/src/System.Private.CoreLib/shared/System/IO/Path.cs b/src/System.Private.CoreLib/shared/System/IO/Path.cs index 2676f0d2f..c9b9ed0cd 100644 --- a/src/System.Private.CoreLib/shared/System/IO/Path.cs +++ b/src/System.Private.CoreLib/shared/System/IO/Path.cs @@ -3,7 +3,6 @@ // See the LICENSE file in the project root for more information. using System.Diagnostics; -using System.Diagnostics.Contracts; using System.Text; namespace System.IO @@ -100,7 +99,6 @@ namespace System.IO // period (".") character of the extension except when you have a terminal period when you get string.Empty, such as ".exe" or // ".cpp". The returned value is null if the given path is // null or if the given path does not include an extension. - [Pure] public static string GetExtension(string path) { if (path == null) @@ -127,7 +125,6 @@ namespace System.IO // Returns the name and extension parts of the given path. The resulting // string contains the characters of path that follow the last // separator in path. The resulting string is null if path is null. - [Pure] public static string GetFileName(string path) { if (path == null) @@ -138,7 +135,6 @@ namespace System.IO return path.Substring(offset, count); } - [Pure] public static string GetFileNameWithoutExtension(string path) { if (path == null) @@ -194,7 +190,6 @@ namespace System.IO // true if the characters that follow the last directory // separator ('\\' or '/') or volume separator (':') in the path include // a period (".") other than a terminal period. The result is false otherwise. - [Pure] public static bool HasExtension(string path) { if (path != null) @@ -218,7 +213,6 @@ namespace System.IO { if (path1 == null || path2 == null) throw new ArgumentNullException((path1 == null) ? nameof(path1) : nameof(path2)); - Contract.EndContractBlock(); PathInternal.CheckInvalidPathChars(path1); PathInternal.CheckInvalidPathChars(path2); @@ -230,7 +224,6 @@ namespace System.IO { if (path1 == null || path2 == null || path3 == null) throw new ArgumentNullException((path1 == null) ? nameof(path1) : (path2 == null) ? nameof(path2) : nameof(path3)); - Contract.EndContractBlock(); PathInternal.CheckInvalidPathChars(path1); PathInternal.CheckInvalidPathChars(path2); @@ -243,7 +236,6 @@ namespace System.IO { if (path1 == null || path2 == null || path3 == null || path4 == null) throw new ArgumentNullException((path1 == null) ? nameof(path1) : (path2 == null) ? nameof(path2) : (path3 == null) ? nameof(path3) : nameof(path4)); - Contract.EndContractBlock(); PathInternal.CheckInvalidPathChars(path1); PathInternal.CheckInvalidPathChars(path2); @@ -259,7 +251,6 @@ namespace System.IO { throw new ArgumentNullException(nameof(paths)); } - Contract.EndContractBlock(); int finalSize = 0; int firstComponent = 0; diff --git a/src/System.Private.CoreLib/shared/System/IO/PinnedBufferMemoryStream.cs b/src/System.Private.CoreLib/shared/System/IO/PinnedBufferMemoryStream.cs index e8f74dd05..2bd1ef6b9 100644 --- a/src/System.Private.CoreLib/shared/System/IO/PinnedBufferMemoryStream.cs +++ b/src/System.Private.CoreLib/shared/System/IO/PinnedBufferMemoryStream.cs @@ -17,7 +17,6 @@ using System; using System.Runtime.InteropServices; using System.Diagnostics; -using System.Diagnostics.Contracts; namespace System.IO { diff --git a/src/System.Private.CoreLib/shared/System/IO/UnmanagedMemoryStream.cs b/src/System.Private.CoreLib/shared/System/IO/UnmanagedMemoryStream.cs index 76e6beb7a..dc6f67bae 100644 --- a/src/System.Private.CoreLib/shared/System/IO/UnmanagedMemoryStream.cs +++ b/src/System.Private.CoreLib/shared/System/IO/UnmanagedMemoryStream.cs @@ -3,7 +3,6 @@ // See the LICENSE file in the project root for more information. using System.Diagnostics; -using System.Diagnostics.Contracts; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Threading; @@ -111,7 +110,6 @@ namespace System.IO { throw new ArgumentOutOfRangeException(nameof(access)); } - Contract.EndContractBlock(); if (_isOpen) { @@ -178,7 +176,6 @@ namespace System.IO throw new ArgumentOutOfRangeException((length < 0) ? nameof(length) : nameof(capacity), SR.ArgumentOutOfRange_NeedNonNegNum); if (length > capacity) throw new ArgumentOutOfRangeException(nameof(length), SR.ArgumentOutOfRange_LengthGreaterThanCapacity); - Contract.EndContractBlock(); // Check for wraparound. if (((byte*)((long)pointer + capacity)) < pointer) throw new ArgumentOutOfRangeException(nameof(capacity), SR.ArgumentOutOfRange_UnmanagedMemStreamWrapAround); @@ -200,7 +197,6 @@ namespace System.IO /// </summary> public override bool CanRead { - [Pure] get { return _isOpen && (_access & FileAccess.Read) != 0; } } @@ -209,7 +205,6 @@ namespace System.IO /// </summary> public override bool CanSeek { - [Pure] get { return _isOpen; } } @@ -218,7 +213,6 @@ namespace System.IO /// </summary> public override bool CanWrite { - [Pure] get { return _isOpen && (_access & FileAccess.Write) != 0; } } @@ -298,14 +292,12 @@ namespace System.IO get { if (!CanSeek) throw Error.GetStreamIsClosed(); - Contract.EndContractBlock(); return Interlocked.Read(ref _position); } set { if (value < 0) throw new ArgumentOutOfRangeException(nameof(value), SR.ArgumentOutOfRange_NeedNonNegNum); if (!CanSeek) throw Error.GetStreamIsClosed(); - Contract.EndContractBlock(); Interlocked.Exchange(ref _position, value); } @@ -452,7 +444,6 @@ namespace System.IO throw new ArgumentOutOfRangeException(nameof(count), SR.ArgumentOutOfRange_NeedNonNegNum); if (buffer.Length - offset < count) throw new ArgumentException(SR.Argument_InvalidOffLen); - Contract.EndContractBlock(); // contract validation copied from Read(...) if (cancellationToken.IsCancellationRequested) return Task.FromCanceled<Int32>(cancellationToken); @@ -600,7 +591,6 @@ namespace System.IO { if (value < 0) throw new ArgumentOutOfRangeException(nameof(value), SR.ArgumentOutOfRange_NeedNonNegNum); - Contract.EndContractBlock(); if (_buffer != null) throw new NotSupportedException(SR.NotSupported_UmsSafeBuffer); if (!_isOpen) throw Error.GetStreamIsClosed(); @@ -748,7 +738,6 @@ namespace System.IO throw new ArgumentOutOfRangeException(nameof(count), SR.ArgumentOutOfRange_NeedNonNegNum); if (buffer.Length - offset < count) throw new ArgumentException(SR.Argument_InvalidOffLen); - Contract.EndContractBlock(); // contract validation copied from Write(..) if (cancellationToken.IsCancellationRequested) return Task.FromCanceled(cancellationToken); diff --git a/src/System.Private.CoreLib/shared/System/IO/UnmanagedMemoryStreamWrapper.cs b/src/System.Private.CoreLib/shared/System/IO/UnmanagedMemoryStreamWrapper.cs index 2699912ea..90bb21ac5 100644 --- a/src/System.Private.CoreLib/shared/System/IO/UnmanagedMemoryStreamWrapper.cs +++ b/src/System.Private.CoreLib/shared/System/IO/UnmanagedMemoryStreamWrapper.cs @@ -14,7 +14,6 @@ using System; using System.Runtime.InteropServices; using System.Diagnostics.CodeAnalysis; -using System.Diagnostics.Contracts; using System.Threading; using System.Threading.Tasks; @@ -82,7 +81,6 @@ namespace System.IO { return (int)_unmanagedStream.Capacity; } - [SuppressMessage("Microsoft.Contracts", "CC1055")] // Skip extra error checking to avoid *potential* AppCompat problems. set { throw new IOException(SR.IO_FixedCapacity); @@ -156,7 +154,6 @@ namespace System.IO { if (stream == null) throw new ArgumentNullException(nameof(stream), SR.ArgumentNull_Stream); - Contract.EndContractBlock(); byte[] buffer = ToArray(); @@ -193,7 +190,6 @@ namespace System.IO if (!destination.CanWrite) throw new NotSupportedException(SR.NotSupported_UnwritableStream); - Contract.EndContractBlock(); return _unmanagedStream.CopyToAsync(destination, bufferSize, cancellationToken); } diff --git a/src/System.Private.CoreLib/shared/System/Int16.cs b/src/System.Private.CoreLib/shared/System/Int16.cs index 6aaf4280d..87004861c 100644 --- a/src/System.Private.CoreLib/shared/System/Int16.cs +++ b/src/System.Private.CoreLib/shared/System/Int16.cs @@ -12,7 +12,6 @@ ** ===========================================================*/ -using System.Diagnostics.Contracts; using System.Globalization; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; @@ -80,32 +79,26 @@ namespace System public override String ToString() { - Contract.Ensures(Contract.Result<String>() != null); return Number.FormatInt32(m_value, null, NumberFormatInfo.CurrentInfo); } public String ToString(IFormatProvider provider) { - Contract.Ensures(Contract.Result<String>() != null); return Number.FormatInt32(m_value, null, NumberFormatInfo.GetInstance(provider)); } public String ToString(String format) { - Contract.Ensures(Contract.Result<String>() != null); return ToString(format, NumberFormatInfo.CurrentInfo); } public String ToString(String format, IFormatProvider provider) { - Contract.Ensures(Contract.Result<String>() != null); return ToString(format, NumberFormatInfo.GetInstance(provider)); } private String ToString(String format, NumberFormatInfo info) { - Contract.Ensures(Contract.Result<String>() != null); - if (m_value < 0 && format != null && format.Length > 0 && (format[0] == 'X' || format[0] == 'x')) { uint temp = (uint)(m_value & 0x0000FFFF); diff --git a/src/System.Private.CoreLib/shared/System/Int32.cs b/src/System.Private.CoreLib/shared/System/Int32.cs index f5e832a27..d674e7b6b 100644 --- a/src/System.Private.CoreLib/shared/System/Int32.cs +++ b/src/System.Private.CoreLib/shared/System/Int32.cs @@ -12,7 +12,6 @@ ** ===========================================================*/ -using System.Diagnostics.Contracts; using System.Globalization; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; @@ -87,42 +86,32 @@ namespace System return m_value; } - [Pure] public override String ToString() { - Contract.Ensures(Contract.Result<String>() != null); return Number.FormatInt32(m_value, null, NumberFormatInfo.CurrentInfo); } - [Pure] public String ToString(String format) { - Contract.Ensures(Contract.Result<String>() != null); return Number.FormatInt32(m_value, format, NumberFormatInfo.CurrentInfo); } - [Pure] public String ToString(IFormatProvider provider) { - Contract.Ensures(Contract.Result<String>() != null); return Number.FormatInt32(m_value, null, NumberFormatInfo.GetInstance(provider)); } - [Pure] public String ToString(String format, IFormatProvider provider) { - Contract.Ensures(Contract.Result<String>() != null); return Number.FormatInt32(m_value, format, NumberFormatInfo.GetInstance(provider)); } - [Pure] public static int Parse(String s) { if (s == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.s); return Number.ParseInt32(s.AsReadOnlySpan(), NumberStyles.Integer, NumberFormatInfo.CurrentInfo); } - [Pure] public static int Parse(String s, NumberStyles style) { NumberFormatInfo.ValidateParseStyleInteger(style); @@ -134,7 +123,6 @@ namespace System // a NumberFormatInfo isn't specified, the current culture's // NumberFormatInfo is assumed. // - [Pure] public static int Parse(String s, IFormatProvider provider) { if (s == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.s); @@ -145,7 +133,6 @@ namespace System // a NumberFormatInfo isn't specified, the current culture's // NumberFormatInfo is assumed. // - [Pure] public static int Parse(String s, NumberStyles style, IFormatProvider provider) { NumberFormatInfo.ValidateParseStyleInteger(style); @@ -162,7 +149,6 @@ namespace System // Parses an integer from a String. Returns false rather // than throwing exceptin if input is invalid // - [Pure] public static bool TryParse(String s, out Int32 result) { if (s == null) @@ -177,7 +163,6 @@ namespace System // Parses an integer from a String in the given style. Returns false rather // than throwing exceptin if input is invalid // - [Pure] public static bool TryParse(String s, NumberStyles style, IFormatProvider provider, out Int32 result) { NumberFormatInfo.ValidateParseStyleInteger(style); @@ -201,7 +186,6 @@ namespace System // IConvertible implementation // - [Pure] public TypeCode GetTypeCode() { return TypeCode.Int32; diff --git a/src/System.Private.CoreLib/shared/System/Int64.cs b/src/System.Private.CoreLib/shared/System/Int64.cs index 785fa39fa..e17c3ea6e 100644 --- a/src/System.Private.CoreLib/shared/System/Int64.cs +++ b/src/System.Private.CoreLib/shared/System/Int64.cs @@ -12,7 +12,6 @@ ** ===========================================================*/ -using System.Diagnostics.Contracts; using System.Globalization; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; @@ -86,25 +85,21 @@ namespace System public override String ToString() { - Contract.Ensures(Contract.Result<String>() != null); return Number.FormatInt64(m_value, null, NumberFormatInfo.CurrentInfo); } public String ToString(IFormatProvider provider) { - Contract.Ensures(Contract.Result<String>() != null); return Number.FormatInt64(m_value, null, NumberFormatInfo.GetInstance(provider)); } public String ToString(String format) { - Contract.Ensures(Contract.Result<String>() != null); return Number.FormatInt64(m_value, format, NumberFormatInfo.CurrentInfo); } public String ToString(String format, IFormatProvider provider) { - Contract.Ensures(Contract.Result<String>() != null); return Number.FormatInt64(m_value, format, NumberFormatInfo.GetInstance(provider)); } diff --git a/src/System.Private.CoreLib/shared/System/Math.cs b/src/System.Private.CoreLib/shared/System/Math.cs new file mode 100644 index 000000000..5c69c84e4 --- /dev/null +++ b/src/System.Private.CoreLib/shared/System/Math.cs @@ -0,0 +1,832 @@ +// 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. + +/*============================================================ +** +** +** +** Purpose: Some floating-point math operations +** +** +===========================================================*/ + +//This class contains only static members and doesn't require serialization. + +using System.Diagnostics; +using System.Diagnostics.Contracts; +using System.Runtime; +using System.Runtime.CompilerServices; +using System.Runtime.Versioning; + +namespace System +{ + public static partial class Math + { + public const double E = 2.7182818284590452354; + + public const double PI = 3.14159265358979323846; + + private const int maxRoundingDigits = 15; + + private static double doubleRoundLimit = 1e16d; + + // This table is required for the Round function which can specify the number of digits to round to + private static double[] roundPower10Double = new double[] { + 1E0, 1E1, 1E2, 1E3, 1E4, 1E5, 1E6, 1E7, 1E8, + 1E9, 1E10, 1E11, 1E12, 1E13, 1E14, 1E15 + }; + + public static short Abs(short value) + { + return (value >= 0) ? value : AbsHelper(value); + } + + public static int Abs(int value) + { + return (value >= 0) ? value : AbsHelper(value); + } + + public static long Abs(long value) + { + return (value >= 0) ? value : AbsHelper(value); + } + + [CLSCompliant(false)] + public static sbyte Abs(sbyte value) + { + return (value >= 0) ? value : AbsHelper(value); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static decimal Abs(decimal value) + { + return decimal.Abs(value); + } + + public static long BigMul(int a, int b) + { + return ((long)a) * b; + } + + public static int DivRem(int a, int b, out int result) + { + // TODO https://github.com/dotnet/coreclr/issues/3439: + // Restore to using % and / when the JIT is able to eliminate one of the idivs. + // In the meantime, a * and - is measurably faster than an extra /. + + int div = a / b; + result = a - (div * b); + return div; + } + + public static long DivRem(long a, long b, out long result) + { + // TODO https://github.com/dotnet/coreclr/issues/3439: + // Restore to using % and / when the JIT is able to eliminate one of the idivs. + // In the meantime, a * and - is measurably faster than an extra /. + + long div = a / b; + result = a - (div * b); + return div; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static decimal Ceiling(decimal d) + { + return decimal.Ceiling(d); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static byte Clamp(byte value, byte min, byte max) + { + if (min > max) + { + ThrowMinMaxException(min, max); + } + + if (value < min) + { + return min; + } + else if (value > max) + { + return max; + } + + return value; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static decimal Clamp(decimal value, decimal min, decimal max) + { + if (min > max) + { + ThrowMinMaxException(min, max); + } + + if (value < min) + { + return min; + } + else if (value > max) + { + return max; + } + + return value; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static double Clamp(double value, double min, double max) + { + if (min > max) + { + ThrowMinMaxException(min, max); + } + + if (value < min) + { + return min; + } + else if (value > max) + { + return max; + } + + return value; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static short Clamp(short value, short min, short max) + { + if (min > max) + { + ThrowMinMaxException(min, max); + } + + if (value < min) + { + return min; + } + else if (value > max) + { + return max; + } + + return value; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int Clamp(int value, int min, int max) + { + if (min > max) + { + ThrowMinMaxException(min, max); + } + + if (value < min) + { + return min; + } + else if (value > max) + { + return max; + } + + return value; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static long Clamp(long value, long min, long max) + { + if (min > max) + { + ThrowMinMaxException(min, max); + } + + if (value < min) + { + return min; + } + else if (value > max) + { + return max; + } + + return value; + } + + [CLSCompliant(false)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static sbyte Clamp(sbyte value, sbyte min, sbyte max) + { + if (min > max) + { + ThrowMinMaxException(min, max); + } + + if (value < min) + { + return min; + } + else if (value > max) + { + return max; + } + + return value; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float Clamp(float value, float min, float max) + { + if (min > max) + { + ThrowMinMaxException(min, max); + } + + if (value < min) + { + return min; + } + else if (value > max) + { + return max; + } + + return value; + } + + [CLSCompliant(false)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ushort Clamp(ushort value, ushort min, ushort max) + { + if (min > max) + { + ThrowMinMaxException(min, max); + } + + if (value < min) + { + return min; + } + else if (value > max) + { + return max; + } + + return value; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + [CLSCompliant(false)] + public static uint Clamp(uint value, uint min, uint max) + { + if (min > max) + { + ThrowMinMaxException(min, max); + } + + if (value < min) + { + return min; + } + else if (value > max) + { + return max; + } + + return value; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + [CLSCompliant(false)] + public static ulong Clamp(ulong value, ulong min, ulong max) + { + if (min > max) + { + ThrowMinMaxException(min, max); + } + + if (value < min) + { + return min; + } + else if (value > max) + { + return max; + } + + return value; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static decimal Floor(decimal d) + { + return decimal.Floor(d); + } + + public static double IEEERemainder(double x, double y) + { + if (double.IsNaN(x)) + { + return x; // IEEE 754-2008: NaN payload must be preserved + } + + if (double.IsNaN(y)) + { + return y; // IEEE 754-2008: NaN payload must be preserved + } + + var regularMod = x % y; + + if (double.IsNaN(regularMod)) + { + return double.NaN; + } + + if ((regularMod == 0) && double.IsNegative(x)) + { + return double.NegativeZero; + } + + var alternativeResult = (regularMod - (Abs(y) * Sign(x))); + + if (Abs(alternativeResult) == Abs(regularMod)) + { + var divisionResult = x / y; + var roundedResult = Round(divisionResult); + + if (Abs(roundedResult) > Abs(divisionResult)) + { + return alternativeResult; + } + else + { + return regularMod; + } + } + + if (Abs(alternativeResult) < Abs(regularMod)) + { + return alternativeResult; + } + else + { + return regularMod; + } + } + + public static double Log(double a, double newBase) + { + if (double.IsNaN(a)) + { + return a; // IEEE 754-2008: NaN payload must be preserved + } + + if (double.IsNaN(newBase)) + { + return newBase; // IEEE 754-2008: NaN payload must be preserved + } + + if (newBase == 1) + { + return double.NaN; + } + + if ((a != 1) && ((newBase == 0) || double.IsPositiveInfinity(newBase))) + { + return double.NaN; + } + + return (Log(a) / Log(newBase)); + } + + [NonVersionable] + public static byte Max(byte val1, byte val2) + { + return (val1 >= val2) ? val1 : val2; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static decimal Max(decimal val1, decimal val2) + { + return decimal.Max(val1, val2); + } + + public static double Max(double val1, double val2) + { + if (val1 > val2) + { + return val1; + } + + if (double.IsNaN(val1)) + { + return val1; + } + + return val2; + } + + [NonVersionable] + public static short Max(short val1, short val2) + { + return (val1 >= val2) ? val1 : val2; + } + + [NonVersionable] + public static int Max(int val1, int val2) + { + return (val1 >= val2) ? val1 : val2; + } + + [NonVersionable] + public static long Max(long val1, long val2) + { + return (val1 >= val2) ? val1 : val2; + } + + [CLSCompliant(false)] + [NonVersionable] + public static sbyte Max(sbyte val1, sbyte val2) + { + return (val1 >= val2) ? val1 : val2; + } + + public static float Max(float val1, float val2) + { + if (val1 > val2) + { + return val1; + } + + if (float.IsNaN(val1)) + { + return val1; + } + + return val2; + } + + [CLSCompliant(false)] + [NonVersionable] + public static ushort Max(ushort val1, ushort val2) + { + return (val1 >= val2) ? val1 : val2; + } + + [CLSCompliant(false)] + [NonVersionable] + public static uint Max(uint val1, uint val2) + { + return (val1 >= val2) ? val1 : val2; + } + + [CLSCompliant(false)] + [NonVersionable] + public static ulong Max(ulong val1, ulong val2) + { + return (val1 >= val2) ? val1 : val2; + } + + [NonVersionable] + public static byte Min(byte val1, byte val2) + { + return (val1 <= val2) ? val1 : val2; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static decimal Min(decimal val1, decimal val2) + { + return decimal.Min(val1, val2); + } + + public static double Min(double val1, double val2) + { + if (val1 < val2) + { + return val1; + } + + if (double.IsNaN(val1)) + { + return val1; + } + + return val2; + } + + [NonVersionable] + public static short Min(short val1, short val2) + { + return (val1 <= val2) ? val1 : val2; + } + + [NonVersionable] + public static int Min(int val1, int val2) + { + return (val1 <= val2) ? val1 : val2; + } + + [NonVersionable] + public static long Min(long val1, long val2) + { + return (val1 <= val2) ? val1 : val2; + } + + [CLSCompliant(false)] + [NonVersionable] + public static sbyte Min(sbyte val1, sbyte val2) + { + return (val1 <= val2) ? val1 : val2; + } + + public static float Min(float val1, float val2) + { + if (val1 < val2) + { + return val1; + } + + if (float.IsNaN(val1)) + { + return val1; + } + + return val2; + } + + [CLSCompliant(false)] + [NonVersionable] + public static ushort Min(ushort val1, ushort val2) + { + return (val1 <= val2) ? val1 : val2; + } + + [CLSCompliant(false)] + [NonVersionable] + public static uint Min(uint val1, uint val2) + { + return (val1 <= val2) ? val1 : val2; + } + + [CLSCompliant(false)] + [NonVersionable] + public static ulong Min(ulong val1, ulong val2) + { + return (val1 <= val2) ? val1 : val2; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static decimal Round(decimal d) + { + return decimal.Round(d, 0); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static decimal Round(decimal d, int decimals) + { + return decimal.Round(d, decimals); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static decimal Round(decimal d, MidpointRounding mode) + { + return decimal.Round(d, 0, mode); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static decimal Round(decimal d, int decimals, MidpointRounding mode) + { + return decimal.Round(d, decimals, mode); + } + + [Intrinsic] + public static double Round(double a) + { + // ************************************************************************************ + // IMPORTANT: Do not change this implementation without also updating Math.Round(double), + // FloatingPointUtils::round(double), and FloatingPointUtils::round(float) + // ************************************************************************************ + + // If the number has no fractional part do nothing + // This shortcut is necessary to workaround precision loss in borderline cases on some platforms + + if (a == (double)((long)a)) + { + return a; + } + + // We had a number that was equally close to 2 integers. + // We need to return the even one. + + double flrTempVal = Floor(a + 0.5); + + if ((a == (Floor(a) + 0.5)) && (FMod(flrTempVal, 2.0) != 0)) + { + flrTempVal -= 1.0; + } + + return copysign(flrTempVal, a); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static double Round(double value, int digits) + { + return Round(value, digits, MidpointRounding.ToEven); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static double Round(double value, MidpointRounding mode) + { + return Round(value, 0, mode); + } + + public static unsafe double Round(double value, int digits, MidpointRounding mode) + { + if ((digits < 0) || (digits > maxRoundingDigits)) + { + throw new ArgumentOutOfRangeException(nameof(digits), SR.ArgumentOutOfRange_RoundingDigits); + } + + if (mode < MidpointRounding.ToEven || mode > MidpointRounding.AwayFromZero) + { + throw new ArgumentException(SR.Format(SR.Argument_InvalidEnumValue, mode, nameof(MidpointRounding)), nameof(mode)); + } + + if (Abs(value) < doubleRoundLimit) + { + var power10 = roundPower10Double[digits]; + + value *= power10; + + if (mode == MidpointRounding.AwayFromZero) + { + var fraction = ModF(value, &value); + + if (Abs(fraction) >= 0.5) + { + value += Sign(fraction); + } + } + else + { + value = Round(value); + } + + value /= power10; + } + + return value; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int Sign(decimal value) + { + return decimal.Sign(ref value); + } + + public static int Sign(double value) + { + if (value < 0) + { + return -1; + } + else if (value > 0) + { + return 1; + } + else if (value == 0) + { + return 0; + } + + throw new ArithmeticException(SR.Arithmetic_NaN); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int Sign(short value) + { + return Sign((int)value); + } + + public static int Sign(int value) + { + return unchecked(value >> 31 | (int)((uint)-value >> 31)); + } + + public static int Sign(long value) + { + return unchecked((int)(value >> 63 | (long)((ulong)-value >> 63))); + } + + [CLSCompliant(false)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int Sign(sbyte value) + { + return Sign((int)value); + } + + public static int Sign(float value) + { + if (value < 0) + { + return -1; + } + else if (value > 0) + { + return 1; + } + else if (value == 0) + { + return 0; + } + + throw new ArithmeticException(SR.Arithmetic_NaN); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static decimal Truncate(decimal d) + { + return decimal.Truncate(d); + } + + public static unsafe double Truncate(double d) + { + ModF(d, &d); + return d; + } + + private static short AbsHelper(short value) + { + Debug.Assert(value < 0, "AbsHelper should only be called for negative values! (workaround for JIT inlining)"); + + if (value == short.MinValue) + { + throw new OverflowException(SR.Overflow_NegateTwosCompNum); + } + + return ((short)(-value)); + } + + private static int AbsHelper(int value) + { + Debug.Assert(value < 0, "AbsHelper should only be called for negative values! (workaround for JIT inlining)"); + + if (value == int.MinValue) + { + throw new OverflowException(SR.Overflow_NegateTwosCompNum); + } + + return -value; + } + + private static long AbsHelper(long value) + { + Debug.Assert(value < 0, "AbsHelper should only be called for negative values! (workaround for JIT inlining)"); + + if (value == long.MinValue) + { + throw new OverflowException(SR.Overflow_NegateTwosCompNum); + } + + return -value; + } + + private static sbyte AbsHelper(sbyte value) + { + Debug.Assert(value < 0, "AbsHelper should only be called for negative values! (workaround for JIT inlining)"); + + if (value == sbyte.MinValue) + { + throw new OverflowException(SR.Overflow_NegateTwosCompNum); + } + + return ((sbyte)(-value)); + } + + private static unsafe double copysign(double x, double y) + { + var xbits = BitConverter.DoubleToInt64Bits(x); + var ybits = BitConverter.DoubleToInt64Bits(y); + + // If the sign bits of x and y are not the same, + // flip the sign bit of x and return the new value; + // otherwise, just return x + + if (((xbits ^ ybits) >> 63) != 0) + { + return BitConverter.Int64BitsToDouble(xbits ^ long.MinValue); + } + + return x; + } + + private static void ThrowMinMaxException<T>(T min, T max) + { + throw new ArgumentException(SR.Format(SR.Argument_MinMaxValue, min, max)); + } + } +} diff --git a/src/System.Private.CoreLib/shared/System/MathF.cs b/src/System.Private.CoreLib/shared/System/MathF.cs new file mode 100644 index 000000000..5b7e48b06 --- /dev/null +++ b/src/System.Private.CoreLib/shared/System/MathF.cs @@ -0,0 +1,235 @@ +// 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. + +/*============================================================ +** +** Purpose: Some single-precision floating-point math operations +** +===========================================================*/ + +//This class contains only static members and doesn't require serialization. + +using System.Runtime; +using System.Runtime.CompilerServices; + +namespace System +{ + public static partial class MathF + { + public const float E = 2.71828183f; + + public const float PI = 3.14159265f; + + private const int maxRoundingDigits = 6; + + // This table is required for the Round function which can specify the number of digits to round to + private static float[] roundPower10Single = new float[] { + 1e0f, 1e1f, 1e2f, 1e3f, 1e4f, 1e5f, 1e6f + }; + + private static float singleRoundLimit = 1e8f; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float Abs(float x) + { + return Math.Abs(x); + } + + public static float IEEERemainder(float x, float y) + { + if (float.IsNaN(x)) + { + return x; // IEEE 754-2008: NaN payload must be preserved + } + + if (float.IsNaN(y)) + { + return y; // IEEE 754-2008: NaN payload must be preserved + } + + var regularMod = x % y; + + if (float.IsNaN(regularMod)) + { + return float.NaN; + } + + if ((regularMod == 0) && float.IsNegative(x)) + { + return float.NegativeZero; + } + + var alternativeResult = (regularMod - (Abs(y) * Sign(x))); + + if (Abs(alternativeResult) == Abs(regularMod)) + { + var divisionResult = x / y; + var roundedResult = Round(divisionResult); + + if (Abs(roundedResult) > Abs(divisionResult)) + { + return alternativeResult; + } + else + { + return regularMod; + } + } + + if (Abs(alternativeResult) < Abs(regularMod)) + { + return alternativeResult; + } + else + { + return regularMod; + } + } + + public static float Log(float x, float y) + { + if (float.IsNaN(x)) + { + return x; // IEEE 754-2008: NaN payload must be preserved + } + + if (float.IsNaN(y)) + { + return y; // IEEE 754-2008: NaN payload must be preserved + } + + if (y == 1) + { + return float.NaN; + } + + if ((x != 1) && ((y == 0) || float.IsPositiveInfinity(y))) + { + return float.NaN; + } + + return Log(x) / Log(y); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float Max(float x, float y) + { + return Math.Max(x, y); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float Min(float x, float y) + { + return Math.Min(x, y); + } + + [Intrinsic] + public static float Round(float x) + { + // ************************************************************************************ + // IMPORTANT: Do not change this implementation without also updating Math.Round(double), + // FloatingPointUtils::round(double), and FloatingPointUtils::round(float) + // ************************************************************************************ + + // If the number has no fractional part do nothing + // This shortcut is necessary to workaround precision loss in borderline cases on some platforms + + if (x == (float)((int)x)) + { + return x; + } + + // We had a number that was equally close to 2 integers. + // We need to return the even one. + + float flrTempVal = Floor(x + 0.5f); + + if ((x == (Floor(x) + 0.5f)) && (FMod(flrTempVal, 2.0f) != 0)) + { + flrTempVal -= 1.0f; + } + + return CopySign(flrTempVal, x); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float Round(float x, int digits) + { + return Round(x, digits, MidpointRounding.ToEven); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float Round(float x, MidpointRounding mode) + { + return Round(x, 0, mode); + } + + public static unsafe float Round(float x, int digits, MidpointRounding mode) + { + if ((digits < 0) || (digits > maxRoundingDigits)) + { + throw new ArgumentOutOfRangeException(nameof(digits), SR.ArgumentOutOfRange_RoundingDigits); + } + + if (mode < MidpointRounding.ToEven || mode > MidpointRounding.AwayFromZero) + { + throw new ArgumentException(SR.Format(SR.Argument_InvalidEnum, mode, nameof(MidpointRounding)), nameof(mode)); + } + + if (Abs(x) < singleRoundLimit) + { + var power10 = roundPower10Single[digits]; + + x *= power10; + + if (mode == MidpointRounding.AwayFromZero) + { + var fraction = ModF(x, &x); + + if (Abs(fraction) >= 0.5f) + { + x += Sign(fraction); + } + } + else + { + x = Round(x); + } + + x /= power10; + } + + return x; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int Sign(float x) + { + return Math.Sign(x); + } + + public static unsafe float Truncate(float x) + { + ModF(x, &x); + return x; + } + + private static unsafe float CopySign(float x, float y) + { + var xbits = BitConverter.SingleToInt32Bits(x); + var ybits = BitConverter.SingleToInt32Bits(y); + + // If the sign bits of x and y are not the same, + // flip the sign bit of x and return the new value; + // otherwise, just return x + + if (((xbits ^ ybits) >> 31) != 0) + { + return BitConverter.Int32BitsToSingle(xbits ^ int.MinValue); + } + + return x; + } + } +} diff --git a/src/System.Private.CoreLib/shared/System/Resources/RuntimeResourceSet.cs b/src/System.Private.CoreLib/shared/System/Resources/RuntimeResourceSet.cs index 41d7541c2..eadc92c7f 100644 --- a/src/System.Private.CoreLib/shared/System/Resources/RuntimeResourceSet.cs +++ b/src/System.Private.CoreLib/shared/System/Resources/RuntimeResourceSet.cs @@ -21,7 +21,6 @@ using System.Globalization; using System.Reflection; using System.Runtime.Versioning; using System.Diagnostics; -using System.Diagnostics.Contracts; namespace System.Resources { @@ -285,7 +284,6 @@ namespace System.Resources throw new ArgumentNullException(nameof(key)); if (Reader == null || _resCache == null) throw new ObjectDisposedException(null, SR.ObjectDisposed_ResourceSet); - Contract.EndContractBlock(); Object value = null; ResourceLocator resLocation; diff --git a/src/System.Private.CoreLib/shared/System/Runtime/CompilerServices/ConfiguredValueTaskAwaitable.cs b/src/System.Private.CoreLib/shared/System/Runtime/CompilerServices/ConfiguredValueTaskAwaitable.cs index 4ec931c4a..0784e6135 100644 --- a/src/System.Private.CoreLib/shared/System/Runtime/CompilerServices/ConfiguredValueTaskAwaitable.cs +++ b/src/System.Private.CoreLib/shared/System/Runtime/CompilerServices/ConfiguredValueTaskAwaitable.cs @@ -39,7 +39,7 @@ namespace System.Runtime.CompilerServices /// <summary>The value being awaited.</summary> private ValueTask<TResult> _value; // Methods are called on this; avoid making it readonly so as to avoid unnecessary copies /// <summary>The value to pass to ConfigureAwait.</summary> - private readonly bool _continueOnCapturedContext; + internal readonly bool _continueOnCapturedContext; /// <summary>Initializes the awaiter.</summary> /// <param name="value">The value to be awaited.</param> @@ -66,6 +66,9 @@ namespace System.Runtime.CompilerServices /// <summary>Schedules the continuation action for the <see cref="ConfiguredValueTaskAwaitable{TResult}"/>.</summary> public void UnsafeOnCompleted(Action continuation) => _value.AsTask().ConfigureAwait(_continueOnCapturedContext).GetAwaiter().UnsafeOnCompleted(continuation); + + /// <summary>Gets the task underlying <see cref="_value"/>.</summary> + internal Task<TResult> AsTask() => _value.AsTask(); } } } diff --git a/src/System.Private.CoreLib/shared/System/Runtime/CompilerServices/ValueTaskAwaiter.cs b/src/System.Private.CoreLib/shared/System/Runtime/CompilerServices/ValueTaskAwaiter.cs index c41948252..30e688e07 100644 --- a/src/System.Private.CoreLib/shared/System/Runtime/CompilerServices/ValueTaskAwaiter.cs +++ b/src/System.Private.CoreLib/shared/System/Runtime/CompilerServices/ValueTaskAwaiter.cs @@ -33,5 +33,8 @@ namespace System.Runtime.CompilerServices /// <summary>Schedules the continuation action for this ValueTask.</summary> public void UnsafeOnCompleted(Action continuation) => _value.AsTask().ConfigureAwait(continueOnCapturedContext: true).GetAwaiter().UnsafeOnCompleted(continuation); + + /// <summary>Gets the task underlying <see cref="_value"/>.</summary> + internal Task<TResult> AsTask() => _value.AsTask(); } } diff --git a/src/System.Private.CoreLib/shared/System/Runtime/Versioning/TargetFrameworkAttribute.cs b/src/System.Private.CoreLib/shared/System/Runtime/Versioning/TargetFrameworkAttribute.cs index 54ccdf2c8..a81906638 100644 --- a/src/System.Private.CoreLib/shared/System/Runtime/Versioning/TargetFrameworkAttribute.cs +++ b/src/System.Private.CoreLib/shared/System/Runtime/Versioning/TargetFrameworkAttribute.cs @@ -13,7 +13,6 @@ ===========================================================*/ using System; -using System.Diagnostics.Contracts; namespace System.Runtime.Versioning { @@ -28,7 +27,6 @@ namespace System.Runtime.Versioning { if (frameworkName == null) throw new ArgumentNullException(nameof(frameworkName)); - Contract.EndContractBlock(); _frameworkName = frameworkName; } diff --git a/src/System.Private.CoreLib/shared/System/SByte.cs b/src/System.Private.CoreLib/shared/System/SByte.cs index c98476733..5b5c031d5 100644 --- a/src/System.Private.CoreLib/shared/System/SByte.cs +++ b/src/System.Private.CoreLib/shared/System/SByte.cs @@ -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.Diagnostics.Contracts; using System.Globalization; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; @@ -74,32 +73,26 @@ namespace System // Provides a string representation of a byte. public override String ToString() { - Contract.Ensures(Contract.Result<String>() != null); return Number.FormatInt32(m_value, null, NumberFormatInfo.CurrentInfo); } public String ToString(IFormatProvider provider) { - Contract.Ensures(Contract.Result<String>() != null); return Number.FormatInt32(m_value, null, NumberFormatInfo.GetInstance(provider)); } public String ToString(String format) { - Contract.Ensures(Contract.Result<String>() != null); return ToString(format, NumberFormatInfo.CurrentInfo); } public String ToString(String format, IFormatProvider provider) { - Contract.Ensures(Contract.Result<String>() != null); return ToString(format, NumberFormatInfo.GetInstance(provider)); } private String ToString(String format, NumberFormatInfo info) { - Contract.Ensures(Contract.Result<String>() != null); - if (m_value < 0 && format != null && format.Length > 0 && (format[0] == 'X' || format[0] == 'x')) { uint temp = (uint)(m_value & 0x000000FF); diff --git a/src/System.Private.CoreLib/shared/System/Single.cs b/src/System.Private.CoreLib/shared/System/Single.cs index 0be8cfbc3..14f0ca49f 100644 --- a/src/System.Private.CoreLib/shared/System/Single.cs +++ b/src/System.Private.CoreLib/shared/System/Single.cs @@ -11,7 +11,6 @@ ** ===========================================================*/ -using System.Diagnostics.Contracts; using System.Globalization; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; @@ -40,7 +39,6 @@ namespace System internal const float NegativeZero = (float)-0.0; /// <summary>Determines whether the specified value is finite (zero, subnormal, or normal).</summary> - [Pure] [NonVersionable] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool IsFinite(float f) @@ -50,7 +48,6 @@ namespace System } /// <summary>Determines whether the specified value is infinite.</summary> - [Pure] [NonVersionable] [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static bool IsInfinity(float f) @@ -60,7 +57,6 @@ namespace System } /// <summary>Determines whether the specified value is NaN.</summary> - [Pure] [NonVersionable] [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static bool IsNaN(float f) @@ -70,7 +66,6 @@ namespace System } /// <summary>Determines whether the specified value is negative.</summary> - [Pure] [NonVersionable] [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static bool IsNegative(float f) @@ -80,7 +75,6 @@ namespace System } /// <summary>Determines whether the specified value is negative infinity.</summary> - [Pure] [NonVersionable] [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static bool IsNegativeInfinity(float f) @@ -89,7 +83,6 @@ namespace System } /// <summary>Determines whether the specified value is normal.</summary> - [Pure] [NonVersionable] // This is probably not worth inlining, it has branches and should be rarely called public unsafe static bool IsNormal(float f) @@ -100,7 +93,6 @@ namespace System } /// <summary>Determines whether the specified value is positive infinity.</summary> - [Pure] [NonVersionable] [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static bool IsPositiveInfinity(float f) @@ -109,7 +101,6 @@ namespace System } /// <summary>Determines whether the specified value is subnormal.</summary> - [Pure] [NonVersionable] // This is probably not worth inlining, it has branches and should be rarely called public unsafe static bool IsSubnormal(float f) @@ -236,25 +227,21 @@ namespace System public override String ToString() { - Contract.Ensures(Contract.Result<String>() != null); return Number.FormatSingle(m_value, null, NumberFormatInfo.CurrentInfo); } public String ToString(IFormatProvider provider) { - Contract.Ensures(Contract.Result<String>() != null); return Number.FormatSingle(m_value, null, NumberFormatInfo.GetInstance(provider)); } public String ToString(String format) { - Contract.Ensures(Contract.Result<String>() != null); return Number.FormatSingle(m_value, format, NumberFormatInfo.CurrentInfo); } public String ToString(String format, IFormatProvider provider) { - Contract.Ensures(Contract.Result<String>() != null); return Number.FormatSingle(m_value, format, NumberFormatInfo.GetInstance(provider)); } diff --git a/src/System.Private.CoreLib/shared/System/StringComparer.cs b/src/System.Private.CoreLib/shared/System/StringComparer.cs index ad667ae29..73c013599 100644 --- a/src/System.Private.CoreLib/shared/System/StringComparer.cs +++ b/src/System.Private.CoreLib/shared/System/StringComparer.cs @@ -5,7 +5,6 @@ using System.Collections; using System.Collections.Generic; using System.Globalization; -using System.Diagnostics.Contracts; using System.Runtime.Serialization; namespace System @@ -23,7 +22,6 @@ namespace System { get { - Contract.Ensures(Contract.Result<StringComparer>() != null); return s_invariantCulture; } } @@ -32,7 +30,6 @@ namespace System { get { - Contract.Ensures(Contract.Result<StringComparer>() != null); return s_invariantCultureIgnoreCase; } } @@ -41,7 +38,6 @@ namespace System { get { - Contract.Ensures(Contract.Result<StringComparer>() != null); return new CultureAwareComparer(CultureInfo.CurrentCulture, false); } } @@ -50,7 +46,6 @@ namespace System { get { - Contract.Ensures(Contract.Result<StringComparer>() != null); return new CultureAwareComparer(CultureInfo.CurrentCulture, true); } } @@ -59,7 +54,6 @@ namespace System { get { - Contract.Ensures(Contract.Result<StringComparer>() != null); return s_ordinal; } } @@ -68,7 +62,6 @@ namespace System { get { - Contract.Ensures(Contract.Result<StringComparer>() != null); return s_ordinalIgnoreCase; } } @@ -101,8 +94,6 @@ namespace System { throw new ArgumentNullException(nameof(culture)); } - Contract.Ensures(Contract.Result<StringComparer>() != null); - Contract.EndContractBlock(); return new CultureAwareComparer(culture, ignoreCase); } @@ -156,7 +147,6 @@ namespace System { throw new ArgumentNullException(nameof(obj)); } - Contract.EndContractBlock(); string s = obj as string; if (s != null) @@ -279,7 +269,6 @@ namespace System { ThrowHelper.ThrowArgumentNullException(ExceptionArgument.obj); } - Contract.EndContractBlock(); if (_ignoreCase) { diff --git a/src/System.Private.CoreLib/shared/System/Text/ASCIIEncoding.cs b/src/System.Private.CoreLib/shared/System/Text/ASCIIEncoding.cs index f614fb768..2d2bf205a 100644 --- a/src/System.Private.CoreLib/shared/System/Text/ASCIIEncoding.cs +++ b/src/System.Private.CoreLib/shared/System/Text/ASCIIEncoding.cs @@ -4,7 +4,6 @@ using System; using System.Diagnostics; -using System.Diagnostics.Contracts; namespace System.Text { @@ -66,7 +65,6 @@ namespace System.Text if (chars.Length - index < count) throw new ArgumentOutOfRangeException("chars", SR.ArgumentOutOfRange_IndexCountBuffer); - Contract.EndContractBlock(); // If no input, return 0, avoid fixed empty array problem if (count == 0) @@ -87,7 +85,6 @@ namespace System.Text // Validate input if (chars==null) throw new ArgumentNullException("chars"); - Contract.EndContractBlock(); fixed (char* pChars = chars) return GetByteCount(pChars, chars.Length, null); @@ -106,7 +103,6 @@ namespace System.Text if (count < 0) throw new ArgumentOutOfRangeException("count", SR.ArgumentOutOfRange_NeedNonNegNum); - Contract.EndContractBlock(); // Call it with empty encoder return GetByteCount(chars, count, null); @@ -131,7 +127,6 @@ namespace System.Text if (byteIndex < 0 || byteIndex > bytes.Length) throw new ArgumentOutOfRangeException("byteIndex", SR.ArgumentOutOfRange_Index); - Contract.EndContractBlock(); int byteCount = bytes.Length - byteIndex; @@ -172,7 +167,6 @@ namespace System.Text if (byteIndex < 0 || byteIndex > bytes.Length) throw new ArgumentOutOfRangeException("byteIndex", SR.ArgumentOutOfRange_Index); - Contract.EndContractBlock(); // If nothing to encode return 0, avoid fixed problem if (charCount == 0) @@ -203,7 +197,6 @@ namespace System.Text if (charCount < 0 || byteCount < 0) throw new ArgumentOutOfRangeException((charCount < 0 ? "charCount" : "byteCount"), SR.ArgumentOutOfRange_NeedNonNegNum); - Contract.EndContractBlock(); return GetBytes(chars, charCount, bytes, byteCount, null); } @@ -227,7 +220,6 @@ namespace System.Text if (bytes.Length - index < count) throw new ArgumentOutOfRangeException("bytes", SR.ArgumentOutOfRange_IndexCountBuffer); - Contract.EndContractBlock(); // If no input just return 0, fixed doesn't like 0 length arrays if (count == 0) @@ -251,7 +243,6 @@ namespace System.Text if (count < 0) throw new ArgumentOutOfRangeException("count", SR.ArgumentOutOfRange_NeedNonNegNum); - Contract.EndContractBlock(); return GetCharCount(bytes, count, null); } @@ -276,7 +267,6 @@ namespace System.Text if (charIndex < 0 || charIndex > chars.Length) throw new ArgumentOutOfRangeException("charIndex", SR.ArgumentOutOfRange_Index); - Contract.EndContractBlock(); // If no input, return 0 & avoid fixed problem if (byteCount == 0) @@ -307,7 +297,6 @@ namespace System.Text if (charCount < 0 || byteCount < 0) throw new ArgumentOutOfRangeException((charCount < 0 ? "charCount" : "byteCount"), SR.ArgumentOutOfRange_NeedNonNegNum); - Contract.EndContractBlock(); return GetChars(bytes, byteCount, chars, charCount, null); } @@ -332,7 +321,6 @@ namespace System.Text if (bytes.Length - byteIndex < byteCount) throw new ArgumentOutOfRangeException("bytes", SR.ArgumentOutOfRange_IndexCountBuffer); - Contract.EndContractBlock(); // Avoid problems with empty input buffer if (byteCount == 0) return String.Empty; @@ -910,7 +898,6 @@ namespace System.Text if (charCount < 0) throw new ArgumentOutOfRangeException(nameof(charCount), SR.ArgumentOutOfRange_NeedNonNegNum); - Contract.EndContractBlock(); // Characters would be # of characters + 1 in case high surrogate is ? * max fallback long byteCount = (long)charCount + 1; @@ -931,7 +918,6 @@ namespace System.Text if (byteCount < 0) throw new ArgumentOutOfRangeException(nameof(byteCount), SR.ArgumentOutOfRange_NeedNonNegNum); - Contract.EndContractBlock(); // Just return length, SBCS stay the same length because they don't map to surrogate long charCount = (long)byteCount; diff --git a/src/System.Private.CoreLib/shared/System/Text/Decoder.cs b/src/System.Private.CoreLib/shared/System/Text/Decoder.cs index 82d33d518..8dccaacd9 100644 --- a/src/System.Private.CoreLib/shared/System/Text/Decoder.cs +++ b/src/System.Private.CoreLib/shared/System/Text/Decoder.cs @@ -5,7 +5,6 @@ using System.Text; using System; using System.Diagnostics; -using System.Diagnostics.Contracts; namespace System.Text { @@ -42,7 +41,6 @@ namespace System.Text { if (value == null) throw new ArgumentNullException(nameof(value)); - Contract.EndContractBlock(); // Can't change fallback if buffer is wrong if (_fallbackBuffer != null && _fallbackBuffer.Remaining > 0) @@ -123,7 +121,6 @@ namespace System.Text if (count < 0) throw new ArgumentOutOfRangeException(nameof(count), SR.ArgumentOutOfRange_NeedNonNegNum); - Contract.EndContractBlock(); byte[] arrbyte = new byte[count]; int index; @@ -195,7 +192,6 @@ namespace System.Text if (byteCount < 0 || charCount < 0) throw new ArgumentOutOfRangeException((byteCount < 0 ? nameof(byteCount) : nameof(charCount)), SR.ArgumentOutOfRange_NeedNonNegNum); - Contract.EndContractBlock(); // Get the byte array to convert byte[] arrByte = new byte[byteCount]; @@ -274,7 +270,6 @@ namespace System.Text if (chars.Length - charIndex < charCount) throw new ArgumentOutOfRangeException(nameof(chars), SR.ArgumentOutOfRange_IndexCountBuffer); - Contract.EndContractBlock(); bytesUsed = byteCount; @@ -319,7 +314,6 @@ namespace System.Text if (byteCount < 0 || charCount < 0) throw new ArgumentOutOfRangeException((byteCount < 0 ? nameof(byteCount) : nameof(charCount)), SR.ArgumentOutOfRange_NeedNonNegNum); - Contract.EndContractBlock(); // Get ready to do it bytesUsed = byteCount; diff --git a/src/System.Private.CoreLib/shared/System/Text/DecoderNLS.cs b/src/System.Private.CoreLib/shared/System/Text/DecoderNLS.cs index ef85200d5..098730eed 100644 --- a/src/System.Private.CoreLib/shared/System/Text/DecoderNLS.cs +++ b/src/System.Private.CoreLib/shared/System/Text/DecoderNLS.cs @@ -5,7 +5,6 @@ using System.Runtime.Serialization; using System.Text; using System; -using System.Diagnostics.Contracts; namespace System.Text { @@ -67,7 +66,6 @@ namespace System.Text throw new ArgumentOutOfRangeException(nameof(bytes), SR.ArgumentOutOfRange_IndexCountBuffer); - Contract.EndContractBlock(); // Avoid null fixed problem if (bytes.Length == 0) @@ -88,7 +86,6 @@ namespace System.Text if (count < 0) throw new ArgumentOutOfRangeException(nameof(count), SR.ArgumentOutOfRange_NeedNonNegNum); - Contract.EndContractBlock(); // Remember the flush _mustFlush = flush; @@ -124,7 +121,6 @@ namespace System.Text throw new ArgumentOutOfRangeException(nameof(charIndex), SR.ArgumentOutOfRange_Index); - Contract.EndContractBlock(); // Avoid empty input fixed problem if (bytes.Length == 0) @@ -153,7 +149,6 @@ namespace System.Text if (byteCount < 0 || charCount < 0) throw new ArgumentOutOfRangeException((byteCount < 0 ? nameof(byteCount) : nameof(charCount)), SR.ArgumentOutOfRange_NeedNonNegNum); - Contract.EndContractBlock(); // Remember our flush _mustFlush = flush; @@ -190,7 +185,6 @@ namespace System.Text throw new ArgumentOutOfRangeException(nameof(chars), SR.ArgumentOutOfRange_IndexCountBuffer); - Contract.EndContractBlock(); // Avoid empty input problem if (bytes.Length == 0) @@ -223,7 +217,6 @@ namespace System.Text if (byteCount < 0 || charCount < 0) throw new ArgumentOutOfRangeException((byteCount < 0 ? nameof(byteCount) : nameof(charCount)), SR.ArgumentOutOfRange_NeedNonNegNum); - Contract.EndContractBlock(); // We don't want to throw _mustFlush = flush; diff --git a/src/System.Private.CoreLib/shared/System/Text/DecoderReplacementFallback.cs b/src/System.Private.CoreLib/shared/System/Text/DecoderReplacementFallback.cs index 8a8d550c8..422b80bb2 100644 --- a/src/System.Private.CoreLib/shared/System/Text/DecoderReplacementFallback.cs +++ b/src/System.Private.CoreLib/shared/System/Text/DecoderReplacementFallback.cs @@ -3,7 +3,6 @@ // See the LICENSE file in the project root for more information. using System.Diagnostics; -using System.Diagnostics.Contracts; namespace System.Text { @@ -21,7 +20,6 @@ namespace System.Text { if (replacement == null) throw new ArgumentNullException(nameof(replacement)); - Contract.EndContractBlock(); // Make sure it doesn't have bad surrogate pairs bool bFoundHigh = false; diff --git a/src/System.Private.CoreLib/shared/System/Text/Encoder.cs b/src/System.Private.CoreLib/shared/System/Text/Encoder.cs index 79a633f1f..167060859 100644 --- a/src/System.Private.CoreLib/shared/System/Text/Encoder.cs +++ b/src/System.Private.CoreLib/shared/System/Text/Encoder.cs @@ -5,7 +5,6 @@ using System.Text; using System; using System.Diagnostics; -using System.Diagnostics.Contracts; namespace System.Text { @@ -42,7 +41,6 @@ namespace System.Text { if (value == null) throw new ArgumentNullException(nameof(value)); - Contract.EndContractBlock(); // Can't change fallback if buffer is wrong if (_fallbackBuffer != null && _fallbackBuffer.Remaining > 0) @@ -121,7 +119,6 @@ namespace System.Text if (count < 0) throw new ArgumentOutOfRangeException(nameof(count), SR.ArgumentOutOfRange_NeedNonNegNum); - Contract.EndContractBlock(); char[] arrChar = new char[count]; int index; @@ -190,7 +187,6 @@ namespace System.Text if (charCount < 0 || byteCount < 0) throw new ArgumentOutOfRangeException((charCount < 0 ? nameof(charCount) : nameof(byteCount)), SR.ArgumentOutOfRange_NeedNonNegNum); - Contract.EndContractBlock(); // Get the char array to convert char[] arrChar = new char[charCount]; @@ -268,7 +264,6 @@ namespace System.Text if (bytes.Length - byteIndex < byteCount) throw new ArgumentOutOfRangeException(nameof(bytes), SR.ArgumentOutOfRange_IndexCountBuffer); - Contract.EndContractBlock(); charsUsed = charCount; @@ -313,7 +308,6 @@ namespace System.Text if (charCount < 0 || byteCount < 0) throw new ArgumentOutOfRangeException((charCount < 0 ? nameof(charCount) : nameof(byteCount)), SR.ArgumentOutOfRange_NeedNonNegNum); - Contract.EndContractBlock(); // Get ready to do it charsUsed = charCount; diff --git a/src/System.Private.CoreLib/shared/System/Text/EncoderBestFitFallback.cs b/src/System.Private.CoreLib/shared/System/Text/EncoderBestFitFallback.cs index a8c288b63..7f3be2a7a 100644 --- a/src/System.Private.CoreLib/shared/System/Text/EncoderBestFitFallback.cs +++ b/src/System.Private.CoreLib/shared/System/Text/EncoderBestFitFallback.cs @@ -7,7 +7,6 @@ // using System.Diagnostics; -using System.Diagnostics.Contracts; using System.Globalization; using System.Threading; @@ -123,7 +122,6 @@ namespace System.Text throw new ArgumentOutOfRangeException(nameof(charUnknownLow), SR.Format(SR.ArgumentOutOfRange_Range, 0xDC00, 0xDFFF)); - Contract.EndContractBlock(); // If we had a buffer already we're being recursive, throw, it's probably at the suspect // character in our array. 0 is processing last character, < 0 is not falling back diff --git a/src/System.Private.CoreLib/shared/System/Text/EncoderExceptionFallback.cs b/src/System.Private.CoreLib/shared/System/Text/EncoderExceptionFallback.cs index 71426e5f3..4c7191690 100644 --- a/src/System.Private.CoreLib/shared/System/Text/EncoderExceptionFallback.cs +++ b/src/System.Private.CoreLib/shared/System/Text/EncoderExceptionFallback.cs @@ -4,7 +4,6 @@ using System; using System.Runtime.Serialization; -using System.Diagnostics.Contracts; namespace System.Text { @@ -68,7 +67,6 @@ namespace System.Text throw new ArgumentOutOfRangeException(nameof(charUnknownLow), SR.Format(SR.ArgumentOutOfRange_Range, 0xDC00, 0xDFFF)); } - Contract.EndContractBlock(); int iTemp = Char.ConvertToUtf32(charUnknownHigh, charUnknownLow); @@ -143,7 +141,6 @@ namespace System.Text throw new ArgumentOutOfRangeException(nameof(CharUnknownLow), SR.Format(SR.ArgumentOutOfRange_Range, 0xDC00, 0xDFFF)); } - Contract.EndContractBlock(); _charUnknownHigh = charUnknownHigh; _charUnknownLow = charUnknownLow; diff --git a/src/System.Private.CoreLib/shared/System/Text/EncoderNLS.cs b/src/System.Private.CoreLib/shared/System/Text/EncoderNLS.cs index 28a1b8b9b..f8ff86d98 100644 --- a/src/System.Private.CoreLib/shared/System/Text/EncoderNLS.cs +++ b/src/System.Private.CoreLib/shared/System/Text/EncoderNLS.cs @@ -4,7 +4,6 @@ using System.Text; using System; -using System.Diagnostics.Contracts; namespace System.Text { @@ -63,7 +62,6 @@ namespace System.Text if (chars.Length - index < count) throw new ArgumentOutOfRangeException(nameof(chars), SR.ArgumentOutOfRange_IndexCountBuffer); - Contract.EndContractBlock(); // Avoid empty input problem if (chars.Length == 0) @@ -88,7 +86,6 @@ namespace System.Text if (count < 0) throw new ArgumentOutOfRangeException(nameof(count), SR.ArgumentOutOfRange_NeedNonNegNum); - Contract.EndContractBlock(); _mustFlush = flush; _throwOnOverflow = true; @@ -114,7 +111,6 @@ namespace System.Text if (byteIndex < 0 || byteIndex > bytes.Length) throw new ArgumentOutOfRangeException(nameof(byteIndex), SR.ArgumentOutOfRange_Index); - Contract.EndContractBlock(); if (chars.Length == 0) chars = new char[1]; @@ -142,7 +138,6 @@ namespace System.Text if (byteCount < 0 || charCount < 0) throw new ArgumentOutOfRangeException((byteCount < 0 ? nameof(byteCount) : nameof(charCount)), SR.ArgumentOutOfRange_NeedNonNegNum); - Contract.EndContractBlock(); _mustFlush = flush; _throwOnOverflow = true; @@ -176,7 +171,6 @@ namespace System.Text throw new ArgumentOutOfRangeException(nameof(bytes), SR.ArgumentOutOfRange_IndexCountBuffer); - Contract.EndContractBlock(); // Avoid empty input problem if (chars.Length == 0) @@ -208,7 +202,6 @@ namespace System.Text if (charCount < 0 || byteCount < 0) throw new ArgumentOutOfRangeException((charCount < 0 ? nameof(charCount) : nameof(byteCount)), SR.ArgumentOutOfRange_NeedNonNegNum); - Contract.EndContractBlock(); // We don't want to throw _mustFlush = flush; diff --git a/src/System.Private.CoreLib/shared/System/Text/EncoderReplacementFallback.cs b/src/System.Private.CoreLib/shared/System/Text/EncoderReplacementFallback.cs index 22d094ce5..a1d0bbcd9 100644 --- a/src/System.Private.CoreLib/shared/System/Text/EncoderReplacementFallback.cs +++ b/src/System.Private.CoreLib/shared/System/Text/EncoderReplacementFallback.cs @@ -5,7 +5,6 @@ using System; using System.Runtime; using System.Diagnostics; -using System.Diagnostics.Contracts; namespace System.Text { @@ -24,7 +23,6 @@ namespace System.Text // Must not be null if (replacement == null) throw new ArgumentNullException(nameof(replacement)); - Contract.EndContractBlock(); // Make sure it doesn't have bad surrogate pairs bool bFoundHigh = false; @@ -153,7 +151,6 @@ namespace System.Text if (!Char.IsLowSurrogate(charUnknownLow)) throw new ArgumentOutOfRangeException(nameof(charUnknownLow), SR.Format(SR.ArgumentOutOfRange_Range, 0xDC00, 0xDFFF)); - Contract.EndContractBlock(); // If we had a buffer already we're being recursive, throw, it's probably at the suspect // character in our array. diff --git a/src/System.Private.CoreLib/shared/System/Text/Encoding.cs b/src/System.Private.CoreLib/shared/System/Text/Encoding.cs index bf8cb03db..8e4d29d24 100644 --- a/src/System.Private.CoreLib/shared/System/Text/Encoding.cs +++ b/src/System.Private.CoreLib/shared/System/Text/Encoding.cs @@ -4,7 +4,6 @@ using System.Diagnostics; using System.Globalization; -using System.Diagnostics.Contracts; using System.Threading; using System.Runtime.Serialization; using System.Diagnostics.CodeAnalysis; @@ -178,7 +177,6 @@ namespace System.Text { throw new ArgumentOutOfRangeException(nameof(codePage)); } - Contract.EndContractBlock(); // Remember code page _codePage = codePage; @@ -197,7 +195,6 @@ namespace System.Text { throw new ArgumentOutOfRangeException(nameof(codePage)); } - Contract.EndContractBlock(); // Remember code page _codePage = codePage; @@ -220,13 +217,11 @@ namespace System.Text // dstEncoding, and the returned value is a new byte array // containing the result of the conversion. // - [Pure] public static byte[] Convert(Encoding srcEncoding, Encoding dstEncoding, byte[] bytes) { if (bytes == null) throw new ArgumentNullException(nameof(bytes)); - Contract.Ensures(Contract.Result<byte[]>() != null); return Convert(srcEncoding, dstEncoding, bytes, 0, bytes.Length); } @@ -236,7 +231,6 @@ namespace System.Text // index index from srcEncoding to dstEncoding, and // returns a new byte array containing the result of the conversion. // - [Pure] public static byte[] Convert(Encoding srcEncoding, Encoding dstEncoding, byte[] bytes, int index, int count) { @@ -250,7 +244,6 @@ namespace System.Text throw new ArgumentNullException(nameof(bytes), SR.ArgumentNull_Array); } - Contract.Ensures(Contract.Result<byte[]>() != null); return dstEncoding.GetBytes(srcEncoding.GetChars(bytes, index, count)); } @@ -261,7 +254,6 @@ namespace System.Text EncodingProvider.AddProvider(provider); } - [Pure] public static Encoding GetEncoding(int codepage) { Encoding result = EncodingProvider.GetEncodingFromProvider(codepage); @@ -280,7 +272,6 @@ namespace System.Text nameof(codepage), SR.Format(SR.ArgumentOutOfRange_Range, 0, 65535)); } - Contract.EndContractBlock(); switch (codepage) { @@ -312,7 +303,6 @@ namespace System.Text return UTF8; } - [Pure] public static Encoding GetEncoding(int codepage, EncoderFallback encoderFallback, DecoderFallback decoderFallback) { @@ -334,7 +324,6 @@ namespace System.Text // Returns an Encoding object for a given name or a given code page value. // - [Pure] public static Encoding GetEncoding(String name) { Encoding baseEncoding = EncodingProvider.GetEncodingFromProvider(name); @@ -352,7 +341,6 @@ namespace System.Text // Returns an Encoding object for a given name or a given code page value. // - [Pure] public static Encoding GetEncoding(String name, EncoderFallback encoderFallback, DecoderFallback decoderFallback) { @@ -370,13 +358,11 @@ namespace System.Text } // Return a list of all EncodingInfo objects describing all of our encodings - [Pure] public static EncodingInfo[] GetEncodings() { return EncodingTable.GetEncodings(); } - [Pure] public virtual byte[] GetPreamble() { return Array.Empty<byte>(); @@ -590,7 +576,6 @@ namespace System.Text if (value == null) throw new ArgumentNullException(nameof(value)); - Contract.EndContractBlock(); encoderFallback = value; } @@ -611,7 +596,6 @@ namespace System.Text if (value == null) throw new ArgumentNullException(nameof(value)); - Contract.EndContractBlock(); decoderFallback = value; } @@ -650,7 +634,6 @@ namespace System.Text // Returns the number of bytes required to encode the given character // array. // - [Pure] public virtual int GetByteCount(char[] chars) { if (chars == null) @@ -658,17 +641,14 @@ namespace System.Text throw new ArgumentNullException(nameof(chars), SR.ArgumentNull_Array); } - Contract.EndContractBlock(); return GetByteCount(chars, 0, chars.Length); } - [Pure] public virtual int GetByteCount(String s) { if (s == null) throw new ArgumentNullException(nameof(s)); - Contract.EndContractBlock(); char[] chars = s.ToCharArray(); return GetByteCount(chars, 0, chars.Length); @@ -677,12 +657,10 @@ namespace System.Text // Returns the number of bytes required to encode a range of characters in // a character array. // - [Pure] public abstract int GetByteCount(char[] chars, int index, int count); // Returns the number of bytes required to encode a string range. // - [Pure] public int GetByteCount(string s, int index, int count) { if (s == null) @@ -697,7 +675,6 @@ namespace System.Text if (index > s.Length - count) throw new ArgumentOutOfRangeException(nameof(index), SR.ArgumentOutOfRange_IndexCount); - Contract.EndContractBlock(); unsafe { @@ -712,7 +689,6 @@ namespace System.Text // unfortunately for existing overrides, it has to call the [] version, // which is really slow, so this method should be avoided if you're calling // a 3rd party encoding. - [Pure] [CLSCompliant(false)] public virtual unsafe int GetByteCount(char* chars, int count) { @@ -724,7 +700,6 @@ namespace System.Text if (count < 0) throw new ArgumentOutOfRangeException(nameof(count), SR.ArgumentOutOfRange_NeedNonNegNum); - Contract.EndContractBlock(); char[] arrChar = new char[count]; int index; @@ -756,7 +731,6 @@ namespace System.Text // Returns a byte array containing the encoded representation of the given // character array. // - [Pure] public virtual byte[] GetBytes(char[] chars) { if (chars == null) @@ -764,14 +738,12 @@ namespace System.Text throw new ArgumentNullException(nameof(chars), SR.ArgumentNull_Array); } - Contract.EndContractBlock(); return GetBytes(chars, 0, chars.Length); } // Returns a byte array containing the encoded representation of a range // of characters in a character array. // - [Pure] public virtual byte[] GetBytes(char[] chars, int index, int count) { byte[] result = new byte[GetByteCount(chars, index, count)]; @@ -794,13 +766,11 @@ namespace System.Text // Returns a byte array containing the encoded representation of the given // string. // - [Pure] public virtual byte[] GetBytes(String s) { if (s == null) throw new ArgumentNullException(nameof(s), SR.ArgumentNull_String); - Contract.EndContractBlock(); int byteCount = GetByteCount(s); byte[] bytes = new byte[byteCount]; @@ -812,7 +782,6 @@ namespace System.Text // Returns a byte array containing the encoded representation of the given // string range. // - [Pure] public byte[] GetBytes(string s, int index, int count) { if (s == null) @@ -827,7 +796,6 @@ namespace System.Text if (index > s.Length - count) throw new ArgumentOutOfRangeException(nameof(index), SR.ArgumentOutOfRange_IndexCount); - Contract.EndContractBlock(); unsafe { @@ -853,7 +821,6 @@ namespace System.Text { if (s == null) throw new ArgumentNullException(nameof(s)); - Contract.EndContractBlock(); return GetBytes(s.ToCharArray(), charIndex, charCount, bytes, byteIndex); } @@ -894,7 +861,6 @@ namespace System.Text if (charCount < 0 || byteCount < 0) throw new ArgumentOutOfRangeException((charCount < 0 ? nameof(charCount) : nameof(byteCount)), SR.ArgumentOutOfRange_NeedNonNegNum); - Contract.EndContractBlock(); // Get the char array to convert char[] arrChar = new char[charCount]; @@ -938,7 +904,6 @@ namespace System.Text // Returns the number of characters produced by decoding the given byte // array. // - [Pure] public virtual int GetCharCount(byte[] bytes) { if (bytes == null) @@ -946,19 +911,16 @@ namespace System.Text throw new ArgumentNullException(nameof(bytes), SR.ArgumentNull_Array); } - Contract.EndContractBlock(); return GetCharCount(bytes, 0, bytes.Length); } // Returns the number of characters produced by decoding a range of bytes // in a byte array. // - [Pure] public abstract int GetCharCount(byte[] bytes, int index, int count); // We expect this to be the workhorse for NLS Encodings, but for existing // ones we need a working (if slow) default implementation) - [Pure] [CLSCompliant(false)] public virtual unsafe int GetCharCount(byte* bytes, int count) { @@ -970,7 +932,6 @@ namespace System.Text if (count < 0) throw new ArgumentOutOfRangeException(nameof(count), SR.ArgumentOutOfRange_NeedNonNegNum); - Contract.EndContractBlock(); byte[] arrbyte = new byte[count]; int index; @@ -999,7 +960,6 @@ namespace System.Text // Returns a character array containing the decoded representation of a // given byte array. // - [Pure] public virtual char[] GetChars(byte[] bytes) { if (bytes == null) @@ -1007,14 +967,12 @@ namespace System.Text throw new ArgumentNullException(nameof(bytes), SR.ArgumentNull_Array); } - Contract.EndContractBlock(); return GetChars(bytes, 0, bytes.Length); } // Returns a character array containing the decoded representation of a // range of bytes in a byte array. // - [Pure] public virtual char[] GetChars(byte[] bytes, int index, int count) { char[] result = new char[GetCharCount(bytes, index, count)]; @@ -1065,7 +1023,6 @@ namespace System.Text if (byteCount < 0 || charCount < 0) throw new ArgumentOutOfRangeException((byteCount < 0 ? nameof(byteCount) : nameof(charCount)), SR.ArgumentOutOfRange_NeedNonNegNum); - Contract.EndContractBlock(); // Get the byte array to convert byte[] arrByte = new byte[byteCount]; @@ -1123,7 +1080,6 @@ namespace System.Text if (byteCount < 0) throw new ArgumentOutOfRangeException(nameof(byteCount), SR.ArgumentOutOfRange_NeedNonNegNum); - Contract.EndContractBlock(); return String.CreateStringFromEncoding(bytes, byteCount, this); } @@ -1152,13 +1108,11 @@ namespace System.Text // IsAlwaysNormalized // Returns true if the encoding is always normalized for the specified encoding form - [Pure] public bool IsAlwaysNormalized() { return this.IsAlwaysNormalized(NormalizationForm.FormC); } - [Pure] public virtual bool IsAlwaysNormalized(NormalizationForm form) { // Assume false unless the encoding knows otherwise @@ -1214,7 +1168,6 @@ namespace System.Text // WARNING: If you're using something besides the default replacement encoder fallback, // then you could have more bytes than this returned from an actual call to GetBytes(). // - [Pure] public abstract int GetMaxByteCount(int charCount); // Returns the maximum number of characters produced by decoding a given @@ -1225,19 +1178,16 @@ namespace System.Text // exceptions will occur if buffers are sized according to the results of // this method. // - [Pure] public abstract int GetMaxCharCount(int byteCount); // Returns a string containing the decoded representation of a given byte // array. // - [Pure] public virtual String GetString(byte[] bytes) { if (bytes == null) throw new ArgumentNullException(nameof(bytes), SR.ArgumentNull_Array); - Contract.EndContractBlock(); return GetString(bytes, 0, bytes.Length); } @@ -1247,7 +1197,6 @@ namespace System.Text // // Internally we override this for performance // - [Pure] public virtual String GetString(byte[] bytes, int index, int count) { return new String(GetChars(bytes, index, count)); @@ -1393,7 +1342,6 @@ namespace System.Text return _encoding.GetByteCount(chars, index, count); } - [SuppressMessage("Microsoft.Contracts", "CC1055")] // Skip extra error checking to avoid *potential* AppCompat problems. public unsafe override int GetByteCount(char* chars, int count, bool flush) { return _encoding.GetByteCount(chars, count); @@ -1425,7 +1373,6 @@ namespace System.Text return _encoding.GetBytes(chars, charIndex, charCount, bytes, byteIndex); } - [SuppressMessage("Microsoft.Contracts", "CC1055")] // Skip extra error checking to avoid *potential* AppCompat problems. public unsafe override int GetBytes(char* chars, int charCount, byte* bytes, int byteCount, bool flush) { @@ -1464,7 +1411,6 @@ namespace System.Text return _encoding.GetCharCount(bytes, index, count); } - [SuppressMessage("Microsoft.Contracts", "CC1055")] // Skip extra error checking to avoid *potential* AppCompat problems. public unsafe override int GetCharCount(byte* bytes, int count, bool flush) { // By default just call the encoding version, no flush by default @@ -1500,7 +1446,6 @@ namespace System.Text return _encoding.GetChars(bytes, byteIndex, byteCount, chars, charIndex); } - [SuppressMessage("Microsoft.Contracts", "CC1055")] // Skip extra error checking to avoid *potential* AppCompat problems. public unsafe override int GetChars(byte* bytes, int byteCount, char* chars, int charCount, bool flush) { diff --git a/src/System.Private.CoreLib/shared/System/Text/EncodingNLS.cs b/src/System.Private.CoreLib/shared/System/Text/EncodingNLS.cs index 835bf8fb3..5059407ab 100644 --- a/src/System.Private.CoreLib/shared/System/Text/EncodingNLS.cs +++ b/src/System.Private.CoreLib/shared/System/Text/EncodingNLS.cs @@ -3,7 +3,6 @@ // See the LICENSE file in the project root for more information. using System; -using System.Diagnostics.Contracts; using System.Collections; using System.Globalization; using System.Threading; @@ -47,7 +46,6 @@ namespace System.Text if (chars.Length - index < count) throw new ArgumentOutOfRangeException("chars", SR.ArgumentOutOfRange_IndexCountBuffer); - Contract.EndContractBlock(); // If no input, return 0, avoid fixed empty array problem if (count == 0) @@ -67,7 +65,6 @@ namespace System.Text // Validate input if (s==null) throw new ArgumentNullException("s"); - Contract.EndContractBlock(); fixed (char* pChars = s) return GetByteCount(pChars, s.Length, null); @@ -84,7 +81,6 @@ namespace System.Text if (count < 0) throw new ArgumentOutOfRangeException("count", SR.ArgumentOutOfRange_NeedNonNegNum); - Contract.EndContractBlock(); // Call it with empty encoder return GetByteCount(chars, count, null); @@ -108,7 +104,6 @@ namespace System.Text if (byteIndex < 0 || byteIndex > bytes.Length) throw new ArgumentOutOfRangeException("byteIndex", SR.ArgumentOutOfRange_Index); - Contract.EndContractBlock(); int byteCount = bytes.Length - byteIndex; @@ -148,7 +143,6 @@ namespace System.Text if (byteIndex < 0 || byteIndex > bytes.Length) throw new ArgumentOutOfRangeException("byteIndex", SR.ArgumentOutOfRange_Index); - Contract.EndContractBlock(); // If nothing to encode return 0, avoid fixed problem if (charCount == 0) @@ -177,7 +171,6 @@ namespace System.Text if (charCount < 0 || byteCount < 0) throw new ArgumentOutOfRangeException((charCount < 0 ? "charCount" : "byteCount"), SR.ArgumentOutOfRange_NeedNonNegNum); - Contract.EndContractBlock(); return GetBytes(chars, charCount, bytes, byteCount, null); } @@ -200,7 +193,6 @@ namespace System.Text if (bytes.Length - index < count) throw new ArgumentOutOfRangeException("bytes", SR.ArgumentOutOfRange_IndexCountBuffer); - Contract.EndContractBlock(); // If no input just return 0, fixed doesn't like 0 length arrays if (count == 0) @@ -222,7 +214,6 @@ namespace System.Text if (count < 0) throw new ArgumentOutOfRangeException("count", SR.ArgumentOutOfRange_NeedNonNegNum); - Contract.EndContractBlock(); return GetCharCount(bytes, count, null); } @@ -246,7 +237,6 @@ namespace System.Text if (charIndex < 0 || charIndex > chars.Length) throw new ArgumentOutOfRangeException("charIndex", SR.ArgumentOutOfRange_Index); - Contract.EndContractBlock(); // If no input, return 0 & avoid fixed problem if (byteCount == 0) @@ -275,7 +265,6 @@ namespace System.Text if (charCount < 0 || byteCount < 0) throw new ArgumentOutOfRangeException((charCount < 0 ? "charCount" : "byteCount"), SR.ArgumentOutOfRange_NeedNonNegNum); - Contract.EndContractBlock(); return GetChars(bytes, byteCount, chars, charCount, null); } @@ -298,7 +287,6 @@ namespace System.Text if (bytes.Length - index < count) throw new ArgumentOutOfRangeException("bytes", SR.ArgumentOutOfRange_IndexCountBuffer); - Contract.EndContractBlock(); // Avoid problems with empty input buffer if (count == 0) return String.Empty; diff --git a/src/System.Private.CoreLib/shared/System/Text/Latin1Encoding.cs b/src/System.Private.CoreLib/shared/System/Text/Latin1Encoding.cs index 679698d92..335eb76e3 100644 --- a/src/System.Private.CoreLib/shared/System/Text/Latin1Encoding.cs +++ b/src/System.Private.CoreLib/shared/System/Text/Latin1Encoding.cs @@ -4,7 +4,6 @@ using System; using System.Diagnostics; -using System.Diagnostics.Contracts; namespace System.Text { @@ -420,7 +419,6 @@ namespace System.Text if (charCount < 0) throw new ArgumentOutOfRangeException(nameof(charCount), SR.ArgumentOutOfRange_NeedNonNegNum); - Contract.EndContractBlock(); // Characters would be # of characters + 1 in case high surrogate is ? * max fallback long byteCount = (long)charCount + 1; @@ -440,7 +438,6 @@ namespace System.Text if (byteCount < 0) throw new ArgumentOutOfRangeException(nameof(byteCount), SR.ArgumentOutOfRange_NeedNonNegNum); - Contract.EndContractBlock(); // Just return length, SBCS stay the same length because they don't map to surrogate long charCount = (long)byteCount; diff --git a/src/System.Private.CoreLib/shared/System/Text/StringBuilder.cs b/src/System.Private.CoreLib/shared/System/Text/StringBuilder.cs index a73e6757d..f5003d812 100644 --- a/src/System.Private.CoreLib/shared/System/Text/StringBuilder.cs +++ b/src/System.Private.CoreLib/shared/System/Text/StringBuilder.cs @@ -12,7 +12,6 @@ using System.Security; using System.Threading; using System.Globalization; using System.Diagnostics; -using System.Diagnostics.Contracts; using System.Collections.Generic; namespace System.Text @@ -134,7 +133,6 @@ namespace System.Text { throw new ArgumentOutOfRangeException(nameof(startIndex), SR.ArgumentOutOfRange_StartIndex); } - Contract.EndContractBlock(); if (value == null) { @@ -183,7 +181,6 @@ namespace System.Text { throw new ArgumentOutOfRangeException(nameof(capacity), SR.Format(SR.ArgumentOutOfRange_MustBePositive, nameof(capacity))); } - Contract.EndContractBlock(); if (capacity == 0) { @@ -200,7 +197,6 @@ namespace System.Text { throw new ArgumentNullException(nameof(info)); } - Contract.EndContractBlock(); int persistedCapacity = 0; string persistedString = null; @@ -265,7 +261,6 @@ namespace System.Text { throw new ArgumentNullException(nameof(info)); } - Contract.EndContractBlock(); AssertInvariants(); info.AddValue(MaxCapacityField, m_MaxCapacity); @@ -321,7 +316,6 @@ namespace System.Text { throw new ArgumentOutOfRangeException(nameof(value), SR.ArgumentOutOfRange_SmallCapacity); } - Contract.EndContractBlock(); if (Capacity != value) { @@ -352,7 +346,6 @@ namespace System.Text { throw new ArgumentOutOfRangeException(nameof(capacity), SR.ArgumentOutOfRange_NegativeCapacity); } - Contract.EndContractBlock(); if (Capacity < capacity) Capacity = capacity; @@ -410,8 +403,6 @@ namespace System.Text /// <param name="length">The number of characters to read in this builder.</param> public string ToString(int startIndex, int length) { - Contract.Ensures(Contract.Result<String>() != null); - int currentLength = this.Length; if (startIndex < 0) { @@ -496,7 +487,6 @@ namespace System.Text { get { - Contract.Ensures(Contract.Result<int>() >= 0); return m_ChunkOffset + m_ChunkLength; } set @@ -511,7 +501,6 @@ namespace System.Text { throw new ArgumentOutOfRangeException(nameof(value), SR.ArgumentOutOfRange_SmallCapacity); } - Contract.EndContractBlock(); int originalCapacity = Capacity; @@ -612,8 +601,6 @@ namespace System.Text { throw new ArgumentOutOfRangeException(nameof(repeatCount), SR.ArgumentOutOfRange_NegativeCount); } - Contract.Ensures(Contract.Result<StringBuilder>() != null); - Contract.EndContractBlock(); if (repeatCount == 0) { @@ -666,8 +653,6 @@ namespace System.Text { throw new ArgumentOutOfRangeException(nameof(charCount), SR.ArgumentOutOfRange_GenericPositive); } - Contract.Ensures(Contract.Result<StringBuilder>() != null); - Contract.EndContractBlock(); if (value == null) { @@ -705,8 +690,6 @@ namespace System.Text /// <param name="value">The string to append.</param> public StringBuilder Append(String value) { - Contract.Ensures(Contract.Result<StringBuilder>() != null); - if (value != null) { // We could have just called AppendHelper here; this is a hand-specialization of that code. @@ -776,7 +759,6 @@ namespace System.Text { throw new ArgumentOutOfRangeException(nameof(count), SR.ArgumentOutOfRange_GenericPositive); } - Contract.Ensures(Contract.Result<StringBuilder>() != null); if (value == null) { @@ -831,7 +813,6 @@ namespace System.Text { throw new ArgumentException(SR.ArgumentOutOfRange_OffsetOut); } - Contract.EndContractBlock(); CopyTo(sourceIndex, new Span<char>(destination).Slice(destinationIndex), count); } @@ -852,7 +833,6 @@ namespace System.Text { throw new ArgumentException(SR.Arg_LongerThanSrcString); } - Contract.EndContractBlock(); AssertInvariants(); @@ -896,8 +876,6 @@ namespace System.Text { throw new ArgumentOutOfRangeException(nameof(count), SR.ArgumentOutOfRange_NeedNonNegNum); } - Contract.Ensures(Contract.Result<StringBuilder>() != null); - Contract.EndContractBlock(); int currentLength = Length; if ((uint)index > (uint)currentLength) @@ -959,8 +937,6 @@ namespace System.Text { throw new ArgumentOutOfRangeException(nameof(length), SR.ArgumentOutOfRange_Index); } - Contract.Ensures(Contract.Result<StringBuilder>() != null); - Contract.EndContractBlock(); if (Length == length && startIndex == 0) { @@ -987,8 +963,6 @@ namespace System.Text public StringBuilder Append(char value) { - Contract.Ensures(Contract.Result<StringBuilder>() != null); - if (m_ChunkLength < m_ChunkChars.Length) { m_ChunkChars[m_ChunkLength++] = value; @@ -1170,8 +1144,6 @@ namespace System.Text { throw new ArgumentOutOfRangeException(nameof(index), SR.ArgumentOutOfRange_Index); } - Contract.Ensures(Contract.Result<StringBuilder>() != null); - Contract.EndContractBlock(); if (value != null) { @@ -1195,8 +1167,6 @@ namespace System.Text public StringBuilder Insert(int index, char value) { - Contract.Ensures(Contract.Result<StringBuilder>() != null); - unsafe { Insert(index, &value, 1); @@ -1210,8 +1180,6 @@ namespace System.Text { throw new ArgumentOutOfRangeException(nameof(index), SR.ArgumentOutOfRange_Index); } - Contract.Ensures(Contract.Result<StringBuilder>() != null); - Contract.EndContractBlock(); if (value != null) Insert(index, value, 0, value.Length); @@ -1220,8 +1188,6 @@ namespace System.Text public StringBuilder Insert(int index, char[] value, int startIndex, int charCount) { - Contract.Ensures(Contract.Result<StringBuilder>() != null); - int currentLength = Length; if ((uint)index > (uint)currentLength) { @@ -1286,9 +1252,6 @@ namespace System.Text public StringBuilder Insert(int index, ReadOnlySpan<char> value) { - Contract.Ensures(Contract.Result<StringBuilder>() != null); - Contract.EndContractBlock(); - if ((uint)index > (uint)Length) { throw new ArgumentOutOfRangeException(nameof(index), SR.ArgumentOutOfRange_Index); @@ -1320,8 +1283,6 @@ namespace System.Text string paramName = (format == null) ? nameof(format) : nameof(args); throw new ArgumentNullException(paramName); } - Contract.Ensures(Contract.Result<String>() != null); - Contract.EndContractBlock(); return AppendFormatHelper(null, format, new ParamsArray(args)); } @@ -1341,8 +1302,6 @@ namespace System.Text string paramName = (format == null) ? nameof(format) : nameof(args); throw new ArgumentNullException(paramName); } - Contract.Ensures(Contract.Result<String>() != null); - Contract.EndContractBlock(); return AppendFormatHelper(provider, format, new ParamsArray(args)); } @@ -1362,8 +1321,6 @@ namespace System.Text { throw new ArgumentNullException(nameof(format)); } - Contract.Ensures(Contract.Result<StringBuilder>() != null); - Contract.EndContractBlock(); int pos = 0; int len = format.Length; @@ -1665,8 +1622,6 @@ namespace System.Text /// </remarks> public StringBuilder Replace(String oldValue, String newValue, int startIndex, int count) { - Contract.Ensures(Contract.Result<StringBuilder>() != null); - int currentLength = Length; if ((uint)startIndex > (uint)currentLength) { @@ -1762,8 +1717,6 @@ namespace System.Text /// <param name="count">The number of characters to read in this builder.</param> public StringBuilder Replace(char oldChar, char newChar, int startIndex, int count) { - Contract.Ensures(Contract.Result<StringBuilder>() != null); - int currentLength = Length; if ((uint)startIndex > (uint)currentLength) { @@ -2125,8 +2078,8 @@ namespace System.Text /// </remarks> private void ExpandByABlock(int minBlockCharCount) { - Contract.Requires(Capacity == Length, $"{nameof(ExpandByABlock)} should only be called when there is no space left."); - Contract.Requires(minBlockCharCount > 0); + Debug.Assert(Capacity == Length, nameof(ExpandByABlock) + " should only be called when there is no space left."); + Debug.Assert(minBlockCharCount > 0); AssertInvariants(); diff --git a/src/System.Private.CoreLib/shared/System/Text/UTF32Encoding.cs b/src/System.Private.CoreLib/shared/System/Text/UTF32Encoding.cs index 260518e21..a666c2562 100644 --- a/src/System.Private.CoreLib/shared/System/Text/UTF32Encoding.cs +++ b/src/System.Private.CoreLib/shared/System/Text/UTF32Encoding.cs @@ -8,7 +8,6 @@ using System; using System.Diagnostics; -using System.Diagnostics.Contracts; using System.Globalization; namespace System.Text @@ -110,7 +109,6 @@ namespace System.Text if (chars.Length - index < count) throw new ArgumentOutOfRangeException("chars", SR.ArgumentOutOfRange_IndexCountBuffer); - Contract.EndContractBlock(); // If no input, return 0, avoid fixed empty array problem if (count == 0) @@ -131,7 +129,6 @@ namespace System.Text // Validate input if (s==null) throw new ArgumentNullException("s"); - Contract.EndContractBlock(); fixed (char* pChars = s) return GetByteCount(pChars, s.Length, null); @@ -150,7 +147,6 @@ namespace System.Text if (count < 0) throw new ArgumentOutOfRangeException("count", SR.ArgumentOutOfRange_NeedNonNegNum); - Contract.EndContractBlock(); // Call it with empty encoder return GetByteCount(chars, count, null); @@ -175,7 +171,6 @@ namespace System.Text if (byteIndex < 0 || byteIndex > bytes.Length) throw new ArgumentOutOfRangeException("byteIndex", SR.ArgumentOutOfRange_Index); - Contract.EndContractBlock(); int byteCount = bytes.Length - byteIndex; @@ -216,7 +211,6 @@ namespace System.Text if (byteIndex < 0 || byteIndex > bytes.Length) throw new ArgumentOutOfRangeException("byteIndex", SR.ArgumentOutOfRange_Index); - Contract.EndContractBlock(); // If nothing to encode return 0, avoid fixed problem if (charCount == 0) @@ -247,7 +241,6 @@ namespace System.Text if (charCount < 0 || byteCount < 0) throw new ArgumentOutOfRangeException((charCount < 0 ? "charCount" : "byteCount"), SR.ArgumentOutOfRange_NeedNonNegNum); - Contract.EndContractBlock(); return GetBytes(chars, charCount, bytes, byteCount, null); } @@ -271,7 +264,6 @@ namespace System.Text if (bytes.Length - index < count) throw new ArgumentOutOfRangeException("bytes", SR.ArgumentOutOfRange_IndexCountBuffer); - Contract.EndContractBlock(); // If no input just return 0, fixed doesn't like 0 length arrays. if (count == 0) @@ -295,7 +287,6 @@ namespace System.Text if (count < 0) throw new ArgumentOutOfRangeException("count", SR.ArgumentOutOfRange_NeedNonNegNum); - Contract.EndContractBlock(); return GetCharCount(bytes, count, null); } @@ -320,7 +311,6 @@ namespace System.Text if (charIndex < 0 || charIndex > chars.Length) throw new ArgumentOutOfRangeException("charIndex", SR.ArgumentOutOfRange_Index); - Contract.EndContractBlock(); // If no input, return 0 & avoid fixed problem if (byteCount == 0) @@ -351,7 +341,6 @@ namespace System.Text if (charCount < 0 || byteCount < 0) throw new ArgumentOutOfRangeException((charCount < 0 ? "charCount" : "byteCount"), SR.ArgumentOutOfRange_NeedNonNegNum); - Contract.EndContractBlock(); return GetChars(bytes, byteCount, chars, charCount, null); } @@ -375,7 +364,6 @@ namespace System.Text if (bytes.Length - index < count) throw new ArgumentOutOfRangeException("bytes", SR.ArgumentOutOfRange_IndexCountBuffer); - Contract.EndContractBlock(); // Avoid problems with empty input buffer if (count == 0) return String.Empty; @@ -960,7 +948,6 @@ namespace System.Text if (!fallbackResult) { - // Couldn't fallback, throw or wait til next time // We either read enough bytes for bytes-=4 to work, or we're // going to throw in ThrowCharsOverflow because chars == charStart @@ -1114,7 +1101,6 @@ namespace System.Text if (charCount < 0) throw new ArgumentOutOfRangeException(nameof(charCount), SR.ArgumentOutOfRange_NeedNonNegNum); - Contract.EndContractBlock(); // Characters would be # of characters + 1 in case left over high surrogate is ? * max fallback long byteCount = (long)charCount + 1; @@ -1137,7 +1123,6 @@ namespace System.Text if (byteCount < 0) throw new ArgumentOutOfRangeException(nameof(byteCount), SR.ArgumentOutOfRange_NeedNonNegNum); - Contract.EndContractBlock(); // A supplementary character becomes 2 surrogate characters, so 4 input bytes becomes 2 chars, // plus we may have 1 surrogate char left over if the decoder has 3 bytes in it already for a non-bmp char. diff --git a/src/System.Private.CoreLib/shared/System/Text/UTF7Encoding.cs b/src/System.Private.CoreLib/shared/System/Text/UTF7Encoding.cs index b9065477e..78813649b 100644 --- a/src/System.Private.CoreLib/shared/System/Text/UTF7Encoding.cs +++ b/src/System.Private.CoreLib/shared/System/Text/UTF7Encoding.cs @@ -8,7 +8,6 @@ using System; using System.Diagnostics; -using System.Diagnostics.Contracts; namespace System.Text { @@ -140,7 +139,6 @@ namespace System.Text if (chars.Length - index < count) throw new ArgumentOutOfRangeException("chars", SR.ArgumentOutOfRange_IndexCountBuffer); - Contract.EndContractBlock(); // If no input, return 0, avoid fixed empty array problem if (count == 0) @@ -161,7 +159,6 @@ namespace System.Text // Validate input if (s==null) throw new ArgumentNullException("s"); - Contract.EndContractBlock(); fixed (char* pChars = s) return GetByteCount(pChars, s.Length, null); @@ -180,7 +177,6 @@ namespace System.Text if (count < 0) throw new ArgumentOutOfRangeException("count", SR.ArgumentOutOfRange_NeedNonNegNum); - Contract.EndContractBlock(); // Call it with empty encoder return GetByteCount(chars, count, null); @@ -205,7 +201,6 @@ namespace System.Text if (byteIndex < 0 || byteIndex > bytes.Length) throw new ArgumentOutOfRangeException("byteIndex", SR.ArgumentOutOfRange_Index); - Contract.EndContractBlock(); int byteCount = bytes.Length - byteIndex; @@ -246,7 +241,6 @@ namespace System.Text if (byteIndex < 0 || byteIndex > bytes.Length) throw new ArgumentOutOfRangeException("byteIndex", SR.ArgumentOutOfRange_Index); - Contract.EndContractBlock(); // If nothing to encode return 0, avoid fixed problem if (charCount == 0) @@ -277,7 +271,6 @@ namespace System.Text if (charCount < 0 || byteCount < 0) throw new ArgumentOutOfRangeException((charCount < 0 ? "charCount" : "byteCount"), SR.ArgumentOutOfRange_NeedNonNegNum); - Contract.EndContractBlock(); return GetBytes(chars, charCount, bytes, byteCount, null); } @@ -301,7 +294,6 @@ namespace System.Text if (bytes.Length - index < count) throw new ArgumentOutOfRangeException("bytes", SR.ArgumentOutOfRange_IndexCountBuffer); - Contract.EndContractBlock(); // If no input just return 0, fixed doesn't like 0 length arrays. if (count == 0) @@ -325,7 +317,6 @@ namespace System.Text if (count < 0) throw new ArgumentOutOfRangeException("count", SR.ArgumentOutOfRange_NeedNonNegNum); - Contract.EndContractBlock(); return GetCharCount(bytes, count, null); } @@ -350,7 +341,6 @@ namespace System.Text if (charIndex < 0 || charIndex > chars.Length) throw new ArgumentOutOfRangeException("charIndex", SR.ArgumentOutOfRange_Index); - Contract.EndContractBlock(); // If no input, return 0 & avoid fixed problem if (byteCount == 0) @@ -381,7 +371,6 @@ namespace System.Text if (charCount < 0 || byteCount < 0) throw new ArgumentOutOfRangeException((charCount < 0 ? "charCount" : "byteCount"), SR.ArgumentOutOfRange_NeedNonNegNum); - Contract.EndContractBlock(); return GetChars(bytes, byteCount, chars, charCount, null); } @@ -405,7 +394,6 @@ namespace System.Text if (bytes.Length - index < count) throw new ArgumentOutOfRangeException("bytes", SR.ArgumentOutOfRange_IndexCountBuffer); - Contract.EndContractBlock(); // Avoid problems with empty input buffer if (count == 0) return String.Empty; @@ -762,7 +750,6 @@ namespace System.Text if (charCount < 0) throw new ArgumentOutOfRangeException(nameof(charCount), SR.ArgumentOutOfRange_NeedNonNegNum); - Contract.EndContractBlock(); // Suppose that every char can not be direct-encoded, we know that // a byte can encode 6 bits of the Unicode character. And we will @@ -795,7 +782,6 @@ namespace System.Text if (byteCount < 0) throw new ArgumentOutOfRangeException(nameof(byteCount), SR.ArgumentOutOfRange_NeedNonNegNum); - Contract.EndContractBlock(); // Worst case is 1 char per byte. Minimum 1 for left over bits in case decoder is being flushed // Also note that we ignore extra bits (per spec), so UTF7 doesn't have unknown in this direction. diff --git a/src/System.Private.CoreLib/shared/System/Text/UTF8Encoding.cs b/src/System.Private.CoreLib/shared/System/Text/UTF8Encoding.cs index 974bf7565..e5544c519 100644 --- a/src/System.Private.CoreLib/shared/System/Text/UTF8Encoding.cs +++ b/src/System.Private.CoreLib/shared/System/Text/UTF8Encoding.cs @@ -16,7 +16,6 @@ using System; using System.Diagnostics; -using System.Diagnostics.Contracts; using System.Globalization; namespace System.Text @@ -137,7 +136,6 @@ namespace System.Text if (chars.Length - index < count) throw new ArgumentOutOfRangeException("chars", SR.ArgumentOutOfRange_IndexCountBuffer); - Contract.EndContractBlock(); // If no input, return 0, avoid fixed empty array problem if (count == 0) @@ -158,7 +156,6 @@ namespace System.Text // Validate input if (chars==null) throw new ArgumentNullException("s"); - Contract.EndContractBlock(); fixed (char* pChars = chars) return GetByteCount(pChars, chars.Length, null); @@ -177,7 +174,6 @@ namespace System.Text if (count < 0) throw new ArgumentOutOfRangeException("count", SR.ArgumentOutOfRange_NeedNonNegNum); - Contract.EndContractBlock(); // Call it with empty encoder return GetByteCount(chars, count, null); @@ -202,7 +198,6 @@ namespace System.Text if (byteIndex < 0 || byteIndex > bytes.Length) throw new ArgumentOutOfRangeException("byteIndex", SR.ArgumentOutOfRange_Index); - Contract.EndContractBlock(); int byteCount = bytes.Length - byteIndex; @@ -243,7 +238,6 @@ namespace System.Text if (byteIndex < 0 || byteIndex > bytes.Length) throw new ArgumentOutOfRangeException("byteIndex", SR.ArgumentOutOfRange_Index); - Contract.EndContractBlock(); // If nothing to encode return 0, avoid fixed problem if (charCount == 0) @@ -274,7 +268,6 @@ namespace System.Text if (charCount < 0 || byteCount < 0) throw new ArgumentOutOfRangeException((charCount < 0 ? "charCount" : "byteCount"), SR.ArgumentOutOfRange_NeedNonNegNum); - Contract.EndContractBlock(); return GetBytes(chars, charCount, bytes, byteCount, null); } @@ -298,7 +291,6 @@ namespace System.Text if (bytes.Length - index < count) throw new ArgumentOutOfRangeException("bytes", SR.ArgumentOutOfRange_IndexCountBuffer); - Contract.EndContractBlock(); // If no input just return 0, fixed doesn't like 0 length arrays. if (count == 0) @@ -322,7 +314,6 @@ namespace System.Text if (count < 0) throw new ArgumentOutOfRangeException("count", SR.ArgumentOutOfRange_NeedNonNegNum); - Contract.EndContractBlock(); return GetCharCount(bytes, count, null); } @@ -347,7 +338,6 @@ namespace System.Text if (charIndex < 0 || charIndex > chars.Length) throw new ArgumentOutOfRangeException("charIndex", SR.ArgumentOutOfRange_Index); - Contract.EndContractBlock(); // If no input, return 0 & avoid fixed problem if (byteCount == 0) @@ -378,7 +368,6 @@ namespace System.Text if (charCount < 0 || byteCount < 0) throw new ArgumentOutOfRangeException((charCount < 0 ? "charCount" : "byteCount"), SR.ArgumentOutOfRange_NeedNonNegNum); - Contract.EndContractBlock(); return GetChars(bytes, byteCount, chars, charCount, null); } @@ -402,7 +391,6 @@ namespace System.Text if (bytes.Length - index < count) throw new ArgumentOutOfRangeException("bytes", SR.ArgumentOutOfRange_IndexCountBuffer); - Contract.EndContractBlock(); // Avoid problems with empty input buffer if (count == 0) return String.Empty; @@ -2448,7 +2436,6 @@ namespace System.Text if (charCount < 0) throw new ArgumentOutOfRangeException(nameof(charCount), SR.ArgumentOutOfRange_NeedNonNegNum); - Contract.EndContractBlock(); // Characters would be # of characters + 1 in case left over high surrogate is ? * max fallback long byteCount = (long)charCount + 1; @@ -2471,7 +2458,6 @@ namespace System.Text if (byteCount < 0) throw new ArgumentOutOfRangeException(nameof(byteCount), SR.ArgumentOutOfRange_NeedNonNegNum); - Contract.EndContractBlock(); // Figure out our length, 1 char per input byte + 1 char if 1st byte is last byte of 4 byte surrogate pair long charCount = ((long)byteCount + 1); diff --git a/src/System.Private.CoreLib/shared/System/Text/UnicodeEncoding.cs b/src/System.Private.CoreLib/shared/System/Text/UnicodeEncoding.cs index 78355299c..a5b89a666 100644 --- a/src/System.Private.CoreLib/shared/System/Text/UnicodeEncoding.cs +++ b/src/System.Private.CoreLib/shared/System/Text/UnicodeEncoding.cs @@ -9,7 +9,6 @@ using System; using System.Globalization; using System.Diagnostics; -using System.Diagnostics.Contracts; namespace System.Text { @@ -96,7 +95,6 @@ namespace System.Text if (chars.Length - index < count) throw new ArgumentOutOfRangeException("chars", SR.ArgumentOutOfRange_IndexCountBuffer); - Contract.EndContractBlock(); // If no input, return 0, avoid fixed empty array problem if (count == 0) @@ -117,7 +115,6 @@ namespace System.Text // Validate input if (s==null) throw new ArgumentNullException("s"); - Contract.EndContractBlock(); fixed (char* pChars = s) return GetByteCount(pChars, s.Length, null); @@ -136,7 +133,6 @@ namespace System.Text if (count < 0) throw new ArgumentOutOfRangeException("count", SR.ArgumentOutOfRange_NeedNonNegNum); - Contract.EndContractBlock(); // Call it with empty encoder return GetByteCount(chars, count, null); @@ -161,7 +157,6 @@ namespace System.Text if (byteIndex < 0 || byteIndex > bytes.Length) throw new ArgumentOutOfRangeException("byteIndex", SR.ArgumentOutOfRange_Index); - Contract.EndContractBlock(); int byteCount = bytes.Length - byteIndex; @@ -202,7 +197,6 @@ namespace System.Text if (byteIndex < 0 || byteIndex > bytes.Length) throw new ArgumentOutOfRangeException("byteIndex", SR.ArgumentOutOfRange_Index); - Contract.EndContractBlock(); // If nothing to encode return 0, avoid fixed problem if (charCount == 0) @@ -233,7 +227,6 @@ namespace System.Text if (charCount < 0 || byteCount < 0) throw new ArgumentOutOfRangeException((charCount < 0 ? "charCount" : "byteCount"), SR.ArgumentOutOfRange_NeedNonNegNum); - Contract.EndContractBlock(); return GetBytes(chars, charCount, bytes, byteCount, null); } @@ -257,7 +250,6 @@ namespace System.Text if (bytes.Length - index < count) throw new ArgumentOutOfRangeException("bytes", SR.ArgumentOutOfRange_IndexCountBuffer); - Contract.EndContractBlock(); // If no input just return 0, fixed doesn't like 0 length arrays if (count == 0) @@ -281,7 +273,6 @@ namespace System.Text if (count < 0) throw new ArgumentOutOfRangeException("count", SR.ArgumentOutOfRange_NeedNonNegNum); - Contract.EndContractBlock(); return GetCharCount(bytes, count, null); } @@ -306,7 +297,6 @@ namespace System.Text if (charIndex < 0 || charIndex > chars.Length) throw new ArgumentOutOfRangeException("charIndex", SR.ArgumentOutOfRange_Index); - Contract.EndContractBlock(); // If no input, return 0 & avoid fixed problem if (byteCount == 0) @@ -337,7 +327,6 @@ namespace System.Text if (charCount < 0 || byteCount < 0) throw new ArgumentOutOfRangeException((charCount < 0 ? "charCount" : "byteCount"), SR.ArgumentOutOfRange_NeedNonNegNum); - Contract.EndContractBlock(); return GetChars(bytes, byteCount, chars, charCount, null); } @@ -361,7 +350,6 @@ namespace System.Text if (bytes.Length - index < count) throw new ArgumentOutOfRangeException("bytes", SR.ArgumentOutOfRange_IndexCountBuffer); - Contract.EndContractBlock(); // Avoid problems with empty input buffer if (count == 0) return String.Empty; @@ -1911,7 +1899,6 @@ namespace System.Text if (charCount < 0) throw new ArgumentOutOfRangeException(nameof(charCount), SR.ArgumentOutOfRange_NeedNonNegNum); - Contract.EndContractBlock(); // Characters would be # of characters + 1 in case left over high surrogate is ? * max fallback long byteCount = (long)charCount + 1; @@ -1934,7 +1921,6 @@ namespace System.Text if (byteCount < 0) throw new ArgumentOutOfRangeException(nameof(byteCount), SR.ArgumentOutOfRange_NeedNonNegNum); - Contract.EndContractBlock(); // long because byteCount could be biggest int. // 1 char per 2 bytes. Round up in case 1 left over in decoder. diff --git a/src/System.Private.CoreLib/shared/System/Threading/ExecutionContext.cs b/src/System.Private.CoreLib/shared/System/Threading/ExecutionContext.cs index a573af338..2d5f5be19 100644 --- a/src/System.Private.CoreLib/shared/System/Threading/ExecutionContext.cs +++ b/src/System.Private.CoreLib/shared/System/Threading/ExecutionContext.cs @@ -12,7 +12,6 @@ ===========================================================*/ using System.Diagnostics; -using System.Diagnostics.Contracts; using System.Runtime.ExceptionServices; using System.Runtime.Serialization; @@ -103,7 +102,6 @@ namespace System.Threading { throw new InvalidOperationException(SR.InvalidOperation_CannotSupressFlowMultipleTimes); } - Contract.EndContractBlock(); executionContext = executionContext.ShallowClone(isFlowSuppressed: true); var asyncFlowControl = new AsyncFlowControl(); @@ -120,7 +118,6 @@ namespace System.Threading { throw new InvalidOperationException(SR.InvalidOperation_CannotRestoreUnsupressedFlow); } - Contract.EndContractBlock(); currentThread.ExecutionContext = executionContext.ShallowClone(isFlowSuppressed: false); } @@ -322,7 +319,6 @@ namespace System.Threading { throw new InvalidOperationException(SR.InvalidOperation_AsyncFlowCtrlCtxMismatch); } - Contract.EndContractBlock(); _thread = null; ExecutionContext.RestoreFlow(); diff --git a/src/System.Private.CoreLib/shared/System/TimeSpan.cs b/src/System.Private.CoreLib/shared/System/TimeSpan.cs index 263a0a582..639d24b24 100644 --- a/src/System.Private.CoreLib/shared/System/TimeSpan.cs +++ b/src/System.Private.CoreLib/shared/System/TimeSpan.cs @@ -6,7 +6,6 @@ using System.Text; using System; using System.Runtime; using System.Runtime.CompilerServices; -using System.Diagnostics.Contracts; using System.Globalization; namespace System @@ -207,7 +206,6 @@ namespace System { if (Ticks == TimeSpan.MinValue.Ticks) throw new OverflowException(SR.Overflow_Duration); - Contract.EndContractBlock(); return new TimeSpan(_ticks >= 0 ? _ticks : -_ticks); } @@ -244,7 +242,6 @@ namespace System { if (Double.IsNaN(value)) throw new ArgumentException(SR.Arg_CannotBeNaN); - Contract.EndContractBlock(); double tmp = value * scale; double millis = tmp + (value >= 0 ? 0.5 : -0.5); if ((millis > Int64.MaxValue / TicksPerMillisecond) || (millis < Int64.MinValue / TicksPerMillisecond)) @@ -266,7 +263,6 @@ namespace System { if (Ticks == TimeSpan.MinValue.Ticks) throw new OverflowException(SR.Overflow_NegateTwosCompNum); - Contract.EndContractBlock(); return new TimeSpan(-_ticks); } diff --git a/src/System.Private.CoreLib/shared/System/UInt16.cs b/src/System.Private.CoreLib/shared/System/UInt16.cs index 4cd290bc4..be61313e3 100644 --- a/src/System.Private.CoreLib/shared/System/UInt16.cs +++ b/src/System.Private.CoreLib/shared/System/UInt16.cs @@ -11,7 +11,6 @@ ** ===========================================================*/ -using System.Diagnostics.Contracts; using System.Globalization; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; @@ -79,26 +78,22 @@ namespace System // Converts the current value to a String in base-10 with no extra padding. public override String ToString() { - Contract.Ensures(Contract.Result<String>() != null); return Number.FormatUInt32(m_value, null, NumberFormatInfo.CurrentInfo); } public String ToString(IFormatProvider provider) { - Contract.Ensures(Contract.Result<String>() != null); return Number.FormatUInt32(m_value, null, NumberFormatInfo.GetInstance(provider)); } public String ToString(String format) { - Contract.Ensures(Contract.Result<String>() != null); return Number.FormatUInt32(m_value, format, NumberFormatInfo.CurrentInfo); } public String ToString(String format, IFormatProvider provider) { - Contract.Ensures(Contract.Result<String>() != null); return Number.FormatUInt32(m_value, format, NumberFormatInfo.GetInstance(provider)); } diff --git a/src/System.Private.CoreLib/shared/System/UInt32.cs b/src/System.Private.CoreLib/shared/System/UInt32.cs index 49835613b..3cd016cba 100644 --- a/src/System.Private.CoreLib/shared/System/UInt32.cs +++ b/src/System.Private.CoreLib/shared/System/UInt32.cs @@ -12,7 +12,6 @@ ** ===========================================================*/ -using System.Diagnostics.Contracts; using System.Globalization; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; @@ -89,25 +88,21 @@ namespace System // The base 10 representation of the number with no extra padding. public override String ToString() { - Contract.Ensures(Contract.Result<String>() != null); return Number.FormatUInt32(m_value, null, NumberFormatInfo.CurrentInfo); } public String ToString(IFormatProvider provider) { - Contract.Ensures(Contract.Result<String>() != null); return Number.FormatUInt32(m_value, null, NumberFormatInfo.GetInstance(provider)); } public String ToString(String format) { - Contract.Ensures(Contract.Result<String>() != null); return Number.FormatUInt32(m_value, format, NumberFormatInfo.CurrentInfo); } public String ToString(String format, IFormatProvider provider) { - Contract.Ensures(Contract.Result<String>() != null); return Number.FormatUInt32(m_value, format, NumberFormatInfo.GetInstance(provider)); } diff --git a/src/System.Private.CoreLib/shared/System/UInt64.cs b/src/System.Private.CoreLib/shared/System/UInt64.cs index 424d48b8b..175d76330 100644 --- a/src/System.Private.CoreLib/shared/System/UInt64.cs +++ b/src/System.Private.CoreLib/shared/System/UInt64.cs @@ -11,7 +11,6 @@ ** ===========================================================*/ -using System.Diagnostics.Contracts; using System.Globalization; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; @@ -86,25 +85,21 @@ namespace System public override String ToString() { - Contract.Ensures(Contract.Result<String>() != null); return Number.FormatUInt64(m_value, null, NumberFormatInfo.CurrentInfo); } public String ToString(IFormatProvider provider) { - Contract.Ensures(Contract.Result<String>() != null); return Number.FormatUInt64(m_value, null, NumberFormatInfo.GetInstance(provider)); } public String ToString(String format) { - Contract.Ensures(Contract.Result<String>() != null); return Number.FormatUInt64(m_value, format, NumberFormatInfo.CurrentInfo); } public String ToString(String format, IFormatProvider provider) { - Contract.Ensures(Contract.Result<String>() != null); return Number.FormatUInt64(m_value, format, NumberFormatInfo.GetInstance(provider)); } diff --git a/src/System.Private.CoreLib/shared/System/ValueTuple.cs b/src/System.Private.CoreLib/shared/System/ValueTuple.cs index 3464f2781..d3ae20f41 100644 --- a/src/System.Private.CoreLib/shared/System/ValueTuple.cs +++ b/src/System.Private.CoreLib/shared/System/ValueTuple.cs @@ -4,7 +4,7 @@ using System.Collections; using System.Collections.Generic; -using System.Diagnostics.Contracts; +using System.Diagnostics; using System.Runtime.InteropServices; using System.Runtime.CompilerServices; using HashHelpers = System.Numerics.Hashing.HashHelpers; @@ -2186,7 +2186,7 @@ namespace System rest.GetHashCode()); } - Contract.Assert(false, "Missed all cases for computing ValueTuple hash code"); + Debug.Fail("Missed all cases for computing ValueTuple hash code"); return -1; } @@ -2237,7 +2237,7 @@ namespace System comparer.GetHashCode(Item7), rest.GetHashCode(comparer)); } - Contract.Assert(false, "Missed all cases for computing ValueTuple hash code"); + Debug.Fail("Missed all cases for computing ValueTuple hash code"); return -1; } diff --git a/src/System.Private.CoreLib/shared/System/Version.cs b/src/System.Private.CoreLib/shared/System/Version.cs index 9c66d9b90..a084f9f5a 100644 --- a/src/System.Private.CoreLib/shared/System/Version.cs +++ b/src/System.Private.CoreLib/shared/System/Version.cs @@ -4,7 +4,6 @@ using System.Globalization; using System.Diagnostics; -using System.Diagnostics.Contracts; using System.Text; namespace System @@ -39,7 +38,6 @@ namespace System if (revision < 0) throw new ArgumentOutOfRangeException(nameof(revision), SR.ArgumentOutOfRange_Version); - Contract.EndContractBlock(); _Major = major; _Minor = minor; @@ -58,7 +56,6 @@ namespace System if (build < 0) throw new ArgumentOutOfRangeException(nameof(build), SR.ArgumentOutOfRange_Version); - Contract.EndContractBlock(); _Major = major; _Minor = minor; @@ -72,7 +69,6 @@ namespace System if (minor < 0) throw new ArgumentOutOfRangeException(nameof(minor), SR.ArgumentOutOfRange_Version); - Contract.EndContractBlock(); _Major = major; _Minor = minor; @@ -441,7 +437,6 @@ namespace System { if ((Object)v1 == null) throw new ArgumentNullException(nameof(v1)); - Contract.EndContractBlock(); return (v1.CompareTo(v2) < 0); } @@ -449,7 +444,6 @@ namespace System { if ((Object)v1 == null) throw new ArgumentNullException(nameof(v1)); - Contract.EndContractBlock(); return (v1.CompareTo(v2) <= 0); } diff --git a/src/System.Private.CoreLib/src/Resources/Strings.resx b/src/System.Private.CoreLib/src/Resources/Strings.resx index e3827350b..9d57c995b 100644 --- a/src/System.Private.CoreLib/src/Resources/Strings.resx +++ b/src/System.Private.CoreLib/src/Resources/Strings.resx @@ -939,6 +939,9 @@ <data name="ArgumentOutOfRange_NegativeLength" xml:space="preserve"> <value>Length cannot be less than zero.</value> </data> + <data name="ArgumentOutOfRange_NoGCLohSizeGreaterTotalSize" xml:space="preserve"> + <value>lohSize can't be greater than totalSize</value> + </data> <data name="ArgumentOutOfRange_OffsetLength" xml:space="preserve"> <value>Offset and length must refer to a position in the string.</value> </data> diff --git a/src/System.Private.CoreLib/src/System.Private.CoreLib.csproj b/src/System.Private.CoreLib/src/System.Private.CoreLib.csproj index 609f00d43..cd81f6ce9 100644 --- a/src/System.Private.CoreLib/src/System.Private.CoreLib.csproj +++ b/src/System.Private.CoreLib/src/System.Private.CoreLib.csproj @@ -38,6 +38,10 @@ <PropertyGroup> <DefineConstants Condition="'$(FeatureCominterop)' == 'true'">FEATURE_COMINTEROP;$(DefineConstants)</DefineConstants> </PropertyGroup> + <PropertyGroup> + <FeaturePortableThreadPool Condition="'$(FeaturePortableThreadPool)' == ''">false</FeaturePortableThreadPool> + <FeaturePortableThreadPool Condition="'$(TargetsUnix)' == 'true'">true</FeaturePortableThreadPool> + </PropertyGroup> <ItemGroup> <Compile Include="..\..\Common\src\Internal\Runtime\RuntimeConstants.cs"> <Link>Internal\Runtime\RuntimeConstants.cs</Link> @@ -241,8 +245,8 @@ <Compile Include="System\InsufficientMemoryException.cs" /> <Compile Include="System\IntPtr.cs" /> <Compile Include="System\Marvin.cs" /> - <Compile Include="System\Math.cs" /> - <Compile Include="System\MathF.cs" /> + <Compile Include="System\Math.CoreRT.cs" /> + <Compile Include="System\MathF.CoreRT.cs" /> <Compile Include="System\MissingFieldException.cs" /> <Compile Include="System\MissingMemberException.cs" /> <Compile Include="System\MulticastDelegate.cs" /> @@ -326,6 +330,8 @@ <Compile Include="System\Threading\Interlocked.cs" /> <Compile Include="System\Threading\IOCompletionCallback.cs" /> <Compile Include="System\Threading\LockHolder.cs" /> + <Compile Include="System\Threading\LowLevelLock.cs" /> + <Compile Include="System\Threading\LowLevelMonitor.cs" /> <Compile Include="System\Threading\ManualResetEventSlim.cs" /> <Compile Include="System\Threading\Monitor.cs" /> <Compile Include="System\Threading\Mutex.cs" /> @@ -457,9 +463,24 @@ <Compile Include="..\..\Common\src\Interop\Windows\kernel32\Interop.MultiByteToWideChar.cs"> <Link>Interop\Windows\kernel32\Interop.MultiByteToWideChar.cs</Link> </Compile> + <Compile Include="..\..\Common\src\Interop\Windows\kernel32\Interop.CompletionPort.cs"> + <Link>Interop\Windows\kernel32\Interop.CompletionPort.cs</Link> + </Compile> + <Compile Include="..\..\Common\src\Interop\Windows\kernel32\Interop.CriticalSection.cs"> + <Link>Interop\Windows\kernel32\Interop.CriticalSection.cs</Link> + </Compile> + <Compile Include="..\..\Common\src\Interop\Windows\kernel32\Interop.ConditionVariable.cs"> + <Link>Interop\Windows\kernel32\Interop.ConditionVariable.cs</Link> + </Compile> + <Compile Include="..\..\Common\src\Interop\Windows\kernel32\Interop.GetSystemTimes.cs"> + <Link>Interop\Windows\kernel32\Interop.GetSystemTimes.cs</Link> + </Compile> <Compile Include="..\..\Common\src\Interop\Windows\kernel32\Interop.GetModuleFileName.cs"> <Link>Interop\Windows\kernel32\Interop.GetModuleFileName.cs</Link> </Compile> + <Compile Include="..\..\Common\src\Interop\Windows\kernel32\Interop.QueryPerformance.cs"> + <Link>Interop\Windows\kernel32\Interop.QueryPerformance.cs</Link> + </Compile> <Compile Include="..\..\Common\src\Interop\Windows\mincore\Interop.GetCurrentThreadId.cs"> <Link>Interop\Windows\mincore\Interop.GetCurrentThreadId.cs</Link> </Compile> @@ -514,10 +535,13 @@ <Compile Condition="'$(EnableWinRT)' != 'true'" Include="..\..\Common\src\Interop\Windows\mincore\Interop.DynamicLoad.cs"> <Link>Interop\Windows\mincore\Interop.DynamicLoad.cs</Link> </Compile> + <Compile Include="System\HighPerformanceCounter.Windows.cs" /> <Compile Include="System\Threading\EventWaitHandle.Windows.cs" /> + <Compile Include="System\Threading\LowLevelMonitor.Windows.cs" /> + <Compile Include="System\Threading\LowLevelLifoSemaphore.Windows.cs" /> <Compile Include="System\Threading\Mutex.Windows.cs" /> <Compile Include="System\Threading\Semaphore.Windows.cs" /> - <Compile Include="System\Threading\ThreadPool.Windows.cs" /> + <Compile Include="System\Threading\ThreadPool.Windows.cs" Condition="'$(FeaturePortableThreadPool)' != 'true'" /> <Compile Include="System\Threading\WaitHandle.Windows.cs" /> <Compile Include="System\Threading\Win32ThreadPoolBoundHandle.cs" /> <Compile Include="System\Threading\Win32ThreadPoolNativeOverlapped.cs" /> @@ -543,6 +567,19 @@ <Link>Interop\Windows\mincore\Interop.Normalization.cs</Link> </Compile> </ItemGroup> + <ItemGroup Condition="'$(FeaturePortableThreadPool)' == 'true'"> + <Compile Include="System\Threading\ThreadPool.Portable.cs" /> + <Compile Include="System\Threading\ClrThreadPool.cs" /> + <Compile Include="System\Threading\ClrThreadPoolEventSource.cs" /> + <Compile Include="System\Threading\ClrThreadPool.GateThread.cs" /> + <Compile Include="System\Threading\ClrThreadPool.HillClimbing.cs" /> + <Compile Include="System\Threading\ClrThreadPool.HillClimbing.Complex.cs" /> + <Compile Include="System\Threading\ClrThreadPool.ThreadCounts.cs" /> + <Compile Include="System\Threading\ClrThreadPool.WaitThread.cs" /> + <Compile Include="System\Threading\ClrThreadPool.WorkerThread.cs" /> + <Compile Include="System\Threading\ClrThreadPool.CpuUtilizationReader.Unix.cs" Condition="'$(TargetsUnix)' == 'true'" /> + <Compile Include="System\Threading\ClrThreadPool.CpuUtilizationReader.Windows.cs" Condition="'$(TargetsWindows)'=='true'" /> + </ItemGroup> <ItemGroup> <!-- CORERT-TODO: Port to Unix --> <Compile Include="..\..\Common\src\Interop\Windows\Interop.Libraries.cs"> @@ -600,22 +637,11 @@ <Compile Include="System\Number.Unix.cs" /> <Compile Include="System\HighPerformanceCounter.Unix.cs" /> <Compile Include="System\Runtime\InteropServices\PInvokeMarshal.Unix.cs" /> - <Compile Include="System\Threading\ClrThreadPool.cs" /> - <Compile Include="System\Threading\ClrThreadPool.CpuUtilizationReader.Unix.cs" /> - <Compile Include="System\Threading\ClrThreadPool.GateThread.cs" /> - <Compile Include="System\Threading\ClrThreadPool.HillClimbing.cs" /> - <Compile Include="System\Threading\ClrThreadPool.HillClimbing.Complex.cs" /> - <Compile Include="System\Threading\ClrThreadPool.ThreadCounts.cs" /> - <Compile Include="System\Threading\ClrThreadPool.WaitThread.cs" /> - <Compile Include="System\Threading\ClrThreadPool.WorkerThread.cs" /> - <Compile Include="System\Threading\ClrThreadPoolEventSource.cs" /> <Compile Include="System\Threading\EventWaitHandle.Unix.cs" /> <Compile Include="System\Threading\LowLevelLifoSemaphore.Unix.cs" /> - <Compile Include="System\Threading\LowLevelLock.Unix.cs" /> <Compile Include="System\Threading\LowLevelMonitor.Unix.cs" /> <Compile Include="System\Threading\Mutex.Unix.cs" /> <Compile Include="System\Threading\Semaphore.Unix.cs" /> - <Compile Include="System\Threading\ThreadPool.Unix.cs" /> <Compile Include="System\Threading\Timer.Unix.cs" /> <Compile Include="System\Threading\WaitHandle.Unix.cs" /> <Compile Include="System\Threading\WaitSubsystem.HandleManager.Unix.cs" /> diff --git a/src/System.Private.CoreLib/src/System/Decimal.DecCalc.cs b/src/System.Private.CoreLib/src/System/Decimal.DecCalc.cs index 27844daf6..5e67f3f61 100644 --- a/src/System.Private.CoreLib/src/System/Decimal.DecCalc.cs +++ b/src/System.Private.CoreLib/src/System/Decimal.DecCalc.cs @@ -2,11 +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.Globalization; +using System.Diagnostics; using System.Runtime.InteropServices; -using System.Runtime.CompilerServices; -using System.Diagnostics.Contracts; namespace System { @@ -31,7 +28,7 @@ namespace System set { umid = value; } } - internal bool Sign + internal bool IsNegative { get { return (uflags & SignMask) != 0; } set { uflags = (uflags & ~SignMask) | (value ? SignMask : 0); } @@ -39,14 +36,19 @@ namespace System internal int Scale { - get { return (int)((uflags & ScaleMask) >> ScaleShift); } + get { return (byte)(uflags >> ScaleShift); } set { uflags = (uflags & ~ScaleMask) | ((uint)value << ScaleShift); } } private ulong Low64 { +#if BIGENDIAN get { return ((ulong)umid << 32) | ulo; } set { umid = (uint)(value >> 32); ulo = (uint)value; } +#else + get => ulomidLE; + set => ulomidLE = value; +#endif } #region APIs need by number formatting. @@ -71,7 +73,7 @@ namespace System /// <summary> /// Class that contains all the mathematical calculations for decimal. Most of which have been ported from oleaut32. /// </summary> - private class DecCalc + private static class DecCalc { // Constant representing the negative number that is the closest possible // Decimal value to -0m. @@ -83,24 +85,19 @@ namespace System private const int DEC_SCALE_MAX = 28; - private const uint OVFL_MAX_9_HI = 4; - private const uint OVFL_MAX_9_MID = 1266874889; - private const uint OVFL_MAX_9_LO = 3047500985; - private const uint OVFL_MAX_5_HI = 42949; - private const uint OVFL_MAX_1_HI = 429496729; - private const uint SNGBIAS = 126; private const uint DBLBIAS = 1022; private const uint TenToPowerNine = 1000000000; - private const uint TenToPowerTenDiv4 = 2500000000; private static readonly Split64 s_tenToPowerEighteen = new Split64() { int64 = 1000000000000000000 }; // The maximum power of 10 that a 32 bit integer can store private const Int32 MaxInt32Scale = 9; + // The maximum power of 10 that a 64 bit integer can store + private const Int32 MaxInt64Scale = 19; // Fast access for 10^n where n is 0-9 - private static UInt32[] s_powers10 = new UInt32[] { + private static readonly UInt32[] s_powers10 = new UInt32[] { 1, 10, 100, @@ -113,7 +110,30 @@ namespace System 1000000000 }; - private static double[] s_doublePowers10 = new double[] { + // Fast access for 10^n where n is 1-19 + private static readonly ulong[] s_ulongPowers10 = new ulong[] { + 10, + 100, + 1000, + 10000, + 100000, + 1000000, + 10000000, + 100000000, + 1000000000, + 10000000000, + 100000000000, + 1000000000000, + 10000000000000, + 100000000000000, + 1000000000000000, + 10000000000000000, + 100000000000000000, + 1000000000000000000, + 10000000000000000000, + }; + + private static readonly double[] s_doublePowers10 = new double[] { 1, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, 1e20, 1e21, 1e22, 1e23, 1e24, 1e25, 1e26, 1e27, 1e28, 1e29, @@ -181,30 +201,6 @@ namespace System return sdl.int64; } - private static uint FullDiv64By32(ref ulong pdlNum, uint ulDen) - { - Split64 sdlTmp = new Split64(); - Split64 sdlRes = new Split64(); - - sdlTmp.int64 = pdlNum; - sdlRes.High32 = 0; - - if (sdlTmp.High32 >= ulDen) - { - // DivMod64by32 returns quotient in Lo, remainder in Hi. - // - sdlRes.Low32 = sdlTmp.High32; - sdlRes.int64 = DivMod64by32(sdlRes.int64, ulDen); - sdlTmp.High32 = sdlRes.High32; - sdlRes.High32 = sdlRes.Low32; - } - - sdlTmp.int64 = DivMod64by32(sdlTmp.int64, ulDen); - sdlRes.Low32 = sdlTmp.Low32; - pdlNum = sdlRes.int64; - return sdlTmp.High32; - } - private static ulong UInt32x32To64(uint a, uint b) { return (ulong)a * (ulong)b; @@ -236,7 +232,7 @@ namespace System * Div96By32 * * Entry: - * rgulNum - Pointer to 96-bit dividend as array of ULONGs, least-sig first + * bufNum - 96-bit dividend as array of ULONGs, least-sig first * ulDen - 32-bit divisor. * * Purpose: @@ -250,43 +246,80 @@ namespace System * None. * ***********************************************************************/ - private static uint Div96By32(uint[] rgulNum, uint ulDen) + private static uint Div96By32(ref Buf12 bufNum, uint ulDen) { - Split64 sdlTmp = new Split64(); - - sdlTmp.High32 = 0; + // TODO: https://github.com/dotnet/coreclr/issues/3439 + ulong tmp, div; + if (bufNum.U2 != 0) + { + tmp = bufNum.High64; + div = tmp / ulDen; + bufNum.High64 = div; + tmp = ((tmp - div * ulDen) << 32) | bufNum.U0; + uint div32 = (uint)(tmp / ulDen); + bufNum.U0 = div32; + return (uint)tmp - div32 * ulDen; + } - if (rgulNum[2] != 0) - goto Div3Word; + tmp = bufNum.Low64; + div = tmp / ulDen; + bufNum.Low64 = div; + return (uint)(tmp - div * ulDen); + } - if (rgulNum[1] >= ulDen) - goto Div2Word; + private static uint Div96ByConst100000000(ref Buf12 bufNum) + { + const uint ulDen = 100000000; + ulong tmp = bufNum.High64; + ulong div = tmp / ulDen; + bufNum.High64 = div; + tmp = ((tmp - div * ulDen) << 32) | bufNum.U0; + uint div32 = (uint)(tmp / ulDen); + bufNum.U0 = div32; + return (uint)tmp - div32 * ulDen; + } - sdlTmp.High32 = rgulNum[1]; - rgulNum[1] = 0; - goto Div1Word; + private static uint Div96ByConst10000(ref Buf12 bufNum) + { + const uint ulDen = 10000; + ulong tmp = bufNum.High64; + ulong div = tmp / ulDen; + bufNum.High64 = div; + tmp = ((tmp - div * ulDen) << 32) | bufNum.U0; + uint div32 = (uint)(tmp / ulDen); + bufNum.U0 = div32; + return (uint)tmp - div32 * ulDen; + } - Div3Word: - sdlTmp.Low32 = rgulNum[2]; - sdlTmp.int64 = DivMod64by32(sdlTmp.int64, ulDen); - rgulNum[2] = sdlTmp.Low32; - Div2Word: - sdlTmp.Low32 = rgulNum[1]; - sdlTmp.int64 = DivMod64by32(sdlTmp.int64, ulDen); - rgulNum[1] = sdlTmp.Low32; - Div1Word: - sdlTmp.Low32 = rgulNum[0]; - sdlTmp.int64 = DivMod64by32(sdlTmp.int64, ulDen); - rgulNum[0] = sdlTmp.Low32; + private static uint Div96ByConst100(ref Buf12 bufNum) + { + const uint ulDen = 100; + ulong tmp = bufNum.High64; + ulong div = tmp / ulDen; + bufNum.High64 = div; + tmp = ((tmp - div * ulDen) << 32) | bufNum.U0; + uint div32 = (uint)(tmp / ulDen); + bufNum.U0 = div32; + return (uint)tmp - div32 * ulDen; + } - return sdlTmp.High32; + private static uint Div96ByConst10(ref Buf12 bufNum) + { + const uint ulDen = 10; + ulong tmp = bufNum.High64; + ulong div = tmp / ulDen; + bufNum.High64 = div; + tmp = ((tmp - div * ulDen) << 32) | bufNum.U0; + uint div32 = (uint)(tmp / ulDen); + bufNum.U0 = div32; + return (uint)tmp - div32 * ulDen; } /*** * Div96By64 * * Entry: - * rgulNum - Pointer to 96-bit dividend as array of ULONGs, least-sig first + * bufNum - 96-bit dividend as array of ULONGs, least-sig first * sdlDen - 64-bit divisor. * * Purpose: @@ -301,77 +334,87 @@ namespace System * None. * ***********************************************************************/ - private static uint Div96By64(System.Collections.Generic.IList<uint> rgulNum, Split64 sdlDen) + private static uint Div96By64(ref Buf12 bufNum, ulong den) { - Split64 sdlQuo = new Split64(); - Split64 sdlNum = new Split64(); - Split64 sdlProd = new Split64(); + uint quo; + ulong num; + uint num2 = bufNum.U2; + if (num2 == 0) + { + num = bufNum.Low64; + if (num < den) + // Result is zero. Entire dividend is remainder. + return 0; - sdlNum.Low32 = rgulNum[0]; + // TODO: https://github.com/dotnet/coreclr/issues/3439 + quo = (uint)(num / den); + num -= quo * den; // remainder + bufNum.Low64 = num; + return quo; + } - if (rgulNum[2] >= sdlDen.High32) + uint denHigh32 = (uint)(den >> 32); + if (num2 >= denHigh32) { // Divide would overflow. Assume a quotient of 2^32, and set // up remainder accordingly. // - sdlNum.High32 = rgulNum[1] - sdlDen.Low32; - sdlQuo.Low32 = 0; + num = bufNum.Low64; + num -= den << 32; + quo = 0; // Remainder went negative. Add divisor back in until it's positive, // a max of 2 times. // do { - sdlQuo.Low32--; - sdlNum.int64 += sdlDen.int64; - } while (sdlNum.int64 >= sdlDen.int64); + quo--; + num += den; + } while (num >= den); - goto Done; + bufNum.Low64 = num; + return quo; } // Hardware divide won't overflow // - if (rgulNum[2] == 0 && rgulNum[1] < sdlDen.High32) + ulong num64 = bufNum.High64; + if (num64 < denHigh32) // Result is zero. Entire dividend is remainder. // return 0; - // DivMod64by32 returns quotient in Lo, remainder in Hi. - // - sdlQuo.Low32 = rgulNum[1]; - sdlQuo.High32 = rgulNum[2]; - sdlQuo.int64 = DivMod64by32(sdlQuo.int64, sdlDen.High32); - sdlNum.High32 = sdlQuo.High32; // remainder + // TODO: https://github.com/dotnet/coreclr/issues/3439 + quo = (uint)(num64 / denHigh32); + num = bufNum.U0 | ((num64 - quo * denHigh32) << 32); // remainder // Compute full remainder, rem = dividend - (quo * divisor). // - sdlProd.int64 = UInt32x32To64(sdlQuo.Low32, sdlDen.Low32); // quo * lo divisor - sdlNum.int64 -= sdlProd.int64; + ulong prod = UInt32x32To64(quo, (uint)den); // quo * lo divisor + num -= prod; - if (sdlNum.int64 > ~sdlProd.int64) + if (num > ~prod) { // Remainder went negative. Add divisor back in until it's positive, // a max of 2 times. // do { - sdlQuo.Low32--; - sdlNum.int64 += sdlDen.int64; - } while (sdlNum.int64 >= sdlDen.int64); + quo--; + num += den; + } while (num >= den); } - Done: - rgulNum[0] = sdlNum.Low32; - rgulNum[1] = sdlNum.High32; - return sdlQuo.Low32; + bufNum.Low64 = num; + return quo; } /*** * Div128By96 * * Entry: - * rgulNum - Pointer to 128-bit dividend as array of ULONGs, least-sig first - * rgulDen - Pointer to 96-bit divisor. + * bufNum - 128-bit dividend as array of ULONGs, least-sig first + * bufDen - 96-bit divisor. * * Purpose: * Do partial divide, yielding 32-bit result and 96-bit remainder. @@ -389,83 +432,77 @@ namespace System * None. * ***********************************************************************/ - private static uint Div128By96(uint[] rgulNum, uint[] rgulDen) + private static uint Div128By96(ref Buf16 bufNum, ref Buf12 bufDen) { - Split64 sdlQuo = new Split64(); - Split64 sdlNum = new Split64(); - Split64 sdlProd1 = new Split64(); - Split64 sdlProd2 = new Split64(); - - sdlNum.Low32 = rgulNum[0]; - sdlNum.High32 = rgulNum[1]; - - if (rgulNum[3] == 0 && rgulNum[2] < rgulDen[2]) + ulong dividend = bufNum.High64; + uint den = bufDen.U2; + if (dividend < den) // Result is zero. Entire dividend is remainder. // return 0; - // DivMod64by32 returns quotient in Lo, remainder in Hi. - // - sdlQuo.Low32 = rgulNum[2]; - sdlQuo.High32 = rgulNum[3]; - sdlQuo.int64 = DivMod64by32(sdlQuo.int64, rgulDen[2]); + // TODO: https://github.com/dotnet/coreclr/issues/3439 + uint quo = (uint)(dividend / den); + uint remainder = (uint)dividend - quo * den; // Compute full remainder, rem = dividend - (quo * divisor). // - sdlProd1.int64 = UInt32x32To64(sdlQuo.Low32, rgulDen[0]); // quo * lo divisor - sdlProd2.int64 = UInt32x32To64(sdlQuo.Low32, rgulDen[1]); // quo * mid divisor - sdlProd2.int64 += sdlProd1.High32; - sdlProd1.High32 = sdlProd2.Low32; + ulong prod1 = UInt32x32To64(quo, bufDen.U0); // quo * lo divisor + ulong prod2 = UInt32x32To64(quo, bufDen.U1); // quo * mid divisor + prod2 += prod1 >> 32; + prod1 = (uint)prod1 | (prod2 << 32); + prod2 >>= 32; - sdlNum.int64 -= sdlProd1.int64; - rgulNum[2] = sdlQuo.High32 - sdlProd2.High32; // sdlQuo.Hi is remainder + ulong num = bufNum.Low64; + num -= prod1; + remainder -= (uint)prod2; // Propagate carries // - bool fallthru = false; - if (sdlNum.int64 > ~sdlProd1.int64) + if (num > ~prod1) { - rgulNum[2]--; - if (rgulNum[2] >= ~sdlProd2.High32) - fallthru = true; + remainder--; + if (remainder < ~(uint)prod2) + goto PosRem; } - if (fallthru || rgulNum[2] > ~sdlProd2.High32) + else if (remainder <= ~(uint)prod2) + goto PosRem; { // Remainder went negative. Add divisor back in until it's positive, // a max of 2 times. // - sdlProd1.Low32 = rgulDen[0]; - sdlProd1.High32 = rgulDen[1]; + prod1 = bufDen.Low64; for (;;) { - sdlQuo.Low32--; - sdlNum.int64 += sdlProd1.int64; - rgulNum[2] += rgulDen[2]; + quo--; + num += prod1; + remainder += den; - if (sdlNum.int64 < sdlProd1.int64) + if (num < prod1) { // Detected carry. Check for carry out of top // before adding it in. // - if (rgulNum[2]++ < rgulDen[2]) + if (remainder++ < den) break; } - if (rgulNum[2] < rgulDen[2]) + if (remainder < den) break; // detected carry } } +PosRem: - rgulNum[0] = sdlNum.Low32; - rgulNum[1] = sdlNum.High32; - return sdlQuo.Low32; + bufNum.Low64 = num; + bufNum.U2 = remainder; + return quo; } /*** * IncreaseScale * * Entry: - * rgulNum - Pointer to 96-bit number as array of ULONGs, least-sig first + * bufNum - 96-bit number as array of ULONGs, least-sig first * ulPwr - Scale factor to multiply by * * Purpose: @@ -479,25 +516,34 @@ namespace System * None. * ***********************************************************************/ - private static uint IncreaseScale(uint[] rgulNum, uint ulPwr) + private static uint IncreaseScale(ref Buf12 bufNum, uint ulPwr) { - Split64 sdlTmp = new Split64(); + ulong tmp = UInt32x32To64(bufNum.U0, ulPwr); + bufNum.U0 = (uint)tmp; + tmp >>= 32; + tmp += UInt32x32To64(bufNum.U1, ulPwr); + bufNum.U1 = (uint)tmp; + tmp >>= 32; + tmp += UInt32x32To64(bufNum.U2, ulPwr); + bufNum.U2 = (uint)tmp; + return (uint)(tmp >> 32); + } - sdlTmp.int64 = UInt32x32To64(rgulNum[0], ulPwr); - rgulNum[0] = sdlTmp.Low32; - sdlTmp.int64 = UInt32x32To64(rgulNum[1], ulPwr) + sdlTmp.High32; - rgulNum[1] = sdlTmp.Low32; - sdlTmp.int64 = UInt32x32To64(rgulNum[2], ulPwr) + sdlTmp.High32; - rgulNum[2] = sdlTmp.Low32; - return sdlTmp.High32; + private static void IncreaseScale64(ref Buf12 bufNum, uint ulPwr) + { + ulong tmp = UInt32x32To64(bufNum.U0, ulPwr); + bufNum.U0 = (uint)tmp; + tmp >>= 32; + tmp += UInt32x32To64(bufNum.U1, ulPwr); + bufNum.High64 = tmp; } /*** * ScaleResult * * Entry: - * rgulRes - Array of ULONGs with value, least-significant first. - * iHiRes - Index of last non-zero value in rgulRes. + * bufRes - Array of ULONGs with value, least-significant first. + * iHiRes - Index of last non-zero value in bufRes. * iScale - Scale factor for this value, range 0 - 2 * DEC_SCALE_MAX * * Purpose: @@ -505,18 +551,14 @@ namespace System * Perform needed scaling. Adjust scale factor accordingly. * * Exit: - * rgulRes updated in place, always 3 ULONGs. - * New scale factor returned, -1 if overflow error. + * bufRes updated in place, always 3 ULONGs. + * New scale factor returned. * ***********************************************************************/ - private static int ScaleResult(uint[] rgulRes, int iHiRes, int iScale) + private static unsafe int ScaleResult(Buf24* bufRes, uint iHiRes, int iScale) { - int iNewScale; - int iCur; - uint ulPwr; - uint ulTmp; - uint ulSticky; - Split64 sdlTmp = new Split64(); + Debug.Assert(iHiRes < bufRes->Length); + uint* rgulRes = (uint*)bufRes; // See if we need to scale the result. The combined scale must // be <= DEC_SCALE_MAX and the upper 96 bits must be zero. @@ -525,37 +567,35 @@ namespace System // the upper 96 bits zero. iHiRes is the index into rgulRes[] // of the highest non-zero ULONG. // - iNewScale = iHiRes * 32 - 64 - 1; - if (iNewScale > 0) + int iNewScale = 0; + if (iHiRes > 2) { + iNewScale = (int)iHiRes * 32 - 64 - 1; // Find the MSB. // - ulTmp = rgulRes[iHiRes]; + uint ulTmp = rgulRes[iHiRes]; + iNewScale--; if ((ulTmp & 0xFFFF0000) == 0) { - iNewScale -= 16; ulTmp <<= 16; + iNewScale -= 16; } if ((ulTmp & 0xFF000000) == 0) { - iNewScale -= 8; ulTmp <<= 8; + iNewScale -= 8; } if ((ulTmp & 0xF0000000) == 0) { - iNewScale -= 4; ulTmp <<= 4; + iNewScale -= 4; } if ((ulTmp & 0xC0000000) == 0) { - iNewScale -= 2; ulTmp <<= 2; + iNewScale -= 2; } - if ((ulTmp & 0x80000000) == 0) - { - iNewScale--; - ulTmp <<= 1; - } + iNewScale -= (int)ulTmp >> 31; // Multiply bit position by log10(2) to figure it's power of 10. // We scale the log by 256. log(2) = .30103, * 256 = 77. Doing this @@ -574,10 +614,8 @@ namespace System // current scale of the result, we'll overflow. // if (iNewScale > iScale) - return -1; + goto ThrowOverflow; } - else - iNewScale = 0; // Make sure we scale by enough to bring the current scale factor // into valid range. @@ -592,42 +630,132 @@ namespace System // be 1 power of 10 short. // iScale -= iNewScale; - ulSticky = 0; - sdlTmp.High32 = 0; // initialize remainder + uint ulSticky = 0; + uint quotient, remainder = 0; for (;;) { - ulSticky |= sdlTmp.High32; // record remainder as sticky bit - - if (iNewScale > MaxInt32Scale) - ulPwr = TenToPowerNine; - else - ulPwr = s_powers10[iNewScale]; + ulSticky |= remainder; // record remainder as sticky bit - // Compute first quotient. - // DivMod64by32 returns quotient in Lo, remainder in Hi. - // - sdlTmp.int64 = DivMod64by32(rgulRes[iHiRes], ulPwr); - rgulRes[iHiRes] = sdlTmp.Low32; - iCur = iHiRes - 1; - - if (iCur >= 0) + uint ulPwr; + uint high = rgulRes[iHiRes]; + // Scaling loop specialized for each power of 10 because division by constant is an order of magnitude faster (especially for 64-bit division that's actually done by 128bit DIV on x64) + switch (iNewScale) { - // If first quotient was 0, update iHiRes. - // - if (sdlTmp.Low32 == 0) - iHiRes--; - - // Compute subsequent quotients. - // - do - { - sdlTmp.Low32 = rgulRes[iCur]; - sdlTmp.int64 = DivMod64by32(sdlTmp.int64, ulPwr); - rgulRes[iCur] = sdlTmp.Low32; - iCur--; - } while (iCur >= 0); + case 1: + { + const uint power = 10; + remainder = high - (quotient = high / power) * power; + for (uint i = iHiRes - 1; (int)i >= 0; i--) + { + ulong num = rgulRes[i] + ((ulong)remainder << 32); + remainder = (uint)num - (rgulRes[i] = (uint)(num / power)) * power; + } + ulPwr = power; + break; + } + case 2: + { + const uint power = 100; + remainder = high - (quotient = high / power) * power; + for (uint i = iHiRes - 1; (int)i >= 0; i--) + { + ulong num = rgulRes[i] + ((ulong)remainder << 32); + remainder = (uint)num - (rgulRes[i] = (uint)(num / power)) * power; + } + ulPwr = power; + break; + } + case 3: + { + const uint power = 1000; + remainder = high - (quotient = high / power) * power; + for (uint i = iHiRes - 1; (int)i >= 0; i--) + { + ulong num = rgulRes[i] + ((ulong)remainder << 32); + remainder = (uint)num - (rgulRes[i] = (uint)(num / power)) * power; + } + ulPwr = power; + break; + } + case 4: + { + const uint power = 10000; + remainder = high - (quotient = high / power) * power; + for (uint i = iHiRes - 1; (int)i >= 0; i--) + { + ulong num = rgulRes[i] + ((ulong)remainder << 32); + remainder = (uint)num - (rgulRes[i] = (uint)(num / power)) * power; + } + ulPwr = power; + break; + } + case 5: + { + const uint power = 100000; + remainder = high - (quotient = high / power) * power; + for (uint i = iHiRes - 1; (int)i >= 0; i--) + { + ulong num = rgulRes[i] + ((ulong)remainder << 32); + remainder = (uint)num - (rgulRes[i] = (uint)(num / power)) * power; + } + ulPwr = power; + break; + } + case 6: + { + const uint power = 1000000; + remainder = high - (quotient = high / power) * power; + for (uint i = iHiRes - 1; (int)i >= 0; i--) + { + ulong num = rgulRes[i] + ((ulong)remainder << 32); + remainder = (uint)num - (rgulRes[i] = (uint)(num / power)) * power; + } + ulPwr = power; + break; + } + case 7: + { + const uint power = 10000000; + remainder = high - (quotient = high / power) * power; + for (uint i = iHiRes - 1; (int)i >= 0; i--) + { + ulong num = rgulRes[i] + ((ulong)remainder << 32); + remainder = (uint)num - (rgulRes[i] = (uint)(num / power)) * power; + } + ulPwr = power; + break; + } + case 8: + { + const uint power = 100000000; + remainder = high - (quotient = high / power) * power; + for (uint i = iHiRes - 1; (int)i >= 0; i--) + { + ulong num = rgulRes[i] + ((ulong)remainder << 32); + remainder = (uint)num - (rgulRes[i] = (uint)(num / power)) * power; + } + ulPwr = power; + break; + } + default: + { + const uint power = TenToPowerNine; + remainder = high - (quotient = high / power) * power; + for (uint i = iHiRes - 1; (int)i >= 0; i--) + { + ulong num = rgulRes[i] + ((ulong)remainder << 32); + remainder = (uint)num - (rgulRes[i] = (uint)(num / power)) * power; + } + ulPwr = power; + break; + } } + rgulRes[iHiRes] = quotient; + // If first quotient was 0, update iHiRes. + // + if (quotient == 0 && iHiRes != 0) + iHiRes--; iNewScale -= MaxInt32Scale; if (iNewScale > 0) @@ -638,6 +766,8 @@ namespace System // if (iHiRes > 2) { + if (iScale == 0) + goto ThrowOverflow; iNewScale = 1; iScale--; continue; // scale by 10 @@ -647,90 +777,106 @@ namespace System // If remainder == 1/2 divisor, round up if odd or sticky bit set. // ulPwr >>= 1; // power of 10 always even - if (ulPwr <= sdlTmp.High32 && (ulPwr < sdlTmp.High32 || - ((rgulRes[0] & 1) | ulSticky) != 0)) + if (ulPwr <= remainder && (ulPwr < remainder || ((rgulRes[0] & 1) | ulSticky) != 0) && ++rgulRes[0] == 0) { - iCur = -1; - while (++rgulRes[++iCur] == 0) - ; + uint iCur = 0; + do + { + Debug.Assert(iCur + 1 < bufRes->Length); + } + while (++rgulRes[++iCur] == 0); if (iCur > 2) { // The rounding caused us to carry beyond 96 bits. // Scale by 10 more. // + if (iScale == 0) + goto ThrowOverflow; iHiRes = iCur; ulSticky = 0; // no sticky bit - sdlTmp.High32 = 0; // or remainder + remainder = 0; // or remainder iNewScale = 1; iScale--; continue; // scale by 10 } } - // We may have scaled it more than we planned. Make sure the scale - // factor hasn't gone negative, indicating overflow. - // - if (iScale < 0) - return -1; - - return iScale; + break; } // for(;;) } return iScale; + +ThrowOverflow: + throw new OverflowException(SR.Overflow_Decimal); } // Adjust the quotient to deal with an overflow. We need to divide by 10, // feed in the high bit to undo the overflow and then round as required, - private static void OverflowUnscale(uint[] rgulQuo, bool fRemainder) + private static int OverflowUnscale(ref Buf12 bufQuo, int iScale, bool fRemainder) { + if (--iScale < 0) + throw new OverflowException(SR.Overflow_Decimal); + Split64 sdlTmp = new Split64(); // We have overflown, so load the high bit with a one. sdlTmp.High32 = 1; - sdlTmp.Low32 = rgulQuo[2]; + sdlTmp.Low32 = bufQuo.U2; sdlTmp.int64 = DivMod64by32(sdlTmp.int64, 10); - rgulQuo[2] = sdlTmp.Low32; - sdlTmp.Low32 = rgulQuo[1]; + bufQuo.U2 = sdlTmp.Low32; + sdlTmp.Low32 = bufQuo.U1; sdlTmp.int64 = DivMod64by32(sdlTmp.int64, 10); - rgulQuo[1] = sdlTmp.Low32; - sdlTmp.Low32 = rgulQuo[0]; + bufQuo.U1 = sdlTmp.Low32; + sdlTmp.Low32 = bufQuo.U0; sdlTmp.int64 = DivMod64by32(sdlTmp.int64, 10); - rgulQuo[0] = sdlTmp.Low32; + bufQuo.U0 = sdlTmp.Low32; // The remainder is the last digit that does not fit, so we can use it to work out if we need to round up - if ((sdlTmp.High32 > 5) || ((sdlTmp.High32 == 5) && (fRemainder || (rgulQuo[0] & 1) != 0))) - Add32To96(rgulQuo, 1); + if ((sdlTmp.High32 > 5) || ((sdlTmp.High32 == 5) && (fRemainder || (bufQuo.U0 & 1) != 0))) + Add32To96(ref bufQuo, 1); + return iScale; } /*** * SearchScale * * Entry: - * ulResHi - Top ULONG of quotient - * ulResMid - Middle ULONG of quotient - * ulResLo - Lower ULONG of quotient - * iScale - Scale factor of quotient, range -DEC_SCALE_MAX to DEC_SCALE_MAX + * bufQuo - 96-bit quotient + * iScale - Scale factor of quotient, range -DEC_SCALE_MAX to DEC_SCALE_MAX-1 * * Purpose: * Determine the max power of 10, <= 9, that the quotient can be scaled * up by and still fit in 96 bits. * * Exit: - * Returns power of 10 to scale by, -1 if overflow error. + * Returns power of 10 to scale by. * ***********************************************************************/ - private static int SearchScale(uint ulResHi, uint ulResMid, uint ulResLo, int iScale) + private static int SearchScale(ref Buf12 bufQuo, int iScale) { - int iCurScale; + const uint OVFL_MAX_9_HI = 4; + const uint OVFL_MAX_8_HI = 42; + const uint OVFL_MAX_7_HI = 429; + const uint OVFL_MAX_6_HI = 4294; + const uint OVFL_MAX_5_HI = 42949; + const uint OVFL_MAX_4_HI = 429496; + const uint OVFL_MAX_3_HI = 4294967; + const uint OVFL_MAX_2_HI = 42949672; + const uint OVFL_MAX_1_HI = 429496729; + const ulong OVFL_MAX_9_MIDLO = 5441186219426131129; + + uint ulResHi = bufQuo.U2; + ulong ulResMidLo = bufQuo.Low64; + int iCurScale = 0; // Quick check to stop us from trying to scale any more. // - if (ulResHi > OVFL_MAX_1_HI || iScale >= DEC_SCALE_MAX) + if (ulResHi > OVFL_MAX_1_HI) { - iCurScale = 0; goto HaveScale; } + var powerOvfl = PowerOvflValues; if (iScale > DEC_SCALE_MAX - 9) { // We can't scale by 10^9 without exceeding the max scale factor. @@ -738,120 +884,91 @@ namespace System // standard search for scale factor. // iCurScale = DEC_SCALE_MAX - iScale; - if (ulResHi < PowerOvfl.Hi(iCurScale - 1)) + if (ulResHi < powerOvfl[iCurScale - 1].Hi) goto HaveScale; - - if (ulResHi == PowerOvfl.Hi(iCurScale - 1)) - { - UpperEq(ulResMid, ulResLo, ref iCurScale); - goto HaveScale; - } } - else if (ulResHi < OVFL_MAX_9_HI || (ulResHi == OVFL_MAX_9_HI && - ulResMid < OVFL_MAX_9_MID) || (ulResHi == OVFL_MAX_9_HI && ulResMid == OVFL_MAX_9_MID && ulResLo <= OVFL_MAX_9_LO)) + else if (ulResHi < OVFL_MAX_9_HI || ulResHi == OVFL_MAX_9_HI && ulResMidLo <= OVFL_MAX_9_MIDLO) return 9; - // Search for a power to scale by < 9. Do a binary search - // on PowerOvfl[]. + // Search for a power to scale by < 9. Do a binary search. // - iCurScale = 5; - if (ulResHi < OVFL_MAX_5_HI) - iCurScale = 7; - else if (ulResHi > OVFL_MAX_5_HI) - iCurScale = 3; - else + if (ulResHi > OVFL_MAX_5_HI) { - UpperEq(ulResMid, ulResLo, ref iCurScale); - goto HaveScale; + if (ulResHi > OVFL_MAX_3_HI) + { + iCurScale = 2; + if (ulResHi > OVFL_MAX_2_HI) + iCurScale--; + } + else + { + iCurScale = 4; + if (ulResHi > OVFL_MAX_4_HI) + iCurScale--; + } } - - // iCurScale is 3 or 7. - // - if (ulResHi < PowerOvfl.Hi(iCurScale - 1)) - iCurScale++; - else if (ulResHi > PowerOvfl.Hi(iCurScale - 1)) - iCurScale--; else { - UpperEq(ulResMid, ulResLo, ref iCurScale); - goto HaveScale; + if (ulResHi > OVFL_MAX_7_HI) + { + iCurScale = 6; + if (ulResHi > OVFL_MAX_6_HI) + iCurScale--; + } + else + { + iCurScale = 8; + if (ulResHi > OVFL_MAX_8_HI) + iCurScale--; + } } - // iCurScale is 2, 4, 6, or 8. - // // In all cases, we already found we could not use the power one larger. // So if we can use this power, it is the biggest, and we're done. If // we can't use this power, the one below it is correct for all cases // unless it's 10^1 -- we might have to go to 10^0 (no scaling). // - if (ulResHi > PowerOvfl.Hi(iCurScale - 1)) + if (ulResHi == powerOvfl[iCurScale - 1].Hi && ulResMidLo > powerOvfl[iCurScale - 1].MidLo) iCurScale--; - if (ulResHi == PowerOvfl.Hi(iCurScale - 1)) - UpperEq(ulResMid, ulResLo, ref iCurScale); - HaveScale: // iCurScale = largest power of 10 we can scale by without overflow, // iCurScale < 9. See if this is enough to make scale factor // positive if it isn't already. // if (iCurScale + iScale < 0) - iCurScale = -1; + throw new OverflowException(SR.Overflow_Decimal); return iCurScale; } - private static void UpperEq(uint ulResMid, uint ulResLo, ref int iCurScale) - { - if (ulResMid > PowerOvfl.Mid(iCurScale - 1) || - (ulResMid == PowerOvfl.Mid(iCurScale - 1) && ulResLo > PowerOvfl.Lo(iCurScale - 1))) - { - iCurScale--; - } - } - // Add a 32 bit unsigned long to an array of 3 unsigned longs representing a 96 integer // Returns false if there is an overflow - private static bool Add32To96(uint[] rgulNum, uint ulValue) + private static bool Add32To96(ref Buf12 bufNum, uint ulValue) { - rgulNum[0] += ulValue; - if (rgulNum[0] < ulValue) + if ((bufNum.Low64 += ulValue) < ulValue) { - if (++rgulNum[1] == 0) - { - if (++rgulNum[2] == 0) - return false; - } + if (++bufNum.U2 == 0) + return false; } return true; } // DecAddSub adds or subtracts two decimal values. On return, d1 contains the result // of the operation. Passing in true for bSign means subtract and false means add. - // - // Returns true if we overflow otherwise false. - private static bool DecAddSub(ref Decimal d1, ref Decimal d2, bool bSign) + private static unsafe void DecAddSub(ref Decimal d1, ref Decimal d2, bool bSign) { - uint[] rgulNum = new uint[6]; - uint ulPwr; - int iScale; - int iHiProd; - int iCur; - Split64 sdlTmp = new Split64(); - Decimal result = new Decimal(); - Decimal tmp = new Decimal(); + ulong low64 = d1.Low64; + uint high = d1.High, flags = d1.uflags, d2flags = d2.uflags; - bSign ^= d2.Sign ^ d1.Sign; + uint xorflags = d2flags ^ flags; + bSign ^= (xorflags & SignMask) != 0; - if (d2.Scale == d1.Scale) + if ((xorflags & ScaleMask) == 0) { // Scale factors are equal, no alignment necessary. // - result.Sign = d1.Sign; - result.Scale = d1.Scale; - - if (AlignedAdd(ref result, ref d1, ref d2, bSign)) - return true; + goto AlignedAdd; } else { @@ -861,22 +978,28 @@ namespace System // the larger scale factor. The result will have the larger // scale factor. // - result.Scale = d2.Scale; // scale factor of "smaller" - result.Sign = d1.Sign; // but sign of "larger" - iScale = result.Scale - d1.Scale; + uint d1flags = flags; + flags = d2flags & ScaleMask | flags & SignMask; // scale factor of "smaller", but sign of "larger" + int iScale = (int)(flags - d1flags) >> ScaleShift; if (iScale < 0) { // Guessed scale factor wrong. Swap operands. // iScale = -iScale; - result.Scale = d1.Scale; - result.Sign ^= bSign; - tmp = d2; + flags = d1flags; + if (bSign) + flags ^= SignMask; + low64 = d2.Low64; + high = d2.High; d2 = d1; - d1 = tmp; } + Buf24 bufNum; + _ = &bufNum; // workaround for CS0165 + uint ulPwr, iHiProd; + ulong tmp64; + // d1 will need to be multiplied by 10^iScale so // it will have the same scale as d2. We could be // extending it to up to 192 bits of precision. @@ -886,302 +1009,268 @@ namespace System // Scaling won't make it larger than 4 ULONGs // ulPwr = s_powers10[iScale]; - tmp = UInt32x32To64(d1.Low, ulPwr); - sdlTmp.int64 = UInt32x32To64(d1.Mid, ulPwr); - sdlTmp.int64 += tmp.Mid; - tmp.Mid = sdlTmp.Low32; - tmp.High = sdlTmp.High32; - sdlTmp.int64 = UInt32x32To64(d1.High, ulPwr); - sdlTmp.int64 += tmp.High; - if (sdlTmp.High32 == 0) + ulong tmpLow = UInt32x32To64((uint)low64, ulPwr); + tmp64 = (low64 >> 32) * ulPwr + (tmpLow >> 32); + low64 = (uint)tmpLow + (tmp64 << 32); + tmp64 >>= 32; + tmp64 += UInt32x32To64(high, ulPwr); + if (tmp64 <= uint.MaxValue) { // Result fits in 96 bits. Use standard aligned add. // - tmp.High = sdlTmp.Low32; - d1 = tmp; - if (AlignedAdd(ref result, ref d1, ref d2, bSign)) - return true; - d1 = result; - return false; + high = (uint)tmp64; + goto AlignedAdd; } - rgulNum[0] = tmp.Low; - rgulNum[1] = tmp.Mid; - rgulNum[2] = sdlTmp.Low32; - rgulNum[3] = sdlTmp.High32; + bufNum.Low64 = low64; + bufNum.Mid64 = tmp64; iHiProd = 3; } else { - // Have to scale by a bunch. Move the number to a buffer - // where it has room to grow as it's scaled. - // - rgulNum[0] = d1.Low; - rgulNum[1] = d1.Mid; - rgulNum[2] = d1.High; iHiProd = 2; // Scan for zeros in the upper words. // - if (rgulNum[2] == 0) + if (high == 0) { iHiProd = 1; - if (rgulNum[1] == 0) + if (low64 >> 32 == 0) { iHiProd = 0; - if (rgulNum[0] == 0) + if ((uint)low64 == 0) { // Left arg is zero, return right. // - result.Low64 = d2.Low64; - result.High = d2.High; - result.Sign ^= bSign; - d1 = result; - return false; + uint signFlags = flags & SignMask; + if (bSign) + signFlags ^= SignMask; + d1 = d2; + d1.uflags = d2.uflags & ScaleMask | signFlags; + return; } } } + // Have to scale by a bunch. Move the number to a buffer + // where it has room to grow as it's scaled. + // + bufNum.Low64 = low64; + bufNum.U2 = high; + // Scaling loop, up to 10^9 at a time. iHiProd stays updated // with index of highest non-zero ULONG. // for (; iScale > 0; iScale -= MaxInt32Scale) { - if (iScale > MaxInt32Scale) + if (iScale >= MaxInt32Scale) ulPwr = TenToPowerNine; else ulPwr = s_powers10[iScale]; - sdlTmp.High32 = 0; - for (iCur = 0; iCur <= iHiProd; iCur++) + tmp64 = 0; + uint* rgulNum = (uint*)&bufNum; + for (uint iCur = 0; ;) { - sdlTmp.int64 = UInt32x32To64(rgulNum[iCur], ulPwr) + sdlTmp.High32; - rgulNum[iCur] = sdlTmp.Low32; + Debug.Assert(iCur < bufNum.Length); + tmp64 += UInt32x32To64(rgulNum[iCur], ulPwr); + rgulNum[iCur] = (uint)tmp64; + iCur++; + tmp64 >>= 32; + if (iCur > iHiProd) + break; } - if (sdlTmp.High32 != 0) + if ((uint)tmp64 != 0) + { // We're extending the result by another ULONG. - rgulNum[++iHiProd] = sdlTmp.High32; + Debug.Assert(iHiProd + 1 < bufNum.Length); + rgulNum[++iHiProd] = (uint)tmp64; + } } } // Scaling complete, do the add. Could be subtract if signs differ. // - sdlTmp.Low32 = rgulNum[0]; - sdlTmp.High32 = rgulNum[1]; + tmp64 = bufNum.Low64; + low64 = d2.Low64; + uint tmpHigh = bufNum.U2; + high = d2.High; if (bSign) { // Signs differ, subtract. // - result.Low64 = sdlTmp.int64 - d2.Low64; - result.High = rgulNum[2] - d2.High; + low64 = tmp64 - low64; + high = tmpHigh - high; // Propagate carry // - if (result.Low64 > sdlTmp.int64) + if (low64 > tmp64) { - result.High--; - if (result.High >= rgulNum[2]) - if (LongSub(ref result, ref iHiProd, rgulNum)) - { - d1 = result; - return false; - } + high--; + if (high < tmpHigh) + goto NoCarry; } - else if (result.High > rgulNum[2]) + else if (high <= tmpHigh) + goto NoCarry; + + // If rgulNum has more than 96 bits of precision, then we need to + // carry the subtraction into the higher bits. If it doesn't, + // then we subtracted in the wrong order and have to flip the + // sign of the result. + // + if (iHiProd <= 2) { - if (LongSub(ref result, ref iHiProd, rgulNum)) - { - d1 = result; - return false; - } + goto SignFlip; } + + uint* rgulNum = (uint*)&bufNum; + uint iCur = 3; + do + { + Debug.Assert(iCur < bufNum.Length); + } while (rgulNum[iCur++]-- == 0); + Debug.Assert(iHiProd < bufNum.Length); + if (rgulNum[iHiProd] == 0) + iHiProd--; } else { // Signs the same, add. // - result.Low64 = sdlTmp.int64 + d2.Low64; - result.High = rgulNum[2] + d2.High; + low64 += tmp64; + high += tmpHigh; // Propagate carry // - if (result.Low64 < sdlTmp.int64) + if (low64 < tmp64) { - result.High++; - if (result.High <= rgulNum[2]) - LongAdd(ref iHiProd, rgulNum); + high++; + if (high > tmpHigh) + goto NoCarry; } - else if (result.High < rgulNum[2]) + else if (high >= tmpHigh) + goto NoCarry; + + uint* rgulNum = (uint*)&bufNum; + uint iCur = 3; + do { - LongAdd(ref iHiProd, rgulNum); - } + Debug.Assert(iCur < bufNum.Length); + if (iHiProd < iCur) + { + rgulNum[iCur] = 1; + iHiProd = iCur; + break; + } + } while (++rgulNum[iCur++] == 0); } +NoCarry: if (iHiProd > 2) { - rgulNum[0] = result.Low; - rgulNum[1] = result.Mid; - rgulNum[2] = result.High; - int scale = ScaleResult(rgulNum, iHiProd, result.Scale); - if (scale == -1) - return true; - result.Scale = scale; - - result.Low = rgulNum[0]; - result.Mid = rgulNum[1]; - result.High = rgulNum[2]; - } - } - - d1 = result; - return false; - } - - private static void SignFlip(ref Decimal value) - { - value.Low64 = (ulong)-(long)value.Low64; - value.High = ~value.High; - if (value.Low64 == 0) - value.High++; - value.Sign ^= true; - } - - // Returns true if we overflowed - private static bool AlignedScale(ref Decimal value) - { - Split64 sdlTmp = new Split64(); - - // Divide the value by 10, dropping the scale factor. - // - if (value.Scale == 0) - return true; - value.Scale--; + bufNum.Low64 = low64; + bufNum.U2 = high; + int scale = ScaleResult(&bufNum, iHiProd, (byte)(flags >> ScaleShift)); + flags = (flags & ~ScaleMask) | ((uint)scale << ScaleShift); - sdlTmp.Low32 = value.High; - sdlTmp.High32 = 1; - sdlTmp.int64 = DivMod64by32(sdlTmp.int64, 10); - value.High = sdlTmp.Low32; - - sdlTmp.Low32 = value.Mid; - sdlTmp.int64 = DivMod64by32(sdlTmp.int64, 10); - value.Mid = sdlTmp.Low32; - - sdlTmp.Low32 = value.Low; - sdlTmp.int64 = DivMod64by32(sdlTmp.int64, 10); - value.Low = sdlTmp.Low32; + low64 = bufNum.Low64; + high = bufNum.U2; + } - // See if we need to round up. - // - if (sdlTmp.High32 >= 5 && (sdlTmp.High32 > 5 || (value.Low & 1) != 0)) - { - value.Low64 = value.Low64 + 1; - if (value.Low64 == 0) - value.High++; + goto ReturnResult; } - return false; - } - private static bool LongSub(ref Decimal value, ref int iHiProd, uint[] rgulNum) - { - // If rgulNum has more than 96 bits of precision, then we need to - // carry the subtraction into the higher bits. If it doesn't, - // then we subtracted in the wrong order and have to flip the - // sign of the result. - // - if (iHiProd <= 2) +SignFlip: { - SignFlip(ref value); - return true; + // Got negative result. Flip its sign. + flags ^= SignMask; + high = ~high; + low64 = (ulong)-(long)low64; + if (low64 == 0) + high++; + goto ReturnResult; } - int iCur = 3; - while (rgulNum[iCur++]-- == 0) - ; - if (rgulNum[iHiProd] == 0) - iHiProd--; - - return false; - } - - private static void LongAdd(ref int iHiProd, uint[] rgulNum) - { - int iCur = 3; - do +AlignedScale: { - if (iHiProd < iCur) + // The addition carried above 96 bits. + // Divide the value by 10, dropping the scale factor. + // + if ((flags & ScaleMask) == 0) + throw new OverflowException(SR.Overflow_Decimal); + flags -= 1 << ScaleShift; + + const uint den = 10; + ulong num = high + (1UL << 32); + high = (uint)(num / den); + num = ((num - high * den) << 32) + (low64 >> 32); + uint div = (uint)(num / den); + num = ((num - div * den) << 32) + (uint)low64; + low64 = div; + low64 <<= 32; + div = (uint)(num / den); + low64 += div; + div = (uint)num - div * den; + + // See if we need to round up. + // + if (div >= 5 && (div > 5 || (low64 & 1) != 0)) { - rgulNum[iCur] = 1; - iHiProd = iCur; - break; + if (++low64 == 0) + high++; } - } while (++rgulNum[iCur++] == 0); - } + goto ReturnResult; + } - // Returns true if we overflowed - private static bool AlignedAdd(ref Decimal value, ref Decimal d1, ref Decimal d2, bool bSign) - { - if (bSign) +AlignedAdd: { - // Signs differ - subtract - // - value.Low64 = d1.Low64 - d2.Low64; - value.High = d1.High - d2.High; - - // Propagate carry - // - if (value.Low64 > d1.Low64) - { - value.High--; - if (value.High >= d1.High) - SignFlip(ref value); - } - else if (value.High > d1.High) + ulong d1Low64 = low64; + uint d1High = high; + if (bSign) { - // Got negative result. Flip its sign. + // Signs differ - subtract // - SignFlip(ref value); - } - } - else - { - // Signs are the same - add - // - value.Low64 = d1.Low64 + d2.Low64; - value.High = d1.High + d2.High; + low64 = d1Low64 - d2.Low64; + high = d1High - d2.High; - // Propagate carry - // - if (value.Low64 < d1.Low64) - { - value.High++; - if (value.High <= d1.High) + // Propagate carry + // + if (low64 > d1Low64) { - if (AlignedScale(ref value)) - return true; + high--; + if (high >= d1High) + goto SignFlip; } + else if (high > d1High) + goto SignFlip; } - else if (value.High < d1.High) + else { - // The addition carried above 96 bits. Divide the result by 10, - // dropping the scale factor. - // - if (AlignedScale(ref value)) - return true; + // Signs are the same - add + // + low64 = d1Low64 + d2.Low64; + high = d1High + d2.High; + + // Propagate carry + // + if (low64 < d1Low64) + { + high++; + if (high <= d1High) + goto AlignedScale; + } + else if (high < d1High) + goto AlignedScale; } + goto ReturnResult; } - return false; - } - private static void RoundUp(uint[] rgulQuo, ref int iScale) - { - if (!Add32To96(rgulQuo, 1)) - { - if (iScale == 0) - throw new OverflowException(SR.Overflow_Decimal); - iScale--; - OverflowUnscale(rgulQuo, true); - } +ReturnResult: + d1.uflags = flags; + d1.High = high; + d1.Low64 = low64; + return; } // Returns the absolute value of the given Decimal. If d is @@ -1210,20 +1299,21 @@ namespace System * None. * ***********************************************************************/ - private static uint DecFixInt(ref Decimal input, ref Decimal result) + private static unsafe uint DecFixInt(ref Decimal input, ref Decimal result) { - uint[] tmpNum = new uint[3]; + Buf12 bufNum; + _ = &bufNum; // workaround for CS0165 uint remainder; uint power; int scale; if (input.Scale > 0) { - tmpNum[0] = input.ulo; - tmpNum[1] = input.umid; - tmpNum[2] = input.uhi; + bufNum.U0 = input.ulo; + bufNum.U1 = input.umid; + bufNum.U2 = input.uhi; scale = input.Scale; - result.Sign = input.Sign; + result.IsNegative = input.IsNegative; remainder = 0; do @@ -1233,13 +1323,13 @@ namespace System else power = s_powers10[scale]; - remainder |= Div96By32(tmpNum, power); + remainder |= Div96By32(ref bufNum, power); scale -= MaxInt32Scale; } while (scale > 0); - result.ulo = tmpNum[0]; - result.umid = tmpNum[1]; - result.uhi = tmpNum[2]; + result.ulo = bufNum.U0; + result.umid = bufNum.U1; + result.uhi = bufNum.U2; result.Scale = 0; return remainder; @@ -1265,13 +1355,13 @@ namespace System { if (pdecIn.High != 0 || (pdecIn.Mid >= 0x80000000U && - (pdecIn.Mid != 0x80000000U || pdecIn.Low != 0 || !pdecIn.Sign))) + (pdecIn.Mid != 0x80000000U || pdecIn.Low != 0 || !pdecIn.IsNegative))) throw new OverflowException(SR.Overflow_Currency); sdlTmp.Low32 = pdecIn.Low; sdlTmp.High32 = pdecIn.Mid; - if (pdecIn.Sign) + if (pdecIn.IsNegative) pcyOut = -(long)sdlTmp.int64; else pcyOut = (long)sdlTmp.int64; @@ -1378,10 +1468,10 @@ namespace System } if (sdlTmp.High32 >= 0x80000000U && - (sdlTmp.int64 != 0x8000000000000000LU || !pdecIn.Sign)) + (sdlTmp.int64 != 0x8000000000000000LU || !pdecIn.IsNegative)) throw new OverflowException(SR.Overflow_Currency); - if (pdecIn.Sign) + if (pdecIn.IsNegative) sdlTmp.int64 = (ulong)(-(long)sdlTmp.int64); pcyOut = (long)sdlTmp.int64; @@ -1392,101 +1482,120 @@ namespace System //********************************************************************** internal static int VarDecCmp(ref Decimal pdecL, ref Decimal pdecR) { - int signLeft = 0; - int signRight = 0; + if ((pdecR.Low | pdecR.Mid | pdecR.High) == 0) + { + if ((pdecL.Low | pdecL.Mid | pdecL.High) == 0) + return 0; + return (pdecL.flags >> 31) | 1; + } + if ((pdecL.Low | pdecL.Mid | pdecL.High) == 0) + return -((pdecR.flags >> 31) | 1); + + int sign = (pdecL.flags >> 31) - (pdecR.flags >> 31); + if (sign != 0) + return sign; + return VarDecCmpSub(ref pdecL, ref pdecR); + } - if (pdecL.Low != 0 || pdecL.Mid != 0 || pdecL.High != 0) - signLeft = pdecL.Sign ? -1 : 1; + private static int VarDecCmpSub(ref Decimal d1, ref Decimal d2) + { + int flags = d2.flags; + int sign = (flags >> 31) | 1; + int iScale = flags - d1.flags; - if (pdecR.Low != 0 || pdecR.Mid != 0 || pdecR.High != 0) - signRight = pdecR.Sign ? -1 : 1; + ulong low64 = d1.Low64; + uint high = d1.High; - if (signLeft == signRight) + if (iScale != 0) { - if (signLeft == 0) // both are zero - return 0; // return equal + iScale >>= ScaleShift; - Decimal decLAndResult = pdecL; // Copy the left and pass that to AddSub because it gets mutated. - DecAddSub(ref decLAndResult, ref pdecR, true); // Call DecAddSub instead of VarDecSub to avoid exceptions - if (decLAndResult.Low == 0 && decLAndResult.Mid == 0 && decLAndResult.High == 0) - return 0; - if (decLAndResult.Sign) - return -1; - return 1; + // Scale factors are not equal. Assume that a larger scale factor (more decimal places) is likely to mean that number is smaller. + // Start by guessing that the right operand has the larger scale factor. + if (iScale < 0) + { + // Guessed scale factor wrong. Swap operands. + iScale = -iScale; + sign = -sign; + low64 = d2.Low64; + high = d2.High; + d2 = d1; + } + + // d1 will need to be multiplied by 10^iScale so it will have the same scale as d2. + // Scaling loop, up to 10^9 at a time. + do + { + uint ulPwr = iScale >= MaxInt32Scale ? TenToPowerNine : s_powers10[iScale]; + ulong tmpLow = UInt32x32To64((uint)low64, ulPwr); + ulong tmp = (low64 >> 32) * ulPwr + (tmpLow >> 32); + low64 = (uint)tmpLow + (tmp << 32); + tmp >>= 32; + tmp += UInt32x32To64(high, ulPwr); + // If the scaled value has more than 96 significant bits then it's greater than d2 + if (tmp > uint.MaxValue) + return sign; + high = (uint)tmp; + } while ((iScale -= MaxInt32Scale) > 0); } - // Signs are different. Used signed byte compares - // - if (signLeft > signRight) - return 1; - return -1; + uint cmpHigh = high - d2.High; + if (cmpHigh != 0) + { + // check for overflow + if (cmpHigh > high) + sign = -sign; + return sign; + } + + ulong cmpLow64 = low64 - d2.Low64; + if (cmpLow64 == 0) + sign = 0; + // check for overflow + else if (cmpLow64 > low64) + sign = -sign; + return sign; } //********************************************************************** // VarDecMul - Decimal Multiply //********************************************************************** - internal static void VarDecMul(ref Decimal pdecL, ref Decimal pdecR, out Decimal pdecRes) + internal static unsafe void VarDecMul(ref Decimal pdecL, ref Decimal pdecR) { - Split64 sdlTmp = new Split64(); - Split64 sdlTmp2 = new Split64(); - Split64 sdlTmp3 = new Split64(); - int iScale; - int iHiProd; - uint ulPwr; - uint ulRemLo; - uint ulRemHi; - uint[] rgulProd = new uint[6]; - - pdecRes = new Decimal(); - iScale = pdecL.Scale + pdecR.Scale; + int iScale = (byte)(pdecL.uflags + pdecR.uflags >> ScaleShift); if ((pdecL.High | pdecL.Mid | pdecR.High | pdecR.Mid) == 0) { // Upper 64 bits are zero. // - sdlTmp.int64 = UInt32x32To64(pdecL.Low, pdecR.Low); + ulong low64 = UInt32x32To64(pdecL.Low, pdecR.Low); if (iScale > DEC_SCALE_MAX) { // Result iScale is too big. Divide result by power of 10 to reduce it. // If the amount to divide by is > 19 the result is guaranteed // less than 1/2. [max value in 64 bits = 1.84E19] // - iScale -= DEC_SCALE_MAX; - if (iScale > 19) - { - //DECIMAL_SETZERO(*pdecRes); - return; - } - if (iScale > MaxInt32Scale) - { - // Divide by 1E10 first, to get the power down to a 32-bit quantity. - // 1E10 itself doesn't fit in 32 bits, so we'll divide by 2.5E9 now - // then multiply the next divisor by 4 (which will be a max of 4E9). - // - ulRemLo = FullDiv64By32(ref sdlTmp.int64, TenToPowerTenDiv4); - ulPwr = s_powers10[iScale - 10] << 2; - } - else - { - ulPwr = s_powers10[iScale]; - ulRemLo = 0; - } + iScale -= DEC_SCALE_MAX + 1; + if (iScale >= MaxInt64Scale) + goto ReturnZero; - // Power to divide by fits in 32 bits. - // - ulRemHi = FullDiv64By32(ref sdlTmp.int64, ulPwr); + ulong ulPwr = s_ulongPowers10[iScale]; + + // TODO: https://github.com/dotnet/coreclr/issues/3439 + ulong div = low64 / ulPwr; + ulong remainder = low64 - div * ulPwr; + low64 = div; // Round result. See if remainder >= 1/2 of divisor. // Divisor is a power of 10, so it is always even. // ulPwr >>= 1; - if (ulRemHi >= ulPwr && (ulRemHi > ulPwr || (ulRemLo | (sdlTmp.Low32 & 1)) > 0)) - sdlTmp.int64++; + if (remainder >= ulPwr && (remainder > ulPwr || (low64 & 1) > 0)) + low64++; iScale = DEC_SCALE_MAX; } - pdecRes.Low64 = sdlTmp.int64; - pdecRes.High = 0; + pdecL.Low64 = low64; } else { @@ -1511,87 +1620,93 @@ namespace System // ------------------------------ // [p-5][p-4][p-3][p-2][p-1][p-0] prod[] array // - sdlTmp.int64 = UInt32x32To64(pdecL.Low, pdecR.Low); - rgulProd[0] = sdlTmp.Low32; + uint iHiProd; + Buf24 bufProd; + _ = &bufProd; // workaround for CS0165 - sdlTmp2.int64 = UInt32x32To64(pdecL.Low, pdecR.Mid) + sdlTmp.High32; + ulong tmp = UInt32x32To64(pdecL.Low, pdecR.Low); + bufProd.U0 = (uint)tmp; - sdlTmp.int64 = UInt32x32To64(pdecL.Mid, pdecR.Low); - sdlTmp.int64 += sdlTmp2.int64; // this could generate carry - rgulProd[1] = sdlTmp.Low32; - if (sdlTmp.int64 < sdlTmp2.int64) // detect carry - sdlTmp2.High32 = 1; + ulong tmp2 = UInt32x32To64(pdecL.Low, pdecR.Mid) + (tmp >> 32); + + tmp = UInt32x32To64(pdecL.Mid, pdecR.Low); + tmp += tmp2; // this could generate carry + bufProd.U1 = (uint)tmp; + if (tmp < tmp2) // detect carry + tmp2 = 1UL << 32; else - sdlTmp2.High32 = 0; - sdlTmp2.Low32 = sdlTmp.High32; + tmp2 = 0; + tmp2 += tmp >> 32; - sdlTmp.int64 = UInt32x32To64(pdecL.Mid, pdecR.Mid) + sdlTmp2.int64; + tmp = UInt32x32To64(pdecL.Mid, pdecR.Mid) + tmp2; if ((pdecL.High | pdecR.High) > 0) { // Highest 32 bits is non-zero. Calculate 5 more partial products. // - sdlTmp2.int64 = UInt32x32To64(pdecL.Low, pdecR.High); - sdlTmp.int64 += sdlTmp2.int64; // this could generate carry - if (sdlTmp.int64 < sdlTmp2.int64) // detect carry - sdlTmp3.High32 = 1; - else - sdlTmp3.High32 = 0; - - sdlTmp2.int64 = UInt32x32To64(pdecL.High, pdecR.Low); - sdlTmp.int64 += sdlTmp2.int64; // this could generate carry - rgulProd[2] = sdlTmp.Low32; - if (sdlTmp.int64 < sdlTmp2.int64) // detect carry - sdlTmp3.High32++; - sdlTmp3.Low32 = sdlTmp.High32; - - sdlTmp.int64 = UInt32x32To64(pdecL.Mid, pdecR.High); - sdlTmp.int64 += sdlTmp3.int64; // this could generate carry - if (sdlTmp.int64 < sdlTmp3.int64) // detect carry - sdlTmp3.High32 = 1; - else - sdlTmp3.High32 = 0; - - sdlTmp2.int64 = UInt32x32To64(pdecL.High, pdecR.Mid); - sdlTmp.int64 += sdlTmp2.int64; // this could generate carry - rgulProd[3] = sdlTmp.Low32; - if (sdlTmp.int64 < sdlTmp2.int64) // detect carry - sdlTmp3.High32++; - sdlTmp3.Low32 = sdlTmp.High32; - - sdlTmp.int64 = UInt32x32To64(pdecL.High, pdecR.High) + sdlTmp3.int64; - rgulProd[4] = sdlTmp.Low32; - rgulProd[5] = sdlTmp.High32; + tmp2 = UInt32x32To64(pdecL.Low, pdecR.High); + tmp += tmp2; // this could generate carry + ulong tmp3 = 0; + if (tmp < tmp2) // detect carry + tmp3 = 1UL << 32; + + tmp2 = UInt32x32To64(pdecL.High, pdecR.Low); + tmp += tmp2; // this could generate carry + bufProd.U2 = (uint)tmp; + if (tmp < tmp2) // detect carry + tmp3 += 1UL << 32; + tmp2 = tmp3 + (tmp >> 32); + + tmp = UInt32x32To64(pdecL.Mid, pdecR.High); + tmp += tmp2; // this could generate carry + tmp3 = 0; + if (tmp < tmp2) // detect carry + tmp3 = 1UL << 32; + + tmp2 = UInt32x32To64(pdecL.High, pdecR.Mid); + tmp += tmp2; // this could generate carry + bufProd.U3 = (uint)tmp; + if (tmp < tmp2) // detect carry + tmp3 += 1UL << 32; + tmp3 += tmp >> 32; + + tmp = UInt32x32To64(pdecL.High, pdecR.High) + tmp3; + bufProd.High64 = tmp; iHiProd = 5; } - else + else if (tmp != 0) { - rgulProd[2] = sdlTmp.Low32; - rgulProd[3] = sdlTmp.High32; + bufProd.Mid64 = tmp; iHiProd = 3; } + else + iHiProd = 1; // Check for leading zero ULONGs on the product // + uint* rgulProd = (uint*)&bufProd; while (rgulProd[iHiProd] == 0) { + if (iHiProd == 0) + goto ReturnZero; iHiProd--; - if (iHiProd < 0) - return; } - iScale = ScaleResult(rgulProd, iHiProd, iScale); - if (iScale == -1) - throw new OverflowException(SR.Overflow_Decimal); + if (iHiProd > 2 || iScale > DEC_SCALE_MAX) + { + iScale = ScaleResult(&bufProd, iHiProd, iScale); + } - pdecRes.Low = rgulProd[0]; - pdecRes.Mid = rgulProd[1]; - pdecRes.High = rgulProd[2]; + pdecL.Low64 = bufProd.Low64; + pdecL.High = bufProd.U2; } - pdecRes.Sign = pdecR.Sign ^ pdecL.Sign; - pdecRes.Scale = (char)iScale; + pdecL.uflags = ((pdecR.uflags ^ pdecL.uflags) & SignMask) | ((uint)iScale << ScaleShift); + return; + +ReturnZero: + pdecL = default(Decimal); } //********************************************************************** @@ -1743,7 +1858,7 @@ namespace System pdecOut.Scale = iPower; } - pdecOut.Sign = input < 0; + pdecOut.IsNegative = input < 0; } //********************************************************************** @@ -1904,7 +2019,7 @@ namespace System pdecOut.Low64 = sdlMant.int64; } - pdecOut.Sign = input < 0; + pdecOut.IsNegative = input < 0; } //********************************************************************** @@ -1923,7 +2038,7 @@ namespace System double dbl = ((double)pdecIn.Low64 + (double)pdecIn.High * ds2to64) / GetDoublePower10(pdecIn.Scale); - if (pdecIn.Sign) + if (pdecIn.IsNegative) dbl = -dbl; return dbl; @@ -1933,56 +2048,45 @@ namespace System // of the operation internal static void VarDecAdd(ref Decimal d1, ref Decimal d2) { - if (DecAddSub(ref d1, ref d2, false)) - throw new OverflowException(SR.Overflow_Decimal); + DecAddSub(ref d1, ref d2, false); } // VarDecSub divides two decimal values. On return, d1 contains the result // of the operation. internal static void VarDecSub(ref Decimal d1, ref Decimal d2) { - if (DecAddSub(ref d1, ref d2, true)) - throw new OverflowException(SR.Overflow_Decimal); + DecAddSub(ref d1, ref d2, true); } // VarDecDiv divides two decimal values. On return, d1 contains the result // of the operation. - internal static void VarDecDiv(ref Decimal d1, ref Decimal d2) + internal static unsafe void VarDecDiv(ref Decimal d1, ref Decimal d2) { - uint[] rgulQuo = new uint[3]; - uint[] rgulQuoSave = new uint[3]; - uint[] rgulRem = new uint[4]; - uint[] rgulDivisor = new uint[3]; + Buf12 bufQuo, bufDivisor; + _ = &bufQuo; // workaround for CS0165 + _ = &bufDivisor; // workaround for CS0165 uint ulPwr; - uint ulTmp; - uint ulTmp1; - Split64 sdlTmp = new Split64(); - Split64 sdlDivisor = new Split64(); - int iScale; int iCurScale; - bool fUnscale; - iScale = d1.Scale - d2.Scale; - fUnscale = false; - rgulDivisor[0] = d2.Low; - rgulDivisor[1] = d2.Mid; - rgulDivisor[2] = d2.High; + int iScale = (sbyte)(d1.uflags - d2.uflags >> ScaleShift); + bool fUnscale = false; + uint ulTmp; - if (rgulDivisor[1] == 0 && rgulDivisor[2] == 0) + if (d2.High == 0 && d2.Mid == 0) { // Divisor is only 32 bits. Easy divide. // - if (rgulDivisor[0] == 0) + uint den = d2.Low; + if (den == 0) throw new DivideByZeroException(SR.Overflow_Decimal); - rgulQuo[0] = d1.Low; - rgulQuo[1] = d1.Mid; - rgulQuo[2] = d1.High; - rgulRem[0] = Div96By32(rgulQuo, rgulDivisor[0]); + bufQuo.Low64 = d1.Low64; + bufQuo.U2 = d1.High; + uint remainder = Div96By32(ref bufQuo, den); for (;;) { - if (rgulRem[0] == 0) + if (remainder == 0) { if (iScale < 0) { @@ -2012,38 +2116,32 @@ namespace System // is the largest value in rgulQuo[1] (when rgulQuo[2] == 4) that is // assured not to overflow. // - iCurScale = SearchScale(rgulQuo[2], rgulQuo[1], rgulQuo[0], iScale); - if (iCurScale == 0) + if (iScale == DEC_SCALE_MAX || (iCurScale = SearchScale(ref bufQuo, iScale)) == 0) { // No more scaling to be done, but remainder is non-zero. // Round quotient. // - ulTmp = rgulRem[0] << 1; - if (ulTmp < rgulRem[0] || (ulTmp >= rgulDivisor[0] && - (ulTmp > rgulDivisor[0] || (rgulQuo[0] & 1) != 0))) - RoundUp(rgulQuo, ref iScale); + ulTmp = remainder << 1; + if (ulTmp < remainder || ulTmp >= den && (ulTmp > den || (bufQuo.U0 & 1) != 0)) + goto RoundUp; break; } - if (iCurScale < 0) - throw new OverflowException(SR.Overflow_Decimal); - HaveScale: ulPwr = s_powers10[iCurScale]; iScale += iCurScale; - if (IncreaseScale(rgulQuo, ulPwr) != 0) - throw new OverflowException(SR.Overflow_Decimal); + if (IncreaseScale(ref bufQuo, ulPwr) != 0) + goto ThrowOverflow; - sdlTmp.int64 = DivMod64by32(UInt32x32To64(rgulRem[0], ulPwr), rgulDivisor[0]); - rgulRem[0] = sdlTmp.High32; + ulong num = UInt32x32To64(remainder, ulPwr); + // TODO: https://github.com/dotnet/coreclr/issues/3439 + uint div = (uint)(num / den); + remainder = (uint)num - div * den; - if (!Add32To96(rgulQuo, sdlTmp.Low32)) + if (!Add32To96(ref bufQuo, div)) { - if (iScale == 0) - throw new OverflowException(SR.Overflow_Decimal); - iScale--; - OverflowUnscale(rgulQuo, (rgulRem[0] != 0)); + iScale = OverflowUnscale(ref bufQuo, iScale, remainder != 0); break; } } // for (;;) @@ -2057,68 +2155,56 @@ namespace System // normalize by. The dividend will be shifted by the same amount so // the quotient is not changed. // - if (rgulDivisor[2] == 0) - ulTmp = rgulDivisor[1]; - else - ulTmp = rgulDivisor[2]; + bufDivisor.Low64 = d2.Low64; + ulTmp = d2.High; + bufDivisor.U2 = ulTmp; + if (ulTmp == 0) + ulTmp = d2.Mid; - iCurScale = 0; + iCurScale = 1; if ((ulTmp & 0xFFFF0000) == 0) { - iCurScale += 16; ulTmp <<= 16; + iCurScale += 16; } if ((ulTmp & 0xFF000000) == 0) { - iCurScale += 8; ulTmp <<= 8; + iCurScale += 8; } if ((ulTmp & 0xF0000000) == 0) { - iCurScale += 4; ulTmp <<= 4; + iCurScale += 4; } if ((ulTmp & 0xC0000000) == 0) { - iCurScale += 2; ulTmp <<= 2; + iCurScale += 2; } - if ((ulTmp & 0x80000000) == 0) - { - iCurScale++; - ulTmp <<= 1; - } + iCurScale += (int)ulTmp >> 31; // Shift both dividend and divisor left by iCurScale. // - sdlTmp.int64 = d1.Low64 << iCurScale; - rgulRem[0] = sdlTmp.Low32; - rgulRem[1] = sdlTmp.High32; - sdlTmp.Low32 = d1.Mid; - sdlTmp.High32 = d1.High; - sdlTmp.int64 <<= iCurScale; - rgulRem[2] = sdlTmp.High32; - rgulRem[3] = (d1.High >> (31 - iCurScale)) >> 1; - - sdlDivisor.Low32 = rgulDivisor[0]; - sdlDivisor.High32 = rgulDivisor[1]; - sdlDivisor.int64 <<= iCurScale; - - if (rgulDivisor[2] == 0) + Buf16 bufRem; + _ = &bufRem; // workaround for CS0165 + bufRem.Low64 = d1.Low64 << iCurScale; + bufRem.High64 = (d1.Mid + ((ulong)d1.High << 32)) >> (31 - iCurScale) >> 1; + + ulong divisor = bufDivisor.Low64 << iCurScale; + + if (bufDivisor.U2 == 0) { // Have a 64-bit divisor in sdlDivisor. The remainder // (currently 96 bits spread over 4 ULONGs) will be < divisor. // - sdlTmp.Low32 = rgulRem[2]; - sdlTmp.High32 = rgulRem[3]; - rgulQuo[2] = 0; - rgulQuo[1] = Div96By64(new ArraySegment<uint>(rgulRem, 1, 3), sdlDivisor); - rgulQuo[0] = Div96By64(rgulRem, sdlDivisor); + bufQuo.U1 = Div96By64(ref *(Buf12*)&bufRem.U1, divisor); + bufQuo.U0 = Div96By64(ref *(Buf12*)&bufRem, divisor); for (;;) { - if ((rgulRem[0] | rgulRem[1]) == 0) + if (bufRem.Low64 == 0) { if (iScale < 0) { @@ -2134,39 +2220,30 @@ namespace System // Remainder is non-zero. Scale up quotient and remainder by // powers of 10 so we can compute more significant bits. // - iCurScale = SearchScale(rgulQuo[2], rgulQuo[1], rgulQuo[0], iScale); - if (iCurScale == 0) + if (iScale == DEC_SCALE_MAX || (iCurScale = SearchScale(ref bufQuo, iScale)) == 0) { // No more scaling to be done, but remainder is non-zero. // Round quotient. // - sdlTmp.Low32 = rgulRem[0]; - sdlTmp.High32 = rgulRem[1]; - if (sdlTmp.High32 >= 0x80000000 || (sdlTmp.int64 <<= 1) > sdlDivisor.int64 || - (sdlTmp.int64 == sdlDivisor.int64 && (rgulQuo[0] & 1) != 0)) - RoundUp(rgulQuo, ref iScale); + ulong tmp = bufRem.Low64; + if ((long)tmp < 0 || (tmp <<= 1) > divisor || + (tmp == divisor && (bufQuo.U0 & 1) != 0)) + goto RoundUp; break; } - if (iCurScale < 0) - throw new OverflowException(SR.Overflow_Decimal); - HaveScale64: ulPwr = s_powers10[iCurScale]; iScale += iCurScale; - if (IncreaseScale(rgulQuo, ulPwr) != 0) - throw new OverflowException(SR.Overflow_Decimal); + if (IncreaseScale(ref bufQuo, ulPwr) != 0) + goto ThrowOverflow; - rgulRem[2] = 0; // rem is 64 bits, IncreaseScale uses 96 - IncreaseScale(rgulRem, ulPwr); - ulTmp = Div96By64(rgulRem, sdlDivisor); - if (!Add32To96(rgulQuo, ulTmp)) + IncreaseScale64(ref *(Buf12*)&bufRem, ulPwr); + ulTmp = Div96By64(ref *(Buf12*)&bufRem, divisor); + if (!Add32To96(ref bufQuo, ulTmp)) { - if (iScale == 0) - throw new OverflowException(SR.Overflow_Decimal); - iScale--; - OverflowUnscale(rgulQuo, (rgulRem[0] != 0 || rgulRem[1] != 0)); + iScale = OverflowUnscale(ref bufQuo, iScale, bufRem.Low64 != 0); break; } } // for (;;) @@ -2177,23 +2254,18 @@ namespace System // // Start by finishing the shift left by iCurScale. // - sdlTmp.Low32 = rgulDivisor[1]; - sdlTmp.High32 = rgulDivisor[2]; - sdlTmp.int64 <<= iCurScale; - rgulDivisor[0] = sdlDivisor.Low32; - rgulDivisor[1] = sdlDivisor.High32; - rgulDivisor[2] = sdlTmp.High32; + uint tmp = (uint)(bufDivisor.High64 >> (31 - iCurScale) >> 1); + bufDivisor.Low64 = divisor; + bufDivisor.U2 = tmp; // The remainder (currently 96 bits spread over 4 ULONGs) // will be < divisor. // - rgulQuo[2] = 0; - rgulQuo[1] = 0; - rgulQuo[0] = Div128By96(rgulRem, rgulDivisor); + bufQuo.Low64 = Div128By96(ref bufRem, ref bufDivisor); for (;;) { - if ((rgulRem[0] | rgulRem[1] | rgulRem[2]) == 0) + if ((bufRem.Low64 | bufRem.U2) == 0) { if (iScale < 0) { @@ -2209,56 +2281,48 @@ namespace System // Remainder is non-zero. Scale up quotient and remainder by // powers of 10 so we can compute more significant bits. // - iCurScale = SearchScale(rgulQuo[2], rgulQuo[1], rgulQuo[0], iScale); - if (iCurScale == 0) + if (iScale == DEC_SCALE_MAX || (iCurScale = SearchScale(ref bufQuo, iScale)) == 0) { // No more scaling to be done, but remainder is non-zero. // Round quotient. // - if (rgulRem[2] >= 0x80000000) + if ((int)bufRem.U2 < 0) { - RoundUp(rgulQuo, ref iScale); - break; + goto RoundUp; } - ulTmp = (rgulRem[0] > 0x80000000) ? 1u : 0u; - ulTmp1 = (rgulRem[1] > 0x80000000) ? 1u : 0u; - rgulRem[0] <<= 1; - rgulRem[1] = (rgulRem[1] << 1) + ulTmp; - rgulRem[2] = (rgulRem[2] << 1) + ulTmp1; - - if (rgulRem[2] > rgulDivisor[2] || rgulRem[2] == rgulDivisor[2] && - (rgulRem[1] > rgulDivisor[1] || rgulRem[1] == rgulDivisor[1] && - (rgulRem[0] > rgulDivisor[0] || rgulRem[0] == rgulDivisor[0] && - (rgulQuo[0] & 1) != 0))) - RoundUp(rgulQuo, ref iScale); + ulTmp = bufRem.U1 >> 31; + bufRem.Low64 <<= 1; + bufRem.U2 = (bufRem.U2 << 1) + ulTmp; + + if (bufRem.U2 > bufDivisor.U2 || bufRem.U2 == bufDivisor.U2 && + (bufRem.Low64 > bufDivisor.Low64 || bufRem.Low64 == bufDivisor.Low64 && + (bufQuo.U0 & 1) != 0)) + goto RoundUp; break; } - if (iCurScale < 0) - throw new OverflowException(SR.Overflow_Decimal); - HaveScale96: ulPwr = s_powers10[iCurScale]; iScale += iCurScale; - if (IncreaseScale(rgulQuo, ulPwr) != 0) - throw new OverflowException(SR.Overflow_Decimal); + if (IncreaseScale(ref bufQuo, ulPwr) != 0) + goto ThrowOverflow; - rgulRem[3] = IncreaseScale(rgulRem, ulPwr); - ulTmp = Div128By96(rgulRem, rgulDivisor); - if (!Add32To96(rgulQuo, ulTmp)) + bufRem.U3 = IncreaseScale(ref *(Buf12*)&bufRem, ulPwr); + ulTmp = Div128By96(ref bufRem, ref bufDivisor); + if (!Add32To96(ref bufQuo, ulTmp)) { - if (iScale == 0) - throw new OverflowException(SR.Overflow_Decimal); - iScale--; - OverflowUnscale(rgulQuo, (rgulRem[0] != 0 || rgulRem[1] != 0 || rgulRem[2] != 0 || rgulRem[3] != 0)); + iScale = OverflowUnscale(ref bufQuo, iScale, (bufRem.Low64 | bufRem.High64) != 0); break; } } // for (;;) } } +Unscale: + ulong low64 = bufQuo.Low64; + uint high = bufQuo.U2; // We need to unscale if and only if we have a non-zero remainder if (fUnscale) { @@ -2272,74 +2336,79 @@ namespace System // we can extract. We use this as a quick test on whether to try a // given power. // - while ((rgulQuo[0] & 0xFF) == 0 && iScale >= 8) + while (((uint)low64 & 0xFF) == 0 && iScale >= 8) { - rgulQuoSave[0] = rgulQuo[0]; - rgulQuoSave[1] = rgulQuo[1]; - rgulQuoSave[2] = rgulQuo[2]; - - if (Div96By32(rgulQuoSave, 100000000) == 0) + if (Div96ByConst100000000(ref bufQuo) == 0) { - rgulQuo[0] = rgulQuoSave[0]; - rgulQuo[1] = rgulQuoSave[1]; - rgulQuo[2] = rgulQuoSave[2]; + low64 = bufQuo.Low64; + high = bufQuo.U2; iScale -= 8; } else + { + bufQuo.Low64 = low64; + bufQuo.U2 = high; break; + } } - if ((rgulQuo[0] & 0xF) == 0 && iScale >= 4) + if (((uint)low64 & 0xF) == 0 && iScale >= 4) { - rgulQuoSave[0] = rgulQuo[0]; - rgulQuoSave[1] = rgulQuo[1]; - rgulQuoSave[2] = rgulQuo[2]; - - if (Div96By32(rgulQuoSave, 10000) == 0) + if (Div96ByConst10000(ref bufQuo) == 0) { - rgulQuo[0] = rgulQuoSave[0]; - rgulQuo[1] = rgulQuoSave[1]; - rgulQuo[2] = rgulQuoSave[2]; + low64 = bufQuo.Low64; + high = bufQuo.U2; iScale -= 4; } + else + { + bufQuo.Low64 = low64; + bufQuo.U2 = high; + } } - if ((rgulQuo[0] & 3) == 0 && iScale >= 2) + if (((uint)low64 & 3) == 0 && iScale >= 2) { - rgulQuoSave[0] = rgulQuo[0]; - rgulQuoSave[1] = rgulQuo[1]; - rgulQuoSave[2] = rgulQuo[2]; - - if (Div96By32(rgulQuoSave, 100) == 0) + if (Div96ByConst100(ref bufQuo) == 0) { - rgulQuo[0] = rgulQuoSave[0]; - rgulQuo[1] = rgulQuoSave[1]; - rgulQuo[2] = rgulQuoSave[2]; + low64 = bufQuo.Low64; + high = bufQuo.U2; iScale -= 2; } + else + { + bufQuo.Low64 = low64; + bufQuo.U2 = high; + } } - if ((rgulQuo[0] & 1) == 0 && iScale >= 1) + if (((uint)low64 & 1) == 0 && iScale >= 1 && Div96ByConst10(ref bufQuo) == 0) { - rgulQuoSave[0] = rgulQuo[0]; - rgulQuoSave[1] = rgulQuo[1]; - rgulQuoSave[2] = rgulQuo[2]; + low64 = bufQuo.Low64; + high = bufQuo.U2; + iScale -= 1; + } + } - if (Div96By32(rgulQuoSave, 10) == 0) + d1.uflags = ((d1.uflags ^ d2.uflags) & SignMask) | ((uint)iScale << ScaleShift); + d1.High = high; + d1.Low64 = low64; + return; + +RoundUp: + { + if (++bufQuo.Low64 == 0) + { + if (++bufQuo.U2 == 0) { - rgulQuo[0] = rgulQuoSave[0]; - rgulQuo[1] = rgulQuoSave[1]; - rgulQuo[2] = rgulQuoSave[2]; - iScale -= 1; + iScale = OverflowUnscale(ref bufQuo, iScale, true); } } + goto Unscale; } - d1.Sign = d1.Sign ^ d2.Sign; - d1.High = rgulQuo[2]; - d1.Mid = rgulQuo[1]; - d1.Low = rgulQuo[0]; - d1.Scale = iScale; +ThrowOverflow: + throw new OverflowException(SR.Overflow_Decimal); } //********************************************************************** @@ -2349,7 +2418,7 @@ namespace System { Decimal result = new Decimal(); - if (DecCalc.DecFixInt(ref d, ref result) != 0 && result.Sign) + if (DecCalc.DecFixInt(ref d, ref result) != 0 && result.IsNegative) // We have chopped off a non-zero amount from a negative value. Since // we round toward -infinity, we must increase the integer result by // 1 to make it more negative. This will never overflow because @@ -2375,9 +2444,10 @@ namespace System //********************************************************************** // VarDecRound - Decimal Round //********************************************************************** - internal static void VarDecRound(ref Decimal input, int decimals, ref Decimal result) + internal static unsafe void VarDecRound(ref Decimal input, int decimals, ref Decimal result) { - uint[] tmpNum = new uint[3]; + Buf12 bufNum; + _ = &bufNum; // workaround for CS0165 uint remainder; uint sticky; uint power; @@ -2388,10 +2458,10 @@ namespace System scale = input.Scale - decimals; if (scale > 0) { - tmpNum[0] = input.ulo; - tmpNum[1] = input.umid; - tmpNum[2] = input.uhi; - result.Sign = input.Sign; + bufNum.U0 = input.ulo; + bufNum.U1 = input.umid; + bufNum.U2 = input.uhi; + result.IsNegative = input.IsNegative; remainder = sticky = 0; do @@ -2402,23 +2472,23 @@ namespace System else power = s_powers10[scale]; - remainder = Div96By32(tmpNum, power); + remainder = Div96By32(ref bufNum, power); scale -= MaxInt32Scale; } while (scale > 0); // Now round. ulRem has last remainder, ulSticky has sticky bits. // To do IEEE rounding, we add LSB of result to sticky bits so // either causes round up if remainder * 2 == last divisor. - sticky |= tmpNum[0] & 1; + sticky |= bufNum.U0 & 1; remainder = (remainder << 1) + (uint)(sticky != 0 ? 1 : 0); if (power < remainder - && ++tmpNum[0] == 0 - && ++tmpNum[1] == 0) - ++tmpNum[2]; + && ++bufNum.U0 == 0 + && ++bufNum.U1 == 0) + ++bufNum.U2; - result.ulo = tmpNum[0]; - result.umid = tmpNum[1]; - result.uhi = tmpNum[2]; + result.ulo = bufNum.U0; + result.umid = bufNum.U1; + result.uhi = bufNum.U2; result.Scale = decimals; return; } @@ -2651,46 +2721,174 @@ namespace System } } - private static class PowerOvfl + struct PowerOvfl { - private static uint[] s_powerOvfl = + public readonly uint Hi; + public readonly ulong MidLo; + + public PowerOvfl(uint hi, uint mid, uint lo) { - // This is a table of the largest values that can be in the upper two - // ULONGs of a 96-bit number that will not overflow when multiplied - // by a given power. For the upper word, this is a table of - // 2^32 / 10^n for 1 <= n <= 9. For the lower word, this is the - // remaining fraction part * 2^32. 2^32 = 4294967296. - // - // Table logically consists of three components for each entry (high, - // mid and low) but we declare it as a flat array of uints since that's - // all C# will support. We hide this via the accessor methods on this - // class. - // - 429496729, 2576980377, 2576980377, // 10^1 remainder 0.6 - 42949672, 4123168604, 687194767, // 10^2 remainder 0.16 - 4294967, 1271310319, 2645699854, // 10^3 remainder 0.616 - 429496, 3133608139, 694066715, // 10^4 remainder 0.1616 - 42949, 2890341191, 2216890319, // 10^5 remainder 0.51616 - 4294, 4154504685, 2369172679, // 10^6 remainder 0.551616 - 429, 2133437386, 4102387834, // 10^7 remainder 0.9551616 - 42, 4078814305, 410238783, // 10^8 remainder 0.09991616 - 4, 1266874889, 3047500985, // 10^9 remainder 0.709551616 - }; + Hi = hi; + MidLo = ((ulong)mid << 32) + lo; + } + } - public static uint Hi(int index) + static readonly PowerOvfl[] PowerOvflValues = new[] + { + // This is a table of the largest values that can be in the upper two + // ULONGs of a 96-bit number that will not overflow when multiplied + // by a given power. For the upper word, this is a table of + // 2^32 / 10^n for 1 <= n <= 8. For the lower word, this is the + // remaining fraction part * 2^32. 2^32 = 4294967296. + // + new PowerOvfl(429496729, 2576980377, 2576980377), // 10^1 remainder 0.6 + new PowerOvfl(42949672, 4123168604, 687194767), // 10^2 remainder 0.16 + new PowerOvfl(4294967, 1271310319, 2645699854), // 10^3 remainder 0.616 + new PowerOvfl(429496, 3133608139, 694066715), // 10^4 remainder 0.1616 + new PowerOvfl(42949, 2890341191, 2216890319), // 10^5 remainder 0.51616 + new PowerOvfl(4294, 4154504685, 2369172679), // 10^6 remainder 0.551616 + new PowerOvfl(429, 2133437386, 4102387834), // 10^7 remainder 0.9551616 + new PowerOvfl(42, 4078814305, 410238783), // 10^8 remainder 0.09991616 + }; + + [StructLayout(LayoutKind.Explicit)] + private struct Buf12 + { + [FieldOffset(0 * 4)] + public uint U0; + [FieldOffset(1 * 4)] + public uint U1; + [FieldOffset(2 * 4)] + public uint U2; + + [FieldOffset(0)] + private ulong ulo64LE; + [FieldOffset(4)] + private ulong uhigh64LE; + + public ulong Low64 + { +#if BIGENDIAN + get => ((ulong)U1 << 32) | U0; + set { U1 = (uint)(value >> 32); U0 = (uint)value; } +#else + get => ulo64LE; + set => ulo64LE = value; +#endif + } + + /// <summary> + /// U1-U2 combined (overlaps with Low64) + /// </summary> + public ulong High64 + { +#if BIGENDIAN + get => ((ulong)U2 << 32) | U1; + set { U2 = (uint)(value >> 32); U1 = (uint)value; } +#else + get => uhigh64LE; + set => uhigh64LE = value; +#endif + } + } + + [StructLayout(LayoutKind.Explicit)] + private struct Buf16 + { + [FieldOffset(0 * 4)] + public uint U0; + [FieldOffset(1 * 4)] + public uint U1; + [FieldOffset(2 * 4)] + public uint U2; + [FieldOffset(3 * 4)] + public uint U3; + + [FieldOffset(0 * 8)] + private ulong ulo64LE; + [FieldOffset(1 * 8)] + private ulong uhigh64LE; + + public ulong Low64 { - return s_powerOvfl[index * 3]; +#if BIGENDIAN + get => ((ulong)U1 << 32) | U0; + set { U1 = (uint)(value >> 32); U0 = (uint)value; } +#else + get => ulo64LE; + set => ulo64LE = value; +#endif } - public static uint Mid(int index) + public ulong High64 { - return s_powerOvfl[(index * 3) + 1]; +#if BIGENDIAN + get => ((ulong)U3 << 32) | U2; + set { U3 = (uint)(value >> 32); U2 = (uint)value; } +#else + get => uhigh64LE; + set => uhigh64LE = value; +#endif } + } - public static uint Lo(int index) + [StructLayout(LayoutKind.Explicit)] + private struct Buf24 + { + [FieldOffset(0 * 4)] + public uint U0; + [FieldOffset(1 * 4)] + public uint U1; + [FieldOffset(2 * 4)] + public uint U2; + [FieldOffset(3 * 4)] + public uint U3; + [FieldOffset(4 * 4)] + public uint U4; + [FieldOffset(5 * 4)] + public uint U5; + + [FieldOffset(0 * 8)] + private ulong ulo64LE; + [FieldOffset(1 * 8)] + private ulong umid64LE; + [FieldOffset(2 * 8)] + private ulong uhigh64LE; + + public ulong Low64 { - return s_powerOvfl[(index * 3) + 2]; +#if BIGENDIAN + get => ((ulong)U1 << 32) | U0; + set { U1 = (uint)(value >> 32); U0 = (uint)value; } +#else + get => ulo64LE; + set => ulo64LE = value; +#endif } + + public ulong Mid64 + { +#if BIGENDIAN + get => ((ulong)U3 << 32) | U2; + set { U3 = (uint)(value >> 32); U2 = (uint)value; } +#else + get => umid64LE; + set => umid64LE = value; +#endif + } + + public ulong High64 + { +#if BIGENDIAN + get => ((ulong)U5 << 32) | U4; + set { U5 = (uint)(value >> 32); U4 = (uint)value; } +#else + get => uhigh64LE; + set => uhigh64LE = value; +#endif + } + + public int Length => 6; } } } diff --git a/src/System.Private.CoreLib/src/System/Decimal.cs b/src/System.Private.CoreLib/src/System/Decimal.cs index 930fe3ea8..2fc98da8c 100644 --- a/src/System.Private.CoreLib/src/System/Decimal.cs +++ b/src/System.Private.CoreLib/src/System/Decimal.cs @@ -123,13 +123,11 @@ namespace System [FieldOffset(12), NonSerialized] private uint umid; - // Constructs a zero Decimal. - //public Decimal() { - // lo = 0; - // mid = 0; - // hi = 0; - // flags = 0; - //} + /// <summary> + /// The low and mid fields combined in little-endian order + /// </summary> + [FieldOffset(8), NonSerialized] + private ulong ulomidLE; // Constructs a Decimal from an integer value. // @@ -179,8 +177,7 @@ namespace System uflags = SignMask; value_copy = -value_copy; } - ulo = (uint)value_copy; - umid = (uint)(value_copy >> 32); + Low64 = (ulong)value; uhi = 0; } @@ -190,8 +187,7 @@ namespace System public Decimal(ulong value) { uflags = 0; - ulo = (uint)value; - umid = (uint)(value >> 32); + Low64 = value; uhi = 0; } @@ -223,7 +219,7 @@ namespace System ulong absoluteCy; // has to be ulong to accommodate the case where cy == long.MinValue. if (cy < 0) { - d.Sign = true; + d.IsNegative = true; absoluteCy = (ulong)(-cy); } else @@ -280,10 +276,6 @@ namespace System // public Decimal(int[] bits) { - lo = 0; - mid = 0; - hi = 0; - flags = 0; SetBits(bits); } @@ -652,9 +644,8 @@ namespace System // public static Decimal Multiply(Decimal d1, Decimal d2) { - Decimal decRes; - DecCalc.VarDecMul(ref d1, ref d2, out decRes); - return decRes; + DecCalc.VarDecMul(ref d1, ref d2); + return d1; } // Returns the negated value of the given Decimal. If d is non-zero, @@ -717,6 +708,8 @@ namespace System return d; } + internal static int Sign(ref decimal d) => (d.lo | d.mid | d.hi) == 0 ? 0 : (d.flags >> 31) | 1; + // Subtracts two Decimal values. // public static Decimal Subtract(Decimal d1, Decimal d2) @@ -801,7 +794,7 @@ namespace System if (d.hi == 0 && d.mid == 0) { int i = d.lo; - if (!d.Sign) + if (!d.IsNegative) { if (i >= 0) return i; } @@ -824,7 +817,7 @@ namespace System if (d.uhi == 0) { long l = d.ulo | (long)(int)d.umid << 32; - if (!d.Sign) + if (!d.IsNegative) { if (l >= 0) return l; } @@ -867,7 +860,7 @@ namespace System if (d.Scale != 0) DecCalc.VarDecFix(ref d); if (d.uhi == 0 && d.umid == 0) { - if (!d.Sign || d.ulo == 0) + if (!d.IsNegative || d.ulo == 0) return d.ulo; } throw new OverflowException(SR.Overflow_UInt32); @@ -884,7 +877,7 @@ namespace System if (d.uhi == 0) { ulong l = (ulong)d.ulo | ((ulong)d.umid << 32); - if (!d.Sign || l == 0) + if (!d.IsNegative || l == 0) return l; } throw new OverflowException(SR.Overflow_UInt64); diff --git a/src/System.Private.CoreLib/src/System/GC.cs b/src/System.Private.CoreLib/src/System/GC.cs index 5e350b028..b6b7b09a1 100644 --- a/src/System.Private.CoreLib/src/System/GC.cs +++ b/src/System.Private.CoreLib/src/System/GC.cs @@ -324,24 +324,41 @@ namespace System private static bool StartNoGCRegionWorker(long totalSize, bool hasLohSize, long lohSize, bool disallowFullBlockingGC) { - StartNoGCRegionStatus status = - (StartNoGCRegionStatus)RuntimeImports.RhStartNoGCRegion(totalSize, hasLohSize, lohSize, disallowFullBlockingGC); - if (status == StartNoGCRegionStatus.AmountTooLarge) + if (totalSize <= 0) { throw new ArgumentOutOfRangeException( nameof(totalSize), - SR.ArgumentOutOfRangeException_NoGCRegionSizeTooLarge); + SR.Format(SR.ArgumentOutOfRange_MustBePositive, nameof(totalSize))); } - else if (status == StartNoGCRegionStatus.AlreadyInProgress) + + if (hasLohSize) { - throw new InvalidOperationException( - SR.InvalidOperationException_AlreadyInNoGCRegion); + if (lohSize <= 0) + { + throw new ArgumentOutOfRangeException( + nameof(lohSize), + SR.Format(SR.ArgumentOutOfRange_MustBePositive, nameof(lohSize))); + } + + if (lohSize > totalSize) + { + throw new ArgumentOutOfRangeException(nameof(lohSize), SR.ArgumentOutOfRange_NoGCLohSizeGreaterTotalSize); + } } - else if (status == StartNoGCRegionStatus.NotEnoughMemory) + + StartNoGCRegionStatus status = + (StartNoGCRegionStatus)RuntimeImports.RhStartNoGCRegion(totalSize, hasLohSize, lohSize, disallowFullBlockingGC); + switch (status) { - return false; + case StartNoGCRegionStatus.NotEnoughMemory: + return false; + case StartNoGCRegionStatus.AlreadyInProgress: + throw new InvalidOperationException(SR.InvalidOperationException_AlreadyInNoGCRegion); + case StartNoGCRegionStatus.AmountTooLarge: + throw new ArgumentOutOfRangeException(nameof(totalSize), SR.ArgumentOutOfRangeException_NoGCRegionSizeTooLarge); } + Debug.Assert(status == StartNoGCRegionStatus.Succeeded); return true; } diff --git a/src/System.Private.CoreLib/src/System/HighPerformanceCounter.Unix.cs b/src/System.Private.CoreLib/src/System/HighPerformanceCounter.Unix.cs index f06a4a9d3..06298f0f8 100644 --- a/src/System.Private.CoreLib/src/System/HighPerformanceCounter.Unix.cs +++ b/src/System.Private.CoreLib/src/System/HighPerformanceCounter.Unix.cs @@ -9,7 +9,6 @@ namespace System public static ulong TickCount => Interop.Sys.GetHighPrecisionCount(); // Cache the frequency on the managed side to avoid the cost of P/Invoke on every access to Frequency - private static ulong s_frequency; - public static ulong Frequency => s_frequency == 0 ? s_frequency = Interop.Sys.GetHighPrecisionCounterFrequency() : s_frequency; + public static ulong Frequency { get; } = Interop.Sys.GetHighPrecisionCounterFrequency(); } } diff --git a/src/System.Private.CoreLib/src/System/HighPerformanceCounter.Windows.cs b/src/System.Private.CoreLib/src/System/HighPerformanceCounter.Windows.cs new file mode 100644 index 000000000..70be268d4 --- /dev/null +++ b/src/System.Private.CoreLib/src/System/HighPerformanceCounter.Windows.cs @@ -0,0 +1,26 @@ +// 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 +{ + internal static class HighPerformanceCounter + { + public static ulong TickCount + { + get + { + Interop.Kernel32.QueryPerformanceCounter(out ulong counter); + return counter; + } + } + + public static ulong Frequency { get; } = GetFrequency(); + + private static ulong GetFrequency() + { + Interop.Kernel32.QueryPerformanceFrequency(out ulong frequency); + return frequency; + } + } +} diff --git a/src/System.Private.CoreLib/src/System/IO/Stream.cs b/src/System.Private.CoreLib/src/System/IO/Stream.cs index b5e16d9ac..4b6068bb7 100644 --- a/src/System.Private.CoreLib/src/System/IO/Stream.cs +++ b/src/System.Private.CoreLib/src/System/IO/Stream.cs @@ -95,36 +95,7 @@ namespace System.IO public Task CopyToAsync(Stream destination) { - int bufferSize = DefaultCopyBufferSize; - - if (CanSeek) - { - long length = Length; - long position = Position; - if (length <= position) // Handles negative overflows - { - // If we go down this branch, it means there are - // no bytes left in this stream. - - // Ideally we would just return Task.CompletedTask here, - // but CopyToAsync(Stream, int, CancellationToken) was already - // virtual at the time this optimization was introduced. So - // if it does things like argument validation (checking if destination - // is null and throwing an exception), then await fooStream.CopyToAsync(null) - // would no longer throw if there were no bytes left. On the other hand, - // we also can't roll our own argument validation and return Task.CompletedTask, - // because it would be a breaking change if the stream's override didn't throw before, - // or in a different order. So for simplicity, we just set the bufferSize to 1 - // (not 0 since the default implementation throws for 0) and forward to the virtual method. - bufferSize = 1; - } - else - { - long remaining = length - position; - if (remaining > 0) // In the case of a positive overflow, stick to the default size - bufferSize = (int)Math.Min(bufferSize, remaining); - } - } + int bufferSize = GetCopyBufferSize(); return CopyToAsync(destination, bufferSize); } @@ -134,6 +105,13 @@ namespace System.IO return CopyToAsync(destination, bufferSize, CancellationToken.None); } + public Task CopyToAsync(Stream destination, CancellationToken cancellationToken) + { + int bufferSize = GetCopyBufferSize(); + + return CopyToAsync(destination, bufferSize, cancellationToken); + } + public virtual Task CopyToAsync(Stream destination, int bufferSize, CancellationToken cancellationToken) { StreamHelpers.ValidateCopyToArgs(this, destination, bufferSize); @@ -162,6 +140,25 @@ namespace System.IO // the current position. public void CopyTo(Stream destination) { + int bufferSize = GetCopyBufferSize(); + + CopyTo(destination, bufferSize); + } + + public virtual void CopyTo(Stream destination, int bufferSize) + { + StreamHelpers.ValidateCopyToArgs(this, destination, bufferSize); + + byte[] buffer = new byte[bufferSize]; + int read; + while ((read = Read(buffer, 0, buffer.Length)) != 0) + { + destination.Write(buffer, 0, read); + } + } + + private int GetCopyBufferSize() + { int bufferSize = DefaultCopyBufferSize; if (CanSeek) @@ -170,32 +167,24 @@ namespace System.IO long position = Position; if (length <= position) // Handles negative overflows { - // No bytes left in stream - // Call the other overload with a bufferSize of 1, - // in case it's made virtual in the future + // There are no bytes left in the stream to copy. + // However, because CopyTo{Async} is virtual, we need to + // ensure that any override is still invoked to provide its + // own validation, so we use the smallest legal buffer size here. bufferSize = 1; } else { long remaining = length - position; - if (remaining > 0) // In the case of a positive overflow, stick to the default size + if (remaining > 0) + { + // In the case of a positive overflow, stick to the default size bufferSize = (int)Math.Min(bufferSize, remaining); + } } } - CopyTo(destination, bufferSize); - } - - public virtual void CopyTo(Stream destination, int bufferSize) - { - StreamHelpers.ValidateCopyToArgs(this, destination, bufferSize); - - byte[] buffer = new byte[bufferSize]; - int read; - while ((read = Read(buffer, 0, buffer.Length)) != 0) - { - destination.Write(buffer, 0, read); - } + return bufferSize; } public virtual void Close() diff --git a/src/System.Private.CoreLib/src/System/Math.CoreRT.cs b/src/System.Private.CoreLib/src/System/Math.CoreRT.cs new file mode 100644 index 000000000..dc4e40a17 --- /dev/null +++ b/src/System.Private.CoreLib/src/System/Math.CoreRT.cs @@ -0,0 +1,146 @@ +// 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. + +/*============================================================ +** +** Purpose: Some floating-point math operations +** +===========================================================*/ + +//This class contains only static members and doesn't require serialization. + +using System.Runtime; +using System.Runtime.CompilerServices; + +namespace System +{ + public static partial class Math + { + [Intrinsic] + public static float Abs(float value) + { + return (float)RuntimeImports.fabs(value); + } + + [Intrinsic] + public static double Abs(double value) + { + return RuntimeImports.fabs(value); + } + + [Intrinsic] + public static double Acos(double d) + { + return RuntimeImports.acos(d); + } + + [Intrinsic] + public static double Asin(double d) + { + return RuntimeImports.asin(d); + } + + [Intrinsic] + public static double Atan(double d) + { + return RuntimeImports.atan(d); + } + + [Intrinsic] + public static double Atan2(double y, double x) + { + return RuntimeImports.atan2(y, x); + } + + [Intrinsic] + public static double Ceiling(double a) + { + return RuntimeImports.ceil(a); + } + + [Intrinsic] + public static double Cos(double d) + { + return RuntimeImports.cos(d); + } + + [Intrinsic] + public static double Cosh(double value) + { + return RuntimeImports.cosh(value); + } + + [Intrinsic] + public static double Exp(double d) + { + return RuntimeImports.exp(d); + } + + [Intrinsic] + public static double Floor(double d) + { + return RuntimeImports.floor(d); + } + + [Intrinsic] + public static double Log(double d) + { + return RuntimeImports.log(d); + } + + [Intrinsic] + public static double Log10(double d) + { + return RuntimeImports.log10(d); + } + + [Intrinsic] + public static double Pow(double x, double y) + { + return RuntimeImports.pow(x, y); + } + + [Intrinsic] + public static double Sin(double a) + { + return RuntimeImports.sin(a); + } + + [Intrinsic] + public static double Sinh(double value) + { + return RuntimeImports.sinh(value); + } + + [Intrinsic] + public static double Sqrt(double d) + { + return RuntimeImports.sqrt(d); + } + + [Intrinsic] + public static double Tan(double a) + { + return RuntimeImports.tan(a); + } + + [Intrinsic] + public static double Tanh(double value) + { + return RuntimeImports.tanh(value); + } + + [Intrinsic] + private static double FMod(double x, double y) + { + return RuntimeImports.fmod(x, y); + } + + [Intrinsic] + private static unsafe double ModF(double x, double* intptr) + { + return RuntimeImports.modf(x, intptr); + } + } +} diff --git a/src/System.Private.CoreLib/src/System/Math.cs b/src/System.Private.CoreLib/src/System/Math.cs deleted file mode 100644 index 738f2d46a..000000000 --- a/src/System.Private.CoreLib/src/System/Math.cs +++ /dev/null @@ -1,688 +0,0 @@ -// 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. - -/*============================================================ -** -** -** -** Purpose: Some floating-point math operations -** -** -===========================================================*/ - -using System.Runtime; -using System.Runtime.CompilerServices; -using System.Runtime.Versioning; -using System.Diagnostics; -using System.Diagnostics.Contracts; - -namespace System -{ - public static class Math - { - private static double s_doubleRoundLimit = 1e16d; - - private const int maxRoundingDigits = 15; - - // This table is required for the Round function which can specify the number of digits to round to - private static double[] s_roundPower10Double = new double[] { - 1E0, 1E1, 1E2, 1E3, 1E4, 1E5, 1E6, 1E7, 1E8, - 1E9, 1E10, 1E11, 1E12, 1E13, 1E14, 1E15 - }; - - public const double PI = 3.14159265358979323846; - public const double E = 2.7182818284590452354; - - [Intrinsic] - public static double Acos(double d) - { - return RuntimeImports.acos(d); - } - - [Intrinsic] - public static double Asin(double d) - { - return RuntimeImports.asin(d); - } - - [Intrinsic] - public static double Atan(double d) - { - return RuntimeImports.atan(d); - } - - [Intrinsic] - public static double Atan2(double y, double x) - { - return RuntimeImports.atan2(y, x); - } - - public static Decimal Ceiling(Decimal d) - { - return Decimal.Ceiling(d); - } - - [Intrinsic] - public static double Ceiling(double a) - { - return RuntimeImports.ceil(a); - } - - [Intrinsic] - public static double Cos(double d) - { - return RuntimeImports.cos(d); - } - - [Intrinsic] - public static double Cosh(double value) - { - return RuntimeImports.cosh(value); - } - - public static Decimal Floor(Decimal d) - { - return Decimal.Floor(d); - } - - [Intrinsic] - public static double Floor(double d) - { - return RuntimeImports.floor(d); - } - - private static unsafe double InternalRound(double value, int digits, MidpointRounding mode) - { - if (Abs(value) < s_doubleRoundLimit) - { - Double power10 = s_roundPower10Double[digits]; - value *= power10; - if (mode == MidpointRounding.AwayFromZero) - { - double fraction = RuntimeImports.modf(value, &value); - if (Abs(fraction) >= 0.5d) - { - value += Sign(fraction); - } - } - else - { - // On X86 this can be inlined to just a few instructions - value = Round(value); - } - value /= power10; - } - return value; - } - - [Intrinsic] - public static double Sin(double a) - { - return RuntimeImports.sin(a); - } - - [Intrinsic] - public static double Tan(double a) - { - return RuntimeImports.tan(a); - } - - [Intrinsic] - public static double Sinh(double value) - { - return RuntimeImports.sinh(value); - } - - [Intrinsic] - public static double Tanh(double value) - { - return RuntimeImports.tanh(value); - } - - [Intrinsic] - public static double Round(double a) - { - // If the number has no fractional part do nothing - // This shortcut is necessary to workaround precision loss in borderline cases on some platforms - if (a == (double)(Int64)a) - return a; - - double tempVal = a + 0.5; - // We had a number that was equally close to 2 integers. - // We need to return the even one. - double flrTempVal = RuntimeImports.floor(tempVal); - if (flrTempVal == tempVal) - { - if (0.0 != RuntimeImports.fmod(tempVal, 2.0)) - { - flrTempVal -= 1.0; - } - } - - if (flrTempVal == 0 && Double.IsNegative(a)) - { - flrTempVal = Double.NegativeZero; - } - return flrTempVal; - } - - public static double Round(double value, int digits) - { - if ((digits < 0) || (digits > maxRoundingDigits)) - throw new ArgumentOutOfRangeException(nameof(digits), SR.ArgumentOutOfRange_RoundingDigits); - Contract.EndContractBlock(); - return InternalRound(value, digits, MidpointRounding.ToEven); - } - - public static double Round(double value, MidpointRounding mode) - { - return Round(value, 0, mode); - } - - public static double Round(double value, int digits, MidpointRounding mode) - { - if ((digits < 0) || (digits > maxRoundingDigits)) - throw new ArgumentOutOfRangeException(nameof(digits), SR.ArgumentOutOfRange_RoundingDigits); - if (mode < MidpointRounding.ToEven || mode > MidpointRounding.AwayFromZero) - { - throw new ArgumentException(SR.Format(SR.Argument_InvalidEnumValue, mode, "MidpointRounding"), nameof(mode)); - } - Contract.EndContractBlock(); - return InternalRound(value, digits, mode); - } - - public static Decimal Round(Decimal d) - { - return Decimal.Round(d, 0); - } - - public static Decimal Round(Decimal d, int decimals) - { - return Decimal.Round(d, decimals); - } - - public static Decimal Round(Decimal d, MidpointRounding mode) - { - return Decimal.Round(d, 0, mode); - } - - public static Decimal Round(Decimal d, int decimals, MidpointRounding mode) - { - return Decimal.Round(d, decimals, mode); - } - - public static Decimal Truncate(Decimal d) - { - return Decimal.Truncate(d); - } - - public static unsafe double Truncate(double d) - { - double intpart; - RuntimeImports.modf(d, &intpart); - return intpart; - } - - [Intrinsic] - public static double Sqrt(double d) - { - return RuntimeImports.sqrt(d); - } - - [Intrinsic] - public static double Log(double d) - { - return RuntimeImports.log(d); - } - - [Intrinsic] - public static double Log10(double d) - { - return RuntimeImports.log10(d); - } - - [Intrinsic] - public static double Exp(double d) - { - return RuntimeImports.exp(d); - } - - [Intrinsic] - public static double Pow(double x, double y) - { - return RuntimeImports.pow(x, y); - } - - - public static double IEEERemainder(double x, double y) - { - if (Double.IsNaN(x)) - { - return x; // IEEE 754-2008: NaN payload must be preserved - } - if (Double.IsNaN(y)) - { - return y; // IEEE 754-2008: NaN payload must be preserved - } - - double regularMod = x % y; - if (Double.IsNaN(regularMod)) - { - return Double.NaN; - } - if (regularMod == 0) - { - if (Double.IsNegative(x)) - { - return Double.NegativeZero; - } - } - double alternativeResult; - alternativeResult = regularMod - (Math.Abs(y) * Math.Sign(x)); - if (Math.Abs(alternativeResult) == Math.Abs(regularMod)) - { - double divisionResult = x / y; - double roundedResult = Math.Round(divisionResult); - if (Math.Abs(roundedResult) > Math.Abs(divisionResult)) - { - return alternativeResult; - } - else - { - return regularMod; - } - } - if (Math.Abs(alternativeResult) < Math.Abs(regularMod)) - { - return alternativeResult; - } - else - { - return regularMod; - } - } - - /*================================Abs========================================= - **Returns the absolute value of it's argument. - ============================================================================*/ - - [CLSCompliant(false)] - public static sbyte Abs(sbyte value) - { - if (value >= 0) - return value; - else - return AbsHelper(value); - } - - private static sbyte AbsHelper(sbyte value) - { - Debug.Assert(value < 0, "AbsHelper should only be called for negative values!"); - if (value == SByte.MinValue) - throw new OverflowException(SR.Overflow_NegateTwosCompNum); - Contract.EndContractBlock(); - return ((sbyte)(-value)); - } - - public static short Abs(short value) - { - if (value >= 0) - return value; - else - return AbsHelper(value); - } - - private static short AbsHelper(short value) - { - Debug.Assert(value < 0, "AbsHelper should only be called for negative values!"); - if (value == Int16.MinValue) - throw new OverflowException(SR.Overflow_NegateTwosCompNum); - Contract.EndContractBlock(); - return (short)-value; - } - - public static int Abs(int value) - { - if (value >= 0) - return value; - else - return AbsHelper(value); - } - - private static int AbsHelper(int value) - { - Debug.Assert(value < 0, "AbsHelper should only be called for negative values!"); - if (value == Int32.MinValue) - throw new OverflowException(SR.Overflow_NegateTwosCompNum); - Contract.EndContractBlock(); - return -value; - } - - public static long Abs(long value) - { - if (value >= 0) - return value; - else - return AbsHelper(value); - } - - private static long AbsHelper(long value) - { - Debug.Assert(value < 0, "AbsHelper should only be called for negative values!"); - if (value == Int64.MinValue) - throw new OverflowException(SR.Overflow_NegateTwosCompNum); - Contract.EndContractBlock(); - return -value; - } - - [Intrinsic] - public static float Abs(float value) - { - return (float)RuntimeImports.fabs(value); - } - - [Intrinsic] - public static double Abs(double value) - { - return RuntimeImports.fabs(value); - } - - public static Decimal Abs(Decimal value) - { - return Decimal.Abs(value); - } - - /*================================MAX========================================= - **Returns the larger of val1 and val2 - ============================================================================*/ - [CLSCompliant(false)] - [NonVersionable] - public static sbyte Max(sbyte val1, sbyte val2) - { - return (val1 >= val2) ? val1 : val2; - } - - [NonVersionable] - public static byte Max(byte val1, byte val2) - { - return (val1 >= val2) ? val1 : val2; - } - - [NonVersionable] - public static short Max(short val1, short val2) - { - return (val1 >= val2) ? val1 : val2; - } - - [CLSCompliant(false)] - [NonVersionable] - public static ushort Max(ushort val1, ushort val2) - { - return (val1 >= val2) ? val1 : val2; - } - - [NonVersionable] - public static int Max(int val1, int val2) - { - return (val1 >= val2) ? val1 : val2; - } - - [CLSCompliant(false)] - [NonVersionable] - public static uint Max(uint val1, uint val2) - { - return (val1 >= val2) ? val1 : val2; - } - - [NonVersionable] - public static long Max(long val1, long val2) - { - return (val1 >= val2) ? val1 : val2; - } - - [CLSCompliant(false)] - [NonVersionable] - public static ulong Max(ulong val1, ulong val2) - { - return (val1 >= val2) ? val1 : val2; - } - - public static float Max(float val1, float val2) - { - if (val1 > val2) - return val1; - - if (Single.IsNaN(val1)) - return val1; - - return val2; - } - - public static double Max(double val1, double val2) - { - if (val1 > val2) - return val1; - - if (Double.IsNaN(val1)) - return val1; - - return val2; - } - - public static Decimal Max(Decimal val1, Decimal val2) - { - return Decimal.Max(val1, val2); - } - - /*================================MIN========================================= - **Returns the smaller of val1 and val2. - ============================================================================*/ - [CLSCompliant(false)] - [NonVersionable] - public static sbyte Min(sbyte val1, sbyte val2) - { - return (val1 <= val2) ? val1 : val2; - } - - [NonVersionable] - public static byte Min(byte val1, byte val2) - { - return (val1 <= val2) ? val1 : val2; - } - - [NonVersionable] - public static short Min(short val1, short val2) - { - return (val1 <= val2) ? val1 : val2; - } - - [CLSCompliant(false)] - [NonVersionable] - public static ushort Min(ushort val1, ushort val2) - { - return (val1 <= val2) ? val1 : val2; - } - - [NonVersionable] - public static int Min(int val1, int val2) - { - return (val1 <= val2) ? val1 : val2; - } - - [CLSCompliant(false)] - [NonVersionable] - public static uint Min(uint val1, uint val2) - { - return (val1 <= val2) ? val1 : val2; - } - - [NonVersionable] - public static long Min(long val1, long val2) - { - return (val1 <= val2) ? val1 : val2; - } - - [CLSCompliant(false)] - [NonVersionable] - public static ulong Min(ulong val1, ulong val2) - { - return (val1 <= val2) ? val1 : val2; - } - - public static float Min(float val1, float val2) - { - if (val1 < val2) - return val1; - - if (Single.IsNaN(val1)) - return val1; - - return val2; - } - - public static double Min(double val1, double val2) - { - if (val1 < val2) - return val1; - - if (Double.IsNaN(val1)) - return val1; - - return val2; - } - - public static Decimal Min(Decimal val1, Decimal val2) - { - return Decimal.Min(val1, val2); - } - - /*=====================================Log====================================== - ** - ==============================================================================*/ - public static double Log(double a, double newBase) - { - if (Double.IsNaN(a)) - { - return a; // IEEE 754-2008: NaN payload must be preserved - } - if (Double.IsNaN(newBase)) - { - return newBase; // IEEE 754-2008: NaN payload must be preserved - } - - if (newBase == 1) - return Double.NaN; - if (a != 1 && (newBase == 0 || Double.IsPositiveInfinity(newBase))) - return Double.NaN; - - return (Log(a) / Log(newBase)); - } - - - // Sign function for VB. Returns -1, 0, or 1 if the sign of the number - // is negative, 0, or positive. Throws for floating point NaN's. - [CLSCompliant(false)] - public static int Sign(sbyte value) - { - if (value < 0) - return -1; - else if (value > 0) - return 1; - else - return 0; - } - - - // Sign function for VB. Returns -1, 0, or 1 if the sign of the number - // is negative, 0, or positive. Throws for floating point NaN's. - public static int Sign(short value) - { - if (value < 0) - return -1; - else if (value > 0) - return 1; - else - return 0; - } - - // Sign function for VB. Returns -1, 0, or 1 if the sign of the number - // is negative, 0, or positive. Throws for floating point NaN's. - public static int Sign(int value) - { - if (value < 0) - return -1; - else if (value > 0) - return 1; - else - return 0; - } - - public static int Sign(long value) - { - if (value < 0) - return -1; - else if (value > 0) - return 1; - else - return 0; - } - - public static int Sign(float value) - { - if (value < 0) - return -1; - else if (value > 0) - return 1; - else if (value == 0) - return 0; - throw new ArithmeticException(SR.Arithmetic_NaN); - } - - public static int Sign(double value) - { - if (value < 0) - return -1; - else if (value > 0) - return 1; - else if (value == 0) - return 0; - throw new ArithmeticException(SR.Arithmetic_NaN); - } - - public static int Sign(Decimal value) - { - if (value < 0) - return -1; - else if (value > 0) - return 1; - else - return 0; - } - - public static long BigMul(int a, int b) - { - return ((long)a) * b; - } - - public static int DivRem(int a, int b, out int result) - { - // TODO https://github.com/dotnet/coreclr/issues/3439: - // Restore to using % and / when the JIT is able to eliminate one of the idivs. - // In the meantime, a * and - is measurably faster than an extra /. - int div = a / b; - result = a - (div * b); - return div; - } - - public static long DivRem(long a, long b, out long result) - { - // TODO https://github.com/dotnet/coreclr/issues/3439: - // Restore to using % and / when the JIT is able to eliminate one of the idivs. - // In the meantime, a * and - is measurably faster than an extra /. - long div = a / b; - result = a - (div * b); - return div; - } - } -} diff --git a/src/System.Private.CoreLib/src/System/MathF.CoreRT.cs b/src/System.Private.CoreLib/src/System/MathF.CoreRT.cs new file mode 100644 index 000000000..b67b8bbd4 --- /dev/null +++ b/src/System.Private.CoreLib/src/System/MathF.CoreRT.cs @@ -0,0 +1,139 @@ +// 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. + +/*============================================================ +** +** Purpose: Some single-precision floating-point math operations +** +===========================================================*/ + +//This class contains only static members and doesn't require serialization. + +using System.Runtime; +using System.Runtime.CompilerServices; + +namespace System +{ + public static partial class MathF + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float Acos(float x) + { + return (float)Math.Acos(x); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float Asin(float x) + { + return (float)Math.Asin(x); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float Atan(float x) + { + return (float)Math.Atan(x); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float Atan2(float y, float x) + { + return (float)Math.Atan2(y, x); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float Ceiling(float x) + { + return (float)Math.Ceiling(x); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float Cos(float x) + { + return (float)Math.Cos(x); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float Cosh(float x) + { + return (float)Math.Cosh(x); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float Exp(float x) + { + return (float)Math.Exp(x); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float Floor(float x) + { + return (float)Math.Floor(x); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float Log(float x) + { + return (float)Math.Log(x); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float Log10(float x) + { + return (float)Math.Log10(x); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float Pow(float x, float y) + { + return (float)Math.Pow(x, y); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float Sin(float x) + { + return (float)Math.Sin(x); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float Sinh(float x) + { + return (float)Math.Sinh(x); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float Sqrt(float x) + { + return (float)Math.Sqrt(x); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float Tan(float x) + { + return (float)Math.Tan(x); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float Tanh(float x) + { + return (float)Math.Tanh(x); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static float FMod(float x, float y) + { + return (float)RuntimeImports.fmod(x, y); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static unsafe float ModF(float x, float* intptr) + { + //todo : https://github.com/dotnet/corert/issues/3167 + double d = x; + double r = RuntimeImports.modf(d, &d); + + *intptr = (float)d; + return (float)r; + } + } +} diff --git a/src/System.Private.CoreLib/src/System/MathF.cs b/src/System.Private.CoreLib/src/System/MathF.cs deleted file mode 100644 index 598b0425b..000000000 --- a/src/System.Private.CoreLib/src/System/MathF.cs +++ /dev/null @@ -1,262 +0,0 @@ -// 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.Runtime; -using System.Runtime.CompilerServices; - -namespace System -{ - public static class MathF - { - public const float PI = (float)Math.PI; - - public const float E = 2.71828183f; - - private static float singleRoundLimit = 1e8f; - - private const int maxRoundingDigits = 6; - - // This table is required for the Round function which can specify the number of digits to round to - private static float[] roundPower10Single = new float[] { - 1e0f, 1e1f, 1e2f, 1e3f, 1e4f, 1e5f, 1e6f - }; - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static float Abs(float x) - { - return Math.Abs(x); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static float Acos(float x) - { - return (float)Math.Acos(x); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static float Asin(float x) - { - return (float)Math.Asin(x); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static float Atan(float x) - { - return (float)Math.Atan(x); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static float Atan2(float y, float x) - { - return (float)Math.Atan2(y, x); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static float Cos(float x) - { - return (float)Math.Cos(x); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static float Ceiling(float x) - { - return (float)Math.Ceiling(x); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static float Cosh(float x) { return (float)Math.Cosh(x); } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static float Exp(float x) { return (float)Math.Exp(x); } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static float Floor(float x) { return (float)Math.Floor(x); } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static float Log(float x) - { - return (float)Math.Log(x); - } - public static float Log(float x, float y) - { - if (float.IsNaN(x)) - { - return x; // IEEE 754-2008: NaN payload must be preserved - } - - if (float.IsNaN(y)) - { - return y; // IEEE 754-2008: NaN payload must be preserved - } - - if (y == 1) - { - return float.NaN; - } - - if ((x != 1) && ((y == 0) || float.IsPositiveInfinity(y))) - { - return float.NaN; - } - - return Log(x) / Log(y); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static float Log10(float x) - { - return (float)Math.Log10(x); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static float Max(float x, float y) - { - return Math.Max(x, y); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static float Min(float x, float y) - { - return Math.Min(x, y); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static float Pow(float x, float y) - { - return (float)Math.Pow(x, y); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static float Round(float x) - { - return (float)Math.Round(x); - } - - public static float Round(float x, int digits) - { - if ((digits < 0) || (digits > maxRoundingDigits)) - { - throw new ArgumentOutOfRangeException(nameof(digits), SR.ArgumentOutOfRange_RoundingDigits); - } - - return InternalRound(x, digits, MidpointRounding.ToEven); - } - - public static float Round(float x, int digits, MidpointRounding mode) - { - if ((digits < 0) || (digits > maxRoundingDigits)) - { - throw new ArgumentOutOfRangeException(nameof(digits), SR.ArgumentOutOfRange_RoundingDigits); - } - - if (mode < MidpointRounding.ToEven || mode > MidpointRounding.AwayFromZero) - { - throw new ArgumentException(SR.Format(SR.Argument_InvalidEnum, mode, nameof(MidpointRounding)), nameof(mode)); - } - - return InternalRound(x, digits, mode); - } - - public static float Round(float x, MidpointRounding mode) - { - if (mode < MidpointRounding.ToEven || mode > MidpointRounding.AwayFromZero) - { - throw new ArgumentException(SR.Format(SR.Argument_InvalidEnum, mode, nameof(MidpointRounding)), nameof(mode)); - } - - return InternalRound(x, 0, mode); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static float IEEERemainder(float x, float y) - { - return (float)Math.IEEERemainder(x, y); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static float Sin(float x) - { - return (float)Math.Sin(x); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static float Sqrt(float x) - { - return (float)Math.Sqrt(x); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static float Tan(float x) - { - return (float)Math.Tan(x); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int Sign(float x) - { - return Math.Sign(x); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static float Sinh(float x) - { - return (float)Math.Sinh(x); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static float Tanh(float x) - { - return (float)Math.Tanh(x); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static float Truncate(float x) => InternalTruncate(x); - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static unsafe float SplitFractionSingle(float* x) - { - //todo : https://github.com/dotnet/corert/issues/3167 - double d = *x; - double r = RuntimeImports.modf(d, &d); - - *x = (float)d; - return (float)r; - } - - private unsafe static float InternalTruncate(float x) - { - SplitFractionSingle(&x); - return x; - } - - private static unsafe float InternalRound(float x, int digits, MidpointRounding mode) - { - if (Abs(x) < singleRoundLimit) - { - var power10 = roundPower10Single[digits]; - - x *= power10; - - if (mode == MidpointRounding.AwayFromZero) - { - var fraction = SplitFractionSingle(&x); - - if (Abs(fraction) >= 0.5f) - { - x += Sign(fraction); - } - } - else - { - x = Round(x); - } - - x /= power10; - } - - return x; - } - } -} diff --git a/src/System.Private.CoreLib/src/System/Number.FormatAndParse.cs b/src/System.Private.CoreLib/src/System/Number.FormatAndParse.cs index c80f0f0fb..ac2d11f74 100644 --- a/src/System.Private.CoreLib/src/System/Number.FormatAndParse.cs +++ b/src/System.Private.CoreLib/src/System/Number.FormatAndParse.cs @@ -1135,7 +1135,7 @@ namespace System { d.Scale = -e; } - d.Sign = number.sign; + d.IsNegative = number.sign; value = d; return true; @@ -1147,7 +1147,7 @@ namespace System char* buffer = number.digits; number.precision = DECIMAL_PRECISION; - number.sign = d.Sign; + number.sign = d.IsNegative; int index = DECIMAL_PRECISION; while (d.Mid != 0 | d.High != 0) diff --git a/src/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.cs b/src/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.cs index 2c1c1dfda..93831c772 100644 --- a/src/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.cs +++ b/src/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.cs @@ -157,6 +157,9 @@ namespace System.Runtime.CompilerServices public static int OffsetToStringData { + // Workaround to allow WebAssembly to define a size here without a special CoreLib build + // https://github.com/dotnet/corert/issues/4506 includes removing this. + [Intrinsic] get { // Number of bytes from the address pointed to by a reference to diff --git a/src/System.Private.CoreLib/src/System/Threading/ClrThreadPool.CpuUtilizationReader.Unix.cs b/src/System.Private.CoreLib/src/System/Threading/ClrThreadPool.CpuUtilizationReader.Unix.cs index ffe2c80b4..2d1ad01e7 100644 --- a/src/System.Private.CoreLib/src/System/Threading/ClrThreadPool.CpuUtilizationReader.Unix.cs +++ b/src/System.Private.CoreLib/src/System/Threading/ClrThreadPool.CpuUtilizationReader.Unix.cs @@ -9,13 +9,8 @@ namespace System.Threading private class CpuUtilizationReader { private Interop.Sys.ProcessCpuInformation _cpuInfo; - public CpuUtilizationReader() - { - _cpuInfo = new Interop.Sys.ProcessCpuInformation(); - Interop.Sys.GetCpuUtilization(ref _cpuInfo); // Initialize the cpuInfo structure so future calls with it get correct readings - } public int CurrentUtilization => Interop.Sys.GetCpuUtilization(ref _cpuInfo); // Updates cpuInfo as a side effect for the next call } } -}
\ No newline at end of file +} diff --git a/src/System.Private.CoreLib/src/System/Threading/ClrThreadPool.CpuUtilizationReader.Windows.cs b/src/System.Private.CoreLib/src/System/Threading/ClrThreadPool.CpuUtilizationReader.Windows.cs new file mode 100644 index 000000000..b7d7f8ae4 --- /dev/null +++ b/src/System.Private.CoreLib/src/System/Threading/ClrThreadPool.CpuUtilizationReader.Windows.cs @@ -0,0 +1,54 @@ +// 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.Diagnostics; +using System.Runtime.InteropServices; + +namespace System.Threading +{ + internal partial class ClrThreadPool + { + private class CpuUtilizationReader + { + private struct ProcessCpuInformation + { + public long idleTime; + public long kernelTime; + public long userTime; + } + + private ProcessCpuInformation _processCpuInfo = new ProcessCpuInformation(); + + public int CurrentUtilization + { + get + { + if (!Interop.Kernel32.GetSystemTimes(out var idleTime, out var kernelTime, out var userTime)) + { + int error = Marshal.GetLastWin32Error(); + var exception = new OutOfMemoryException(); + exception.SetErrorCode(error); + throw exception; + } + + long cpuTotalTime = ((long)userTime - _processCpuInfo.userTime) + ((long)kernelTime - _processCpuInfo.kernelTime); + long cpuBusyTime = cpuTotalTime - ((long)idleTime - _processCpuInfo.idleTime); + + _processCpuInfo.kernelTime = (long)kernelTime; + _processCpuInfo.userTime = (long)userTime; + _processCpuInfo.idleTime = (long)idleTime; + + if (cpuTotalTime > 0 && cpuBusyTime > 0) + { + long reading = cpuBusyTime * 100 / cpuTotalTime; + reading = Math.Min(reading, 100); + Debug.Assert(0 <= reading); + return (int)reading; + } + return 0; + } + } + } + } +} diff --git a/src/System.Private.CoreLib/src/System/Threading/ClrThreadPool.ThreadCounts.cs b/src/System.Private.CoreLib/src/System/Threading/ClrThreadPool.ThreadCounts.cs index 82f109fe5..1f2fe886e 100644 --- a/src/System.Private.CoreLib/src/System/Threading/ClrThreadPool.ThreadCounts.cs +++ b/src/System.Private.CoreLib/src/System/Threading/ClrThreadPool.ThreadCounts.cs @@ -75,10 +75,10 @@ namespace System.Threading private void Validate() { - Debug.Assert(numThreadsGoal > 0); - Debug.Assert(numExistingThreads >= 0); - Debug.Assert(numProcessingWork >= 0); - Debug.Assert(numProcessingWork <= numExistingThreads); + Debug.Assert(numThreadsGoal > 0, "Goal must be positive"); + Debug.Assert(numExistingThreads >= 0, "Number of existing threads must be non-zero"); + Debug.Assert(numProcessingWork >= 0, "Number of threads processing work must be non-zero"); + Debug.Assert(numProcessingWork <= numExistingThreads, $"Num processing work ({numProcessingWork}) must be less than or equal to Num existing threads ({numExistingThreads})"); } } } diff --git a/src/System.Private.CoreLib/src/System/Threading/ClrThreadPool.WorkerThread.cs b/src/System.Private.CoreLib/src/System/Threading/ClrThreadPool.WorkerThread.cs index 6e6546a53..507eeb472 100644 --- a/src/System.Private.CoreLib/src/System/Threading/ClrThreadPool.WorkerThread.cs +++ b/src/System.Private.CoreLib/src/System/Threading/ClrThreadPool.WorkerThread.cs @@ -36,15 +36,6 @@ namespace System.Threading // If the queue runs out of work for us, we need to update the number of working workers to reflect that we are done working for now RemoveWorkingWorker(); } - - // Reset thread-local state that we control. - if (currentThread.Priority != ThreadPriority.Normal) - { - currentThread.Priority = ThreadPriority.Normal; - } - - CultureInfo.CurrentCulture = CultureInfo.InstalledUICulture; - CultureInfo.CurrentUICulture = CultureInfo.InstalledUICulture; } else { diff --git a/src/System.Private.CoreLib/src/System/Threading/ClrThreadPool.cs b/src/System.Private.CoreLib/src/System/Threading/ClrThreadPool.cs index dfa622220..2d1993a62 100644 --- a/src/System.Private.CoreLib/src/System/Threading/ClrThreadPool.cs +++ b/src/System.Private.CoreLib/src/System/Threading/ClrThreadPool.cs @@ -21,7 +21,7 @@ namespace System.Threading private const int CpuUtilizationHigh = 95; private const int CpuUtilizationLow = 80; - private int _cpuUtilization = 85; // TODO: Add calculation for CPU utilization + private int _cpuUtilization = 0; private static readonly short s_forcedMinWorkerThreads = AppContextConfigHelper.GetInt16Config("System.Threading.ThreadPool.MinThreads", 0); @@ -88,7 +88,7 @@ namespace System.Threading _minThreads = threads; ThreadCounts counts = ThreadCounts.VolatileReadCounts(ref _separated.counts); - while (counts.numThreadsGoal < minThreads) + while (counts.numThreadsGoal < _minThreads) { ThreadCounts newCounts = counts; newCounts.numThreadsGoal = _minThreads; @@ -137,7 +137,7 @@ namespace System.Threading _maxThreads = threads; ThreadCounts counts = ThreadCounts.VolatileReadCounts(ref _separated.counts); - while (counts.numThreadsGoal > maxThreads) + while (counts.numThreadsGoal > _maxThreads) { ThreadCounts newCounts = counts; newCounts.numThreadsGoal = _maxThreads; diff --git a/src/System.Private.CoreLib/src/System/Threading/LowLevelLifoSemaphore.Unix.cs b/src/System.Private.CoreLib/src/System/Threading/LowLevelLifoSemaphore.Unix.cs index 1c198499d..ce3a097a1 100644 --- a/src/System.Private.CoreLib/src/System/Threading/LowLevelLifoSemaphore.Unix.cs +++ b/src/System.Private.CoreLib/src/System/Threading/LowLevelLifoSemaphore.Unix.cs @@ -8,7 +8,7 @@ namespace System.Threading /// A LIFO semaphore. /// Waits on this semaphore are uninterruptible. /// </summary> - internal sealed class LowLevelLifoSemaphore + internal sealed class LowLevelLifoSemaphore : IDisposable { private WaitSubsystem.WaitableObject _semaphore; @@ -26,5 +26,9 @@ namespace System.Threading { return WaitSubsystem.ReleaseSemaphore(_semaphore, count); } + + public void Dispose() + { + } } } diff --git a/src/System.Private.CoreLib/src/System/Threading/LowLevelLifoSemaphore.Windows.cs b/src/System.Private.CoreLib/src/System/Threading/LowLevelLifoSemaphore.Windows.cs new file mode 100644 index 000000000..88ca53420 --- /dev/null +++ b/src/System.Private.CoreLib/src/System/Threading/LowLevelLifoSemaphore.Windows.cs @@ -0,0 +1,63 @@ +// 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.Diagnostics; +using System.Runtime.InteropServices; + +namespace System.Threading +{ + /// <summary> + /// A LIFO semaphore implemented using Win32 IO Completion Ports. + /// </summary> + /// <remarks> + /// IO Completion ports release waiting threads in LIFO order, so we can use them to create a LIFO semaphore. + /// See https://msdn.microsoft.com/en-us/library/windows/desktop/aa365198(v=vs.85).aspx under How I/O Completion Ports Work. + /// From the docs "Threads that block their execution on an I/O completion port are released in last-in-first-out (LIFO) order." + /// </remarks> + internal sealed class LowLevelLifoSemaphore : IDisposable + { + private IntPtr _completionPort; + + public LowLevelLifoSemaphore(int initialSignalCount, int maximumSignalCount) + { + Debug.Assert(initialSignalCount >= 0, "Windows LowLevelLifoSemaphore does not support a negative signal count"); // TODO: Track actual signal count to enable this + _completionPort = Interop.Kernel32.CreateIoCompletionPort(new IntPtr(-1), IntPtr.Zero, UIntPtr.Zero, 1); + if (_completionPort == IntPtr.Zero) + { + var error = Marshal.GetLastWin32Error(); + var exception = new OutOfMemoryException(); + exception.SetErrorCode(error); + throw exception; + } + Release(initialSignalCount); + } + + public bool Wait(int timeoutMs) + { + bool success = Interop.Kernel32.GetQueuedCompletionStatus(_completionPort, out var numberOfBytes, out var completionKey, out var pointerToOverlapped, timeoutMs); + Debug.Assert(success || (Marshal.GetLastWin32Error() == WaitHandle.WaitTimeout)); + return success; + } + + public int Release(int count) + { + for (int i = 0; i < count; i++) + { + if(!Interop.Kernel32.PostQueuedCompletionStatus(_completionPort, 1, UIntPtr.Zero, IntPtr.Zero)) + { + var lastError = Marshal.GetLastWin32Error(); + var exception = new OutOfMemoryException(); + exception.SetErrorCode(lastError); + throw exception; + } + } + return 0; // TODO: Track actual signal count to calculate this + } + + public void Dispose() + { + Interop.Kernel32.CloseHandle(_completionPort); + } + } +} diff --git a/src/System.Private.CoreLib/src/System/Threading/LowLevelLock.Unix.cs b/src/System.Private.CoreLib/src/System/Threading/LowLevelLock.cs index 719541856..719541856 100644 --- a/src/System.Private.CoreLib/src/System/Threading/LowLevelLock.Unix.cs +++ b/src/System.Private.CoreLib/src/System/Threading/LowLevelLock.cs diff --git a/src/System.Private.CoreLib/src/System/Threading/LowLevelMonitor.Unix.cs b/src/System.Private.CoreLib/src/System/Threading/LowLevelMonitor.Unix.cs index 6f20f2af3..f87ba7a91 100644 --- a/src/System.Private.CoreLib/src/System/Threading/LowLevelMonitor.Unix.cs +++ b/src/System.Private.CoreLib/src/System/Threading/LowLevelMonitor.Unix.cs @@ -12,14 +12,10 @@ namespace System.Threading /// /// Used by the wait subsystem on Unix, so this class cannot have any dependencies on the wait subsystem. /// </summary> - internal sealed class LowLevelMonitor : IDisposable + internal sealed partial class LowLevelMonitor : IDisposable { private IntPtr _nativeMonitor; -#if DEBUG - private RuntimeThread _ownerThread; -#endif - public LowLevelMonitor() { _nativeMonitor = Interop.Sys.LowLevelMonitor_New(); @@ -27,21 +23,10 @@ namespace System.Threading { throw new OutOfMemoryException(); } - -#if DEBUG - _ownerThread = null; -#endif - } - - ~LowLevelMonitor() - { - Dispose(); } - public void Dispose() + private void DisposeCore() { - VerifyIsNotLockedByAnyThread(); - if (_nativeMonitor == IntPtr.Zero) { return; @@ -49,96 +34,39 @@ namespace System.Threading Interop.Sys.LowLevelMonitor_Delete(_nativeMonitor); _nativeMonitor = IntPtr.Zero; - GC.SuppressFinalize(this); } -#if DEBUG - public bool IsLocked => _ownerThread == RuntimeThread.CurrentThread; -#endif - - public void VerifyIsLocked() - { -#if DEBUG - Debug.Assert(IsLocked); -#endif - } - - public void VerifyIsNotLocked() + private void AcquireCore() { -#if DEBUG - Debug.Assert(!IsLocked); -#endif - } - - private void VerifyIsNotLockedByAnyThread() - { -#if DEBUG - Debug.Assert(_ownerThread == null); -#endif - } - - private void ResetOwnerThread() - { -#if DEBUG - VerifyIsLocked(); - _ownerThread = null; -#endif - } - - private void SetOwnerThreadToCurrent() - { -#if DEBUG - VerifyIsNotLockedByAnyThread(); - _ownerThread = RuntimeThread.CurrentThread; -#endif - } - - public void Acquire() - { - VerifyIsNotLocked(); Interop.Sys.LowLevelMutex_Acquire(_nativeMonitor); - SetOwnerThreadToCurrent(); } - public void Release() + private void ReleaseCore() { - ResetOwnerThread(); Interop.Sys.LowLevelMutex_Release(_nativeMonitor); } - public void Wait() + private void WaitCore() { - ResetOwnerThread(); Interop.Sys.LowLevelMonitor_Wait(_nativeMonitor); - SetOwnerThreadToCurrent(); } - public bool Wait(int timeoutMilliseconds) + private bool WaitCore(int timeoutMilliseconds) { Debug.Assert(timeoutMilliseconds >= -1); if (timeoutMilliseconds < 0) { - Wait(); + WaitCore(); return true; } - ResetOwnerThread(); - bool waitResult = Interop.Sys.LowLevelMonitor_TimedWait(_nativeMonitor, timeoutMilliseconds); - SetOwnerThreadToCurrent(); - return waitResult; + return Interop.Sys.LowLevelMonitor_TimedWait(_nativeMonitor, timeoutMilliseconds); } - public void Signal_Release() + private void Signal_ReleaseCore() { - ResetOwnerThread(); Interop.Sys.LowLevelMonitor_Signal_Release(_nativeMonitor); } - - /// The following methods typical in a monitor are omitted since they are currently not necessary for the way in which - /// this class is used: - /// - TryAcquire - /// - Signal (use <see cref="Signal_Release"/> instead) - /// - SignalAll } } diff --git a/src/System.Private.CoreLib/src/System/Threading/LowLevelMonitor.Windows.cs b/src/System.Private.CoreLib/src/System/Threading/LowLevelMonitor.Windows.cs new file mode 100644 index 000000000..602908d6d --- /dev/null +++ b/src/System.Private.CoreLib/src/System/Threading/LowLevelMonitor.Windows.cs @@ -0,0 +1,67 @@ +// 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.Diagnostics; +using System.Runtime.InteropServices; +using Internal.Runtime.Augments; + +namespace System.Threading +{ + /// <summary> + /// Wraps a critical section and condition variable. + /// </summary> + internal sealed partial class LowLevelMonitor : IDisposable + { + private Interop.Kernel32.CRITICAL_SECTION _criticalSection; + private Interop.Kernel32.CONDITION_VARIABLE _conditionVariable; + + public LowLevelMonitor() + { + Interop.Kernel32.InitializeCriticalSection(out _criticalSection); + Interop.Kernel32.InitializeConditionVariable(out _conditionVariable); + } + + private void DisposeCore() + { + Interop.Kernel32.DeleteCriticalSection(ref _criticalSection); + } + + private void AcquireCore() + { + Interop.Kernel32.EnterCriticalSection(ref _criticalSection); + } + + private void ReleaseCore() + { + Interop.Kernel32.LeaveCriticalSection(ref _criticalSection); + } + + private void WaitCore() + { + WaitCore(-1); + } + + private bool WaitCore(int timeoutMilliseconds) + { + bool waitResult = Interop.Kernel32.SleepConditionVariableCS(ref _conditionVariable, ref _criticalSection, timeoutMilliseconds); + if (!waitResult) + { + int lastError = Marshal.GetLastWin32Error(); + if (lastError != Interop.Errors.ERROR_TIMEOUT) + { + var exception = new OutOfMemoryException(); + exception.SetErrorCode(lastError); + throw exception; + } + } + return waitResult; + } + + private void Signal_ReleaseCore() + { + Interop.Kernel32.WakeConditionVariable(ref _conditionVariable); + Interop.Kernel32.LeaveCriticalSection(ref _criticalSection); + } + } +} diff --git a/src/System.Private.CoreLib/src/System/Threading/LowLevelMonitor.cs b/src/System.Private.CoreLib/src/System/Threading/LowLevelMonitor.cs new file mode 100644 index 000000000..88f1f5725 --- /dev/null +++ b/src/System.Private.CoreLib/src/System/Threading/LowLevelMonitor.cs @@ -0,0 +1,116 @@ +// 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.Diagnostics; +using Internal.Runtime.Augments; + +namespace System.Threading +{ + /// <summary> + /// Wraps a non-recursive mutex and condition. + /// + /// Used by the wait subsystem on Unix, so this class cannot have any dependencies on the wait subsystem. + /// </summary> + internal sealed partial class LowLevelMonitor : IDisposable + { +#if DEBUG + private RuntimeThread _ownerThread = null; +#endif + + ~LowLevelMonitor() + { + Dispose(); + } + + public void Dispose() + { + VerifyIsNotLockedByAnyThread(); + DisposeCore(); + GC.SuppressFinalize(this); + } + +#if DEBUG + public bool IsLocked => _ownerThread == RuntimeThread.CurrentThread; +#endif + + public void VerifyIsLocked() + { +#if DEBUG + Debug.Assert(IsLocked); +#endif + } + + public void VerifyIsNotLocked() + { +#if DEBUG + Debug.Assert(!IsLocked); +#endif + } + + private void VerifyIsNotLockedByAnyThread() + { +#if DEBUG + Debug.Assert(_ownerThread == null); +#endif + } + + private void ResetOwnerThread() + { +#if DEBUG + VerifyIsLocked(); + _ownerThread = null; +#endif + } + + private void SetOwnerThreadToCurrent() + { +#if DEBUG + VerifyIsNotLockedByAnyThread(); + _ownerThread = RuntimeThread.CurrentThread; +#endif + } + + public void Acquire() + { + VerifyIsNotLocked(); + AcquireCore(); + SetOwnerThreadToCurrent(); + } + + public void Release() + { + ResetOwnerThread(); + ReleaseCore(); + } + + public void Wait() + { + ResetOwnerThread(); + WaitCore(); + SetOwnerThreadToCurrent(); + } + + public bool Wait(int timeoutMilliseconds) + { + Debug.Assert(timeoutMilliseconds >= -1); + + ResetOwnerThread(); + bool waitResult = WaitCore(timeoutMilliseconds); + SetOwnerThreadToCurrent(); + return waitResult; + } + + public void Signal_Release() + { + ResetOwnerThread(); + Signal_ReleaseCore(); + } + + /// The following methods typical in a monitor are omitted since they are currently not necessary for the way in which + /// this class is used: + /// - TryAcquire + /// - Signal (use <see cref="Signal_Release"/> instead) + /// - SignalAll + } +} diff --git a/src/System.Private.CoreLib/src/System/Threading/ThreadPool.Unix.cs b/src/System.Private.CoreLib/src/System/Threading/ThreadPool.Portable.cs index 4e4fe597e..f7dff9475 100644 --- a/src/System.Private.CoreLib/src/System/Threading/ThreadPool.Unix.cs +++ b/src/System.Private.CoreLib/src/System/Threading/ThreadPool.Portable.cs @@ -9,7 +9,7 @@ using Microsoft.Win32.SafeHandles; namespace System.Threading { // - // Unix-specific implementation of ThreadPool + // Portable implementation of ThreadPool // /// <summary> @@ -325,61 +325,43 @@ namespace System.Threading public static partial class ThreadPool { - // TODO: this is a very primitive (temporary) implementation of Thread Pool to allow Tasks to be - // used on Unix. All of this code must be replaced with proper implementation. - - /// <summary> - /// Max allowed number of threads in the thread pool. This is just arbitrary number - /// that is used to prevent unbounded creation of threads. - /// It should by high enough to provide sufficient number of thread pool workers - /// in case if some threads get blocked while running user code. - /// </summary> - private static readonly int MaxThreadCount = 4 * ThreadPoolGlobals.processorCount; - - /// <summary> - /// Semaphore that is used to release waiting thread pool workers when new work becomes available. - /// </summary> - private static SemaphoreSlim s_semaphore = new SemaphoreSlim(0); - - /// <summary> - /// Number of worker threads created by the thread pool. - /// </summary> - private static volatile int s_workerCount = 0; - public static bool SetMaxThreads(int workerThreads, int completionPortThreads) { - // Not supported at present - return false; + if (workerThreads < 0 || completionPortThreads < 0) + { + return false; + } + return ClrThreadPool.ThreadPoolInstance.SetMaxThreads(workerThreads); } public static void GetMaxThreads(out int workerThreads, out int completionPortThreads) { // Note that worker threads and completion port threads share the same thread pool. // The total number of threads cannot exceed MaxThreadCount. - workerThreads = MaxThreadCount; - completionPortThreads = MaxThreadCount; + workerThreads = ClrThreadPool.ThreadPoolInstance.GetMaxThreads(); + completionPortThreads = 1; } public static bool SetMinThreads(int workerThreads, int completionPortThreads) { - // Not supported at present - return false; + if (workerThreads < 0 || completionPortThreads < 0) + { + return false; + } + return ClrThreadPool.ThreadPoolInstance.SetMinThreads(workerThreads); } public static void GetMinThreads(out int workerThreads, out int completionPortThreads) { // All threads are pre-created at present - workerThreads = MaxThreadCount; - completionPortThreads = MaxThreadCount; + workerThreads = ClrThreadPool.ThreadPoolInstance.GetMinThreads(); + completionPortThreads = 0; } public static void GetAvailableThreads(out int workerThreads, out int completionPortThreads) { - // Make sure we return a non-negative value if thread pool defaults are changed - int availableThreads = Math.Max(MaxThreadCount - ThreadPoolGlobals.workQueue.numWorkingThreads, 0); - - workerThreads = availableThreads; - completionPortThreads = availableThreads; + workerThreads = ClrThreadPool.ThreadPoolInstance.GetAvailableThreads(); + completionPortThreads = 0; } /// <summary> @@ -387,22 +369,7 @@ namespace System.Threading /// </summary> internal static void RequestWorkerThread() { - // For simplicity of the state management, we pre-create all thread pool workers on the first - // request and then use the semaphore to release threads as new requests come in. - if ((s_workerCount == 0) && Interlocked.Exchange(ref s_workerCount, MaxThreadCount) == 0) - { - for (int i = 0; i < MaxThreadCount; i++) - { - if (!Interop.Sys.RuntimeThread_CreateThread(IntPtr.Zero /*use default stack size*/, - AddrofIntrinsics.AddrOf<Interop.Sys.ThreadProc>(ThreadPoolDispatchCallback), IntPtr.Zero)) - { - throw new OutOfMemoryException(); - } - } - } - - // Release one thread to handle the new request - s_semaphore.Release(1); + ClrThreadPool.ThreadPoolInstance.RequestWorker(); } internal static bool KeepDispatching(int startTickCount) @@ -412,32 +379,12 @@ namespace System.Threading internal static void NotifyWorkItemProgress() { + ClrThreadPool.ThreadPoolInstance.NotifyWorkItemComplete(); } internal static bool NotifyWorkItemComplete() { - return true; - } - - /// <summary> - /// This method is an entry point of a thread pool worker thread. - /// </summary> - [NativeCallable] - private static IntPtr ThreadPoolDispatchCallback(IntPtr context) - { - var wrapper = ThreadPoolCallbackWrapper.Enter(); - - do - { - // Handle pending requests - ThreadPoolWorkQueue.Dispatch(); - - // Wait for new requests to arrive - s_semaphore.Wait(); - - } while (true); - - //wrapper.Exit(resetThread: false); + return ClrThreadPool.ThreadPoolInstance.NotifyWorkItemComplete(); } private static RegisteredWaitHandle RegisterWaitForSingleObject( diff --git a/src/System.Private.CoreLib/src/System/Threading/ThreadPool.cs b/src/System.Private.CoreLib/src/System/Threading/ThreadPool.cs index e43665391..e1db16f85 100644 --- a/src/System.Private.CoreLib/src/System/Threading/ThreadPool.cs +++ b/src/System.Private.CoreLib/src/System/Threading/ThreadPool.cs @@ -58,12 +58,6 @@ namespace System.Threading public static WorkStealingQueue[] Queues => _queues; - // Track whether the WorkStealingQueueList is empty - // Three states simplifies race conditions. They may be considered. - // Now Active --> Maybe Inactive -> Confirmed Inactive - public const int WsqNowActive = 2; - public static int wsqActive; - public static void Add(WorkStealingQueue queue) { Debug.Assert(queue != null); @@ -386,6 +380,7 @@ namespace System.Threading missedSteal = true; } + return null; } } @@ -451,18 +446,6 @@ namespace System.Threading if (null != tl) { tl.workStealingQueue.LocalPush(callback); - - // We must guarantee wsqActive is set to WsqNowActive after we push - // The ordering must be global because we rely on other threads - // observing in this order - Interlocked.MemoryBarrier(); - - // We do not want to simply write. We want to prevent unnecessary writes - // which would invalidate reader's caches - if (WorkStealingQueueList.wsqActive != WorkStealingQueueList.WsqNowActive) - { - Volatile.Write(ref WorkStealingQueueList.wsqActive, WorkStealingQueueList.WsqNowActive); - } } else { @@ -480,56 +463,33 @@ namespace System.Threading public IThreadPoolWorkItem Dequeue(ThreadPoolWorkQueueThreadLocals tl, ref bool missedSteal) { + WorkStealingQueue localWsq = tl.workStealingQueue; IThreadPoolWorkItem callback; - int wsqActiveObserved = WorkStealingQueueList.wsqActive; - if (wsqActiveObserved > 0) - { - WorkStealingQueue localWsq = tl.workStealingQueue; - if ((callback = localWsq.LocalPop()) == null && // first try the local queue - !workItems.TryDequeue(out callback)) // then try the global queue + if ((callback = localWsq.LocalPop()) == null && // first try the local queue + !workItems.TryDequeue(out callback)) // then try the global queue + { + // finally try to steal from another thread's local queue + WorkStealingQueue[] queues = WorkStealingQueueList.Queues; + int c = queues.Length; + Debug.Assert(c > 0, "There must at least be a queue for this thread."); + int maxIndex = c - 1; + int i = tl.random.Next(c); + while (c > 0) { - // finally try to steal from another thread's local queue - WorkStealingQueue[] queues = WorkStealingQueueList.Queues; - int c = queues.Length; - Debug.Assert(c > 0, "There must at least be a queue for this thread."); - int maxIndex = c - 1; - int i = tl.random.Next(c); - while (c > 0) + i = (i < maxIndex) ? i + 1 : 0; + WorkStealingQueue otherQueue = queues[i]; + if (otherQueue != localWsq && otherQueue.CanSteal) { - i = (i < maxIndex) ? i + 1 : 0; - WorkStealingQueue otherQueue = queues[i]; - if (otherQueue != localWsq && otherQueue.CanSteal) + callback = otherQueue.TrySteal(ref missedSteal); + if (callback != null) { - callback = otherQueue.TrySteal(ref missedSteal); - if (callback != null) - { - break; - } + break; } - c--; - } - if ((callback == null) && !missedSteal) - { - // Only decrement if the value is unchanged since we started looking for work - // This prevents multiple threads decrementing based on overlapping scans. - // - // When we decrement from active, the producer may have inserted a queue item during our scan - // therefore we cannot transition to empty - // - // When we decrement from Maybe Inactive, if the producer inserted a queue item during our scan, - // the producer must write Active. We may transition to empty briefly if we beat the - // producer's write, but the producer will then overwrite us before waking threads. - // So effectively we cannot mark the queue empty when an item is in the queue. - Interlocked.CompareExchange(ref WorkStealingQueueList.wsqActive, wsqActiveObserved - 1, wsqActiveObserved); } + c--; } } - else - { - // We only need to look at the global queue since WorkStealingQueueList is inactive - workItems.TryDequeue(out callback); - } return callback; } @@ -642,7 +602,6 @@ namespace System.Threading } } - // Simple random number generator. We don't need great randomness, we just need a little and for it to be fast. internal struct FastRandom // xorshift prng { @@ -668,14 +627,12 @@ namespace System.Threading } } - // Holds a WorkStealingQueue, and remmoves it from the list when this object is no longer referened. internal sealed class ThreadPoolWorkQueueThreadLocals { [ThreadStatic] public static ThreadPoolWorkQueueThreadLocals threadLocals; - public readonly ThreadPoolWorkQueue workQueue; public readonly ThreadPoolWorkQueue.WorkStealingQueue workStealingQueue; public FastRandom random = new FastRandom(Environment.CurrentManagedThreadId); // mutable struct, do not copy or make readonly @@ -802,7 +759,6 @@ namespace System.Threading } } - internal sealed class QueueUserWorkItemCallbackDefaultContext : IThreadPoolWorkItem { private WaitCallback callback; @@ -1014,9 +970,12 @@ namespace System.Threading } public static bool QueueUserWorkItem(WaitCallback callBack) => - QueueUserWorkItem(callBack, null); + QueueUserWorkItem(callBack, null, preferLocal: false); - public static bool QueueUserWorkItem(WaitCallback callBack, object state) + public static bool QueueUserWorkItem(WaitCallback callBack, object state) => + QueueUserWorkItem(callBack, state, preferLocal: false); + + public static bool QueueUserWorkItem(WaitCallback callBack, object state, bool preferLocal) { if (callBack == null) { @@ -1029,7 +988,7 @@ namespace System.Threading new QueueUserWorkItemCallbackDefaultContext(callBack, state) : (IThreadPoolWorkItem)new QueueUserWorkItemCallback(callBack, state, context); - ThreadPoolGlobals.workQueue.Enqueue(tpcallBack, forceGlobal: true); + ThreadPoolGlobals.workQueue.Enqueue(tpcallBack, forceGlobal: !preferLocal); return true; } diff --git a/tests/src/Simple/HelloWasm/Program.cs b/tests/src/Simple/HelloWasm/Program.cs index 964bb1413..367a23c79 100644 --- a/tests/src/Simple/HelloWasm/Program.cs +++ b/tests/src/Simple/HelloWasm/Program.cs @@ -10,30 +10,22 @@ internal static class Program private static unsafe void Main(string[] args) { Add(1, 2); - TwoCharStr strStruct = new TwoCharStr(); - strStruct.first = (byte)'H'; - strStruct.second = (byte)'\0'; - printf((byte*)&strStruct, null); - strStruct.first = (byte)'i'; - printf((byte*)&strStruct, null); - strStruct.first = (byte)' '; - printf((byte*)&strStruct, null); - strStruct.first = (byte)'f'; - printf((byte*)&strStruct, null); - strStruct.first = (byte)'r'; - printf((byte*)&strStruct, null); - strStruct.first = (byte)'o'; - printf((byte*)&strStruct, null); - strStruct.first = (byte)'m'; - printf((byte*)&strStruct, null); - strStruct.first = (byte)' '; - printf((byte*)&strStruct, null); - strStruct.first = (byte)'C'; - printf((byte*)&strStruct, null); - strStruct.first = (byte)'#'; - printf((byte*)&strStruct, null); - strStruct.first = (byte)'!'; - printf((byte*)&strStruct, null); + + string s = "Hello from C#!"; + PrintString(s, 14); + } + + private static unsafe void PrintString(string s, int length) + { + fixed (char* curChar = s) + { + for (int i = 0; i < length; i++) + { + TwoByteStr curCharStr = new TwoByteStr(); + curCharStr.first = (byte)(*(curChar + i)); + printf((byte*)&curCharStr, null); + } + } } private static int Add(int a, int b) @@ -45,7 +37,7 @@ internal static class Program private static unsafe extern int printf(byte* str, byte* unused); } -public struct TwoCharStr +public struct TwoByteStr { public byte first; public byte second; diff --git a/tests/src/Simple/Threading/Threading.cs b/tests/src/Simple/Threading/Threading.cs index 038cb32bb..99d6b610e 100644 --- a/tests/src/Simple/Threading/Threading.cs +++ b/tests/src/Simple/Threading/Threading.cs @@ -4,7 +4,9 @@ using System; using System.Collections.Generic; +using System.Globalization; using System.Threading; +using System.Threading.Tasks; // TODO: Move these tests to CoreFX once they can be run on CoreRT @@ -36,6 +38,32 @@ internal static class Runner //Console.WriteLine(" WaitSubsystemTests.MutexMaximumReacquireCountTest"); //WaitSubsystemTests.MutexMaximumReacquireCountTest(); + Console.WriteLine(" ThreadPoolTests.RunProcessorCountItemsInParallel"); + ThreadPoolTests.RunProcessorCountItemsInParallel(); + + Console.WriteLine(" ThreadPoolTests.RunMoreThanMaxJobsMakesOneJobWaitForStarvationDetection"); + ThreadPoolTests.RunMoreThanMaxJobsMakesOneJobWaitForStarvationDetection(); + + Console.WriteLine(" ThreadPoolTests.ThreadPoolCanPickUpOneJobWhenThreadIsAvailable"); + ThreadPoolTests.ThreadPoolCanPickUpOneJobWhenThreadIsAvailable(); + + Console.WriteLine(" ThreadPoolTests.ThreadPoolCanPickUpMultipleJobsWhenThreadsAreAvailable"); + ThreadPoolTests.ThreadPoolCanPickUpMultipleJobsWhenThreadsAreAvailable(); + + // This test takes a long time to run (min 42 seconds sleeping). Enable for manual testing. + // Console.WriteLine(" ThreadPoolTests.RunJobsAfterThreadTimeout"); + // ThreadPoolTests.RunJobsAfterThreadTimeout(); + + Console.WriteLine(" ThreadPoolTests.WorkQueueDepletionTest"); + ThreadPoolTests.WorkQueueDepletionTest(); + + Console.WriteLine(" ThreadPoolTests.WorkerThreadStateReset"); + ThreadPoolTests.WorkerThreadStateReset(); + + // This test is not applicable (and will not pass) on Windows since it uses the Windows OS-provided thread pool. + // Console.WriteLine(" ThreadPoolTests.SettingMinThreadsWillCreateThreadsUpToMinimum"); + // ThreadPoolTests.SettingMinThreadsWillCreateThreadsUpToMinimum(); + Console.WriteLine(" WaitThreadTests.SignalingRegisteredHandleCallsCalback"); WaitThreadTests.SignalingRegisteredHandleCallsCalback(); @@ -806,6 +834,289 @@ internal static class WaitSubsystemTests } } +internal static class ThreadPoolTests +{ + [Fact] + public static void RunProcessorCountItemsInParallel() + { + int count = 0; + AutoResetEvent e0 = new AutoResetEvent(false); + for(int i = 0; i < Environment.ProcessorCount; ++i) + { + ThreadPool.QueueUserWorkItem( _ => { + if(Interlocked.Increment(ref count) == Environment.ProcessorCount) + { + e0.Set(); + } + }); + } + e0.CheckedWait(); + // Run the test again to make sure we can reuse the threads. + count = 0; + for(int i = 0; i < Environment.ProcessorCount; ++i) + { + ThreadPool.QueueUserWorkItem( _ => { + if(Interlocked.Increment(ref count) == Environment.ProcessorCount) + { + e0.Set(); + } + }); + } + e0.CheckedWait(); + } + + [Fact] + public static void RunMoreThanMaxJobsMakesOneJobWaitForStarvationDetection() + { + ManualResetEvent e0 = new ManualResetEvent(false); + AutoResetEvent jobsQueued = new AutoResetEvent(false); + int count = 0; + AutoResetEvent e1 = new AutoResetEvent(false); + for(int i = 0; i < Environment.ProcessorCount; ++i) + { + ThreadPool.QueueUserWorkItem( _ => { + if(Interlocked.Increment(ref count) == Environment.ProcessorCount) + { + jobsQueued.Set(); + } + e0.CheckedWait(); + }); + } + jobsQueued.CheckedWait(); + ThreadPool.QueueUserWorkItem( _ => e1.Set()); + Thread.Sleep(500); // Sleep for the gate thread delay to wait for starvation + e1.CheckedWait(); + e0.Set(); + } + + [Fact] + public static void ThreadPoolCanPickUpOneJobWhenThreadIsAvailable() + { + ManualResetEvent e0 = new ManualResetEvent(false); + AutoResetEvent jobsQueued = new AutoResetEvent(false); + AutoResetEvent testJobCompleted = new AutoResetEvent(false); + int count = 0; + + for(int i = 0; i < Environment.ProcessorCount - 1; ++i) + { + ThreadPool.QueueUserWorkItem( _ => { + if(Interlocked.Increment(ref count) == Environment.ProcessorCount - 1) + { + jobsQueued.Set(); + } + e0.CheckedWait(); + }); + } + jobsQueued.CheckedWait(); + ThreadPool.QueueUserWorkItem( _ => testJobCompleted.Set()); + testJobCompleted.CheckedWait(); + e0.Set(); + } + + [Fact] + public static void ThreadPoolCanPickUpMultipleJobsWhenThreadsAreAvailable() + { + ManualResetEvent e0 = new ManualResetEvent(false); + AutoResetEvent jobsQueued = new AutoResetEvent(false); + AutoResetEvent testJobCompleted = new AutoResetEvent(false); + int count = 0; + + for(int i = 0; i < Environment.ProcessorCount - 1; ++i) + { + ThreadPool.QueueUserWorkItem( _ => { + if(Interlocked.Increment(ref count) == Environment.ProcessorCount - 1) + { + jobsQueued.Set(); + } + e0.CheckedWait(); + }); + } + jobsQueued.CheckedWait(); + int testJobsCount = 0; + int maxCount = 5; + void Job(object _) + { + if(Interlocked.Increment(ref testJobsCount) != maxCount) + { + ThreadPool.QueueUserWorkItem(Job); + } + else + { + testJobCompleted.Set(); + } + } + ThreadPool.QueueUserWorkItem(Job); + testJobCompleted.CheckedWait(); + e0.Set(); + } + + private static WaitCallback CreateRecursiveJob(int jobCount, int targetJobCount, AutoResetEvent testJobCompleted) + { + return _ => + { + if (jobCount == targetJobCount) + { + testJobCompleted.Set(); + } + else + { + ThreadPool.QueueUserWorkItem(CreateRecursiveJob(jobCount + 1, targetJobCount, testJobCompleted)); + } + }; + } + + [Fact] + [OuterLoop] + public static void RunJobsAfterThreadTimeout() + { + ManualResetEvent e0 = new ManualResetEvent(false); + AutoResetEvent jobsQueued = new AutoResetEvent(false); + AutoResetEvent testJobCompleted = new AutoResetEvent(false); + int count = 0; + + for(int i = 0; i < Environment.ProcessorCount - 1; ++i) + { + ThreadPool.QueueUserWorkItem( _ => { + if(Interlocked.Increment(ref count) == Environment.ProcessorCount - 1) + { + jobsQueued.Set(); + } + e0.CheckedWait(); + }); + } + jobsQueued.CheckedWait(); + ThreadPool.QueueUserWorkItem( _ => testJobCompleted.Set()); + testJobCompleted.CheckedWait(); + Console.Write("Sleeping to time out thread\n"); + Thread.Sleep(21000); + ThreadPool.QueueUserWorkItem( _ => testJobCompleted.Set()); + testJobCompleted.CheckedWait(); + e0.Set(); + Console.Write("Sleeping to time out all threads\n"); + Thread.Sleep(21000); + ThreadPool.QueueUserWorkItem( _ => testJobCompleted.Set()); + testJobCompleted.CheckedWait(); + } + + [Fact] + public static void WorkQueueDepletionTest() + { + ManualResetEvent e0 = new ManualResetEvent(false); + int numLocalScheduled = 1; + int numGlobalScheduled = 1; + int numToSchedule = Environment.ProcessorCount * 64; + int numCompleted = 0; + object syncRoot = new object(); + void ThreadLocalJob() + { + if(Interlocked.Increment(ref numLocalScheduled) <= numToSchedule) + { + Task.Factory.StartNew(ThreadLocalJob); + } + if(Interlocked.Increment(ref numLocalScheduled) <= numToSchedule) + { + Task.Factory.StartNew(ThreadLocalJob); + } + if (Interlocked.Increment(ref numCompleted) == numToSchedule * 2) + { + e0.Set(); + } + } + void GlobalJob(object _) + { + if(Interlocked.Increment(ref numGlobalScheduled) <= numToSchedule) + { + ThreadPool.QueueUserWorkItem(GlobalJob); + } + if(Interlocked.Increment(ref numGlobalScheduled) <= numToSchedule) + { + ThreadPool.QueueUserWorkItem(GlobalJob); + } + if (Interlocked.Increment(ref numCompleted) == numToSchedule * 2) + { + e0.Set(); + } + } + Task.Factory.StartNew(ThreadLocalJob); + ThreadPool.QueueUserWorkItem(GlobalJob); + e0.CheckedWait(); + } + + [Fact] + public static void WorkerThreadStateReset() + { + var cultureInfo = new CultureInfo("pt-BR"); + var expectedCultureInfo = CultureInfo.CurrentCulture; + var expectedUICultureInfo = CultureInfo.CurrentUICulture; + int count = 0; + AutoResetEvent e0 = new AutoResetEvent(false); + for(int i = 0; i < Environment.ProcessorCount; ++i) + { + ThreadPool.QueueUserWorkItem( _ => { + CultureInfo.CurrentCulture = cultureInfo; + CultureInfo.CurrentUICulture = cultureInfo; + Thread.CurrentThread.Priority = ThreadPriority.AboveNormal; + if(Interlocked.Increment(ref count) == Environment.ProcessorCount) + { + e0.Set(); + } + }); + } + e0.CheckedWait(); + // Run the test again to make sure we can reuse the threads. + count = 0; + for(int i = 0; i < Environment.ProcessorCount; ++i) + { + ThreadPool.QueueUserWorkItem( _ => { + Assert.Equal(expectedCultureInfo, CultureInfo.CurrentCulture); + Assert.Equal(expectedUICultureInfo, CultureInfo.CurrentUICulture); + Assert.Equal(ThreadPriority.Normal, Thread.CurrentThread.Priority); + if(Interlocked.Increment(ref count) == Environment.ProcessorCount) + { + e0.Set(); + } + }); + } + e0.CheckedWait(); + } + + [Fact] + public static void SettingMinThreadsWillCreateThreadsUpToMinimum() + { + ThreadPool.GetMinThreads(out int minThreads, out int unusedMin); + ThreadPool.GetMaxThreads(out int maxThreads, out int unusedMax); + try + { + ManualResetEvent e0 = new ManualResetEvent(false); + AutoResetEvent jobsQueued = new AutoResetEvent(false); + int count = 0; + ThreadPool.SetMaxThreads(minThreads, unusedMax); + for(int i = 0; i < minThreads + 1; ++i) + { + ThreadPool.QueueUserWorkItem( _ => { + if(Interlocked.Increment(ref count) == minThreads + 1) + { + jobsQueued.Set(); + } + e0.CheckedWait(); + }); + } + Assert.False(jobsQueued.WaitOne(ThreadTestHelpers.ExpectedTimeoutMilliseconds)); + Assert.True(ThreadPool.SetMaxThreads(minThreads + 1, unusedMax)); + Assert.True(ThreadPool.SetMinThreads(minThreads + 1, unusedMin)); + + jobsQueued.CheckedWait(); + + e0.Set(); + } + finally + { + ThreadPool.SetMinThreads(minThreads, unusedMin); + ThreadPool.SetMaxThreads(maxThreads, unusedMax); + } + } +} + internal static class WaitThreadTests { private const int WaitThreadTimeoutTimeMs = 20000; @@ -1017,8 +1328,6 @@ internal static class ThreadTestHelpers } } - - internal sealed class InvalidWaitHandle : WaitHandle { } |