From d703a22938ef94deeff54483791b65569b7a7939 Mon Sep 17 00:00:00 2001 From: Ben Adams Date: Thu, 9 Feb 2017 15:11:09 +0000 Subject: [PATCH] Inlinable ArraySegment ctor (dotnet/coreclr#9433) Commit migrated from https://github.com/dotnet/coreclr/commit/7d81c60da7846d73df31d657a5c8c27aaed15d83 --- .../src/mscorlib/src/System/ArraySegment.cs | 14 ++++--------- src/coreclr/src/mscorlib/src/System/ThrowHelper.cs | 23 ++++++++++++++++++++-- 2 files changed, 25 insertions(+), 12 deletions(-) diff --git a/src/coreclr/src/mscorlib/src/System/ArraySegment.cs b/src/coreclr/src/mscorlib/src/System/ArraySegment.cs index b767e7b..03556e4 100644 --- a/src/coreclr/src/mscorlib/src/System/ArraySegment.cs +++ b/src/coreclr/src/mscorlib/src/System/ArraySegment.cs @@ -15,8 +15,6 @@ using System.Collections; using System.Collections.Generic; -using System.Runtime.InteropServices; -using System.Diagnostics; using System.Diagnostics.Contracts; namespace System @@ -46,14 +44,10 @@ namespace System public ArraySegment(T[] array, int offset, int count) { - if (array == null) - ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array); - if (offset < 0) - ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.offset, ExceptionResource.ArgumentOutOfRange_NeedNonNegNum); - if (count < 0) - ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.count, ExceptionResource.ArgumentOutOfRange_NeedNonNegNum); - if (array.Length - offset < count) - ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_InvalidOffLen); + // Validate arguments, check is minimal instructions with reduced branching for inlinable fast-path + // Failure should be rare and location determination and message is delegated to failure functions + if (array == null || (offset | count) < 0 || (array.Length - offset < count)) + ThrowHelper.ThrowArraySegmentCtorValidationFailedExceptions(array, offset, count); Contract.EndContractBlock(); _array = array; diff --git a/src/coreclr/src/mscorlib/src/System/ThrowHelper.cs b/src/coreclr/src/mscorlib/src/System/ThrowHelper.cs index 5ba7a30..a48bb60 100644 --- a/src/coreclr/src/mscorlib/src/System/ThrowHelper.cs +++ b/src/coreclr/src/mscorlib/src/System/ThrowHelper.cs @@ -39,7 +39,6 @@ namespace System { using Collections.Generic; using System.Runtime.CompilerServices; using System.Runtime.Serialization; - using System.Diagnostics; using System.Diagnostics.Contracts; [Pure] @@ -125,8 +124,12 @@ namespace System { throw GetArgumentException(resource, argument); } + private static ArgumentNullException GetArgumentNullException(ExceptionArgument argument) { + return new ArgumentNullException(GetArgumentName(argument)); + } + internal static void ThrowArgumentNullException(ExceptionArgument argument) { - throw new ArgumentNullException(GetArgumentName(argument)); + throw GetArgumentNullException(argument); } internal static void ThrowArgumentNullException(ExceptionResource resource) { @@ -209,6 +212,22 @@ namespace System { throw GetInvalidOperationException(ExceptionResource.InvalidOperation_EnumOpCantHappen); } + internal static void ThrowArraySegmentCtorValidationFailedExceptions(Array array, int offset, int count) { + throw GetArraySegmentCtorValidationFailedException(array, offset, count); + } + + private static Exception GetArraySegmentCtorValidationFailedException(Array array, int offset, int count) { + if (array == null) + return GetArgumentNullException(ExceptionArgument.array); + if (offset < 0) + return GetArgumentOutOfRangeException(ExceptionArgument.offset, ExceptionResource.ArgumentOutOfRange_NeedNonNegNum); + if (count < 0) + return GetArgumentOutOfRangeException(ExceptionArgument.count, ExceptionResource.ArgumentOutOfRange_NeedNonNegNum); + + Debug.Assert(array.Length - offset < count); + return GetArgumentException(ExceptionResource.Argument_InvalidOffLen); + } + private static ArgumentException GetArgumentException(ExceptionResource resource) { return new ArgumentException(GetResourceString(resource)); } -- 2.7.4