--- jsweakmap.h
+++ jsweakmap.h
@@ -78,17 +78,17 @@ class WeakMapBase {
 
     // Restore information about which weak maps are marked for many compartments.
     static void restoreCompartmentMarkedWeakMaps(WeakMapSet& markedWeakMaps);
 
     // Remove a weakmap from its compartment's weakmaps list.
     static void removeWeakMapFromList(WeakMapBase* weakmap);
 
     // Object keys must participate in ephemeron marking by overriding this method.
-    virtual void maybeMarkEntry(JSTracer* trc, gc::Cell* l) = 0;
+    virtual void maybeMarkEntry(JSTracer* trc, gc::Cell* markedCell, JS::GCCellPtr l) = 0;
 
   protected:
     // Instance member functions called by the above. Instantiations of WeakMap override
     // these with definitions appropriate for their Key and Value types.
     virtual void nonMarkingTraceKeys(JSTracer* tracer) = 0;
     virtual void nonMarkingTraceValues(JSTracer* tracer) = 0;
     virtual bool markIteratively(JSTracer* tracer) = 0;
     virtual void markEphemeronEntries(JSTracer* trc) = 0;
@@ -160,65 +160,76 @@ class WeakMap : public HashMap<Key, Valu
         return p;
     }
 
     // The WeakMap and some part of the key are marked. Mark the value if the
     // key is "fully marked" according to the exact semantics of this WeakMap.
     // (For a standard WeakMap, the key is either marked or not, so just mark
     // the value here. But a subclass might have multipart keys with more
     // complicated semantics.)
-    virtual void maybeMarkEntry(JSTracer* trc, gc::Cell* l)
+    virtual void maybeMarkEntry(JSTracer* trc, gc::Cell* markedCell, JS::GCCellPtr origKey)
     {
         MOZ_ASSERT(marked);
 
+        gc::Cell* l = origKey.asCell();
         Ptr p = Base::lookup(reinterpret_cast<const Lookup&>(l));
         Key key(p->key());
-        if (gc::IsMarked(&key))
+        if (gc::IsMarked(&key)) {
             TraceEdge(trc, &p->value(), "ephemeron value");
+        } else if (keyNeedsMark(key)) {
+            TraceEdge(trc, &p->value(), "WeakMap ephemeron value");
+            TraceEdge(trc, &key, "proxy-preserved WeakMap ephemeron key");
+            MOZ_ASSERT(key == p->key()); // No moving
+        }
         key.unsafeSet(nullptr);
     }
 
   protected:
+    static void addWeakEntry(JSTracer* trc, JS::GCCellPtr key, gc::WeakMarkable markable)
+    {
+        GCMarker& marker = *static_cast<GCMarker*>(trc);
+
+        auto p = marker.weakKeys.get(key);
+        if (p) {
+            gc::WeakEntryVector& weakEntries = p->value;
+            if (!weakEntries.append(Move(markable)))
+                marker.abortLinearWeakMarking();
+        } else {
+            gc::WeakEntryVector weakEntries;
+            JS_ALWAYS_TRUE(weakEntries.append(Move(markable)));
+            if (!marker.weakKeys.put(JS::GCCellPtr(key), Move(weakEntries)))
+                marker.abortLinearWeakMarking();
+        }
+    }
+
     virtual void markEphemeronEntries(JSTracer* trc) {
-        gc::WeakKeyTable& weakKeys = static_cast<GCMarker*>(trc)->weakKeys;
-
         MOZ_ASSERT(marked);
         for (Enum e(*this); !e.empty(); e.popFront()) {
             Key key(e.front().key());
 
             // If the entry is live, ensure its key and value are marked.
             if (gc::IsMarked(&key)) {
                 (void) markValue(trc, &e.front().value());
-                if (e.front().key() != key)
-                    entryMoved(e, key);
+                MOZ_ASSERT(key == e.front().key()); // No moving
             } else if (keyNeedsMark(key)) {
                 TraceEdge(trc, &e.front().value(), "WeakMap entry value");
                 TraceEdge(trc, &key, "proxy-preserved WeakMap entry key");
-                if (e.front().key() != key)
-                    entryMoved(e, key);
+                MOZ_ASSERT(key == e.front().key()); // No moving
             } else {
                 // Entry is not known to be live yet. Record it in the list of
-                // weak keys. Or rather, record a pointer to this weakmap, so
-                // we can look the key up again when we need to (to allow
-                // incremental weak marking.)
-                auto p = weakKeys.get(JS::GCCellPtr(key));
-                if (p) {
-                    gc::WeakEntryVector& weakEntries = p->value;
-                    if (!weakEntries.append(this)) {
-                        static_cast<GCMarker*>(trc)->endWeakMarkingPhase();
-                        break;
-                    }
-                } else {
-                    gc::WeakEntryVector weakEntries;
-                    JS_ALWAYS_TRUE(weakEntries.append(this));
-                    if (!weakKeys.put(JS::GCCellPtr(key), Move(weakEntries))) {
-                        static_cast<GCMarker*>(trc)->endWeakMarkingPhase();
-                        break;
-                    }
-                }
+                // weak keys. Or rather, record this weakmap and the lookup key
+                // so we can repeat the lookup when we need to (to allow
+                // incremental weak marking, we can't just store a pointer to
+                // the entry.) Also record the delegate, if any, because
+                // marking the delegate must also mark the entry.
+                JS::GCCellPtr weakKey(key);
+                gc::WeakMarkable markable(this, weakKey);
+                addWeakEntry(trc, weakKey, markable);
+                if (JSObject* delegate = getDelegate(key))
+                    addWeakEntry(trc, JS::GCCellPtr(delegate), markable);
             }
             key.unsafeSet(nullptr);
         }
     }
 
   private:
     void exposeGCThingToActiveJS(const JS::Value& v) const { JS::ExposeValueToActiveJS(v); }
     void exposeGCThingToActiveJS(JSObject* obj) const { JS::ExposeObjectToActiveJS(obj); }
