Bug 624224 - cleanup compartment sweep code r=brendan
☠☠ backed out by 7c578c10675d ☠ ☠
authorGregor Wagner <anygregor@gmail.com>
Thu, 13 Jan 2011 16:58:27 -0800
changeset 60586 1548012fa682be8a7ca24a7567b79d579ccbeed3
parent 60585 bd65fcd20aaa24e5e7accabfd4fc728335fbcd93
child 60587 7c578c10675de909c1b86e5aabff4ae52121f98b
push id18037
push usercleary@mozilla.com
push dateFri, 14 Jan 2011 17:42:55 +0000
treeherdermozilla-central@4e0501a0c5e5 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbrendan
bugs624224
milestone2.0b10pre
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 624224 - cleanup compartment sweep code r=brendan
js/src/jsgc.cpp
--- a/js/src/jsgc.cpp
+++ b/js/src/jsgc.cpp
@@ -2157,66 +2157,59 @@ GCHelperThread::doSweep()
 #endif /* JS_THREADSAFE */
 
 static void
 SweepCrossCompartmentWrappers(JSContext *cx)
 {
     JSRuntime *rt = cx->runtime;
     /*
      * Figure out how much JIT code should be released from inactive compartments.
-     * If multiple eighth-lifes have passed, compound the release interval linearly;
+     * If multiple eighth-lives have passed, compound the release interval linearly;
      * if enough time has passed, all inactive JIT code will be released.
      */
     uint32 releaseInterval = 0;
     int64 now = PRMJ_Now();
     if (now >= rt->gcJitReleaseTime) {
         releaseInterval = 8;
         while (now >= rt->gcJitReleaseTime) {
             if (--releaseInterval == 1)
                 rt->gcJitReleaseTime = now;
             rt->gcJitReleaseTime += JIT_SCRIPT_EIGHTH_LIFETIME;
         }
     }
 
     /* Remove dead wrappers from the compartment map. */
-    for (JSCompartment **c = rt->compartments.begin(); c != rt->compartments.end(); ++c) {
+    for (JSCompartment **c = rt->compartments.begin(); c != rt->compartments.end(); ++c)
         (*c)->sweep(cx, releaseInterval);
-    }
-    
 }
 
 static void
 SweepCompartments(JSContext *cx, JSGCInvocationKind gckind)
 {
     JSRuntime *rt = cx->runtime;
     JSCompartmentCallback callback = rt->compartmentCallback;
     JSCompartment **read = rt->compartments.begin();
     JSCompartment **end = rt->compartments.end();
     JSCompartment **write = read;
 
-    /* Delete atomsCompartment only during runtime shutdown */
-    rt->atomsCompartment->marked = true;
-
     while (read < end) {
-        JSCompartment *compartment = (*read++);
-        if (compartment->marked) {
+        JSCompartment *compartment = *read++;
+        /* Unmarked compartments containing marked objects don't get deleted, except LAST_CONTEXT GC is performed. */
+        if ((!compartment->marked && compartment->arenaListsAreEmpty()) || gckind == GC_LAST_CONTEXT) {
+            JS_ASSERT(compartment->freeLists.isEmpty());
+            if (compartment == rt->atomsCompartment)
+                continue;
+            if (callback)
+                (void) callback(cx, compartment, JSCOMPARTMENT_DESTROY);
+            if (compartment->principals)
+                JSPRINCIPALS_DROP(cx, compartment->principals);
+            delete compartment;
+        } else {
             compartment->marked = false;
             *write++ = compartment;
-        } else {
-            JS_ASSERT(compartment->freeLists.isEmpty());
-            if (compartment->arenaListsAreEmpty() || gckind == GC_LAST_CONTEXT) {
-                if (callback)
-                    (void) callback(cx, compartment, JSCOMPARTMENT_DESTROY);
-                if (compartment->principals)
-                    JSPRINCIPALS_DROP(cx, compartment->principals);
-                delete compartment;
-            } else {
-                compartment->marked = false;
-                *write++ = compartment;
-            }
         }
     }
     rt->compartments.resize(write - rt->compartments.begin());
 }
 
 /*
  * Common cache invalidation and so forth that must be done before GC. Even if
  * GCUntilDone calls GC several times, this work needs to be done only once.
@@ -2349,17 +2342,16 @@ MarkAndSweepCompartment(JSContext *cx, J
 #endif
 
     /*
      * We finalize iterators before other objects so the iterator can use the
      * object which properties it enumerates over to finalize the enumeration
      * state. We finalize objects before other GC things to ensure that
      * object's finalizer can access them even if they will be freed.
      */
-
     comp->sweep(cx, 0);
 
     comp->finalizeObjectArenaLists(cx);
     TIMESTAMP(sweepObjectEnd);
 
     comp->finalizeStringArenaLists(cx);
     TIMESTAMP(sweepStringEnd);
 
@@ -2459,24 +2451,23 @@ MarkAndSweep(JSContext *cx, JSGCInvocati
     SweepCrossCompartmentWrappers(cx);
 
     /*
      * We finalize iterators before other objects so the iterator can use the
      * object which properties it enumerates over to finalize the enumeration
      * state. We finalize objects before other GC things to ensure that
      * object's finalizer can access them even if they will be freed.
      */
-
-    for (JSCompartment **comp = rt->compartments.begin(); comp != rt->compartments.end(); comp++)
-        (*comp)->finalizeObjectArenaLists(cx);
+    for (JSCompartment **c = rt->compartments.begin(); c != rt->compartments.end(); c++)
+        (*c)->finalizeObjectArenaLists(cx);
 
     TIMESTAMP(sweepObjectEnd);
 
-    for (JSCompartment **comp = rt->compartments.begin(); comp != rt->compartments.end(); comp++)
-        (*comp)->finalizeStringArenaLists(cx);
+    for (JSCompartment **c = rt->compartments.begin(); c != rt->compartments.end(); c++)
+        (*c)->finalizeStringArenaLists(cx);
 
     TIMESTAMP(sweepStringEnd);
 
     SweepCompartments(cx, gckind);
 
     /*
      * Sweep the runtime's property trees after finalizing objects, in case any
      * had watchpoints referencing tree nodes.