From 66c59c96750fa7a07520f67350449f217421d660 Mon Sep 17 00:00:00 2001
From: Andrew McCreight <amccreight@mozilla.com>
Date: Sat, 19 May 2012 13:56:29 -0700
Subject: [PATCH] Bug 714725 - use deferred release in XPC_WN_Helper_Finalize.
 r=bholley

---
 js/xpconnect/src/XPCWrappedNativeJSOps.cpp | 47 +++++++++-------------
 1 file changed, 19 insertions(+), 28 deletions(-)

diff --git a/js/xpconnect/src/XPCWrappedNativeJSOps.cpp b/js/xpconnect/src/XPCWrappedNativeJSOps.cpp
index f3d1cc064148d..d1c027ccbf38c 100644
--- a/js/xpconnect/src/XPCWrappedNativeJSOps.cpp
+++ b/js/xpconnect/src/XPCWrappedNativeJSOps.cpp
@@ -615,8 +615,13 @@ XPC_WN_Shared_Enumerate(JSContext *cx, JSObject *obj)
 static PRUint32 sFinalizedSlimWrappers;
 #endif
 
+enum WNHelperType {
+    WN_NOHELPER,
+    WN_HELPER
+};
+
 static void
-XPC_WN_NoHelper_Finalize(js::FreeOp *fop, JSObject *obj)
+WrappedNativeFinalize(js::FreeOp *fop, JSObject *obj, WNHelperType helperType)
 {
     js::Class* clazz = js::GetObjectClass(obj);
     if (clazz->flags & JSCLASS_DOM_GLOBAL) {
@@ -635,14 +640,21 @@ XPC_WN_NoHelper_Finalize(js::FreeOp *fop, JSObject *obj)
         cache->ClearWrapper();
 
         XPCJSRuntime *rt = nsXPConnect::GetRuntimeInstance();
-        if(rt)
-            rt->DeferredRelease(p);
-        else
-            NS_RELEASE(p);
+        MOZ_ASSERT(rt, "XPCJSRuntime should exist during a GC.");
+        rt->DeferredRelease(p);
         return;
     }
 
-    static_cast<XPCWrappedNative*>(p)->FlatJSObjectFinalized();
+    XPCWrappedNative* wrapper = static_cast<XPCWrappedNative*>(p);
+    if (helperType == WN_HELPER)
+        wrapper->GetScriptableCallback()->Finalize(wrapper, js::CastToJSFreeOp(fop), obj);
+    wrapper->FlatJSObjectFinalized();
+}
+
+static void
+XPC_WN_NoHelper_Finalize(js::FreeOp *fop, JSObject *obj)
+{
+    WrappedNativeFinalize(fop, obj, WN_NOHELPER);
 }
 
 static void
@@ -1040,28 +1052,7 @@ XPC_WN_Helper_HasInstance(JSContext *cx, JSObject *obj, const jsval *valp, JSBoo
 static void
 XPC_WN_Helper_Finalize(js::FreeOp *fop, JSObject *obj)
 {
-    js::Class* clazz = js::GetObjectClass(obj);
-    if (clazz->flags & JSCLASS_DOM_GLOBAL) {
-        mozilla::dom::DestroyProtoOrIfaceCache(obj);
-    }
-    nsISupports* p = static_cast<nsISupports*>(xpc_GetJSPrivate(obj));
-    if (IS_SLIM_WRAPPER(obj)) {
-        SLIM_LOG(("----- %i finalized slim wrapper (%p, %p)\n",
-                  ++sFinalizedSlimWrappers, obj, p));
-
-        nsWrapperCache* cache;
-        CallQueryInterface(p, &cache);
-        cache->ClearWrapper();
-        NS_RELEASE(p);
-        return;
-    }
-
-    XPCWrappedNative* wrapper = (XPCWrappedNative*)p;
-    if (!wrapper)
-        return;
-
-    wrapper->GetScriptableCallback()->Finalize(wrapper, js::CastToJSFreeOp(fop), obj);
-    wrapper->FlatJSObjectFinalized();
+    WrappedNativeFinalize(fop, obj, WN_HELPER);
 }
 
 static JSBool
-- 
GitLab