Bug 1338383 - Clear gcZoneGroupEdges set when finding zone groups fails due to over-recursion. r=sfink, a=jcristau
authorJon Coppeard <jcoppeard@mozilla.com>
Tue, 14 Feb 2017 10:18:32 +0000
changeset 378522 7597080fcccbebbd7d1e01e8353bec0893723fc1
parent 378521 34611d3b1fb6b6a6ff620c90c808020b8da7803d
child 378523 9e1cfea4cefbceaa9bfddebfecd25ddca520aaa2
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
bugs1338383
milestone53.0a2
Bug 1338383 - Clear gcZoneGroupEdges set when finding zone groups fails due to over-recursion. r=sfink, a=jcristau
js/src/jit-test/tests/gc/bug-1338383.js
js/src/jsgc.cpp
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/gc/bug-1338383.js
@@ -0,0 +1,16 @@
+// |jit-test| error: InternalError
+
+if (helperThreadCount() === 0)
+    throw InternalError();
+
+var lfOffThreadGlobal = newGlobal();
+enableShellAllocationMetadataBuilder()
+lfOffThreadGlobal.offThreadCompileScript(`
+  if ("gczeal" in this)
+    gczeal(8, 1)
+  function recurse(x) {
+    recurse(x + 1);
+  };
+  recurse(0);
+`);
+lfOffThreadGlobal.runOffThreadScript();
--- a/js/src/jsgc.cpp
+++ b/js/src/jsgc.cpp
@@ -4440,17 +4440,16 @@ Zone::findOutgoingEdges(ZoneComponentFin
 
     for (CompartmentsInZoneIter comp(this); !comp.done(); comp.next())
         comp->findOutgoingEdges(finder);
 
     for (ZoneSet::Range r = gcZoneGroupEdges.all(); !r.empty(); r.popFront()) {
         if (r.front()->isGCMarking())
             finder.addEdgeTo(r.front());
     }
-    gcZoneGroupEdges.clear();
 
     Debugger::findZoneEdges(this, finder);
 }
 
 bool
 GCRuntime::findZoneEdgesForWeakMaps()
 {
     /*
@@ -4458,45 +4457,48 @@ 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;
 }
 
 void
 GCRuntime::findZoneGroups(AutoLockForExclusiveAccess& lock)
 {
+#ifdef DEBUG
+    for (ZonesIter zone(rt, WithAtoms); !zone.done(); zone.next())
+        MOZ_ASSERT(zone->gcZoneGroupEdges.empty());
+#endif
+
     JSContext* cx = rt->contextFromMainThread();
     ZoneComponentFinder finder(cx->nativeStackLimit[StackForSystemCode], lock);
     if (!isIncremental || !findZoneEdgesForWeakMaps())
         finder.useOneComponent();
 
     for (GCZonesIter zone(rt); !zone.done(); zone.next()) {
         MOZ_ASSERT(zone->isGCMarking());
         finder.addNode(zone);
     }
     zoneGroups = finder.getResultsList();
     currentZoneGroup = zoneGroups;
     zoneGroupIndex = 0;
 
+    for (GCZonesIter zone(rt); !zone.done(); zone.next())
+        zone->gcZoneGroupEdges.clear();
+
 #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())