Added rehashing of hash tables when there are too many deleted elements.
authorbak@chromium.org <bak@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Tue, 5 Jan 2010 11:38:36 +0000 (11:38 +0000)
committerbak@chromium.org <bak@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Tue, 5 Jan 2010 11:38:36 +0000 (11:38 +0000)
Review URL: http://codereview.chromium.org/525024

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@3536 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/objects.cc
src/objects.h

index 52f1f9af616032caf774abe277b019746099322a..c30a64334905143220b2e2a1c486d4e5af996d9c 100644 (file)
@@ -6841,6 +6841,7 @@ Object* HashTable<Shape, Key>::Allocate(
   Object* obj = Heap::AllocateHashTable(EntryToIndex(capacity));
   if (!obj->IsFailure()) {
     HashTable::cast(obj)->SetNumberOfElements(0);
+    HashTable::cast(obj)->SetNumberOfDeletedElements(0);
     HashTable::cast(obj)->SetCapacity(capacity);
   }
   return obj;
@@ -6880,8 +6881,12 @@ template<typename Shape, typename Key>
 Object* HashTable<Shape, Key>::EnsureCapacity(int n, Key key) {
   int capacity = Capacity();
   int nof = NumberOfElements() + n;
-  // Make sure 50% is free
-  if (nof + (nof >> 1) <= capacity) return this;
+  int nod = NumberOfDeletedElements();
+  // Return if:
+  //   50% is still free after adding n elements and
+  //   at most 50% of the free elements are deleted elements.
+  if ((nof + (nof >> 1) <= capacity) &&
+      (nod <= (capacity - nof) >> 1) ) return this;
 
   Object* obj = Allocate(nof * 2);
   if (obj->IsFailure()) return obj;
@@ -6908,6 +6913,7 @@ Object* HashTable<Shape, Key>::EnsureCapacity(int n, Key key) {
     }
   }
   table->SetNumberOfElements(NumberOfElements());
+  table->SetNumberOfDeletedElements(0);
   return table;
 }
 
@@ -7703,7 +7709,7 @@ void NumberDictionary::RemoveNumberEntries(uint32_t from, uint32_t to) {
   }
 
   // Update the number of elements.
-  SetNumberOfElements(NumberOfElements() - removed_entries);
+  ElementsRemoved(removed_entries);
 }
 
 
index 55be2290e28a4b4db9d56111c2a7f39fc49b256d..d6670bb573505e02fbd22fb804a91d3fb36e5957 100644 (file)
@@ -1886,6 +1886,11 @@ class HashTable: public FixedArray {
     return Smi::cast(get(kNumberOfElementsIndex))->value();
   }
 
+  // Returns the number of deleted elements in the hash table.
+  int NumberOfDeletedElements() {
+    return Smi::cast(get(kNumberOfDeletedElementsIndex))->value();
+  }
+
   // Returns the capacity of the hash table.
   int Capacity() {
     return Smi::cast(get(kCapacityIndex))->value();
@@ -1897,8 +1902,14 @@ class HashTable: public FixedArray {
 
   // ElementRemoved should be called whenever an element is removed from
   // a hash table.
-  void ElementRemoved() { SetNumberOfElements(NumberOfElements() - 1); }
-  void ElementsRemoved(int n) { SetNumberOfElements(NumberOfElements() - n); }
+  void ElementRemoved() {
+    SetNumberOfElements(NumberOfElements() - 1);
+    SetNumberOfDeletedElements(NumberOfDeletedElements() + 1);
+  }
+  void ElementsRemoved(int n) {
+    SetNumberOfElements(NumberOfElements() - n);
+    SetNumberOfDeletedElements(NumberOfDeletedElements() + n);
+  }
 
   // Returns a new HashTable object. Might return Failure.
   static Object* Allocate(int at_least_space_for);
@@ -1925,12 +1936,13 @@ class HashTable: public FixedArray {
   }
 
   static const int kNumberOfElementsIndex = 0;
-  static const int kCapacityIndex         = 1;
-  static const int kPrefixStartIndex      = 2;
-  static const int kElementsStartIndex    =
+  static const int kNumberOfDeletedElementsIndex = 1;
+  static const int kCapacityIndex = 2;
+  static const int kPrefixStartIndex = 3;
+  static const int kElementsStartIndex =
       kPrefixStartIndex + Shape::kPrefixSize;
-  static const int kEntrySize             = Shape::kEntrySize;
-  static const int kElementsStartOffset   =
+  static const int kEntrySize = Shape::kEntrySize;
+  static const int kElementsStartOffset =
       kHeaderSize + kElementsStartIndex * kPointerSize;
 
   // Constant used for denoting a absent entry.
@@ -1955,6 +1967,11 @@ class HashTable: public FixedArray {
     fast_set(this, kNumberOfElementsIndex, Smi::FromInt(nof));
   }
 
+  // Update the number of deleted elements in the hash table.
+  void SetNumberOfDeletedElements(int nod) {
+    fast_set(this, kNumberOfDeletedElementsIndex, Smi::FromInt(nod));
+  }
+
   // Sets the capacity of the hash table.
   void SetCapacity(int capacity) {
     // To scale a computed hash code to fit within the hash table, we