Skip to content

Conversation

prozolic
Copy link
Contributor

This PR replaces signed comparisons with unsigned comparisons in bounds checking for ImmutableArray<T>.Builder indexer and ItemRef method. Change bounds check from if (index >= this.Count) to if ((uint)index >= (uint)this.Count).

…ng ImmutableArray<T>.Builder indexer and ItemRef method.
@EgorBo
Copy link
Member

EgorBo commented Oct 19, 2025

Any specific pattern you're trying to improve? can you provide before/after asm for it?

Although, your change kind of makes sense to me, It looks like it's mostly a regression, see MihuBot/runtime-utils#1584 (comment)

@xtqqczze
Copy link
Contributor

What is the motivation for the change, is it a correctness issue?

@prozolic
Copy link
Contributor Author

@EgorBo Thanks for the feedback.

With the current implementation, negative indices pass the bounds check (-1 >= this.Count is false), and the exception is only thrown later by the array access itself. While the result is the same IndexOutOfRangeException, I think that this seems inconsistent with explicit bounds checking semantics.

However, I understand that this change leads to a significant performance regression as shown in MihuBot/runtime-utils#1584. Considering performance regression, would you prefer that I close this PR?

@EgorBo
Copy link
Member

EgorBo commented Oct 19, 2025

I think that this seems inconsistent with explicit bounds checking semantics.

Ah, I see. Looks like in both cases exactly the same exception is thrown - IndexOutOfRangeException with the same text, so not sure it's actually an issue? stack-trace might be slightly different, thought:

too big index:

Unhandled exception. System.IndexOutOfRangeException: Index was outside the bounds of the array.
   at System.Collections.Immutable.ImmutableArray`1.Builder.ThrowIndexOutOfRangeException()
   at System.Collections.Immutable.ImmutableArray`1.Builder.ItemRef(Int32 index)

negative index:

Unhandled exception. System.IndexOutOfRangeException: Index was outside the bounds of the array.
   at System.Collections.Immutable.ImmutableArray`1.Builder.ItemRef(Int32 index)

@xtqqczze
Copy link
Contributor

stack-trace might be slightly different, thought:

The stack trace differs only because ThrowIndexOutOfRangeException doesn’t have the [StackTraceHidden] attribute that most throw helpers have.

@EgorBo
Copy link
Member

EgorBo commented Oct 19, 2025

stack-trace might be slightly different, thought:

The stack trace differs only because ThrowIndexOutOfRangeException doesn’t have the [StackTraceHidden] attribute that most throw helpers have.

I don't think we have a rule to slap that attribute on the throw helpers. in Release, stack-traces get cut due to inlining and tail-calls heavily, so we'd better not hide frames which may help identify the actual source of the exception

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area-System.Collections community-contribution Indicates that the PR has been added by a community member

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants