Bug 1330687 - Fix computation of zone edges for weakmap key delgates. r=sfink, a=jcristau
authorJon Coppeard <jcoppeard@mozilla.com>
Tue, 07 Feb 2017 17:37:45 +0000
changeset 378346 c8eeb0d150df26360bb162db3da74ed686c8bca5
parent 378345 04dcfae8a1655e38d82225da507d17f27bfeef51
child 378347 2e0af7243d08369ef93638aa306f6cc2056c28b9
push id1419
push userjlund@mozilla.com
push dateMon, 10 Apr 2017 20:44:07 +0000
treeherdermozilla-release@5e6801b73ef6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssfink, jcristau
bugs1330687
milestone53.0a2
Bug 1330687 - Fix computation of zone edges for weakmap key delgates. r=sfink, a=jcristau
js/src/jsgc.cpp
js/src/jsweakmap.cpp
js/src/jsweakmap.h
--- a/js/src/jsgc.cpp
+++ b/js/src/jsgc.cpp
@@ -4458,16 +4458,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;
 }
 
@@ -4482,22 +4487,26 @@ GCRuntime::findZoneGroups(AutoLockForExc
     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
@@ -140,17 +140,17 @@ ObjectValueMap::findZoneEdges()
     for (Range r = all(); !r.empty(); r.popFront()) {
         JSObject* key = r.front().key();
         if (key->asTenured().isMarked(BLACK) && !key->asTenured().isMarked(GRAY))
             continue;
         JSObject* delegate = getDelegate(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
@@ -273,17 +273,25 @@ class WeakMap : public HashMap<Key, Valu
             }
         }
 
         return markedAny;
     }
 
     JSObject* getDelegate(JSObject* key) const {
         JSWeakmapKeyDelegateOp op = key->getClass()->extWeakmapKeyDelegateOp();
-        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(JSScript* script) const {
         return nullptr;
     }
 
   private:
     void exposeGCThingToActiveJS(const JS::Value& v) const { JS::ExposeValueToActiveJS(v); }