| Index: src/objects.cc
|
| diff --git a/src/objects.cc b/src/objects.cc
|
| index 43e3f53a536dfe12a5927dd7edab9d3bf533c834..362b363cc80174caf85d440d881f4c392974a3f2 100644
|
| --- a/src/objects.cc
|
| +++ b/src/objects.cc
|
| @@ -13806,6 +13806,74 @@ MaybeObject* HashTable<Shape, Key>::Rehash(HashTable* new_table, Key key) {
|
|
|
|
|
| template<typename Shape, typename Key>
|
| +uint32_t HashTable<Shape, Key>::EntryForProbe(Key key,
|
| + Object* k,
|
| + int probe,
|
| + uint32_t expected) {
|
| + uint32_t hash = HashTable<Shape, Key>::HashForObject(key, k);
|
| + uint32_t capacity = Capacity();
|
| + uint32_t entry = FirstProbe(hash, capacity);
|
| + for (int i = 1; i < probe; i++) {
|
| + if (entry == expected) return expected;
|
| + entry = NextProbe(entry, i, capacity);
|
| + }
|
| + return entry;
|
| +}
|
| +
|
| +
|
| +template<typename Shape, typename Key>
|
| +void HashTable<Shape, Key>::Swap(uint32_t entry1,
|
| + uint32_t entry2,
|
| + WriteBarrierMode mode) {
|
| + int index1 = EntryToIndex(entry1);
|
| + int index2 = EntryToIndex(entry2);
|
| + Object* temp[Shape::kEntrySize];
|
| + for (int j = 0; j < Shape::kEntrySize; j++) {
|
| + temp[j] = get(index1 + j);
|
| + }
|
| + for (int j = 0; j < Shape::kEntrySize; j++) {
|
| + set(index1 + j, get(index2 + j), mode);
|
| + }
|
| + for (int j = 0; j < Shape::kEntrySize; j++) {
|
| + set(index2 + j, temp[j], mode);
|
| + }
|
| +}
|
| +
|
| +
|
| +template<typename Shape, typename Key>
|
| +void HashTable<Shape, Key>::Rehash(Key key) {
|
| + DisallowHeapAllocation no_gc;
|
| + WriteBarrierMode mode = GetWriteBarrierMode(no_gc);
|
| + uint32_t capacity = Capacity();
|
| + bool done = false;
|
| + for (int probe = 1; !done; probe++) {
|
| + // All elements at entries given by one of the first _probe_ probes
|
| + // are placed correctly. Other elements might need to be moved.
|
| + done = true;
|
| + for (uint32_t current = 0; current < capacity; current++) {
|
| + Object* current_key = get(EntryToIndex(current));
|
| + if (IsKey(current_key)) {
|
| + uint32_t target = EntryForProbe(key, current_key, probe, current);
|
| + if (current == target) continue;
|
| + Object* target_key = get(EntryToIndex(target));
|
| + if (!IsKey(target_key) ||
|
| + EntryForProbe(key, target_key, probe, target) != target) {
|
| + // Put the current element into the correct position.
|
| + Swap(current, target, mode);
|
| + // The other element will be processed on the next iteration.
|
| + current--;
|
| + } else {
|
| + // The place for the current element is occupied. Leave the element
|
| + // for the next probe.
|
| + done = false;
|
| + }
|
| + }
|
| + }
|
| + }
|
| +}
|
| +
|
| +
|
| +template<typename Shape, typename Key>
|
| MaybeObject* HashTable<Shape, Key>::EnsureCapacity(int n, Key key) {
|
| int capacity = Capacity();
|
| int nof = NumberOfElements() + n;
|
|
|