Bug 1330687 - Fix computation of zone edges for weakmap key delegates. r=sfink, a=gchang
authorJon Coppeard <jcoppeard@mozilla.com>
Tue, 07 Feb 2017 17:37:45 +0000
changeset 487450 fe4a2cda54adf386f7e29807d400806185d8b6e0
parent 487449 347c10e4d6d189d9d26e6e8c8fa3e360e6928d53
child 487451 41ae8441d8d632696daa974f2b64487cadb929d5
push id46228
push userpaul@paul.cx
push dateTue, 21 Feb 2017 16:19:44 +0000
reviewerssfink, gchang
bugs1330687
milestone45.7.1
Bug 1330687 - Fix computation of zone edges for weakmap key delegates. r=sfink, a=gchang
js/src/jsgc.cpp
js/src/jsweakmap.cpp
js/src/jsweakmap.h
--- a/js/src/jsgc.cpp
+++ b/js/src/jsgc.cpp
@@ -4604,16 +4604,21 @@ GCRuntime::findZoneEdgesForWeakMaps()
      * need for zone edges from the delegate's zone to the weakmap zone.
      *
      * Since the edges point into and not away from the zone the weakmap is in
      * we must find these edges in advance and store them in a set on the Zone.
      * If we run out of memory, we fall back to sweeping everything in one
      * group.
      */
 
+#ifdef DEBUG
+    for (ZonesIter zone(rt, WithAtoms); !zone.done(); zone.next())
+        MOZ_ASSERT(zone->gcZoneGroupEdges.empty());
+#endif
+
     for (GCZonesIter zone(rt); !zone.done(); zone.next()) {
         if (!WeakMapBase::findInterZoneEdges(zone))
             return false;
     }
 
     return true;
 }
 
@@ -4627,22 +4632,26 @@ GCRuntime::findZoneGroups()
     for (GCZonesIter zone(rt); !zone.done(); zone.next()) {
         MOZ_ASSERT(zone->isGCMarking());
         finder.addNode(zone);
     }
     zoneGroups = finder.getResultsList();
     currentZoneGroup = zoneGroups;
     zoneGroupIndex = 0;
 
+#ifdef DEBUG
     for (Zone* head = currentZoneGroup; head; head = head->nextGroup()) {
         for (Zone* zone = head; zone; zone = zone->nextNodeInGroup())
             MOZ_ASSERT(zone->isGCMarking());
     }
 
     MOZ_ASSERT_IF(!isIncremental, !currentZoneGroup->nextGroup());
+    for (ZonesIter zone(rt, WithAtoms); !zone.done(); zone.next())
+        MOZ_ASSERT(zone->gcZoneGroupEdges.empty());
+#endif
 }
 
 static void
 ResetGrayList(JSCompartment* comp);
 
 void
 GCRuntime::getNextZoneGroup()
 {
--- a/js/src/jsweakmap.cpp
+++ b/js/src/jsweakmap.cpp
@@ -145,17 +145,17 @@ ObjectValueMap::findZoneEdges()
             continue;
         JSWeakmapKeyDelegateOp op = key->getClass()->ext.weakmapKeyDelegateOp;
         if (!op)
             continue;
         JSObject* delegate = op(key);
         if (!delegate)
             continue;
         Zone* delegateZone = delegate->zone();
-        if (delegateZone == zone)
+        if (delegateZone == zone || !delegateZone->isGCMarking())
             continue;
         if (!delegateZone->gcZoneGroupEdges.put(key->zone()))
             return false;
     }
     return true;
 }
 
 ObjectWeakMap::ObjectWeakMap(JSContext* cx)
--- a/js/src/jsweakmap.h
+++ b/js/src/jsweakmap.h
@@ -278,17 +278,25 @@ class WeakMap : public HashMap<Key, Valu
     }
 
   private:
     void exposeGCThingToActiveJS(const JS::Value& v) const { JS::ExposeValueToActiveJS(v); }
     void exposeGCThingToActiveJS(JSObject* obj) const { JS::ExposeObjectToActiveJS(obj); }
 
     JSObject* getDelegate(JSObject* key) const {
         JSWeakmapKeyDelegateOp op = key->getClass()->ext.weakmapKeyDelegateOp;
-        return op ? op(key) : nullptr;
+        if (!op)
+            return nullptr;
+
+        JSObject* obj = op(key);
+        if (!obj)
+            return nullptr;
+
+        MOZ_ASSERT(obj->runtimeFromMainThread() == zone->runtimeFromMainThread());
+        return obj;
     }
 
     JSObject* getDelegate(gc::Cell* cell) const {
         return nullptr;
     }
 
     bool keyNeedsMark(JSObject* key) const {
         JSObject* delegate = getDelegate(key);