Improve Dictionary FindEntry CQ
authorBen Adams <thundercat@illyriad.co.uk>
Mon, 11 Dec 2017 02:19:19 +0000 (02:19 +0000)
committerJan Kotas <jkotas@microsoft.com>
Thu, 1 Mar 2018 22:07:02 +0000 (14:07 -0800)
src/mscorlib/shared/System/Collections/Generic/Dictionary.cs

index 1b89158..72c2a32 100644 (file)
@@ -362,15 +362,28 @@ namespace System.Collections.Generic
                 ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key);
             }
 
-            if (_buckets != null)
+            int[] buckets = _buckets;
+            int i = -1;
+            if (buckets != null)
             {
-                int hashCode = _comparer.GetHashCode(key) & 0x7FFFFFFF;
-                for (int i = _buckets[hashCode % _buckets.Length]; i >= 0; i = _entries[i].next)
+                IEqualityComparer<TKey> comparer = _comparer;
+                int hashCode = comparer.GetHashCode(key) & 0x7FFFFFFF;
+                i = buckets[hashCode % buckets.Length];
+
+                Entry[] entries = _entries;
+                do
                 {
-                    if (_entries[i].hashCode == hashCode && _comparer.Equals(_entries[i].key, key)) return i;
-                }
+                    // Should be a while loop https://github.com/dotnet/coreclr/issues/15476
+                    // Test in if to drop range check for following array access
+                    if ((uint)i >= (uint)entries.Length || (entries[i].hashCode == hashCode && comparer.Equals(entries[i].key, key)))
+                    {
+                        break;
+                    }
+
+                    i = entries[i].next;
+                } while (true);
             }
-            return -1;
+            return i;
         }
 
         private int Initialize(int capacity)