Bug 1597481 - upgrade heap-allocated MessagePortParent*s to CheckedUnsafePtr<MessagePortParent> r=asuth a=RyanVM DEVEDITION_72_0b8_BUILD1 DEVEDITION_72_0b8_RELEASE FIREFOX_72_0b8_BUILD1 FIREFOX_72_0b8_RELEASE
authorPerry Jiang <perry@mozilla.com>
Mon, 16 Dec 2019 23:07:14 +0000
changeset 566874 d54b88a700c047f6f0c7a680290df1eebb899f4f
parent 566873 efdba899f9cfa29e8903dfdfee9f0bf70a78a074
child 566875 520ff618bd590af9091d3546caa3af77d7ee4571
push id12440
push useraiakab@mozilla.com
push dateWed, 18 Dec 2019 03:35:33 +0000
treeherdermozilla-beta@d54b88a700c0 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersasuth, RyanVM
bugs1597481
milestone72.0
Bug 1597481 - upgrade heap-allocated MessagePortParent*s to CheckedUnsafePtr<MessagePortParent> r=asuth a=RyanVM Differential Revision: https://phabricator.services.mozilla.com/D54649
dom/messagechannel/MessagePortParent.h
dom/messagechannel/MessagePortService.cpp
dom/messagechannel/MessagePortService.h
--- a/dom/messagechannel/MessagePortParent.h
+++ b/dom/messagechannel/MessagePortParent.h
@@ -3,23 +3,26 @@
 /* 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/. */
 
 #ifndef mozilla_dom_MessagePortParent_h
 #define mozilla_dom_MessagePortParent_h
 
 #include "mozilla/dom/PMessagePortParent.h"
+#include "mozilla/dom/quota/CheckedUnsafePtr.h"
 
 namespace mozilla {
 namespace dom {
 
 class MessagePortService;
 
-class MessagePortParent final : public PMessagePortParent {
+class MessagePortParent final
+    : public PMessagePortParent,
+      public SupportsCheckedUnsafePtr<CheckIf<DiagnosticAssertEnabled>> {
   friend class PMessagePortParent;
 
  public:
   explicit MessagePortParent(const nsID& aUUID);
   ~MessagePortParent();
 
   bool Entangle(const nsID& aDestinationUUID, const uint32_t& aSequenceID);
 
--- a/dom/messagechannel/MessagePortService.cpp
+++ b/dom/messagechannel/MessagePortService.cpp
@@ -2,16 +2,17 @@
 /* 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 "MessagePortService.h"
 #include "MessagePortParent.h"
 #include "SharedMessagePortMessage.h"
+#include "mozilla/dom/quota/CheckedUnsafePtr.h"
 #include "mozilla/ipc/BackgroundParent.h"
 #include "mozilla/StaticPtr.h"
 #include "mozilla/Unused.h"
 #include "nsTArray.h"
 
 using mozilla::ipc::AssertIsOnBackgroundThread;
 
 namespace mozilla {
@@ -22,16 +23,33 @@ namespace {
 StaticRefPtr<MessagePortService> gInstance;
 
 void AssertIsInMainProcess() {
   MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
 }
 
 }  // namespace
 
+struct MessagePortService::NextParent {
+  uint32_t mSequenceID;
+  // MessagePortParent keeps the service alive, and we don't want a cycle.
+  CheckedUnsafePtr<MessagePortParent> mParent;
+};
+
+}  // namespace dom
+}  // namespace mozilla
+
+// Need to call CheckedUnsafePtr's copy constructor and destructor when
+// resizing dynamic arrays containing NextParent (by calling NextParent's
+// implicit copy constructor/destructor rather than memmove-ing NextParents).
+DECLARE_USE_COPY_CONSTRUCTORS(mozilla::dom::MessagePortService::NextParent);
+
+namespace mozilla {
+namespace dom {
+
 class MessagePortService::MessagePortServiceData final {
  public:
   explicit MessagePortServiceData(const nsID& aDestinationUUID)
       : mDestinationUUID(aDestinationUUID),
         mSequenceID(1),
         mParent(nullptr)
         // By default we don't know the next parent.
         ,
@@ -43,23 +61,17 @@ class MessagePortService::MessagePortSer
   MessagePortServiceData(const MessagePortServiceData& aOther) = delete;
   MessagePortServiceData& operator=(const MessagePortServiceData&) = delete;
 
   ~MessagePortServiceData() { MOZ_COUNT_DTOR(MessagePortServiceData); }
 
   nsID mDestinationUUID;
 
   uint32_t mSequenceID;
-  MessagePortParent* mParent;
-
-  struct NextParent {
-    uint32_t mSequenceID;
-    // MessagePortParent keeps the service alive, and we don't want a cycle.
-    MessagePortParent* mParent;
-  };
+  CheckedUnsafePtr<MessagePortParent> mParent;
 
   FallibleTArray<NextParent> mNextParents;
   FallibleTArray<RefPtr<SharedMessagePortMessage>> mMessages;
 
   bool mWaitingForNewParent;
   bool mNextStepCloseAll;
 };
 
@@ -155,18 +167,17 @@ bool MessagePortService::RequestEntangli
       CloseAll(aParent->ID());
     }
 
     return true;
   }
 
   // This new parent will be the next one when a Disentangle request is
   // received from the current parent.
-  MessagePortServiceData::NextParent* nextParent =
-      data->mNextParents.AppendElement(mozilla::fallible);
+  auto nextParent = data->mNextParents.AppendElement(mozilla::fallible);
   if (!nextParent) {
     CloseAll(aParent->ID());
     return false;
   }
 
   nextParent->mSequenceID = aSequenceID;
   nextParent->mParent = aParent;
 
@@ -260,19 +271,20 @@ void MessagePortService::CloseAll(const 
   MessagePortServiceData* data;
   if (!mPorts.Get(aUUID, &data)) {
     MaybeShutdown();
     return;
   }
 
   if (data->mParent) {
     data->mParent->Close();
+    data->mParent = nullptr;
   }
 
-  for (const MessagePortServiceData::NextParent& parent : data->mNextParents) {
+  for (const auto& parent : data->mNextParents) {
     parent.mParent->CloseAndDelete();
   }
 
   nsID destinationUUID = data->mDestinationUUID;
 
   // If we have informations about the other port and that port has some
   // pending messages to deliver but the parent has not processed them yet,
   // because its entangling request didn't arrive yet), we cannot close this
--- a/dom/messagechannel/MessagePortService.h
+++ b/dom/messagechannel/MessagePortService.h
@@ -16,16 +16,19 @@ namespace dom {
 
 class MessagePortParent;
 class SharedMessagePortMessage;
 
 class MessagePortService final {
  public:
   NS_INLINE_DECL_REFCOUNTING(MessagePortService)
 
+  // Needs to be public for the DECLARE_USE_COPY_CONSTRUCTORS macro.
+  struct NextParent;
+
   static MessagePortService* Get();
   static MessagePortService* GetOrCreate();
 
   bool RequestEntangling(MessagePortParent* aParent,
                          const nsID& aDestinationUUID,
                          const uint32_t& aSequenceID);
 
   bool DisentanglePort(