Bug 1244412 - Make ZoneCellIter work correctly whether called under GC or not r=terrence a=ritu
authorJon Coppeard <jcoppeard@mozilla.com>
Thu, 17 Mar 2016 10:05:55 +0000
changeset 326133 c3a62b8c2eebbd63f1c1be226bd6f4290626d4f4
parent 326132 4024148c74ff6b43af69a61bcda99dab06a296d6
child 326134 70eb1923fa000c2d73e9be012953e92187241a2e
push id1128
push userjlund@mozilla.com
push dateWed, 01 Jun 2016 01:31:59 +0000
treeherdermozilla-release@fe0d30de989d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersterrence, ritu
bugs1244412
milestone47.0
Bug 1244412 - Make ZoneCellIter work correctly whether called under GC or not r=terrence a=ritu
js/src/gc/Zone.cpp
js/src/jsgcinlines.h
js/src/vm/TypeInference.cpp
--- a/js/src/gc/Zone.cpp
+++ b/js/src/gc/Zone.cpp
@@ -195,29 +195,29 @@ Zone::discardJitCode(FreeOp* fop)
         return;
 
     if (isPreservingCode()) {
         PurgeJITCaches(this);
     } else {
 
 #ifdef DEBUG
         /* Assert no baseline scripts are marked as active. */
-        for (ZoneCellIterUnderGC i(this, AllocKind::SCRIPT); !i.done(); i.next()) {
+        for (ZoneCellIter i(this, AllocKind::SCRIPT); !i.done(); i.next()) {
             JSScript* script = i.get<JSScript>();
             MOZ_ASSERT_IF(script->hasBaselineScript(), !script->baselineScript()->active());
         }
 #endif
 
         /* Mark baseline scripts on the stack as active. */
         jit::MarkActiveBaselineScripts(this);
 
         /* Only mark OSI points if code is being discarded. */
         jit::InvalidateAll(fop, this);
 
-        for (ZoneCellIterUnderGC i(this, AllocKind::SCRIPT); !i.done(); i.next()) {
+        for (ZoneCellIter i(this, AllocKind::SCRIPT); !i.done(); i.next()) {
             JSScript* script = i.get<JSScript>();
             jit::FinishInvalidation(fop, script);
 
             /*
              * Discard baseline script if it's not marked as active. Note that
              * this also resets the active flag.
              */
             jit::FinishDiscardBaselineScript(fop, script);
--- a/js/src/jsgcinlines.h
+++ b/js/src/jsgcinlines.h
@@ -245,34 +245,38 @@ class ZoneCellIterUnderGC : public ZoneC
 class ZoneCellIter : public ZoneCellIterImpl
 {
     JS::AutoAssertNoAlloc noAlloc;
 
   public:
     ZoneCellIter(JS::Zone* zone, AllocKind kind) {
         JSRuntime* rt = zone->runtimeFromMainThread();
 
-        /*
-         * We have a single-threaded runtime, so there's no need to protect
-         * against other threads iterating or allocating. However, we do have
-         * background finalization; we have to wait for this to finish if it's
-         * currently active.
-         */
-        if (IsBackgroundFinalized(kind) &&
-            zone->arenas.needBackgroundFinalizeWait(kind))
-        {
-            rt->gc.waitBackgroundSweepEnd();
+        if (zone->runtimeFromAnyThread()->isHeapBusy()) {
+            MOZ_ASSERT(zone->runtimeFromAnyThread()->gc.nursery.isEmpty());
+        } else {
+            /*
+             * We have a single-threaded runtime, so there's no need to protect
+             * against other threads iterating or allocating. However, we do have
+             * background finalization; we have to wait for this to finish if it's
+             * currently active.
+             */
+            if (IsBackgroundFinalized(kind) &&
+                zone->arenas.needBackgroundFinalizeWait(kind))
+            {
+                rt->gc.waitBackgroundSweepEnd();
+            }
+
+            /* Evict the nursery before iterating so we can see all things. */
+            rt->gc.evictNursery();
+
+            /* Assert that no GCs can occur while a ZoneCellIter is live. */
+            noAlloc.disallowAlloc(rt);
         }
 
-        /* Evict the nursery before iterating so we can see all things. */
-        rt->gc.evictNursery();
-
-        /* Assert that no GCs can occur while a ZoneCellIter is live. */
-        noAlloc.disallowAlloc(rt);
-
         init(zone, kind);
     }
 };
 
 class GCZonesIter
 {
   private:
     ZonesIter zone;
--- a/js/src/vm/TypeInference.cpp
+++ b/js/src/vm/TypeInference.cpp
@@ -4426,17 +4426,17 @@ TypeZone::endSweep(JSRuntime* rt)
     sweepReleaseTypes = false;
 
     rt->gc.freeAllLifoBlocksAfterSweeping(&sweepTypeLifoAlloc);
 }
 
 void
 TypeZone::clearAllNewScriptsOnOOM()
 {
-    for (gc::ZoneCellIterUnderGC iter(zone(), gc::AllocKind::OBJECT_GROUP);
+    for (gc::ZoneCellIter iter(zone(), gc::AllocKind::OBJECT_GROUP);
          !iter.done(); iter.next())
     {
         ObjectGroup* group = iter.get<ObjectGroup>();
         if (!IsAboutToBeFinalizedUnbarriered(&group))
             group->maybeClearNewScriptOnOOM();
     }
 }