Bug 886408 - Move nsContentUtils::ReleaseWrapper into nsWrapperCache; r=mccr8
authorMs2ger <ms2ger@gmail.com>
Fri, 02 Aug 2013 09:04:01 +0200
changeset 141058 15c0ae74266f5703a5be69f9deb86a685f84dae3
parent 141057 3ac5fdcbb36685ab5eff3ad3a30c210f38740c09
child 141059 6088be7ecfea76a298f88d5b8e475076d7fbfa24
push id31979
push userMs2ger@gmail.com
push dateFri, 02 Aug 2013 09:08:26 +0000
treeherdermozilla-inbound@ee108221c037 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmccr8
bugs886408
milestone25.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 886408 - Move nsContentUtils::ReleaseWrapper into nsWrapperCache; r=mccr8
content/base/public/nsContentUtils.h
content/base/src/FragmentOrElement.cpp
content/base/src/nsContentUtils.cpp
content/base/src/nsDocument.cpp
content/base/src/nsGenericDOMDataNode.cpp
content/base/src/nsINode.cpp
content/base/src/nsInProcessTabChildGlobal.cpp
content/base/src/nsNodeUtils.cpp
content/events/src/nsDOMEventTargetHelper.cpp
dom/base/nsWrapperCache.cpp
dom/base/nsWrapperCache.h
dom/indexedDB/IDBWrapperCache.cpp
layout/style/StyleRule.cpp
layout/style/nsCSSRules.cpp
--- a/content/base/public/nsContentUtils.h
+++ b/content/base/public/nsContentUtils.h
@@ -1273,19 +1273,16 @@ public:
   static bool AreJSObjectsHeld(void* aScriptObjectHolder); 
 #endif
 
   static void DeferredFinalize(nsISupports* aSupports);
   static void DeferredFinalize(mozilla::DeferredFinalizeAppendFunction aAppendFunc,
                                mozilla::DeferredFinalizeFunction aFunc,
                                void* aThing);
 
