Bug 690970, part 2: unmark gray read barrier for watchpoints. r=billm a=lsblakk
--- a/js/src/jswatchpoint.cpp
+++ b/js/src/jswatchpoint.cpp
@@ -88,18 +88,22 @@ WatchpointMap::watch(JSContext *cx, Hand
void
WatchpointMap::unwatch(JSObject *obj, jsid id,
JSWatchPointHandler *handlerp, JSObject **closurep)
{
if (Map::Ptr p = map.lookup(WatchKey(obj, id))) {
if (handlerp)
*handlerp = p->value.handler;
- if (closurep)
+ if (closurep) {
+ // Read barrier to prevent an incorrectly gray closure from escaping the
+ // watchpoint. See the comment before UnmarkGrayChildren in gc/Marking.cpp
+ ExposeGCThingToActiveJS(p->value.closure, JSTRACE_OBJECT);
*closurep = p->value.closure;
+ }
map.remove(p);
}
}
void
WatchpointMap::unwatchObject(JSObject *obj)
{
for (Map::Enum e(map); !e.empty(); e.popFront()) {
@@ -133,16 +137,20 @@ WatchpointMap::triggerWatchpoint(JSConte
old.setUndefined();
if (obj->isNative()) {
if (UnrootedShape shape = obj->nativeLookup(cx, id)) {
if (shape->hasSlot())
old = obj->nativeGetSlot(shape->slot());
}
}
+ // Read barrier to prevent an incorrectly gray closure from escaping the
+ // watchpoint. See the comment before UnmarkGrayChildren in gc/Marking.cpp
+ ExposeGCThingToActiveJS(closure, JSTRACE_OBJECT);
+
/* Call the handler. */
return handler(cx, obj, id, old, vp.address(), closure);
}
bool
WatchpointMap::markCompartmentIteratively(JSCompartment *c, JSTracer *trc)
{
if (!c->watchpointMap)