Bug 967364: Use every already_AddRefed. r=bsmedberg
authorKyle Huey <khuey@kylehuey.com>
Sat, 15 Mar 2014 12:00:16 -0700
changeset 190965 ff034c181ae4520eca6b8eba4156f60d632bcb2a
parent 190964 49dfebffbf8e300cf0c63d3040905add42576274
child 190966 a07dde918187f3c244d412917144872e1a349cf3
push id3503
push userraliiev@mozilla.com
push dateMon, 28 Apr 2014 18:51:11 +0000
treeherdermozilla-beta@c95ac01e332e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbsmedberg
bugs967364
milestone30.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 967364: Use every already_AddRefed. r=bsmedberg
content/media/MediaStreamGraph.cpp
content/svg/content/src/nsSVGElement.cpp
dom/base/nsGlobalWindow.cpp
ipc/glue/BackgroundImpl.cpp
layout/forms/nsComboboxControlFrame.cpp
netwerk/protocol/http/nsHttpConnectionMgr.cpp
netwerk/protocol/wyciwyg/nsWyciwygChannel.cpp
parser/html/nsHtml5Atom.cpp
uriloader/prefetch/nsOfflineCacheUpdateService.cpp
widget/xpwidgets/nsBaseWidget.cpp
xpcom/ds/nsAtomTable.cpp
xpcom/glue/nsCOMPtr.h
--- a/content/media/MediaStreamGraph.cpp
+++ b/content/media/MediaStreamGraph.cpp
@@ -1,15 +1,16 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-*/
 /* 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 "MediaStreamGraphImpl.h"
 #include "mozilla/LinkedList.h"
+#include "mozilla/unused.h"
 
 #include "AudioSegment.h"
 #include "VideoSegment.h"
 #include "nsContentUtils.h"
 #include "nsIAppShell.h"
 #include "nsIObserver.h"
 #include "nsServiceManagerUtils.h"
 #include "nsWidgetsCID.h"
@@ -19,16 +20,17 @@
 #include "ImageContainer.h"
 #include "AudioChannelCommon.h"
 #include "AudioNodeEngine.h"
 #include "AudioNodeStream.h"
 #include "AudioNodeExternalInputStream.h"
 #include <algorithm>
 #include "DOMMediaStream.h"
 #include "GeckoProfiler.h"
+#include "mozilla/unused.h"
 
 using namespace mozilla::layers;
 using namespace mozilla::dom;
 using namespace mozilla::gfx;
 
 namespace mozilla {
 
 #ifdef PR_LOGGING
@@ -2382,17 +2384,17 @@ ProcessedMediaStream::AllocateInputPort(
     Message(MediaInputPort* aPort)
       : ControlMessage(aPort->GetDestination()),
         mPort(aPort) {}
     virtual void Run()
     {
       mPort->Init();
       // The graph holds its reference implicitly
       mPort->GraphImpl()->SetStreamOrderDirty();
-      mPort.forget();
+      unused << mPort.forget();
     }
     virtual void RunDuringShutdown()
     {
       Run();
     }
     nsRefPtr<MediaInputPort> mPort;
   };
   nsRefPtr<MediaInputPort> port = new MediaInputPort(aStream, this, aFlags,
--- a/content/svg/content/src/nsSVGElement.cpp
+++ b/content/svg/content/src/nsSVGElement.cpp
@@ -1,15 +1,16 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* 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 "mozilla/ArrayUtils.h"
 #include "mozilla/DebugOnly.h"
+#include "mozilla/unused.h"
 
 #include "nsSVGElement.h"
 
 #include "mozilla/dom/SVGSVGElement.h"
 #include "mozilla/dom/SVGTests.h"
 #include "nsContentUtils.h"
 #include "nsICSSDeclaration.h"
 #include "nsIDocument.h"
@@ -44,16 +45,17 @@
 #include "SVGContentUtils.h"
 #include "nsIFrame.h"
 #include <stdarg.h>
 #include "nsSMILMappedAttribute.h"
 #include "SVGMotionSMILAttr.h"
 #include "nsAttrValueOrString.h"
 #include "nsSMILAnimationController.h"
 #include "mozilla/dom/SVGElementBinding.h"
+#include "mozilla/unused.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
 // This is needed to ensure correct handling of calls to the
 // vararg-list methods in this file:
 //   nsSVGElement::GetAnimated{Length,Number,Integer}Values
 // See bug 547964 for details:
@@ -1358,17 +1360,17 @@ nsSVGElement::UpdateAnimatedContentStyle
   if (animContentStyleRule) {
 #ifdef DEBUG
     nsresult rv =
 #endif
       SetProperty(SMIL_MAPPED_ATTR_ANIMVAL,
                   SMIL_MAPPED_ATTR_STYLERULE_ATOM,
                   animContentStyleRule.get(),
                   ReleaseStyleRule);
-    animContentStyleRule.forget();
+    unused << animContentStyleRule.forget();
     NS_ABORT_IF_FALSE(rv == NS_OK,
                       "SetProperty failed (or overwrote something)");
   }
 }
 
 css::StyleRule*
 nsSVGElement::GetAnimatedContentStyleRule()
 {
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -43,16 +43,17 @@
 #include "js/OldDebugAPI.h"     // for JS_ClearWatchPointsForObject
 #include "jswrapper.h"
 #include "nsReadableUtils.h"
 #include "nsDOMClassInfo.h"
 #include "nsJSEnvironment.h"
 #include "ScriptSettings.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/Likely.h"
+#include "mozilla/unused.h"
 
 // Other Classes
 #include "nsEventListenerManager.h"
 #include "mozilla/dom/BarProps.h"
 #include "nsContentCID.h"
 #include "nsLayoutStatics.h"
 #include "nsCCUncollectableMarker.h"
 #include "mozilla/dom/workers/Workers.h"
@@ -11662,17 +11663,17 @@ nsGlobalWindow::SetTimeoutOrInterval(nsI
     nsRefPtr<nsTimeout> copy = timeout;
 
     rv = timeout->InitTimer(TimerCallback, realInterval);
     if (NS_FAILED(rv)) {
       return rv;
     }
 
     // The timeout is now also held in the timer's closure.
-    copy.forget();
+    unused << copy.forget();
   } else {
     // If we are frozen, however, then we instead simply set
     // timeout->mTimeRemaining to be the "time remaining" in the timeout (i.e.,
     // the interval itself). We don't create a timer for it, since that will
     // happen when we are thawed and the timeout will then get a timer and run
     // to completion.
 
     timeout->mTimeRemaining = delta;
--- a/ipc/glue/BackgroundImpl.cpp
+++ b/ipc/glue/BackgroundImpl.cpp
@@ -4,16 +4,17 @@
 
 #include "base/process_util.h"
 #include "mozilla/Assertions.h"
 #include "mozilla/Atomics.h"
 #include "mozilla/ClearOnShutdown.h"
 #include "mozilla/DebugOnly.h"
 #include "mozilla/Services.h"
 #include "mozilla/StaticPtr.h"
+#include "mozilla/unused.h"
 #include "mozilla/dom/ContentChild.h"
 #include "mozilla/dom/ContentParent.h"
 #include "mozilla/ipc/ProtocolTypes.h"
 #include "BackgroundChild.h"
 #include "BackgroundChildImpl.h"
 #include "BackgroundParent.h"
 #include "BackgroundParentImpl.h"
 #include "GeckoProfiler.h"
@@ -672,17 +673,17 @@ public:
 
   NS_DECL_ISUPPORTS_INHERITED
 
 private:
   ~OpenChildProcessActorRunnable()
   {
     if (mTransport) {
       CRASH_IN_CHILD_PROCESS("Leaking transport!");
-      mTransport.forget();
+      unused << mTransport.forget();
     }
   }
 
   NS_DECL_NSIRUNNABLE
 };
 
 class ChildImpl::OpenMainProcessActorRunnable MOZ_FINAL :
   public ChildImpl::CreateCallbackRunnable
@@ -1528,17 +1529,17 @@ ChildImpl::GetOrCreateForCurrentThread(
 
   return true;
 }
 
 ChildImpl::CreateCallbackRunnable::~CreateCallbackRunnable()
 {
   if (mActor) {
     CRASH_IN_CHILD_PROCESS("Leaking actor!");
-    mActor.forget();
+    unused << mActor.forget();
   }
 }
 
 // static
 already_AddRefed<nsIIPCBackgroundChildCreateCallback>
 ChildImpl::CreateCallbackRunnable::GetNextCallback()
 {
   // May run on any thread!
@@ -1671,17 +1672,17 @@ ChildImpl::OpenMainProcessActorRunnable:
       callback->ActorFailed();
       callback = GetNextCallback();
     }
 
     return NS_OK;
   }
 
   // Now that Open() has succeeded transfer the ownership of the actors to IPDL.
-  parentActor.forget();
+  unused << parentActor.forget();
 
   auto threadLocalInfo =
     static_cast<ThreadLocalInfo*>(PR_GetThreadPrivate(sThreadLocalIndex));
 
   MOZ_ASSERT(threadLocalInfo);
   MOZ_ASSERT(!threadLocalInfo->mActor);
 
   nsRefPtr<ChildImpl>& childActor = threadLocalInfo->mActor;
--- a/layout/forms/nsComboboxControlFrame.cpp
+++ b/layout/forms/nsComboboxControlFrame.cpp
@@ -33,16 +33,17 @@
 #include "nsITheme.h"
 #include "nsAsyncDOMEvent.h"
 #include "nsRenderingContext.h"
 #include "mozilla/Likely.h"
 #include <algorithm>
 #include "nsTextNode.h"
 #include "mozilla/LookAndFeel.h"
 #include "mozilla/MouseEvents.h"
+#include "mozilla/unused.h"
 
 using namespace mozilla;
 
 NS_IMETHODIMP
 nsComboboxControlFrame::RedisplayTextEvent::Run()
 {
   if (mControlFrame)
     mControlFrame->HandleRedisplayTextEvent();
@@ -798,17 +799,17 @@ nsComboboxControlFrame::Reflow(nsPresCon
 
   // First reflow our dropdown so that we know how tall we should be.
   ReflowDropdown(aPresContext, aReflowState);
   nsRefPtr<nsResizeDropdownAtFinalPosition> resize =
     new nsResizeDropdownAtFinalPosition(this);
   if (NS_SUCCEEDED(aPresContext->PresShell()->PostReflowCallback(resize))) {
     // The reflow callback queue doesn't AddRef so we keep it alive until
     // it's released in its ReflowFinished / ReflowCallbackCanceled.
-    resize.forget();
+    unused << resize.forget();
   }
 
   // Get the width of the vertical scrollbar.  That will be the width of the
   // dropdown button.
   nscoord buttonWidth;
   const nsStyleDisplay *disp = StyleDisplay();
   if (IsThemed(disp) && !aPresContext->GetTheme()->ThemeNeedsComboboxDropmarker()) {
     buttonWidth = 0;
--- a/netwerk/protocol/http/nsHttpConnectionMgr.cpp
+++ b/netwerk/protocol/http/nsHttpConnectionMgr.cpp
@@ -26,16 +26,17 @@
 #include "mozilla/Telemetry.h"
 #include "mozilla/net/DashboardTypes.h"
 #include "NullHttpTransaction.h"
 #include "nsITransport.h"
 #include "nsISocketTransportService.h"
 #include <algorithm>
 #include "Http2Compression.h"
 #include "mozilla/ChaosMode.h"
+#include "mozilla/unused.h"
 
 // defined by the socket transport service while active
 extern PRThread *gSocketThread;
 
 namespace mozilla {
 namespace net {
 
 //-----------------------------------------------------------------------------
@@ -328,17 +329,17 @@ nsHttpConnectionMgr::PruneDeadConnection
 nsresult
 nsHttpConnectionMgr::DoShiftReloadConnectionCleanup(nsHttpConnectionInfo *aCI)
 {
     nsRefPtr<nsHttpConnectionInfo> connInfo(aCI);
 
     nsresult rv = PostEvent(&nsHttpConnectionMgr::OnMsgDoShiftReloadConnectionCleanup,
                             0, connInfo);
     if (NS_SUCCEEDED(rv))
-        connInfo.forget();
+        unused << connInfo.forget();
     return rv;
 }
 
 class SpeculativeConnectArgs
 {
 public:
     SpeculativeConnectArgs() { mOverridesOK = false; }
     virtual ~SpeculativeConnectArgs() {}
@@ -403,17 +404,17 @@ nsHttpConnectionMgr::SpeculativeConnect(
         overrider->GetIgnoreIdle(&args->mIgnoreIdle);
         overrider->GetIgnorePossibleSpdyConnections(
             &args->mIgnorePossibleSpdyConnections);
     }
 
     nsresult rv =
         PostEvent(&nsHttpConnectionMgr::OnMsgSpeculativeConnect, 0, args);
     if (NS_SUCCEEDED(rv))
-        args.forget();
+        unused << args.forget();
     return rv;
 }
 
 nsresult
 nsHttpConnectionMgr::GetSocketThreadTarget(nsIEventTarget **target)
 {
     EnsureSocketThreadTarget();
 
@@ -500,17 +501,17 @@ nsHttpConnectionMgr::UpdateRequestTokenB
 {
     nsRefPtr<EventTokenBucket> bucket(aBucket);
 
     // Call From main thread when a new EventTokenBucket has been made in order
     // to post the new value to the socket thread.
     nsresult rv = PostEvent(&nsHttpConnectionMgr::OnMsgUpdateRequestTokenBucket,
                             0, bucket);
     if (NS_SUCCEEDED(rv))
-        bucket.forget();
+        unused << bucket.forget();
     return rv;
 }
 
 // Given a nsHttpConnectionInfo find the connection entry object that
 // contains either the nshttpconnection or nshttptransaction parameter.
 // Normally this is done by the hashkey lookup of connectioninfo,
 // but if spdy coalescing is in play it might be found in a redirected
 // entry
--- a/netwerk/protocol/wyciwyg/nsWyciwygChannel.cpp
+++ b/netwerk/protocol/wyciwyg/nsWyciwygChannel.cpp
@@ -19,31 +19,32 @@
 #include "nsThreadUtils.h"
 #include "nsIEventTarget.h"
 #include "nsIInputStream.h"
 #include "nsIInputStreamPump.h"
 #include "nsIOutputStream.h"
 #include "nsIProgressEventSink.h"
 #include "nsIURI.h"
 #include "mozilla/DebugOnly.h"
+#include "mozilla/unused.h"
 
 typedef mozilla::net::LoadContextInfo LoadContextInfo;
 
 // Must release mChannel on the main thread
 class nsWyciwygAsyncEvent : public nsRunnable {
 public:
   nsWyciwygAsyncEvent(nsWyciwygChannel *aChannel) : mChannel(aChannel) {}
 
   ~nsWyciwygAsyncEvent()
   {
     nsCOMPtr<nsIThread> thread = do_GetMainThread();
     NS_WARN_IF_FALSE(thread, "Couldn't get the main thread!");
     if (thread) {
       nsIWyciwygChannel *chan = static_cast<nsIWyciwygChannel *>(mChannel);
-      mChannel.forget();
+      mozilla::unused << mChannel.forget();
       NS_ProxyRelease(thread, chan);
     }
   }
 protected:
   nsRefPtr<nsWyciwygChannel> mChannel;
 };
 
 class nsWyciwygSetCharsetandSourceEvent : public nsWyciwygAsyncEvent {
--- a/parser/html/nsHtml5Atom.cpp
+++ b/parser/html/nsHtml5Atom.cpp
@@ -1,14 +1,15 @@
 /* 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 "nsHtml5Atom.h"
 #include "nsAutoPtr.h"
+#include "mozilla/unused.h"
 
 nsHtml5Atom::nsHtml5Atom(const nsAString& aString)
 {
   mLength = aString.Length();
   nsRefPtr<nsStringBuffer> buf = nsStringBuffer::FromString(aString);
   if (buf) {
     mString = static_cast<char16_t*>(buf->Data());
   } else {
@@ -19,17 +20,17 @@ nsHtml5Atom::nsHtml5Atom(const nsAString
   }
 
   NS_ASSERTION(mString[mLength] == char16_t(0), "null terminated");
   NS_ASSERTION(buf && buf->StorageSize() >= (mLength+1) * sizeof(char16_t),
                "enough storage");
   NS_ASSERTION(Equals(aString), "correct data");
 
   // Take ownership of buffer
-  buf.forget();
+  mozilla::unused << buf.forget();
 }
 
 nsHtml5Atom::~nsHtml5Atom()
 {
   nsStringBuffer::FromData(mString)->Release();
 }
 
 NS_IMETHODIMP_(nsrefcnt)
--- a/uriloader/prefetch/nsOfflineCacheUpdateService.cpp
+++ b/uriloader/prefetch/nsOfflineCacheUpdateService.cpp
@@ -43,23 +43,25 @@
 #include "nsServiceManagerUtils.h"
 #include "nsStreamUtils.h"
 #include "nsThreadUtils.h"
 #include "nsProxyRelease.h"
 #include "prlog.h"
 #include "nsIAsyncVerifyRedirectCallback.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/Attributes.h"
+#include "mozilla/unused.h"
 #include "nsIDiskSpaceWatcher.h"
 #include "nsIDocShell.h"
 #include "nsIDocShellTreeItem.h"
 #include "nsIDocShellTreeOwner.h"
 #include "mozilla/dom/TabChild.h"
 #include "mozilla/dom/PermissionMessageUtils.h"
 #include "nsContentUtils.h"
+#include "mozilla/unused.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
 static nsOfflineCacheUpdateService *gOfflineCacheUpdateService = nullptr;
 
 nsTHashtable<nsCStringHashKey>* nsOfflineCacheUpdateService::mAllowedDomains = nullptr;
 
@@ -400,17 +402,17 @@ nsOfflineCacheUpdateService::ScheduleOnD
                                         aDocumentURI, aDocument);
     NS_ENSURE_TRUE(update, NS_ERROR_OUT_OF_MEMORY);
 
     nsresult rv = progress->AddProgressListener
         (update, nsIWebProgress::NOTIFY_STATE_DOCUMENT);
     NS_ENSURE_SUCCESS(rv, rv);
 
     // The update will release when it has scheduled itself.
-    update.forget();
+    unused << update.forget();
 
     return NS_OK;
 }
 
 nsresult
 nsOfflineCacheUpdateService::UpdateFinished(nsOfflineCacheUpdate *aUpdate)
 {
     LOG(("nsOfflineCacheUpdateService::UpdateFinished [%p, update=%p]",
--- a/widget/xpwidgets/nsBaseWidget.cpp
+++ b/widget/xpwidgets/nsBaseWidget.cpp
@@ -31,22 +31,24 @@
 #include "nsEventStateManager.h"
 #include "nsIWidgetListener.h"
 #include "nsIGfxInfo.h"
 #include "npapi.h"
 #include "base/thread.h"
 #include "prdtoa.h"
 #include "prenv.h"
 #include "mozilla/Attributes.h"
+#include "mozilla/unused.h"
 #include "nsContentUtils.h"
 #include "gfxPrefs.h"
 #include "mozilla/gfx/2D.h"
 #include "mozilla/MouseEvents.h"
 #include "GLConsts.h"
 #include "LayerScope.h"
+#include "mozilla/unused.h"
 
 #ifdef ACCESSIBILITY
 #include "nsAccessibilityService.h"
 #endif
 
 #ifdef DEBUG
 #include "nsIObserver.h"
 
@@ -184,18 +186,18 @@ void nsBaseWidget::DestroyCompositor()
     // events already in the MessageLoop get processed before the
     // CompositorChild is destroyed, so we add a task to the MessageLoop to
     // handle compositor desctruction.
     MessageLoop::current()->PostTask(FROM_HERE,
                NewRunnableFunction(DeferredDestroyCompositor, mCompositorParent,
                                    mCompositorChild));
     // The DestroyCompositor task we just added to the MessageLoop will handle
     // releasing mCompositorParent and mCompositorChild.
-    mCompositorParent.forget();
-    mCompositorChild.forget();
+    unused << mCompositorParent.forget();
+    unused << mCompositorChild.forget();
   }
 }
 
 //-------------------------------------------------------------------------
 //
 // nsBaseWidget destructor
 //
 //-------------------------------------------------------------------------
--- a/xpcom/ds/nsAtomTable.cpp
+++ b/xpcom/ds/nsAtomTable.cpp
@@ -5,16 +5,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/Assertions.h"
 #include "mozilla/Attributes.h"
 #include "mozilla/Compiler.h"
 #include "mozilla/HashFunctions.h"
 #include "mozilla/MemoryReporting.h"
 #include "mozilla/DebugOnly.h"
+#include "mozilla/unused.h"
 
 #include "nsAtomTable.h"
 #include "nsStaticAtom.h"
 #include "nsString.h"
 #include "nsCRT.h"
 #include "pldhash.h"
 #include "prenv.h"
 #include "nsThreadUtils.h"
@@ -339,17 +340,17 @@ AtomImpl::AtomImpl(const nsAString& aStr
   MOZ_ASSERT(mHash == HashString(mString, mLength));
 
   NS_ASSERTION(mString[mLength] == char16_t(0), "null terminated");
   NS_ASSERTION(buf && buf->StorageSize() >= (mLength+1) * sizeof(char16_t),
                "enough storage");
   NS_ASSERTION(Equals(aString), "correct data");
 
   // Take ownership of buffer
-  buf.forget();
+  mozilla::unused << buf.forget();
 }
 
 AtomImpl::AtomImpl(nsStringBuffer* aStringBuffer, uint32_t aLength,
                    uint32_t aHash)
 {
   mLength = aLength;
   mString = static_cast<char16_t*>(aStringBuffer->Data());
   // Technically we could currently avoid doing this addref by instead making
--- a/xpcom/glue/nsCOMPtr.h
+++ b/xpcom/glue/nsCOMPtr.h
@@ -113,16 +113,22 @@
     // ...otherwise, just strip it out of the code
   #define NSCAP_LOG_ASSIGNMENT(this, ptr)
 #endif
 
 #ifndef NSCAP_LOG_RELEASE
   #define NSCAP_LOG_RELEASE(this, ptr)
 #endif
 
+namespace mozilla {
+
+struct unused_t;
+
+} // namespace mozilla
+
 template <class T>
 struct already_AddRefed
     /*
       ...cooperates with |nsCOMPtr| to allow you to assign in a pointer _without_
       |AddRef|ing it.  You might want to use this as a return type from a function
       that produces an already |AddRef|ed pointer as a result.
 
       See also |getter_AddRefs()|, |dont_AddRef()|, and |class nsGetterAddRefs|.
@@ -151,17 +157,43 @@ struct already_AddRefed
     }
 
     already_AddRefed( T* aRawPtr )
       : mRawPtr(aRawPtr)
     {
       // nothing else to do here
     }
 
-    T* take() const { return mRawPtr; }
+    already_AddRefed(const already_AddRefed<T>& aOther)
+      : mRawPtr(aOther.take())
+    {
+      // nothing else to do here
+    }
+
+    ~already_AddRefed()
+    {
+      MOZ_ASSERT(!mRawPtr);
+    }
+
+    // Specialize the unused operator<< for already_AddRefed, to allow
+    // nsCOMPtr<nsIFoo> foo;
+    // unused << foo.forget();
+    friend void operator<<(const mozilla::unused_t& unused,
+                                         const already_AddRefed<T>& rhs)
+    {
+      auto mutableAlreadyAddRefed = const_cast<already_AddRefed<T>*>(&rhs);
+      unused << mutableAlreadyAddRefed->take();
+    }
+
+    T* take()
+    {
+      T* rawPtr = mRawPtr;
+      mRawPtr = nullptr;
+      return rawPtr;
+    }
 
     /**
      * This helper is useful in cases like
      *
      *  already_AddRefed<BaseClass>
      *  Foo()
      *  {
      *    nsRefPtr<SubClass> x = ...;