Commit 9f0997f9 authored by bak@chromium.org's avatar bak@chromium.org

Added rehashing of hash tables when there are too many deleted elements.

Review URL: http://codereview.chromium.org/525024

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@3536 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent b74ab450
...@@ -6841,6 +6841,7 @@ Object* HashTable<Shape, Key>::Allocate( ...@@ -6841,6 +6841,7 @@ Object* HashTable<Shape, Key>::Allocate(
Object* obj = Heap::AllocateHashTable(EntryToIndex(capacity)); Object* obj = Heap::AllocateHashTable(EntryToIndex(capacity));
if (!obj->IsFailure()) { if (!obj->IsFailure()) {
HashTable::cast(obj)->SetNumberOfElements(0); HashTable::cast(obj)->SetNumberOfElements(0);
HashTable::cast(obj)->SetNumberOfDeletedElements(0);
HashTable::cast(obj)->SetCapacity(capacity); HashTable::cast(obj)->SetCapacity(capacity);
} }
return obj; return obj;
...@@ -6880,8 +6881,12 @@ template<typename Shape, typename Key> ...@@ -6880,8 +6881,12 @@ template<typename Shape, typename Key>
Object* HashTable<Shape, Key>::EnsureCapacity(int n, Key key) { Object* HashTable<Shape, Key>::EnsureCapacity(int n, Key key) {
int capacity = Capacity(); int capacity = Capacity();
int nof = NumberOfElements() + n; int nof = NumberOfElements() + n;
// Make sure 50% is free int nod = NumberOfDeletedElements();
if (nof + (nof >> 1) <= capacity) return this; // 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); Object* obj = Allocate(nof * 2);
if (obj->IsFailure()) return obj; if (obj->IsFailure()) return obj;
...@@ -6908,6 +6913,7 @@ Object* HashTable<Shape, Key>::EnsureCapacity(int n, Key key) { ...@@ -6908,6 +6913,7 @@ Object* HashTable<Shape, Key>::EnsureCapacity(int n, Key key) {
} }
} }
table->SetNumberOfElements(NumberOfElements()); table->SetNumberOfElements(NumberOfElements());
table->SetNumberOfDeletedElements(0);
return table; return table;
} }
...@@ -7703,7 +7709,7 @@ void NumberDictionary::RemoveNumberEntries(uint32_t from, uint32_t to) { ...@@ -7703,7 +7709,7 @@ void NumberDictionary::RemoveNumberEntries(uint32_t from, uint32_t to) {
} }
// Update the number of elements. // Update the number of elements.
SetNumberOfElements(NumberOfElements() - removed_entries); ElementsRemoved(removed_entries);
} }
......
...@@ -1886,6 +1886,11 @@ class HashTable: public FixedArray { ...@@ -1886,6 +1886,11 @@ class HashTable: public FixedArray {
return Smi::cast(get(kNumberOfElementsIndex))->value(); 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. // Returns the capacity of the hash table.
int Capacity() { int Capacity() {
return Smi::cast(get(kCapacityIndex))->value(); return Smi::cast(get(kCapacityIndex))->value();
...@@ -1897,8 +1902,14 @@ class HashTable: public FixedArray { ...@@ -1897,8 +1902,14 @@ class HashTable: public FixedArray {
// ElementRemoved should be called whenever an element is removed from // ElementRemoved should be called whenever an element is removed from
// a hash table. // a hash table.
void ElementRemoved() { SetNumberOfElements(NumberOfElements() - 1); } void ElementRemoved() {
void ElementsRemoved(int n) { SetNumberOfElements(NumberOfElements() - n); } SetNumberOfElements(NumberOfElements() - 1);
SetNumberOfDeletedElements(NumberOfDeletedElements() + 1);
}
void ElementsRemoved(int n) {
SetNumberOfElements(NumberOfElements() - n);
SetNumberOfDeletedElements(NumberOfDeletedElements() + n);
}
// Returns a new HashTable object. Might return Failure. // Returns a new HashTable object. Might return Failure.
static Object* Allocate(int at_least_space_for); static Object* Allocate(int at_least_space_for);
...@@ -1925,12 +1936,13 @@ class HashTable: public FixedArray { ...@@ -1925,12 +1936,13 @@ class HashTable: public FixedArray {
} }
static const int kNumberOfElementsIndex = 0; static const int kNumberOfElementsIndex = 0;
static const int kCapacityIndex = 1; static const int kNumberOfDeletedElementsIndex = 1;
static const int kPrefixStartIndex = 2; static const int kCapacityIndex = 2;
static const int kElementsStartIndex = static const int kPrefixStartIndex = 3;
static const int kElementsStartIndex =
kPrefixStartIndex + Shape::kPrefixSize; kPrefixStartIndex + Shape::kPrefixSize;
static const int kEntrySize = Shape::kEntrySize; static const int kEntrySize = Shape::kEntrySize;
static const int kElementsStartOffset = static const int kElementsStartOffset =
kHeaderSize + kElementsStartIndex * kPointerSize; kHeaderSize + kElementsStartIndex * kPointerSize;
// Constant used for denoting a absent entry. // Constant used for denoting a absent entry.
...@@ -1955,6 +1967,11 @@ class HashTable: public FixedArray { ...@@ -1955,6 +1967,11 @@ class HashTable: public FixedArray {
fast_set(this, kNumberOfElementsIndex, Smi::FromInt(nof)); 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. // Sets the capacity of the hash table.
void SetCapacity(int capacity) { void SetCapacity(int capacity) {
// To scale a computed hash code to fit within the hash table, we // To scale a computed hash code to fit within the hash table, we
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment