Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 26 Dec 2017 21:47:13 +0000 (UTC)
From:      Jan Beich <jbeich@FreeBSD.org>
To:        ports-committers@freebsd.org, svn-ports-all@freebsd.org, svn-ports-head@freebsd.org
Subject:   svn commit: r457317 - in head/www/waterfox: . files
Message-ID:  <201712262147.vBQLlEka011157@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: jbeich
Date: Tue Dec 26 21:47:13 2017
New Revision: 457317
URL: https://svnweb.freebsd.org/changeset/ports/457317

Log:
  www/waterfox: apply some FF58 fixes
  
  Security:	a891c5b4-3d7a-4de9-9c71-eef3fd698c77

Added:
  head/www/waterfox/files/patch-bug1224396   (contents, props changed)
  head/www/waterfox/files/patch-bug1399400   (contents, props changed)
  head/www/waterfox/files/patch-bug1399520   (contents, props changed)
  head/www/waterfox/files/patch-bug1408276   (contents, props changed)
  head/www/waterfox/files/patch-bug1409951   (contents, props changed)
  head/www/waterfox/files/patch-bug1410134   (contents, props changed)
  head/www/waterfox/files/patch-bug1412145   (contents, props changed)
  head/www/waterfox/files/patch-bug1413741   (contents, props changed)
  head/www/waterfox/files/patch-bug1414425   (contents, props changed)
  head/www/waterfox/files/patch-bug1414452   (contents, props changed)
  head/www/waterfox/files/patch-bug1414945   (contents, props changed)
  head/www/waterfox/files/patch-bug1415441   (contents, props changed)
  head/www/waterfox/files/patch-bug1415582   (contents, props changed)
  head/www/waterfox/files/patch-bug1415598   (contents, props changed)
  head/www/waterfox/files/patch-bug1417797   (contents, props changed)
  head/www/waterfox/files/patch-bug1418447   (contents, props changed)
  head/www/waterfox/files/patch-bug1418854   (contents, props changed)
  head/www/waterfox/files/patch-bug1419363   (contents, props changed)
  head/www/waterfox/files/patch-bug1422389   (contents, props changed)
  head/www/waterfox/files/patch-bug1423086   (contents, props changed)
  head/www/waterfox/files/patch-bug1423159   (contents, props changed)
  head/www/waterfox/files/patch-bug1424373   (contents, props changed)
  head/www/waterfox/files/patch-z-bug1382366   (contents, props changed)
Modified:
  head/www/waterfox/Makefile   (contents, props changed)

Modified: head/www/waterfox/Makefile
==============================================================================
--- head/www/waterfox/Makefile	Tue Dec 26 21:32:54 2017	(r457316)
+++ head/www/waterfox/Makefile	Tue Dec 26 21:47:13 2017	(r457317)
@@ -2,7 +2,7 @@
 
 PORTNAME=	waterfox
 DISTVERSION=	56.0.1.s20171212
-PORTREVISION=	1
+PORTREVISION=	2
 CATEGORIES=	www ipv6
 
 MAINTAINER=	jbeich@FreeBSD.org

