Bug 1443954 - Part 3: Add support for RefCounted types to IPDL, r=bz,froydnj,baku
authorNika Layzell <nika@thelayzells.com>
Tue, 06 Mar 2018 20:14:59 -0500
changeset 412763 7f79db23bc0f589ca508a9d03370bd7ef3cb554c
parent 412762 c313243cda55d8922e487f201b1cf3891b99b8bb
child 412764 390bb0f184d19261975b88f403801209f00e108e
push id33818
push userapavel@mozilla.com
push dateWed, 11 Apr 2018 14:36:40 +0000
treeherdermozilla-central@cfe6399e142c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbz, froydnj, baku
bugs1443954
milestone61.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 1443954 - Part 3: Add support for RefCounted types to IPDL, r=bz,froydnj,baku This patch was reviewed in parts, however the intermediate states would not build: Bug 1443954 - Part 3A: Strip pointers from the argument to WriteParam and WriteIPDLParam before selecting the ParamTraits impl, r=froydnj Bug 1443954 - Part 3B: Move nsIAlertNotification serialization to the refcounted system, r=bz Bug 1443954 - Part 3C: Move geolocation serialization to the refcounted system, r=bz Bug 1443954 - Part 3D: Move nsIInputStream serialization to the refcounted system, r=baku Bug 1443954 - Part 3E: Move BlobImpl serialization to the refcounted system, r=baku Bug 1443954 - Part 3F: Correctly implement ParamTraits for actors after the ParamTraits changes, r=froydnj
docshell/base/nsDefaultURIFixup.cpp
dom/cache/CacheStreamControlChild.cpp
dom/cache/PCacheStreamControl.ipdl
dom/file/ipc/IPCBlobUtils.cpp
dom/file/ipc/IPCBlobUtils.h
dom/geolocation/nsGeoPositionIPCSerialiser.h
dom/html/HTMLInputElement.cpp
dom/ipc/ContentChild.cpp
dom/ipc/ContentChild.h
dom/ipc/ContentParent.cpp
dom/ipc/ContentParent.h
dom/ipc/PContent.ipdl
dom/plugins/ipc/PluginMessageUtils.h
ipc/chromium/src/chrome/common/ipc_message_utils.h
ipc/glue/IPCStreamUtils.cpp
ipc/glue/IPCStreamUtils.h
ipc/glue/IPDLParamTraits.h
ipc/ipdl/ipdl/lower.py
layout/base/PresState.ipdlh
netwerk/ipc/PNecko.ipdl
netwerk/protocol/res/ExtensionProtocolHandler.cpp
toolkit/components/alerts/AlertNotificationIPCSerializer.h
--- a/docshell/base/nsDefaultURIFixup.cpp
+++ b/docshell/base/nsDefaultURIFixup.cpp
@@ -416,17 +416,17 @@ nsDefaultURIFixup::KeywordToURI(const ns
   keyword.Trim(" ");
 
   if (XRE_IsContentProcess()) {
     dom::ContentChild* contentChild = dom::ContentChild::GetSingleton();
     if (!contentChild) {
       return NS_ERROR_NOT_AVAILABLE;
     }
 
-    nsCOMPtr<nsIInputStream> postData;
+    RefPtr<nsIInputStream> postData;
     ipc::OptionalURIParams uri;
     nsAutoString providerName;
     if (!contentChild->SendKeywordToURI(keyword, &providerName, &postData,
                                         &uri)) {
       return NS_ERROR_FAILURE;
     }
 
     CopyUTF8toUTF16(keyword, info->mKeywordAsSent);
--- a/dom/cache/CacheStreamControlChild.cpp
+++ b/dom/cache/CacheStreamControlChild.cpp
@@ -120,17 +120,17 @@ CacheStreamControlChild::OpenStream(cons
   // If we are on a worker, then we need to hold it alive until the async
   // IPC operation below completes.  While the IPC layer will trigger a
   // rejection here in many cases, we must handle the case where the
   // MozPromise resolve runnable is already in the event queue when the
   // worker wants to shut down.
   RefPtr<CacheWorkerHolder> holder = GetWorkerHolder();
 
   SendOpenStream(aId)->Then(GetCurrentThreadSerialEventTarget(), __func__,
-  [aResolver, holder](const nsCOMPtr<nsIInputStream>& aOptionalStream) {
+  [aResolver, holder](const RefPtr<nsIInputStream>& aOptionalStream) {
     aResolver(nsCOMPtr<nsIInputStream>(aOptionalStream));
   }, [aResolver, holder](ResponseRejectReason aReason) {
     aResolver(nullptr);
   });
 }
 
 void
 CacheStreamControlChild::NoteClosedAfterForget(const nsID& aId)
--- a/dom/cache/PCacheStreamControl.ipdl
+++ b/dom/cache/PCacheStreamControl.ipdl
@@ -3,28 +3,28 @@
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 include protocol PBackground;
 include protocol PFileDescriptorSet;
 include protocol PChildToParentStream;
 include protocol PParentToChildStream;
 
 using struct nsID from "nsID.h";
-using nsCOMPtr<nsIInputStream> from "mozilla/ipc/IPCStreamUtils.h";
+using refcounted class nsIInputStream from "mozilla/ipc/IPCStreamUtils.h";
 
 namespace mozilla {
 namespace dom {
 namespace cache {
 
 protocol PCacheStreamControl
 {
   manager PBackground;
 
 parent:
-  async OpenStream(nsID aStreamId) returns(nsCOMPtr<nsIInputStream> aStream);
+  async OpenStream(nsID aStreamId) returns(nsIInputStream aStream);
   async NoteClosed(nsID aStreamId);
 
 child:
   async Close(nsID aStreamId);
   async CloseAll();
   async __delete__();
 };
 
--- a/dom/file/ipc/IPCBlobUtils.cpp
+++ b/dom/file/ipc/IPCBlobUtils.cpp
@@ -299,35 +299,35 @@ SerializeUntyped(BlobImpl* aBlobImpl, IP
   }
 }
 
 } // IPCBlobUtils namespace
 } // dom namespace
 
 namespace ipc {
 void
-IPDLParamTraits<RefPtr<mozilla::dom::BlobImpl>>::Write(
+IPDLParamTraits<mozilla::dom::BlobImpl>::Write(
   IPC::Message* aMsg, IProtocol* aActor,
-  const RefPtr<mozilla::dom::BlobImpl>& aParam)
+  mozilla::dom::BlobImpl* aParam)
 {
   nsresult rv;
   mozilla::dom::IPCBlob ipcblob;
   if (aParam) {
     rv = mozilla::dom::IPCBlobUtils::SerializeUntyped(aParam, aActor, ipcblob);
   }
   if (!aParam || NS_WARN_IF(NS_FAILED(rv))) {
     WriteIPDLParam(aMsg, aActor, false);
   } else {
     WriteIPDLParam(aMsg, aActor, true);
     WriteIPDLParam(aMsg, aActor, ipcblob);
   }
 }
 
 bool
-IPDLParamTraits<RefPtr<mozilla::dom::BlobImpl>>::Read(
+IPDLParamTraits<mozilla::dom::BlobImpl>::Read(
   const IPC::Message* aMsg, PickleIterator* aIter,
   IProtocol* aActor, RefPtr<mozilla::dom::BlobImpl>* aResult)
 {
   *aResult = nullptr;
 
   bool notnull = false;
   if (!ReadIPDLParam(aMsg, aIter, aActor, &notnull)) {
     return false;
--- a/dom/file/ipc/IPCBlobUtils.h
+++ b/dom/file/ipc/IPCBlobUtils.h
@@ -222,20 +222,16 @@ class PBackgroundParent;
 namespace dom {
 
 class IPCBlob;
 class nsIContentChild;
 class nsIContentParent;
 
 namespace IPCBlobUtils {
 
-// Typedef for use within ipdl files, as the full type cannot be written
-// currently.
-typedef RefPtr<BlobImpl> BlobImplPtr;
-
 already_AddRefed<BlobImpl>
 Deserialize(const IPCBlob& aIPCBlob);
 
 // These 4 methods serialize aBlobImpl into aIPCBlob using the right manager.
 
 nsresult
 Serialize(BlobImpl* aBlobImpl, nsIContentChild* aManager, IPCBlob& aIPCBlob);
 
@@ -259,19 +255,19 @@ SerializeUntyped(BlobImpl* aBlobImpl, mo
 } // dom namespace
 
 namespace ipc {
 // ParamTraits implementation for BlobImpl. N.B: If the original BlobImpl cannot
 // be successfully serialized, a warning will be produced and a nullptr will be
 // sent over the wire. When Read()-ing a BlobImpl,
 // __always make sure to handle null!__
 template<>
-struct IPDLParamTraits<RefPtr<mozilla::dom::BlobImpl>>
+struct IPDLParamTraits<mozilla::dom::BlobImpl>
 {
   static void Write(IPC::Message* aMsg, IProtocol* aActor,
-                    const RefPtr<mozilla::dom::BlobImpl>& aParam);
+                    mozilla::dom::BlobImpl* aParam);
   static bool Read(const IPC::Message* aMsg, PickleIterator* aIter,
                    IProtocol* aActor, RefPtr<mozilla::dom::BlobImpl>* aResult);
 };
 } // ipc namespace
 } // mozilla namespace
 
 #endif // mozilla_dom_IPCBlobUtils_h
--- a/dom/geolocation/nsGeoPositionIPCSerialiser.h
+++ b/dom/geolocation/nsGeoPositionIPCSerialiser.h
@@ -6,27 +6,23 @@
 
 #ifndef dom_src_geolocation_IPC_serialiser
 #define dom_src_geolocation_IPC_serialiser
 
 #include "ipc/IPCMessageUtils.h"
 #include "nsGeoPosition.h"
 #include "nsIDOMGeoPosition.h"
 
-typedef nsIDOMGeoPosition* GeoPosition;
-
 namespace IPC {
 
 template <>
-struct ParamTraits<nsIDOMGeoPositionCoords*>
+struct ParamTraits<nsIDOMGeoPositionCoords>
 {
-  typedef nsIDOMGeoPositionCoords* paramType;
-
   // Function to serialize a geoposition
-  static void Write(Message *aMsg, const paramType& aParam)
+  static void Write(Message *aMsg, nsIDOMGeoPositionCoords* aParam)
   {
     bool isNull = !aParam;
     WriteParam(aMsg, isNull);
     // If it is a null object, then we are done
     if (isNull) return;
 
     double coordData;
 
@@ -48,24 +44,25 @@ struct ParamTraits<nsIDOMGeoPositionCoor
     aParam->GetHeading(&coordData);
     WriteParam(aMsg, coordData);
 
     aParam->GetSpeed(&coordData);
     WriteParam(aMsg, coordData);
   }
 
   // Function to de-serialize a geoposition
-  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter,
+                   RefPtr<nsIDOMGeoPositionCoords>* aResult)
   {
     // Check if it is the null pointer we have transfered
     bool isNull;
     if (!ReadParam(aMsg, aIter, &isNull)) return false;
 
     if (isNull) {
-      *aResult = 0;
+      *aResult = nullptr;
       return true;
     }
 
     double latitude;
     double longitude;
     double altitude;
     double accuracy;
     double altitudeAccuracy;
@@ -86,62 +83,59 @@ struct ParamTraits<nsIDOMGeoPositionCoor
                                        longitude,        /* aLong    */
                                        altitude,         /* aAlt     */
                                        accuracy,         /* aHError  */
                                        altitudeAccuracy, /* aVError  */
                                        heading,          /* aHeading */
                                        speed             /* aSpeed   */
                                       );
     return true;
-
   }
 
 };
 
 template <>
-struct ParamTraits<nsIDOMGeoPosition*>
+struct ParamTraits<nsIDOMGeoPosition>
 {
-  typedef nsIDOMGeoPosition* paramType;
-
   // Function to serialize a geoposition
-  static void Write(Message *aMsg, const paramType& aParam)
+  static void Write(Message *aMsg, nsIDOMGeoPosition* aParam)
   {
     bool isNull = !aParam;
     WriteParam(aMsg, isNull);
     // If it is a null object, then we are done
     if (isNull) return;
 
     DOMTimeStamp timeStamp;
     aParam->GetTimestamp(&timeStamp);
     WriteParam(aMsg, timeStamp);
 
     nsCOMPtr<nsIDOMGeoPositionCoords> coords;
     aParam->GetCoords(getter_AddRefs(coords));
-    WriteParam(aMsg, coords.get());
+    WriteParam(aMsg, coords);
   }
 
   // Function to de-serialize a geoposition
-  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter,
+                   RefPtr<nsIDOMGeoPosition>* aResult)
   {
     // Check if it is the null pointer we have transfered
     bool isNull;
     if (!ReadParam(aMsg, aIter, &isNull)) return false;
 
     if (isNull) {
-      *aResult = 0;
+      *aResult = nullptr;
       return true;
     }
 
     DOMTimeStamp timeStamp;
-    nsIDOMGeoPositionCoords* coords = nullptr;
+    RefPtr<nsIDOMGeoPositionCoords> coords;
 
     // It's not important to us where it fails, but rather if it fails
     if (!ReadParam(aMsg, aIter, &timeStamp) ||
         !ReadParam(aMsg, aIter, &coords)) {
-      nsCOMPtr<nsIDOMGeoPositionCoords> tmpcoords = coords;
       return false;
     }
 
     *aResult = new nsGeoPosition(coords, timeStamp);
 
     return true;
   };
 
--- a/dom/html/HTMLInputElement.cpp
+++ b/dom/html/HTMLInputElement.cpp
@@ -6509,23 +6509,23 @@ HTMLInputElement::RemoveStates(EventStat
 }
 
 static nsTArray<OwningFileOrDirectory>
 RestoreFileContentData(nsPIDOMWindowInner* aWindow,
                        const nsTArray<FileContentData>& aData)
 {
   nsTArray<OwningFileOrDirectory> res(aData.Length());
   for (auto& it : aData) {
-    if (it.type() == FileContentData::TBlobImplPtr) {
-      if (!it.get_BlobImplPtr()) {
+    if (it.type() == FileContentData::TBlobImpl) {
+      if (!it.get_BlobImpl()) {
         // Serialization failed, skip this file.
         continue;
       }
 
-      RefPtr<File> file = File::Create(aWindow, it.get_BlobImplPtr());
+      RefPtr<File> file = File::Create(aWindow, it.get_BlobImpl());
       MOZ_ASSERT(file);
 
       OwningFileOrDirectory* element = res.AppendElement();
       element->SetAsFile() = file;
     } else {
       MOZ_ASSERT(it.type() == FileContentData::TnsString);
       nsCOMPtr<nsIFile> file;
       nsresult rv = NS_NewLocalFile(it.get_nsString(), true,
--- a/dom/ipc/ContentChild.cpp
+++ b/dom/ipc/ContentChild.cpp
@@ -2530,25 +2530,24 @@ ContentChild::RecvAsyncMessage(const nsS
     ipc::UnpackClonedMessageDataForChild(aData, data);
     cpm->ReceiveMessage(cpm, nullptr, aMsg, false, &data, &cpows, aPrincipal, nullptr,
                         IgnoreErrors());
   }
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult
-ContentChild::RecvGeolocationUpdate(const GeoPosition& somewhere)
+ContentChild::RecvGeolocationUpdate(nsIDOMGeoPosition* aPosition)
 {
   nsCOMPtr<nsIGeolocationUpdate> gs =
     do_GetService("@mozilla.org/geolocation/service;1");
   if (!gs) {
     return IPC_OK();
   }
-  nsCOMPtr<nsIDOMGeoPosition> position = somewhere;
-  gs->Update(position);
+  gs->Update(aPosition);
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult
 ContentChild::RecvGeolocationError(const uint16_t& errorCode)
 {
   nsCOMPtr<nsIGeolocationUpdate> gs =
     do_GetService("@mozilla.org/geolocation/service;1");
--- a/dom/ipc/ContentChild.h
+++ b/dom/ipc/ContentChild.h
@@ -387,17 +387,17 @@ public:
 
   virtual mozilla::ipc::IPCResult RecvLoadProcessScript(const nsString& aURL) override;
 
   virtual mozilla::ipc::IPCResult RecvAsyncMessage(const nsString& aMsg,
                                                    InfallibleTArray<CpowEntry>&& aCpows,
                                                    const IPC::Principal& aPrincipal,
                                                    const ClonedMessageData& aData) override;
 
-  virtual mozilla::ipc::IPCResult RecvGeolocationUpdate(const GeoPosition& somewhere) override;
+  virtual mozilla::ipc::IPCResult RecvGeolocationUpdate(nsIDOMGeoPosition* aPosition) override;
 
   virtual mozilla::ipc::IPCResult RecvGeolocationError(const uint16_t& errorCode) override;
 
   virtual mozilla::ipc::IPCResult RecvUpdateDictionaryList(InfallibleTArray<nsString>&& aDictionaries) override;
 
   virtual mozilla::ipc::IPCResult RecvUpdateFontList(InfallibleTArray<SystemFontListEntry>&& aFontList) override;
 
   virtual mozilla::ipc::IPCResult RecvUpdateAppLocales(nsTArray<nsCString>&& aAppLocales) override;
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -3760,34 +3760,29 @@ ContentParent::RecvExtProtocolChannelCon
 
 bool
 ContentParent::HasNotificationPermission(const IPC::Principal& aPrincipal)
 {
   return true;
 }
 
 mozilla::ipc::IPCResult
-ContentParent::RecvShowAlert(const AlertNotificationType& aAlert)
-{
-  nsCOMPtr<nsIAlertNotification> alert(dont_AddRef(aAlert));
-  if (NS_WARN_IF(!alert)) {
-    return IPC_OK();
-  }
-
+ContentParent::RecvShowAlert(nsIAlertNotification* aAlert)
+{
   nsCOMPtr<nsIPrincipal> principal;
-  nsresult rv = alert->GetPrincipal(getter_AddRefs(principal));
+  nsresult rv = aAlert->GetPrincipal(getter_AddRefs(principal));
   if (NS_WARN_IF(NS_FAILED(rv)) ||
       !HasNotificationPermission(IPC::Principal(principal))) {
 
       return IPC_OK();
   }
 
   nsCOMPtr<nsIAlertsService> sysAlerts(do_GetService(NS_ALERTSERVICE_CONTRACTID));
   if (sysAlerts) {
-      sysAlerts->ShowAlert(alert, this);
+      sysAlerts->ShowAlert(aAlert, this);
   }
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult
 ContentParent::RecvCloseAlert(const nsString& aName,
                               const IPC::Principal& aPrincipal)
 {
@@ -3907,17 +3902,17 @@ ContentParent::RecvSetGeolocationHigherA
     mGeolocationWatchID = AddGeolocationListener(this, this, aEnable);
   }
   return IPC_OK();
 }
 
 NS_IMETHODIMP
 ContentParent::HandleEvent(nsIDOMGeoPosition* postion)
 {
-  Unused << SendGeolocationUpdate(GeoPosition(postion));
+  Unused << SendGeolocationUpdate(postion);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 ContentParent::HandleEvent(nsIDOMGeoPositionError* postionError)
 {
   int16_t errorCode;
   nsresult rv;
@@ -4119,17 +4114,17 @@ ContentParent::SendPBrowserConstructor(P
                                                  aChromeFlags,
                                                  aCpId,
                                                  aIsForBrowser);
 }
 
 mozilla::ipc::IPCResult
 ContentParent::RecvKeywordToURI(const nsCString& aKeyword,
                                 nsString* aProviderName,
-                                nsCOMPtr<nsIInputStream>* aPostData,
+                                RefPtr<nsIInputStream>* aPostData,
                                 OptionalURIParams* aURI)
 {
   *aPostData = nullptr;
   *aURI = void_t();
 
   nsCOMPtr<nsIURIFixup> fixup = do_GetService(NS_URIFIXUP_CONTRACTID);
   if (!fixup) {
     return IPC_OK();
--- a/dom/ipc/ContentParent.h
+++ b/dom/ipc/ContentParent.h
@@ -1009,17 +1009,17 @@ private:
                                                const OptionalURIParams& referrer,
                                                const uint32_t& flags) override;
 
   virtual mozilla::ipc::IPCResult RecvSetURITitle(const URIParams& uri,
                                                   const nsString& title) override;
 
   bool HasNotificationPermission(const IPC::Principal& aPrincipal);
 
-  virtual mozilla::ipc::IPCResult RecvShowAlert(const AlertNotificationType& aAlert) override;
+  virtual mozilla::ipc::IPCResult RecvShowAlert(nsIAlertNotification* aAlert) override;
 
   virtual mozilla::ipc::IPCResult RecvCloseAlert(const nsString& aName,
                                                  const IPC::Principal& aPrincipal) override;
 
   virtual mozilla::ipc::IPCResult RecvDisableNotifications(const IPC::Principal& aPrincipal) override;
 
   virtual mozilla::ipc::IPCResult RecvOpenNotificationSettings(const IPC::Principal& aPrincipal) override;
 
@@ -1086,17 +1086,17 @@ public:
   virtual mozilla::ipc::IPCResult RecvPrivateDocShellsExist(const bool& aExist) override;
 
   virtual mozilla::ipc::IPCResult RecvFirstIdle() override;
 
   virtual mozilla::ipc::IPCResult RecvDeviceReset() override;
 
   virtual mozilla::ipc::IPCResult RecvKeywordToURI(const nsCString& aKeyword,
                                                    nsString* aProviderName,
-                                                   nsCOMPtr<nsIInputStream>* aPostData,
+                                                   RefPtr<nsIInputStream>* aPostData,
                                                    OptionalURIParams* aURI) override;
 
   virtual mozilla::ipc::IPCResult RecvNotifyKeywordSearchLoading(const nsString &aProvider,
                                                                  const nsString &aKeyword) override;
 
   virtual mozilla::ipc::IPCResult RecvCopyFavicon(const URIParams& aOldURI,
                                                   const URIParams& aNewURI,
                                                   const IPC::Principal& aLoadingPrincipal,
--- a/dom/ipc/PContent.ipdl
+++ b/dom/ipc/PContent.ipdl
@@ -61,18 +61,18 @@ include MemoryReportTypes;
 include ClientIPCTypes;
 include HangTypes;
 
 // Workaround to prevent error if PContentChild.cpp & PContentBridgeParent.cpp
 // are put into different UnifiedProtocolsXX.cpp files.
 // XXX Remove this once bug 1069073 is fixed
 include "mozilla/dom/PContentBridgeParent.h";
 
-using GeoPosition from "nsGeoPositionIPCSerialiser.h";
-using AlertNotificationType from "mozilla/AlertNotificationIPCSerializer.h";
+using refcounted class nsIDOMGeoPosition from "nsGeoPositionIPCSerialiser.h";
+using refcounted class nsIAlertNotification from "mozilla/AlertNotificationIPCSerializer.h";
 
 using struct ChromePackage from "mozilla/chrome/RegistryMessageUtils.h";
 using struct SubstitutionMapping from "mozilla/chrome/RegistryMessageUtils.h";
 using struct OverrideMapping from "mozilla/chrome/RegistryMessageUtils.h";
 using base::ProcessId from "base/process.h";
 using struct IPC::Permission from "mozilla/net/NeckoMessageUtils.h";
 using class IPC::Principal from "mozilla/dom/PermissionMessageUtils.h";
 using struct mozilla::null_t from "ipc/IPCMessageUtils.h";
@@ -94,17 +94,17 @@ using mozilla::layers::LayersId from "mo
 using mozilla::Telemetry::HistogramAccumulation from "mozilla/TelemetryComms.h";
 using mozilla::Telemetry::KeyedHistogramAccumulation from "mozilla/TelemetryComms.h";
 using mozilla::Telemetry::ScalarAction from "mozilla/TelemetryComms.h";
 using mozilla::Telemetry::KeyedScalarAction from "mozilla/TelemetryComms.h";
 using mozilla::Telemetry::DynamicScalarDefinition from "mozilla/TelemetryComms.h";
 using mozilla::Telemetry::ChildEventData from "mozilla/TelemetryComms.h";
 using mozilla::Telemetry::DiscardedData from "mozilla/TelemetryComms.h";
 using mozilla::CrossProcessMutexHandle from "mozilla/ipc/CrossProcessMutex.h";
-using nsCOMPtr<nsIInputStream> from "mozilla/ipc/IPCStreamUtils.h";
+using refcounted class nsIInputStream from "mozilla/ipc/IPCStreamUtils.h";
 
 union ChromeRegistryItem
 {
     ChromePackage;
     OverrideMapping;
     SubstitutionMapping;
 };
 
@@ -439,17 +439,17 @@ child:
     async VarUpdate(GfxVarUpdate var);
 
     async DataStoragePut(nsString aFilename, DataStorageItem aItem);
     async DataStorageRemove(nsString aFilename, nsCString aKey, DataStorageType aType);
     async DataStorageClear(nsString aFilename);
 
     async NotifyAlertsObserver(nsCString topic, nsString data);
 
-    async GeolocationUpdate(GeoPosition somewhere);
+    async GeolocationUpdate(nsIDOMGeoPosition aPosition);
 
     async GeolocationError(uint16_t errorCode);
 
     async UpdateDictionaryList(nsString[] dictionaries);
 
     async UpdateFontList(SystemFontListEntry[] fontList);
 
     async UpdateAppLocales(nsCString[] appLocales);
@@ -800,17 +800,17 @@ parent:
     sync SyncMessage(nsString aMessage, ClonedMessageData aData,
                      CpowEntry[] aCpows, Principal aPrincipal)
       returns (StructuredCloneData[] retval);
 
     nested(inside_sync) sync RpcMessage(nsString aMessage, ClonedMessageData aData,
                                         CpowEntry[] aCpows, Principal aPrincipal)
       returns (StructuredCloneData[] retval);
 
-    async ShowAlert(AlertNotificationType alert);
+    async ShowAlert(nsIAlertNotification alert);
 
     async CloseAlert(nsString name, Principal principal);
 
     async DisableNotifications(Principal principal);
 
     async OpenNotificationSettings(Principal principal);
 
     async PPSMContentDownloader(uint32_t aCertType);
@@ -879,17 +879,17 @@ parent:
     async PrivateDocShellsExist(bool aExist);
 
     // Tell the parent that the child has gone idle for the first time.
     async FirstIdle();
 
     async DeviceReset();
 
     sync KeywordToURI(nsCString keyword)
-        returns (nsString providerName, nsCOMPtr<nsIInputStream> postData, OptionalURIParams uri);
+        returns (nsString providerName, nsIInputStream postData, OptionalURIParams uri);
 
     sync NotifyKeywordSearchLoading(nsString providerName, nsString keyword);
 
     async CopyFavicon(URIParams oldURI, URIParams newURI, Principal aLoadingPrincipal, bool isPrivate);
 
     // Tell the compositor to allocate a layer tree id for nested remote mozbrowsers.
     sync AllocateLayerTreeId(ContentParentId cpId, TabId tabId)
         returns (LayersId id);
--- a/dom/plugins/ipc/PluginMessageUtils.h
+++ b/dom/plugins/ipc/PluginMessageUtils.h
@@ -403,23 +403,21 @@ struct ParamTraits<mozilla::plugins::NPR
                               (unsigned long)aParam.window,
                               aParam.x, aParam.y, aParam.width,
                               aParam.height, (long)aParam.type));
   }
 };
 
 #ifdef XP_MACOSX
 template <>
-struct ParamTraits<NPNSString*>
+struct ParamTraits<NPNSString>
 {
-  typedef NPNSString* paramType;
-
   // Empty string writes a length of 0 and no buffer.
   // We don't write a nullptr terminating character in buffers.
-  static void Write(Message* aMsg, const paramType& aParam)
+  static void Write(Message* aMsg, NPNSString* aParam)
   {
     CFStringRef cfString = (CFStringRef)aParam;
 
     // Write true if we have a string, false represents nullptr.
     aMsg->WriteBool(!!cfString);
     if (!cfString) {
       return;
     }
@@ -436,17 +434,17 @@ struct ParamTraits<NPNSString*>
     } else {
       UniChar *buffer = (UniChar*)moz_xmalloc(length * sizeof(UniChar));
       ::CFStringGetCharacters(cfString, ::CFRangeMake(0, length), buffer);
       aMsg->WriteBytes(buffer, length * sizeof(UniChar));
       free(buffer);
     }
   }
 
-  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, NPNSString** aResult)
   {
     bool haveString = false;
     if (!aMsg->ReadBool(aIter, &haveString)) {
       return false;
     }
     if (!haveString) {
       *aResult = nullptr;
       return true;
--- a/ipc/chromium/src/chrome/common/ipc_message_utils.h
+++ b/ipc/chromium/src/chrome/common/ipc_message_utils.h
@@ -16,16 +16,19 @@
 #include "base/string16.h"
 #include "base/time.h"
 
 #if defined(OS_POSIX)
 #include "chrome/common/file_descriptor_set_posix.h"
 #endif
 #include "chrome/common/ipc_message.h"
 
+template<typename T> class RefPtr;
+template<typename T> class nsCOMPtr;
+
 namespace IPC {
 
 //-----------------------------------------------------------------------------
 // An iterator class for reading the fields contained within a Message.
 
 class MessageIterator {
  public:
   explicit MessageIterator(const Message& m) : msg_(m), iter_(m) {
@@ -100,35 +103,55 @@ class MessageIterator {
 //
 // The scheme we follow below names the various classes according to the types
 // in them, and the number of ParamTraits levels is larger, but otherwise it's
 // exactly the above idea.
 //
 
 template <class P> struct ParamTraits;
 
-template <class P>
-static inline void WriteParam(Message* m, const P& p) {
-  ParamTraits<P>::Write(m, p);
-}
+// When WriteParam or ReadParam is passed a pointer type like RefPtr<T> or T*,
+// we want to invoke Write() on ParamTraits<T>, as the intype is often T*, while
+// the ReadParam type may be RefPtr<T>.
+namespace detail {
+template<typename T>
+struct StripPointers{ typedef T Type; };
+template<typename T>
+struct StripPointers<T*> { typedef T Type; };
+template<typename T>
+struct StripPointers<RefPtr<T>> { typedef T Type; };
+template<typename T>
+struct StripPointers<nsCOMPtr<T>> { typedef T Type; };
+} // namespace detail
 
-template <class P>
-static inline void WriteParam(Message* m, P& p) {
-  ParamTraits<P>::Write(m, p);
+// NOTE: This helper is also used in IPDLParamTraits.h
+template<typename T>
+struct ParamTraitsSelector
+  : public detail::StripPointers<typename mozilla::Decay<T>::Type>
+{};
+
+template<typename P>
+static inline void
+WriteParam(Message* m, P&& p) {
+  ParamTraits<typename ParamTraitsSelector<P>::Type>
+    ::Write(m, mozilla::Forward<P>(p));
 }
 
-template <class P>
-static inline bool WARN_UNUSED_RESULT ReadParam(const Message* m, PickleIterator* iter,
-                                                P* p) {
-  return ParamTraits<P>::Read(m, iter, p);
+template<typename P>
+static inline bool WARN_UNUSED_RESULT
+ReadParam(const Message* m, PickleIterator* iter,
+          P* p)
+{
+  return ParamTraits<typename ParamTraitsSelector<P>::Type>::Read(m, iter, p);
 }
 
-template <class P>
-static inline void LogParam(const P& p, std::wstring* l) {
-  ParamTraits<P>::Log(p, l);
+template<typename P>
+static inline void
+LogParam(const P& p, std::wstring* l) {
+  ParamTraits<typename ParamTraitsSelector<P>::Type>::Log(p, l);
 }
 
 // Fundamental types.
 
 template <class P>
 struct ParamTraitsFundamental {};
 
 template <>
@@ -387,42 +410,46 @@ struct ParamTraitsStd<std::map<K, V> > {
 };
 
 // Windows-specific types.
 
 template <class P>
 struct ParamTraitsWindows : ParamTraitsStd<P> {};
 
 #if defined(OS_WIN)
+// NOTE: HANDLE is a pointer, which we need to strip off, otherwise we won't find
+// this specialization.
 template <>
-struct ParamTraitsWindows<HANDLE> {
-  typedef HANDLE param_type;
-  static void Write(Message* m, const param_type& p) {
+struct ParamTraitsWindows<detail::StripPointers<HANDLE>::Type> {
+  static_assert(sizeof(HANDLE) == sizeof(intptr_t), "Wrong size for HANDLE?");
+
+  static void Write(Message* m, HANDLE p) {
     m->WriteIntPtr(reinterpret_cast<intptr_t>(p));
   }
-  static bool Read(const Message* m, PickleIterator* iter, param_type* r) {
-    DCHECK_EQ(sizeof(param_type), sizeof(intptr_t));
+  static bool Read(const Message* m, PickleIterator* iter, HANDLE* r) {
     return m->ReadIntPtr(iter, reinterpret_cast<intptr_t*>(r));
   }
-  static void Log(const param_type& p, std::wstring* l) {
+  static void Log(const HANDLE& p, std::wstring* l) {
     l->append(StringPrintf(L"0x%X", p));
   }
 };
 
+// NOTE: HWND is a pointer, which we need to strip off, otherwise we won't find
+// this specialization.
 template <>
-struct ParamTraitsWindows<HWND> {
-  typedef HWND param_type;
-  static void Write(Message* m, const param_type& p) {
+struct ParamTraitsWindows<detail::StripPointers<HWND>::Type> {
+  static_assert(sizeof(HWND) == sizeof(intptr_t), "Wrong size for HWND?");
+
+  static void Write(Message* m, HWND p) {
     m->WriteIntPtr(reinterpret_cast<intptr_t>(p));
   }
-  static bool Read(const Message* m, PickleIterator* iter, param_type* r) {
-    DCHECK_EQ(sizeof(param_type), sizeof(intptr_t));
+  static bool Read(const Message* m, PickleIterator* iter, HWND* r) {
     return m->ReadIntPtr(iter, reinterpret_cast<intptr_t*>(r));
   }
-  static void Log(const param_type& p, std::wstring* l) {
+  static void Log(const HWND& p, std::wstring* l) {
     l->append(StringPrintf(L"0x%X", p));
   }
 };
 #endif  // defined(OS_WIN)
 
 // Various ipc/chromium types.
 
 template <class P>
--- a/ipc/glue/IPCStreamUtils.cpp
+++ b/ipc/glue/IPCStreamUtils.cpp
@@ -621,19 +621,19 @@ AutoIPCStream::TakeOptionalValue()
   MOZ_ASSERT(!mValue);
   MOZ_ASSERT(mOptionalValue);
   mTaken = true;
   AssertValidValueToTake(*mOptionalValue);
   return *mOptionalValue;
 }
 
 void
-IPDLParamTraits<nsCOMPtr<nsIInputStream>>::Write(IPC::Message* aMsg,
-                                                 IProtocol* aActor,
-                                                 const nsCOMPtr<nsIInputStream>& aParam)
+IPDLParamTraits<nsIInputStream>::Write(IPC::Message* aMsg,
+                                       IProtocol* aActor,
+                                       nsIInputStream* aParam)
 {
   mozilla::ipc::AutoIPCStream autoStream;
   bool ok = false;
   bool found = false;
 
   // We can only serialize our nsIInputStream if it's going to be sent over one
   // of the protocols we support, or a protocol which is managed by one of the
   // protocols we support.
@@ -672,18 +672,18 @@ IPDLParamTraits<nsCOMPtr<nsIInputStream>
     aActor->FatalError("Attempt to send nsIInputStream over an unsupported ipdl protocol");
   }
   MOZ_RELEASE_ASSERT(ok, "Failed to serialize nsIInputStream");
 
   WriteIPDLParam(aMsg, aActor, autoStream.TakeOptionalValue());
 }
 
 bool
-IPDLParamTraits<nsCOMPtr<nsIInputStream>>::Read(const IPC::Message* aMsg, PickleIterator* aIter,
-                                                IProtocol* aActor, nsCOMPtr<nsIInputStream>* aResult)
+IPDLParamTraits<nsIInputStream>::Read(const IPC::Message* aMsg, PickleIterator* aIter,
+                                      IProtocol* aActor, RefPtr<nsIInputStream>* aResult)
 {
   mozilla::ipc::OptionalIPCStream ipcStream;
   if (!ReadIPDLParam(aMsg, aIter, aActor, &ipcStream)) {
     return false;
   }
 
   *aResult = mozilla::ipc::DeserializeIPCStream(ipcStream);
   return true;
--- a/ipc/glue/IPCStreamUtils.h
+++ b/ipc/glue/IPCStreamUtils.h
@@ -184,22 +184,20 @@ public:
 
 private:
   AutoIPCStream(const AutoIPCStream& aOther) = delete;
   AutoIPCStream& operator=(const AutoIPCStream& aOther) = delete;
   AutoIPCStream& operator=(const AutoIPCStream&& aOther) = delete;
 };
 
 template<>
-struct IPDLParamTraits<nsCOMPtr<nsIInputStream>>
+struct IPDLParamTraits<nsIInputStream>
 {
-  typedef nsCOMPtr<nsIInputStream> paramType;
-
   static void Write(IPC::Message* aMsg, IProtocol* aActor,
-                    const paramType& aParam);
+                    nsIInputStream* aParam);
   static bool Read(const IPC::Message* aMsg, PickleIterator* aIter,
-                   IProtocol* aActor, paramType* aResult);
+                   IProtocol* aActor, RefPtr<nsIInputStream>* aResult);
 };
 
 } // namespace ipc
 } // namespace mozilla
 
 #endif // mozilla_ipc_IPCStreamUtils_h
--- a/ipc/glue/IPDLParamTraits.h
+++ b/ipc/glue/IPDLParamTraits.h
@@ -20,28 +20,31 @@ class IProtocol;
 // All types which already implement ParamTraits also support IPDLParamTraits.
 //
 template<typename P>
 struct IPDLParamTraits
 {
   // This is the default impl which discards the actor parameter and calls into
   // ParamTraits. Types which want to use the actor parameter must specialize
   // IPDLParamTraits.
-  static inline void Write(IPC::Message* aMsg, IProtocol*, const P& aParam) {
-    IPC::ParamTraits<P>::Write(aMsg, aParam);
-  }
-  // Some types which implement ParamTraits require non-const references, as
-  // they move their data into the IPC layer. This overload supports these
-  // types.
-  static inline void Write(IPC::Message* aMsg, IProtocol*, P& aParam) {
-    IPC::ParamTraits<P>::Write(aMsg, aParam);
+  template<typename R>
+  static inline void Write(IPC::Message* aMsg, IProtocol*, R&& aParam)
+  {
+    static_assert(IsSame<P, typename IPC::ParamTraitsSelector<R>::Type>::value,
+                  "IPDLParamTraits::Write only forwards calls which work via WriteParam");
+
+    IPC::ParamTraits<P>::Write(aMsg, Forward<R>(aParam));
   }
 
+  template<typename R>
   static inline bool Read(const IPC::Message* aMsg, PickleIterator* aIter,
-                          IProtocol*, P* aResult) {
+                          IProtocol*, R* aResult) {
+    static_assert(IsSame<P, typename IPC::ParamTraitsSelector<R>::Type>::value,
+                  "IPDLParamTraits::Read only forwards calls which work via ReadParam");
+
     return IPC::ParamTraits<P>::Read(aMsg, aIter, aResult);
   }
 };
 
 //
 // WriteIPDLParam and ReadIPDLParam are like IPC::WriteParam and IPC::ReadParam,
 // however, they also accept an extra actor argument, and use IPDLParamTraits
 // rather than ParamTraits.
@@ -52,27 +55,29 @@ struct IPDLParamTraits
 // more information.
 //
 template<typename P>
 static inline void
 WriteIPDLParam(IPC::Message* aMsg,
                IProtocol* aActor,
                P&& aParam)
 {
-  IPDLParamTraits<typename Decay<P>::Type>::Write(aMsg, aActor, Forward<P>(aParam));
+  IPDLParamTraits<typename IPC::ParamTraitsSelector<P>::Type>
+    ::Write(aMsg, aActor, Forward<P>(aParam));
 }
 
 template<typename P>
 static inline bool
 ReadIPDLParam(const IPC::Message* aMsg,
               PickleIterator* aIter,
               IProtocol* aActor,
               P* aResult)
 {
-  return IPDLParamTraits<P>::Read(aMsg, aIter, aActor, aResult);
+  return IPDLParamTraits<typename IPC::ParamTraitsSelector<P>::Type>
+    ::Read(aMsg, aIter, aActor, aResult);
 }
 
 // nsTArray support for IPDLParamTraits
 template<typename T>
 struct IPDLParamTraits<nsTArray<T>>
 {
   static inline void Write(IPC::Message* aMsg, IProtocol* aActor,
                            const nsTArray<T>& aParam) {
--- a/ipc/ipdl/ipdl/lower.py
+++ b/ipc/ipdl/ipdl/lower.py
@@ -1887,18 +1887,22 @@ class _ParamTraits():
             errfn=errfn,
             paramtype=what,
             sentinelKey=sentinelKey,
             errfnSentinel=errfnSentinel(),
             actor=cls.actor)
 
     @classmethod
     def generateDecl(cls, fortype, write, read, constin=1):
+        # IPDLParamTraits impls are selected ignoring constness, references,
+        # and pointers.
         pt = Class('IPDLParamTraits',
-                   specializes=fortype,
+                   specializes=Type(fortype.name,
+                                    T=fortype.T,
+                                    inner=fortype.inner),
                    struct=True)
 
         # typedef T paramType;
         pt.addstmt(Typedef(fortype, 'paramType'))
 
         iprotocoltype = Type('mozilla::ipc::IProtocol', ptr=1)
 
         # static void Write(Message*, const T&);
--- a/layout/base/PresState.ipdlh
+++ b/layout/base/PresState.ipdlh
@@ -1,31 +1,31 @@
 /* -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 8 -*- */
 /* vim: set sw=2 ts=8 et tw=80 ft=cpp : */
 /* 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/. */
 
 using mozilla::void_t from "ipc/IPCMessageUtils.h";
 using nsPoint from "mozilla/GfxMessageUtils.h";
-using mozilla::dom::IPCBlobUtils::BlobImplPtr from "mozilla/dom/IPCBlobUtils.h";
+using refcounted class mozilla::dom::BlobImpl from "mozilla/dom/IPCBlobUtils.h";
 
 namespace mozilla {
 
 struct SelectContentData {
   uint32_t[] indices;
   nsString[] values;
 };
 
 struct CheckedContentData {
   bool checked;
 };
 
 union FileContentData {
-  BlobImplPtr;
+  BlobImpl;
   nsString;
 };
 
 union PresContentData {
   void_t;
   nsString;
   SelectContentData;
   CheckedContentData;
--- a/netwerk/ipc/PNecko.ipdl
+++ b/netwerk/ipc/PNecko.ipdl
@@ -31,17 +31,17 @@ include IPCStream;
 include URIParams;
 include NeckoChannelParams;
 include PBrowserOrId;
 include protocol PAltDataOutputStream;
 
 using class IPC::SerializedLoadContext from "SerializedLoadContext.h";
 using mozilla::dom::TabId from "mozilla/dom/ipc/IdType.h";
 using class IPC::Principal from "mozilla/dom/PermissionMessageUtils.h";
-using nsCOMPtr<nsIInputStream> from "mozilla/ipc/IPCStreamUtils.h";
+using refcounted class nsIInputStream from "mozilla/ipc/IPCStreamUtils.h";
 
 namespace mozilla {
 namespace net {
 
 //-------------------------------------------------------------------
 nested(upto inside_cpow) sync protocol PNecko
 {
   manager PContent;
@@ -123,17 +123,17 @@ parent:
 
   async PAltDataOutputStream(nsCString type, PHttpChannel channel);
 
   async PStunAddrsRequest();
 
   /**
    * WebExtension-specific remote resource loading
    */
-  async GetExtensionStream(URIParams uri) returns (nsCOMPtr<nsIInputStream> stream);
+  async GetExtensionStream(URIParams uri) returns (nsIInputStream stream);
   async GetExtensionFD(URIParams uri) returns (FileDescriptor fd);
 
 child:
   /*
    * Bring up the http auth prompt for a nested remote mozbrowser.
    * NestedFrameId is the id corresponding to the PBrowser.  It is the same id
    * that was passed to the PBrowserOrId param in to the PHttpChannel constructor
    */
--- a/netwerk/protocol/res/ExtensionProtocolHandler.cpp
+++ b/netwerk/protocol/res/ExtensionProtocolHandler.cpp
@@ -234,17 +234,17 @@ ExtensionStreamGetter::GetAsync(nsIStrea
     );
     return Ok();
   }
 
   // Request an input stream for this moz-extension URI
   gNeckoChild->SendGetExtensionStream(uri)->Then(
     mMainThreadEventTarget,
     __func__,
-    [self] (const nsCOMPtr<nsIInputStream>& stream) {
+    [self] (const RefPtr<nsIInputStream>& stream) {
       self->OnStream(do_AddRef(stream));
     },
     [self] (const mozilla::ipc::ResponseRejectReason) {
       self->OnStream(nullptr);
     }
   );
   return Ok();
 }
--- a/toolkit/components/alerts/AlertNotificationIPCSerializer.h
+++ b/toolkit/components/alerts/AlertNotificationIPCSerializer.h
@@ -10,26 +10,22 @@
 #include "nsIAlertsService.h"
 #include "nsIPrincipal.h"
 #include "nsString.h"
 
 #include "ipc/IPCMessageUtils.h"
 
 #include "mozilla/dom/PermissionMessageUtils.h"
 
-typedef nsIAlertNotification* AlertNotificationType;
-
 namespace IPC {
 
 template <>
-struct ParamTraits<AlertNotificationType>
+struct ParamTraits<nsIAlertNotification>
 {
-  typedef AlertNotificationType paramType;
-
-  static void Write(Message* aMsg, const paramType& aParam)
+  static void Write(Message* aMsg, nsIAlertNotification* aParam)
   {
     bool isNull = !aParam;
     if (isNull) {
       WriteParam(aMsg, isNull);
       return;
     }
 
     nsString name, imageURL, title, text, cookie, dir, lang, data;
@@ -65,17 +61,17 @@ struct ParamTraits<AlertNotificationType
     WriteParam(aMsg, dir);
     WriteParam(aMsg, lang);
     WriteParam(aMsg, data);
     WriteParam(aMsg, IPC::Principal(principal));
     WriteParam(aMsg, inPrivateBrowsing);
     WriteParam(aMsg, requireInteraction);
   }
 
-  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
+  static bool Read(const Message* aMsg, PickleIterator* aIter, RefPtr<nsIAlertNotification>* aResult)
   {
     bool isNull;
     NS_ENSURE_TRUE(ReadParam(aMsg, aIter, &isNull), false);
     if (isNull) {
       *aResult = nullptr;
       return true;
     }
 
@@ -107,16 +103,16 @@ struct ParamTraits<AlertNotificationType
     }
     nsresult rv = alert->Init(name, imageURL, title, text, textClickable,
                               cookie, dir, lang, data, principal,
                               inPrivateBrowsing, requireInteraction);
     if (NS_WARN_IF(NS_FAILED(rv))) {
       *aResult = nullptr;
       return true;
     }
-    alert.forget(aResult);
+    *aResult = alert.forget();
     return true;
   }
 };
 
 } // namespace IPC
 
 #endif /* mozilla_AlertNotificationIPCSerializer_h__ */