Back out bug 729940 (a108aee:d75775d) due to 32-bit red.
authorJustin Lebar <justin.lebar@gmail.com>
Sun, 04 Mar 2012 14:20:34 -0500
changeset 88257 b69617debd8d2d5a7686a7d61da5c0ab987eeb00
parent 88256 158587a6b17e84403075f55e06aaf626372aac21
child 88258 cf668a3984fef3a56c4671dab84b4ae6f10010fc
push id585
push userrcampbell@mozilla.com
push dateThu, 08 Mar 2012 14:31:19 +0000
treeherderfx-team@75b24396b0ce [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs729940
milestone13.0a1
Back out bug 729940 (a108aee:d75775d) due to 32-bit red.
caps/src/nsPrincipal.cpp
content/base/src/nsAttrValue.cpp
content/base/src/nsContentList.h
content/base/src/nsDOMAttributeMap.h
content/base/src/nsDocument.h
content/base/src/nsMappedAttributes.cpp
content/base/src/nsNameSpaceManager.cpp
content/base/src/nsNodeInfoManager.cpp
content/canvas/src/CanvasImageCache.cpp
content/html/content/src/nsHTMLFormElement.h
content/xslt/src/xslt/txKeyFunctionCall.cpp
content/xul/templates/src/nsRDFConInstanceTestNode.h
content/xul/templates/src/nsRDFPropertyTestNode.h
dom/base/nsScriptNameSpaceManager.cpp
dom/indexedDB/OpenDatabaseHelper.cpp
dom/plugins/base/nsJSNPRuntime.cpp
dom/tests/mochitest/localstorage/test_localStorageBase.html
dom/tests/mochitest/localstorage/test_localStorageBasePrivateBrowsing.html
dom/tests/mochitest/localstorage/test_localStorageBaseSessionOnly.html
dom/tests/mochitest/sessionstorage/test_sessionStorageBase.html
embedding/components/commandhandler/src/nsCommandParams.cpp
gfx/thebes/gfxFont.h
intl/unicharutil/util/nsUnicharUtils.cpp
intl/unicharutil/util/nsUnicharUtils.h
js/src/jsatom.h
js/src/jsdhash.cpp
js/src/jshash.cpp
js/src/jsinfer.cpp
js/src/jsinferinlines.h
js/src/jsobj.cpp
js/src/jsobjinlines.h
js/src/jspropertycache.h
js/src/jsscope.cpp
js/src/jsscopeinlines.h
js/src/jswatchpoint.cpp
js/xpconnect/src/XPCMaps.cpp
mfbt/HashFunctions.cpp
mfbt/HashFunctions.h
mfbt/sources.mk
modules/libpref/src/Preferences.cpp
modules/libpref/src/nsPrefBranch.h
netwerk/base/public/nsNetUtil.h
netwerk/base/public/nsURIHashKey.h
netwerk/cache/nsCacheEntry.cpp
netwerk/cookie/nsCookieService.h
netwerk/dns/nsHostResolver.cpp
netwerk/protocol/http/nsHttp.cpp
parser/htmlparser/src/nsHTMLTags.cpp
rdf/base/src/nsRDFService.cpp
security/manager/ssl/src/nsNSSCallbacks.cpp
toolkit/system/gnome/nsAlertsIconListener.cpp
xpcom/components/ManifestParser.cpp
xpcom/ds/nsAtomTable.cpp
xpcom/ds/nsCRT.cpp
xpcom/ds/nsCRT.h
xpcom/ds/nsDoubleHashtable.h
xpcom/ds/nsHashtable.cpp
xpcom/ds/nsStaticNameTable.cpp
xpcom/glue/nsHashKeys.h
xpcom/glue/nsTHashtable.cpp
xpcom/glue/pldhash.cpp
xpcom/io/nsLocalFileOS2.cpp
xpcom/io/nsLocalFileUnix.cpp
xpcom/tests/TestHashtables.cpp
xpcom/tests/TestUTF.cpp
--- a/caps/src/nsPrincipal.cpp
+++ b/caps/src/nsPrincipal.cpp
@@ -55,17 +55,16 @@
 #include "nsIObjectOutputStream.h"
 #include "nsIClassInfoImpl.h"
 #include "nsDOMError.h"
 #include "nsIContentSecurityPolicy.h"
 
 #include "nsPrincipal.h"
 
 #include "mozilla/Preferences.h"
-#include "mozilla/HashFunctions.h"
 
 using namespace mozilla;
 
 static bool gCodeBasePrincipalSupport = false;
 static bool gIsObservingCodeBasePrincipalSupport = false;
 
 static bool URIIsImmutable(nsIURI* aURI)
 {
@@ -802,17 +801,17 @@ nsPrincipal::SetCsp(nsIContentSecurityPo
 
 NS_IMETHODIMP
 nsPrincipal::GetHashValue(PRUint32* aValue)
 {
   NS_PRECONDITION(mCert || mCodebase, "Need a cert or codebase");
 
   // If there is a certificate, it takes precendence over the codebase.
   if (mCert) {
-    *aValue = HashString(mCert->fingerprint);
+    *aValue = nsCRT::HashCode(mCert->fingerprint.get());
   }
   else {
     *aValue = nsScriptSecurityManager::HashPrincipalByOrigin(this);
   }
 
   return NS_OK;
 }
 
--- a/content/base/src/nsAttrValue.cpp
+++ b/content/base/src/nsAttrValue.cpp
@@ -46,19 +46,20 @@
 #include "nsUnicharUtils.h"
 #include "mozilla/css/StyleRule.h"
 #include "mozilla/css/Declaration.h"
 #include "nsIHTMLDocument.h"
 #include "nsIDocument.h"
 #include "nsContentUtils.h"
 #include "nsReadableUtils.h"
 #include "prprf.h"
-#include "mozilla/HashFunctions.h"
 
-using namespace mozilla;
+namespace css = mozilla::css;
+
+using mozilla::SVGAttrValueWrapper;
 
 #define MISC_STR_PTR(_cont) \
   reinterpret_cast<void*>((_cont)->mStringBits & NS_ATTRVALUE_POINTERVALUE_MASK)
 
 nsTArray<const nsAttrValue::EnumTable*>* nsAttrValue::sEnumTableArray = nsnull;
 
 nsAttrValue::nsAttrValue()
     : mBits(0)
@@ -386,29 +387,29 @@ nsAttrValue::SetTo(const nsSVGIntegerPai
 
 void
 nsAttrValue::SetTo(const nsSVGLength2& aValue, const nsAString* aSerialized)
 {
   SetSVGType(eSVGLength, &aValue, aSerialized);
 }
 
 void
-nsAttrValue::SetTo(const SVGLengthList& aValue,
+nsAttrValue::SetTo(const mozilla::SVGLengthList& aValue,
                    const nsAString* aSerialized)
 {
   // While an empty string will parse as a length list, there's no need to store
   // it (and SetMiscAtomOrString will assert if we try)
   if (aSerialized && aSerialized->IsEmpty()) {
     aSerialized = nsnull;
   }
   SetSVGType(eSVGLengthList, &aValue, aSerialized);
 }
 
 void
-nsAttrValue::SetTo(const SVGNumberList& aValue,
+nsAttrValue::SetTo(const mozilla::SVGNumberList& aValue,
                    const nsAString* aSerialized)
 {
   // While an empty string will parse as a number list, there's no need to store
   // it (and SetMiscAtomOrString will assert if we try)
   if (aSerialized && aSerialized->IsEmpty()) {
     aSerialized = nsnull;
   }
   SetSVGType(eSVGNumberList, &aValue, aSerialized);
@@ -416,60 +417,60 @@ nsAttrValue::SetTo(const SVGNumberList& 
 
 void
 nsAttrValue::SetTo(const nsSVGNumberPair& aValue, const nsAString* aSerialized)
 {
   SetSVGType(eSVGNumberPair, &aValue, aSerialized);
 }
 
 void
-nsAttrValue::SetTo(const SVGPathData& aValue,
+nsAttrValue::SetTo(const mozilla::SVGPathData& aValue,
                    const nsAString* aSerialized)
 {
   // While an empty string will parse as path data, there's no need to store it
   // (and SetMiscAtomOrString will assert if we try)
   if (aSerialized && aSerialized->IsEmpty()) {
     aSerialized = nsnull;
   }
   SetSVGType(eSVGPathData, &aValue, aSerialized);
 }
 
 void
-nsAttrValue::SetTo(const SVGPointList& aValue,
+nsAttrValue::SetTo(const mozilla::SVGPointList& aValue,
                    const nsAString* aSerialized)
 {
   // While an empty string will parse as a point list, there's no need to store
   // it (and SetMiscAtomOrString will assert if we try)
   if (aSerialized && aSerialized->IsEmpty()) {
     aSerialized = nsnull;
   }
   SetSVGType(eSVGPointList, &aValue, aSerialized);
 }
 
 void
-nsAttrValue::SetTo(const SVGAnimatedPreserveAspectRatio& aValue,
+nsAttrValue::SetTo(const mozilla::SVGAnimatedPreserveAspectRatio& aValue,
                    const nsAString* aSerialized)
 {
   SetSVGType(eSVGPreserveAspectRatio, &aValue, aSerialized);
 }
 
 void
-nsAttrValue::SetTo(const SVGStringList& aValue,
+nsAttrValue::SetTo(const mozilla::SVGStringList& aValue,
                    const nsAString* aSerialized)
 {
   // While an empty string will parse as a string list, there's no need to store
   // it (and SetMiscAtomOrString will assert if we try)
   if (aSerialized && aSerialized->IsEmpty()) {
     aSerialized = nsnull;
   }
   SetSVGType(eSVGStringList, &aValue, aSerialized);
 }
 
 void
-nsAttrValue::SetTo(const SVGTransformList& aValue,
+nsAttrValue::SetTo(const mozilla::SVGTransformList& aValue,
                    const nsAString* aSerialized)
 {
   // While an empty string will parse as a transform list, there's no need to
   // store it (and SetMiscAtomOrString will assert if we try)
   if (aSerialized && aSerialized->IsEmpty()) {
     aSerialized = nsnull;
   }
   SetSVGType(eSVGTransformList, &aValue, aSerialized);
@@ -758,17 +759,17 @@ PRUint32
 nsAttrValue::HashValue() const
 {
   switch(BaseType()) {
     case eStringBase:
     {
       nsStringBuffer* str = static_cast<nsStringBuffer*>(GetPtr());
       if (str) {
         PRUint32 len = str->StorageSize()/sizeof(PRUnichar) - 1;
-        return HashString(static_cast<PRUnichar*>(str->Data()), len);
+        return nsCRT::HashCode(static_cast<PRUnichar*>(str->Data()), len);
       }
 
       return 0;
     }
     case eOtherBase:
     {
       break;
     }
@@ -806,24 +807,24 @@ nsAttrValue::HashValue() const
       return cont->mColor;
     }
     case eCSSStyleRule:
     {
       return NS_PTR_TO_INT32(cont->mCSSStyleRule);
     }
     case eAtomArray:
     {
-      PRUint32 hash = 0;
+      PRUint32 retval = 0;
       PRUint32 count = cont->mAtomArray->Length();
       for (nsCOMPtr<nsIAtom> *cur = cont->mAtomArray->Elements(),
                              *end = cur + count;
            cur != end; ++cur) {
-        hash = AddToHash(hash, cur->get());
+        retval ^= NS_PTR_TO_INT32(cur->get());
       }
-      return hash;
+      return retval;
     }
     case eDoubleValue:
     {
       // XXX this is crappy, but oh well
       return cont->mDoubleValue;
     }
     case eIntMarginValue:
     {
--- a/content/base/src/nsContentList.h
+++ b/content/base/src/nsContentList.h
@@ -50,18 +50,18 @@
 #include "nsIHTMLCollection.h"
 #include "nsIDOMNodeList.h"
 #include "nsINodeList.h"
 #include "nsStubMutationObserver.h"
 #include "nsIAtom.h"
 #include "nsINameSpaceManager.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsWrapperCache.h"
+#include "nsCRT.h"
 #include "nsHashKeys.h"
-#include "mozilla/HashFunctions.h"
 
 // Magic namespace id that means "match all namespaces".  This is
 // negative so it won't collide with actual namespace constants.
 #define kNameSpaceID_Wildcard PR_INT32_MIN
 
 // This is a callback function type that can be used to implement an
 // arbitrary matching algorithm.  aContent is the content that may
 // match the list, while aNamespaceID, aAtom, and aData are whatever
@@ -199,18 +199,20 @@ struct nsContentListKey
     : mRootNode(aContentListKey.mRootNode),
       mMatchNameSpaceId(aContentListKey.mMatchNameSpaceId),
       mTagname(aContentListKey.mTagname)
   {
   }
 
   inline PRUint32 GetHash(void) const
   {
-    PRUint32 hash = mozilla::HashString(mTagname);
-    return mozilla::AddToHash(hash, mRootNode, mMatchNameSpaceId);
+    return
+      HashString(mTagname) ^
+      (NS_PTR_TO_INT32(mRootNode) << 12) ^
+      (mMatchNameSpaceId << 24);
   }
   
   nsINode* const mRootNode; // Weak ref
   const PRInt32 mMatchNameSpaceId;
   const nsAString& mTagname;
 };
 
 /**
@@ -483,18 +485,18 @@ public:
                        const nsAString& aString) :
     mRootNode(aRootNode),
     mFunc(aFunc),
     mString(aString)
     {}
 
   PRUint32 GetHash(void) const
   {
-    PRUint32 hash = mozilla::HashString(mString);
-    return mozilla::AddToHash(hash, mRootNode, mFunc);
+    return NS_PTR_TO_INT32(mRootNode) ^ (NS_PTR_TO_INT32(mFunc) << 12) ^
+      nsCRT::HashCode(mString.BeginReading(), mString.Length());
   }
 
 private:
   friend class nsCacheableFuncStringContentList;
 
   nsINode* const mRootNode;
   const nsContentListMatchFunc mFunc;
   const nsAString& mString;
--- a/content/base/src/nsDOMAttributeMap.h
+++ b/content/base/src/nsDOMAttributeMap.h
@@ -107,17 +107,18 @@ public:
     }
 
   static KeyTypePointer KeyToPointer(KeyType aKey) { return &aKey; }
   static PLDHashNumber HashKey(KeyTypePointer aKey)
     {
       if (!aKey)
         return 0;
 
-      return mozilla::HashGeneric(aKey->mNamespaceID, aKey->mLocalName);
+      return PR_ROTATE_LEFT32(static_cast<PRUint32>(aKey->mNamespaceID), 4) ^
+             NS_PTR_TO_INT32(aKey->mLocalName);
     }
   enum { ALLOW_MEMMOVE = true };
 
 private:
   nsAttrKey mKey;
 };
 
 // Helper class that implements the nsIDOMNamedNodeMap interface.
--- a/content/base/src/nsDocument.h
+++ b/content/base/src/nsDocument.h
@@ -233,17 +233,18 @@ public:
       return aKey->mCallback == mKey.mCallback &&
              aKey->mData == mKey.mData &&
              aKey->mForImage == mKey.mForImage;
     }
 
     static KeyTypePointer KeyToPointer(KeyType& aKey) { return &aKey; }
     static PLDHashNumber HashKey(KeyTypePointer aKey)
     {
-      return mozilla::HashGeneric(aKey->mCallback, aKey->mData);
+      return (NS_PTR_TO_INT32(aKey->mCallback) >> 2) ^
+             (NS_PTR_TO_INT32(aKey->mData));
     }
     enum { ALLOW_MEMMOVE = true };
     
     ChangeCallback mKey;
   };
 
 private:
   void FireChangeCallbacks(Element* aOldElement, Element* aNewElement,
--- a/content/base/src/nsMappedAttributes.cpp
+++ b/content/base/src/nsMappedAttributes.cpp
@@ -40,19 +40,16 @@
  * A unique per-element set of attributes that is used as an
  * nsIStyleRule; used to implement presentational attributes.
  */
 
 #include "nsMappedAttributes.h"
 #include "nsHTMLStyleSheet.h"
 #include "nsRuleWalker.h"
 #include "prmem.h"
-#include "mozilla/HashFunctions.h"
-
-using namespace mozilla;
 
 nsMappedAttributes::nsMappedAttributes(nsHTMLStyleSheet* aSheet,
                                        nsMapRuleToAttributesFunc aMapRuleFunc)
   : mAttrCount(0),
     mSheet(aSheet),
     mRuleMapper(aMapRuleFunc)
 {
 }
@@ -174,26 +171,24 @@ nsMappedAttributes::Equals(const nsMappe
   }
 
   return true;
 }
 
 PRUint32
 nsMappedAttributes::HashValue() const
 {
-  PRUint32 hash = HashGeneric(mRuleMapper);
+  PRUint32 value = NS_PTR_TO_INT32(mRuleMapper);
 
   PRUint32 i;
   for (i = 0; i < mAttrCount; ++i) {
-    hash = AddToHash(hash,
-                     Attrs()[i].mName.HashValue(),
-                     Attrs()[i].mValue.HashValue());
+    value ^= Attrs()[i].mName.HashValue() ^ Attrs()[i].mValue.HashValue();
   }
 
-  return hash;
+  return value;
 }
 
 void
 nsMappedAttributes::SetStyleSheet(nsHTMLStyleSheet* aSheet)
 {
   if (mSheet) {
     mSheet->DropMappedAttributes(this);
   }
--- a/content/base/src/nsNameSpaceManager.cpp
+++ b/content/base/src/nsNameSpaceManager.cpp
@@ -52,17 +52,16 @@
 
 #ifdef MOZ_XTF
 #include "nsIServiceManager.h"
 #include "nsIXTFService.h"
 #include "nsContentUtils.h"
 static NS_DEFINE_CID(kXTFServiceCID, NS_XTFSERVICE_CID);
 #endif
 
-using namespace mozilla;
 using namespace mozilla::dom;
 
 #define kXMLNSNameSpaceURI "http://www.w3.org/2000/xmlns/"
 #define kXMLNameSpaceURI "http://www.w3.org/XML/1998/namespace"
 #define kXHTMLNameSpaceURI "http://www.w3.org/1999/xhtml"
 #define kXLinkNameSpaceURI "http://www.w3.org/1999/xlink"
 #define kXSLTNameSpaceURI "http://www.w3.org/1999/XSL/Transform"
 #define kXBLNameSpaceURI "http://www.mozilla.org/xbl"
--- a/content/base/src/nsNodeInfoManager.cpp
+++ b/content/base/src/nsNodeInfoManager.cpp
@@ -51,18 +51,16 @@
 #include "nsReadableUtils.h"
 #include "nsGkAtoms.h"
 #include "nsComponentManagerUtils.h"
 #include "nsLayoutStatics.h"
 #include "nsBindingManager.h"
 #include "nsHashKeys.h"
 #include "nsCCUncollectableMarker.h"
 
-using namespace mozilla;
-
 #ifdef MOZ_LOGGING
 // so we can get logging even in release builds
 #define FORCE_PR_LOG 1
 #endif
 #include "prlog.h"
 
 #ifdef PR_LOGGING
 static PRLogModuleInfo* gNodeInfoManagerLeakPRLog;
@@ -72,19 +70,16 @@ PLHashNumber
 nsNodeInfoManager::GetNodeInfoInnerHashValue(const void *key)
 {
   NS_ASSERTION(key, "Null key passed to nsNodeInfo::GetHashValue!");
 
   const nsINodeInfo::nsNodeInfoInner *node =
     reinterpret_cast<const nsINodeInfo::nsNodeInfoInner *>(key);
 
   if (node->mName) {
-    // Ideally, we'd return node->mName->hash() here.  But that doesn't work at
-    // the moment because node->mName->hash() is not the same as
-    // HashString(*(node->mNameString)).  See bug 732815.
     return HashString(nsDependentAtomString(node->mName));
   }
   return HashString(*(node->mNameString));
 }
 
 
 PRIntn
 nsNodeInfoManager::NodeInfoInnerKeyCompare(const void *key1, const void *key2)
--- a/content/canvas/src/CanvasImageCache.cpp
+++ b/content/canvas/src/CanvasImageCache.cpp
@@ -97,17 +97,17 @@ public:
   bool KeyEquals(KeyTypePointer key) const
   {
     return mData->mImage == key->mImage && mData->mCanvas == key->mCanvas;
   }
 
   static KeyTypePointer KeyToPointer(KeyType& key) { return &key; }
   static PLDHashNumber HashKey(KeyTypePointer key)
   {
-    return HashGeneric(key->mImage, key->mCanvas);
+    return (NS_PTR_TO_INT32(key->mImage) ^ NS_PTR_TO_INT32(key->mCanvas)) >> 2;
   }
   enum { ALLOW_MEMMOVE = true };
 
   nsAutoPtr<ImageCacheEntryData> mData;
 };
 
 class ImageCache MOZ_FINAL : public nsExpirationTracker<ImageCacheEntryData,4> {
 public:
--- a/content/html/content/src/nsHTMLFormElement.h
+++ b/content/html/content/src/nsHTMLFormElement.h
@@ -44,23 +44,57 @@
 #include "nsFormSubmission.h"
 #include "nsGenericHTMLElement.h"
 #include "nsIDOMHTMLFormElement.h"
 #include "nsIWebProgressListener.h"
 #include "nsIRadioGroupContainer.h"
 #include "nsIURI.h"
 #include "nsIWeakReferenceUtils.h"
 #include "nsPIDOMWindow.h"
+#include "nsUnicharUtils.h"
 #include "nsThreadUtils.h"
 #include "nsInterfaceHashtable.h"
 #include "nsDataHashtable.h"
 
 class nsFormControlList;
 class nsIMutableArray;
 
+/**
+ * hashkey wrapper using nsAString KeyType
+ *
+ * @see nsTHashtable::EntryType for specification
+ */
+class nsStringCaseInsensitiveHashKey : public PLDHashEntryHdr
+{
+public:
+  typedef const nsAString& KeyType;
+  typedef const nsAString* KeyTypePointer;
+  nsStringCaseInsensitiveHashKey(KeyTypePointer aStr) : mStr(*aStr) { } //take it easy just deal HashKey 
+  nsStringCaseInsensitiveHashKey(const nsStringCaseInsensitiveHashKey& toCopy) : mStr(toCopy.mStr) { }
+  ~nsStringCaseInsensitiveHashKey() { }
+
+  KeyType GetKey() const { return mStr; }
+  bool KeyEquals(const KeyTypePointer aKey) const
+  {
+    return mStr.Equals(*aKey, nsCaseInsensitiveStringComparator());
+  }
+
+  static KeyTypePointer KeyToPointer(KeyType aKey) { return &aKey; }
+  static PLDHashNumber HashKey(const KeyTypePointer aKey)
+  {
+      nsAutoString tmKey(*aKey);
+      ToLowerCase(tmKey);
+      return HashString(tmKey);
+  }
+  enum { ALLOW_MEMMOVE = true };
+
+private:
+  const nsString mStr;
+};
+
 class nsHTMLFormElement : public nsGenericHTMLElement,
                           public nsIDOMHTMLFormElement,
                           public nsIWebProgressListener,
                           public nsIForm,
                           public nsIRadioGroupContainer
 {
 public:
   nsHTMLFormElement(already_AddRefed<nsINodeInfo> aNodeInfo);
--- a/content/xslt/src/xslt/txKeyFunctionCall.cpp
+++ b/content/xslt/src/xslt/txKeyFunctionCall.cpp
@@ -39,19 +39,16 @@
 #include "txExecutionState.h"
 #include "nsGkAtoms.h"
 #include "txSingleNodeContext.h"
 #include "txXSLTFunctions.h"
 #include "nsReadableUtils.h"
 #include "txKey.h"
 #include "txXSLTPatterns.h"
 #include "txNamespaceMap.h"
-#include "mozilla/HashFunctions.h"
-
-using namespace mozilla;
 
 /*
  * txKeyFunctionCall
  * A representation of the XSLT additional function: key()
  */
 
 /*
  * Creates a new key function call
@@ -170,19 +167,20 @@ txKeyValueHashEntry::MatchEntry(const vo
 }
 
 PLDHashNumber
 txKeyValueHashEntry::HashKey(const void* aKey)
 {
     const txKeyValueHashKey* key =
         static_cast<const txKeyValueHashKey*>(aKey);
 
-    PLDHashNumber hash = HashString(key->mKeyValue);
-    return AddToHash(hash, key->mKeyName.mNamespaceID, key->mRootIdentifier,
-                     key->mKeyName.mLocalName.get());
+    return key->mKeyName.mNamespaceID ^
+           NS_PTR_TO_INT32(key->mKeyName.mLocalName.get()) ^
+           key->mRootIdentifier ^
+           HashString(key->mKeyValue);
 }
 
 bool
 txIndexedKeyHashEntry::MatchEntry(const void* aKey) const
 {
     const txIndexedKeyHashKey* key =
         static_cast<const txIndexedKeyHashKey*>(aKey);
 
@@ -190,19 +188,20 @@ txIndexedKeyHashEntry::MatchEntry(const 
            mKey.mRootIdentifier == key->mRootIdentifier;
 }
 
 PLDHashNumber
 txIndexedKeyHashEntry::HashKey(const void* aKey)
 {
     const txIndexedKeyHashKey* key =
         static_cast<const txIndexedKeyHashKey*>(aKey);
-    return HashGeneric(key->mKeyName.mNamespaceID,
-                       key->mRootIdentifier,
-                       key->mKeyName.mLocalName.get());
+
+    return key->mKeyName.mNamespaceID ^
+           NS_PTR_TO_INT32(key->mKeyName.mLocalName.get()) ^
+           key->mRootIdentifier;
 }
 
 /*
  * Class managing XSLT-keys
  */
 
 nsresult
 txKeyHash::getKeyNodes(const txExpandedName& aKeyName,
--- a/content/xul/templates/src/nsRDFConInstanceTestNode.h
+++ b/content/xul/templates/src/nsRDFConInstanceTestNode.h
@@ -104,18 +104,19 @@ public:
             this->~Element();
             MemoryElement::gPool.Free(this, sizeof(Element));
         }
 
         virtual const char* Type() const {
             return "nsRDFConInstanceTestNode::Element"; }
 
         virtual PLHashNumber Hash() const {
-            return mozilla::HashGeneric(mContainerTest, mEmptyTest, mContainer.get());
-        }
+            return (PLHashNumber(NS_PTR_TO_INT32(mContainer.get())) >> 4) ^
+                PLHashNumber(mContainerTest) ^
+                (PLHashNumber(mEmptyTest) << 4); }
 
         virtual bool Equals(const MemoryElement& aElement) const {
             if (aElement.Type() == Type()) {
                 const Element& element = static_cast<const Element&>(aElement);
                 return mContainer == element.mContainer
                     && mContainerTest == element.mContainerTest
                     && mEmptyTest == element.mEmptyTest;
             }
--- a/content/xul/templates/src/nsRDFPropertyTestNode.h
+++ b/content/xul/templates/src/nsRDFPropertyTestNode.h
@@ -119,18 +119,19 @@ public:
             this->~Element();
             MemoryElement::gPool.Free(this, sizeof(Element));
         }
 
         virtual const char* Type() const {
             return "nsRDFPropertyTestNode::Element"; }
 
         virtual PLHashNumber Hash() const {
-            return mozilla::HashGeneric(mSource.get(), mProperty.get(), mTarget.get());
-        }
+            return PLHashNumber(NS_PTR_TO_INT32(mSource.get())) ^
+                (PLHashNumber(NS_PTR_TO_INT32(mProperty.get())) >> 4) ^
+                (PLHashNumber(NS_PTR_TO_INT32(mTarget.get())) >> 12); }
 
         virtual bool Equals(const MemoryElement& aElement) const {
             if (aElement.Type() == Type()) {
                 const Element& element = static_cast<const Element&>(aElement);
                 return mSource == element.mSource
                     && mProperty == element.mProperty
                     && mTarget == element.mTarget;
             }
--- a/dom/base/nsScriptNameSpaceManager.cpp
+++ b/dom/base/nsScriptNameSpaceManager.cpp
@@ -55,32 +55,31 @@
 #include "nsDOMClassInfo.h"
 #include "nsCRT.h"
 #include "nsIObserverService.h"
 #include "mozilla/Services.h"
 
 #define NS_INTERFACE_PREFIX "nsI"
 #define NS_DOM_INTERFACE_PREFIX "nsIDOM"
 
-using namespace mozilla;
-
 // Our extended PLDHashEntryHdr
 class GlobalNameMapEntry : public PLDHashEntryHdr
 {
 public:
   // Our hash table ops don't care about the order of these members
   nsString mKey;
   nsGlobalNameStruct mGlobalName;
 };
 
 
 static PLDHashNumber
 GlobalNameHashHashKey(PLDHashTable *table, const void *key)
 {
   const nsAString *str = static_cast<const nsAString *>(key);
+
   return HashString(*str);
 }
 
 static bool
 GlobalNameHashMatchEntry(PLDHashTable *table, const PLDHashEntryHdr *entry,
                          const void *key)
 {
   const GlobalNameMapEntry *e =
--- a/dom/indexedDB/OpenDatabaseHelper.cpp
+++ b/dom/indexedDB/OpenDatabaseHelper.cpp
@@ -46,17 +46,16 @@
 #include "nsThreadUtils.h"
 #include "snappy/snappy.h"
 #include "test_quota.h"
 
 #include "IDBEvents.h"
 #include "IDBFactory.h"
 #include "IndexedDatabaseManager.h"
 
-using namespace mozilla;
 USING_INDEXEDDB_NAMESPACE
 
 namespace {
 
 // If JS_STRUCTURED_CLONE_VERSION changes then we need to update our major
 // schema version.
 PR_STATIC_ASSERT(JS_STRUCTURED_CLONE_VERSION == 1);
 
--- a/dom/plugins/base/nsJSNPRuntime.cpp
+++ b/dom/plugins/base/nsJSNPRuntime.cpp
@@ -51,22 +51,20 @@
 #include "nsIDocument.h"
 #include "nsIJSRuntimeService.h"
 #include "nsIJSContextStack.h"
 #include "nsIXPConnect.h"
 #include "nsIDOMElement.h"
 #include "prmem.h"
 #include "nsIContent.h"
 #include "nsIPluginInstanceOwner.h"
-#include "mozilla/HashFunctions.h"
 
 #define NPRUNTIME_JSCLASS_NAME "NPObject JS wrapper class"
 
 using namespace mozilla::plugins::parent;
-using namespace mozilla;
 
 #include "mozilla/plugins/PluginScriptableObjectParent.h"
 using mozilla::plugins::PluginScriptableObjectParent;
 using mozilla::plugins::ParentNPObject;
 
 // Hash of JSObject wrappers that wraps JSObjects as NPObjects. There
 // will be one wrapper per JSObject per plugin instance, i.e. if two
 // plugins access the JSObject x, two wrappers for x will be
@@ -1019,17 +1017,18 @@ public:
   nsJSObjWrapper *mJSObjWrapper;
 };
 
 
 static PLDHashNumber
 JSObjWrapperHash(PLDHashTable *table, const void *key)
 {
   const nsJSObjWrapperKey *e = static_cast<const nsJSObjWrapperKey *>(key);
-  return HashGeneric(e->mJSObj, e->mNpp);
+
+  return (PLDHashNumber)((PRWord)e->mJSObj ^ (PRWord)e->mNpp) >> 2;
 }
 
 static bool
 JSObjWrapperHashMatchEntry(PLDHashTable *table, const PLDHashEntryHdr *entry,
                            const void *key)
 {
   const nsJSObjWrapperKey *objWrapperKey =
     static_cast<const nsJSObjWrapperKey *>(key);
--- a/dom/tests/mochitest/localstorage/test_localStorageBase.html
+++ b/dom/tests/mochitest/localstorage/test_localStorageBase.html
@@ -95,17 +95,17 @@ function startTest()
   localStorage.setItem("key2", "value2");
   is(localStorage.length, 2, "The storage has two key-value pairs");
   is(localStorage.getItem("key1"), "value1");
   is(localStorage.getItem("key2"), "value2");
   var firstKey = localStorage.key(0);
   var secondKey = localStorage.key(1);
   ok((firstKey == 'key1' && secondKey == 'key2') ||
      (firstKey == 'key2' && secondKey == 'key1'),
-     'key() API works.');
+     'Both keys should be present.');
 
   // change the second key
   localStorage.setItem("key2", "value2-2");
   is(localStorage.length, 2, "The storage has two key-value pairs");
   is(localStorage.key(0), firstKey); // After key value changes the order must be preserved
   is(localStorage.key(1), secondKey);
   checkException(function() {localStorage.key(-1);}, INDEX_SIZE_ERR);
   checkException(function() {localStorage.key(2);}, INDEX_SIZE_ERR);
--- a/dom/tests/mochitest/localstorage/test_localStorageBasePrivateBrowsing.html
+++ b/dom/tests/mochitest/localstorage/test_localStorageBasePrivateBrowsing.html
@@ -114,17 +114,17 @@ function doTest()
   localStorage.setItem("key2", "value2");
   is(localStorage.length, 2, "The storage has two key-value pairs");
   is(localStorage.getItem("key1"), "value1");
   is(localStorage.getItem("key2"), "value2");
   var firstKey = localStorage.key(0);
   var secondKey = localStorage.key(1);
   ok((firstKey == 'key1' && secondKey == 'key2') ||
      (firstKey == 'key2' && secondKey == 'key1'),
-     'key() API works.');
+     'Both keys should be present.');
 
   // change the second key
   localStorage.setItem("key2", "value2-2");
   is(localStorage.length, 2, "The storage has two key-value pairs");
   is(localStorage.key(0), firstKey); // After key value changes the order must be preserved
   is(localStorage.key(1), secondKey);
   checkException(function() {localStorage.key(-1);}, INDEX_SIZE_ERR);
   checkException(function() {localStorage.key(2);}, INDEX_SIZE_ERR);
--- a/dom/tests/mochitest/localstorage/test_localStorageBaseSessionOnly.html
+++ b/dom/tests/mochitest/localstorage/test_localStorageBaseSessionOnly.html
@@ -105,17 +105,17 @@ function startTest()
   localStorage.setItem("key2", "value2");
   is(localStorage.length, 2, "The storage has two key-value pairs");
   is(localStorage.getItem("key1"), "value1");
   is(localStorage.getItem("key2"), "value2");
   var firstKey = localStorage.key(0);
   var secondKey = localStorage.key(1);
   ok((firstKey == 'key1' && secondKey == 'key2') ||
      (firstKey == 'key2' && secondKey == 'key1'),
-     'key() API works.');
+     'Both keys should be present.');
 
   // change the second key
   localStorage.setItem("key2", "value2-2");
   is(localStorage.length, 2, "The storage has two key-value pairs");
   is(localStorage.key(0), firstKey); // After key value changes the order must be preserved
   is(localStorage.key(1), secondKey);
   checkException(function() {localStorage.key(-1);}, INDEX_SIZE_ERR);
   checkException(function() {localStorage.key(2);}, INDEX_SIZE_ERR);
--- a/dom/tests/mochitest/sessionstorage/test_sessionStorageBase.html
+++ b/dom/tests/mochitest/sessionstorage/test_sessionStorageBase.html
@@ -97,17 +97,17 @@ function startTest()
   sessionStorage.setItem("key2", "value2");
   is(sessionStorage.length, 2, "The storage has two key-value pairs");
   is(sessionStorage.getItem("key1"), "value1");
   is(sessionStorage.getItem("key2"), "value2");
   var firstKey = sessionStorage.key(0);
   var secondKey = sessionStorage.key(1);
   ok((firstKey == 'key1' && secondKey == 'key2') ||
      (firstKey == 'key2' && secondKey == 'key1'),
-     'key() API works.');
+     'Both keys should be present.');
 
   // change the second key
   sessionStorage.setItem("key2", "value2-2");
   is(sessionStorage.length, 2, "The storage has two key-value pairs");
   is(sessionStorage.key(0), firstKey); // After key value changes the order must be preserved
   is(sessionStorage.key(1), secondKey);
   checkException(function() {sessionStorage.key(-1);}, INDEX_SIZE_ERR);
   checkException(function() {sessionStorage.key(2);}, INDEX_SIZE_ERR);
--- a/embedding/components/commandhandler/src/nsCommandParams.cpp
+++ b/embedding/components/commandhandler/src/nsCommandParams.cpp
@@ -36,19 +36,17 @@
  * ***** END LICENSE BLOCK ***** */
 
 #include "xpcom-config.h"
 #include NEW_H    // for placement new
 #include "nscore.h"
 #include "nsCRT.h"
 
 #include "nsCommandParams.h"
-#include "mozilla/HashFunctions.h"
 
-using namespace mozilla;
 
 PLDHashTableOps nsCommandParams::sHashOps =
 {
     PL_DHashAllocTable,
     PL_DHashFreeTable,
     HashKey,
     HashMatchEntry,
     HashMoveEntry,
@@ -353,17 +351,17 @@ nsCommandParams::GetOrMakeEntry(const ch
 
 #if 0
 #pragma mark -
 #endif
 
 PLDHashNumber
 nsCommandParams::HashKey(PLDHashTable *table, const void *key)
 {
-  return HashString((const char *)key);
+  return nsCRT::HashCode((const char *)key);
 }
 
 bool
 nsCommandParams::HashMatchEntry(PLDHashTable *table,
                                 const PLDHashEntryHdr *entry, const void *key)
 {
   const char*   keyString = (const char*)key;
   const HashEntry*   thisEntry = static_cast<const HashEntry*>(entry);
--- a/gfx/thebes/gfxFont.h
+++ b/gfx/thebes/gfxFont.h
@@ -53,17 +53,16 @@
 #include "gfxSkipChars.h"
 #include "gfxRect.h"
 #include "nsExpirationTracker.h"
 #include "gfxFontConstants.h"
 #include "gfxPlatform.h"
 #include "nsIAtom.h"
 #include "nsISupportsImpl.h"
 #include "gfxPattern.h"
-#include "mozilla/HashFunctions.h"
 
 typedef struct _cairo_scaled_font cairo_scaled_font_t;
 
 #ifdef DEBUG
 #include <stdio.h>
 #endif
 
 class gfxContext;
@@ -791,17 +790,17 @@ protected:
         // blank. The caller of Put() will fill this in.
         HashEntry(KeyTypePointer aStr) : mFont(nsnull) { }
         HashEntry(const HashEntry& toCopy) : mFont(toCopy.mFont) { }
         ~HashEntry() { }
 
         bool KeyEquals(const KeyTypePointer aKey) const;
         static KeyTypePointer KeyToPointer(KeyType aKey) { return &aKey; }
         static PLDHashNumber HashKey(const KeyTypePointer aKey) {
-            return mozilla::HashGeneric(aKey->mStyle->Hash(), aKey->mFontEntry);
+            return NS_PTR_TO_INT32(aKey->mFontEntry) ^ aKey->mStyle->Hash();
         }
         enum { ALLOW_MEMMOVE = true };
 
         gfxFont* mFont;
     };
 
     nsTHashtable<HashEntry> mFonts;
 
--- a/intl/unicharutil/util/nsUnicharUtils.cpp
+++ b/intl/unicharutil/util/nsUnicharUtils.cpp
@@ -42,17 +42,16 @@
 #include "nsUnicharUtilCIID.h"
 
 #include "nsCRT.h"
 #include "nsICaseConversion.h"
 #include "nsServiceManagerUtils.h"
 #include "nsXPCOMStrings.h"
 #include "casetable.h"
 #include "nsUTF8Utils.h"
-#include "nsHashKeys.h"
 
 #include <ctype.h>
 
 // For gUpperToTitle
 enum {
   kUpperIdx =0,
   kTitleIdx
 };
@@ -536,38 +535,8 @@ CaseInsensitiveUTF8CharsEqual(const char
   }
 
   // Can't have an error past this point.
   *aErr = false;
 
   return leftChar == rightChar;
 }
 
-namespace mozilla {
-
-PRUint32
-HashUTF8AsUTF16(const char* aUTF8, PRUint32 aLength, bool* aErr)
-{
-  PRUint32 hash = 0;
-  const char* s = aUTF8;
-  const char* end = aUTF8 + aLength;
-
-  *aErr = false;
-
-  while (s < end)
-  {
-    PRUint32 ucs4 = UTF8CharEnumerator::NextChar(&s, end, aErr);
-    if (*aErr) {
-      return 0;
-    }
-
-    if (ucs4 < PLANE1_BASE) {
-      hash = AddToHash(hash, ucs4);
-    }
-    else {
-      hash = AddToHash(hash, H_SURROGATE(ucs4), L_SURROGATE(ucs4));
-    }
-  }
-
-  return hash;
-}
-
-} // namespace mozilla
--- a/intl/unicharutil/util/nsUnicharUtils.h
+++ b/intl/unicharutil/util/nsUnicharUtils.h
@@ -158,24 +158,9 @@ CaseInsensitiveCompare(const char* aLeft
  * aRightNext are guaranteed to be initialized.
  */
 bool
 CaseInsensitiveUTF8CharsEqual(const char* aLeft, const char* aRight,
                               const char* aLeftEnd, const char* aRightEnd,
                               const char** aLeftNext, const char** aRightNext,
                               bool* aErr);
 
-namespace mozilla {
-
-/**
- * Hash a UTF8 string as though it were a UTF16 string.
- *
- * The value returned is the same as if we converted the string to UTF16 and
- * then ran HashString() on the result.
- *
- * The given |length| is in bytes.
- */
-PRUint32
-HashUTF8AsUTF16(const char* aUTF8, PRUint32 aLength, bool* aErr);
-
-} // namespace mozilla
-
 #endif  /* nsUnicharUtils_h__ */
--- a/js/src/jsatom.h
+++ b/js/src/jsatom.h
@@ -46,17 +46,16 @@
 #include "jsapi.h"
 #include "jsprvtd.h"
 #include "jshash.h"
 #include "jspubtd.h"
 #include "jslock.h"
 
 #include "gc/Barrier.h"
 #include "js/HashTable.h"
-#include "mozilla/HashFunctions.h"
 
 struct JSIdArray {
     int length;
     js::HeapId vector[1];    /* actually, length jsid words */
 };
 
 /* Engine-internal extensions of jsid */
 
@@ -169,21 +168,19 @@ extern const char *
 js_AtomToPrintableString(JSContext *cx, JSAtom *atom, JSAutoByteString *bytes);
 
 namespace js {
 
 /* Compute a hash function from chars/length. */
 inline uint32_t
 HashChars(const jschar *chars, size_t length)
 {
-    // We could call mozilla::HashString here, but that isn't inlined.
-
     uint32_t h = 0;
-    for (size_t i = 0; i < length; i++)
-        h = mozilla::AddToHash(h, chars[i]);
+    for (; length; chars++, length--)
+        h = JS_ROTATE_LEFT32(h, 4) ^ *chars;
     return h;
 }
 
 class AtomStateEntry
 {
     uintptr_t bits;
 
     static const uintptr_t NO_TAG_MASK = uintptr_t(-1) - 1;
--- a/js/src/jsdhash.cpp
+++ b/js/src/jsdhash.cpp
@@ -43,17 +43,16 @@
  *
  * Try to keep this file in sync with xpcom/glue/pldhash.cpp.
  */
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include "jsdhash.h"
 #include "jsutil.h"
-#include "mozilla/HashFunctions.h"
 
 using namespace js;
 
 #ifdef JS_DHASHMETER
 # if defined MOZILLA_CLIENT && defined DEBUG_XXXbrendan
 #  include "nsTraceMalloc.h"
 # endif
 # define METER(x)       x
@@ -121,17 +120,23 @@ JS_PUBLIC_API(void)
 JS_DHashFreeTable(JSDHashTable *table, void *ptr)
 {
     UnwantedForeground::free_(ptr);
 }
 
 JS_PUBLIC_API(JSDHashNumber)
 JS_DHashStringKey(JSDHashTable *table, const void *key)
 {
-    return mozilla::HashString(static_cast<const char*>(key));
+    JSDHashNumber h;
+    const unsigned char *s;
+
+    h = 0;
+    for (s = (const unsigned char *) key; *s != '\0'; s++)
+        h = JS_ROTATE_LEFT32(h, 4) ^ *s;
+    return h;
 }
 
 JS_PUBLIC_API(JSDHashNumber)
 JS_DHashVoidPtrKeyStub(JSDHashTable *table, const void *key)
 {
     return (JSDHashNumber)(uintptr_t)key >> 2;
 }
 
--- a/js/src/jshash.cpp
+++ b/js/src/jshash.cpp
@@ -40,17 +40,16 @@
 /*
  * PR hash table package.
  */
 #include <stdlib.h>
 #include <string.h>
 #include "jstypes.h"
 #include "jsutil.h"
 #include "jshash.h"
-#include "mozilla/HashFunctions.h"
 
 using namespace js;
 
 /* Compute the number of buckets in ht */
 #define NBUCKETS(ht)    JS_BIT(JS_HASH_BITS - (ht)->shift)
 
 /* The smallest table has 16 buckets */
 #define MINBUCKETSLOG2  4
@@ -457,16 +456,22 @@ JS_HashTableDump(JSHashTable *ht, JSHash
     JS_HashTableDumpMeter(ht, dump, fp);
 #endif
     return count;
 }
 
 JS_PUBLIC_API(JSHashNumber)
 JS_HashString(const void *key)
 {
-    return mozilla::HashString(static_cast<const char*>(key));
+    JSHashNumber h;
+    const unsigned char *s;
+
+    h = 0;
+    for (s = (const unsigned char *)key; *s; s++)
+        h = JS_ROTATE_LEFT32(h, 4) ^ *s;
+    return h;
 }
 
 JS_PUBLIC_API(int)
 JS_CompareValues(const void *v1, const void *v2)
 {
     return v1 == v2;
 }
--- a/js/src/jsinfer.cpp
+++ b/js/src/jsinfer.cpp
@@ -2522,17 +2522,17 @@ struct types::ArrayTableKey
 
     ArrayTableKey()
         : type(Type::UndefinedType()), proto(NULL)
     {}
 
     typedef ArrayTableKey Lookup;
 
     static inline uint32_t hash(const ArrayTableKey &v) {
-        return HashGeneric(v.type.raw(), v.proto);
+        return (uint32_t) (v.type.raw() ^ ((uint32_t)(size_t)v.proto >> 2));
     }
 
     static inline bool match(const ArrayTableKey &v1, const ArrayTableKey &v2) {
         return v1.type == v2.type && v1.proto == v2.proto;
     }
 };
 
 void
@@ -2610,20 +2610,19 @@ struct types::ObjectTableKey
     jsid *ids;
     uint32_t nslots;
     uint32_t nfixed;
     JSObject *proto;
 
     typedef JSObject * Lookup;
 
     static inline uint32_t hash(JSObject *obj) {
-        return HashGeneric(JSID_BITS(obj->lastProperty()->propid().get()),
-                           obj->slotSpan(),
-                           obj->numFixedSlots(),
-                           obj->getProto());
+        return (uint32_t) (JSID_BITS(obj->lastProperty()->propid().get()) ^
+                         obj->slotSpan() ^ obj->numFixedSlots() ^
+                         ((uint32_t)(size_t)obj->getProto() >> 2));
     }
 
     static inline bool match(const ObjectTableKey &v, JSObject *obj) {
         if (obj->slotSpan() != v.nslots ||
             obj->numFixedSlots() != v.nfixed ||
             obj->getProto() != v.proto) {
             return false;
         }
--- a/js/src/jsinferinlines.h
+++ b/js/src/jsinferinlines.h
@@ -41,17 +41,16 @@
 
 #include "jsarray.h"
 #include "jsanalyze.h"
 #include "jscompartment.h"
 #include "jsgcmark.h"
 #include "jsinfer.h"
 #include "jsprf.h"
 #include "vm/GlobalObject.h"
-#include "mozilla/HashFunctions.h"
 
 #include "vm/Stack-inl.h"
 
 #ifndef jsinferinlines_h___
 #define jsinferinlines_h___
 
 /////////////////////////////////////////////////////////////////////
 // Types
@@ -531,18 +530,17 @@ struct AllocationSiteKey {
 
     static const uint32_t OFFSET_LIMIT = (1 << 23);
 
     AllocationSiteKey() { PodZero(this); }
 
     typedef AllocationSiteKey Lookup;
 
     static inline uint32_t hash(AllocationSiteKey key) {
-        return mozilla::HashGeneric(uint32_t(size_t(key.script->code + key.offset)),
-                                    key.kind);
+        return uint32_t(size_t(key.script->code + key.offset)) ^ key.kind;
     }
 
     static inline bool match(const AllocationSiteKey &a, const AllocationSiteKey &b) {
         return a.script == b.script && a.offset == b.offset && a.kind == b.kind;
     }
 };
 
 /* static */ inline TypeObject *
--- a/js/src/jsobj.cpp
+++ b/js/src/jsobj.cpp
@@ -40,17 +40,16 @@
 
 /*
  * JS object implementation.
  */
 #include <stdlib.h>
 #include <string.h>
 
 #include "mozilla/Util.h"
-#include "mozilla/HashFunctions.h"
 
 #include "jstypes.h"
 #include "jsutil.h"
 #include "jshash.h"
 #include "jsdhash.h"
 #include "jsprf.h"
 #include "jsapi.h"
 #include "jsarray.h"
@@ -753,18 +752,19 @@ EvalCacheHash(JSContext *cx, JSLinearStr
 {
     const jschar *s = str->chars();
     size_t n = str->length();
 
     if (n > 100)
         n = 100;
     uint32_t h;
     for (h = 0; n; s++, n--)
-        h = mozilla::AddToHash(h, *s);
-
+        h = JS_ROTATE_LEFT32(h, 4) ^ *s;
+
+    h *= JS_GOLDEN_RATIO;
     h >>= 32 - JS_EVAL_CACHE_SHIFT;
     return &cx->compartment->evalCache[h];
 }
 
 static JS_ALWAYS_INLINE JSScript *
 EvalCacheLookup(JSContext *cx, JSLinearString *str, StackFrame *caller, unsigned staticLevel,
                 JSPrincipals *principals, JSObject &scopeobj, JSScript **bucket)
 {
--- a/js/src/jsobjinlines.h
+++ b/js/src/jsobjinlines.h
@@ -1552,22 +1552,23 @@ class AutoPropertyDescriptorRooter : pri
     }
 
     friend void AutoGCRooter::trace(JSTracer *trc);
 };
 
 inline bool
 NewObjectCache::lookup(Class *clasp, gc::Cell *key, gc::AllocKind kind, EntryIndex *pentry)
 {
-    uintptr_t hash = mozilla::HashGeneric(clasp, key, kind);
+    uintptr_t hash = (uintptr_t(clasp) ^ uintptr_t(key)) + kind;
     *pentry = hash % js::ArrayLength(entries);
 
     Entry *entry = &entries[*pentry];
 
-    return (entry->clasp == clasp && entry->key == key && entry->kind == kind);
+    /* N.B. Lookups with the same clasp/key but different kinds map to different entries. */
+    return (entry->clasp == clasp && entry->key == key);
 }
 
 inline bool
 NewObjectCache::lookupProto(Class *clasp, JSObject *proto, gc::AllocKind kind, EntryIndex *pentry)
 {
     JS_ASSERT(!proto->isGlobal());
     return lookup(clasp, proto, kind, pentry);
 }
--- a/js/src/jspropertycache.h
+++ b/js/src/jspropertycache.h
@@ -39,17 +39,16 @@
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef jspropertycache_h___
 #define jspropertycache_h___
 
 #include "jsapi.h"
 #include "jsprvtd.h"
 #include "jstypes.h"
-#include "mozilla/HashFunctions.h"
 
 #include "vm/String.h"
 
 namespace js {
 
 /*
  * Property cache with structurally typed capabilities for invalidation, for
  * polymorphic callsite method/get/set speedups.  For details, see
@@ -173,17 +172,17 @@ class PropertyCache
     PropertyCache() {
         PodZero(this);
     }
     
   private:
     static inline uintptr_t
     hash(jsbytecode *pc, const Shape *kshape)
     {
-        return mozilla::HashGeneric(pc, kshape) & MASK;
+        return (((uintptr_t(pc) >> SIZE_LOG2) ^ uintptr_t(pc) ^ ((uintptr_t)kshape >> 3)) & MASK);
     }
 
     static inline bool matchShape(JSContext *cx, JSObject *obj, uint32_t shape);
 
     PropertyName *
     fullTest(JSContext *cx, jsbytecode *pc, JSObject **objp,
              JSObject **pobjp, PropertyCacheEntry *entry);
 
--- a/js/src/jsscope.cpp
+++ b/js/src/jsscope.cpp
@@ -1259,19 +1259,22 @@ Shape::setObjectFlag(JSContext *cx, Base
     base.flags |= flag;
 
     return replaceLastProperty(cx, base, proto, last);
 }
 
 /* static */ inline HashNumber
 StackBaseShape::hash(const StackBaseShape *base)
 {
-    JSDHashNumber hash = HashGeneric(base->flags);
-    return AddToHash(hash, base->clasp, base->parent,
-                             base->rawGetter, base->rawSetter);
+    JSDHashNumber hash = base->flags;
+    hash = JS_ROTATE_LEFT32(hash, 4) ^ (uintptr_t(base->clasp) >> 3);
+    hash = JS_ROTATE_LEFT32(hash, 4) ^ (uintptr_t(base->parent) >> 3);
+    hash = JS_ROTATE_LEFT32(hash, 4) ^ uintptr_t(base->rawGetter);
+    hash = JS_ROTATE_LEFT32(hash, 4) ^ uintptr_t(base->rawSetter);
+    return hash;
 }
 
 /* static */ inline bool
 StackBaseShape::match(UnownedBaseShape *key, const StackBaseShape *lookup)
 {
     return key->flags == lookup->flags
         && key->clasp == lookup->clasp
         && key->parent == lookup->parent
@@ -1393,18 +1396,20 @@ Bindings::setParent(JSContext *cx, JSObj
         return false;
     self->lastBinding = newShape;
     return true;
 }
 
 /* static */ inline HashNumber
 InitialShapeEntry::hash(const Lookup &lookup)
 {
-    JSDHashNumber hash = HashGeneric(lookup.clasp, lookup.proto, lookup.parent);
-    return AddToHash(hash, lookup.nfixed);
+    JSDHashNumber hash = uintptr_t(lookup.clasp) >> 3;
+    hash = JS_ROTATE_LEFT32(hash, 4) ^ (uintptr_t(lookup.proto) >> 3);
+    hash = JS_ROTATE_LEFT32(hash, 4) ^ (uintptr_t(lookup.parent) >> 3);
+    return hash + lookup.nfixed;
 }
 
 /* static */ inline bool
 InitialShapeEntry::match(const InitialShapeEntry &key, const Lookup &lookup)
 {
     return lookup.clasp == key.shape->getObjectClass()
         && lookup.proto == key.proto
         && lookup.parent == key.shape->getObjectParent()
--- a/js/src/jsscopeinlines.h
+++ b/js/src/jsscopeinlines.h
@@ -234,19 +234,25 @@ Shape::Shape(UnownedBaseShape *base, uin
 {
     JS_ASSERT(base);
     kids.setNull();
 }
 
 inline JSDHashNumber
 StackShape::hash() const
 {
-    return AddToHash(HashGeneric(base),
-                     flags & Shape::PUBLIC_FLAGS, attrs,
-                     shortid, slot_, JSID_BITS(propid));
+    JSDHashNumber hash = uintptr_t(base);
+
+    /* Accumulate from least to most random so the low bits are most random. */
+    hash = JS_ROTATE_LEFT32(hash, 4) ^ (flags & Shape::PUBLIC_FLAGS);
+    hash = JS_ROTATE_LEFT32(hash, 4) ^ attrs;
+    hash = JS_ROTATE_LEFT32(hash, 4) ^ shortid;
+    hash = JS_ROTATE_LEFT32(hash, 4) ^ slot_;
+    hash = JS_ROTATE_LEFT32(hash, 4) ^ JSID_BITS(propid);
+    return hash;
 }
 
 inline bool
 Shape::matches(const js::Shape *other) const
 {
     return propid_.get() == other->propid_.get() &&
            matchesParamsAfterId(other->base(), other->maybeSlot(), other->attrs,
                                 other->flags, other->shortid_);
--- a/js/src/jswatchpoint.cpp
+++ b/js/src/jswatchpoint.cpp
@@ -36,26 +36,24 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "jswatchpoint.h"
 #include "jsatom.h"
 #include "jsgcmark.h"
 #include "jsobjinlines.h"
-#include "mozilla/HashFunctions.h"
 
 using namespace js;
 using namespace js::gc;
 
 inline HashNumber
 DefaultHasher<WatchKey>::hash(const Lookup &key)
 {
-    return mozilla::HashGeneric(DefaultHasher<JSObject *>::hash(key.object.get()),
-                                HashId(key.id.get()));
+    return DefaultHasher<JSObject *>::hash(key.object.get()) ^ HashId(key.id.get());
 }
 
 class AutoEntryHolder {
     typedef WatchpointMap::Map Map;
     Map &map;
     Map::Ptr p;
     uint32_t gen;
     WatchKey key;
--- a/js/xpconnect/src/XPCMaps.cpp
+++ b/js/xpconnect/src/XPCMaps.cpp
@@ -38,19 +38,16 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 /* Private maps (hashtables). */
 
 #include "xpcprivate.h"
 
 #include "jshash.h"
-#include "mozilla/HashFunctions.h"
-
-using namespace mozilla;
 
 /***************************************************************************/
 // static shared...
 
 // Note this is returning the bit pattern of the first part of the nsID, not
 // the pointer to the nsID.
 
 static JSDHashNumber
@@ -86,31 +83,33 @@ HashNativeKey(JSDHashTable *table, const
     } else {
         Set      = (XPCNativeSet*) Key;
         Addition = nsnull;
         Position = 0;
     }
 
     if (!Set) {
         NS_ASSERTION(Addition, "bad key");
-        h = AddToHash(h, Addition);
+        // This would be an XOR like below.
+        // But "0 ^ x == x". So it does not matter.
+        h = (JSHashNumber) NS_PTR_TO_INT32(Addition) >> 2;
     } else {
         XPCNativeInterface** Current = Set->GetInterfaceArray();
         PRUint16 count = Set->GetInterfaceCount();
         if (Addition) {
             count++;
             for (PRUint16 i = 0; i < count; i++) {
                 if (i == Position)
-                    h = AddToHash(h, Addition);
+                    h ^= (JSHashNumber) NS_PTR_TO_INT32(Addition) >> 2;
                 else
-                    h = AddToHash(h, *(Current++));
+                    h ^= (JSHashNumber) NS_PTR_TO_INT32(*(Current++)) >> 2;
             }
         } else {
             for (PRUint16 i = 0; i < count; i++)
-                h = AddToHash(h, *(Current++));
+                h ^= (JSHashNumber) NS_PTR_TO_INT32(*(Current++)) >> 2;
         }
     }
 
     return h;
 }
 
 /***************************************************************************/
 // implement JSObject2WrappedJSMap...
@@ -549,18 +548,20 @@ XPCNativeScriptableSharedMap::Entry::Has
 
     XPCNativeScriptableShared* obj =
         (XPCNativeScriptableShared*) key;
 
     // hash together the flags and the classname string, ignore the interfaces
     // bitmap since it's very rare that it's different when flags and classname
     // are the same.
 
-    h = HashGeneric(obj->GetFlags());
-    return AddToHash(h, HashString(obj->GetJSClass()->name));
+    h = (JSDHashNumber) obj->GetFlags();
+    for (s = (const unsigned char*) obj->GetJSClass()->name; *s != '\0'; s++)
+        h = JS_ROTATE_LEFT32(h, 4) ^ *s;
+    return h;
 }
 
 JSBool
 XPCNativeScriptableSharedMap::Entry::Match(JSDHashTable *table,
                                            const JSDHashEntryHdr *entry,
                                            const void *key)
 {
     XPCNativeScriptableShared* obj1 =
deleted file mode 100644
--- a/mfbt/HashFunctions.cpp
+++ /dev/null
@@ -1,72 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- * vim: set ts=8 sw=4 et tw=99 ft=cpp:
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at:
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Code.
- *
- * The Initial Developer of the Original Code is
- *   The Mozilla Foundation
- * Portions created by the Initial Developer are Copyright (C) 2011
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *   Justin Lebar <justin.lebar@gmail.com>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/* Implementations of hash functions */
-
-#include "mozilla/HashFunctions.h"
-#include <string.h>
-
-namespace mozilla {
-
-MFBT_API(uint32_t)
-HashBytes(const void* bytes, size_t length)
-{
-  uint32_t hash = 0;
-  const char* b = reinterpret_cast<const char*>(bytes);
-
-  /* Walk word by word. */
-  size_t i = 0;
-  for (; i < length - (length % sizeof(size_t)); i += sizeof(size_t)) {
-    /* Do an explicitly unaligned load of the data. */
-    size_t data;
-    memcpy(&data, b + i, sizeof(size_t));
-
-    hash = AddToHash(hash, data, sizeof(data));
-  }
-
-  /* Get the remaining bytes. */
-  for (; i < length; i++) {
-    hash = AddToHash(hash, b[i]);
-  }
-
-  return hash;
-}
-
-} /* namespace mozilla */
--- a/mfbt/HashFunctions.h
+++ b/mfbt/HashFunctions.h
@@ -2,51 +2,16 @@
  * vim: set ts=8 sw=4 et tw=99 ft=cpp:
  *
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /* Utilities for hashing */
 
-/*
- * This file exports functions for hashing data down to a 32-bit value,
- * including:
- *
- *  - HashString    Hash a char* or uint16_t/wchar_t* of known or unknown
- *                  length.
- *
- *  - HashBytes     Hash a byte array of known length.
- *
- *  - HashGeneric   Hash one or more values.  Currently, we support uint32_t,
- *                  types which can be implicitly cast to uint32_t, data
- *                  pointers, and function pointers.
- *
- *  - AddToHash     Add one or more values to the given hash.  This supports the
- *                  same list of types as HashGeneric.
- *
- *
- * You can chain these functions together to hash complex objects.  For example:
- *
- *  class ComplexObject {
- *    char* str;
- *    uint32_t uint1, uint2;
- *    void (*callbackFn)();
- *
- *    uint32_t Hash() {
- *      uint32_t hash = HashString(str);
- *      hash = AddToHash(hash, uint1, uint2);
- *      return AddToHash(hash, callbackFn);
- *    }
- *  };
- *
- * If you want to hash an nsAString or nsACString, use the HashString functions
- * in nsHashKey.h.
- */
-
 #ifndef mozilla_HashFunctions_h_
 #define mozilla_HashFunctions_h_
 
 #include "mozilla/Assertions.h"
 #include "mozilla/Attributes.h"
 #include "mozilla/StandardInteger.h"
 
 #ifdef __cplusplus
@@ -59,25 +24,28 @@ static const uint32_t GoldenRatioU32 = 0
 
 inline uint32_t
 RotateLeft32(uint32_t value, uint8_t bits)
 {
   MOZ_ASSERT(bits < 32);
   return (value << bits) | (value >> (32 - bits));
 }
 
-namespace detail {
-
+/**
+ * Add the given value(s) to the given hashcode and return the new hashcode.
+ *
+ * AddToHash(h, x, y) is equivalent to AddToHash(AddToHash(h, x), y).
+ */
+MOZ_WARN_UNUSED_RESULT
 inline uint32_t
-AddU32ToHash(uint32_t hash, uint32_t value)
+AddToHash(uint32_t hash, uint32_t value)
 {
   /*
-   * This is the meat of all our hash routines.  This hash function is not
-   * particularly sophisticated, but it seems to work well for our mostly
-   * plain-text inputs.  Implementation notes follow.
+   * This is not a sophisticated hash routine, but it seems to work well for our
+   * mostly plain-text inputs.  Implementation notes follow.
    *
    * Our use of the golden ratio here is arbitrary; we could pick almost any
    * number which:
    *
    *  * is odd (because otherwise, all our hash values will be even)
    *
    *  * has a reasonably-even mix of 1's and 0's (consider the extreme case
    *    where we multiply by 0x3 or 0xeffffff -- this will not produce good
@@ -85,259 +53,60 @@ AddU32ToHash(uint32_t hash, uint32_t val
    *
    * The rotation length of 5 is also arbitrary, although an odd number is again
    * preferable so our hash explores the whole universe of possible rotations.
    *
    * Finally, we multiply by the golden ratio *after* xor'ing, not before.
    * Otherwise, if |hash| is 0 (as it often is for the beginning of a message),
    * the expression
    *
-   *   (GoldenRatioU32 * RotateLeft(hash, 5)) |xor| value
+   *   (GoldenRatioU32 * RotateLeft(hash, 5)) ^ value
    *
    * evaluates to |value|.
    *
    * (Number-theoretic aside: Because any odd number |m| is relatively prime to
    * our modulus (2^32), the list
    *
    *    [x * m (mod 2^32) for 0 <= x < 2^32]
    *
    * has no duplicate elements.  This means that multiplying by |m| does not
    * cause us to skip any possible hash values.
    *
-   * It's also nice if |m| has large-ish order mod 2^32 -- that is, if the
-   * smallest k such that m^k == 1 (mod 2^32) is large -- so we can safely
-   * multiply our hash value by |m| a few times without negating the
-   * multiplicative effect.  Our golden ratio constant has order 2^29, which is
-   * more than enough for our purposes.)
+   * It's also nice if |m| has larger order mod 2^32 -- that is, if the smallest
+   * k such that m^k == 1 (mod 2^32) is large -- so we can safely multiply our
+   * hash value by |m| a few times without negating the multiplicative effect.
+   * Our golden ratio constant has order 2^29, which is more than enough for our
+   * purposes.)
    */
   return GoldenRatioU32 * (RotateLeft32(hash, 5) ^ value);
 }
 
-/**
- * AddUintptrToHash takes sizeof(uintptr_t) as a template parameter.
- */
-template<size_t PtrSize>
-inline uint32_t
-AddUintptrToHash(uint32_t hash, uintptr_t value);
-
-template<>
-inline uint32_t
-AddUintptrToHash<4>(uint32_t hash, uintptr_t value)
-{
-  return AddU32ToHash(hash, static_cast<uint32_t>(value));
-}
-
-template<>
-inline uint32_t
-AddUintptrToHash<8>(uint32_t hash, uintptr_t value)
-{
-  uint32_t v1 = static_cast<uint32_t>(value);
-  uint32_t v2 = static_cast<uint32_t>(value >> 32);
-  return AddU32ToHash(AddU32ToHash(hash, v1), v2);
-}
-
-} /* namespace detail */
-
-/**
- * AddToHash takes a hash and some values and returns a new hash based on the
- * inputs.
- *
- * Currently, we support hashing uint32_t's, values which we can implicitly
- * convert to uint32_t, data pointers, and function pointers.
- */
-template<typename A>
 MOZ_WARN_UNUSED_RESULT
 inline uint32_t
-AddToHash(uint32_t hash, A a)
-{
-  /*
-   * Try to convert |A| to uint32_t implicitly.  If this works, great.  If not,
-   * we'll error out.
-   */
-  return detail::AddU32ToHash(hash, a);
-}
-
-template<typename A>
-MOZ_WARN_UNUSED_RESULT
-inline uint32_t
-AddToHash(uint32_t hash, A* a)
+AddToHash(uint32_t hash, uint32_t v1, uint32_t v2)
 {
-  /*
-   * You might think this function should just take a void*.  But then we'd only
-   * catch data pointers and couldn't handle function pointers.
-   */
-
-  MOZ_STATIC_ASSERT(sizeof(a) == sizeof(uintptr_t),
-                    "Strange pointer!");
-
-  return detail::AddUintptrToHash<sizeof(uintptr_t)>(hash, uintptr_t(a));
-}
-
-template<typename A, typename B>
-MOZ_WARN_UNUSED_RESULT
-uint32_t
-AddToHash(uint32_t hash, A a, B b)
-{
-  return AddToHash(AddToHash(hash, a), b);
-}
-
-template<typename A, typename B, typename C>
-MOZ_WARN_UNUSED_RESULT
-uint32_t
-AddToHash(uint32_t hash, A a, B b, C c)
-{
-  return AddToHash(AddToHash(hash, a, b), c);
-}
-
-template<typename A, typename B, typename C, typename D>
-MOZ_WARN_UNUSED_RESULT
-uint32_t
-AddToHash(uint32_t hash, A a, B b, C c, D d)
-{
-  return AddToHash(AddToHash(hash, a, b, c), d);
+  return AddToHash(AddToHash(hash, v1), v2);
 }
 
-template<typename A, typename B, typename C, typename D, typename E>
-MOZ_WARN_UNUSED_RESULT
-uint32_t
-AddToHash(uint32_t hash, A a, B b, C c, D d, E e)
-{
-  return AddToHash(AddToHash(hash, a, b, c, d), e);
-}
-
-/**
- * The HashGeneric class of functions let you hash one or more values.
- *
- * If you want to hash together two values x and y, calling HashGeneric(x, y) is
- * much better than calling AddToHash(x, y), because AddToHash(x, y) assumes
- * that x has already been hashed.
- */
-template<typename A>
-MOZ_WARN_UNUSED_RESULT
-inline uint32_t
-HashGeneric(A a)
-{
-  return AddToHash(0, a);
-}
-
-template<typename A, typename B>
-MOZ_WARN_UNUSED_RESULT
-inline uint32_t
-HashGeneric(A a, B b)
-{
-  return AddToHash(0, a, b);
-}
-
-template<typename A, typename B, typename C>
-MOZ_WARN_UNUSED_RESULT
-inline uint32_t
-HashGeneric(A a, B b, C c)
-{
-  return AddToHash(0, a, b, c);
-}
-
-template<typename A, typename B, typename C, typename D>
 MOZ_WARN_UNUSED_RESULT
 inline uint32_t
-HashGeneric(A a, B b, C c, D d)
-{
-  return AddToHash(0, a, b, c, d);
-}
-
-template<typename A, typename B, typename C, typename D, typename E>
-MOZ_WARN_UNUSED_RESULT
-inline uint32_t
-HashGeneric(A a, B b, C c, D d, E e)
-{
-  return AddToHash(0, a, b, c, d, e);
-}
-
-namespace detail {
-
-template<typename T>
-uint32_t
-HashUntilZero(const T* str)
+AddToHash(uint32_t hash, uint32_t v1, uint32_t v2, uint32_t v3)
 {
-  uint32_t hash = 0;
-  for (T c; (c = *str); str++)
-    hash = AddToHash(hash, c);
-  return hash;
-}
-
-template<typename T>
-uint32_t
-HashKnownLength(const T* str, size_t length)
-{
-  uint32_t hash = 0;
-  for (size_t i = 0; i < length; i++)
-    hash = AddToHash(hash, str[i]);
-  return hash;
-}
-
-} /* namespace detail */
-
-/**
- * The HashString overloads below do just what you'd expect.
- *
- * If you have the string's length, you might as well call the overload which
- * includes the length.  It may be marginally faster.
- */
-MOZ_WARN_UNUSED_RESULT
-inline uint32_t
-HashString(const char* str)
-{
-  return detail::HashUntilZero(str);
+  return AddToHash(AddToHash(hash, v1, v2), v3);
 }
 
 MOZ_WARN_UNUSED_RESULT
 inline uint32_t
-HashString(const char* str, size_t length)
+AddToHash(uint32_t hash, uint32_t v1, uint32_t v2, uint32_t v3, uint32_t v4)
 {
-  return detail::HashKnownLength(str, length);
-}
-
-MOZ_WARN_UNUSED_RESULT
-inline uint32_t
-HashString(const uint16_t* str)
-{
-  return detail::HashUntilZero(str);
+  return AddToHash(AddToHash(hash, v1, v2, v3), v4);
 }
 
 MOZ_WARN_UNUSED_RESULT
 inline uint32_t
-HashString(const uint16_t* str, size_t length)
+AddToHash(uint32_t hash, uint32_t v1, uint32_t v2, uint32_t v3, uint32_t v4, uint32_t v5)
 {
-  return detail::HashKnownLength(str, length);
-}
-
-/*
- * On Windows, wchar_t (PRUnichar) is not the same as uint16_t, even though it's
- * the same width!
- */
-#ifdef WIN32
-MOZ_WARN_UNUSED_RESULT
-inline uint32_t
-HashString(const wchar_t* str)
-{
-  return detail::HashUntilZero(str);
+  return AddToHash(AddToHash(hash, v1, v2, v3, v4), v5);
 }
 
-MOZ_WARN_UNUSED_RESULT
-inline uint32_t
-HashString(const wchar_t* str, size_t length)
-{
-  return detail::HashKnownLength(str, length);
-}
-#endif
-
-/**
- * Hash some number of bytes.
- *
- * This hash walks word-by-word, rather than byte-by-byte, so you won't get the
- * same result out of HashBytes as you would out of HashString.
- */
-MOZ_WARN_UNUSED_RESULT
-extern MFBT_API(uint32_t)
-HashBytes(const void* bytes, size_t length);
-
 } /* namespace mozilla */
 #endif /* __cplusplus */
 #endif /* mozilla_HashFunctions_h_ */
--- a/mfbt/sources.mk
+++ b/mfbt/sources.mk
@@ -1,4 +1,3 @@
 CPPSRCS += \
   Assertions.cpp \
-  HashFunctions.cpp \
   $(NULL)
--- a/modules/libpref/src/Preferences.cpp
+++ b/modules/libpref/src/Preferences.cpp
@@ -35,17 +35,16 @@
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "mozilla/dom/ContentChild.h"
 
 #include "mozilla/Util.h"
-#include "mozilla/HashFunctions.h"
 
 #include "nsXULAppAPI.h"
 
 #include "mozilla/Preferences.h"
 #include "nsAppDirectoryServiceDefs.h"
 #include "nsDirectoryServiceDefs.h"
 #include "nsICategoryManager.h"
 #include "nsCategoryManagerUtils.h"
@@ -102,18 +101,19 @@ public:
 
   static const ValueObserverHashKey* KeyToPointer(ValueObserverHashKey *aKey)
   {
     return aKey;
   }
 
   static PLDHashNumber HashKey(const ValueObserverHashKey *aKey)
   {
-    PLDHashNumber hash = HashString(aKey->mPrefName);
-    return AddToHash(hash, aKey->mCallback);
+    PRUint32 strHash = nsCRT::HashCode(aKey->mPrefName.BeginReading(),
+                                       aKey->mPrefName.Length());
+    return PR_ROTATE_LEFT32(strHash, 4) ^ NS_PTR_TO_UINT32(aKey->mCallback);
   }
 
   ValueObserverHashKey(const char *aPref, PrefChangedFunc aCallback) :
     mPrefName(aPref), mCallback(aCallback) { }
 
   ValueObserverHashKey(const ValueObserverHashKey *aOther) :
     mPrefName(aOther->mPrefName), mCallback(aOther->mCallback)
   { }
--- a/modules/libpref/src/nsPrefBranch.h
+++ b/modules/libpref/src/nsPrefBranch.h
@@ -50,35 +50,37 @@
 #include "nsString.h"
 #include "nsVoidArray.h"
 #include "nsTArray.h"
 #include "nsWeakReference.h"
 #include "nsClassHashtable.h"
 #include "nsCRT.h"
 #include "prbit.h"
 #include "nsTraceRefcnt.h"
-#include "mozilla/HashFunctions.h"
 
 class nsPrefBranch;
 
 class PrefCallback : public PLDHashEntryHdr {
 
   public:
     typedef PrefCallback* KeyType;
     typedef const PrefCallback* KeyTypePointer;
 
     static const PrefCallback* KeyToPointer(PrefCallback *aKey)
     {
       return aKey;
     }
 
     static PLDHashNumber HashKey(const PrefCallback *aKey)
     {
-      PRUint32 hash = mozilla::HashString(aKey->mDomain);
-      return mozilla::AddToHash(hash, aKey->mCanonical);
+      PRUint32 strHash = nsCRT::HashCode(aKey->mDomain.BeginReading(),
+                                         aKey->mDomain.Length());
+
+      return PR_ROTATE_LEFT32(strHash, 4) ^
+             NS_PTR_TO_UINT32(aKey->mCanonical);
     }
 
 
   public:
     // Create a PrefCallback with a strong reference to its observer.
     PrefCallback(const char *aDomain, nsIObserver *aObserver,
                  nsPrefBranch *aBranch)
       : mDomain(aDomain),
--- a/netwerk/base/public/nsNetUtil.h
+++ b/netwerk/base/public/nsNetUtil.h
@@ -43,19 +43,18 @@
 #define nsNetUtil_h__
 
 #include "nsNetError.h"
 #include "nsNetCID.h"
 #include "nsStringGlue.h"
 #include "nsMemory.h"
 #include "nsCOMPtr.h"
 #include "prio.h" // for read/write flags, permissions, etc.
-#include "nsHashKeys.h"
 
-#include "plstr.h"
+#include "nsCRT.h"
 #include "nsIURI.h"
 #include "nsIStandardURL.h"
 #include "nsIURLParser.h"
 #include "nsIUUIDGenerator.h"
 #include "nsIInputStream.h"
 #include "nsIOutputStream.h"
 #include "nsISafeOutputStream.h"
 #include "nsIStreamListener.h"
@@ -102,20 +101,21 @@
 #include "nsIMutable.h"
 #include "nsIPropertyBag2.h"
 #include "nsIWritablePropertyBag2.h"
 #include "nsIIDNService.h"
 #include "nsIChannelEventSink.h"
 #include "nsIChannelPolicy.h"
 #include "nsISocketProviderService.h"
 #include "nsISocketProvider.h"
-#include "nsIRedirectChannelRegistrar.h"
 #include "nsIMIMEHeaderParam.h"
 #include "mozilla/Services.h"
 
+#include "nsIRedirectChannelRegistrar.h"
+
 #ifdef MOZILLA_INTERNAL_API
 
 inline already_AddRefed<nsIIOService>
 do_GetIOService(nsresult* error = 0)
 {
     already_AddRefed<nsIIOService> ret = mozilla::services::GetIOService();
     if (error)
         *error = ret.get() ? NS_OK : NS_ERROR_FAILURE;
@@ -1613,39 +1613,40 @@ NS_GetFinalChannelURI(nsIChannel* channe
 inline PRUint32
 NS_SecurityHashURI(nsIURI* aURI)
 {
     nsCOMPtr<nsIURI> baseURI = NS_GetInnermostURI(aURI);
 
     nsCAutoString scheme;
     PRUint32 schemeHash = 0;
     if (NS_SUCCEEDED(baseURI->GetScheme(scheme)))
-        schemeHash = mozilla::HashString(scheme);
+        schemeHash = nsCRT::HashCode(scheme.get());
 
     // TODO figure out how to hash file:// URIs
     if (scheme.EqualsLiteral("file"))
         return schemeHash; // sad face
 
     if (scheme.EqualsLiteral("imap") ||
         scheme.EqualsLiteral("mailbox") ||
         scheme.EqualsLiteral("news"))
     {
         nsCAutoString spec;
         PRUint32 specHash = baseURI->GetSpec(spec);
         if (NS_SUCCEEDED(specHash))
-            specHash = mozilla::HashString(spec);
+            specHash = nsCRT::HashCode(spec.get());
         return specHash;
     }
 
     nsCAutoString host;
     PRUint32 hostHash = 0;
     if (NS_SUCCEEDED(baseURI->GetAsciiHost(host)))
-        hostHash = mozilla::HashString(host);
+        hostHash = nsCRT::HashCode(host.get());
 
-    return mozilla::AddToHash(schemeHash, hostHash, NS_GetRealPort(baseURI));
+    // XOR to combine hash values
+    return schemeHash ^ hostHash ^ NS_GetRealPort(baseURI);
 }
 
 inline bool
 NS_SecurityCompareURIs(nsIURI* aSourceURI,
                        nsIURI* aTargetURI,
                        bool aStrictFileOriginPolicy)
 {
     // Note that this is not an Equals() test on purpose -- for URIs that don't
--- a/netwerk/base/public/nsURIHashKey.h
+++ b/netwerk/base/public/nsURIHashKey.h
@@ -35,18 +35,18 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 #ifndef nsURIHashKey_h__
 #define nsURIHashKey_h__
 
 #include "pldhash.h"
 #include "nsCOMPtr.h"
+#include "nsCRT.h"
 #include "nsIURI.h"
-#include "nsHashKeys.h"
 
 /**
  * Hashtable key class to use with nsTHashtable/nsBaseHashtable
  */
 class nsURIHashKey : public PLDHashEntryHdr
 {
 public:
     typedef nsIURI* KeyType;
@@ -67,17 +67,17 @@ public:
         }
         return false;
     }
 
     static const nsIURI* KeyToPointer(nsIURI* aKey) { return aKey; }
     static PLDHashNumber HashKey(const nsIURI* aKey) {
         nsCAutoString spec;
         const_cast<nsIURI*>(aKey)->GetSpec(spec);
-        return mozilla::HashString(spec);
+        return nsCRT::HashCode(spec.get());
     }
     
     enum { ALLOW_MEMMOVE = true };
 
 protected:
     nsCOMPtr<nsIURI> mKey;
 };
 
--- a/netwerk/cache/nsCacheEntry.cpp
+++ b/netwerk/cache/nsCacheEntry.cpp
@@ -45,19 +45,18 @@
 #include "nsCacheMetaData.h"
 #include "nsCacheRequest.h"
 #include "nsThreadUtils.h"
 #include "nsError.h"
 #include "nsICacheService.h"
 #include "nsCache.h"
 #include "nsCacheService.h"
 #include "nsCacheDevice.h"
-#include "nsHashKeys.h"
+#include "nsCRT.h"
 
-using namespace mozilla;
 
 nsCacheEntry::nsCacheEntry(nsCString *          key,
                            bool                 streamBased,
                            nsCacheStoragePolicy storagePolicy)
     : mKey(key),
       mFetchCount(0),
       mLastFetched(0),
       mLastModified(0),
@@ -519,17 +518,17 @@ nsCacheEntryHashTable::VisitEntries( PLD
 
 /**
  *  hash table operation callback functions
  */
 
 PLDHashNumber
 nsCacheEntryHashTable::HashKey( PLDHashTable *table, const void *key)
 {
-    return HashString(*static_cast<const nsCString *>(key));
+    return PL_DHashStringKey(table,((nsCString *)key)->get());
 }
 
 bool
 nsCacheEntryHashTable::MatchEntry(PLDHashTable *       /* table */,
                                   const PLDHashEntryHdr * hashEntry,
                                   const void *            key)
 {
     NS_ASSERTION(key !=  nsnull, "### nsCacheEntryHashTable::MatchEntry : null key");
--- a/netwerk/cookie/nsCookieService.h
+++ b/netwerk/cookie/nsCookieService.h
@@ -122,17 +122,17 @@ class nsCookieEntry : public PLDHashEntr
 
     static KeyTypePointer KeyToPointer(KeyType aKey)
     {
       return &aKey;
     }
 
     static PLDHashNumber HashKey(KeyTypePointer aKey)
     {
-      return mozilla::HashString(*aKey);
+      return HashString(*aKey);
     }
 
     enum { ALLOW_MEMMOVE = true };
 
     inline ArrayType& GetCookies() { return mCookies; }
 
   private:
     nsCString mBaseDomain;
--- a/netwerk/dns/nsHostResolver.cpp
+++ b/netwerk/dns/nsHostResolver.cpp
@@ -59,17 +59,16 @@
 #include "prerror.h"
 #include "prtime.h"
 #include "prlong.h"
 #include "prlog.h"
 #include "pldhash.h"
 #include "plstr.h"
 #include "nsURLHelper.h"
 
-#include "mozilla/HashFunctions.h"
 #include "mozilla/FunctionTimer.h"
 #include "mozilla/TimeStamp.h"
 #include "mozilla/Telemetry.h"
 
 using namespace mozilla;
 
 //----------------------------------------------------------------------------
 
@@ -274,17 +273,17 @@ struct nsHostDBEnt : PLDHashEntryHdr
 {
     nsHostRecord *rec;
 };
 
 static PLDHashNumber
 HostDB_HashKey(PLDHashTable *table, const void *key)
 {
     const nsHostKey *hk = static_cast<const nsHostKey *>(key);
-    return AddToHash(HashString(hk->host), RES_KEY_FLAGS(hk->flags), hk->af);
+    return PL_DHashStringKey(table, hk->host) ^ RES_KEY_FLAGS(hk->flags) ^ hk->af;
 }
 
 static bool
 HostDB_MatchEntry(PLDHashTable *table,
                   const PLDHashEntryHdr *entry,
                   const void *key)
 {
     const nsHostDBEnt *he = static_cast<const nsHostDBEnt *>(entry);
--- a/netwerk/protocol/http/nsHttp.cpp
+++ b/netwerk/protocol/http/nsHttp.cpp
@@ -35,22 +35,19 @@
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "nsHttp.h"
 #include "pldhash.h"
 #include "mozilla/Mutex.h"
-#include "mozilla/HashFunctions.h"
 #include "nsCRT.h"
 #include "prbit.h"
 
-using namespace mozilla;
-
 #if defined(PR_LOGGING)
 PRLogModuleInfo *gHttpLog = nsnull;
 #endif
 
 // define storage for all atoms
 #define HTTP_ATOM(_name, _value) nsHttpAtom nsHttp::_name = { _value };
 #include "nsHttpAtomList.h"
 #undef HTTP_ATOM
@@ -96,17 +93,17 @@ NewHeapAtom(const char *value) {
 }
 
 // Hash string ignore case, based on PL_HashString
 static PLDHashNumber
 StringHash(PLDHashTable *table, const void *key)
 {
     PLDHashNumber h = 0;
     for (const char *s = reinterpret_cast<const char*>(key); *s; ++s)
-        h = AddToHash(h, nsCRT::ToLower(*s));
+        h = PR_ROTATE_LEFT32(h, 4) ^ nsCRT::ToLower(*s);
     return h;
 }
 
 static bool
 StringCompare(PLDHashTable *table, const PLDHashEntryHdr *entry,
               const void *testKey)
 {
     const void *entryKey =
--- a/parser/htmlparser/src/nsHTMLTags.cpp
+++ b/parser/htmlparser/src/nsHTMLTags.cpp
@@ -38,17 +38,16 @@
 #include "mozilla/Util.h"
 
 #include "nsHTMLTags.h"
 #include "nsCRT.h"
 #include "nsReadableUtils.h"
 #include "nsString.h"
 #include "nsStaticAtom.h"
 #include "nsUnicharUtils.h"
-#include "mozilla/HashFunctions.h"
 
 using namespace mozilla;
 
 // C++ sucks! There's no way to do this with a macro, at least not
 // that I know, if you know how to do this with a macro then please do
 // so...
 static const PRUnichar sHTMLTagUnicodeName_a[] =
   {'a', '\0'};
@@ -321,17 +320,19 @@ PRInt32 nsHTMLTags::gTableRefCount;
 PLHashTable* nsHTMLTags::gTagTable;
 PLHashTable* nsHTMLTags::gTagAtomTable;
 
 
 // PRUnichar* -> id hash
 static PLHashNumber
 HTMLTagsHashCodeUCPtr(const void *key)
 {
-  return HashString(static_cast<const PRUnichar*>(key));
+  const PRUnichar *str = (const PRUnichar *)key;
+
+  return nsCRT::HashCode(str);
 }
 
 static PRIntn
 HTMLTagsKeyCompareUCPtr(const void *key1, const void *key2)
 {
   const PRUnichar *str1 = (const PRUnichar *)key1;
   const PRUnichar *str2 = (const PRUnichar *)key2;
 
--- a/rdf/base/src/nsRDFService.cpp
+++ b/rdf/base/src/nsRDFService.cpp
@@ -84,19 +84,16 @@
 #include "plstr.h"
 #include "prlog.h"
 #include "prprf.h"
 #include "prmem.h"
 #include "rdf.h"
 #include "nsCRT.h"
 #include "nsCRTGlue.h"
 #include "prbit.h"
-#include "mozilla/HashFunctions.h"
-
-using namespace mozilla;
 
 ////////////////////////////////////////////////////////////////////////
 
 static NS_DEFINE_CID(kRDFXMLDataSourceCID,    NS_RDFXMLDATASOURCE_CID);
 static NS_DEFINE_CID(kRDFDefaultResourceCID,  NS_RDFDEFAULTRESOURCE_CID);
 
 static NS_DEFINE_IID(kIRDFLiteralIID,         NS_IRDFLITERAL_IID);
 static NS_DEFINE_IID(kIRDFDateIID,         NS_IRDFDATE_IID);
@@ -153,17 +150,17 @@ static PLHashAllocOps dataSourceHashAllo
 
 struct ResourceHashEntry : public PLDHashEntryHdr {
     const char *mKey;
     nsIRDFResource *mResource;
 
     static PLDHashNumber
     HashKey(PLDHashTable *table, const void *key)
     {
-        return HashString(static_cast<const char *>(key));
+        return nsCRT::HashCode(static_cast<const char *>(key));
     }
 
     static bool
     MatchEntry(PLDHashTable *table, const PLDHashEntryHdr *hdr,
                const void *key)
     {
         const ResourceHashEntry *entry =
             static_cast<const ResourceHashEntry *>(hdr);
@@ -191,17 +188,17 @@ static PLDHashTableOps gResourceTableOps
 
 struct LiteralHashEntry : public PLDHashEntryHdr {
     nsIRDFLiteral *mLiteral;
     const PRUnichar *mKey;
 
     static PLDHashNumber
     HashKey(PLDHashTable *table, const void *key)
     {
-        return HashString(static_cast<const PRUnichar *>(key));
+        return nsCRT::HashCode(static_cast<const PRUnichar *>(key));
     }
 
     static bool
     MatchEntry(PLDHashTable *table, const PLDHashEntryHdr *hdr,
                const void *key)
     {
         const LiteralHashEntry *entry =
             static_cast<const LiteralHashEntry *>(hdr);
@@ -387,17 +384,22 @@ BlobImpl::GetLength(PRInt32 *aResult)
 struct BlobHashEntry : public PLDHashEntryHdr {
     BlobImpl *mBlob;
 
     static PLDHashNumber
     HashKey(PLDHashTable *table, const void *key)
     {
         const BlobImpl::Data *data =
             static_cast<const BlobImpl::Data *>(key);
-        return HashBytes(data->mBytes, data->mLength);
+
+        const PRUint8 *p = data->mBytes, *limit = p + data->mLength;
+        PLDHashNumber h = 0;
+        for ( ; p < limit; ++p)
+            h = PR_ROTATE_LEFT32(h, 4) ^ *p;
+        return h;
     }
 
     static bool
     MatchEntry(PLDHashTable *table, const PLDHashEntryHdr *hdr,
                const void *key)
     {
         const BlobHashEntry *entry =
             static_cast<const BlobHashEntry *>(hdr);
--- a/security/manager/ssl/src/nsNSSCallbacks.cpp
+++ b/security/manager/ssl/src/nsNSSCallbacks.cpp
@@ -49,17 +49,16 @@
 #include "nsNSSShutDown.h"
 #include "nsIUploadChannel.h"
 #include "nsThreadUtils.h"
 #include "nsIPrompt.h"
 #include "nsProxyRelease.h"
 #include "PSMRunnable.h"
 #include "nsIConsoleService.h"
 #include "nsIHttpChannelInternal.h"
-#include "nsCRT.h"
 
 #include "ssl.h"
 #include "ocsp.h"
 #include "nssb64.h"
 
 using namespace mozilla;
 using namespace mozilla::psm;
 
--- a/toolkit/system/gnome/nsAlertsIconListener.cpp
+++ b/toolkit/system/gnome/nsAlertsIconListener.cpp
@@ -38,17 +38,16 @@
 #include "nsAlertsIconListener.h"
 #include "imgIContainer.h"
 #include "imgILoader.h"
 #include "imgIRequest.h"
 #include "nsNetUtil.h"
 #include "nsIImageToPixbuf.h"
 #include "nsIStringBundle.h"
 #include "nsIObserverService.h"
-#include "nsCRT.h"
 
 #include <gdk/gdk.h>
 
 // Compatibility macro for <libnotify-0.7
 #ifndef NOTIFY_CHECK_VERSION
 #define NOTIFY_CHECK_VERSION(x,y,z) 0
 #endif
 
--- a/xpcom/components/ManifestParser.cpp
+++ b/xpcom/components/ManifestParser.cpp
@@ -37,17 +37,16 @@
  * ***** END LICENSE BLOCK ***** */
 
 #include "mozilla/Util.h"
 
 #include "ManifestParser.h"
 
 #include <string.h>
 
-#include "nsCRT.h"
 #include "prio.h"
 #include "prprf.h"
 #if defined(XP_WIN)
 #include <windows.h>
 #elif defined(MOZ_WIDGET_COCOA)
 #include <CoreServices/CoreServices.h>
 #elif defined(MOZ_WIDGET_GTK2)
 #include <gtk/gtk.h>
--- a/xpcom/ds/nsAtomTable.cpp
+++ b/xpcom/ds/nsAtomTable.cpp
@@ -32,37 +32,33 @@
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "mozilla/Assertions.h"
-#include "mozilla/HashFunctions.h"
 
 #include "nsAtomTable.h"
 #include "nsStaticAtom.h"
 #include "nsString.h"
 #include "nsReadableUtils.h"
 #include "nsUTF8Utils.h"
 #include "nsCRT.h"
 #include "pldhash.h"
 #include "prenv.h"
 #include "nsThreadUtils.h"
 #include "nsDataHashtable.h"
 #include "nsHashKeys.h"
 #include "nsAutoPtr.h"
-#include "nsUnicharUtils.h"
 
 #define PL_ARENA_CONST_ALIGN_MASK 3
 #include "plarena.h"
 
-using namespace mozilla;
-
 /**
  * The shared hash table for atom lookups.
  *
  * XXX This should be manipulated in a threadsafe way or we should make
  * sure it's only manipulated from the main thread.  Probably the latter
  * is better, since the former would hurt performance.
  *
  * If |gAtomTable.ops| is 0, then the table is uninitialized.
@@ -191,27 +187,27 @@ struct AtomTableKey
 
 static PLDHashNumber
 AtomTableGetHash(PLDHashTable *table, const void *key)
 {
   const AtomTableKey *k = static_cast<const AtomTableKey*>(key);
 
   if (k->mUTF8String) {
     bool err;
-    PRUint32 hash = HashUTF8AsUTF16(k->mUTF8String, k->mLength, &err);
+    PRUint32 hash = nsCRT::HashCodeAsUTF16(k->mUTF8String, k->mLength, &err);
     if (err) {
       AtomTableKey* mutableKey = const_cast<AtomTableKey*>(k);
       mutableKey->mUTF8String = nsnull;
       mutableKey->mLength = 0;
       hash = 0;
     }
     return hash;
   }
 
-  return HashString(k->mUTF16String, k->mLength);
+  return nsCRT::HashCode(k->mUTF16String, k->mLength);
 }
 
 static bool
 AtomTableMatchKey(PLDHashTable *table, const PLDHashEntryHdr *entry,
                   const void *key)
 {
   const AtomTableEntry *he = static_cast<const AtomTableEntry*>(entry);
   const AtomTableKey *k = static_cast<const AtomTableKey*>(key);
--- a/xpcom/ds/nsCRT.cpp
+++ b/xpcom/ds/nsCRT.cpp
@@ -50,16 +50,19 @@
  * routines, we simply return 0.
  */
 
 
 #include "nsCRT.h"
 #include "nsIServiceManager.h"
 #include "nsCharTraits.h"
 #include "nsUTF8Utils.h"
+#include "mozilla/HashFunctions.h"
+
+using namespace mozilla;
 
 //----------------------------------------------------------------------
 
 
 ////////////////////////////////////////////////////////////////////////////////
 // My lovely strtok routine
 
 #define IS_DELIM(m, c)          ((m)[(c) >> 3] & (1 << ((c) & 7)))
@@ -194,16 +197,118 @@ PRUnichar* nsCRT::strndup(const PRUnicha
   // PRUnichar* rslt = new PRUnichar[len + 1];
 
   if (rslt == NULL) return NULL;
   memcpy(rslt, str, len * sizeof(PRUnichar));
   rslt[len] = 0;
   return rslt;
 }
 
+  /**
+   * |nsCRT::HashCode| is identical to |PL_HashString|, which tests
+   *  (http://bugzilla.mozilla.org/showattachment.cgi?attach_id=26596)
+   *  show to be the best hash among several other choices.
+   *
+   * We re-implement it here rather than calling it for two reasons:
+   *  (1) in this interface, we also calculate the length of the
+   *  string being hashed; and (2) the narrow and wide and `buffer' versions here
+   *  will hash equivalent strings to the same value, e.g., "Hello" and L"Hello".
+   */
+PRUint32 nsCRT::HashCode(const char* str, PRUint32* resultingStrLen)
+{
+  PRUint32 h = 0;
+  const char* s = str;
+
+  if (!str) return h;
+
+  unsigned char c;
+  while ( (c = *s++) ) {
+    h = AddToHash(h, c);
+  }
+
+  if ( resultingStrLen )
+    *resultingStrLen = (s-str)-1;
+
+  return h;
+}
+
+PRUint32 nsCRT::HashCode(const char* start, PRUint32 length)
+{
+  PRUint32 h = 0;
+  const char* s = start;
+  const char* end = start + length;
+
+  unsigned char c;
+  while ( s < end ) {
+    c = *s++;
+    h = AddToHash(h, c);
+  }
+
+  return h;
+}
+
+PRUint32 nsCRT::HashCode(const PRUnichar* str, PRUint32* resultingStrLen)
+{
+  PRUint32 h = 0;
+  const PRUnichar* s = str;
+
+  if (!str) return h;
+
+  PRUnichar c;
+  while ( (c = *s++) )
+    h = AddToHash(h, c);
+
+  if ( resultingStrLen )
+    *resultingStrLen = (s-str)-1;
+
+  return h;
+}
+
+PRUint32 nsCRT::HashCode(const PRUnichar* start, PRUint32 length)
+{
+  PRUint32 h = 0;
+  const PRUnichar* s = start;
+  const PRUnichar* end = start + length;
+
+  PRUnichar c;
+  while ( s < end ) {
+    c = *s++;
+    h = AddToHash(h, c);
+  }
+
+  return h;
+}
+
+PRUint32 nsCRT::HashCodeAsUTF16(const char* start, PRUint32 length,
+                                bool* err)
+{
+  PRUint32 h = 0;
+  const char* s = start;
+  const char* end = start + length;
+
+  *err = false;
+
+  while ( s < end )
+    {
+      PRUint32 ucs4 = UTF8CharEnumerator::NextChar(&s, end, err);
+      if (*err) {
+	return 0;
+      }
+
+      if (ucs4 < PLANE1_BASE) {
+        h = AddToHash(h, ucs4);
+      }
+      else {
+        h = AddToHash(h, H_SURROGATE(ucs4), L_SURROGATE(ucs4));
+      }
+    }
+
+  return h;
+}
+
 // This should use NSPR but NSPR isn't exporting its PR_strtoll function
 // Until then...
 PRInt64 nsCRT::atoll(const char *str)
 {
     if (!str)
         return LL_Zero();
 
     PRInt64 ll = LL_Zero(), digitll = LL_Zero();
--- a/xpcom/ds/nsCRT.h
+++ b/xpcom/ds/nsCRT.h
@@ -224,16 +224,38 @@ public:
   // by strndup(PRUnichar*, PRUint32).
   static PRUnichar* strndup(const PRUnichar* str, PRUint32 len);
 
   static void free(PRUnichar* str) {
   	nsCppSharedAllocator<PRUnichar> shared_allocator;
   	shared_allocator.deallocate(str, 0 /*we never new or kept the size*/);
   }
 
+  // Computes the hashcode for a c-string, returns the string length as
+  // an added bonus.
+  static PRUint32 HashCode(const char* str,
+                           PRUint32* resultingStrLen = nsnull);
+
+  // Computes the hashcode for a length number of bytes of c-string data.
+  static PRUint32 HashCode(const char* start, PRUint32 length);
+
+  // Computes the hashcode for a ucs2 string, returns the string length
+  // as an added bonus.
+  static PRUint32 HashCode(const PRUnichar* str,
+                           PRUint32* resultingStrLen = nsnull);
+
+  // Computes the hashcode for a buffer with a specified length.
+  static PRUint32 HashCode(const PRUnichar* str, PRUint32 strLen);
+
+  // Computes a hashcode for a length number of UTF8
+  // characters. Returns the same hash code as the HashCode method
+  // taking a |PRUnichar*| would if the string were converted to UTF16.
+  static PRUint32 HashCodeAsUTF16(const char* start, PRUint32 length,
+                                  bool* err);
+
   // String to longlong
   static PRInt64 atoll(const char *str);
   
   static char ToUpper(char aChar) { return NS_ToUpper(aChar); }
   static char ToLower(char aChar) { return NS_ToLower(aChar); }
   
   static bool IsUpper(char aChar) { return NS_IsUpper(aChar); }
   static bool IsLower(char aChar) { return NS_IsLower(aChar); }
--- a/xpcom/ds/nsDoubleHashtable.h
+++ b/xpcom/ds/nsDoubleHashtable.h
@@ -401,17 +401,17 @@ void CLASSNAME::Remove(const KEY_TYPE aK
 class PLDHashStringEntry : public PLDHashEntryHdr
 {
 public:
   PLDHashStringEntry(const void* aKey) :
     mKey(*static_cast<const nsAString*>(aKey)) { }
   ~PLDHashStringEntry() { }
 
   static PLDHashNumber HashKey(const void* key) {
-    return mozilla::HashString(*static_cast<const nsAString*>(key));
+    return HashString(*static_cast<const nsAString*>(key));
   }
   bool MatchEntry(const void* key) const {
     return static_cast<const nsAString*>(key)->Equals(mKey);
   }
 
   const nsString mKey;
 };
 
@@ -421,17 +421,17 @@ public:
 class PLDHashCStringEntry : public PLDHashEntryHdr
 {
 public:
   PLDHashCStringEntry(const void* aKey) :
     mKey(*static_cast<const nsACString*>(aKey)) { }
   ~PLDHashCStringEntry() { }
 
   static PLDHashNumber HashKey(const void* key) {
-    return mozilla::HashString(*static_cast<const nsACString*>(key));
+    return HashString(*static_cast<const nsACString*>(key));
   }
   bool MatchEntry(const void* key) const {
     return static_cast<const nsACString*>(key)->Equals(mKey);
   }
 
   const nsCString mKey;
 };
 
--- a/xpcom/ds/nsHashtable.cpp
+++ b/xpcom/ds/nsHashtable.cpp
@@ -49,19 +49,16 @@
 #include <string.h>
 #include "prmem.h"
 #include "prlog.h"
 #include "nsHashtable.h"
 #include "nsReadableUtils.h"
 #include "nsIObjectInputStream.h"
 #include "nsIObjectOutputStream.h"
 #include "nsCRT.h"
-#include "mozilla/HashFunctions.h"
-
-using namespace mozilla;
 
 struct HTEntry : PLDHashEntryHdr
 {
     nsHashKey* key;
     void* value;
 };
 
 //
@@ -532,17 +529,17 @@ nsCStringKey::~nsCStringKey(void)
     if (mOwnership == OWN)
         nsMemory::Free(mStr);
     MOZ_COUNT_DTOR(nsCStringKey);
 }
 
 PRUint32
 nsCStringKey::HashCode(void) const
 {
-    return HashString(mStr, mStrLen);
+    return nsCRT::HashCode(mStr, (PRUint32*)&mStrLen);
 }
 
 bool
 nsCStringKey::Equals(const nsHashKey* aKey) const
 {
     NS_ASSERTION(aKey->GetKeyType() == CStringKey, "mismatched key types");
     nsCStringKey* other = (nsCStringKey*)aKey;
     NS_ASSERTION(mStrLen != PRUint32(-1), "never called HashCode");
@@ -659,17 +656,17 @@ nsStringKey::~nsStringKey(void)
     if (mOwnership == OWN)
         nsMemory::Free(mStr);
     MOZ_COUNT_DTOR(nsStringKey);
 }
 
 PRUint32
 nsStringKey::HashCode(void) const
 {
-    return HashString(mStr, mStrLen);
+    return nsCRT::HashCode(mStr, (PRUint32*)&mStrLen);
 }
 
 bool
 nsStringKey::Equals(const nsHashKey* aKey) const
 {
     NS_ASSERTION(aKey->GetKeyType() == StringKey, "mismatched key types");
     nsStringKey* other = (nsStringKey*)aKey;
     NS_ASSERTION(mStrLen != PRUint32(-1), "never called HashCode");
--- a/xpcom/ds/nsStaticNameTable.cpp
+++ b/xpcom/ds/nsStaticNameTable.cpp
@@ -40,23 +40,20 @@
 /* Class to manage lookup of static names in a table. */
 
 #include "nsCRT.h"
 
 #include "nscore.h"
 #include "nsString.h"
 #include "nsReadableUtils.h"
 #include "prbit.h"
-#include "mozilla/HashFunctions.h"
 
 #define PL_ARENA_CONST_ALIGN_MASK 3
 #include "nsStaticNameTable.h"
 
-using namespace mozilla;
-
 struct NameTableKey
 {
     NameTableKey(const nsAFlatCString* aKeyStr)
         : mIsUnichar(false)
     {
         mKeyStr.m1b = aKeyStr;
     }
         
@@ -111,24 +108,24 @@ static PLDHashNumber
 caseInsensitiveStringHashKey(PLDHashTable *table, const void *key)
 {
     PLDHashNumber h = 0;
     const NameTableKey* tableKey = static_cast<const NameTableKey*>(key);
     if (tableKey->mIsUnichar) {
         for (const PRUnichar* s = tableKey->mKeyStr.m2b->get();
              *s != '\0';
              s++)
-            h = AddToHash(h, *s & ~0x20);
+            h = PR_ROTATE_LEFT32(h, 4) ^ (*s & ~0x20);
     } else {
         for (const unsigned char* s =
                  reinterpret_cast<const unsigned char*>
                                  (tableKey->mKeyStr.m1b->get());
              *s != '\0';
              s++)
-            h = AddToHash(h, *s & ~0x20);
+            h = PR_ROTATE_LEFT32(h, 4) ^ (*s & ~0x20);
     }
     return h;
 }
 
 static const struct PLDHashTableOps nametable_CaseInsensitiveHashTableOps = {
     PL_DHashAllocTable,
     PL_DHashFreeTable,
     caseInsensitiveStringHashKey,
--- a/xpcom/glue/nsHashKeys.h
+++ b/xpcom/glue/nsHashKeys.h
@@ -42,41 +42,20 @@
 #include "nsISupports.h"
 #include "nsIHashable.h"
 #include "nsCOMPtr.h"
 #include "pldhash.h"
 #include NEW_H
 
 #include "nsStringGlue.h"
 #include "nsCRTGlue.h"
-#include "nsUnicharUtils.h"
 
 #include <stdlib.h>
 #include <string.h>
 
-#include "mozilla/HashFunctions.h"
-
-namespace mozilla {
-
-// These are defined analogously to the HashString overloads in mfbt.
-
-inline PRUint32
-HashString(const nsAString& aStr)
-{
-  return HashString(aStr.BeginReading(), aStr.Length());
-}
-
-inline PRUint32
-HashString(const nsACString& aStr)
-{
-  return HashString(aStr.BeginReading(), aStr.Length());
-}
-
-} // namespace mozilla
-
 /** @file nsHashKeys.h
  * standard HashKey classes for nsBaseHashtable and relatives. Each of these
  * classes follows the nsTHashtable::EntryType specification
  *
  * Lightweight keytypes provided here:
  * nsStringHashKey
  * nsCStringHashKey
  * nsUint32HashKey
@@ -88,16 +67,21 @@ HashString(const nsACString& aStr)
  * nsISupportsHashKey
  * nsIDHashKey
  * nsDepCharHashKey
  * nsCharPtrHashKey
  * nsUnicharPtrHashKey
  * nsHashableHashKey
  */
 
+NS_COM_GLUE PRUint32 HashString(const nsAString& aStr);
+NS_COM_GLUE PRUint32 HashString(const nsACString& aStr);
+NS_COM_GLUE PRUint32 HashString(const char* aKey);
+NS_COM_GLUE PRUint32 HashString(const PRUnichar* aKey);
+
 /**
  * hashkey wrapper using nsAString KeyType
  *
  * @see nsTHashtable::EntryType for specification
  */
 class nsStringHashKey : public PLDHashEntryHdr
 {
 public:
@@ -112,65 +96,24 @@ public:
   bool KeyEquals(const KeyTypePointer aKey) const
   {
     return mStr.Equals(*aKey);
   }
 
   static KeyTypePointer KeyToPointer(KeyType aKey) { return &aKey; }
   static PLDHashNumber HashKey(const KeyTypePointer aKey)
   {
-    return mozilla::HashString(*aKey);
+    return HashString(*aKey);
   }
   enum { ALLOW_MEMMOVE = true };
 
 private:
   const nsString mStr;
 };
 
-#ifdef MOZILLA_INTERNAL_API
-
-/**
- * hashkey wrapper using nsAString KeyType
- *
- * This is internal-API only because nsCaseInsensitiveStringComparator is
- * internal-only.
- *
- * @see nsTHashtable::EntryType for specification
- */
-class nsStringCaseInsensitiveHashKey : public PLDHashEntryHdr
-{
-public:
-  typedef const nsAString& KeyType;
-  typedef const nsAString* KeyTypePointer;
-
-  nsStringCaseInsensitiveHashKey(KeyTypePointer aStr) : mStr(*aStr) { } //take it easy just deal HashKey 
-  nsStringCaseInsensitiveHashKey(const nsStringCaseInsensitiveHashKey& toCopy) : mStr(toCopy.mStr) { }
-  ~nsStringCaseInsensitiveHashKey() { }
-
-  KeyType GetKey() const { return mStr; }
-  bool KeyEquals(const KeyTypePointer aKey) const
-  {
-    return mStr.Equals(*aKey, nsCaseInsensitiveStringComparator());
-  }
-
-  static KeyTypePointer KeyToPointer(KeyType aKey) { return &aKey; }
-  static PLDHashNumber HashKey(const KeyTypePointer aKey)
-  {
-      nsAutoString tmKey(*aKey);
-      ToLowerCase(tmKey);
-      return mozilla::HashString(tmKey);
-  }
-  enum { ALLOW_MEMMOVE = true };
-
-private:
-  const nsString mStr;
-};
-
-#endif
-
 /**
  * hashkey wrapper using nsACString KeyType
  *
  * @see nsTHashtable::EntryType for specification
  */
 class nsCStringHashKey : public PLDHashEntryHdr
 {
 public:
@@ -183,17 +126,17 @@ public:
 
   KeyType GetKey() const { return mStr; }
 
   bool KeyEquals(KeyTypePointer aKey) const { return mStr.Equals(*aKey); }
 
   static KeyTypePointer KeyToPointer(KeyType aKey) { return &aKey; }
   static PLDHashNumber HashKey(KeyTypePointer aKey)
   {
-    return mozilla::HashString(*aKey);
+    return HashString(*aKey);
   }
   enum { ALLOW_MEMMOVE = true };
 
 private:
   const nsCString mStr;
 };
 
 /**
@@ -380,22 +323,17 @@ public:
   nsIDHashKey(const nsIDHashKey& toCopy) : mID(toCopy.mID) { }
   ~nsIDHashKey() { }
 
   KeyType GetKey() const { return mID; }
 
   bool KeyEquals(KeyTypePointer aKey) const { return aKey->Equals(mID); }
 
   static KeyTypePointer KeyToPointer(KeyType aKey) { return &aKey; }
-  static PLDHashNumber HashKey(KeyTypePointer aKey)
-  {
-    // Hash the nsID object's raw bytes.
-    return mozilla::HashBytes(aKey, sizeof(KeyType));
-  }
-
+  static PLDHashNumber HashKey(KeyTypePointer aKey);
   enum { ALLOW_MEMMOVE = true };
 
 private:
   const nsID mID;
 };
 
 /**
  * hashkey wrapper for "dependent" const char*; this class does not "own"
@@ -419,17 +357,17 @@ public:
 
   const char* GetKey() const { return mKey; }
   bool KeyEquals(const char* aKey) const
   {
     return !strcmp(mKey, aKey);
   }
 
   static const char* KeyToPointer(const char* aKey) { return aKey; }
-  static PLDHashNumber HashKey(const char* aKey) { return mozilla::HashString(aKey); }
+  static PLDHashNumber HashKey(const char* aKey) { return HashString(aKey); }
   enum { ALLOW_MEMMOVE = true };
 
 private:
   const char* mKey;
 };
 
 /**
  * hashkey wrapper for const char*; at construction, this class duplicates
@@ -448,17 +386,17 @@ public:
 
   const char* GetKey() const { return mKey; }
   bool KeyEquals(KeyTypePointer aKey) const
   {
     return !strcmp(mKey, aKey);
   }
 
   static KeyTypePointer KeyToPointer(KeyType aKey) { return aKey; }
-  static PLDHashNumber HashKey(KeyTypePointer aKey) { return mozilla::HashString(aKey); }
+  static PLDHashNumber HashKey(KeyTypePointer aKey) { return HashString(aKey); }
 
   enum { ALLOW_MEMMOVE = true };
 
 private:
   const char* mKey;
 };
 
 /**
@@ -478,17 +416,17 @@ public:
 
   const PRUnichar* GetKey() const { return mKey; }
   bool KeyEquals(KeyTypePointer aKey) const
   {
     return !NS_strcmp(mKey, aKey);
   }
 
   static KeyTypePointer KeyToPointer(KeyType aKey) { return aKey; }
-  static PLDHashNumber HashKey(KeyTypePointer aKey) { return mozilla::HashString(aKey); }
+  static PLDHashNumber HashKey(KeyTypePointer aKey) { return HashString(aKey); }
 
   enum { ALLOW_MEMMOVE = true };
 
 private:
   const PRUnichar* mKey;
 };
 
 /**
--- a/xpcom/glue/nsTHashtable.cpp
+++ b/xpcom/glue/nsTHashtable.cpp
@@ -31,17 +31,110 @@
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "nsTHashtable.h"
+#include "nsHashKeys.h"
+#include "prbit.h"
+#include "mozilla/HashFunctions.h"
+
+using namespace mozilla;
+
+PRUint32
+HashString( const nsAString& aStr )
+{
+  PRUint32 code = 0;
+
+#ifdef MOZILLA_INTERNAL_API
+  nsAString::const_iterator begin, end;
+  aStr.BeginReading(begin);
+  aStr.EndReading(end);
+#else
+  const PRUnichar *begin, *end;
+  PRUint32 len = NS_StringGetData(aStr, &begin);
+  end = begin + len;
+#endif
+
+  while (begin != end) {
+    code = AddToHash(code, *begin);
+    ++begin;
+  }
+
+  return code;
+}
+
+PRUint32
+HashString( const nsACString& aStr )
+{
+  PRUint32 code = 0;
+
+#ifdef MOZILLA_INTERNAL_API
+  nsACString::const_iterator begin, end;
+  aStr.BeginReading(begin);
+  aStr.EndReading(end);
+#else
+  const char *begin, *end;
+  PRUint32 len = NS_CStringGetData(aStr, &begin);
+  end = begin + len;
+#endif
+
+  while (begin != end) {
+    code = AddToHash(code, *begin);
+    ++begin;
+  }
+
+  return code;
+}
+
+PRUint32
+HashString(const char *str)
+{
+  PRUint32 code = 0;
+  const char *origStr = str;
+
+  while (*str) {
+    code = AddToHash(code, *str);
+    ++str;
+  }
+
+  return code;
+}
+
+PRUint32
+HashString(const PRUnichar *str)
+{
+  PRUint32 code = 0;
+  const PRUnichar *origStr = str;
+
+  while (*str) {
+    code = AddToHash(code, *str);
+    ++str;
+  }
+
+  return code;
+}
 
 PLDHashOperator
 PL_DHashStubEnumRemove(PLDHashTable    *table,
                                        PLDHashEntryHdr *entry,
                                        PRUint32         ordinal,
                                        void            *userarg)
 {
   return PL_DHASH_REMOVE;
 }
+
+PRUint32 nsIDHashKey::HashKey(const nsID* id)
+{
+  PRUint32 h = id->m0;
+  PRUint32 i;
+
+  h = PR_ROTATE_LEFT32(h, 4) ^ id->m1;
+  h = PR_ROTATE_LEFT32(h, 4) ^ id->m2;
+
+  for (i = 0; i < 8; i++)
+    h = PR_ROTATE_LEFT32(h, 4) ^ id->m3[i];
+
+  return h;
+}
--- a/xpcom/glue/pldhash.cpp
+++ b/xpcom/glue/pldhash.cpp
@@ -121,17 +121,23 @@ void
 PL_DHashFreeTable(PLDHashTable *table, void *ptr)
 {
     free(ptr);
 }
 
 PLDHashNumber
 PL_DHashStringKey(PLDHashTable *table, const void *key)
 {
-    return HashString(static_cast<const char*>(key));
+    PLDHashNumber h;
+    const unsigned char *s;
+
+    h = 0;
+    for (s = (const unsigned char *) key; *s != '\0'; s++)
+        h = AddToHash(h, *s);
+    return h;
 }
 
 PLDHashNumber
 PL_DHashVoidPtrKeyStub(PLDHashTable *table, const void *key)
 {
     return (PLDHashNumber)(PRPtrdiff)key >> 2;
 }
 
--- a/xpcom/io/nsLocalFileOS2.cpp
+++ b/xpcom/io/nsLocalFileOS2.cpp
@@ -54,18 +54,16 @@
 #include "prtypes.h"
 #include "prio.h"
 
 #include "nsReadableUtils.h"
 #include "nsISupportsPrimitives.h"
 #include "nsIMutableArray.h"
 #include "nsTraceRefcntImpl.h"
 
-using namespace mozilla;
-
 #define CHECK_mWorkingPath()                    \
     PR_BEGIN_MACRO                              \
         if (mWorkingPath.IsEmpty())             \
             return NS_ERROR_NOT_INITIALIZED;    \
     PR_END_MACRO
 
 //-----------------------------------------------------------------------------
 // static helper functions
@@ -2572,17 +2570,17 @@ nsLocalFile::Equals(nsIHashable* aOther,
     }
 
     return Equals(otherfile, aResult);
 }
 
 NS_IMETHODIMP
 nsLocalFile::GetHashCode(PRUint32 *aResult)
 {
-    *aResult = HashString(mWorkingPath);
+    *aResult = nsCRT::HashCode(mWorkingPath.get());
     return NS_OK;
 }
 
 nsresult
 NS_NewLocalFile(const nsAString &path, bool followLinks, nsILocalFile* *result)
 {
     nsCAutoString buf;
     nsresult rv = NS_CopyUnicodeToNative(path, buf);
--- a/xpcom/io/nsLocalFileUnix.cpp
+++ b/xpcom/io/nsLocalFileUnix.cpp
@@ -116,17 +116,16 @@ static nsresult MacErrorMapper(OSErr inE
 #ifdef MOZ_WIDGET_ANDROID
 #include "AndroidBridge.h"
 #include "nsIMIMEService.h"
 #include <linux/magic.h>
 #endif
 
 #include "nsNativeCharsetUtils.h"
 #include "nsTraceRefcntImpl.h"
-#include "nsHashKeys.h"
 
 using namespace mozilla;
 
 #define ENSURE_STAT_CACHE()                     \
     PR_BEGIN_MACRO                              \
         if (!FillStatCache())                   \
              return NSRESULT_FOR_ERRNO();       \
     PR_END_MACRO
@@ -2026,17 +2025,17 @@ nsLocalFile::Equals(nsIHashable* aOther,
     }
 
     return Equals(otherFile, aResult);
 }
 
 NS_IMETHODIMP
 nsLocalFile::GetHashCode(PRUint32 *aResult)
 {
-    *aResult = HashString(mPath);
+    *aResult = nsCRT::HashCode(mPath.get());
     return NS_OK;
 }
 
 nsresult 
 NS_NewLocalFile(const nsAString &path, bool followLinks, nsILocalFile* *result)
 {
     nsCAutoString buf;
     nsresult rv = NS_CopyUnicodeToNative(path, buf);
--- a/xpcom/tests/TestHashtables.cpp
+++ b/xpcom/tests/TestHashtables.cpp
@@ -102,17 +102,17 @@ public:
   typedef const char* KeyTypePointer;
 
   EntityToUnicodeEntry(const char* aKey) { mNode = nsnull; }
   EntityToUnicodeEntry(const EntityToUnicodeEntry& aEntry) { mNode = aEntry.mNode; }
   ~EntityToUnicodeEntry() { };
 
   bool KeyEquals(const char* aEntity) const { return !strcmp(mNode->mStr, aEntity); }
   static const char* KeyToPointer(const char* aEntity) { return aEntity; }
-  static PLDHashNumber HashKey(const char* aEntity) { return mozilla::HashString(aEntity); }
+  static PLDHashNumber HashKey(const char* aEntity) { return HashString(aEntity); }
   enum { ALLOW_MEMMOVE = true };
 
   const EntityNode* mNode;
 };
 
 PLDHashOperator
 nsTEnumGo(EntityToUnicodeEntry* aEntry, void* userArg) {
   printf("  enumerated \"%s\" = %u\n", 
--- a/xpcom/tests/TestUTF.cpp
+++ b/xpcom/tests/TestUTF.cpp
@@ -36,19 +36,19 @@
 
 #include "mozilla/Util.h"
 
 #include <stdio.h>
 #include <stdlib.h>
 #include "nsString.h"
 #include "nsStringBuffer.h"
 #include "nsReadableUtils.h"
+#include "nsCRTGlue.h"
 #include "UTFStrings.h"
-#include "nsUnicharUtils.h"
-#include "mozilla/HashFunctions.h"
+#include "nsCRT.h"
 
 using namespace mozilla;
 
 namespace TestUTF {
 
 bool
 test_valid()
 {
@@ -148,37 +148,37 @@ test_malformed8()
 }
 
 bool
 test_hashas16()
 {
   for (unsigned int i = 0; i < ArrayLength(ValidStrings); ++i) {
     nsDependentCString str8(ValidStrings[i].m8);
     bool err;
-    if (HashString(ValidStrings[i].m16) !=
-        HashUTF8AsUTF16(str8.get(), str8.Length(), &err) ||
+    if (nsCRT::HashCode(ValidStrings[i].m16) !=
+        nsCRT::HashCodeAsUTF16(str8.get(), str8.Length(), &err) ||
         err)
       return false;
   }
 
   for (unsigned int i = 0; i < ArrayLength(Invalid8Strings); ++i) {
     nsDependentCString str8(Invalid8Strings[i].m8);
     bool err;
-    if (HashString(Invalid8Strings[i].m16) !=
-        HashUTF8AsUTF16(str8.get(), str8.Length(), &err) ||
+    if (nsCRT::HashCode(Invalid8Strings[i].m16) !=
+        nsCRT::HashCodeAsUTF16(str8.get(), str8.Length(), &err) ||
         err)
       return false;
   }
 
 // Don't run this test in debug builds as that intentionally asserts.
 #ifndef DEBUG
   for (unsigned int i = 0; i < ArrayLength(Malformed8Strings); ++i) {
     nsDependentCString str8(Malformed8Strings[i]);
     bool err;
-    if (HashUTF8AsUTF16(str8.get(), str8.Length(), &err) != 0 ||
+    if (nsCRT::HashCodeAsUTF16(str8.get(), str8.Length(), &err) != 0 ||
         !err)
       return false;
   }
 #endif
 
   return true;
 }