 Chromium Code Reviews
 Chromium Code Reviews Issue 525024:
  Added rehashing of hash tables when there are too many deleted elements.  (Closed) 
  Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
    
  
    Issue 525024:
  Added rehashing of hash tables when there are too many deleted elements.  (Closed) 
  Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/| OLD | NEW | 
|---|---|
| 1 // Copyright 2006-2009 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2009 the V8 project authors. All rights reserved. | 
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without | 
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are | 
| 4 // met: | 4 // met: | 
| 5 // | 5 // | 
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright | 
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. | 
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above | 
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following | 
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided | 
| (...skipping 6823 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6834 | 6834 | 
| 6835 | 6835 | 
| 6836 template<typename Shape, typename Key> | 6836 template<typename Shape, typename Key> | 
| 6837 Object* HashTable<Shape, Key>::Allocate( | 6837 Object* HashTable<Shape, Key>::Allocate( | 
| 6838 int at_least_space_for) { | 6838 int at_least_space_for) { | 
| 6839 int capacity = RoundUpToPowerOf2(at_least_space_for); | 6839 int capacity = RoundUpToPowerOf2(at_least_space_for); | 
| 6840 if (capacity < 4) capacity = 4; // Guarantee min capacity. | 6840 if (capacity < 4) capacity = 4; // Guarantee min capacity. | 
| 6841 Object* obj = Heap::AllocateHashTable(EntryToIndex(capacity)); | 6841 Object* obj = Heap::AllocateHashTable(EntryToIndex(capacity)); | 
| 6842 if (!obj->IsFailure()) { | 6842 if (!obj->IsFailure()) { | 
| 6843 HashTable::cast(obj)->SetNumberOfElements(0); | 6843 HashTable::cast(obj)->SetNumberOfElements(0); | 
| 6844 HashTable::cast(obj)->SetNumberOfDeletedElements(0); | |
| 6844 HashTable::cast(obj)->SetCapacity(capacity); | 6845 HashTable::cast(obj)->SetCapacity(capacity); | 
| 6845 } | 6846 } | 
| 6846 return obj; | 6847 return obj; | 
| 6847 } | 6848 } | 
| 6848 | 6849 | 
| 6849 | 6850 | 
| 6850 | 6851 | 
| 6851 // Find entry for key otherwise return -1. | 6852 // Find entry for key otherwise return -1. | 
| 6852 template<typename Shape, typename Key> | 6853 template<typename Shape, typename Key> | 
| 6853 int HashTable<Shape, Key>::FindEntry(Key key) { | 6854 int HashTable<Shape, Key>::FindEntry(Key key) { | 
| (...skipping 19 matching lines...) Expand all Loading... | |
| 6873 } | 6874 } | 
| 6874 } | 6875 } | 
| 6875 return kNotFound; | 6876 return kNotFound; | 
| 6876 } | 6877 } | 
| 6877 | 6878 | 
| 6878 | 6879 | 
| 6879 template<typename Shape, typename Key> | 6880 template<typename Shape, typename Key> | 
| 6880 Object* HashTable<Shape, Key>::EnsureCapacity(int n, Key key) { | 6881 Object* HashTable<Shape, Key>::EnsureCapacity(int n, Key key) { | 
| 6881 int capacity = Capacity(); | 6882 int capacity = Capacity(); | 
| 6882 int nof = NumberOfElements() + n; | 6883 int nof = NumberOfElements() + n; | 
| 6883 // Make sure 50% is free | 6884 int nod = NumberOfDeletedElements(); | 
| 6884 if (nof + (nof >> 1) <= capacity) return this; | 6885 // Return if: | 
| 6886 // 50% is still free after adding n elements and | |
| 6887 // atmost 50% of the free elements are deleted elements. | |
| 
Mads Ager (chromium)
2010/01/05 11:36:17
atmost -> at most
 | |
| 6888 if ((nof + (nof >> 1) <= capacity) && | |
| 6889 (nod <= (capacity - nof) >> 1) ) return this; | |
| 6885 | 6890 | 
| 6886 Object* obj = Allocate(nof * 2); | 6891 Object* obj = Allocate(nof * 2); | 
| 6887 if (obj->IsFailure()) return obj; | 6892 if (obj->IsFailure()) return obj; | 
| 6888 HashTable* table = HashTable::cast(obj); | 6893 HashTable* table = HashTable::cast(obj); | 
| 6889 WriteBarrierMode mode = table->GetWriteBarrierMode(); | 6894 WriteBarrierMode mode = table->GetWriteBarrierMode(); | 
| 6890 | 6895 | 
| 6891 // Copy prefix to new array. | 6896 // Copy prefix to new array. | 
| 6892 for (int i = kPrefixStartIndex; | 6897 for (int i = kPrefixStartIndex; | 
| 6893 i < kPrefixStartIndex + Shape::kPrefixSize; | 6898 i < kPrefixStartIndex + Shape::kPrefixSize; | 
| 6894 i++) { | 6899 i++) { | 
| 6895 table->set(i, get(i), mode); | 6900 table->set(i, get(i), mode); | 
| 6896 } | 6901 } | 
| 6897 // Rehash the elements. | 6902 // Rehash the elements. | 
| 6898 for (int i = 0; i < capacity; i++) { | 6903 for (int i = 0; i < capacity; i++) { | 
| 6899 uint32_t from_index = EntryToIndex(i); | 6904 uint32_t from_index = EntryToIndex(i); | 
| 6900 Object* k = get(from_index); | 6905 Object* k = get(from_index); | 
| 6901 if (IsKey(k)) { | 6906 if (IsKey(k)) { | 
| 6902 uint32_t hash = Shape::HashForObject(key, k); | 6907 uint32_t hash = Shape::HashForObject(key, k); | 
| 6903 uint32_t insertion_index = | 6908 uint32_t insertion_index = | 
| 6904 EntryToIndex(table->FindInsertionEntry(hash)); | 6909 EntryToIndex(table->FindInsertionEntry(hash)); | 
| 6905 for (int j = 0; j < Shape::kEntrySize; j++) { | 6910 for (int j = 0; j < Shape::kEntrySize; j++) { | 
| 6906 table->set(insertion_index + j, get(from_index + j), mode); | 6911 table->set(insertion_index + j, get(from_index + j), mode); | 
| 6907 } | 6912 } | 
| 6908 } | 6913 } | 
| 6909 } | 6914 } | 
| 6910 table->SetNumberOfElements(NumberOfElements()); | 6915 table->SetNumberOfElements(NumberOfElements()); | 
| 6916 table->SetNumberOfDeletedElements(0); | |
| 6911 return table; | 6917 return table; | 
| 6912 } | 6918 } | 
| 6913 | 6919 | 
| 6914 | 6920 | 
| 6915 template<typename Shape, typename Key> | 6921 template<typename Shape, typename Key> | 
| 6916 uint32_t HashTable<Shape, Key>::FindInsertionEntry(uint32_t hash) { | 6922 uint32_t HashTable<Shape, Key>::FindInsertionEntry(uint32_t hash) { | 
| 6917 uint32_t capacity = Capacity(); | 6923 uint32_t capacity = Capacity(); | 
| 6918 uint32_t entry = GetProbe(hash, 0, capacity); | 6924 uint32_t entry = GetProbe(hash, 0, capacity); | 
| 6919 Object* element = KeyAt(entry); | 6925 Object* element = KeyAt(entry); | 
| 6920 | 6926 | 
| (...skipping 775 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 7696 if (key->IsNumber()) { | 7702 if (key->IsNumber()) { | 
| 7697 uint32_t number = static_cast<uint32_t>(key->Number()); | 7703 uint32_t number = static_cast<uint32_t>(key->Number()); | 
| 7698 if (from <= number && number < to) { | 7704 if (from <= number && number < to) { | 
| 7699 SetEntry(i, sentinel, sentinel, Smi::FromInt(0)); | 7705 SetEntry(i, sentinel, sentinel, Smi::FromInt(0)); | 
| 7700 removed_entries++; | 7706 removed_entries++; | 
| 7701 } | 7707 } | 
| 7702 } | 7708 } | 
| 7703 } | 7709 } | 
| 7704 | 7710 | 
| 7705 // Update the number of elements. | 7711 // Update the number of elements. | 
| 7706 SetNumberOfElements(NumberOfElements() - removed_entries); | 7712 ElementsRemoved(removed_entries); | 
| 7707 } | 7713 } | 
| 7708 | 7714 | 
| 7709 | 7715 | 
| 7710 template<typename Shape, typename Key> | 7716 template<typename Shape, typename Key> | 
| 7711 Object* Dictionary<Shape, Key>::DeleteProperty(int entry, | 7717 Object* Dictionary<Shape, Key>::DeleteProperty(int entry, | 
| 7712 JSObject::DeleteMode mode) { | 7718 JSObject::DeleteMode mode) { | 
| 7713 PropertyDetails details = DetailsAt(entry); | 7719 PropertyDetails details = DetailsAt(entry); | 
| 7714 // Ignore attributes if forcing a deletion. | 7720 // Ignore attributes if forcing a deletion. | 
| 7715 if (details.IsDontDelete() && mode == JSObject::NORMAL_DELETION) { | 7721 if (details.IsDontDelete() && mode == JSObject::NORMAL_DELETION) { | 
| 7716 return Heap::false_value(); | 7722 return Heap::false_value(); | 
| (...skipping 577 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 8294 if (break_point_objects()->IsUndefined()) return 0; | 8300 if (break_point_objects()->IsUndefined()) return 0; | 
| 8295 // Single beak point. | 8301 // Single beak point. | 
| 8296 if (!break_point_objects()->IsFixedArray()) return 1; | 8302 if (!break_point_objects()->IsFixedArray()) return 1; | 
| 8297 // Multiple break points. | 8303 // Multiple break points. | 
| 8298 return FixedArray::cast(break_point_objects())->length(); | 8304 return FixedArray::cast(break_point_objects())->length(); | 
| 8299 } | 8305 } | 
| 8300 #endif | 8306 #endif | 
| 8301 | 8307 | 
| 8302 | 8308 | 
| 8303 } } // namespace v8::internal | 8309 } } // namespace v8::internal | 
| OLD | NEW |