Bug 1379282 - Improve XPCOM's pointer hashing functions for pointers to neighboring memory locations; r=erahm
authorEhsan Akhgari <ehsan@mozilla.com>
Fri, 07 Jul 2017 16:54:16 -0400
changeset 418444 5eeb5b9f118b819bebb8ef8cc2c06cdb6b412761
parent 418443 09deb3ef1f63354a1d4716826c4ccbec1d730db4
child 418445 6b8a76e20661787f7b17e3a4c8ff1f030c30529b
push id7566
push usermtabara@mozilla.com
push dateWed, 02 Aug 2017 08:25:16 +0000
treeherdermozilla-beta@86913f512c3c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerserahm
bugs1379282
milestone56.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
Bug 1379282 - Improve XPCOM's pointer hashing functions for pointers to neighboring memory locations; r=erahm The simplistic shift-based hashing function creates a lot of collisions for pointers pointing to arrays as it doesn't do a great job at distributing the data randomly based on the input bytes.
xpcom/ds/PLDHashTable.cpp
xpcom/ds/nsPointerHashKeys.h
--- a/xpcom/ds/PLDHashTable.cpp
+++ b/xpcom/ds/PLDHashTable.cpp
@@ -8,16 +8,17 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include "PLDHashTable.h"
 #include "mozilla/HashFunctions.h"
 #include "mozilla/MathAlgorithms.h"
 #include "mozilla/OperatorNewExtensions.h"
 #include "nsAlgorithm.h"
+#include "nsPointerHashKeys.h"
 #include "mozilla/Likely.h"
 #include "mozilla/MemoryReporting.h"
 #include "mozilla/ChaosMode.h"
 
 using namespace mozilla;
 
 #ifdef DEBUG
 
@@ -67,20 +68,17 @@ public:
 PLDHashTable::HashStringKey(const void* aKey)
 {
   return HashString(static_cast<const char*>(aKey));
 }
 
 /* static */ PLDHashNumber
 PLDHashTable::HashVoidPtrKeyStub(const void* aKey)
 {
-  // Be careful!  We don't want to do the cast to PLDHashNumber which is a
-  // trimming cast on 64-bit platforms before the shift, otherwise we will lose
-  // valuable bits from our hash key!
-  return PLDHashNumber(uintptr_t(aKey) >> 2);
+  return nsPtrHashKey<void>::HashKey(aKey);
 }
 
 /* static */ bool
 PLDHashTable::MatchEntryStub(const PLDHashEntryHdr* aEntry, const void* aKey)
 {
   const PLDHashEntryStub* stub = (const PLDHashEntryStub*)aEntry;
 
   return stub->key == aKey;
--- a/xpcom/ds/nsPointerHashKeys.h
+++ b/xpcom/ds/nsPointerHashKeys.h
@@ -7,16 +7,17 @@
 /* Definitions for nsPtrHashKey<T> and nsVoidPtrHashKey.  */
 
 #ifndef nsPointerHashKeys_h
 #define nsPointerHashKeys_h
 
 #include "nscore.h"
 
 #include "mozilla/Attributes.h"
+#include "mozilla/HashFunctions.h"
 
 /**
  * hashkey wrapper using T* KeyType
  *
  * @see nsTHashtable::EntryType for specification
  */
 template<class T>
 class nsPtrHashKey : public PLDHashEntryHdr
@@ -30,20 +31,17 @@ public:
   ~nsPtrHashKey() {}
 
   KeyType GetKey() const { return mKey; }
   bool KeyEquals(KeyTypePointer aKey) const { return aKey == mKey; }
 
   static KeyTypePointer KeyToPointer(KeyType aKey) { return aKey; }
   static PLDHashNumber HashKey(KeyTypePointer aKey)
   {
-    // Be careful!  We don't want to do the cast to PLDHashNumber which is a
-    // trimming cast on 64-bit platforms before the shift, otherwise we will
-    // lose valuable bits from our hash key!
-    return PLDHashNumber(uintptr_t(aKey) >> 2);
+    return mozilla::HashGeneric(aKey);
   }
   enum { ALLOW_MEMMOVE = true };
 
 protected:
   T* MOZ_NON_OWNING_REF mKey;
 };
 
 typedef nsPtrHashKey<const void> nsVoidPtrHashKey;