try: -b d -p all -u all -t none
authorOlli Pettay <Olli.Pettay@helsinki.fi>
Thu, 03 May 2018 22:22:22 +0300
changeset 1502105 bdca8795b0c0f6734a1605b90e125bdeb1999a3c
parent 1500763 2c2199bb1e91370ac0f100eaab9469109f4ac7fc
child 1623876 88594986c0f3098d5fe0f43973c66161bbd3ae60
push id269128
push useropettay@mozilla.com
push dateThu, 03 May 2018 19:23:22 +0000
treeherdertry@bdca8795b0c0 [default view] [failures only]
milestone61.0a1
try: -b d -p all -u all -t none
dom/animation/AnimationTimeline.cpp
dom/animation/DocumentTimeline.cpp
dom/base/nsDocument.cpp
dom/base/nsIGlobalObject.cpp
dom/base/nsIGlobalObject.h
dom/events/DOMEventTargetHelper.h
layout/base/nsPresContext.cpp
layout/style/MediaQueryList.cpp
--- a/dom/animation/AnimationTimeline.cpp
+++ b/dom/animation/AnimationTimeline.cpp
@@ -43,16 +43,16 @@ AnimationTimeline::NotifyAnimationUpdate
     mAnimationOrder.insertBack(&aAnimation);
   }
 }
 
 void
 AnimationTimeline::RemoveAnimation(Animation* aAnimation)
 {
   MOZ_ASSERT(!aAnimation->GetTimeline() || aAnimation->GetTimeline() == this);
-  if (aAnimation->isInList()) {
-    aAnimation->remove();
+  if (static_cast<LinkedListElement<Animation>*>(aAnimation)->isInList()) {
+    static_cast<LinkedListElement<Animation>*>(aAnimation)->remove();
   }
   mAnimations.RemoveEntry(aAnimation);
 }
 
 } // namespace dom
 } // namespace mozilla
--- a/dom/animation/DocumentTimeline.cpp
+++ b/dom/animation/DocumentTimeline.cpp
@@ -162,17 +162,18 @@ DocumentTimeline::WillRefresh(mozilla::T
   // Note that this should be done before nsAutoAnimationMutationBatch.  If
   // PerformMicroTaskCheckpoint was called before nsAutoAnimationMutationBatch
   // is destroyed, some mutation records might not be delivered in this
   // checkpoint.
   nsAutoMicroTask mt;
   nsAutoAnimationMutationBatch mb(mDocument);
 
   for (Animation* animation = mAnimationOrder.getFirst(); animation;
-       animation = animation->getNext()) {
+       animation =
+         static_cast<LinkedListElement<Animation>*>(animation)->getNext()) {
     // Skip any animations that are longer need associated with this timeline.
     if (animation->GetTimeline() != this) {
       // If animation has some other timeline, it better not be also in the
       // animation list of this timeline object!
       MOZ_ASSERT(!animation->GetTimeline());
       animationsToRemove.AppendElement(animation);
       continue;
     }
--- a/dom/base/nsDocument.cpp
+++ b/dom/base/nsDocument.cpp
@@ -1954,17 +1954,18 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_
     }
   }
 
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCSSLoader)
 
   // We own only the items in mDOMMediaQueryLists that have listeners;
   // this reference is managed by their AddListener and RemoveListener
   // methods.
