Bug 1438541 P2 Make nsIGlobalObject::GetOrCreateServiceWorker() use the DOMEventTargetHelper list stored on the global. r=smaug
authorBen Kelly <ben@wanderview.com>
Wed, 21 Feb 2018 10:53:52 -0800
changeset 404682 9a2fc66acc13134ec5025fa65ed226e196e30a2e
parent 404681 a1d30eced092547c59253e12383fee05c0284b04
child 404683 26cad18f73fa3286a302abd18d648e2f577a26f0
push id100067
push userbkelly@mozilla.com
push dateWed, 21 Feb 2018 18:54:01 +0000
treeherdermozilla-inbound@5675db58f9e9 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs1438541
milestone60.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 1438541 P2 Make nsIGlobalObject::GetOrCreateServiceWorker() use the DOMEventTargetHelper list stored on the global. r=smaug
dom/base/nsGlobalWindowInner.cpp
dom/base/nsGlobalWindowInner.h
dom/base/nsIGlobalObject.cpp
dom/base/nsIGlobalObject.h
dom/serviceworkers/ServiceWorker.cpp
dom/serviceworkers/ServiceWorker.h
--- a/dom/base/nsGlobalWindowInner.cpp
+++ b/dom/base/nsGlobalWindowInner.cpp
@@ -6347,44 +6347,36 @@ nsGlobalWindowInner::GetController() con
   return Move(controller);
 }
 
 RefPtr<ServiceWorker>
 nsGlobalWindowInner::GetOrCreateServiceWorker(const ServiceWorkerDescriptor& aDescriptor)
 {
   MOZ_ASSERT(NS_IsMainThread());
   RefPtr<ServiceWorker> ref;
-  for (auto sw : mServiceWorkerList) {
-    if (sw->Descriptor().Matches(aDescriptor)) {
-      ref = sw;
-      return ref.forget();
-    }
-  }
-  ref = ServiceWorker::Create(this, aDescriptor);
+  ForEachEventTargetObject([&] (DOMEventTargetHelper* aTarget) {
+    // TODO: allow short-cuts
+    if (ref) {
+      return;
+    }
+
+    RefPtr<ServiceWorker> sw = do_QueryObject(aTarget);
+    if (!sw || !sw->Descriptor().Matches(aDescriptor)) {
+      return;
+    }
+    ref = sw.forget();
+  });
+
+  if (!ref) {
+    ref = ServiceWorker::Create(this, aDescriptor);
+  }
+
   return ref.forget();
 }
 
