Bug 982561 - Add zone edges for unmarked weakmap keys with delegates in a different zone r=terrence

This commit is contained in:
Jon Coppeard
2014-05-16 09:44:43 +01:00
parent 693795a94c
commit 111c625233
8 changed files with 105 additions and 5 deletions

View File

@@ -20,6 +20,7 @@
#include "jsobjinlines.h"
using namespace js;
using namespace js::gc;
WeakMapBase::WeakMapBase(JSObject *memOf, JSCompartment *c)
: memberOf(memOf),
@@ -78,6 +79,16 @@ WeakMapBase::markCompartmentIteratively(JSCompartment *c, JSTracer *tracer)
return markedAny;
}
bool
WeakMapBase::findZoneEdgesForCompartment(JSCompartment *c)
{
for (WeakMapBase *m = c->gcWeakMapList; m; m = m->next) {
if (!m->findZoneEdges())
return false;
}
return true;
}
void
WeakMapBase::sweepCompartment(JSCompartment *c)
{
@@ -146,6 +157,34 @@ WeakMapBase::removeWeakMapFromList(WeakMapBase *weakmap)
}
}
bool
ObjectValueMap::findZoneEdges()
{
/*
* For unmarked weakmap keys with delegates in a different zone, add a zone
* edge to ensure that the delegate zone does finish marking after the key
* zone.
*/
Zone *mapZone = compartment->zone();
for (Range r = all(); !r.empty(); r.popFront()) {
JSObject *key = r.front().key();
if (key->isMarked(BLACK) && !key->isMarked(GRAY))
continue;
JSWeakmapKeyDelegateOp op = key->getClass()->ext.weakmapKeyDelegateOp;
if (!op)
continue;
JSObject *delegate = op(key);
if (!delegate)
continue;
Zone *delegateZone = delegate->zone();
if (delegateZone == mapZone)
continue;
if (!delegateZone->gcZoneGroupEdges.put(key->zone()))
return false;
}
return true;
}
static JSObject *
GetKeyArg(JSContext *cx, CallArgs &args)
{
@@ -319,7 +358,7 @@ WeakMapPostWriteBarrier(JSRuntime *rt, ObjectValueMap *weakMap, JSObject *key)
typedef HashMap<JSObject *, Value> UnbarrieredMap;
UnbarrieredMap *unbarrieredMap = reinterpret_cast<UnbarrieredMap *>(baseHashMap);
typedef gc::HashKeyRef<UnbarrieredMap, JSObject *> Ref;
typedef HashKeyRef<UnbarrieredMap, JSObject *> Ref;
if (key && IsInsideNursery(rt, key))
rt->gc.storeBuffer.putGeneric(Ref((unbarrieredMap), key));
#endif
@@ -406,7 +445,7 @@ JS_NondeterministicGetWeakMapKeys(JSContext *cx, HandleObject objArg, MutableHan
ObjectValueMap *map = obj->as<WeakMapObject>().getMap();
if (map) {
// Prevent GC from mutating the weakmap while iterating.
gc::AutoSuppressGC suppress(cx);
AutoSuppressGC suppress(cx);
for (ObjectValueMap::Base::Range r = map->all(); !r.empty(); r.popFront()) {
RootedObject key(cx, r.front().key());
if (!cx->compartment()->wrap(cx, &key))