-  static void ReleaseWrapper(void* aScriptObjectHolder,
-                             nsWrapperCache* aCache);
-
   /*
    * Notify when the first XUL menu is opened and when the all XUL menus are
    * closed. At opening, aInstalling should be TRUE, otherwise, it should be
    * FALSE.
    */
   static void NotifyInstalledMenuKeyboardListener(bool aInstalling);
 
   /**
--- a/content/base/src/FragmentOrElement.cpp
+++ b/content/base/src/FragmentOrElement.cpp
@@ -984,17 +984,17 @@ void
 FragmentOrElement::DestroyContent()
 {
   nsIDocument *document = OwnerDoc();
   document->BindingManager()->RemovedFromDocument(this, document);
   document->ClearBoxObjectFor(this);
 
   // XXX We really should let cycle collection do this, but that currently still
   //     leaks (see https://bugzilla.mozilla.org/show_bug.cgi?id=406684).
-  nsContentUtils::ReleaseWrapper(this, this);
+  ReleaseWrapper(this);
 
   uint32_t i, count = mAttrsAndChildren.ChildCount();
   for (i = 0; i < count; ++i) {
     // The child can remove itself from the parent in BindToTree.
     mAttrsAndChildren.ChildAt(i)->DestroyContent();
   }
 }
 
--- a/content/base/src/nsContentUtils.cpp
+++ b/content/base/src/nsContentUtils.cpp
@@ -6286,34 +6286,16 @@ nsContentUtils::IsInPointerLockContext(n
 
   nsCOMPtr<nsIDOMWindow> top;
   aWin->GetScriptableTop(getter_AddRefs(top));
 
   return top == lockTop;
 }
 
 // static
-void
-nsContentUtils::ReleaseWrapper(void* aScriptObjectHolder,
-                               nsWrapperCache* aCache)
-{
-  if (aCache->PreservingWrapper()) {
-    // PreserveWrapper puts new DOM bindings in the JS holders hash, but they
-    // can also be in the DOM expando hash, so we need to try to remove them
-    // from both here.
-    JSObject* obj = aCache->GetWrapperPreserveColor();
-    if (aCache->IsDOMBinding() && obj && js::IsProxy(obj)) {
-        DOMProxyHandler::GetAndClearExpandoObject(obj);
-    }
-    aCache->SetPreservingWrapper(false);
-    DropJSObjects(aScriptObjectHolder);
-  }
-}
-
-// static
 int32_t
 nsContentUtils::GetAdjustedOffsetInTextControl(nsIFrame* aOffsetFrame,
                                                int32_t aOffset)
 {
   // The structure of the anonymous frames within a text control frame is
   // an optional block frame, followed by an optional br frame.
 
   // If the offset frame has a child, then this frame is the block which
--- a/content/base/src/nsDocument.cpp
+++ b/content/base/src/nsDocument.cpp
@@ -7783,17 +7783,17 @@ nsDocument::Destroy()
   // leak-fixing if we fix nsDocumentViewer to do cycle-collection, but
   // tearing down all those frame trees right now is the right thing to do.
   mExternalResourceMap.Shutdown();
 
   mCustomPrototypes.Clear();
 
   // XXX We really should let cycle collection do this, but that currently still
   //     leaks (see https://bugzilla.mozilla.org/show_bug.cgi?id=406684).
-  nsContentUtils::ReleaseWrapper(static_cast<nsINode*>(this), this);
+  ReleaseWrapper(static_cast<nsINode*>(this));
 }
 
 void
 nsDocument::RemovedFromDocShell()
 {
   if (mRemovedFromDocShell)
     return;
 
--- a/content/base/src/nsGenericDOMDataNode.cpp
+++ b/content/base/src/nsGenericDOMDataNode.cpp
@@ -689,17 +689,17 @@ nsGenericDOMDataNode::SaveSubtreeState()
 {
 }
 
 void
 nsGenericDOMDataNode::DestroyContent()
 {
   // XXX We really should let cycle collection do this, but that currently still
   //     leaks (see https://bugzilla.mozilla.org/show_bug.cgi?id=406684).
-  nsContentUtils::ReleaseWrapper(this, this);
+  ReleaseWrapper(this);
 }
 
 #ifdef DEBUG
 void
 nsGenericDOMDataNode::List(FILE* out, int32_t aIndent) const
 {
 }
 
--- a/content/base/src/nsINode.cpp
+++ b/content/base/src/nsINode.cpp
@@ -1249,19 +1249,19 @@ nsINode::Traverse(nsINode *tmp, nsCycleC
     nsContentUtils::TraverseListenerManager(tmp, cb);
   }
 
   return true;
 }
 
 /* static */
 void
-nsINode::Unlink(nsINode *tmp)
+nsINode::Unlink(nsINode* tmp)
 {
-  nsContentUtils::ReleaseWrapper(tmp, tmp);
+  tmp->ReleaseWrapper(tmp);
 
   nsSlots *slots = tmp->GetExistingSlots();
   if (slots) {
     slots->Unlink();
   }
 
   if (tmp->NodeType() != nsIDOMNode::DOCUMENT_NODE &&
       tmp->HasFlag(NODE_HAS_LISTENERMANAGER)) {
--- a/content/base/src/nsInProcessTabChildGlobal.cpp
+++ b/content/base/src/nsInProcessTabChildGlobal.cpp
@@ -255,17 +255,17 @@ nsInProcessTabChildGlobal::DelayedDiscon
     static_cast<nsFrameMessageManager*>(mMessageManager.get())->Disconnect();
     mMessageManager = nullptr;
   }
   if (mListenerManager) {
     mListenerManager->Disconnect();
   }
 
   if (!mLoadingScript) {
-    nsContentUtils::ReleaseWrapper(static_cast<EventTarget*>(this), this);
+    ReleaseWrapper(static_cast<EventTarget*>(this));
     mGlobal = nullptr;
   } else {
     mDelayedDisconnect = true;
   }
 }
 
 NS_IMETHODIMP_(nsIContent *)
 nsInProcessTabChildGlobal::GetOwnerContent()