Added: head/www/waterfox/files/patch-bug1224396
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/www/waterfox/files/patch-bug1224396	Tue Dec 26 21:47:13 2017	(r457317)
@@ -0,0 +1,146 @@
+commit 94f55f3a6124
+Author: Lee Salzman <lsalzman@mozilla.com>
+Date:   Wed Nov 22 12:19:29 2017 -0500
+
+    Bug 1224396 - Skia path allocation cleanups. r=msreckovic a=gchang
+    
+    MozReview-Commit-ID: GAf2vC1Fucv
+    
+    --HG--
+    extra : source : db4543ce21ce1e8a1c81b685a16e61f71db2f602
+---
+ gfx/skia/skia/include/core/SkPathRef.h  | 24 ++++++++++++++----------
+ gfx/skia/skia/src/core/SkArenaAlloc.cpp | 23 ++++++++++++++++++-----
+ gfx/skia/skia/src/core/SkArenaAlloc.h   |  5 ++++-
+ 3 files changed, 36 insertions(+), 16 deletions(-)
+
+diff --git gfx/skia/skia/include/core/SkPathRef.h gfx/skia/skia/include/core/SkPathRef.h
+index 5e6fda7d85b2..24870c64fbc0 100644
+--- gfx/skia/skia/include/core/SkPathRef.h
++++ gfx/skia/skia/include/core/SkPathRef.h
+@@ -16,7 +16,7 @@
+ #include "SkRRect.h"
+ #include "SkRect.h"
+ #include "SkRefCnt.h"
+-#include <stddef.h> // ptrdiff_t
++#include "../private/SkTemplates.h"
+ 
+ class SkRBuffer;
+ class SkWBuffer;
+@@ -433,31 +433,35 @@ private:
+      */
+     void makeSpace(size_t size) {
+         SkDEBUGCODE(this->validate();)
+-        ptrdiff_t growSize = size - fFreeSpace;
+-        if (growSize <= 0) {
++        if (size <= fFreeSpace) {
+             return;
+         }
++        size_t growSize = size - fFreeSpace;
+         size_t oldSize = this->currSize();
+         // round to next multiple of 8 bytes
+         growSize = (growSize + 7) & ~static_cast<size_t>(7);
+         // we always at least double the allocation
+-        if (static_cast<size_t>(growSize) < oldSize) {
++        if (growSize < oldSize) {
+             growSize = oldSize;
+         }
+         if (growSize < kMinSize) {
+             growSize = kMinSize;
+         }
+-        size_t newSize = oldSize + growSize;
++        constexpr size_t maxSize = std::numeric_limits<size_t>::max();
++        size_t newSize;
++        if (growSize <= maxSize - oldSize) {
++            newSize = oldSize + growSize;
++        } else {
++            SK_ABORT("Path too big.");
++        }
+         // Note that realloc could memcpy more than we need. It seems to be a win anyway. TODO:
+         // encapsulate this.
+         fPoints = reinterpret_cast<SkPoint*>(sk_realloc_throw(fPoints, newSize));
+         size_t oldVerbSize = fVerbCnt * sizeof(uint8_t);
+-        void* newVerbsDst = reinterpret_cast<void*>(
+-                                reinterpret_cast<intptr_t>(fPoints) + newSize - oldVerbSize);
+-        void* oldVerbsSrc = reinterpret_cast<void*>(
+-                                reinterpret_cast<intptr_t>(fPoints) + oldSize - oldVerbSize);
++        void* newVerbsDst = SkTAddOffset<void>(fPoints, newSize - oldVerbSize);
++        void* oldVerbsSrc = SkTAddOffset<void>(fPoints, oldSize - oldVerbSize);
+         memmove(newVerbsDst, oldVerbsSrc, oldVerbSize);
+-        fVerbs = reinterpret_cast<uint8_t*>(reinterpret_cast<intptr_t>(fPoints) + newSize);
++        fVerbs = SkTAddOffset<uint8_t>(fPoints, newSize);
+         fFreeSpace += growSize;
+         SkDEBUGCODE(this->validate();)
+     }
+diff --git gfx/skia/skia/src/core/SkArenaAlloc.cpp gfx/skia/skia/src/core/SkArenaAlloc.cpp
+index eca3aa97d761..57a19093d065 100644
+--- gfx/skia/skia/src/core/SkArenaAlloc.cpp
++++ gfx/skia/skia/src/core/SkArenaAlloc.cpp
+@@ -8,6 +8,7 @@
+ #include <algorithm>
+ #include <cstddef>
+ #include "SkArenaAlloc.h"
++#include "SkTypes.h"
+ 
+ static char* end_chain(char*) { return nullptr; }
+ 
+@@ -95,19 +96,31 @@ void SkArenaAlloc::ensureSpace(uint32_t size, uint32_t alignment) {
+     // This must be conservative to add the right amount of extra memory to handle the alignment
+     // padding.
+     constexpr uint32_t alignof_max_align_t = 8;
+-    uint32_t objSizeAndOverhead = size + headerSize + sizeof(Footer);
++    constexpr uint32_t maxSize = std::numeric_limits<uint32_t>::max();
++    constexpr uint32_t overhead = headerSize + sizeof(Footer);
++    SkASSERT_RELEASE(size <= maxSize - overhead);
++    uint32_t objSizeAndOverhead = size + overhead;
+     if (alignment > alignof_max_align_t) {
+-        objSizeAndOverhead += alignment - 1;
++        uint32_t alignmentOverhead = alignment - 1;
++        SkASSERT_RELEASE(objSizeAndOverhead <= maxSize - alignmentOverhead);
++        objSizeAndOverhead += alignmentOverhead;
+     }
+ 
+-    uint32_t allocationSize = std::max(objSizeAndOverhead, fExtraSize * fFib0);
+-    fFib0 += fFib1;
+-    std::swap(fFib0, fFib1);
++    uint32_t minAllocationSize;
++    if (fExtraSize <= maxSize / fFib0) {
++        minAllocationSize = fExtraSize * fFib0;
++        fFib0 += fFib1;
++        std::swap(fFib0, fFib1);
++    } else {
++        minAllocationSize = maxSize;
++    }
++    uint32_t allocationSize = std::max(objSizeAndOverhead, minAllocationSize);
+ 
+     // Round up to a nice size. If > 32K align to 4K boundary else up to max_align_t. The > 32K
+     // heuristic is from the JEMalloc behavior.
+     {
+         uint32_t mask = allocationSize > (1 << 15) ? (1 << 12) - 1 : 16 - 1;
++        SkASSERT_RELEASE(allocationSize <= maxSize - mask);
+         allocationSize = (allocationSize + mask) & ~mask;
+     }
+ 
+diff --git gfx/skia/skia/src/core/SkArenaAlloc.h gfx/skia/skia/src/core/SkArenaAlloc.h
+index 494696ce768d..05d3336684e9 100644
+--- gfx/skia/skia/src/core/SkArenaAlloc.h
++++ gfx/skia/skia/src/core/SkArenaAlloc.h
+@@ -157,6 +157,7 @@ private:
+     template <typename T>
+     char* commonArrayAlloc(uint32_t count) {
+         char* objStart;
++        SkASSERT_RELEASE(count <= std::numeric_limits<uint32_t>::max() / sizeof(T));
+         uint32_t arraySize = SkTo<uint32_t>(count * sizeof(T));
+         uint32_t alignment = SkTo<uint32_t>(alignof(T));
+ 
+@@ -164,7 +165,9 @@ private:
+             objStart = this->allocObject(arraySize, alignment);
+             fCursor = objStart + arraySize;
+         } else {
+-            uint32_t totalSize = arraySize + sizeof(Footer) + sizeof(uint32_t);
++            constexpr uint32_t overhead = sizeof(Footer) + sizeof(uint32_t);
++            SkASSERT_RELEASE(arraySize <= std::numeric_limits<uint32_t>::max() - overhead);
++            uint32_t totalSize = arraySize + overhead;
+             objStart = this->allocObjectWithFooter(totalSize, alignment);
+ 
+             // Can never be UB because max value is alignof(T).

Added: head/www/waterfox/files/patch-bug1399400
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/www/waterfox/files/patch-bug1399400	Tue Dec 26 21:47:13 2017	(r457317)
@@ -0,0 +1,39 @@
+commit 7c15d03b1e83
+Author: Blake Kaplan <mrbkap@gmail.com>
+Date:   Mon Dec 18 19:39:45 2017 -0500
+
+    Bug 1399400 - Use a strong reference when handling mTextField. r=bz a=jcristau
+    
+    MozReview-Commit-ID: IqzGDM4ezeW
+    
+    --HG--
+    extra : rebase_source : 8f9a1f72360fcabdc6e57fec3dbdda1bd705fd03
+    extra : source : 02d457ace9bb8430e25cfb3a1fb6b0303c9d01c5
+---
+ layout/forms/nsNumberControlFrame.cpp | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git layout/forms/nsNumberControlFrame.cpp layout/forms/nsNumberControlFrame.cpp
+index 00b4492f23f1..68819267c906 100644
+--- layout/forms/nsNumberControlFrame.cpp
++++ layout/forms/nsNumberControlFrame.cpp
+@@ -592,15 +592,17 @@ nsNumberControlFrame::HandleFocusEvent(WidgetEvent* aEvent)
+ {
+   if (aEvent->mOriginalTarget != mTextField) {
+     // Move focus to our text field
++    RefPtr<HTMLInputElement> textField = HTMLInputElement::FromContent(mTextField);
+     IgnoredErrorResult ignored;
+-    HTMLInputElement::FromContent(mTextField)->Focus(ignored);
++    textField->Focus(ignored);
+   }
+ }
+ 
+ void
+ nsNumberControlFrame::HandleSelectCall()
+ {
+-  HTMLInputElement::FromContent(mTextField)->Select();
++  RefPtr<HTMLInputElement> textField = HTMLInputElement::FromContent(mTextField);
++  textField->Select();
+ }
+ 
+ #define STYLES_DISABLING_NATIVE_THEMING \

Added: head/www/waterfox/files/patch-bug1399520
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/www/waterfox/files/patch-bug1399520	Tue Dec 26 21:47:13 2017	(r457317)
@@ -0,0 +1,93 @@
+commit b4603106d015
+Author: Liang-Heng Chen <xeonchen@gmail.com>
+Date:   Thu Oct 19 22:29:41 2017 -0400
+
+    Bug 1399520 - Avoid race condition. r=dragana
+    
+    MozReview-Commit-ID: 6Pd2HXqBgX4
+---
+ modules/libjar/nsJAR.cpp | 26 ++++++++++++++++++--------
+ modules/libjar/nsJAR.h   |  8 +++++---
+ 2 files changed, 23 insertions(+), 11 deletions(-)
+
+diff --git modules/libjar/nsJAR.cpp modules/libjar/nsJAR.cpp
+index 80589e03f92b..b3121d99ef0a 100644
+--- modules/libjar/nsJAR.cpp
++++ modules/libjar/nsJAR.cpp
+@@ -43,11 +43,27 @@ NS_IMPL_QUERY_INTERFACE(nsJAR, nsIZipReader)
+ NS_IMPL_ADDREF(nsJAR)
+ 
+ // Custom Release method works with nsZipReaderCache...
++// Release might be called from multi-thread, we have to
++// take this function carefully to avoid delete-after-use.
+ MozExternalRefCountType nsJAR::Release(void)
+ {
+   nsrefcnt count;
+   NS_PRECONDITION(0 != mRefCnt, "dup release");
+-  count = --mRefCnt;
++
++  RefPtr<nsZipReaderCache> cache;
++  if (mRefCnt == 2) { // don't use a lock too frequently
++    // Use a mutex here to guarantee mCache is not racing and the target instance
++    // is still valid to increase ref-count.
++    MutexAutoLock lock(mLock);
++    cache = mCache;
++    mCache = nullptr;
++  }
++  if (cache) {
++    DebugOnly<nsresult> rv = cache->ReleaseZip(this);
++    MOZ_ASSERT(NS_SUCCEEDED(rv), "failed to release zip file");
++  }
++
++  count = --mRefCnt; // don't access any member variable after this line
+   NS_LOG_RELEASE(this, count, "nsJAR");
+   if (0 == count) {
+     mRefCnt = 1; /* stabilize */
+@@ -56,13 +72,7 @@ MozExternalRefCountType nsJAR::Release(void)
+     delete this;
+     return 0;
+   }
+-  if (1 == count && mCache) {
+-#ifdef DEBUG
+-    nsresult rv =
+-#endif
+-      mCache->ReleaseZip(this);
+-    NS_ASSERTION(NS_SUCCEEDED(rv), "failed to release zip file");
+-  }
++
+   return count;
+ }
+ 
+diff --git modules/libjar/nsJAR.h modules/libjar/nsJAR.h
+index 7f675c93003b..4fe948680fbf 100644
+--- modules/libjar/nsJAR.h
++++ modules/libjar/nsJAR.h
+@@ -12,6 +12,7 @@
+ #include "mozilla/Logging.h"
+ #include "prinrval.h"
+ 
++#include "mozilla/Atomics.h"
+ #include "mozilla/Mutex.h"
+ #include "nsIComponentManager.h"
+ #include "nsCOMPtr.h"
+@@ -75,8 +76,9 @@ class nsJAR final : public nsIZipReader
+       mReleaseTime = PR_INTERVAL_NO_TIMEOUT;
+     }
+ 
+-    void SetZipReaderCache(nsZipReaderCache* cache) {
+-      mCache = cache;
++    void SetZipReaderCache(nsZipReaderCache* aCache) {
++      mozilla::MutexAutoLock lock(mLock);
++      mCache = aCache;
+     }
+ 
+     nsresult GetNSPRFileDesc(PRFileDesc** aNSPRFileDesc);
+@@ -89,7 +91,7 @@ class nsJAR final : public nsIZipReader
+     RefPtr<nsZipArchive>     mZip;            // The underlying zip archive
+     PRIntervalTime           mReleaseTime;    // used by nsZipReaderCache for flushing entries
+     nsZipReaderCache*        mCache;          // if cached, this points to the cache it's contained in
+-    mozilla::Mutex           mLock;
++    mozilla::Mutex           mLock;           // protect mCache and mZip
+     int64_t                  mMtime;
+     bool                     mOpened;
+     bool                     mIsOmnijar;

Added: head/www/waterfox/files/patch-bug1408276
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/www/waterfox/files/patch-bug1408276	Tue Dec 26 21:47:13 2017	(r457317)
@@ -0,0 +1,170 @@
+commit a9bc6108422a
+Author: Karl Tomlinson <karlt+@karlt.net>
+Date:   Tue Oct 17 18:14:43 2017 +1300
+
+    Bug 1408276 - Move to LIFECYCLE_WAITING_FOR_MAIN_THREAD_CLEANUP at end of iteration. r=padenot, a=gchang
+    
+    MozReview-Commit-ID: GbfIOPZPuGu
+    
+    --HG--
+    extra : rebase_source : acc2bcee9a36d2b8f18826f08825895de5df0c1e
+---
+ dom/media/GraphDriver.cpp        | 27 +++++++++++++++++----------
+ dom/media/MediaStreamGraph.cpp   | 32 +++++++++++++++++++++-----------
+ dom/media/MediaStreamGraphImpl.h | 12 +++++++++++-
+ 3 files changed, 49 insertions(+), 22 deletions(-)
+
+diff --git dom/media/GraphDriver.cpp dom/media/GraphDriver.cpp
+index 7f6f386fdaca..13944338e3d7 100644
+--- dom/media/GraphDriver.cpp
++++ dom/media/GraphDriver.cpp
+@@ -284,8 +284,7 @@ SystemClockDriver::IsFallback()
+ void
+ ThreadedDriver::RunThread()
+ {
+-  bool stillProcessing = true;
+-  while (stillProcessing) {
++  while (true) {
+     mIterationStart = IterationEnd();
+     mIterationEnd += GetIntervalForIteration();
+ 
+@@ -324,10 +323,16 @@ ThreadedDriver::RunThread()
+          (long)stateComputedTime,
+          (long)nextStateComputedTime));
+ 
+-    stillProcessing = mGraphImpl->OneIteration(nextStateComputedTime);
++    bool stillProcessing = mGraphImpl->OneIteration(nextStateComputedTime);
+ 
++    if (!stillProcessing) {
++      // Enter shutdown mode. The stable-state handler will detect this
++      // and complete shutdown if the graph does not get restarted.
++      mGraphImpl->SignalMainThreadCleanup();
++      return;
++    }
+     MonitorAutoLock lock(GraphImpl()->GetMonitor());
+-    if (NextDriver() && stillProcessing) {
++    if (NextDriver()) {
+       LOG(LogLevel::Debug, ("Switching to AudioCallbackDriver"));
+       RemoveCallback();
+       NextDriver()->SetGraphTime(this, mIterationStart, mIterationEnd);
+@@ -1009,13 +1014,20 @@ AudioCallbackDriver::DataCallback(const AudioDataValue* aInputBuffer,
+   mGraphImpl->NotifyOutputData(aOutputBuffer, static_cast<size_t>(aFrames),
+                                mSampleRate, mOutputChannels);
+ 
++  if (!stillProcessing) {
++    // Enter shutdown mode. The stable-state handler will detect this
++    // and complete shutdown if the graph does not get restarted.
++    mGraphImpl->SignalMainThreadCleanup();
++    return aFrames - 1;
++  }
++
+   bool switching = false;
+   {
+     MonitorAutoLock mon(mGraphImpl->GetMonitor());
+     switching = !!NextDriver();
+   }
+ 
+-  if (switching && stillProcessing) {
++  if (switching) {
+     // If the audio stream has not been started by the previous driver or
+     // the graph itself, keep it alive.
+     MonitorAutoLock mon(mGraphImpl->GetMonitor());
+@@ -1032,11 +1044,6 @@ AudioCallbackDriver::DataCallback(const AudioDataValue* aInputBuffer,
+     return aFrames - 1;
+   }
+ 
+-  if (!stillProcessing) {
+-    LOG(LogLevel::Debug,
+-        ("Stopping audio thread for MediaStreamGraph %p", this));
+-    return aFrames - 1;
+-  }
+   return aFrames;
+ }
+ 
+diff --git dom/media/MediaStreamGraph.cpp dom/media/MediaStreamGraph.cpp
+index 3a742aafe9b2..6420e038a8fe 100644
+--- dom/media/MediaStreamGraph.cpp
++++ dom/media/MediaStreamGraph.cpp
+@@ -1193,11 +1193,13 @@ MediaStreamGraphImpl::PrepareUpdatesToMainThreadState(bool aFinalUpdate)
+     }
+   }
+ 
+-  // Don't send the message to the main thread if it's not going to have
+-  // any work to do.
+-  if (aFinalUpdate ||
+-      !mUpdateRunnables.IsEmpty() ||
+-      !mStreamUpdates.IsEmpty()) {
++  // If this is the final update, then a stable state event will soon be
++  // posted just before this thread finishes, and so there is no need to also
++  // post here.
++  if (!aFinalUpdate &&
++      // Don't send the message to the main thread if it's not going to have
++      // any work to do.
++      !(mUpdateRunnables.IsEmpty() && mStreamUpdates.IsEmpty())) {
+     EnsureStableStateEventPosted();
+   }
+ }
+@@ -1430,12 +1432,7 @@ MediaStreamGraphImpl::UpdateMainThreadState()
+     (IsEmpty() && mBackMessageQueue.IsEmpty());
+   PrepareUpdatesToMainThreadState(finalUpdate);
+   if (finalUpdate) {
+-    // Enter shutdown mode. The stable-state handler will detect this
+-    // and complete shutdown. Destroy any streams immediately.
+-    LOG(LogLevel::Debug,
+-        ("MediaStreamGraph %p waiting for main thread cleanup", this));
+-    // We'll shut down this graph object if it does not get restarted.
+-    mLifecycleState = LIFECYCLE_WAITING_FOR_MAIN_THREAD_CLEANUP;
++    // Enter shutdown mode when this iteration is completed.
+     // No need to Destroy streams here. The main-thread owner of each
+     // stream is responsible for calling Destroy on them.
+     return false;
+@@ -1861,6 +1858,19 @@ MediaStreamGraphImpl::EnsureStableStateEventPosted()
+   mAbstractMainThread->Dispatch(event.forget());
+ }
+ 
++void
++MediaStreamGraphImpl::SignalMainThreadCleanup()
++{
++  MOZ_ASSERT(mDriver->OnThread());
++
++  MonitorAutoLock lock(mMonitor);
++  LOG(LogLevel::Debug,
++      ("MediaStreamGraph %p waiting for main thread cleanup", this));
++  mLifecycleState =
++    MediaStreamGraphImpl::LIFECYCLE_WAITING_FOR_MAIN_THREAD_CLEANUP;
++  EnsureStableStateEventPosted();
++}
++
+ void
+ MediaStreamGraphImpl::AppendMessage(UniquePtr<ControlMessage> aMessage)
+ {
+diff --git dom/media/MediaStreamGraphImpl.h dom/media/MediaStreamGraphImpl.h
+index dfea12bca3a8..dce49da39166 100644
+--- dom/media/MediaStreamGraphImpl.h
++++ dom/media/MediaStreamGraphImpl.h
+@@ -197,6 +197,14 @@ public:
+    */
+   bool OneIteration(GraphTime aStateEnd);
+ 
++  /**
++   * Called from the driver, when the graph thread is about to stop, to tell
++   * the main thread to attempt to begin cleanup.  The main thread may either
++   * shutdown or revive the graph depending on whether it receives new
++   * messages.
++   */
++  void SignalMainThreadCleanup();
++
+   bool Running() const
+   {
+     mMonitor.AssertCurrentThreadOwns();
+@@ -720,7 +728,9 @@ public:
+     LIFECYCLE_WAITING_FOR_STREAM_DESTRUCTION
+   };
+   /**
+-   * Modified only on the main thread in mMonitor.
++   * Modified only in mMonitor.  Transitions to
++   * LIFECYCLE_WAITING_FOR_MAIN_THREAD_CLEANUP occur on the graph thread at
++   * the end of an iteration.  All other transitions occur on the main thread.
+    */
+   LifecycleState mLifecycleState;
+   /**

Added: head/www/waterfox/files/patch-bug1409951
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/www/waterfox/files/patch-bug1409951	Tue Dec 26 21:47:13 2017	(r457317)
@@ -0,0 +1,177 @@
+commit d5562dbcfd63
+Author: Henri Sivonen <hsivonen@hsivonen.fi>
+Date:   Fri Dec 1 10:45:25 2017 -0500
+
+    Bug 1409951 - Use a stack to end serializer contexts instead of recomputing them. r=smaug, a=gchang
+    
+    MozReview-Commit-ID: FOd8AUmtYyA
+    
+    --HG--
+    extra : rebase_source : 1f02ebc32fe80591d617f27ec70094a109ead2b0
+    extra : source : b0a3a621f5c85b5e9a4eb97de77fcb2558ac17c6
+---
+ dom/base/nsDocumentEncoder.cpp     | 56 +++++++++++++++++++-------------------
+ dom/base/nsPlainTextSerializer.cpp |  1 +
+ 2 files changed, 29 insertions(+), 28 deletions(-)
+
+diff --git dom/base/nsDocumentEncoder.cpp dom/base/nsDocumentEncoder.cpp
+index 5912d67da86e..2fb488750366 100644
+--- dom/base/nsDocumentEncoder.cpp
++++ dom/base/nsDocumentEncoder.cpp
+@@ -49,6 +49,7 @@
+ #include "mozilla/dom/Element.h"
+ #include "mozilla/dom/ShadowRoot.h"
+ #include "nsLayoutUtils.h"
++#include "mozilla/ScopeExit.h"
+ 
+ using namespace mozilla;
+ using namespace mozilla::dom;
+@@ -92,8 +93,8 @@ protected:
+                                int32_t aDepth);
+   nsresult SerializeRangeContextStart(const nsTArray<nsINode*>& aAncestorArray,
+                                       nsAString& aString);
+-  nsresult SerializeRangeContextEnd(const nsTArray<nsINode*>& aAncestorArray,
+-                                    nsAString& aString);
++  nsresult SerializeRangeContextEnd(nsAString& aString);
++
+   virtual int32_t
+   GetImmediateContextCount(const nsTArray<nsINode*>& aAncestorArray)
+   {
+@@ -185,6 +186,7 @@ protected:
+   AutoTArray<int32_t, 8>     mStartOffsets;
+   AutoTArray<nsIContent*, 8> mEndNodes;
+   AutoTArray<int32_t, 8>     mEndOffsets;
++  AutoTArray<AutoTArray<nsINode*, 8>, 8> mRangeContexts;
+   // Whether the serializer cares about being notified to scan elements to
+   // keep track of whether they are preformatted.  This stores the out
+   // argument of nsIContentSerializer::Init().
+@@ -874,6 +876,9 @@ nsDocumentEncoder::SerializeRangeContextStart(const nsTArray<nsINode*>& aAncesto
+   if (mDisableContextSerialize) {
+     return NS_OK;
+   }
++
++  AutoTArray<nsINode*, 8>* serializedContext = mRangeContexts.AppendElement();
++
+   int32_t i = aAncestorArray.Length(), j;
+   nsresult rv = NS_OK;
+ 
+@@ -889,7 +894,7 @@ nsDocumentEncoder::SerializeRangeContextStart(const nsTArray<nsINode*>& aAncesto
+     // Either a general inclusion or as immediate context
+     if (IncludeInContext(node) || i < j) {
+       rv = SerializeNodeStart(node, 0, -1, aString);
+-
++      serializedContext->AppendElement(node);
+       if (NS_FAILED(rv))
+         break;
+     }
+@@ -899,34 +904,24 @@ nsDocumentEncoder::SerializeRangeContextStart(const nsTArray<nsINode*>& aAncesto
+ }
+ 
+ nsresult
+-nsDocumentEncoder::SerializeRangeContextEnd(const nsTArray<nsINode*>& aAncestorArray,
+-                                            nsAString& aString)
++nsDocumentEncoder::SerializeRangeContextEnd(nsAString& aString)
+ {
+   if (mDisableContextSerialize) {
+     return NS_OK;
+   }
+-  int32_t i = 0, j;
+-  int32_t count = aAncestorArray.Length();
+-  nsresult rv = NS_OK;
+ 
+-  // currently only for table-related elements
+-  j = GetImmediateContextCount(aAncestorArray);
++  MOZ_RELEASE_ASSERT(!mRangeContexts.IsEmpty(), "Tried to end context without starting one.");
++  AutoTArray<nsINode*, 8>& serializedContext = mRangeContexts.LastElement();
+ 
+-  while (i < count) {
+-    nsINode *node = aAncestorArray.ElementAt(i++);
++  nsresult rv = NS_OK;
++  for (nsINode* node : Reversed(serializedContext)) {
++    rv = SerializeNodeEnd(node, aString);
+ 
+-    if (!node)
++    if (NS_FAILED(rv))
+       break;
+-
+-    // Either a general inclusion or as immediate context
+-    if (IncludeInContext(node) || i - 1 < j) {
+-      rv = SerializeNodeEnd(node, aString);
+-
+-      if (NS_FAILED(rv))
+-        break;
+-    }
+   }
+ 
++  mRangeContexts.RemoveElementAt(mRangeContexts.Length() - 1);
+   return rv;
+ }
+ 
+@@ -992,7 +987,7 @@ nsDocumentEncoder::SerializeRangeToString(nsRange *aRange,
+     rv = SerializeRangeNodes(aRange, mCommonParent, aOutputString, 0);
+     NS_ENSURE_SUCCESS(rv, rv);
+   }
+-  rv = SerializeRangeContextEnd(mCommonAncestors, aOutputString);
++  rv = SerializeRangeContextEnd(aOutputString);
+   NS_ENSURE_SUCCESS(rv, rv);
+ 
+   return rv;
+@@ -1029,6 +1024,11 @@ NS_IMETHODIMP
+ nsDocumentEncoder::EncodeToStringWithMaxLength(uint32_t aMaxLength,
+                                                nsAString& aOutputString)
+ {
++  MOZ_ASSERT(mRangeContexts.IsEmpty(), "Re-entrant call to nsDocumentEncoder.");
++  auto rangeContextGuard = MakeScopeExit([&] {
++    mRangeContexts.Clear();
++  });
++
+   if (!mDocument)
+     return NS_ERROR_NOT_INITIALIZED;
+ 
+@@ -1112,10 +1112,8 @@ nsDocumentEncoder::EncodeToStringWithMaxLength(uint32_t aMaxLength,
+           prevNode = node;
+         } else if (prevNode) {
+           // Went from a <tr> to a non-<tr>
+-          mCommonAncestors.Clear();
+-          nsContentUtils::GetAncestors(p->GetParentNode(), mCommonAncestors);
+           mDisableContextSerialize = false;
+-          rv = SerializeRangeContextEnd(mCommonAncestors, output);
++          rv = SerializeRangeContextEnd(output);
+           NS_ENSURE_SUCCESS(rv, rv);
+           prevNode = nullptr;
+         }
+@@ -1134,10 +1132,8 @@ nsDocumentEncoder::EncodeToStringWithMaxLength(uint32_t aMaxLength,
+       nsCOMPtr<nsINode> p = do_QueryInterface(prevNode);
+       rv = SerializeNodeEnd(p, output);
+       NS_ENSURE_SUCCESS(rv, rv);
+-      mCommonAncestors.Clear();
+-      nsContentUtils::GetAncestors(p->GetParentNode(), mCommonAncestors);
+       mDisableContextSerialize = false;
+-      rv = SerializeRangeContextEnd(mCommonAncestors, output);
++      rv = SerializeRangeContextEnd(output);
+       NS_ENSURE_SUCCESS(rv, rv);
+     }
+ 
+@@ -1196,6 +1192,10 @@ nsDocumentEncoder::EncodeToStringWithMaxLength(uint32_t aMaxLength,
+ NS_IMETHODIMP
+ nsDocumentEncoder::EncodeToStream(nsIOutputStream* aStream)
+ {
++  MOZ_ASSERT(mRangeContexts.IsEmpty(), "Re-entrant call to nsDocumentEncoder.");
++  auto rangeContextGuard = MakeScopeExit([&] {
++    mRangeContexts.Clear();
++  });
+   nsresult rv = NS_OK;
+ 
+   if (!mDocument)
+diff --git dom/base/nsPlainTextSerializer.cpp dom/base/nsPlainTextSerializer.cpp
+index 189469f73bb6..d7ddb0274be5 100644
+--- dom/base/nsPlainTextSerializer.cpp
++++ dom/base/nsPlainTextSerializer.cpp
+@@ -388,6 +388,7 @@ nsPlainTextSerializer::ScanElementForPreformat(Element* aElement)
+ NS_IMETHODIMP
+ nsPlainTextSerializer::ForgetElementForPreformat(Element* aElement)
+ {
++  MOZ_RELEASE_ASSERT(!mPreformatStack.empty(), "Tried to pop without previous push.");
+   mPreformatStack.pop();
+   return NS_OK;
+ }

Added: head/www/waterfox/files/patch-bug1410134
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/www/waterfox/files/patch-bug1410134	Tue Dec 26 21:47:13 2017	(r457317)
@@ -0,0 +1,52 @@
+commit 2d5001acfa08
+Author: Tim Huang <tihuang@mozilla.com>
+Date:   Tue Nov 28 14:56:55 2017 -0500
+
+    Bug 1410134 - Fix the remove-while-iterating for RemoveCookiesWithOriginAttributes. r=jdm, a=gchang
+    
+    MozReview-Commit-ID: u56N4084lL
+    
+    --HG--
+    extra : source : ffab26e34d92c1fc2e5103d2bad3625e180963bb
+---
+ netwerk/cookie/nsCookieService.cpp | 24 ++++++++++--------------
+ 1 file changed, 10 insertions(+), 14 deletions(-)
+
+diff --git netwerk/cookie/nsCookieService.cpp netwerk/cookie/nsCookieService.cpp
+index 7d939da101e2..0692b7088751 100644
+--- netwerk/cookie/nsCookieService.cpp
++++ netwerk/cookie/nsCookieService.cpp
+@@ -4899,23 +4899,19 @@ nsCookieService::RemoveCookiesWithOriginAttributes(
+     }
+ 
+     // Pattern matches. Delete all cookies within this nsCookieEntry.
+-    const nsCookieEntry::ArrayType& cookies = entry->GetCookies();
++    uint32_t cookiesCount = entry->GetCookies().Length();
+ 
+-    while (!cookies.IsEmpty()) {
+-      nsCookie *cookie = cookies.LastElement();
+-
+-      nsAutoCString host;
+-      cookie->GetHost(host);
+-
+-      nsAutoCString name;
+-      cookie->GetName(name);
+-
+-      nsAutoCString path;
+-      cookie->GetPath(path);
++    for (nsCookieEntry::IndexType i = 0 ; i < cookiesCount; ++i) {
++      // Remove the first cookie from the list.
++      nsListIter iter(entry, 0);
++      RefPtr<nsCookie> cookie = iter.Cookie();
+ 
+       // Remove the cookie.
+-      nsresult rv = Remove(host, entry->mOriginAttributes, name, path, false);
+-      NS_ENSURE_SUCCESS(rv, rv);
++      RemoveCookieFromList(iter);
++
++      if (cookie) {
++        NotifyChanged(cookie, u"deleted");
++      }
+     }
+   }
+   DebugOnly<nsresult> rv = transaction.Commit();

Added: head/www/waterfox/files/patch-bug1412145
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/www/waterfox/files/patch-bug1412145	Tue Dec 26 21:47:13 2017	(r457317)
@@ -0,0 +1,286 @@
+commit d83a24ce6fb3
+Author: Xidorn Quan <me@upsuper.org>
+Date:   Tue Nov 28 17:06:51 2017 -0600
+
+    Bug 1412145 - Drop more backpointers of CSSOM objects in dtor and unlink. r=bz, a=gchang
+    
+    MozReview-Commit-ID: Ftg3WMBBNlO
+---
+ layout/style/GroupRule.cpp          |  7 +++++++
+ layout/style/GroupRule.h            |  1 +
+ layout/style/MediaList.h            |  4 +++-
+ layout/style/ServoCSSRuleList.cpp   |  2 ++
+ layout/style/ServoKeyframeRule.cpp  | 12 ++++++++++--
+ layout/style/ServoKeyframesRule.cpp | 23 ++++++++++++++++-------
+ layout/style/ServoMediaRule.cpp     | 17 +++++++++++++++--
+ layout/style/ServoPageRule.cpp      |  2 ++
+ layout/style/ServoStyleRule.cpp     |  1 +
+ layout/style/nsCSSRules.cpp         | 31 +++++++++++++++++++++++++++----
+ 10 files changed, 84 insertions(+), 16 deletions(-)
+
+diff --git layout/style/GroupRule.cpp layout/style/GroupRule.cpp
+index 28739e1818eb..32bd8c83e43a 100644
+--- layout/style/GroupRule.cpp
++++ layout/style/GroupRule.cpp
+@@ -198,6 +198,13 @@ GeckoGroupRuleRules::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const
+ // ServoGroupRuleRules
+ //
+ 
++ServoGroupRuleRules::~ServoGroupRuleRules()
++{
++  if (mRuleList) {
++    mRuleList->DropReference();
++  }
++}
++
+ #ifdef DEBUG
+ void
+ ServoGroupRuleRules::List(FILE* out, int32_t aIndent) const
+diff --git layout/style/GroupRule.h layout/style/GroupRule.h
+index ac9e26921f0b..5c336e5c3611 100644
+--- layout/style/GroupRule.h
++++ layout/style/GroupRule.h
+@@ -87,6 +87,7 @@ struct ServoGroupRuleRules
+     // Do we ever clone Servo rules?
+     MOZ_ASSERT_UNREACHABLE("stylo: Cloning GroupRule not implemented");
+   }
++  ~ServoGroupRuleRules();
+ 
+   void SetParentRule(GroupRule* aParentRule) {
+     if (mRuleList) {
+diff --git layout/style/MediaList.h layout/style/MediaList.h
+index 4e8c12a2461a..b95e6ec26895 100644
+--- layout/style/MediaList.h
++++ layout/style/MediaList.h
+@@ -84,7 +84,9 @@ protected:
+   virtual nsresult Delete(const nsAString& aOldMedium) = 0;
+   virtual nsresult Append(const nsAString& aNewMedium) = 0;
+ 
+-  virtual ~MediaList() {}
++  virtual ~MediaList() {
++    MOZ_ASSERT(!mStyleSheet, "Backpointer should have been cleared");
++  }
+ 
+   // not refcounted; sheet will let us know when it goes away
+   // mStyleSheet is the sheet that needs to be dirtied when this
+diff --git layout/style/ServoCSSRuleList.cpp layout/style/ServoCSSRuleList.cpp
+index 37ce9be9f337..31f481899964 100644
+--- layout/style/ServoCSSRuleList.cpp
++++ layout/style/ServoCSSRuleList.cpp
+@@ -234,6 +234,8 @@ ServoCSSRuleList::GetDOMCSSRuleType(uint32_t aIndex) const
+ 
+ ServoCSSRuleList::~ServoCSSRuleList()
+ {
++  MOZ_ASSERT(!mStyleSheet, "Backpointer should have been cleared");
++  MOZ_ASSERT(!mParentRule, "Backpointer should have been cleared");
+   DropAllRules();
+ }
+ 
+diff --git layout/style/ServoKeyframeRule.cpp layout/style/ServoKeyframeRule.cpp
+index 1be82c3100c5..6ca8a1815f8c 100644
+--- layout/style/ServoKeyframeRule.cpp
++++ layout/style/ServoKeyframeRule.cpp
+@@ -35,7 +35,10 @@ public:
+     return NS_OK;
+   }
+ 
+-  void DropReference() { mRule = nullptr; }
++  void DropReference() {
++    mRule = nullptr;
++    mDecls->SetOwningRule(nullptr);
++  }
+ 
+   DeclarationBlock* GetCSSDeclaration(Operation aOperation) final
+   {
+@@ -81,7 +84,9 @@ public:
+   }
+ 
+ private:
+-  virtual ~ServoKeyframeDeclaration() {}
++  virtual ~ServoKeyframeDeclaration() {
++    MOZ_ASSERT(!mRule, "Backpointer should have been cleared");
++  }
+ 
+   ServoKeyframeRule* mRule;
+   RefPtr<ServoDeclarationBlock> mDecls;
+@@ -102,6 +107,9 @@ NS_INTERFACE_MAP_END_INHERITING(nsDOMCSSDeclaration)
+ 
+ ServoKeyframeRule::~ServoKeyframeRule()
+ {
++  if (mDeclaration) {
++    mDeclaration->DropReference();
++  }
+ }
+ 
+ NS_IMPL_ADDREF_INHERITED(ServoKeyframeRule, dom::CSSKeyframeRule)
+diff --git layout/style/ServoKeyframesRule.cpp layout/style/ServoKeyframesRule.cpp
+index 9a7252a5a639..7341b954ec60 100644
+--- layout/style/ServoKeyframesRule.cpp
++++ layout/style/ServoKeyframesRule.cpp
+@@ -90,7 +90,12 @@ public:
+   {
+     mStyleSheet = nullptr;
+     mParentRule = nullptr;
+-    DropAllRules();
++    for (css::Rule* rule : mRules) {
++      if (rule) {
++        rule->SetStyleSheet(nullptr);
++        rule->SetParentRule(nullptr);
++      }
++    }
+   }
+ 
+   size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
+@@ -103,15 +108,16 @@ public:
+   }
+ 
+ private:
+-  virtual ~ServoKeyframeList() {}
++  virtual ~ServoKeyframeList() {
++    MOZ_ASSERT(!mParentRule, "Backpointer should have been cleared");
++    MOZ_ASSERT(!mStyleSheet, "Backpointer should have been cleared");
++    DropAllRules();
++  }
+ 
+   void DropAllRules()
+   {
+-    for (css::Rule* rule : mRules) {
+-      if (rule) {
+-        rule->SetStyleSheet(nullptr);
+-        rule->SetParentRule(nullptr);
+-      }
++    if (mParentRule || mStyleSheet) {
++      DropReference();
+     }
+     mRules.Clear();
+     mRawRule = nullptr;
+@@ -163,6 +169,9 @@ ServoKeyframesRule::ServoKeyframesRule(RefPtr<RawServoKeyframesRule> aRawRule,
+ 
+ ServoKeyframesRule::~ServoKeyframesRule()
+ {
++  if (mKeyframeList) {
++    mKeyframeList->DropReference();
++  }
+ }
+ 
+ NS_IMPL_ADDREF_INHERITED(ServoKeyframesRule, dom::CSSKeyframesRule)
+diff --git layout/style/ServoMediaRule.cpp layout/style/ServoMediaRule.cpp
+index 002ae20ffd0b..fbda581a377f 100644
+--- layout/style/ServoMediaRule.cpp
++++ layout/style/ServoMediaRule.cpp
+@@ -24,6 +24,9 @@ ServoMediaRule::ServoMediaRule(RefPtr<RawServoMediaRule> aRawRule,
+ 
+ ServoMediaRule::~ServoMediaRule()
+ {
++  if (mMediaList) {
++    mMediaList->SetStyleSheet(nullptr);
++  }
+ }
+ 
+ NS_IMPL_ADDREF_INHERITED(ServoMediaRule, CSSMediaRule)
+@@ -33,8 +36,18 @@ NS_IMPL_RELEASE_INHERITED(ServoMediaRule, CSSMediaRule)
+ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(ServoMediaRule)
+ NS_INTERFACE_MAP_END_INHERITING(CSSMediaRule)
+ 
+-NS_IMPL_CYCLE_COLLECTION_INHERITED(ServoMediaRule, CSSMediaRule,
+-                                   mMediaList)
++NS_IMPL_CYCLE_COLLECTION_CLASS(ServoMediaRule)
++
++NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(ServoMediaRule, CSSMediaRule)
++  if (tmp->mMediaList) {
++    tmp->mMediaList->SetStyleSheet(nullptr);
++    tmp->mMediaList = nullptr;
++  }
++NS_IMPL_CYCLE_COLLECTION_UNLINK_END
++
++NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(ServoMediaRule, CSSMediaRule)
++  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mMediaList)
++NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
+ 
+ /* virtual */ already_AddRefed<css::Rule>
+ ServoMediaRule::Clone() const
+diff --git layout/style/ServoPageRule.cpp layout/style/ServoPageRule.cpp
+index 97c718ed1ba9..93e8ff334122 100644
+--- layout/style/ServoPageRule.cpp
++++ layout/style/ServoPageRule.cpp
+@@ -26,6 +26,7 @@ ServoPageRuleDeclaration::ServoPageRuleDeclaration(
+ 
+ ServoPageRuleDeclaration::~ServoPageRuleDeclaration()
+ {
++  mDecls->SetOwningRule(nullptr);
+ }
+ 
+ // QueryInterface implementation for ServoPageRuleDeclaration
+@@ -141,6 +142,7 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(ServoPageRule, CSSPageRule)
+   // NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER which we can't use
+   // directly because the wrapper is on the declaration, not on us.
+   tmp->mDecls.ReleaseWrapper(static_cast<nsISupports*>(p));
++  tmp->mDecls.mDecls->SetOwningRule(nullptr);
+ NS_IMPL_CYCLE_COLLECTION_UNLINK_END
+ 
+ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(ServoPageRule, CSSPageRule)
+diff --git layout/style/ServoStyleRule.cpp layout/style/ServoStyleRule.cpp
+index 1d7470eef037..855e643515f9 100644
+--- layout/style/ServoStyleRule.cpp
++++ layout/style/ServoStyleRule.cpp
+@@ -28,6 +28,7 @@ ServoStyleRuleDeclaration::ServoStyleRuleDeclaration(
+ 
+ ServoStyleRuleDeclaration::~ServoStyleRuleDeclaration()
+ {
++  mDecls->SetOwningRule(nullptr);
+ }
+ 
+ // QueryInterface implementation for ServoStyleRuleDeclaration
+diff --git layout/style/nsCSSRules.cpp layout/style/nsCSSRules.cpp
+index 5081244c6a53..0bdedc4a3b03 100644
+--- layout/style/nsCSSRules.cpp
++++ layout/style/nsCSSRules.cpp
+@@ -212,12 +212,25 @@ ImportRule::~ImportRule()
+ NS_IMPL_ADDREF_INHERITED(ImportRule, CSSImportRule)
+ NS_IMPL_RELEASE_INHERITED(ImportRule, CSSImportRule)
+ 
+-NS_IMPL_CYCLE_COLLECTION_INHERITED(ImportRule, CSSImportRule, mMedia, mChildSheet)
+-
+ // QueryInterface implementation for ImportRule
+ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(ImportRule)
+ NS_INTERFACE_MAP_END_INHERITING(CSSImportRule)
+ 
++NS_IMPL_CYCLE_COLLECTION_CLASS(ImportRule)
++
++NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(ImportRule, CSSImportRule)
++  if (tmp->mChildSheet) {
++    tmp->mChildSheet->SetOwnerRule(nullptr);
++    tmp->mChildSheet = nullptr;
++  }
++  tmp->mMedia = nullptr;
++NS_IMPL_CYCLE_COLLECTION_UNLINK_END
++
++NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(ImportRule, CSSImportRule)
++  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mMedia)
++  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mChildSheet)
++NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
++
+ #ifdef DEBUG
+ /* virtual */ void
+ ImportRule::List(FILE* out, int32_t aIndent) const
+@@ -342,8 +355,18 @@ NS_IMPL_RELEASE_INHERITED(MediaRule, CSSMediaRule)
+ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(MediaRule)
+ NS_INTERFACE_MAP_END_INHERITING(CSSMediaRule)
+ 
+-NS_IMPL_CYCLE_COLLECTION_INHERITED(MediaRule, CSSMediaRule,
+-                                   mMedia)
++NS_IMPL_CYCLE_COLLECTION_CLASS(MediaRule)
++
++NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(MediaRule, CSSMediaRule)
++  if (tmp->mMedia) {
++    tmp->mMedia->SetStyleSheet(nullptr);
++    tmp->mMedia = nullptr;
++  }
++NS_IMPL_CYCLE_COLLECTION_UNLINK_END
++
++NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(MediaRule, CSSMediaRule)
++  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mMedia)
++NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
+ 
+ /* virtual */ void
+ MediaRule::SetStyleSheet(StyleSheet* aSheet)

Added: head/www/waterfox/files/patch-bug1413741
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/www/waterfox/files/patch-bug1413741	Tue Dec 26 21:47:13 2017	(r457317)
@@ -0,0 +1,25 @@
+commit bd17df85baf4
+Author: Andrea Marchesini <amarchesini@mozilla.com>

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201712262147.vBQLlEka011157>