author | Tooru Fujisawa <arai_a@mac.com> |
Sat, 19 Mar 2016 02:41:44 +0900 | |
changeset 289376 | 4fb38ce47512c913ec5b15ed85a383a7caab65e9 |
parent 289375 | ce85118f049d36cf875b3228495b993473717583 |
child 289377 | a3d994656b2bf373d1deb2cc13f559a4dcf15747 |
push id | 30102 |
push user | ryanvm@gmail.com |
push date | Sat, 19 Mar 2016 15:23:17 +0000 |
treeherder | mozilla-central@720fb3d55e28 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | sfink |
bugs | 1248289 |
milestone | 48.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/js/src/ds/OrderedHashTable.h +++ b/js/src/ds/OrderedHashTable.h @@ -279,54 +279,56 @@ class OrderedHashTable * r.popFront(); * // ...do things that might modify map... * } */ class Range { friend class OrderedHashTable; - OrderedHashTable& ht; + // Cannot be a reference since we need to be able to do + // |offsetof(Range, ht)|. + OrderedHashTable* ht; - /* The index of front() within ht.data. */ + /* The index of front() within ht->data. */ uint32_t i; /* - * The number of nonempty entries in ht.data to the left of front(). + * The number of nonempty entries in ht->data to the left of front(). * This is used when the table is resized or compacted. */ uint32_t count; /* * Links in the doubly-linked list of active Ranges on ht. * * prevp points to the previous Range's .next field; - * or to ht.ranges if this is the first Range in the list. + * or to ht->ranges if this is the first Range in the list. * next points to the next Range; * or nullptr if this is the last Range in the list. * * Invariant: *prevp == this. */ Range** prevp; Range* next; /* * Create a Range over all the entries in ht. - * (This is private on purpose. End users must use ht.all().) + * (This is private on purpose. End users must use ht->all().) */ - explicit Range(OrderedHashTable& ht) : ht(ht), i(0), count(0), prevp(&ht.ranges), next(ht.ranges) { + explicit Range(OrderedHashTable* ht) : ht(ht), i(0), count(0), prevp(&ht->ranges), next(ht->ranges) { *prevp = this; if (next) next->prevp = &next; seek(); } public: Range(const Range& other) - : ht(other.ht), i(other.i), count(other.count), prevp(&ht.ranges), next(ht.ranges) + : ht(other.ht), i(other.i), count(other.count), prevp(&ht->ranges), next(ht->ranges) { *prevp = this; if (next) next->prevp = &next; } ~Range() { *prevp = next; @@ -334,17 +336,17 @@ class OrderedHashTable next->prevp = prevp; } private: // Prohibit copy assignment. Range& operator=(const Range& other) = delete; void seek() { - while (i < ht.dataLength && Ops::isEmpty(Ops::getKey(ht.data[i].element))) + while (i < ht->dataLength && Ops::isEmpty(Ops::getKey(ht->data[i].element))) i++; } /* * The hash table calls this when an entry is removed. * j is the index of the removed entry. */ void onRemove(uint32_t j) { @@ -380,91 +382,91 @@ class OrderedHashTable MOZ_ASSERT(valid()); prevp = &next; next = this; } public: bool empty() const { MOZ_ASSERT(valid()); - return i >= ht.dataLength; + return i >= ht->dataLength; } /* * Return the first element in the range. This must not be called if * this->empty(). * * Warning: Removing an entry from the table also removes it from any * live Ranges, and a Range can become empty that way, rendering * front() invalid. If in doubt, check empty() before calling front(). */ T& front() { MOZ_ASSERT(valid()); MOZ_ASSERT(!empty()); - return ht.data[i].element; + return ht->data[i].element; } /* * Remove the first element from this range. * This must not be called if this->empty(). * * Warning: Removing an entry from the table also removes it from any * live Ranges, and a Range can become empty that way, rendering * popFront() invalid. If in doubt, check empty() before calling * popFront(). */ void popFront() { MOZ_ASSERT(valid()); MOZ_ASSERT(!empty()); - MOZ_ASSERT(!Ops::isEmpty(Ops::getKey(ht.data[i].element))); + MOZ_ASSERT(!Ops::isEmpty(Ops::getKey(ht->data[i].element))); count++; i++; seek(); } /* * Change the key of the front entry. * * This calls Ops::hash on both the current key and the new key. * Ops::hash on the current key must return the same hash code as * when the entry was added to the table. */ void rekeyFront(const Key& k) { MOZ_ASSERT(valid()); - Data& entry = ht.data[i]; - HashNumber oldHash = prepareHash(Ops::getKey(entry.element)) >> ht.hashShift; - HashNumber newHash = prepareHash(k) >> ht.hashShift; + Data& entry = ht->data[i]; + HashNumber oldHash = prepareHash(Ops::getKey(entry.element)) >> ht->hashShift; + HashNumber newHash = prepareHash(k) >> ht->hashShift; Ops::setKey(entry.element, k); if (newHash != oldHash) { // Remove this entry from its old hash chain. (If this crashes // reading nullptr, it would mean we did not find this entry on // the hash chain where we expected it. That probably means the // key's hash code changed since it was inserted, breaking the // hash code invariant.) - Data** ep = &ht.hashTable[oldHash]; + Data** ep = &ht->hashTable[oldHash]; while (*ep != &entry) ep = &(*ep)->chain; *ep = entry.chain; // Add it to the new hash chain. We could just insert it at the // beginning of the chain. Instead, we do a bit of work to // preserve the invariant that hash chains always go in reverse // insertion order (descending memory order). No code currently // depends on this invariant, so it's fine to kill it if // needed. - ep = &ht.hashTable[newHash]; + ep = &ht->hashTable[newHash]; while (*ep && *ep > &entry) ep = &(*ep)->chain; entry.chain = *ep; *ep = &entry; } } }; - Range all() { return Range(*this); } + Range all() { return Range(this); } /* * Change the value of the given key. * * This calls Ops::hash on both the current key and the new key. * Ops::hash on the current key must return the same hash code as * when the entry was added to the table. */