Closed Bug 1860451 Opened 2 years ago Closed 2 years ago

HashPolicy documentation should clarify HashPolicy::match can be called with item with different hash

Categories

(Core :: MFBT, enhancement)

enhancement

Tracking

()

RESOLVED FIXED
121 Branch
Tracking Status
firefox121 --- fixed

People

(Reporter: arai, Assigned: arai)

References

Details

Attachments

(1 file)

(Derived from bug 1802568)

The hash policy document mentions the HashPolicy::match method, but it doesn't explain the underlying assumption (what holds, what doesn't hold) about the key vs lookup:

https://searchfox.org/mozilla-central/rev/3389de86c4daf28fe402fcfe7d99e8646d41f302/mfbt/HashTable.h#720-722,724-725,732-735

//---------------------------------------------------------------------------
// Hash Policy
//---------------------------------------------------------------------------
...
// A hash policy |HP| for a hash table with key-type |Key| must provide:
//
...
//  - a static member function |HP::match| that tests equality of key and
//    lookup values:
//
//      static bool match(const Key&, const Lookup&);

In ParserAtom, we use HashTable for storing atomized strings, and the item contains hash (ParserAtom::hash_), and that value is used by HashPolicy.

https://searchfox.org/mozilla-central/rev/3389de86c4daf28fe402fcfe7d99e8646d41f302/js/src/frontend/ParserAtom.h#549,553-554

struct ParserAtomLookupHasher {
...
  static inline bool match(const ParserAtom* entry, const Lookup& l) {
    return l.equalsEntry(entry);

https://searchfox.org/mozilla-central/rev/3389de86c4daf28fe402fcfe7d99e8646d41f302/js/src/frontend/ParserAtom.h#839-840,854-855

template <typename CharT>
class SpecificParserAtomLookup : public ParserAtomLookup {
...
  virtual bool equalsEntry(const ParserAtom* entry) const override {
    return entry->equalsSeq<CharT>(hash_, seq_);

https://searchfox.org/mozilla-central/rev/3389de86c4daf28fe402fcfe7d99e8646d41f302/js/src/frontend/ParserAtom.h#874-879

template <typename CharT>
inline bool ParserAtom::equalsSeq(HashNumber hash,
                                  InflatedChar16Sequence<CharT> seq) const {
  // Compare hashes first.
  if (hash_ != hash) {
    return false;

the hash of key and lookup are almost always same, that almost implies the hash comparison is unnecessary, but this is actually not true, because HashTable uses a different hash calculated from the original hash, and that can cause collision between two different hashes.

https://searchfox.org/mozilla-central/rev/47be6b9a0719f4311356695d9eed48de97b432b2/mfbt/HashTable.h#2110

HashNumber keyHash = prepareHash(inputHash);

So, the above hash_ != hash comparison results in true only when the collision happens.

It's better mentioning that characteristics in the HashPolicy document, so that it's clear that the HashPolicy::match implementation shouldn't assume hash equality, even if it's almost always same in practice.

Assignee: nobody → arai.unmht
Status: NEW → ASSIGNED
Pushed by arai_a@mac.com: https://hg.mozilla.org/integration/autoland/rev/090a376b2622 Add documentation for the hash inequality in HashPolicy::match. r=mgaudet DONTBUILD
Status: ASSIGNED → RESOLVED
Closed: 2 years ago
Resolution: --- → FIXED
Target Milestone: --- → 121 Branch
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: