Prevent infinite growth of the DenseMap.
authorJakob Stoklund Olesen <stoklund@2pi.dk>
Wed, 30 Mar 2011 18:32:41 +0000 (18:32 +0000)
committerJakob Stoklund Olesen <stoklund@2pi.dk>
Wed, 30 Mar 2011 18:32:41 +0000 (18:32 +0000)
When the hash function uses object pointers all free entries eventually
become tombstones as they are used at least once, regardless of the size.

DenseMap cannot function with zero empty keys, so it double size to get
get ridof the tombstones.

However DenseMap never shrinks automatically unless it is cleared, so
the net result is that certain tables grow infinitely.

The solution is to make a fresh copy of the table without tombstones
instead of doubling size, by simply calling grow with the current size.

Patch by José Fonseca!

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@128564 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/ADT/DenseMap.h

index 36e96b8c3d0a83f326231e438bd16cf11e62ab64..c0209d9a1810ee451e8aea919d4b6172c674b099 100644 (file)
@@ -289,11 +289,14 @@ private:
     // table completely filled with tombstones, no lookup would ever succeed,
     // causing infinite loops in lookup.
     ++NumEntries;
-    if (NumEntries*4 >= NumBuckets*3 ||
-        NumBuckets-(NumEntries+NumTombstones) < NumBuckets/8) {
+    if (NumEntries*4 >= NumBuckets*3) {
       this->grow(NumBuckets * 2);
       LookupBucketFor(Key, TheBucket);
     }
+    if (NumBuckets-(NumEntries+NumTombstones) < NumBuckets/8) {
+      this->grow(NumBuckets);
+      LookupBucketFor(Key, TheBucket);
+    }
 
     // If we are writing over a tombstone, remember this.
     if (!KeyInfoT::isEqual(TheBucket->first, getEmptyKey()))