-  for (auto mql : tmp->mDOMMediaQueryLists) {
+  for (MediaQueryList* mql = tmp->mDOMMediaQueryLists.getFirst(); mql;
+       mql = static_cast<LinkedListElement<MediaQueryList>*>(mql)->getNext()) {
     if (mql->HasListeners()) {
       NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mDOMMediaQueryLists item");
       cb.NoteXPCOMChild(mql);
     }
   }
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(nsDocument)
@@ -2074,17 +2075,18 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(ns
     tmp->mCSSLoader->DropDocumentReference();
     NS_IMPL_CYCLE_COLLECTION_UNLINK(mCSSLoader)
   }
 
   // We own only the items in mDOMMediaQueryLists that have listeners;
   // this reference is managed by their AddListener and RemoveListener
   // methods.
   for (MediaQueryList* mql = tmp->mDOMMediaQueryLists.getFirst(); mql;) {
-    MediaQueryList* next = mql->getNext();
+    MediaQueryList* next =
+      static_cast<LinkedListElement<MediaQueryList>*>(mql)->getNext();
     mql->Disconnect();
     mql = next;
   }
 
   tmp->mInUnlinkOrDeletion = false;
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 nsresult
--- a/dom/base/nsIGlobalObject.cpp
+++ b/dom/base/nsIGlobalObject.cpp
@@ -20,17 +20,17 @@ using mozilla::dom::ServiceWorker;
 using mozilla::dom::ServiceWorkerDescriptor;
 using mozilla::dom::ServiceWorkerRegistration;
 using mozilla::dom::ServiceWorkerRegistrationDescriptor;
 
 nsIGlobalObject::~nsIGlobalObject()
 {
   UnlinkHostObjectURIs();
   DisconnectEventTargetObjects();
-  MOZ_DIAGNOSTIC_ASSERT(mEventTargetObjects.IsEmpty());
+  MOZ_DIAGNOSTIC_ASSERT(mEventTargetObjects.isEmpty());
 }
 
 nsIPrincipal*
 nsIGlobalObject::PrincipalOrNull()
 {
   JSObject *global = GetGlobalJSObject();
   if (NS_WARN_IF(!global))
     return nullptr;
@@ -126,45 +126,47 @@ nsIGlobalObject::TraverseHostObjectURIs(
     nsHostObjectProtocolHandler::Traverse(mHostObjectURIs[index], aCb);
   }
 }
 
 void
 nsIGlobalObject::AddEventTargetObject(DOMEventTargetHelper* aObject)
 {
   MOZ_DIAGNOSTIC_ASSERT(aObject);
-  MOZ_ASSERT(!mEventTargetObjects.Contains(aObject));
-  mEventTargetObjects.PutEntry(aObject);
+  MOZ_ASSERT(!aObject->isInList());
+  mEventTargetObjects.insertBack(aObject);
 }
 
 void
 nsIGlobalObject::RemoveEventTargetObject(DOMEventTargetHelper* aObject)
 {
   MOZ_DIAGNOSTIC_ASSERT(aObject);
-  MOZ_ASSERT(mEventTargetObjects.Contains(aObject));
-  mEventTargetObjects.RemoveEntry(aObject);
+  MOZ_ASSERT(aObject->isInList());
+  MOZ_ASSERT(aObject->GetOwnerGlobal() == this);
+  aObject->remove();
 }
 
 void
 nsIGlobalObject::ForEachEventTargetObject(const std::function<void(DOMEventTargetHelper*, bool* aDoneOut)>& aFunc) const
 {
-  // Protect against the function call triggering a mutation of the hash table
+  // Protect against the function call triggering a mutation of the list
   // while we are iterating by copying the DETH references to a temporary
   // list.
   AutoTArray<DOMEventTargetHelper*, 64> targetList;
-  for (auto iter = mEventTargetObjects.ConstIter(); !iter.Done(); iter.Next()) {
-    targetList.AppendElement(iter.Get()->GetKey());
+  for (const DOMEventTargetHelper* deth = mEventTargetObjects.getFirst();
+       deth; deth = deth->getNext()) {
+    targetList.AppendElement(const_cast<DOMEventTargetHelper*>(deth));
   }
 
   // Iterate the target list and call the function on each one.
   bool done = false;
   for (auto target : targetList) {
     // Check to see if a previous iteration's callback triggered the removal
     // of this target as a side-effect.  If it did, then just ignore it.
-    if (!mEventTargetObjects.Contains(target)) {
+    if (target->GetOwnerGlobal() != this) {
       continue;
     }
     aFunc(target, &done);
     if (done) {
       break;
     }
   }
 }
@@ -172,17 +174,17 @@ nsIGlobalObject::ForEachEventTargetObjec
 void
 nsIGlobalObject::DisconnectEventTargetObjects()
 {
   ForEachEventTargetObject([&] (DOMEventTargetHelper* aTarget, bool* aDoneOut) {
     aTarget->DisconnectFromOwner();
 
     // Calling DisconnectFromOwner() should result in
     // RemoveEventTargetObject() being called.
-    MOZ_DIAGNOSTIC_ASSERT(!mEventTargetObjects.Contains(aTarget));
+    MOZ_DIAGNOSTIC_ASSERT(aTarget->GetOwnerGlobal() != this);
   });
 }
 
 Maybe<ClientInfo>
 nsIGlobalObject::GetClientInfo() const
 {
   // By default globals do not expose themselves as a client.  Only real
   // window and worker globals are currently considered clients.
@@ -210,11 +212,10 @@ nsIGlobalObject::GetOrCreateServiceWorke
   MOZ_DIAGNOSTIC_ASSERT(false, "this global should not have any service worker registrations");
   return nullptr;
 }
 
 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
@@ -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/. */
 
 #ifndef nsIGlobalObject_h__
 #define nsIGlobalObject_h__
 
+#include "mozilla/LinkedList.h"
 #include "mozilla/Maybe.h"
 #include "mozilla/dom/ClientInfo.h"
 #include "mozilla/dom/DispatcherTrait.h"
 #include "mozilla/dom/ServiceWorkerDescriptor.h"
 #include "nsHashKeys.h"
 #include "nsISupports.h"
 #include "nsStringFwd.h"
 #include "nsTArray.h"
@@ -36,20 +37,18 @@ class ServiceWorkerRegistrationDescripto
 } // namespace mozilla
 
 class nsIGlobalObject : public nsISupports,
                         public mozilla::dom::DispatcherTrait
 {
   nsTArray<nsCString> mHostObjectURIs;
 
   // Raw pointers to bound DETH objects.  These are added by
-  // AddEventTargetObject().  The DETH object must call
-  // RemoveEventTargetObject() before its destroyed to clear
-  // its raw pointer here.
-  nsTHashtable<nsPtrHashKey<mozilla::DOMEventTargetHelper>> mEventTargetObjects;
+  // AddEventTargetObject().
+  mozilla::LinkedList<mozilla::DOMEventTargetHelper> mEventTargetObjects;
 
   bool mIsDying;
 
 protected:
   nsIGlobalObject()
    : mIsDying(false)
   {}
 
--- a/dom/events/DOMEventTargetHelper.h
+++ b/dom/events/DOMEventTargetHelper.h
@@ -12,16 +12,17 @@
 #include "nsCycleCollectionParticipant.h"
 #include "nsPIDOMWindow.h"
 #include "nsIScriptGlobalObject.h"
 #include "nsIScriptContext.h"
 #include "nsIWeakReferenceUtils.h"
 #include "MainThreadUtils.h"
 #include "mozilla/Attributes.h"
 #include "mozilla/EventListenerManager.h"
+#include "mozilla/LinkedList.h"
 #include "mozilla/dom/EventTarget.h"
 
 struct JSCompartment;
 class nsIDocument;
 
 namespace mozilla {
 
 class ErrorResult;
@@ -29,17 +30,18 @@ class ErrorResult;
 namespace dom {
 class Event;
 } // namespace dom
 
 #define NS_DOMEVENTTARGETHELPER_IID \
 { 0xa28385c6, 0x9451, 0x4d7e, \
   { 0xa3, 0xdd, 0xf4, 0xb6, 0x87, 0x2f, 0xa4, 0x76 } }
 
-class DOMEventTargetHelper : public dom::EventTarget
+class DOMEventTargetHelper : public dom::EventTarget,
+                             public LinkedListElement<DOMEventTargetHelper>
 {
 public:
   DOMEventTargetHelper()
     : mParentObject(nullptr)
     , mOwnerWindow(nullptr)
     , mHasOrHasHadOwnerWindow(false)
     , mIsKeptAlive(false)
   {
@@ -167,17 +169,17 @@ public:
   //       DOMEventTargetHelper::BindToOwner(aOwner).
   virtual void BindToOwner(nsIGlobalObject* aOwner);
 
   void BindToOwner(nsPIDOMWindowInner* aOwner);
   void BindToOwner(DOMEventTargetHelper* aOther);
 
   virtual void DisconnectFromOwner();
   using EventTarget::GetParentObject;
-  virtual nsIGlobalObject* GetOwnerGlobal() const override
+  virtual nsIGlobalObject* GetOwnerGlobal() const final
   {
     return mParentObject;
   }
   bool HasOrHasHadOwner() { return mHasOrHasHadOwnerWindow; }
 
   virtual void EventListenerAdded(nsAtom* aType) override;
   virtual void EventListenerAdded(const nsAString& aType) override;
 
--- a/layout/base/nsPresContext.cpp
+++ b/layout/base/nsPresContext.cpp
@@ -2079,17 +2079,18 @@ nsPresContext::FlushPendingMediaFeatureV
   }
 
   // We build a list of all the notifications we're going to send
   // before we send any of them.
 
   // Copy pointers to all the lists into a new array, in case one of our
   // notifications modifies the list.
   nsTArray<RefPtr<mozilla::dom::MediaQueryList>> localMediaQueryLists;
-  for (auto* mql : mDocument->MediaQueryLists()) {
+  for (MediaQueryList* mql = mDocument->MediaQueryLists().getFirst(); mql;
+       mql = static_cast<LinkedListElement<MediaQueryList>*>(mql)->getNext()) {
     localMediaQueryLists.AppendElement(mql);
   }
 
   // Now iterate our local array of the lists.
   for (const auto& mql : localMediaQueryLists) {
     nsAutoMicroTask mt;
     mql->MaybeNotify();
   }
--- a/layout/style/MediaQueryList.cpp
+++ b/layout/style/MediaQueryList.cpp
@@ -40,17 +40,17 @@ NS_IMPL_CYCLE_COLLECTION_CLASS(MediaQuer
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(MediaQueryList,
                                                   DOMEventTargetHelper)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDocument)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(MediaQueryList,
                                                 DOMEventTargetHelper)
   if (tmp->mDocument) {
-    tmp->remove();
+    static_cast<LinkedListElement<MediaQueryList>*>(tmp)->remove();
     NS_IMPL_CYCLE_COLLECTION_UNLINK(mDocument)
   }
   tmp->Disconnect();
   NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(MediaQueryList)
 NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)