Bug 684595 - Don't visit WeakMap keys from the WeakMap in markentry. r=jorendorff
authorAndrew McCreight <amccreight@mozilla.com>
Sun, 04 Sep 2011 10:16:23 -0700
changeset 77991 1c432b6fdbdbd691186f8107946072febc8db012
parent 77990 7946546d5a6c0db4a878466344e3d822d0608e90
child 77992 e7525561c3092f3d35ff2e6b4a93b42d1ef8167e
push id78
push userclegnitto@mozilla.com
push dateFri, 16 Dec 2011 17:32:24 +0000
treeherdermozilla-release@79d24e644fdd [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjorendorff
bugs684595
milestone9.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 684595 - Don't visit WeakMap keys from the WeakMap in markentry. r=jorendorff
js/src/jsweakmap.h
--- a/js/src/jsweakmap.h
+++ b/js/src/jsweakmap.h
@@ -94,17 +94,17 @@ namespace js {
 //        became marked.
 //
 //        To ensure that the WeakMap's behavior isn't visibly affected by
 //        garbage collection, this should leave k unmarked only when no key
 //        matching k could ever be produced after this GC cycle completes ---
 //        removing entries whose keys this function leaves unmarked should never
 //        make future lookups fail.
 //
-//        A typical definition of markIteratively would be:
+//        A typical definition of markEntryIfLive would be:
 //
 //          if (keyMarked(k) && !valueMarked(v)) {
 //              markObject(*v, "WeakMap entry value");
 //              return true;
 //          }
 //          return false;
 //
 //        This meets the above constraint when, for example, Key is JSObject *:
@@ -112,21 +112,22 @@ namespace js {
 //        and thus can't be supplied as a key.
 //
 //        Note that this may mark entries where keyMarked(k) is not initially
 //        true. For example, you could have a table whose keys match when the
 //        values of one of their properties are equal: k1.x === k2.x. An entry
 //        in such a table could be live even when its key is not marked. The
 //        markEntryIfLive function for such a table would generally mark both k and v.
 //
-//     void markEntry(Key &k, Value &v)
-//        Mark the table entry's key and value, k and v, as reachable by the
-//        collector. WeakMap uses this function for non-marking tracers: other
-//        code using the GC heap tracing functions to map the heap for some
-//        purpose or other.
+//     void markEntry(Value &v)
+//        Mark the table entry's value v as reachable by the collector. WeakMap
+//        uses this function for non-marking tracers: other code using the GC
+//        heap tracing functions to map the heap for some purpose or other.
+//        This provides a conservative approximation of the true reachability
+//        relation of the heap graph.
 //
 //   If omitted, the MarkPolicy parameter defaults to js::DefaultMarkPolicy<Key,
 //   Value>, a policy template with the obvious definitions for some typical
 //   SpiderMonkey type combinations.
 
 // A policy template holding default marking algorithms for common type combinations. This
 // provides default types for WeakMap's MarkPolicy template parameter.
 template <class Key, class Value> class DefaultMarkPolicy;
@@ -192,17 +193,17 @@ class WeakMap : public HashMap<Key, Valu
   public:
     explicit WeakMap(JSRuntime *rt) : Base(rt) { }
     explicit WeakMap(JSContext *cx) : Base(cx) { }
 
   private:
     void nonMarkingTrace(JSTracer *tracer) {
         MarkPolicy t(tracer);
         for (Range r = Base::all(); !r.empty(); r.popFront())
-            t.markEntry(r.front().key, r.front().value);
+            t.markEntry(r.front().value);
     }
 
     bool markIteratively(JSTracer *tracer) {
         MarkPolicy t(tracer);
         bool markedAny = false;
         for (Range r = Base::all(); !r.empty(); r.popFront()) {
             /* If the entry is live, ensure its key and value are marked. */
             if (t.markEntryIfLive(r.front().key, r.front().value)) {
@@ -276,18 +277,17 @@ class DefaultMarkPolicy<JSObject *, Valu
         if (keyMarked(k))
             return markUnmarkedValue(v);
         if (!overrideKeyMarking(k))
             return false;
         js::gc::MarkObject(tracer, *k, "WeakMap entry wrapper key");
         markUnmarkedValue(v);
         return true;
     }
-    void markEntry(JSObject *k, const Value &v) {
-        js::gc::MarkObject(tracer, *k, "WeakMap entry key");
+    void markEntry(const Value &v) {
         js::gc::MarkValue(tracer, v, "WeakMap entry value");
     }
 };
 
 template <>
 class DefaultMarkPolicy<JSObject *, JSObject *> {
   protected:
     JSTracer *tracer;
@@ -297,18 +297,17 @@ class DefaultMarkPolicy<JSObject *, JSOb
     bool valueMarked(JSObject *v) { return !IsAboutToBeFinalized(tracer->context, v); }
     bool markEntryIfLive(JSObject *k, JSObject *v) {
         if (keyMarked(k) && !valueMarked(v)) {
             js::gc::MarkObject(tracer, *v, "WeakMap entry value");
             return true;
         }
         return false;
     }
-    void markEntry(JSObject *k, JSObject *v) {
-        js::gc::MarkObject(tracer, *k, "WeakMap entry key");
+    void markEntry(JSObject *v) {
         js::gc::MarkObject(tracer, *v, "WeakMap entry value");
     }
 };
 
 // A MarkPolicy for WeakMaps whose keys and values may be objects in arbitrary
 // compartments within a runtime.
 //
 // With the current GC, the implementation turns out to be identical to the