Merge mozilla-central to autoland. a=merge CLOSED TREE
authorNarcis Beleuzu <nbeleuzu@mozilla.com>
Sat, 12 Jan 2019 11:43:14 +0200
changeset 453626 10907464fcc25c1e2fd9b0aed806bfdea2e90ee8
parent 453625 ebca585ed555ffe4fddacd61e669cd7731aaa78c (current diff)
parent 453623 a44934afe25e7ac1fcccc5ca63b90406a29fbee2 (diff)
child 453627 450b8f0cbb4e494b399ebcf23a33b8d9cb883245
push id35362
push userncsoregi@mozilla.com
push dateSat, 12 Jan 2019 21:35:38 +0000
treeherdermozilla-central@877169d8ef49 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone66.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
Merge mozilla-central to autoland. a=merge CLOSED TREE
--- a/browser/config/mozconfigs/win32/mingwclang
+++ b/browser/config/mozconfigs/win32/mingwclang
@@ -47,17 +47,17 @@ HOST_CC="$TOOLTOOL_DIR/clang/bin/clang"
 HOST_CXX="$TOOLTOOL_DIR/clang/bin/clang++"
 CC="$TOOLTOOL_DIR/clang/bin/i686-w64-mingw32-clang"
 CXX="$TOOLTOOL_DIR/clang/bin/i686-w64-mingw32-clang++"
 CXXFLAGS="-fms-extensions"
 AR=llvm-ar
 RANLIB=llvm-ranlib
 
 # For Stylo
-BINDGEN_CFLAGS="-I$TOOLTOOL_DIR/clang/i686-w64-mingw32/include/c++/v1 -I$TOOLTOOL_DIR/clang/lib/clang/8.0.0/include -I$TOOLTOOL_DIR/clang/i686-w64-mingw32/include"
+BINDGEN_CFLAGS="-I$TOOLTOOL_DIR/clang/i686-w64-mingw32/include/c++/v1 -I$TOOLTOOL_DIR/clang/i686-w64-mingw32/include"
 
 # Bug 1471698 - Work around binutils corrupting mingw clang binaries.
 LDFLAGS="-Wl,-S"
 STRIP=/bin/true
 OBJCOPY=/bin/true
 
 # We want to make sure we use binutils and other binaries in the tooltool
 # package.
--- a/browser/config/mozconfigs/win64/mingwclang
+++ b/browser/config/mozconfigs/win64/mingwclang
@@ -47,17 +47,17 @@ HOST_CC="$TOOLTOOL_DIR/clang/bin/clang"
 HOST_CXX="$TOOLTOOL_DIR/clang/bin/clang++"
 CC="$TOOLTOOL_DIR/clang/bin/x86_64-w64-mingw32-clang"
 CXX="$TOOLTOOL_DIR/clang/bin/x86_64-w64-mingw32-clang++"
 CXXFLAGS="-fms-extensions"
 AR=llvm-ar
 RANLIB=llvm-ranlib
 
 # For Stylo
-BINDGEN_CFLAGS="-I$TOOLTOOL_DIR/clang/x86_64-w64-mingw32/include/c++/v1 -I$TOOLTOOL_DIR/clang/lib/clang/8.0.0/include -I$TOOLTOOL_DIR/clang/x86_64-w64-mingw32/include"
+BINDGEN_CFLAGS="-I$TOOLTOOL_DIR/clang/x86_64-w64-mingw32/include/c++/v1 -I$TOOLTOOL_DIR/clang/x86_64-w64-mingw32/include"
 
 # Bug 1471698 - Work around binutils corrupting mingw clang binaries.
 LDFLAGS="-Wl,-S"
 STRIP=/bin/true
 OBJCOPY=/bin/true
 
 # We want to make sure we use binutils and other binaries in the tooltool
 # package.
--- a/devtools/client/inspector/rules/components/Declaration.js
+++ b/devtools/client/inspector/rules/components/Declaration.js
@@ -12,19 +12,112 @@ const Types = require("../types");
 
 class Declaration extends PureComponent {
   static get propTypes() {
     return {
       declaration: PropTypes.shape(Types.declaration).isRequired,
     };
   }
 
+  constructor(props) {
+    super(props);
+
+    this.state = {
+      // Whether or not the computed property list is expanded.
+      isComputedListExpanded: false,
+    };
+
+    this.onComputedExpanderClick = this.onComputedExpanderClick.bind(this);
+  }
+
+  onComputedExpanderClick(event) {
+    event.stopPropagation();
+
+    this.setState(prevState => {
+      return { isComputedListExpanded: !prevState.isComputedListExpanded };
+    });
+  }
+
+  renderComputedPropertyList() {
+    const { computedProperties } = this.props.declaration;
+
+    if (!computedProperties.length) {
+      return null;
+    }
+
+    return (
+      dom.ul(
+        {
+          className: "ruleview-computedlist",
+          style: {
+            display: this.state.isComputedListExpanded ? "block" : "",
+          },
+        },
+        computedProperties.map(({ name, value, isOverridden }) => {
+          return (
+            dom.li(
+              {
+                key: `${name}${value}`,
+                className: "ruleview-computed" +
+                           (isOverridden ? " ruleview-overridden" : ""),
+              },
+              dom.span({ className: "ruleview-namecontainer" },
+                dom.span({ className: "ruleview-propertyname theme-fg-color5" }, name),
+                ": "
+              ),
+              dom.span({ className: "ruleview-propertyvaluecontainer" },
+                dom.span({ className: "ruleview-propertyvalue theme-fg-color1" }, value),
+                ";"
+              )
+            )
+          );
+        })
+      )
+    );
+  }
+
+  renderShorthandOverriddenList() {
+    const { declaration } = this.props;
+
+    if (this.state.isComputedListExpanded || declaration.isOverridden) {
+      return null;
+    }
+
+    return (
+      dom.ul({ className: "ruleview-overridden-items" },
+        declaration.computedProperties.map(({ name, value, isOverridden }) => {
+          if (!isOverridden) {
+            return null;
+          }
+
+          return (
+            dom.li(
+              {
+                key: `${name}${value}`,
+                className: "ruleview-overridden-item ruleview-overridden",
+              },
+              dom.span({ className: "ruleview-namecontainer" },
+                dom.span({ className: "ruleview-propertyname theme-fg-color5" }, name),
+                ": "
+              ),
+              dom.span({ className: "ruleview-propertyvaluecontainer" },
+                dom.span({ className: "ruleview-propertyvalue theme-fg-color1" }, value),
+                ";"
+              )
+            )
+          );
+        })
+      )
+    );
+  }
+
   render() {
     const { declaration } = this.props;
     const {
+      computedProperties,
       isEnabled,
       isKnownProperty,
       isOverridden,
       name,
       value,
     } = declaration;
 
     return (
@@ -39,19 +132,27 @@ class Declaration extends PureComponent 
             className: "ruleview-enableproperty theme-checkbox" +
                         (isEnabled ? " checked" : ""),
             tabIndex: -1,
           }),
           dom.span({ className: "ruleview-namecontainer" },
             dom.span({ className: "ruleview-propertyname theme-fg-color5" }, name),
             ": "
           ),
+          dom.span({
+            className: "ruleview-expander theme-twisty" +
+                       (this.state.isComputedListExpanded ? " open" : ""),
+            onClick: this.onComputedExpanderClick,
+            style: { display: computedProperties.length ? "inline-block" : "none" },
+          }),
           dom.span({ className: "ruleview-propertyvaluecontainer" },
             dom.span({ className: "ruleview-propertyvalue theme-fg-color1" }, value),
             ";"
           )
-        )
+        ),
+        this.renderComputedPropertyList(),
+        this.renderShorthandOverriddenList()
       )
     );
   }
 }
 
 module.exports = Declaration;
