Bug 1223918 - Use stable hashing for WatchPointMap; r=jonco

This commit is contained in:
Terrence Cole 2015-11-12 13:44:06 -08:00
parent 1c4d413300
commit 21741a7a51
4 changed files with 22 additions and 7 deletions

View File

@ -168,7 +168,8 @@ extern JS_PUBLIC_DATA(const JS::HandleId) JSID_EMPTYHANDLE;
namespace js {
template <> struct GCMethods<jsid>
template <>
struct GCMethods<jsid>
{
static jsid initial() { return JSID_VOID; }
static void postBarrier(jsid* idp, jsid prev, jsid next) {}

View File

@ -806,6 +806,17 @@ struct MovableCellHasher
static void rekey(Key& k, const Key& newKey) { k = newKey; }
};
template <typename T>
struct MovableCellHasher<PreBarriered<T>>
{
using Key = PreBarriered<T>;
using Lookup = T;
static HashNumber hash(const Lookup& l) { return MovableCellHasher<T>::hash(l); }
static bool match(const Key& k, const Lookup& l) { return MovableCellHasher<T>::match(k, l); }
static void rekey(Key& k, const Key& newKey) { k.unsafeSet(newKey); }
};
template <typename T>
struct MovableCellHasher<RelocatablePtr<T>>
{

View File

@ -18,9 +18,9 @@ using namespace js;
using namespace js::gc;
inline HashNumber
DefaultHasher<WatchKey>::hash(const Lookup& key)
WatchKeyHasher::hash(const Lookup& key)
{
return DefaultHasher<JSObject*>::hash(key.object.get()) ^ HashId(key.id.get());
return MovableCellHasher<PreBarrieredObject>::hash(key.object) ^ HashId(key.id);
}
namespace {

View File

@ -20,6 +20,9 @@ struct WatchKey {
WatchKey() {}
WatchKey(JSObject* obj, jsid id) : object(obj), id(id) {}
WatchKey(const WatchKey& key) : object(key.object.get()), id(key.id.get()) {}
// These are traced unconditionally during minor GC, so do not require
// post-barriers.
PreBarrieredObject object;
PreBarrieredId id;
@ -40,14 +43,14 @@ struct Watchpoint {
: handler(handler), closure(closure), held(held) {}
};
template <>
struct DefaultHasher<WatchKey>
struct WatchKeyHasher
{
typedef WatchKey Lookup;
static inline js::HashNumber hash(const Lookup& key);
static bool match(const WatchKey& k, const Lookup& l) {
return k.object == l.object && k.id.get() == l.id.get();
return MovableCellHasher<PreBarrieredObject>::match(k.object, l.object) &&
DefaultHasher<PreBarrieredId>::match(k.id, l.id);
}
static void rekey(WatchKey& k, const WatchKey& newKey) {
@ -58,7 +61,7 @@ struct DefaultHasher<WatchKey>
class WatchpointMap {
public:
typedef HashMap<WatchKey, Watchpoint, DefaultHasher<WatchKey>, SystemAllocPolicy> Map;
typedef HashMap<WatchKey, Watchpoint, WatchKeyHasher, SystemAllocPolicy> Map;
bool init();
bool watch(JSContext* cx, HandleObject obj, HandleId id,