[LLVMdev] [PATCH 2/5] Prevent infinite growth of SmallMap instances.

jfonseca at vmware.com
2011-03-15T23:15:52Z

From: José Fonseca <jfonseca at vmware.com>

Rehash but don't grow when full of tombstones.
---
 include/llvm/ADT/StringMap.h |   16 ++--------------
 lib/Support/StringMap.cpp    |   14 +++++++++++++-
 2 files changed, 15 insertions(+), 15 deletions(-)

diff --git a/include/llvm/ADT/StringMap.h b/include/llvm/ADT/StringMap.h
index bad0e6f..f3d6b9f 100644
--- a/include/llvm/ADT/StringMap.h
+++ b/include/llvm/ADT/StringMap.h
@@ -81,16 +81,6 @@ protected:
   StringMapImpl(unsigned InitSize, unsigned ItemSize);
   void RehashTable();

-  /// ShouldRehash - Return true if the table should be rehashed after a new
-  /// element was recently inserted.
-  bool ShouldRehash() const {
-    // If the hash table is now more than 3/4 full, or if fewer than 1/8 of
-    // the buckets are empty (meaning that many are filled with tombstones),
-    // grow the table.
-    return NumItems*4 > NumBuckets*3 ||
-           NumBuckets-(NumItems+NumTombstones) < NumBuckets/8;
-  }
-
   /// LookupBucketFor - Look up the bucket that the specified string should end
   /// up in.  If it already exists as a key in the map, the Item pointer for
the
   /// specified bucket will be non-null.  Otherwise, it will be null.  In
either
@@ -340,8 +330,7 @@ public:
     Bucket.Item = KeyValue;
     ++NumItems;

-    if (ShouldRehash())
-      RehashTable();
+    RehashTable();
     return true;
   }

@@ -383,8 +372,7 @@ public:
     // filled in by LookupBucketFor.
     Bucket.Item = NewItem;

-    if (ShouldRehash())
-      RehashTable();
+    RehashTable();
     return *NewItem;
   }

diff --git a/lib/Support/StringMap.cpp b/lib/Support/StringMap.cpp
index 90ec299..f193aa4 100644
--- a/lib/Support/StringMap.cpp
+++ b/lib/Support/StringMap.cpp
@@ -177,7 +177,19 @@ StringMapEntryBase *StringMapImpl::RemoveKey(StringRef Key)
{
 /// RehashTable - Grow the table, redistributing values into the buckets with
 /// the appropriate mod-of-hashtable-size.
 void StringMapImpl::RehashTable() {
-  unsigned NewSize = NumBuckets*2;
+  unsigned NewSize;
+
+  // If the hash table is now more than 3/4 full, or if fewer than 1/8 of
+  // the buckets are empty (meaning that many are filled with tombstones),
+  // grow/rehash the table.
+  if (NumItems*4 > NumBuckets*3) {
+    NewSize = NumBuckets*2;
+  } else if (NumBuckets-(NumItems+NumTombstones) < NumBuckets/8) {
+    NewSize = NumBuckets;
+  } else {
+    return;
+  }
+
   // Allocate one extra bucket which will always be non-empty.  This allows the
   // iterators to stop at end.
   ItemBucket *NewTableArray =(ItemBucket*)calloc(NewSize+1,
sizeof(ItemBucket));
--
1.7.4.1