Bug 986843 - Don't sweep empty zones if they contain marked compartments. r=terrence, a=sledru
authorJon Coppeard <jcoppeard@mozilla.com>
Mon, 07 Apr 2014 11:03:22 +0100
changeset 183666 ed9793adc2c7
parent 183665 c19e0e0a8535
child 183667 7be150811dd8
push id3440
push userryanvm@gmail.com
push date2014-04-08 16:22 +0000
Treeherderresults
reviewersterrence, sledru
bugs986843
milestone29.0
Bug 986843 - Don't sweep empty zones if they contain marked compartments. r=terrence, a=sledru
js/src/gc/Zone.cpp
js/src/gc/Zone.h
js/src/jsgc.cpp
--- a/js/src/gc/Zone.cpp
+++ b/js/src/gc/Zone.cpp
@@ -225,9 +225,17 @@ js::ZoneOfObject(const JSObject &obj)
 }
 
 JS::Zone *
 js::ZoneOfObjectFromAnyThread(const JSObject &obj)
 {
     return obj.zoneFromAnyThread();
 }
 
-
+bool
+Zone::hasMarkedCompartments()
+{
+    for (CompartmentsInZoneIter comp(this); !comp.done(); comp.next()) {
+        if (comp->marked)
+            return true;
+    }
+    return false;
+}
--- a/js/src/gc/Zone.h
+++ b/js/src/gc/Zone.h
@@ -307,16 +307,18 @@ struct Zone : public JS::shadow::Zone,
     void reportAllocationOverflow() {
         js_ReportAllocationOverflow(nullptr);
     }
 
     js::types::TypeZone types;
 
     void sweep(js::FreeOp *fop, bool releaseTypes);
 
+    bool hasMarkedCompartments();
+
   private:
     void sweepBreakpoints(js::FreeOp *fop);
 };
 
 } /* namespace JS */
 
 namespace js {
 
--- a/js/src/jsgc.cpp
+++ b/js/src/jsgc.cpp
@@ -2807,17 +2807,19 @@ SweepZones(FreeOp *fop, bool lastGC)
     Zone **write = read;
     JS_ASSERT(rt->zones.length() >= 1);
     JS_ASSERT(rt->isAtomsZone(rt->zones[0]));
 
     while (read < end) {
         Zone *zone = *read++;
 
         if (zone->wasGCStarted()) {
-            if (zone->allocator.arenas.arenaListsAreEmpty() || lastGC) {
+            if ((zone->allocator.arenas.arenaListsAreEmpty() && !zone->hasMarkedCompartments()) ||
+                lastGC)
+            {
                 zone->allocator.arenas.checkEmptyFreeLists();
                 if (callback)
                     callback(zone);
                 SweepCompartments(fop, zone, false, lastGC);
                 JS_ASSERT(zone->compartments.empty());
                 fop->delete_(zone);
                 continue;
             }