--- a/devtools/client/inspector/rules/components/Rule.js
+++ b/devtools/client/inspector/rules/components/Rule.js
@@ -22,25 +22,29 @@ class Rule extends PureComponent {
   }
 
   render() {
     const { rule } = this.props;
     const {
       declarations,
       selector,
       sourceLink,
+      type,
     } = rule;
 
     return (
       dom.div(
         { className: "ruleview-rule devtools-monospace" },
         SourceLink({ sourceLink }),
         dom.div({ className: "ruleview-code" },
           dom.div({},
-            Selector({ selector }),
+            Selector({
+              selector,
+              type,
+            }),
             dom.span({ className: "ruleview-ruleopen" }, " {")
           ),
           Declarations({ declarations }),
           dom.div({ className: "ruleview-ruleclose" }, "}")
         )
       )
     );
   }
--- a/devtools/client/inspector/rules/components/Selector.js
+++ b/devtools/client/inspector/rules/components/Selector.js
@@ -3,33 +3,96 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 "use strict";
 
 const { PureComponent } = require("devtools/client/shared/vendor/react");
 const dom = require("devtools/client/shared/vendor/react-dom-factories");
 const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
 
+const {
+  parsePseudoClassesAndAttributes,
+  SELECTOR_ATTRIBUTE,
+  SELECTOR_ELEMENT,
+  SELECTOR_PSEUDO_CLASS,
+} = require("devtools/shared/css/parsing-utils");
+const {
+  ELEMENT_STYLE,
+  PSEUDO_CLASSES,
+} = require("devtools/client/inspector/rules/constants");
+
 const Types = require("../types");
 
 class Selector extends PureComponent {
   static get propTypes() {
     return {
       selector: PropTypes.shape(Types.selector).isRequired,
+      type: PropTypes.number.isRequired,
     };
   }
 
+  renderSelector() {
+    // Show the text directly for custom selector text (such as the inline "element"
+    // style and Keyframes rules).
+    if (this.props.type === ELEMENT_STYLE || this.props.type === CSSRule.KEYFRAME_RULE) {
+      return this.props.selector.selectorText;
+    }
+
+    const { matchedSelectors, selectors } = this.props.selector;
+    const output = [];
+
+    // Go through the CSS rule's selectors and highlight the selectors that actually
+    // matches.
+    for (let i = 0; i < selectors.length; i++) {
+      const selector = selectors[i];
+
+      // Parse the selector for pseudo classes and attributes, and apply different
+      // CSS classes for the parsed values.
+      // NOTE: parsePseudoClassesAndAttributes is a good candidate for memoization.
+      const parsedSelector = parsePseudoClassesAndAttributes(selector);
+      for (const parsedText of parsedSelector) {
+        let selectorSpanClass = matchedSelectors.indexOf(selector) > -1 ?
+          "ruleview-selector-matched" : "ruleview-selector-unmatched";
+
+        switch (parsedText.type) {
+          case SELECTOR_ATTRIBUTE:
+            selectorSpanClass += " ruleview-selector-attribute";
+            break;
+          case SELECTOR_ELEMENT:
+            selectorSpanClass += " ruleview-selector";
+            break;
+          case SELECTOR_PSEUDO_CLASS:
+            selectorSpanClass += PSEUDO_CLASSES.some(p => parsedText.value === p) ?
+              " ruleview-selector-pseudo-class-lock" :
+              " ruleview-selector-pseudo-class";
+            break;
+        }
+
+        output.push(
+          dom.span({ className: selectorSpanClass }, parsedText.value)
+        );
+      }
+
+      // Append a comma separator unless this is the last selector.
+      if (i < selectors.length - 1) {
+        output.push(
+          dom.span({ className: "ruleview-selector-separator" }, ", ")
+        );
+      }
+    }
+
+    return output;
+  }
+
   render() {
-    const { selectorText } = this.props.selector;
-
     return (
       dom.span(
         {
           className: "ruleview-selectorcontainer",
-          tabIndex: -1,
+          tabIndex: 0,
         },
-        selectorText
+        this.renderSelector()
       )
     );
   }
 }
 
 module.exports = Selector;
