Fix for bug 634855 (Memory leak with NoScript 2.0.9.8 installed). r=bent, a=sicking.
authorPeter Van der Beken <peterv@propagandism.org>
Thu, 17 Feb 2011 19:13:28 -0800
changeset 62809 9763667dfc4a668d6c0be3cb481a4eff0cd73ef6
parent 62808 49440149f6a8d9a515c34db982787e9f2c237474
child 62815 9eea65b8b98ea29cf163a3c2e39bbd427ed600b9
push id1
push userroot
push dateTue, 10 Dec 2013 15:46:25 +0000
reviewersbent, sicking
bugs634855
milestone2.0b12pre
Fix for bug 634855 (Memory leak with NoScript 2.0.9.8 installed). r=bent, a=sicking.
js/src/xpconnect/src/xpcprivate.h
js/src/xpconnect/src/xpcwrappednative.cpp
--- a/js/src/xpconnect/src/xpcprivate.h
+++ b/js/src/xpconnect/src/xpcprivate.h
@@ -4552,20 +4552,34 @@ struct CompartmentPrivate
         if (!expandoMap) {
             expandoMap = new nsDataHashtable<nsPtrHashKey<XPCWrappedNative>, JSObject *>();
             if (!expandoMap->Init(8))
                 return false;
         }
         return expandoMap->Put(wn, expando);
     }
 
+    /**
+     * This lookup does not change the color of the JSObject meaning that the
+     * object returned is not guaranteed to be kept alive past the next CC.
+     *
+     * This should only be called if you are certain that the return value won't
+     * be passed into a JS API function and that it won't be stored without
+     * being rooted (or otherwise signaling the stored value to the CC).
+     */
+    JSObject *LookupExpandoObjectPreserveColor(XPCWrappedNative *wn) {
+        return expandoMap ? expandoMap->Get(wn) : nsnull;
+    }
+
+    /**
+     * This lookup clears the gray bit before handing out the JSObject which
+     * means that the object is guaranteed to be kept alive past the next CC.
+     */
     JSObject *LookupExpandoObject(XPCWrappedNative *wn) {
-        if (!expandoMap)
-            return nsnull;
-        JSObject *obj = expandoMap->Get(wn);
+        JSObject *obj = LookupExpandoObjectPreserveColor(wn);
         xpc_UnmarkGrayObject(obj);
         return obj;
     }
 };
 
 inline bool
 CompartmentParticipatesInCycleCollection(JSContext *cx, JSCompartment *compartment)
 {
--- a/js/src/xpconnect/src/xpcwrappednative.cpp
+++ b/js/src/xpconnect/src/xpcwrappednative.cpp
@@ -76,17 +76,17 @@ static PLDHashOperator
 TraverseExpandoObjects(xpc::PtrAndPrincipalHashKey *aKey, JSCompartment *compartment, void *aClosure)
 {
     TraverseExpandoObjectClosure *closure = static_cast<TraverseExpandoObjectClosure*>(aClosure);
     xpc::CompartmentPrivate *priv = 
         (xpc::CompartmentPrivate *)JS_GetCompartmentPrivate(closure->cx, compartment);
 
     NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(closure->cb, "XPCWrappedNative expando object");
     closure->cb.NoteScriptChild(nsIProgrammingLanguage::JAVASCRIPT,
-                                priv->LookupExpandoObject(closure->wn));
+                                priv->LookupExpandoObjectPreserveColor(closure->wn));
 
     return PL_DHASH_NEXT;
 }
 
 NS_IMETHODIMP
 NS_CYCLE_COLLECTION_CLASSNAME(XPCWrappedNative)::Traverse(void *p,
                                                           nsCycleCollectionTraversalCallback &cb)
 {