зеркало из https://github.com/mozilla/gecko-dev.git
Bug 729940 - Part 2: Stop using crappy hash functions in the js engine. r=bhackett
This commit is contained in:
Родитель
ec47a60b90
Коммит
0bc96775ff
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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];
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
|
|
Загрузка…
Ссылка в новой задаче