Backout bug 791174 for orange
authorBill McCloskey <wmccloskey@mozilla.com>
Mon, 15 Oct 2012 17:00:39 -0700
changeset 110485 a8a4f26cbb7855ed2b4707452a36131af5d4a890
parent 110484 74816ae5dd43249ee708b7f216b8c79b0a2f8c8d
child 110486 7b582c09463b12f1f47242e62a94dafb102bc78e
push id93
push usernmatsakis@mozilla.com
push dateWed, 31 Oct 2012 21:26:57 +0000
bugs791174
milestone19.0a1
Backout bug 791174 for orange
js/src/jsgc.cpp
--- a/js/src/jsgc.cpp
+++ b/js/src/jsgc.cpp
@@ -4069,42 +4069,39 @@ class AutoTraceSession {
     ~AutoTraceSession();
 
   protected:
     JSRuntime *runtime;
 
   private:
     AutoTraceSession(const AutoTraceSession&) MOZ_DELETE;
     void operator=(const AutoTraceSession&) MOZ_DELETE;
-
-    JSRuntime::HeapState prevState;
 };
 
 /* ...while this class is to be used only for garbage collection. */
 class AutoGCSession : AutoTraceSession {
   public:
     explicit AutoGCSession(JSRuntime *rt);
     ~AutoGCSession();
 };
 
 /* Start a new heap session. */
 AutoTraceSession::AutoTraceSession(JSRuntime *rt, JSRuntime::HeapState heapState)
-  : runtime(rt),
-    prevState(rt->heapState)
+  : runtime(rt)
 {
     JS_ASSERT(!rt->noGCOrAllocationCheck);
     JS_ASSERT(!rt->isHeapBusy());
     JS_ASSERT(heapState == JSRuntime::Collecting || heapState == JSRuntime::Tracing);
     rt->heapState = heapState;
 }
 
 AutoTraceSession::~AutoTraceSession()
 {
     JS_ASSERT(runtime->isHeapBusy());
-    runtime->heapState = prevState;
+    runtime->heapState = JSRuntime::Idle;
 }
 
 AutoGCSession::AutoGCSession(JSRuntime *rt)
   : AutoTraceSession(rt, JSRuntime::Collecting)
 {
     runtime->gcIsNeeded = false;
     runtime->gcInterFrameGC = true;
 
@@ -4725,46 +4722,44 @@ ShrinkGCBuffers(JSRuntime *rt)
     JS_ASSERT(!rt->isHeapBusy());
 #ifndef JS_THREADSAFE
     ExpireChunksAndArenas(rt, true);
 #else
     rt->gcHelperThread.startBackgroundShrink();
 #endif
 }
 
-struct AutoFinishGC
-{
-    AutoFinishGC(JSRuntime *rt) {
-        if (rt->gcIncrementalState != NO_INCREMENTAL)
-            FinishIncrementalGC(rt, gcreason::API);
-
-        rt->gcHelperThread.waitBackgroundSweepEnd();
-    }
-};
-
-struct AutoPrepareForTracing
-{
-    AutoFinishGC finish;
-    AutoTraceSession session;
-    AutoCopyFreeListToArenas copy;
-
-    AutoPrepareForTracing(JSRuntime *rt)
-      : finish(rt),
-        session(rt),
-        copy(rt)
-    {}
-};
-
 void
 TraceRuntime(JSTracer *trc)
 {
     JS_ASSERT(!IS_GC_MARKING_TRACER(trc));
 
-    AutoPrepareForTracing prep(trc->runtime);
+#ifdef JS_THREADSAFE
+    {
+        JSRuntime *rt = trc->runtime;
+        if (!rt->isHeapBusy()) {
+            AutoTraceSession session(rt);
+
+            rt->gcHelperThread.waitBackgroundSweepEnd();
+
+            AutoCopyFreeListToArenas copy(rt);
+            RecordNativeStackTopForGC(rt);
+            MarkRuntime(trc);
+            return;
+        }
+    }
+#else
+    AutoCopyFreeListToArenas copy(trc->runtime);
     RecordNativeStackTopForGC(trc->runtime);
+#endif
+
+    /*
+     * Calls from inside a normal GC or a recursive calls are OK and do not
+     * require session setup.
+     */
     MarkRuntime(trc);
 }
 
 struct IterateArenaCallbackOp
 {
     JSRuntime *rt;
     void *data;
     IterateArenaCallback callback;
@@ -4792,45 +4787,59 @@ struct IterateCellCallbackOp
 };
 
 void
 IterateCompartmentsArenasCells(JSRuntime *rt, void *data,
                                JSIterateCompartmentCallback compartmentCallback,
                                IterateArenaCallback arenaCallback,
                                IterateCellCallback cellCallback)
 {
-    AutoPrepareForTracing prop(rt);
-
+    JS_ASSERT(!rt->isHeapBusy());
+
+    AutoTraceSession session(rt);
+    rt->gcHelperThread.waitBackgroundSweepEnd();
+
+    AutoCopyFreeListToArenas copy(rt);
     for (CompartmentsIter c(rt); !c.done(); c.next()) {
         (*compartmentCallback)(rt, data, c);
 
         for (size_t thingKind = 0; thingKind != FINALIZE_LIMIT; thingKind++) {
             JSGCTraceKind traceKind = MapAllocToTraceKind(AllocKind(thingKind));
             size_t thingSize = Arena::thingSize(AllocKind(thingKind));
             IterateArenaCallbackOp arenaOp(rt, data, arenaCallback, traceKind, thingSize);
             IterateCellCallbackOp cellOp(rt, data, cellCallback, traceKind, thingSize);
             ForEachArenaAndCell(c, AllocKind(thingKind), arenaOp, cellOp);
         }
     }
 }
 
 void
 IterateChunks(JSRuntime *rt, void *data, IterateChunkCallback chunkCallback)
 {
-    AutoPrepareForTracing prep(rt);
+    /* :XXX: Any way to common this preamble with IterateCompartmentsArenasCells? */
+    JS_ASSERT(!rt->isHeapBusy());
+
+    AutoTraceSession session(rt);
+    rt->gcHelperThread.waitBackgroundSweepEnd();
 
     for (js::GCChunkSet::Range r = rt->gcChunkSet.all(); !r.empty(); r.popFront())
         chunkCallback(rt, data, r.front());
 }
 
 void
 IterateCells(JSRuntime *rt, JSCompartment *compartment, AllocKind thingKind,
              void *data, IterateCellCallback cellCallback)
 {
-    AutoPrepareForTracing prep(rt);
+    /* :XXX: Any way to common this preamble with IterateCompartmentsArenasCells? */
+    JS_ASSERT(!rt->isHeapBusy());
+
+    AutoTraceSession session(rt);
+    rt->gcHelperThread.waitBackgroundSweepEnd();
+
+    AutoCopyFreeListToArenas copy(rt);
 
     JSGCTraceKind traceKind = MapAllocToTraceKind(thingKind);
     size_t thingSize = Arena::thingSize(thingKind);
 
     if (compartment) {
         for (CellIterUnderGC i(compartment, thingKind); !i.done(); i.next())
             cellCallback(rt, data, i.getCell(), traceKind, thingSize);
     } else {
@@ -4840,17 +4849,23 @@ IterateCells(JSRuntime *rt, JSCompartmen
         }
     }
 }
 
 void
 IterateGrayObjects(JSCompartment *compartment, GCThingCallback *cellCallback, void *data)
 {
     JS_ASSERT(compartment);
-    AutoPrepareForTracing prep(compartment->rt);
+    JSRuntime *rt = compartment->rt;
+    JS_ASSERT(!rt->isHeapBusy());
+
+    AutoTraceSession session(rt);
+    rt->gcHelperThread.waitBackgroundSweepEnd();
+
+    AutoCopyFreeListToArenas copy(rt);
 
     for (size_t finalizeKind = 0; finalizeKind <= FINALIZE_OBJECT_LAST; finalizeKind++) {
         for (CellIterUnderGC i(compartment, AllocKind(finalizeKind)); !i.done(); i.next()) {
             Cell *cell = i.getCell();
             if (cell->isMarked(GRAY))
                 cellCallback(data, cell);
         }
     }