Skip to content

Commit 3b824aa

Browse files
authored
Fix IndexOutOfRangeException in CallSite.MoveRule. (#39159)
Because synchronization of AddRule is omitted for performance, concurrent invocations of AddRule may cause Rules to revert back to an older (smaller) version, making i out of bounds. Add a guard against that. The reasoning behind no synchronization is that Rules is just a cache after all. As long as the cache is in a consistent state, wrong updates will only cause more cache misses or longer lookup time. This performance loss is fine if we get more performance gain by omitting synchronization. Fix #36983
1 parent b61effa commit 3b824aa

File tree

1 file changed

+9
-4
lines changed
  • src/libraries/System.Linq.Expressions/src/System/Runtime/CompilerServices

1 file changed

+9
-4
lines changed

src/libraries/System.Linq.Expressions/src/System/Runtime/CompilerServices/CallSite.cs

+9-4
Original file line numberDiff line numberDiff line change
@@ -266,11 +266,16 @@ internal void MoveRule(int i)
266266
if (i > 1)
267267
{
268268
T[] rules = Rules!;
269-
T rule = rules[i];
269+
// Synchronization of AddRule is omitted for performance. Concurrent invocations of AddRule
270+
// may cause Rules to revert back to an older (smaller) version, making i out of bounds.
271+
if (i < rules.Length)
272+
{
273+
T rule = rules[i];
270274

271-
rules[i] = rules[i - 1];
272-
rules[i - 1] = rules[i - 2];
273-
rules[i - 2] = rule;
275+
rules[i] = rules[i - 1];
276+
rules[i - 1] = rules[i - 2];
277+
rules[i - 2] = rule;
278+
}
274279
}
275280
}
276281

0 commit comments

Comments
 (0)