Skip to content

Remove unsafe code from IBinaryInteger.TryReadBigEndian implementations#127485

Merged
EgorBo merged 3 commits intodotnet:mainfrom
EgorBo:reduce-unsafe-tryreadbigendian
Apr 28, 2026
Merged

Remove unsafe code from IBinaryInteger.TryReadBigEndian implementations#127485
EgorBo merged 3 commits intodotnet:mainfrom
EgorBo:reduce-unsafe-tryreadbigendian

Conversation

@EgorBo
Copy link
Copy Markdown
Member

@EgorBo EgorBo commented Apr 28, 2026

Replaces Unsafe.ReadUnaligned / Unsafe.Add / MemoryMarshal.GetReference usage in IBinaryInteger<T>.TryReadBigEndian (Byte, SByte, Char, Int16/UInt16, Int32/UInt32, Int64/UInt64, IntPtr/UIntPtr, Int128/UInt128) with safe equivalents (BinaryPrimitives.ReadXxxBigEndian and span indexing). The JIT is expected to eliminate the resulting bounds checks given the existing length gates.

Note

This PR was authored with assistance from Copilot CLI.


UPD: blocked by #127486 (improved in JIT via #127488)

Diffs

Replace Unsafe.ReadUnaligned/Unsafe.Add/MemoryMarshal.GetReference usage
in TryReadBigEndian on Byte, SByte, Char, Int16/UInt16, Int32/UInt32,
Int64/UInt64, IntPtr/UIntPtr, Int128/UInt128 with safe equivalents
(BinaryPrimitives.ReadXxxBigEndian and span indexing).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings April 28, 2026 00:15
@EgorBo
Copy link
Copy Markdown
Member Author

EgorBo commented Apr 28, 2026

@MihuBot

@dotnet-policy-service
Copy link
Copy Markdown
Contributor

Tagging subscribers to this area: @dotnet/area-system-numerics
See info in area-owners.md if you want to be subscribed.

Copy link
Copy Markdown
Contributor

Copilot AI left a 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 refactors IBinaryInteger<T>.TryReadBigEndian implementations in System.Private.CoreLib primitive / intrinsic numeric types to avoid Unsafe.*-based unaligned reads and pointer arithmetic, using BinaryPrimitives.Read*BigEndian and ReadOnlySpan<byte> indexing instead.

Changes:

  • Replaced Unsafe.ReadUnaligned + manual endianness reversal with BinaryPrimitives.Read{U}Int{16|32|64|128}BigEndian on a tail slice of the input span.
  • Replaced Unsafe.Add(ref sourceRef, i) byte iteration with source[i] indexing in the small-length construction loops.
  • Updated nint/nuint big-endian reads to use BinaryPrimitives.ReadInt{32|64}BigEndian / ReadUInt{32|64}BigEndian under #if TARGET_64BIT.

Reviewed changes

Copilot reviewed 13 out of 13 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
src/libraries/System.Private.CoreLib/src/System/UIntPtr.cs Switches big-endian read to `BinaryPrimitives.ReadUInt{32
src/libraries/System.Private.CoreLib/src/System/UInt64.cs Uses BinaryPrimitives.ReadUInt64BigEndian and span indexing for fallback path.
src/libraries/System.Private.CoreLib/src/System/UInt32.cs Uses BinaryPrimitives.ReadUInt32BigEndian and span indexing for fallback path.
src/libraries/System.Private.CoreLib/src/System/UInt16.cs Uses BinaryPrimitives.ReadUInt16BigEndian and source[0] for the 1-byte case.
src/libraries/System.Private.CoreLib/src/System/UInt128.cs Uses BinaryPrimitives.ReadUInt128BigEndian and span indexing for fallback path.
src/libraries/System.Private.CoreLib/src/System/SByte.cs Replaces unsafe last-byte access with span indexing for big-endian 1-byte read.
src/libraries/System.Private.CoreLib/src/System/IntPtr.cs Switches big-endian read to `BinaryPrimitives.ReadInt{32
src/libraries/System.Private.CoreLib/src/System/Int64.cs Uses BinaryPrimitives.ReadInt64BigEndian and span indexing for fallback path.
src/libraries/System.Private.CoreLib/src/System/Int32.cs Uses BinaryPrimitives.ReadInt32BigEndian and span indexing for fallback path.
src/libraries/System.Private.CoreLib/src/System/Int16.cs Uses BinaryPrimitives.ReadInt16BigEndian and source[0] for the 1-byte cases (signed/unsigned).
src/libraries/System.Private.CoreLib/src/System/Int128.cs Uses BinaryPrimitives.ReadInt128BigEndian and span indexing for fallback path.
src/libraries/System.Private.CoreLib/src/System/Char.cs Uses BinaryPrimitives.ReadUInt16BigEndian (cast to char) and source[0] for the 1-byte case.
src/libraries/System.Private.CoreLib/src/System/Byte.cs Replaces unsafe last-byte access with span indexing for big-endian 1-byte read.

Comment thread src/libraries/System.Private.CoreLib/src/System/UIntPtr.cs Outdated
Comment thread src/libraries/System.Private.CoreLib/src/System/IntPtr.cs Outdated
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings April 28, 2026 01:06
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 13 out of 13 changed files in this pull request and generated 11 comments.

Comment thread src/libraries/System.Private.CoreLib/src/System/UInt32.cs
Comment thread src/libraries/System.Private.CoreLib/src/System/Int32.cs
Comment thread src/libraries/System.Private.CoreLib/src/System/UInt64.cs
Comment thread src/libraries/System.Private.CoreLib/src/System/Int64.cs
Comment thread src/libraries/System.Private.CoreLib/src/System/UInt16.cs
Comment thread src/libraries/System.Private.CoreLib/src/System/UInt128.cs
Comment thread src/libraries/System.Private.CoreLib/src/System/Int128.cs
Comment thread src/libraries/System.Private.CoreLib/src/System/UIntPtr.cs
Comment thread src/libraries/System.Private.CoreLib/src/System/IntPtr.cs
Comment thread src/libraries/System.Private.CoreLib/src/System/Char.cs
@EgorBo
Copy link
Copy Markdown
Member Author

EgorBo commented Apr 28, 2026

@MihuBot

@EgorBo EgorBo marked this pull request as ready for review April 28, 2026 11:25
Copilot AI review requested due to automatic review settings April 28, 2026 11:25
@EgorBo
Copy link
Copy Markdown
Member Author

EgorBo commented Apr 28, 2026

Diffs PTAL @MihaZupan @tannergooding

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 13 out of 13 changed files in this pull request and generated no new comments.

Copy link
Copy Markdown
Member

@MihaZupan MihaZupan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice!

@EgorBo EgorBo merged commit a96c392 into dotnet:main Apr 28, 2026
146 of 151 checks passed
@EgorBo EgorBo deleted the reduce-unsafe-tryreadbigendian branch April 28, 2026 17:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants