Bug 821340 - Fix non-GC marking of weakmaps (r=mccr8)
authorBill McCloskey <wmccloskey@mozilla.com>
Tue, 18 Dec 2012 11:52:37 -0800
changeset 125525 95566cb18e2e13f0ed5a4a7dfd6270c273f0da91
parent 125524 4b7e8f82a341878531c1ca12195bf2ac2f9960de
child 125526 3ec0a08450d8df0bee40bba7ed7b1301156696fc
push id2151
push userlsblakk@mozilla.com
push dateTue, 19 Feb 2013 18:06:57 +0000
treeherdermozilla-beta@4952e88741ec [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmccr8
bugs821340
milestone20.0a1
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 821340 - Fix non-GC marking of weakmaps (r=mccr8)
js/src/gc/Marking.cpp
js/src/jsweakmap.h
--- a/js/src/gc/Marking.cpp
+++ b/js/src/gc/Marking.cpp
@@ -1497,23 +1497,37 @@ js::CallTracer(JSTracer *trc, void *thin
 }
 
 static void
 UnmarkGrayGCThing(void *thing)
 {
     static_cast<js::gc::Cell *>(thing)->unmark(js::gc::GRAY);
 }
 
+static void
+UnmarkGrayChildren(JSTracer *trc, void **thingp, JSGCTraceKind kind);
+
 struct UnmarkGrayTracer : public JSTracer
 {
-    UnmarkGrayTracer() : tracingShape(false), previousShape(NULL) {}
+    /*
+     * We set eagerlyTraceWeakMaps to false because the cycle collector will fix
+     * up any color mismatches involving weakmaps when it runs.
+     */
+    UnmarkGrayTracer(JSRuntime *rt)
+      : tracingShape(false), previousShape(NULL)
+    {
+        JS_TracerInit(this, rt, UnmarkGrayChildren);
+        eagerlyTraceWeakMaps = false;
+    }
+
     UnmarkGrayTracer(JSTracer *trc, bool tracingShape)
-        : tracingShape(tracingShape), previousShape(NULL)
+      : tracingShape(tracingShape), previousShape(NULL)
     {
-        JS_TracerInit(this, trc->runtime, trc->callback);
+        JS_TracerInit(this, trc->runtime, UnmarkGrayChildren);
+        eagerlyTraceWeakMaps = false;
     }
 
     /* True iff we are tracing the immediate children of a shape. */
     bool tracingShape;
 
     /* If tracingShape, shape child or NULL. Otherwise, NULL. */
     void *previousShape;
 };
@@ -1588,12 +1602,11 @@ js::UnmarkGrayGCThingRecursively(void *t
     JS_ASSERT(kind != JSTRACE_SHAPE);
 
     if (!GCThingIsMarkedGray(thing))
         return;
 
     UnmarkGrayGCThing(thing);
 
     JSRuntime *rt = static_cast<Cell *>(thing)->compartment()->rt;
-    UnmarkGrayTracer trc;
-    JS_TracerInit(&trc, rt, UnmarkGrayChildren);
+    UnmarkGrayTracer trc(rt);
     JS_TraceChildren(&trc, thing, kind);
 }
--- a/js/src/jsweakmap.h
+++ b/js/src/jsweakmap.h
@@ -138,17 +138,17 @@ class WeakMap : public HashMap<Key, Valu
             return false;
         gc::Mark(trc, x, "WeakMap entry");
         JS_ASSERT(gc::IsMarked(x));
         return true;
     }
 
     void nonMarkingTrace(JSTracer *trc) {
         for (Range r = Base::all(); !r.empty(); r.popFront())
-            markValue(trc, &r.front().value);
+            gc::Mark(trc, &r.front().value, "WeakMap entry");
     }
 
     bool keyNeedsMark(JSObject *key) {
         if (JSWeakmapKeyDelegateOp op = key->getClass()->ext.weakmapKeyDelegateOp) {
             JSObject *delegate = op(key);
             /*
              * Check if the delegate is marked with any color to properly handle
              * gray marking when the key's delegate is black and the map is