⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 130639 in webkit


Ignore:
Timestamp:
Oct 8, 2012, 7:44:53 AM (14 years ago)
Author:
kling@webkit.org
Message:

Using float/double as WTF hash table key is unreliable.
<​http://webkit.org/b/98627>

Reviewed by Geoffrey Garen.

Source/WTF:

Change FloatHash::equal() to do a bitwise compare instead of a logical compare.
This fixes a problem where the keys with different binary representation but the
same logical value (e.g 0 and -0) could block each other from being found if they
ended up in the same hash bucket.

  • wtf/HashFunctions.h:

(FloatHash):
(WTF::FloatHash::hash):
(WTF::FloatHash::equal):

Tools:

Add a test case checking that using double as the hash table key type won't
have problems distinguishing between keys that are considered equal by operator==
but have different binary representations.

  • TestWebKitAPI/Tests/WTF/HashMap.cpp:

(TestDoubleHashTraits):

Location:
trunk
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WTF/ChangeLog

    r130622 r130639  
     12012-10-08  Andreas Kling  <kling@webkit.org>
     2
     3        Using float/double as WTF hash table key is unreliable.
     4        <http://webkit.org/b/98627>
     5
     6        Reviewed by Geoffrey Garen.
     7
     8        Change FloatHash::equal() to do a bitwise compare instead of a logical compare.
     9        This fixes a problem where the keys with different binary representation but the
     10        same logical value (e.g 0 and -0) could block each other from being found if they
     11        ended up in the same hash bucket.
     12
     13        * wtf/HashFunctions.h:
     14        (FloatHash):
     15        (WTF::FloatHash::hash):
     16        (WTF::FloatHash::equal):
     17
    1182012-10-08  Sheriff Bot  <webkit.review.bot@gmail.com>
    219
  • trunk/Source/WTF/wtf/HashFunctions.h

    r128657 r130639  
    106106
    107107    template<typename T> struct FloatHash {
     108        typedef typename IntTypes<sizeof(T)>::UnsignedType Bits;
    108109        static unsigned hash(T key)
    109110        {
    110             union {
    111                 T key;
    112                 typename IntTypes<sizeof(T)>::UnsignedType bits;
    113             } u;
    114             u.key = key;
    115             return intHash(u.bits);
    116         }
    117         static bool equal(T a, T b) { return a == b; }
     111            return intHash(bitwise_cast<Bits>(key));
     112        }
     113        static bool equal(T a, T b)
     114        {
     115            return bitwise_cast<Bits>(a) == bitwise_cast<Bits>(b);
     116        }
    118117        static const bool safeToCompareToEmptyOrDeleted = true;
    119118    };
  • trunk/Tools/ChangeLog

    r130637 r130639  
     12012-10-08  Andreas Kling  <kling@webkit.org>
     2
     3        Using float/double as WTF hash table key is unreliable.
     4        <http://webkit.org/b/98627>
     5
     6        Reviewed by Geoffrey Garen.
     7
     8        Add a test case checking that using double as the hash table key type won't
     9        have problems distinguishing between keys that are considered equal by operator==
     10        but have different binary representations.
     11
     12        * TestWebKitAPI/Tests/WTF/HashMap.cpp:
     13        (TestDoubleHashTraits):
     14
    1152012-10-08  Christophe Dumez  <christophe.dumez@intel.com>
    216
  • trunk/Tools/TestWebKitAPI/Tests/WTF/HashMap.cpp

    r102483 r130639  
    5050}
    5151
     52struct TestDoubleHashTraits : HashTraits<double> {
     53    static const int minimumTableSize = 8;
     54};
     55
     56typedef HashMap<double, int64_t, DefaultHash<double>::Hash, TestDoubleHashTraits> DoubleHashMap;
     57
     58TEST(WTF, DoubleHashCollisions)
     59{
     60    // The "clobber" key here is one that ends up stealing the bucket that the -0 key
     61    // originally wants to be in. This makes the 0 and -0 keys collide and the test then
     62    // fails unless the FloatHash::equals() implementation can distinguish them.
     63    const double clobberKey = 6;
     64    const double zeroKey = 0;
     65    const double negativeZeroKey = -zeroKey;
     66
     67    DoubleHashMap map;
     68
     69    map.add(clobberKey, 1);
     70    map.add(zeroKey, 2);
     71    map.add(negativeZeroKey, 3);
     72
     73    ASSERT_EQ(map.get(clobberKey), 1);
     74    ASSERT_EQ(map.get(zeroKey), 2);
     75    ASSERT_EQ(map.get(negativeZeroKey), 3);
     76}
     77
    5278} // namespace TestWebKitAPI
Note: See TracChangeset for help on using the changeset viewer.