author | Justin Lebar <justin.lebar@gmail.com> |
Sun, 04 Mar 2012 14:20:34 -0500 | |
changeset 91116 | b69617debd8d2d5a7686a7d61da5c0ab987eeb00 |
parent 91115 | 158587a6b17e84403075f55e06aaf626372aac21 |
child 91117 | cf668a3984fef3a56c4671dab84b4ae6f10010fc |
push id | 783 |
push user | lsblakk@mozilla.com |
push date | Tue, 24 Apr 2012 17:33:42 +0000 |
treeherder | mozilla-beta@11faed19f136 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
bugs | 729940 |
milestone | 13.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/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::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; }