new file mode 100644
--- /dev/null
+++ b/devtools/client/inspector/rules/constants.js
@@ -0,0 +1,13 @@
+/* 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/. */
+
+"use strict";
+
+// The PageStyle actor flattens the DOM CSS objects a little bit, merging
+// Rules and their Styles into one actor. For elements (which have a style
+// but no associated rule) we fake a rule with the following style id.
+exports.ELEMENT_STYLE = 100;
+
+// Pseudo classes in the pseudo class panel.
+exports.PSEUDO_CLASSES = [":active", ":focus", ":focus-within", ":hover"];
--- a/devtools/client/inspector/rules/models/rule.js
+++ b/devtools/client/inspector/rules/models/rule.js
@@ -76,17 +76,17 @@ Rule.prototype = {
       inheritedSource: this.inheritedSource,
     };
   },
 
   get selector() {
     return {
       matchedSelectors: this.matchedSelectors,
       selectors: this.domRule.selectors,
-      selectorText: this.selectorText,
+      selectorText: this.keyframes ? this.domRule.keyText : this.selectorText,
     };
   },
 
   get sourceLink() {
     return {
       column: this.ruleColumn,
       line: this.ruleLine,
       mediaText: this.mediaText,
--- a/devtools/client/inspector/rules/models/text-property.js
+++ b/devtools/client/inspector/rules/models/text-property.js
@@ -44,23 +44,26 @@ function TextProperty(rule, name, value,
   this.cssProperties = this.rule.elementStyle.ruleView.cssProperties;
   this.panelDoc = this.rule.elementStyle.ruleView.inspector.panelDoc;
 
   this.updateComputed();
 }
 
 TextProperty.prototype = {
   get computedProperties() {
-    return this.computed.map(computed => {
-      return {
-        name: computed.name,
-        priority: computed.priority,
-        value: computed.value,
-      };
-    });
+    return this.computed
+      .filter(computed => computed.name !== this.name)
+      .map(computed => {
+        return {
+          isOverridden: computed.overridden,
+          name: computed.name,
+          priority: computed.priority,
+          value: computed.value,
+        };
+      });
   },
 
   /**
    * See whether this property's name is known.
    *
    * @return {Boolean} true if the property name is known, false otherwise.
    */
   get isKnownProperty() {
--- a/devtools/client/inspector/rules/moz.build
+++ b/devtools/client/inspector/rules/moz.build
@@ -9,16 +9,17 @@ DIRS += [
     'components',
     'models',
     'reducers',
     'utils',
     'views',
 ]
 
 DevToolsModules(
+    'constants.js',
     'new-rules.js',
     'rules.js',
     'types.js',
 )
 
 BROWSER_CHROME_MANIFESTS += ['test/browser.ini']
 
 with Files('**'):
--- a/devtools/client/inspector/rules/types.js
+++ b/devtools/client/inspector/rules/types.js
@@ -7,16 +7,18 @@
 const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
 
 /**
  * A CSS declaration.
  */
 const declaration = exports.declaration = {
   // Array of the computed properties for a CSS declaration.
   computedProperties: PropTypes.arrayOf(PropTypes.shape({
+    // Whether or not the computed property is overridden.
+    isOverridden: PropTypes.bool,
     // The computed property name.
     name: PropTypes.string,
     // The computed priority (either "important" or an empty string).
     priority: PropTypes.string,
     // The computed property value.
     value: PropTypes.string,
   })),
 
--- a/dom/base/WindowNamedPropertiesHandler.cpp
+++ b/dom/base/WindowNamedPropertiesHandler.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 "WindowNamedPropertiesHandler.h"
 #include "mozilla/dom/EventTargetBinding.h"
 #include "mozilla/dom/WindowBinding.h"
+#include "mozilla/dom/WindowProxyHolder.h"
 #include "nsContentUtils.h"
 #include "nsDOMWindowList.h"
 #include "nsGlobalWindow.h"
 #include "nsHTMLDocument.h"
 #include "nsJSUtils.h"
 #include "xpcprivate.h"
 
 namespace mozilla {
--- a/gfx/layers/wr/AsyncImagePipelineManager.cpp
+++ b/gfx/layers/wr/AsyncImagePipelineManager.cpp
@@ -395,17 +395,18 @@ void AsyncImagePipelineManager::ApplyAsy
   aPipeline->mIsChanged = false;
 
   wr::LayoutSize contentSize{aPipeline->mScBounds.Width(),
                              aPipeline->mScBounds.Height()};
   wr::DisplayListBuilder builder(aPipelineId, contentSize);
 
   float opacity = 1.0f;
   Maybe<wr::WrSpatialId> referenceFrameId = builder.PushStackingContext(
-      wr::ToRoundedLayoutRect(aPipeline->mScBounds), nullptr, nullptr, &opacity,
+      wr::ToRoundedLayoutRect(aPipeline->mScBounds),
+      wr::WrStackingContextClip::None(), nullptr, &opacity,
       aPipeline->mScTransform.IsIdentity() ? nullptr : &aPipeline->mScTransform,
       wr::TransformStyle::Flat, nullptr, aPipeline->mMixBlendMode,
       nsTArray<wr::FilterOp>(), true,
       // This is fine to do unconditionally because we only push images here.
       wr::RasterSpace::Screen());
 
   Maybe<wr::SpaceAndClipChainHelper> spaceAndClipChainHelper;
   if (referenceFrameId) {
--- a/gfx/layers/wr/StackingContextHelper.cpp
+++ b/gfx/layers/wr/StackingContextHelper.cpp
@@ -26,17 +26,17 @@ StackingContextHelper::StackingContextHe
     nsIFrame* aContainerFrame, nsDisplayItem* aContainerItem,
     wr::DisplayListBuilder& aBuilder, const nsTArray<wr::FilterOp>& aFilters,
     const LayoutDeviceRect& aBounds, const gfx::Matrix4x4* aBoundTransform,
     const wr::WrAnimationProperty* aAnimation, const float* aOpacityPtr,
     const gfx::Matrix4x4* aTransformPtr, const gfx::Matrix4x4* aPerspectivePtr,
     const gfx::CompositionOp& aMixBlendMode, bool aBackfaceVisible,
     bool aIsPreserve3D,
     const Maybe<nsDisplayTransform*>& aDeferredTransformItem,
-    const wr::WrClipId* aClipNodeId, bool aAnimated)
+    const wr::WrStackingContextClip& aClip, bool aAnimated)
     : mBuilder(&aBuilder),
       mScale(1.0f, 1.0f),
       mDeferredTransformItem(aDeferredTransformItem),
       mIsPreserve3D(aIsPreserve3D),
       mRasterizeLocally(aAnimated || aParentSC.mRasterizeLocally) {
   // Compute scale for fallback rendering. We don't try to guess a scale for 3d
   // transformed items
   gfx::Matrix transform2d;
@@ -63,18 +63,17 @@ StackingContextHelper::StackingContextHe
   }
 
   auto rasterSpace =
       mRasterizeLocally
           ? wr::RasterSpace::Local(std::max(mScale.width, mScale.height))
           : wr::RasterSpace::Screen();
 
   mReferenceFrameId = mBuilder->PushStackingContext(
-      wr::ToLayoutRect(aBounds), aClipNodeId, aAnimation, aOpacityPtr,
-      aTransformPtr,
+      wr::ToLayoutRect(aBounds), aClip, aAnimation, aOpacityPtr, aTransformPtr,
       aIsPreserve3D ? wr::TransformStyle::Preserve3D : wr::TransformStyle::Flat,
       aPerspectivePtr, wr::ToMixBlendMode(aMixBlendMode), aFilters,
       aBackfaceVisible, rasterSpace);
 
   if (mReferenceFrameId) {
     mSpaceAndClipChainHelper.emplace(aBuilder, mReferenceFrameId.ref());
   }
 
--- a/gfx/layers/wr/StackingContextHelper.h
+++ b/gfx/layers/wr/StackingContextHelper.h
@@ -36,17 +36,18 @@ class MOZ_RAII StackingContextHelper {
       const gfx::Matrix4x4* aBoundTransform = nullptr,
       const wr::WrAnimationProperty* aAnimation = nullptr,
       const float* aOpacityPtr = nullptr,
       const gfx::Matrix4x4* aTransformPtr = nullptr,
       const gfx::Matrix4x4* aPerspectivePtr = nullptr,
       const gfx::CompositionOp& aMixBlendMode = gfx::CompositionOp::OP_OVER,
       bool aBackfaceVisible = true, bool aIsPreserve3D = false,
       const Maybe<nsDisplayTransform*>& aDeferredTransformItem = Nothing(),
-      const wr::WrClipId* aClipNodeId = nullptr, bool aAnimated = false);
+      const wr::WrStackingContextClip& = wr::WrStackingContextClip::None(),
+      bool aAnimated = false);
   // This version of the constructor should only be used at the root level
   // of the tree, so that we have a StackingContextHelper to pass down into
   // the RenderLayer traversal, but don't actually want it to push a stacking
   // context on the display list builder.
   StackingContextHelper();
 
   // Pops the stacking context, if one was pushed during the constructor.
   ~StackingContextHelper();
--- a/gfx/webrender_bindings/WebRenderAPI.cpp
+++ b/gfx/webrender_bindings/WebRenderAPI.cpp
@@ -15,17 +15,18 @@
 #include "mozilla/widget/CompositorWidget.h"
 #include "mozilla/layers/SynchronousTask.h"
 #include "TextDrawTarget.h"
 
 #define WRDL_LOG(...)
 
 //#define WRDL_LOG(...) printf_stderr("WRDL(%p): " __VA_ARGS__)
 
-//#define WRDL_LOG(...) if (XRE_IsContentProcess()) printf_stderr("WRDL(%p): " __VA_ARGS__)
+//#define WRDL_LOG(...) if (XRE_IsContentProcess()) printf_stderr("WRDL(%p): "
+//__VA_ARGS__)
 
 namespace mozilla {
 namespace wr {
 
 using layers::Stringify;
 
 MOZ_DEFINE_MALLOC_SIZE_OF(WebRenderMallocSizeOf)
 MOZ_DEFINE_MALLOC_ENCLOSING_SIZE_OF(WebRenderMallocEnclosingSizeOf)
@@ -667,17 +668,17 @@ usize DisplayListBuilder::Dump(usize aIn
 
 void DisplayListBuilder::Finalize(wr::LayoutSize& aOutContentSize,
                                   BuiltDisplayList& aOutDisplayList) {
   wr_api_finalize_builder(mWrState, &aOutContentSize, &aOutDisplayList.dl_desc,
                           &aOutDisplayList.dl.inner);
 }
 
 Maybe<wr::WrSpatialId> DisplayListBuilder::PushStackingContext(
-    const wr::LayoutRect& aBounds, const wr::WrClipId* aClipNodeId,
+    const wr::LayoutRect& aBounds, const wr::WrStackingContextClip& aClip,
     const WrAnimationProperty* aAnimation, const float* aOpacity,
     const gfx::Matrix4x4* aTransform, wr::TransformStyle aTransformStyle,
     const gfx::Matrix4x4* aPerspective, const wr::MixBlendMode& aMixBlendMode,
     const nsTArray<wr::FilterOp>& aFilters, bool aIsBackfaceVisible,
     const wr::RasterSpace& aRasterSpace) {
   MOZ_ASSERT(mClipChainLeaf.isNothing(),
              "Non-empty leaf from clip chain given, but not used with SC!");
 
@@ -693,18 +694,18 @@ Maybe<wr::WrSpatialId> DisplayListBuilde
 
   const wr::LayoutTransform* maybePerspective =
       aPerspective ? &perspective : nullptr;
   WRDL_LOG("PushStackingContext b=%s t=%s\n", mWrState,
            Stringify(aBounds).c_str(),
            aTransform ? Stringify(*aTransform).c_str() : "none");
 
   auto spatialId = wr_dp_push_stacking_context(
-      mWrState, aBounds, mCurrentSpaceAndClipChain.space, aClipNodeId,
-      aAnimation, aOpacity, maybeTransform, aTransformStyle, maybePerspective,
+      mWrState, aBounds, mCurrentSpaceAndClipChain.space, &aClip, aAnimation,
+      aOpacity, maybeTransform, aTransformStyle, maybePerspective,
       aMixBlendMode, aFilters.Elements(), aFilters.Length(), aIsBackfaceVisible,
       aRasterSpace);
 
   return spatialId.id != 0 ? Some(spatialId) : Nothing();
 }
 
 void DisplayListBuilder::PopStackingContext(bool aIsReferenceFrame) {
   WRDL_LOG("PopStackingContext\n", mWrState);
--- a/gfx/webrender_bindings/WebRenderAPI.h
+++ b/gfx/webrender_bindings/WebRenderAPI.h
@@ -324,19 +324,18 @@ class DisplayListBuilder {
   void ClearSave();
   usize Dump(usize aIndent, const Maybe<usize>& aStart,
              const Maybe<usize>& aEnd);
 
   void Finalize(wr::LayoutSize& aOutContentSize,
                 wr::BuiltDisplayList& aOutDisplayList);
 
   Maybe<wr::WrSpatialId> PushStackingContext(
-      const wr::LayoutRect&
-          aBounds,  // TODO: We should work with strongly typed rects
-      const wr::WrClipId* aClipNodeId,
+      // TODO: We should work with strongly typed rects
+      const wr::LayoutRect& aBounds, const wr::WrStackingContextClip& aClip,
       const wr::WrAnimationProperty* aAnimation, const float* aOpacity,
       const gfx::Matrix4x4* aTransform, wr::TransformStyle aTransformStyle,
       const gfx::Matrix4x4* aPerspective, const wr::MixBlendMode& aMixBlendMode,
       const nsTArray<wr::FilterOp>& aFilters, bool aIsBackfaceVisible,
       const wr::RasterSpace& aRasterSpace);
   void PopStackingContext(bool aIsReferenceFrame);
 
   wr::WrClipChainId DefineClipChain(const Maybe<wr::WrClipChainId>& aParent,
@@ -481,16 +480,20 @@ class DisplayListBuilder {
   void PushBoxShadow(const wr::LayoutRect& aRect, const wr::LayoutRect& aClip,
                      bool aIsBackfaceVisible, const wr::LayoutRect& aBoxBounds,
                      const wr::LayoutVector2D& aOffset,
                      const wr::ColorF& aColor, const float& aBlurRadius,
                      const float& aSpreadRadius,
                      const wr::BorderRadius& aBorderRadius,
                      const wr::BoxShadowClipMode& aClipMode);
 
+  uint64_t CurrentClipChainId() const {
+    return mCurrentSpaceAndClipChain.clip_chain;
+  }
+
   // Checks to see if the innermost enclosing fixed pos item has the same
   // ASR. If so, it returns the scroll target for that fixed-pos item.
   // Otherwise, it returns Nothing().
   Maybe<layers::ScrollableLayerGuid::ViewID> GetContainingFixedPosScrollTarget(
       const ActiveScrolledRoot* aAsr);
 
   // Set the hit-test info to be used for all display items until the next call
   // to SetHitTestInfo or ClearHitTestInfo.
--- a/gfx/webrender_bindings/src/bindings.rs
+++ b/gfx/webrender_bindings/src/bindings.rs
@@ -135,36 +135,57 @@ impl WrSpaceAndClip {
     fn to_webrender(&self, pipeline_id: WrPipelineId) -> SpaceAndClipInfo {
         SpaceAndClipInfo {
             spatial_id: self.space.to_webrender(pipeline_id),
             clip_id: self.clip.to_webrender(pipeline_id),
         }
     }
 }
 
+#[inline]
+fn clip_chain_id_to_webrender(id: u64, pipeline_id: WrPipelineId) -> ClipId {
+    if id == ROOT_CLIP_CHAIN {
+        ClipId::root(pipeline_id)
+    } else {
+        ClipId::ClipChain(ClipChainId(id, pipeline_id))
+    }
+}
+
 #[repr(C)]
 pub struct WrSpaceAndClipChain {
     space: WrSpatialId,
     clip_chain: u64,
 }
 
 impl WrSpaceAndClipChain {
     fn to_webrender(&self, pipeline_id: WrPipelineId) -> SpaceAndClipInfo {
         //Warning: special case here to support dummy clip chain
         SpaceAndClipInfo {
             spatial_id: self.space.to_webrender(pipeline_id),
-            clip_id: if self.clip_chain == ROOT_CLIP_CHAIN {
-                ClipId::root(pipeline_id)
-            } else {
-                ClipId::ClipChain(ClipChainId(self.clip_chain, pipeline_id))
-            },
+            clip_id: clip_chain_id_to_webrender(self.clip_chain, pipeline_id),
         }
     }
 }
 
+#[repr(C)]
+pub enum WrStackingContextClip {
+    None,
+    ClipId(WrClipId),
+    ClipChain(u64),
+}
+
+impl WrStackingContextClip {
+    fn to_webrender(&self, pipeline_id: WrPipelineId) -> Option<ClipId> {
+        match *self {
+            WrStackingContextClip::None => None,
+            WrStackingContextClip::ClipChain(id) => Some(clip_chain_id_to_webrender(id, pipeline_id)),
+            WrStackingContextClip::ClipId(id) => Some(id.to_webrender(pipeline_id)),
+        }
+    }
+}
 
 fn make_slice<'a, T>(ptr: *const T, len: usize) -> &'a [T] {
     if ptr.is_null() {
         &[]
     } else {
         unsafe { slice::from_raw_parts(ptr, len) }
     }
 }
@@ -1869,40 +1890,39 @@ pub extern "C" fn wr_dp_restore(state: &
 }
 
 #[no_mangle]
 pub extern "C" fn wr_dp_clear_save(state: &mut WrState) {
     state.frame_builder.dl_builder.clear_save();
 }
 
 #[no_mangle]
-pub extern "C" fn wr_dp_push_stacking_context(state: &mut WrState,
-                                              mut bounds: LayoutRect,
-                                              spatial_id: WrSpatialId,
-                                              clip_node_id: *const WrClipId,
-                                              animation: *const WrAnimationProperty,
-                                              opacity: *const f32,
-                                              transform: *const LayoutTransform,
-                                              transform_style: TransformStyle,
-                                              perspective: *const LayoutTransform,
-                                              mix_blend_mode: MixBlendMode,
-                                              filters: *const FilterOp,
-                                              filter_count: usize,
-                                              is_backface_visible: bool,
-                                              glyph_raster_space: RasterSpace,
-                                              ) -> WrSpatialId {
+pub extern "C" fn wr_dp_push_stacking_context(
+    state: &mut WrState,
+    mut bounds: LayoutRect,
+    spatial_id: WrSpatialId,
+    clip: &WrStackingContextClip,
+    animation: *const WrAnimationProperty,
+    opacity: *const f32,
+    transform: *const LayoutTransform,
+    transform_style: TransformStyle,
+    perspective: *const LayoutTransform,
+    mix_blend_mode: MixBlendMode,
+    filters: *const FilterOp,
+    filter_count: usize,
+    is_backface_visible: bool,
+    glyph_raster_space: RasterSpace,
+) -> WrSpatialId {
     debug_assert!(unsafe { !is_in_render_thread() });
 
     let c_filters = make_slice(filters, filter_count);
     let mut filters : Vec<FilterOp> = c_filters.iter().map(|c_filter| {
                                                            *c_filter
     }).collect();
 
-    let clip_node_id_ref = unsafe { clip_node_id.as_ref() };
-
     let transform_ref = unsafe { transform.as_ref() };
     let mut transform_binding = match transform_ref {
         Some(transform) => Some(PropertyBinding::Value(transform.clone())),
         None => None,
     };
 
     let opacity_ref = unsafe { opacity.as_ref() };
     let mut has_opacity_animation = false;
@@ -1937,17 +1957,17 @@ pub extern "C" fn wr_dp_push_stacking_co
 
     let perspective_ref = unsafe { perspective.as_ref() };
     let perspective = match perspective_ref {
         Some(perspective) => Some(perspective.clone()),
         None => None,
     };
 
     let mut wr_spatial_id = spatial_id.to_webrender(state.pipeline_id);
-    let wr_clip_id = clip_node_id_ref.map(|id| id.to_webrender(state.pipeline_id));
+    let wr_clip_id = clip.to_webrender(state.pipeline_id);
 
     let is_reference_frame = transform_binding.is_some() || perspective.is_some();
     // Note: 0 has special meaning in WR land, standing for ROOT_REFERENCE_FRAME.
     // However, it is never returned by `push_reference_frame`, and we need to return
     // an option here across FFI, so we take that 0 value for the None semantics.
     // This is resolved into proper `Maybe<WrSpatialId>` inside `WebRenderAPI::PushStackingContext`.
     let mut result = WrSpatialId { id: 0 };
     if is_reference_frame {
--- a/gfx/webrender_bindings/webrender_ffi_generated.h
+++ b/gfx/webrender_bindings/webrender_ffi_generated.h
@@ -834,16 +834,91 @@ struct Shadow {
 
   bool operator==(const Shadow& aOther) const {
     return offset == aOther.offset &&
            color == aOther.color &&
            blur_radius == aOther.blur_radius;
   }
 };
 
+struct WrStackingContextClip {
+  enum class Tag {
+    None,
+    ClipId,
+    ClipChain,
+
+    Sentinel /* this must be last for serialization purposes. */
+  };
+
+  struct ClipId_Body {
+    WrClipId _0;
+
+    bool operator==(const ClipId_Body& aOther) const {
+      return _0 == aOther._0;
+    }
+  };
+
+  struct ClipChain_Body {
+    uint64_t _0;
+
+    bool operator==(const ClipChain_Body& aOther) const {
+      return _0 == aOther._0;
+    }
+  };
+
+  Tag tag;
+  union {
+    ClipId_Body clip_id;
+    ClipChain_Body clip_chain;
+  };
+
+  static WrStackingContextClip None() {
+    WrStackingContextClip result;
+    result.tag = Tag::None;
+    return result;
+  }
+
+  static WrStackingContextClip ClipId(const WrClipId &a0) {
+    WrStackingContextClip result;
+    result.clip_id._0 = a0;
+    result.tag = Tag::ClipId;
+    return result;
+  }
+
+  static WrStackingContextClip ClipChain(const uint64_t &a0) {
+    WrStackingContextClip result;
+    result.clip_chain._0 = a0;
+    result.tag = Tag::ClipChain;
+    return result;
+  }
+
+  bool IsNone() const {
+    return tag == Tag::None;
+  }
+
+  bool IsClipId() const {
+    return tag == Tag::ClipId;
+  }
+
+  bool IsClipChain() const {
+    return tag == Tag::ClipChain;
+  }
+
+  bool operator==(const WrStackingContextClip& aOther) const {
+    if (tag != aOther.tag) {
+      return false;
+    }
+    switch (tag) {
+      case Tag::ClipId: return clip_id == aOther.clip_id;
+      case Tag::ClipChain: return clip_chain == aOther.clip_chain;
+      default: return true;
+    }
+  }
+};
+
 struct WrAnimationProperty {
   WrAnimationType effect_type;
   uint64_t id;
 
   bool operator==(const WrAnimationProperty& aOther) const {
     return effect_type == aOther.effect_type &&
            id == aOther.id;
   }
@@ -1932,17 +2007,17 @@ void wr_dp_push_shadow(WrState *aState,
                        const WrSpaceAndClipChain *aParent,
                        Shadow aShadow)
 WR_FUNC;
 
 WR_INLINE
 WrSpatialId wr_dp_push_stacking_context(WrState *aState,
                                         LayoutRect aBounds,
                                         WrSpatialId aSpatialId,
-                                        const WrClipId *aClipNodeId,
+                                        const WrStackingContextClip *aClip,
                                         const WrAnimationProperty *aAnimation,
                                         const float *aOpacity,
                                         const LayoutTransform *aTransform,
                                         TransformStyle aTransformStyle,
                                         const LayoutTransform *aPerspective,
                                         MixBlendMode aMixBlendMode,
                                         const FilterOp *aFilters,
                                         uintptr_t aFilterCount,
--- a/js/examples/jorendb.js
+++ b/js/examples/jorendb.js
@@ -859,33 +859,37 @@ while(args.length > 0) {
 print("jorendb: scriptPath = " + scriptPath);
 print("jorendb: scriptArgs = " + scriptArgs);
 print("jorendb: actualScriptArgs = " + actualScriptArgs);
 
 for (var task of todo) {
     task['scriptArgs'] = actualScriptArgs;
 }
 
-// If nothing to run, just drop into a repl
-if (todo.length == 0) {
-    todo.push({ 'action': 'repl' });
-}
+// Always drop into a repl at the end. Especially if the main script throws an
+// exception.
+todo.push({ 'action': 'repl' });
 
 while (rerun) {
     print("Top of run loop");
     rerun = false;
     for (var task of todo) {
         activeTask = task;
         if (task.action == 'eval') {
             debuggeeGlobal.eval(task.code);
         } else if (task.action == 'load') {
             debuggeeGlobal['scriptArgs'] = task.scriptArgs;
             debuggeeGlobal['scriptPath'] = task.script;
             print("Loading JavaScript file " + task.script);
-            debuggeeGlobal.evaluate(read(task.script), { 'fileName': task.script, 'lineNumber': 1 });
+            try {
+                debuggeeGlobal.evaluate(read(task.script), { 'fileName': task.script, 'lineNumber': 1 });
+            } catch (exc) {
+                print("Caught exception " + exc);
+                print(exc.stack);
+            }
         } else if (task.action == 'repl') {
             repl();
         }
         if (rerun)
             break;
     }
 }
 
--- a/js/src/builtin/ModuleObject.cpp
+++ b/js/src/builtin/ModuleObject.cpp
@@ -368,24 +368,25 @@ bool IndirectBindingMap::lookup(jsid nam
 
 /* static */ ModuleNamespaceObject* ModuleNamespaceObject::create(
     JSContext* cx, HandleModuleObject module, HandleObject exports,
     UniquePtr<IndirectBindingMap> bindings) {
   RootedValue priv(cx, ObjectValue(*module));
   ProxyOptions options;
   options.setLazyProto(true);
   options.setSingleton(true);
+  Rooted<UniquePtr<IndirectBindingMap>> rootedBindings(cx, std::move(bindings));
   RootedObject object(
       cx, NewProxyObject(cx, &proxyHandler, priv, nullptr, options));
   if (!object) {
     return nullptr;
   }
 
   SetProxyReservedSlot(object, ExportsSlot, ObjectValue(*exports));
-  SetProxyReservedSlot(object, BindingsSlot, PrivateValue(bindings.release()));
+  SetProxyReservedSlot(object, BindingsSlot, PrivateValue(rootedBindings.release()));
 
   return &object->as<ModuleNamespaceObject>();
 }
 
 ModuleObject& ModuleNamespaceObject::module() {
   return GetProxyPrivate(this).toObject().as<ModuleObject>();
 }
 
--- a/js/src/devtools/rootAnalysis/explain.py
+++ b/js/src/devtools/rootAnalysis/explain.py
@@ -1,12 +1,14 @@
-#!/usr/bin/python
+#!/usr/bin/python3
 
+from __future__ import print_function
+
+import argparse
 import re
-import argparse
 
 from collections import defaultdict
 
 parser = argparse.ArgumentParser(description='Process some integers.')
 parser.add_argument('rootingHazards', nargs='?', default='rootingHazards.txt')
 parser.add_argument('gcFunctions', nargs='?', default='gcFunctions.txt')
 parser.add_argument('hazards', nargs='?', default='hazards.txt')
 parser.add_argument('extra', nargs='?', default='unnecessary.txt')
@@ -29,30 +31,30 @@ try:
         # List of tuples (gcFunction, index of hazard) used to maintain the
         # ordering of the hazards
         hazardOrder = []
 
         for line in rootingHazards:
             m = re.match(r'^Time: (.*)', line)
             mm = re.match(r'^Run on:', line)
             if m or mm:
-                print >>hazards, line
-                print >>extra, line
-                print >>refs, line
+                print(line, file=hazards)
+                print(line, file=extra)
+                print(line, file=refs)
                 continue
 
             m = re.match(r'^Function.*has unnecessary root', line)
             if m:
-                print >>extra, line
+                print(line, file=extra)
                 continue
 
             m = re.match(r'^Function.*takes unsafe address of unrooted', line)
             if m:
                 num_refs += 1
-                print >>refs, line
+                print(line, file=refs)
                 continue
 
             m = re.match(
                 r"^Function.*has unrooted.*of type.*live across GC call ('?)(.*?)('?) at \S+:\d+$", line)  # NOQA: E501
             if m:
                 # Function names are surrounded by single quotes. Field calls
                 # are unquoted.
                 current_gcFunction = m.group(2)
@@ -87,19 +89,19 @@ try:
                     explanation += line
             if current_func:
                 gcExplanations[current_func] = explanation
 
         for gcFunction, index in hazardOrder:
             gcHazards = hazardousGCFunctions[gcFunction]
 
             if gcFunction in gcExplanations:
-                print >>hazards, (gcHazards[index] + gcExplanations[gcFunction])
+                print(gcHazards[index] + gcExplanations[gcFunction], file=hazards)
             else:
-                print >>hazards, gcHazards[index]
+                print(gcHazards[index], file=hazards)
 
 except IOError as e:
     print('Failed: %s' % str(e))
 
 print("Wrote %s" % args.hazards)
 print("Wrote %s" % args.extra)
 print("Wrote %s" % args.refs)
 print("Found %d hazards and %d unsafe references" % (num_hazards, num_refs))
--- a/layout/generic/ScrollAnchorContainer.cpp
+++ b/layout/generic/ScrollAnchorContainer.cpp
@@ -1,16 +1,17 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* 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 "ScrollAnchorContainer.h"
 
+#include "mozilla/dom/Text.h"
 #include "mozilla/StaticPrefs.h"
 #include "nsGfxScrollFrame.h"
 #include "nsLayoutUtils.h"
 
 #define ANCHOR_LOG(...)
 // #define ANCHOR_LOG(...) printf_stderr("ANCHOR: " __VA_ARGS__)
 
 namespace mozilla {
@@ -82,17 +83,17 @@ static void SetAnchorFlags(const nsIFram
  *
  * [1]
  * https://drafts.csswg.org/css-scroll-anchoring-1/#scroll-anchoring-bounding-rect
  * [2] https://github.com/w3c/csswg-drafts/issues/3478
  */
 static nsRect FindScrollAnchoringBoundingRect(const nsIFrame* aScrollFrame,
                                               nsIFrame* aCandidate) {
   MOZ_ASSERT(nsLayoutUtils::IsProperAncestorFrame(aScrollFrame, aCandidate));
-  if (aCandidate->GetContent()->IsText()) {
+  if (!!Text::FromNodeOrNull(aCandidate->GetContent())) {
     nsRect bounding;
     for (nsIFrame* continuation = aCandidate->FirstContinuation(); continuation;
          continuation = continuation->GetNextContinuation()) {
       nsRect localRect =
           continuation->GetScrollableOverflowRectRelativeToSelf();
       nsRect transformed = nsLayoutUtils::TransformFrameRectToAncestor(
           continuation, localRect, aScrollFrame);
       bounding = bounding.Union(transformed);
@@ -341,17 +342,17 @@ ScrollAnchorContainer::ExamineAnchorCand
   // a different layout model than CSS, and the specification doesn't say it
   // should apply.
   //
   // [1] https://github.com/w3c/csswg-drafts/issues/3477
   bool canDescend = !scrollable && !aFrame->IsSVGOuterSVGFrame();
 
   // Check what kind of frame this is
   bool isBlockOutside = aFrame->IsBlockOutside();
-  bool isText = aFrame->GetContent()->IsText();
+  bool isText = !!Text::FromNodeOrNull(aFrame->GetContent());
   bool isAnonBox = aFrame->Style()->IsAnonBox() && !isText;
   bool isInlineOutside = aFrame->IsInlineOutside() && !isText;
   bool isContinuation = !!aFrame->GetPrevContinuation();
 
   // If the frame is anonymous or inline-outside, search its descendants for a
   // scroll anchor.
   if ((isAnonBox || isInlineOutside) && canDescend) {
     ANCHOR_LOG(
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -2921,17 +2921,30 @@ void nsIFrame::BuildDisplayListForStacki
     eSeparatorTransforms,
     eOpacity,
     eFilter,
     eBlendContainer
   };
 
   nsDisplayListBuilder::AutoContainerASRTracker contASRTracker(aBuilder);
 
-  DisplayListClipState::AutoSaveRestore clipState(aBuilder);
+  DisplayListClipState::AutoSaveRestore cssClip(aBuilder);
+  {
+    // The clip property clips everything, including filters and what not.
+    if (auto contentClip = GetClipPropClipRect(disp, effects, GetSize())) {
+      nsPoint offset = isTransformed
+                           ? GetOffsetToCrossDoc(
+                                 aBuilder->FindReferenceFrameFor(GetParent()))
+                           : aBuilder->GetCurrentFrameOffsetToReferenceFrame();
+
+      aBuilder->IntersectDirtyRect(*contentClip);
+      aBuilder->IntersectVisibleRect(*contentClip);
+      cssClip.ClipContentDescendants(*contentClip + offset);
+    }
+  }
 
   // If there is a current clip, then depending on the container items we
   // create, different things can happen to it. Some container items simply
   // propagate the clip to their children and aren't clipped themselves.
   // But other container items, especially those that establish a different
   // geometry for their contents (e.g. transforms), capture the clip on
   // themselves and unset the clip for their contents. If we create more than
   // one of those container items, the clip will be captured on the outermost
@@ -2954,48 +2967,42 @@ void nsIFrame::BuildDisplayListForStacki
       clipCapturedBy = ContainerItemType::ePerspective;
     } else {
       clipCapturedBy = ContainerItemType::eTransform;
     }
   } else if (usingFilter) {
     clipCapturedBy = ContainerItemType::eFilter;
   }
 
+  DisplayListClipState::AutoSaveRestore clipState(aBuilder);
   if (clipCapturedBy != ContainerItemType::eNone) {
     clipState.Clear();
   }
 
-  Maybe<nsRect> clipForMask;
-  if (usingMask) {
-    clipForMask = ComputeClipForMaskItem(aBuilder, this);
-  }
-
   mozilla::UniquePtr<HitTestInfo> hitTestInfo;
 
   nsDisplayListCollection set(aBuilder);
+  Maybe<nsRect> clipForMask;
   {
     DisplayListClipState::AutoSaveRestore nestedClipState(aBuilder);
     nsDisplayListBuilder::AutoInTransformSetter inTransformSetter(aBuilder,
                                                                   inTransform);
     nsDisplayListBuilder::AutoEnterFilter filterASRSetter(aBuilder,
                                                           usingFilter);
 
     CheckForApzAwareEventHandlers(aBuilder, this);
 
-    Maybe<nsRect> contentClip = GetClipPropClipRect(disp, effects, GetSize());
-
     if (usingMask) {
-      contentClip = IntersectMaybeRects(contentClip, clipForMask);
-    }
-
-    if (contentClip) {
-      aBuilder->IntersectDirtyRect(*contentClip);
-      aBuilder->IntersectVisibleRect(*contentClip);
-      nestedClipState.ClipContentDescendants(*contentClip +
-                                             aBuilder->ToReferenceFrame(this));
+      clipForMask = ComputeClipForMaskItem(aBuilder, this);
+      if (clipForMask) {
+        aBuilder->IntersectDirtyRect(*clipForMask);
+        aBuilder->IntersectVisibleRect(*clipForMask);
+        nestedClipState.ClipContentDescendants(
+            *clipForMask + aBuilder->GetCurrentFrameOffsetToReferenceFrame());
+      }
     }
 
     // extend3DContext also guarantees that applyAbsPosClipping and
     // usingSVGEffects are false We only modify the preserve-3d rect if we are
     // the top of a preserve-3d heirarchy
     if (extend3DContext) {
       // Mark these first so MarkAbsoluteFramesForDisplayList knows if we are
       // going to be forced to descend into frames.
--- a/layout/painting/nsDisplayList.cpp
+++ b/layout/painting/nsDisplayList.cpp
@@ -7874,17 +7874,17 @@ bool nsDisplayTransform::CreateWebRender
       ActiveLayerTracker::IsStyleMaybeAnimated(Frame(), eCSSProperty_transform);
 
   StackingContextHelper sc(
       aSc, GetActiveScrolledRoot(), mFrame, this, aBuilder, filters,
       LayoutDeviceRect(position, LayoutDeviceSize()), &newTransformMatrix,
       animationsId ? &prop : nullptr, nullptr, transformForSC, nullptr,
       gfx::CompositionOp::OP_OVER, !BackfaceIsHidden(),
       mFrame->Extend3DContext() && !mNoExtendContext, deferredTransformItem,
-      nullptr, animated);
+      wr::WrStackingContextClip::None(), animated);
 
   return mStoredList.CreateWebRenderCommands(aBuilder, aResources, sc, aManager,
                                              aDisplayListBuilder);
 }
 
 bool nsDisplayTransform::UpdateScrollData(
     mozilla::layers::WebRenderScrollData* aData,
     mozilla::layers::WebRenderLayerScrollData* aLayerData) {
@@ -9068,17 +9068,17 @@ bool nsDisplayMasksAndClipPaths::CreateW
                   /*aAnimation: */ nullptr,
                   /*aOpacity: */ opacity.ptrOr(nullptr),
                   /*aTransform: */ nullptr,
                   /*aPerspective: */ nullptr,
                   /*aMixBlendMode: */ gfx::CompositionOp::OP_OVER,
                   /*aBackfaceVisible: */ true,
                   /*aIsPreserve3D: */ false,
                   /*aTransformForScrollData: */ Nothing(),
-                  /*aClipNodeId: */ &clipId);
+                  /*aClip: */ wr::WrStackingContextClip::ClipId(clipId));
     sc = layer.ptr();
   }
 
   nsDisplayEffectsBase::CreateWebRenderCommands(aBuilder, aResources, *sc,
                                                 aManager, aDisplayListBuilder);
 
   return true;
 }
@@ -9345,25 +9345,23 @@ bool nsDisplayFilters::CreateWebRenderCo
 
   nsTArray<mozilla::wr::FilterOp> wrFilters;
   if (!CreateWebRenderCSSFilters(wrFilters) &&
       !nsSVGIntegrationUtils::BuildWebRenderFilters(
           mFrame, preFilterBounds, wrFilters, postFilterBounds)) {
     return false;
   }
 
-  wr::WrClipId clipId =
-      aBuilder.DefineClip(Nothing(), wr::ToLayoutRect(postFilterBounds));
-
   float opacity = mFrame->StyleEffects()->mOpacity;
   StackingContextHelper sc(
       aSc, GetActiveScrolledRoot(), mFrame, this, aBuilder, wrFilters,
       LayoutDeviceRect(), nullptr, nullptr,
       opacity != 1.0f && mHandleOpacity ? &opacity : nullptr, nullptr, nullptr,
-      gfx::CompositionOp::OP_OVER, true, false, Nothing(), &clipId);
+      gfx::CompositionOp::OP_OVER, true, false, Nothing(),
+      wr::WrStackingContextClip::ClipChain(aBuilder.CurrentClipChainId()));
 
   nsDisplayEffectsBase::CreateWebRenderCommands(aBuilder, aResources, sc,
                                                 aManager, aDisplayListBuilder);
 
   return true;
 }
 
 #ifdef MOZ_DUMP_PAINTING
--- a/toolkit/modules/subprocess/test/xpcshell/test_subprocess.js
+++ b/toolkit/modules/subprocess/test/xpcshell/test_subprocess.js
@@ -177,17 +177,17 @@ add_task(async function test_subprocess_
 
 
   let {exitCode} = await proc.wait();
 
   equal(exitCode, 0, "Got expected exit code");
 });
 
 
-add_task(async function test_subprocess_round_trip_perf() {
+add_task({skip_if: () => mozinfo.ccov}, async function test_subprocess_round_trip_perf() {
   let roundTripTime = Infinity;
   for (let i = 0; i < MAX_RETRIES && roundTripTime > MAX_ROUND_TRIP_TIME_MS; i++) {
     let proc = await Subprocess.call({
       command: PYTHON,
       arguments: ["-u", TEST_SCRIPT, "echo"],
     });
 
 
--- a/tools/fuzzing/faulty/Faulty.cpp
+++ b/tools/fuzzing/faulty/Faulty.cpp
@@ -209,27 +209,22 @@ Faulty::Faulty()
   }
 }
 
 // static
 bool Faulty::IsValidProcessType(void) {
   bool isValidProcessType;
   const bool targetChildren = !!PR_GetEnv("FAULTY_CHILDREN");
   const bool targetParent = !!PR_GetEnv("FAULTY_PARENT");
-  unsigned short int currentProcessType = XRE_GetProcessType();
+  const bool isParent = XRE_IsParentProcess();
 
   if (targetChildren && !targetParent) {
     // Fuzz every child process type but not the parent process.
-    isValidProcessType = currentProcessType == GeckoProcessType_Default;
-  } else if (!targetChildren && targetParent &&
-             (currentProcessType == GeckoProcessType_Plugin ||
-              currentProcessType == GeckoProcessType_Content ||
-              currentProcessType == GeckoProcessType_GMPlugin ||
-              currentProcessType == GeckoProcessType_GPU ||
-              currentProcessType == GeckoProcessType_VR)) {
+    isValidProcessType = isParent;
+  } else if (!targetChildren && targetParent && !isParent) {
     // Fuzz inside any of the above child process only.
     isValidProcessType = true;
   } else if (targetChildren && targetParent) {
     // Fuzz every process type.
     isValidProcessType = true;
   } else {
     // Fuzz no process type at all.
     isValidProcessType = false;