--- a/content/base/src/nsNodeUtils.cpp
+++ b/content/base/src/nsNodeUtils.cpp
@@ -255,17 +255,17 @@ nsNodeUtils::LastRelease(nsINode* aNode)
     // if NODE_FORCE_XBL_BINDINGS is set, the node might still have a binding
     // attached
     if (aNode->HasFlag(NODE_FORCE_XBL_BINDINGS) &&
         ownerDoc->BindingManager()) {
       ownerDoc->BindingManager()->RemovedFromDocument(elem, ownerDoc);
     }
   }
 
-  nsContentUtils::ReleaseWrapper(aNode, aNode);
+  aNode->ReleaseWrapper(aNode);
 }
 
 struct MOZ_STACK_CLASS nsHandlerData
 {
   uint16_t mOperation;
   nsCOMPtr<nsIDOMNode> mSource;
   nsCOMPtr<nsIDOMNode> mDest;
   nsCxPusher mPusher;
--- a/content/events/src/nsDOMEventTargetHelper.cpp
+++ b/content/events/src/nsDOMEventTargetHelper.cpp
@@ -78,17 +78,17 @@ NS_IMPL_DOMTARGET_DEFAULTS(nsDOMEventTar
 nsDOMEventTargetHelper::~nsDOMEventTargetHelper()
 {
   if (nsPIDOMWindow* owner = GetOwner()) {
     static_cast<nsGlobalWindow*>(owner)->RemoveEventTargetObject(this);
   }
   if (mListenerManager) {
     mListenerManager->Disconnect();
   }
-  nsContentUtils::ReleaseWrapper(this, this);
+  ReleaseWrapper(this);
 }
 
 void
 nsDOMEventTargetHelper::BindToOwner(nsPIDOMWindow* aOwner)
 {
   nsCOMPtr<nsIGlobalObject> glob = do_QueryInterface(aOwner);
   BindToOwner(glob);
 }
--- a/dom/base/nsWrapperCache.cpp
+++ b/dom/base/nsWrapperCache.cpp
@@ -1,29 +1,47 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsWrapperCacheInlines.h"
 
+#include "jsproxy.h"
+#include "mozilla/dom/DOMJSProxyHandler.h"
 #include "nsCycleCollectionTraversalCallback.h"
 #include "nsCycleCollector.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
 /* static */ void
 nsWrapperCache::HoldJSObjects(void* aScriptObjectHolder,
                               nsScriptObjectTracer* aTracer)
 {
   cyclecollector::AddJSHolder(aScriptObjectHolder, aTracer);
 }
 
+void
+nsWrapperCache::ReleaseWrapper(void* aScriptObjectHolder)
+{
+  if (PreservingWrapper()) {
+    // PreserveWrapper puts new DOM bindings in the JS holders hash, but they
+    // can also be in the DOM expando hash, so we need to try to remove them
+    // from both here.
+    JSObject* obj = GetWrapperPreserveColor();
+    if (IsDOMBinding() && obj && js::IsProxy(obj)) {
+      DOMProxyHandler::GetAndClearExpandoObject(obj);
+    }
+    SetPreservingWrapper(false);
+    cyclecollector::RemoveJSHolder(aScriptObjectHolder);
+  }
+}
+
 #ifdef DEBUG
 
 class DebugWrapperTraversalCallback : public nsCycleCollectionTraversalCallback
 {
 public:
   DebugWrapperTraversalCallback(void* aWrapper)
     : mFound(false)
     , mWrapper(aWrapper)
--- a/dom/base/nsWrapperCache.h
+++ b/dom/base/nsWrapperCache.h
@@ -239,16 +239,18 @@ public:
     HoldJSObjects(aScriptObjectHolder, aTracer);
     SetPreservingWrapper(true);
 #ifdef DEBUG
     // Make sure the cycle collector will be able to traverse to the wrapper.
     CheckCCWrapperTraversal(aScriptObjectHolder, aTracer);
 #endif
   }
 
+  void ReleaseWrapper(void* aScriptObjectHolder);
+
 private:
   JSObject *GetWrapperJSObject() const
   {
     return mWrapper;
   }
 
   void SetWrapperJSObject(JSObject* aWrapper)
   {
@@ -334,17 +336,17 @@ NS_DEFINE_STATIC_IID_ACCESSOR(nsWrapperC
 
 
 // Cycle collector macros for wrapper caches.
 
 #define NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER \
   tmp->TraceWrapper(aCallbacks, aClosure);
 
 #define NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER \
-  nsContentUtils::ReleaseWrapper(p, tmp);
+  tmp->ReleaseWrapper(p);
 
 #define NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(_class) \
   NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(_class)              \
     NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER        \
   NS_IMPL_CYCLE_COLLECTION_TRACE_END
 
 #define NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(_class) \
   NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(_class)         \
--- a/dom/indexedDB/IDBWrapperCache.cpp
+++ b/dom/indexedDB/IDBWrapperCache.cpp
@@ -34,17 +34,17 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_
 NS_INTERFACE_MAP_END_INHERITING(nsDOMEventTargetHelper)
 
 NS_IMPL_ADDREF_INHERITED(IDBWrapperCache, nsDOMEventTargetHelper)
 NS_IMPL_RELEASE_INHERITED(IDBWrapperCache, nsDOMEventTargetHelper)
 
 IDBWrapperCache::~IDBWrapperCache()
 {
   mScriptOwner = nullptr;
-  nsContentUtils::ReleaseWrapper(this, this);
+  ReleaseWrapper(this);
   NS_DROP_JS_OBJECTS(this, IDBWrapperCache);
 }
 
 void
 IDBWrapperCache::SetScriptOwner(JSObject* aScriptOwner)
 {
   NS_ASSERTION(aScriptOwner, "This should never be null!");
 
--- a/layout/style/StyleRule.cpp
+++ b/layout/style/StyleRule.cpp
@@ -1168,17 +1168,17 @@ NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(DOM
   // directly because the wrapper is on the declaration, not on us.
   tmp->DOMDeclaration()->TraceWrapper(aCallbacks, aClosure);
 NS_IMPL_CYCLE_COLLECTION_TRACE_END
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(DOMCSSStyleRule)
   // Unlink the wrapper for our declaraton.  This just expands out
   // NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER which we can't use
   // directly because the wrapper is on the declaration, not on us.
-  nsContentUtils::ReleaseWrapper(static_cast<nsISupports*>(p), tmp->DOMDeclaration());
+  tmp->DOMDeclaration()->ReleaseWrapper(static_cast<nsISupports*>(p));
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(DOMCSSStyleRule)
   // Just NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS here: that will call
   // into our Trace hook, where we do the right thing with declarations
   // already.
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
--- a/layout/style/nsCSSRules.cpp
+++ b/layout/style/nsCSSRules.cpp
@@ -1755,17 +1755,17 @@ NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(nsC
   // directly because the wrapper is on the declaration, not on us.
   tmp->mDecl.TraceWrapper(aCallbacks, aClosure);
 NS_IMPL_CYCLE_COLLECTION_TRACE_END
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsCSSFontFaceRule)
   // Unlink the wrapper for our declaraton.  This just expands out
   // NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER which we can't use
   // directly because the wrapper is on the declaration, not on us.
-  nsContentUtils::ReleaseWrapper(static_cast<nsISupports*>(p), &tmp->mDecl);
+  tmp->mDecl.ReleaseWrapper(static_cast<nsISupports*>(p));
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsCSSFontFaceRule)
   // Just NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS here: that will call
   // into our Trace hook, where we do the right thing with declarations
   // already.
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END