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 192623 70aebd1f91b2e31f5288db3fb8b95cc6bcb7ed3c
parent 192622 874c602f70fae74ad4e428a464967e7bc4dc1052
child 192624 2dfaa9c55efdb46c3848f506de1625f6d9b5caf6
push id474
push userasasaki@mozilla.com
push dateMon, 02 Jun 2014 21:01:02 +0000
treeherdermozilla-release@967f4cf1b31c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersterrence, sledru
bugs986843
milestone30.0a2
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
@@ -248,9 +248,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
@@ -313,16 +313,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);
 
 #ifdef JS_ION
     js::jit::JitZone *jitZone_;
     js::jit::JitZone *createJitZone(JSContext *cx);
 
   public:
--- a/js/src/jsgc.cpp
+++ b/js/src/jsgc.cpp
@@ -2812,17 +2812,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;
             }