-void
-nsGlobalWindowInner::AddServiceWorker(ServiceWorker* aServiceWorker)
-{
-  MOZ_ASSERT(NS_IsMainThread());
-  MOZ_DIAGNOSTIC_ASSERT(aServiceWorker);
-  MOZ_ASSERT(!mServiceWorkerList.Contains(aServiceWorker));
-  mServiceWorkerList.AppendElement(aServiceWorker);
-}
-
-void
-nsGlobalWindowInner::RemoveServiceWorker(ServiceWorker* aServiceWorker)
-{
-  MOZ_ASSERT(NS_IsMainThread());
-  MOZ_DIAGNOSTIC_ASSERT(aServiceWorker);
-  MOZ_ASSERT(mServiceWorkerList.Contains(aServiceWorker));
-  mServiceWorkerList.RemoveElement(aServiceWorker);
-}
-
 nsresult
 nsGlobalWindowInner::FireDelayedDOMEvents()
 {
   if (mApplicationCache) {
     static_cast<nsDOMOfflineResourceList*>(mApplicationCache.get())->FirePendingEvents();
   }
 
   // Fires an offline status event if the offline status has changed
--- a/dom/base/nsGlobalWindowInner.h
+++ b/dom/base/nsGlobalWindowInner.h
@@ -346,22 +346,16 @@ public:
 
   mozilla::Maybe<mozilla::dom::ClientInfo> GetClientInfo() const override;
   mozilla::Maybe<mozilla::dom::ClientState> GetClientState() const;
   mozilla::Maybe<mozilla::dom::ServiceWorkerDescriptor> GetController() const override;
 
   virtual RefPtr<mozilla::dom::ServiceWorker>
   GetOrCreateServiceWorker(const mozilla::dom::ServiceWorkerDescriptor& aDescriptor) override;
 
-  virtual void
-  AddServiceWorker(mozilla::dom::ServiceWorker* aServiceWorker) override;
-
-  virtual void
-  RemoveServiceWorker(mozilla::dom::ServiceWorker* aServiceWorker) override;
-
   void NoteCalledRegisterForServiceWorkerScope(const nsACString& aScope);
 
   virtual nsresult FireDelayedDOMEvents() override;
 
   virtual nsresult SetNewDocument(nsIDocument *aDocument,
                                   nsISupports *aState,
                                   bool aForceReuseInnerWindow) override;
 
@@ -1439,20 +1433,16 @@ protected:
   RefPtr<mozilla::dom::VREventObserver> mVREventObserver;
 
   int64_t mBeforeUnloadListenerCount;
 
   RefPtr<mozilla::dom::IntlUtils> mIntlUtils;
 
   mozilla::UniquePtr<mozilla::dom::ClientSource> mClientSource;
 
-  // Weak references added by AddServiceWorker() and cleared by
-  // RemoveServiceWorker() when the ServiceWorker is destroyed.
-  nsTArray<mozilla::dom::ServiceWorker*> mServiceWorkerList;
-
   nsTArray<RefPtr<mozilla::dom::Promise>> mPendingPromises;
 
   static InnerWindowByIdTable* sInnerWindowsById;
 
   // Members in the mChromeFields member should only be used in chrome windows.
   // All accesses to this field should be guarded by a check of mIsChrome.
   struct ChromeFields {
     ChromeFields()
--- a/dom/base/nsIGlobalObject.cpp
+++ b/dom/base/nsIGlobalObject.cpp
@@ -187,27 +187,15 @@ nsIGlobalObject::GetController() const
 
 RefPtr<ServiceWorker>
 nsIGlobalObject::GetOrCreateServiceWorker(const ServiceWorkerDescriptor& aDescriptor)
 {
   MOZ_DIAGNOSTIC_ASSERT(false, "this global should not have any service workers");
   return nullptr;
 }
 
-void
-nsIGlobalObject::AddServiceWorker(ServiceWorker* aServiceWorker)
-{
-  MOZ_DIAGNOSTIC_ASSERT(false, "this global should not have any service workers");
-}
-
-void
-nsIGlobalObject::RemoveServiceWorker(ServiceWorker* aServiceWorker)
-{
-  MOZ_DIAGNOSTIC_ASSERT(false, "this global should not have any service workers");
-}
-
 size_t
 nsIGlobalObject::ShallowSizeOfExcludingThis(MallocSizeOf aSizeOf) const
 {
   size_t rtn = mHostObjectURIs.ShallowSizeOfExcludingThis(aSizeOf);
   rtn += mEventTargetObjects.ShallowSizeOfExcludingThis(aSizeOf);
   return rtn;
 }
--- a/dom/base/nsIGlobalObject.h
+++ b/dom/base/nsIGlobalObject.h
@@ -114,26 +114,16 @@ public:
   virtual mozilla::Maybe<mozilla::dom::ServiceWorkerDescriptor>
   GetController() const;
 
   // Get the DOM object for the given descriptor or attempt to create one.
   // Creation can still fail and return nullptr during shutdown, etc.
   virtual RefPtr<mozilla::dom::ServiceWorker>
   GetOrCreateServiceWorker(const mozilla::dom::ServiceWorkerDescriptor& aDescriptor);
 
-  // These methods allow the ServiceWorker instances to note their existence
-  // so that the global can use weak references to them.  The global should
-  // not hold a strong reference to the ServiceWorker.
-  virtual void
-  AddServiceWorker(mozilla::dom::ServiceWorker* aServiceWorker);
-
-  // This method must be called by the ServiceWorker before it is destroyed.
-  virtual void
-  RemoveServiceWorker(mozilla::dom::ServiceWorker* aServiceWorker);
-
 protected:
   virtual ~nsIGlobalObject();
 
   void
   StartDying()
   {
     mIsDying = true;
   }
--- a/dom/serviceworkers/ServiceWorker.cpp
+++ b/dom/serviceworkers/ServiceWorker.cpp
@@ -71,36 +71,31 @@ ServiceWorker::ServiceWorker(nsIGlobalOb
   : DOMEventTargetHelper(aGlobal)
   , mDescriptor(aDescriptor)
   , mInner(aInner)
 {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_DIAGNOSTIC_ASSERT(aGlobal);
   MOZ_DIAGNOSTIC_ASSERT(mInner);
 
-  aGlobal->AddServiceWorker(this);
-
   // This will update our state too.
   mInner->AddServiceWorker(this);
 }
 
 ServiceWorker::~ServiceWorker()
 {
   MOZ_ASSERT(NS_IsMainThread());
   mInner->RemoveServiceWorker(this);
-  nsIGlobalObject* global = GetParentObject();
-  if (global) {
-    global->RemoveServiceWorker(this);
-  }
 }
 
 NS_IMPL_ADDREF_INHERITED(ServiceWorker, DOMEventTargetHelper)
 NS_IMPL_RELEASE_INHERITED(ServiceWorker, DOMEventTargetHelper)
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(ServiceWorker)
+  NS_INTERFACE_MAP_ENTRY(ServiceWorker)
 NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
 
 JSObject*
 ServiceWorker::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   return ServiceWorkerBinding::Wrap(aCx, this, aGivenProto);
@@ -146,17 +141,13 @@ const ServiceWorkerDescriptor&
 ServiceWorker::Descriptor() const
 {
   return mDescriptor;
 }
 
 void
 ServiceWorker::DisconnectFromOwner()
 {
-  nsIGlobalObject* global = GetParentObject();
-  if (global) {
-    global->RemoveServiceWorker(this);
-  }
   DOMEventTargetHelper::DisconnectFromOwner();
 }
 
 } // namespace dom
 } // namespace mozilla
--- a/dom/serviceworkers/ServiceWorker.h
+++ b/dom/serviceworkers/ServiceWorker.h
@@ -15,16 +15,19 @@
 #undef PostMessage
 #endif
 
 class nsIGlobalObject;
 
 namespace mozilla {
 namespace dom {
 
+#define NS_DOM_SERVICEWORKER_IID \
+  {0xd42e0611, 0x3647, 0x4319, {0xae, 0x05, 0x19, 0x89, 0x59, 0xba, 0x99, 0x5e}}
+
 bool
 ServiceWorkerVisible(JSContext* aCx, JSObject* aObj);
 
 class ServiceWorker final : public DOMEventTargetHelper
 {
 public:
   // Abstract interface for the internal representation of the
   // ServiceWorker object.
@@ -54,16 +57,17 @@ public:
     PostMessage(nsIGlobalObject* aGlobal,
                 JSContext* aCx, JS::Handle<JS::Value> aMessage,
                 const Sequence<JSObject*>& aTransferable,
                 ErrorResult& aRv) = 0;
 
     NS_INLINE_DECL_PURE_VIRTUAL_REFCOUNTING
   };
 
+  NS_DECLARE_STATIC_IID_ACCESSOR(NS_DOM_SERVICEWORKER_IID)
   NS_DECL_ISUPPORTS_INHERITED
 
   IMPL_EVENT_HANDLER(statechange)
   IMPL_EVENT_HANDLER(error)
 
   static already_AddRefed<ServiceWorker>
   Create(nsIGlobalObject* aOwner, const ServiceWorkerDescriptor& aDescriptor);
 
@@ -96,12 +100,14 @@ private:
 
   // This class is reference-counted and will be destroyed from Release().
   ~ServiceWorker();
 
   ServiceWorkerDescriptor mDescriptor;
   const RefPtr<Inner> mInner;
 };
 
+NS_DEFINE_STATIC_IID_ACCESSOR(ServiceWorker, NS_DOM_SERVICEWORKER_IID)
+
 } // namespace dom
 } // namespace mozilla
 
 #endif // mozilla_dom_serviceworker_h__