-
Notifications
You must be signed in to change notification settings - Fork 5k
Unify Span/Memory slicing exceptions #115275
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR unifies the exception behavior for Span/Memory slicing operations by removing parameter name disclosures and consolidating bounds checking into MemoryExtensions.ValidateSliceArguments.
- Replaces legacy bounds checking (with TARGET_64BIT conditionals) with calls to MemoryExtensions.ValidateSliceArguments or MemoryExtensions.SliceArgumentsAreValid.
- Updates multiple methods and tests to throw exceptions without including parameter name details.
Reviewed Changes
Copilot reviewed 12 out of 12 changed files in this pull request and generated no comments.
Show a summary per file
File | Description |
---|---|
System/String.cs | Replaces custom bounds checking with MemoryExtensions.SliceArgumentsAreValid. |
System/String.Manipulation.cs | Updates Substring slicing bounds check to use ValidateSliceArguments. |
System/Span.cs | Replaces legacy conditional bounds checks with a unified ValidateSliceArguments call. |
System/Runtime/InteropServices/MemoryMarshal.cs | Updates bounds check to use ValidateSliceArguments. |
System/ReadOnlySpan.cs | Replaces conditional checks with a unified ValidateSliceArguments call. |
System/ReadOnlyMemory.cs | Updates slicing bounds checking and exception throwing to the new unified approach. |
System/Range.cs | Removes parameter name from ArgumentOutOfRange exception. |
System/MemoryExtensions.cs | Adds SliceArgumentsAreValid and ValidateSliceArguments methods to encapsulate bounds checking. |
System/Memory.cs | Replaces legacy bounds checks with ValidateSliceArguments calls. |
System/ArraySegment.cs | Updates argument validation to use SliceArgumentsAreValid. |
Tests | Adjust tests to expect exceptions without a parameter name. |
Tagging subscribers to this area: @dotnet/area-system-memory |
if ((uint)start > (uint)_length || (uint)length > (uint)(_length - start)) | ||
ThrowHelper.ThrowArgumentOutOfRangeException(); | ||
#endif | ||
MemoryExtensions.ValidateSliceArguments(_length, start, length); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This introduces two more levels of inlining. We may want to check that it is not regressing code quality.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Total bytes of delta: -5703 (-0.01 % of base)
I did spot check a couple diffs from PMI MihuBot/runtime-utils#1079, not seeing anything egregious (not seeing a lot less inlining).
As expected there's a bunch of small size improvements from cold blocks sharing the same throw helper (just Throw()
instead of Throw()
and Throw(int)
).
E.g. MemoryExtensions:Trim[int]
, GetRedactedPathAndQuery
, Json.Serialization.Converters.Int128Converter:WriteCore
Most diffs are from string.Substring(int, int)
getting inlined more.
E.g. ParseTimeZoneIds
, EncodingTable:GetEncodings()
, TimeZoneInfo:.ctor
And a handful of cases where a helper is no longer being inlined, e.g.
Http3Frame:TryReadIntegerPair
I'll have to tweak that one, unless we'd be fine with just throwing a less informative argument exception. Edit: Kept |
Fixes #115239
Fixes #53622
Fixes #90939
We no longer report the
"start"
parameter name in these exceptions.We could keeep it in the
.Slice(int)
overloads (no explicit length), but we were already inconsistent there too sinceSpan
doesn't report the parameter, butReadOnlySpan
does.