Chromium Code Reviews| Index: src/objects.cc |
| =================================================================== |
| --- src/objects.cc (revision 2481) |
| +++ src/objects.cc (working copy) |
| @@ -6502,7 +6502,8 @@ |
| Object* HashTable<Shape, Key>::Allocate( |
| int at_least_space_for) { |
| int capacity = RoundUpToPowerOf2(at_least_space_for); |
| - if (capacity < 4) capacity = 4; // Guarantee min capacity. |
| + static const int kMinCapacity = 16; |
| + if (capacity < kMinCapacity) capacity = kMinCapacity; |
| Object* obj = Heap::AllocateHashTable(EntryToIndex(capacity)); |
| if (!obj->IsFailure()) { |
| HashTable::cast(obj)->SetNumberOfElements(0); |
| @@ -6516,26 +6517,25 @@ |
| // Find entry for key otherwise return -1. |
| template<typename Shape, typename Key> |
| int HashTable<Shape, Key>::FindEntry(Key key) { |
| - uint32_t nof = NumberOfElements(); |
| - if (nof == 0) return kNotFound; // Bail out if empty. |
| - |
| - uint32_t capacity = Capacity(); |
| + uint32_t mask = Capacity() - 1; |
| uint32_t hash = Shape::Hash(key); |
| - uint32_t entry = GetProbe(hash, 0, capacity); |
| - Object* element = KeyAt(entry); |
| - uint32_t passed_elements = 0; |
| - if (!element->IsNull()) { |
| - if (!element->IsUndefined() && Shape::IsMatch(key, element)) return entry; |
| - if (++passed_elements == nof) return kNotFound; |
| + // For the first probes rotate the hash to ensure a proper spread. |
| + for (uint32_t i = 0; i < kNofFastProbes; i++) { |
| + int entry = hash & mask; |
| + Object* element = KeyAt(entry); |
| + if (element->IsUndefined()) return kNotFound; |
| + if (!element->IsNull() && Shape::IsMatch(key, element)) return entry; |
| + hash = RotateRight(hash, kHashRotateShift); |
| } |
| - for (uint32_t i = 1; !element->IsUndefined(); i++) { |
| - entry = GetProbe(hash, i, capacity); |
| - element = KeyAt(entry); |
| - if (!element->IsNull()) { |
| - if (!element->IsUndefined() && Shape::IsMatch(key, element)) return entry; |
| - if (++passed_elements == nof) return kNotFound; |
| - } |
| + |
| + |
| + // In this unlikely event, do a linear scan. |
| + for (uint32_t i = 1; i <= mask; i++) { |
| + int entry = ++hash & mask; |
| + Object* element = KeyAt(entry); |
| + if (element->IsUndefined()) return kNotFound; |
| + if (!element->IsNull() && Shape::IsMatch(key, element)) return entry; |
| } |
| return kNotFound; |
| } |
| @@ -6546,7 +6546,7 @@ |
| int capacity = Capacity(); |
| int nof = NumberOfElements() + n; |
| // Make sure 50% is free |
| - if (nof + (nof >> 1) <= capacity) return this; |
| + if (nof + (nof>>1) <= capacity) return this; |
|
Kasper Lund
2009/07/16 12:41:43
Why did you remove the whitespace here?
bak
2009/07/16 12:52:41
Too old to remember. I've added the missing spaces
|
| Object* obj = Allocate(nof * 2); |
| if (obj->IsFailure()) return obj; |
| @@ -6579,15 +6579,23 @@ |
| template<typename Shape, typename Key> |
| uint32_t HashTable<Shape, Key>::FindInsertionEntry(uint32_t hash) { |
| - uint32_t capacity = Capacity(); |
| - uint32_t entry = GetProbe(hash, 0, capacity); |
| - Object* element = KeyAt(entry); |
| + uint32_t mask = Capacity() - 1; |
| + int entry; |
| + Object* element; |
| - for (uint32_t i = 1; !(element->IsUndefined() || element->IsNull()); i++) { |
| - entry = GetProbe(hash, i, capacity); |
| + // For the first probes rotate the hash to ensure a proper spread. |
| + for (uint32_t i = 0; i < kNofFastProbes; i++) { |
| + entry = hash & mask; |
| element = KeyAt(entry); |
| + if (element->IsUndefined() || element->IsNull()) return entry; |
| + hash = RotateRight(hash, kHashRotateShift); |
| } |
| + do { |
| + entry = ++hash & mask; |
| + element = KeyAt(entry); |
| + } while(!(element->IsUndefined() || element->IsNull())); |
| + |
| return entry; |
| } |
| @@ -6666,6 +6674,10 @@ |
| template |
| int Dictionary<StringDictionaryShape, String*>::NumberOfEnumElements(); |
| +template |
| +int HashTable<NumberDictionaryShape, uint32_t>::FindEntry(uint32_t key); |
| + |
| + |
| // Collates undefined and unexisting elements below limit from position |
| // zero of the elements. The object stays in Dictionary mode. |
| Object* JSObject::PrepareSlowElementsForSort(uint32_t limit) { |
| @@ -7021,7 +7033,7 @@ |
| uint32_t HashForObject(Object* obj) { |
| FixedArray* symbols = FixedArray::cast(obj); |
| int len = symbols->length(); |
| - uint32_t hash = 0; |
| + uint32_t hash = 40617523; // In case the array is empty. |
| for (int i = 0; i < len; i++) { |
| hash ^= String::cast(symbols->get(i))->Hash(); |
| } |