Bug 729940 - Part 2: Stop using crappy hash functions in the js engine. r=bhackett

This commit is contained in:
Justin Lebar 2012-03-04 13:49:41 -05:00
parent 2dcd3b129c
commit fef9e78873
12 changed files with 43 additions and 57 deletions

View File

@ -51,6 +51,7 @@
#include "gc/Barrier.h"
#include "js/HashTable.h"
#include "mozilla/HashFunctions.h"
struct JSIdArray {
int length;
@ -173,9 +174,11 @@ namespace js {
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 (; length; chars++, length--)
h = JS_ROTATE_LEFT32(h, 4) ^ *chars;
for (size_t i = 0; i < length; i++)
h = mozilla::AddToHash(h, chars[i]);
return h;
}

View File

@ -48,6 +48,7 @@
#include <string.h>
#include "jsdhash.h"
#include "jsutil.h"
#include "mozilla/HashFunctions.h"
using namespace js;
@ -125,13 +126,7 @@ JS_DHashFreeTable(JSDHashTable *table, void *ptr)
JS_PUBLIC_API(JSDHashNumber)
JS_DHashStringKey(JSDHashTable *table, const void *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;
return mozilla::HashString(static_cast<const char*>(key));
}
JS_PUBLIC_API(JSDHashNumber)

View File

@ -45,6 +45,7 @@
#include "jstypes.h"
#include "jsutil.h"
#include "jshash.h"
#include "mozilla/HashFunctions.h"
using namespace js;
@ -461,13 +462,7 @@ JS_HashTableDump(JSHashTable *ht, JSHashEnumerator dump, FILE *fp)
JS_PUBLIC_API(JSHashNumber)
JS_HashString(const void *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;
return mozilla::HashString(static_cast<const char*>(key));
}
JS_PUBLIC_API(int)

View File

@ -2527,7 +2527,7 @@ struct types::ArrayTableKey
typedef ArrayTableKey Lookup;
static inline uint32_t hash(const ArrayTableKey &v) {
return (uint32_t) (v.type.raw() ^ ((uint32_t)(size_t)v.proto >> 2));
return HashGeneric(v.type.raw(), v.proto);
}
static inline bool match(const ArrayTableKey &v1, const ArrayTableKey &v2) {
@ -2615,9 +2615,10 @@ struct types::ObjectTableKey
typedef JSObject * Lookup;
static inline uint32_t hash(JSObject *obj) {
return (uint32_t) (JSID_BITS(obj->lastProperty()->propid().get()) ^
obj->slotSpan() ^ obj->numFixedSlots() ^
((uint32_t)(size_t)obj->getProto() >> 2));
return HashGeneric(JSID_BITS(obj->lastProperty()->propid().get()),
obj->slotSpan(),
obj->numFixedSlots(),
obj->getProto());
}
static inline bool match(const ObjectTableKey &v, JSObject *obj) {

View File

@ -46,6 +46,7 @@
#include "jsinfer.h"
#include "jsprf.h"
#include "vm/GlobalObject.h"
#include "mozilla/HashFunctions.h"
#include "vm/Stack-inl.h"
@ -535,7 +536,8 @@ struct AllocationSiteKey {
typedef AllocationSiteKey Lookup;
static inline uint32_t hash(AllocationSiteKey key) {
return uint32_t(size_t(key.script->code + key.offset)) ^ key.kind;
return mozilla::HashGeneric(uint32_t(size_t(key.script->code + key.offset)),
key.kind);
}
static inline bool match(const AllocationSiteKey &a, const AllocationSiteKey &b) {

View File

@ -45,6 +45,7 @@
#include <string.h>
#include "mozilla/Util.h"
#include "mozilla/HashFunctions.h"
#include "jstypes.h"
#include "jsutil.h"
@ -757,9 +758,8 @@ EvalCacheHash(JSContext *cx, JSLinearString *str)
n = 100;
uint32_t h;
for (h = 0; n; s++, n--)
h = JS_ROTATE_LEFT32(h, 4) ^ *s;
h = mozilla::AddToHash(h, *s);
h *= JS_GOLDEN_RATIO;
h >>= 32 - JS_EVAL_CACHE_SHIFT;
return &cx->compartment->evalCache[h];
}

View File

@ -1557,13 +1557,12 @@ class AutoPropertyDescriptorRooter : private AutoGCRooter, public PropertyDescri
inline bool
NewObjectCache::lookup(Class *clasp, gc::Cell *key, gc::AllocKind kind, EntryIndex *pentry)
{
uintptr_t hash = (uintptr_t(clasp) ^ uintptr_t(key)) + kind;
uintptr_t hash = mozilla::HashGeneric(clasp, key, kind);
*pentry = hash % js::ArrayLength(entries);
Entry *entry = &entries[*pentry];
/* N.B. Lookups with the same clasp/key but different kinds map to different entries. */
return (entry->clasp == clasp && entry->key == key);
return (entry->clasp == clasp && entry->key == key && entry->kind == kind);
}
inline bool

View File

@ -44,6 +44,7 @@
#include "jsapi.h"
#include "jsprvtd.h"
#include "jstypes.h"
#include "mozilla/HashFunctions.h"
#include "vm/String.h"
@ -177,7 +178,7 @@ class PropertyCache
static inline uintptr_t
hash(jsbytecode *pc, const Shape *kshape)
{
return (((uintptr_t(pc) >> SIZE_LOG2) ^ uintptr_t(pc) ^ ((uintptr_t)kshape >> 3)) & MASK);
return mozilla::HashGeneric(pc, kshape) & MASK;
}
static inline bool matchShape(JSContext *cx, JSObject *obj, uint32_t shape);

View File

@ -1264,12 +1264,9 @@ Shape::setObjectFlag(JSContext *cx, BaseShape::Flag flag, JSObject *proto, Shape
/* static */ inline HashNumber
StackBaseShape::hash(const StackBaseShape *base)
{
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;
JSDHashNumber hash = HashGeneric(base->flags);
return AddToHash(hash, base->clasp, base->parent,
base->rawGetter, base->rawSetter);
}
/* static */ inline bool
@ -1401,10 +1398,8 @@ Bindings::setParent(JSContext *cx, JSObject *obj)
/* static */ inline HashNumber
InitialShapeEntry::hash(const Lookup &lookup)
{
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;
JSDHashNumber hash = HashGeneric(lookup.clasp, lookup.proto, lookup.parent);
return AddToHash(hash, lookup.nfixed);
}
/* static */ inline bool

View File

@ -239,15 +239,9 @@ Shape::Shape(UnownedBaseShape *base, uint32_t nfixed)
inline JSDHashNumber
StackShape::hash() const
{
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;
return AddToHash(HashGeneric(base),
flags & Shape::PUBLIC_FLAGS, attrs,
shortid, slot_, JSID_BITS(propid));
}
inline bool

View File

@ -41,6 +41,7 @@
#include "jsatom.h"
#include "jsgcmark.h"
#include "jsobjinlines.h"
#include "mozilla/HashFunctions.h"
using namespace js;
using namespace js::gc;
@ -48,7 +49,8 @@ using namespace js::gc;
inline HashNumber
DefaultHasher<WatchKey>::hash(const Lookup &key)
{
return DefaultHasher<JSObject *>::hash(key.object.get()) ^ HashId(key.id.get());
return mozilla::HashGeneric(DefaultHasher<JSObject *>::hash(key.object.get()),
HashId(key.id.get()));
}
class AutoEntryHolder {

View File

@ -43,6 +43,9 @@
#include "xpcprivate.h"
#include "jshash.h"
#include "mozilla/HashFunctions.h"
using namespace mozilla;
/***************************************************************************/
// static shared...
@ -88,9 +91,7 @@ HashNativeKey(JSDHashTable *table, const void *key)
if (!Set) {
NS_ASSERTION(Addition, "bad key");
// This would be an XOR like below.
// But "0 ^ x == x". So it does not matter.
h = (JSHashNumber) NS_PTR_TO_INT32(Addition) >> 2;
h = AddToHash(h, Addition);
} else {
XPCNativeInterface** Current = Set->GetInterfaceArray();
PRUint16 count = Set->GetInterfaceCount();
@ -98,13 +99,13 @@ HashNativeKey(JSDHashTable *table, const void *key)
count++;
for (PRUint16 i = 0; i < count; i++) {
if (i == Position)
h ^= (JSHashNumber) NS_PTR_TO_INT32(Addition) >> 2;
h = AddToHash(h, Addition);
else
h ^= (JSHashNumber) NS_PTR_TO_INT32(*(Current++)) >> 2;
h = AddToHash(h, *(Current++));
}
} else {
for (PRUint16 i = 0; i < count; i++)
h ^= (JSHashNumber) NS_PTR_TO_INT32(*(Current++)) >> 2;
h = AddToHash(h, *(Current++));
}
}
@ -553,10 +554,8 @@ XPCNativeScriptableSharedMap::Entry::Hash(JSDHashTable *table, const void *key)
// bitmap since it's very rare that it's different when flags and classname
// are the same.
h = (JSDHashNumber) obj->GetFlags();
for (s = (const unsigned char*) obj->GetJSClass()->name; *s != '\0'; s++)
h = JS_ROTATE_LEFT32(h, 4) ^ *s;
return h;
h = HashGeneric(obj->GetFlags());
return AddToHash(h, HashString(obj->GetJSClass()->name));
}
JSBool