Merge mozilla-central to autoland a=merge on a CLOSED TREE
authorCoroiu Cristina <ccoroiu@mozilla.com>
Thu, 05 Jul 2018 03:33:16 +0300
changeset 425146 ca35db7e2619a2bea6550fe716152ab8d460e664
parent 425145 4312952f4b2a9d7aaf1ce6cbd2c2fb2834711f7d (current diff)
parent 425129 90be04d99fc7941cb9b7186bf5f95e184a4e989a (diff)
child 425147 205ea36361d0e3aec701ddc5c2918152b88ef01e
push id104984
push useraciure@mozilla.com
push dateThu, 05 Jul 2018 09:55:01 +0000
treeherdermozilla-inbound@35ae03d7cf2d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone63.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 on a CLOSED TREE
gfx/layers/basic/BasicBorderLayer.cpp
gfx/layers/client/ClientBorderLayer.cpp
js/src/jit/AliasAnalysisShared.cpp
js/src/jit/AliasAnalysisShared.h
testing/web-platform/meta/css/css-animations/set-animation-play-state-to-paused-002.html.ini
testing/web-platform/meta/fetch/api/request/fetch-destination-no-load-event.https.html.ini
testing/web-platform/meta/html/browsers/the-window-object/window-open-noopener.html.ini
testing/web-platform/meta/keyboard-map/keyboard-map-https.html.ini
testing/web-platform/meta/media-capabilities/idlharness.html.ini
testing/web-platform/meta/screen-orientation/interfaces.html.ini
testing/web-platform/meta/streams/readable-streams/templated.html.ini
testing/web-platform/meta/xhr/interfaces.html.ini
testing/web-platform/tests/css/css-animations/set-animation-play-state-to-paused-002-ref.html
testing/web-platform/tests/css/css-animations/set-animation-play-state-to-paused-002.html
testing/web-platform/tests/keyboard-map/keyboard-map-https.html
testing/web-platform/tests/media-capabilities/idlharness.html
testing/web-platform/tests/performance-timeline/idlharness.html
testing/web-platform/tests/user-timing/idlharness.html
--- a/accessible/base/ARIAMap.cpp
+++ b/accessible/base/ARIAMap.cpp
@@ -1426,22 +1426,20 @@ aria::AttrCharacteristicsFor(nsAtom* aAt
       return gWAIUnivAttrMap[i].characteristics;
 
   return 0;
 }
 
 bool
 aria::HasDefinedARIAHidden(nsIContent* aContent)
 {
-  return aContent &&
-    nsAccUtils::HasDefinedARIAToken(aContent, nsGkAtoms::aria_hidden) &&
-    !aContent->AsElement()->AttrValueIs(kNameSpaceID_None,
-                                        nsGkAtoms::aria_hidden,
-                                        nsGkAtoms::_false,
-                                        eCaseMatters);
+  return aContent && aContent->IsElement() &&
+    aContent->AsElement()->AttrValueIs(kNameSpaceID_None,
+                                       nsGkAtoms::aria_hidden,
+                                       nsGkAtoms::_true, eCaseMatters);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // AttrIterator class
 
 bool
 AttrIterator::Next(nsAString& aAttrName, nsAString& aAttrValue)
 {
--- a/accessible/base/NotificationController.cpp
+++ b/accessible/base/NotificationController.cpp
@@ -745,19 +745,21 @@ NotificationController::WillRefresh(mozi
       if (logging::IsEnabled(logging::eTree | logging::eText)) {
         logging::MsgBegin("TREE", "text node gains new content; doc: %p", mDocument);
         logging::Node("container", containerElm);
         logging::Node("content", textNode);
         logging::MsgEnd();
       }
   #endif
 
-      Accessible* container = mDocument->AccessibleOrTrueContainer(containerNode);
-      MOZ_ASSERT(container,
+      MOZ_ASSERT(mDocument->AccessibleOrTrueContainer(containerNode),
                  "Text node having rendered text hasn't accessible document!");
+
+      Accessible* container = mDocument->AccessibleOrTrueContainer(
+        containerNode, DocAccessible::eNoContainerIfARIAHidden);
       if (container) {
         nsTArray<nsCOMPtr<nsIContent>>* list =
           mContentInsertions.LookupOrAdd(container);
         list->AppendElement(textNode);
       }
     }
   }
   mTextHash.Clear();
--- a/accessible/base/nsAccessibilityService.cpp
+++ b/accessible/base/nsAccessibilityService.cpp
@@ -1044,20 +1044,26 @@ nsAccessibilityService::CreateAccessible
     NS_ERROR("Creating accessible for wrong document");
     return nullptr;
   }
 
   if (!aNode->IsContent())
     return nullptr;
 
   nsIContent* content = aNode->AsContent();
-  nsIFrame* frame = content->GetPrimaryFrame();
+  if (aria::HasDefinedARIAHidden(content)) {
+    if (aIsSubtreeHidden) {
+      *aIsSubtreeHidden = true;
+    }
+    return nullptr;
+  }
 
   // Check frame and its visibility. Note, hidden frame allows visible
   // elements in subtree.
+  nsIFrame* frame = content->GetPrimaryFrame();
   if (!frame || !frame->StyleVisibility()->IsVisible()) {
     // display:contents element doesn't have a frame, but retains the semantics.
     // All its children are unaffected.
     if (content->IsElement() && content->AsElement()->IsDisplayContents()) {
       const HTMLMarkupMapInfo* markupMap =
         mHTMLMarkupMap.Get(content->NodeInfo()->NameAtom());
       if (markupMap && markupMap->new_func) {
         RefPtr<Accessible> newAcc =
--- a/accessible/base/nsAccessiblePivot.cpp
+++ b/accessible/base/nsAccessiblePivot.cpp
@@ -890,23 +890,16 @@ RuleCache::ApplyFilter(Accessible* aAcce
     if ((nsIAccessibleTraversalRule::PREFILTER_OFFSCREEN & mPreFilter) &&
         (state & states::OFFSCREEN))
       return NS_OK;
 
     if ((nsIAccessibleTraversalRule::PREFILTER_NOT_FOCUSABLE & mPreFilter) &&
         !(state & states::FOCUSABLE))
       return NS_OK;
 
-    if (nsIAccessibleTraversalRule::PREFILTER_ARIA_HIDDEN & mPreFilter) {
-      if (aAccessible->IsARIAHidden()) {
-        *aResult |= nsIAccessibleTraversalRule::FILTER_IGNORE_SUBTREE;
-        return NS_OK;
-      }
-    }
-
     if ((nsIAccessibleTraversalRule::PREFILTER_TRANSPARENT & mPreFilter) &&
         !(state & states::OPAQUE1)) {
       nsIFrame* frame = aAccessible->GetFrame();
       if (frame->StyleEffects()->mOpacity == 0.0f) {
         *aResult |= nsIAccessibleTraversalRule::FILTER_IGNORE_SUBTREE;
         return NS_OK;
       }
     }
--- a/accessible/generic/Accessible.cpp
+++ b/accessible/generic/Accessible.cpp
@@ -977,21 +977,16 @@ Accessible::Attributes()
 
   // Expose object attributes from ARIA attributes.
   nsAutoString unused;
   aria::AttrIterator attribIter(mContent);
   nsAutoString name, value;
   while(attribIter.Next(name, value))
     attributes->SetStringProperty(NS_ConvertUTF16toUTF8(name), value, unused);
 
-  if (IsARIAHidden()) {
-    nsAccUtils::SetAccAttr(attributes, nsGkAtoms::hidden,
-                           NS_LITERAL_STRING("true"));
-  }
-
   // If there is no aria-live attribute then expose default value of 'live'
   // object attribute used for ARIA role of this accessible.
   const nsRoleMapEntry* roleMapEntry = ARIARoleMap();
   if (roleMapEntry) {
     if (roleMapEntry->Is(nsGkAtoms::searchbox)) {
       nsAccUtils::SetAccAttr(attributes, nsGkAtoms::textInputType,
                              NS_LITERAL_STRING("search"));
     }
@@ -2108,19 +2103,16 @@ Accessible::BindToParent(Accessible* aPa
   mIndexInParent = aIndexInParent;
 
   // Note: this is currently only used for richlistitems and their children.
   if (mParent->HasNameDependentParent() || mParent->IsXULListItem())
     mContextFlags |= eHasNameDependentParent;
   else
     mContextFlags &= ~eHasNameDependentParent;
 
-  if (mParent->IsARIAHidden() || aria::HasDefinedARIAHidden(mContent))
-    SetARIAHidden(true);
-
   mContextFlags |=
     static_cast<uint32_t>((mParent->IsAlert() ||
                            mParent->IsInsideAlert())) & eInsideAlert;
 }
 
 // Accessible protected
 void
 Accessible::UnbindFromParent()
@@ -2637,30 +2629,16 @@ Accessible::ContainerWidget() const
       // Don't cross DOM document boundaries.
       if (parent->IsDoc())
         break;
     }
   }
   return nullptr;
 }
 
-void
-Accessible::SetARIAHidden(bool aIsDefined)
-{
-  if (aIsDefined)
-    mContextFlags |= eARIAHidden;
-  else
-    mContextFlags &= ~eARIAHidden;
-
-  uint32_t length = mChildren.Length();
-  for (uint32_t i = 0; i < length; i++) {
-    mChildren[i]->SetARIAHidden(aIsDefined);
-  }
-}
-
 ////////////////////////////////////////////////////////////////////////////////
 // Accessible protected methods
 
 void
 Accessible::LastRelease()
 {
   // First cleanup if needed...
   if (mDoc) {
--- a/accessible/generic/Accessible.h
+++ b/accessible/generic/Accessible.h
@@ -936,23 +936,16 @@ public:
   /**
    * Return true if this accessible has a parent whose name depends on this
    * accessible.
    */
   bool HasNameDependentParent() const
     { return mContextFlags & eHasNameDependentParent; }
 
   /**
-   * Return true if aria-hidden="true" is applied to the accessible or inherited
-   * from the parent.
-   */
-  bool IsARIAHidden() const { return mContextFlags & eARIAHidden; }
-  void SetARIAHidden(bool aIsDefined);
-
-  /**
    * Return true if the element is inside an alert.
    */
   bool IsInsideAlert() const { return mContextFlags & eInsideAlert; }
 
   /**
    * Return true if there is a pending reorder event for this accessible.
    */
   bool ReorderEventTarget() const { return mReorderEventTarget; }
@@ -1043,18 +1036,17 @@ protected:
     eLastStateFlag = eNoKidsFromDOM
   };
 
   /**
    * Flags used for contextual information about the accessible.
    */
   enum ContextFlags {
     eHasNameDependentParent = 1 << 0, // Parent's name depends on this accessible.
-    eARIAHidden = 1 << 1,
-    eInsideAlert = 1 << 2,
+    eInsideAlert = 1 << 1,
 
     eLastContextFlag = eInsideAlert
   };
 
 protected:
 
   //////////////////////////////////////////////////////////////////////////////
   // Miscellaneous helpers
@@ -1137,17 +1129,17 @@ protected:
   nsCOMPtr<nsIContent> mContent;
   RefPtr<DocAccessible> mDoc;
 
   Accessible* mParent;
   nsTArray<Accessible*> mChildren;
   int32_t mIndexInParent;
 
   static const uint8_t kStateFlagsBits = 12;
-  static const uint8_t kContextFlagsBits = 3;
+  static const uint8_t kContextFlagsBits = 2;
   static const uint8_t kTypeBits = 6;
   static const uint8_t kGenericTypesBits = 16;
 
   /**
    * Non-NO_ROLE_MAP_ENTRY_INDEX indicates author-supplied role;
    * possibly state & value as well
    */
   uint8_t mRoleMapEntryIndex;
--- a/accessible/generic/DocAccessible-inl.h
+++ b/accessible/generic/DocAccessible-inl.h
@@ -18,21 +18,21 @@
 #ifdef A11Y_LOG
 #include "Logging.h"
 #endif
 
 namespace mozilla {
 namespace a11y {
 
 inline Accessible*
-DocAccessible::AccessibleOrTrueContainer(nsINode* aNode) const
+DocAccessible::AccessibleOrTrueContainer(nsINode* aNode, int aIgnoreARIAHidden) const
 {
   // HTML comboboxes have no-content list accessible as an intermediate
   // containing all options.
-  Accessible* container = GetAccessibleOrContainer(aNode);
+  Accessible* container = GetAccessibleOrContainer(aNode, aIgnoreARIAHidden);
   if (container && container->IsHTMLCombobox()) {
     return container->FirstChild();
   }
   return container;
 }
 
 inline nsIAccessiblePivot*
 DocAccessible::VirtualCursor()
--- a/accessible/generic/DocAccessible.cpp
+++ b/accessible/generic/DocAccessible.cpp
@@ -764,16 +764,29 @@ DocAccessible::AttributeChanged(dom::Ele
   NS_ASSERTION(!IsDefunct(),
                "Attribute changed called on defunct document accessible!");
 
   // Proceed even if the element is not accessible because element may become
   // accessible if it gets certain attribute.
   if (UpdateAccessibleOnAttrChange(aElement, aAttribute))
     return;
 
+  // Update the accessible tree on aria-hidden change. Make sure to not create
+  // a tree under aria-hidden='true'.
+  if (aAttribute == nsGkAtoms::aria_hidden) {
+    if (aria::HasDefinedARIAHidden(aElement)) {
+      ContentRemoved(aElement);
+    }
+    else {
+      ContentInserted(aElement->GetFlattenedTreeParent(),
+                      aElement, aElement->GetNextSibling());
+    }
+    return;
+  }
+
   // Ignore attribute change if the element doesn't have an accessible (at all
   // or still) iff the element is not a root content of this document accessible
   // (which is treated as attribute change on this document accessible).
   // Note: we don't bail if all the content hasn't finished loading because
   // these attributes are changing for a loaded part of the content.
   Accessible* accessible = GetAccessible(aElement);
   if (!accessible) {
     if (mContent != aElement)
@@ -987,32 +1000,16 @@ DocAccessible::ARIAAttributeChanged(Acce
   if (!(attrFlags & ATTR_BYPASSOBJ)) {
     RefPtr<AccEvent> event =
       new AccObjectAttrChangedEvent(aAccessible, aAttribute);
     FireDelayedEvent(event);
   }
 
   dom::Element* elm = aAccessible->GetContent()->AsElement();
 
-  // Update aria-hidden flag for the whole subtree iff aria-hidden is changed
-  // on the root, i.e. ignore any affiliated aria-hidden changes in the subtree
-  // of top aria-hidden.
-  if (aAttribute == nsGkAtoms::aria_hidden) {
-    bool isDefined = aria::HasDefinedARIAHidden(elm);
-    if (isDefined != aAccessible->IsARIAHidden() &&
-        (!aAccessible->Parent() || !aAccessible->Parent()->IsARIAHidden())) {
-      aAccessible->SetARIAHidden(isDefined);
-
-      RefPtr<AccEvent> event =
-        new AccObjectAttrChangedEvent(aAccessible, aAttribute);
-      FireDelayedEvent(event);
-    }
-    return;
-  }
-
   if (aAttribute == nsGkAtoms::aria_checked ||
       (aAccessible->IsButton() &&
        aAttribute == nsGkAtoms::aria_pressed)) {
     const uint64_t kState = (aAttribute == nsGkAtoms::aria_checked) ?
                             states::CHECKED : states::PRESSED;
     RefPtr<AccEvent> event = new AccStateChangeEvent(aAccessible, kState);
     FireDelayedEvent(event);
 
@@ -1228,23 +1225,31 @@ DocAccessible::GetAccessibleByUniqueIDIn
     if (child)
       return child;
   }
 
   return nullptr;
 }
 
 Accessible*
-DocAccessible::GetAccessibleOrContainer(nsINode* aNode) const
+DocAccessible::GetAccessibleOrContainer(nsINode* aNode,
+                                        int aARIAHiddenFlag) const
 {
   if (!aNode || !aNode->GetComposedDoc())
     return nullptr;
 
   for (nsINode* currNode = aNode; currNode;
        currNode = currNode->GetFlattenedTreeParentNode()) {
+
+    // No container if is inside of aria-hidden subtree.
+    if (aARIAHiddenFlag == eNoContainerIfARIAHidden && currNode->IsElement() &&
+        aria::HasDefinedARIAHidden(currNode->AsElement())) {
+      return nullptr;
+    }
+
     if (Accessible* accessible = GetAccessible(currNode)) {
       return accessible;
     }
   }
 
   return nullptr;
 }
 
@@ -1792,17 +1797,18 @@ InsertIterator::Next()
     // overlapping content insertion (i.e. other content was inserted between
     // this inserted content and its container or the content was reinserted
     // into different container of unrelated part of tree). To avoid a double
     // processing of the content insertion ignore this insertion notification.
     // Note, the inserted content might be not in tree at all at this point
     // what means there's no container. Ignore the insertion too.
     nsIContent* prevNode = mNodes->SafeElementAt(mNodesIdx - 1);
     nsIContent* node = mNodes->ElementAt(mNodesIdx++);
-    Accessible* container = Document()->AccessibleOrTrueContainer(node);
+    Accessible* container = Document()->
+      AccessibleOrTrueContainer(node, DocAccessible::eNoContainerIfARIAHidden);
     if (container != Context()) {
       continue;
     }
 
     // HTML comboboxes have no-content list accessible as an intermediate
     // containing all options.
     if (container->IsHTMLCombobox()) {
       container = container->FirstChild();
--- a/accessible/generic/DocAccessible.h
+++ b/accessible/generic/DocAccessible.h
@@ -273,31 +273,37 @@ public:
    * this and nested documents.
    */
   Accessible* GetAccessibleByUniqueIDInSubtree(void* aUniqueID);
 
   /**
    * Return an accessible for the given DOM node or container accessible if
    * the node is not accessible.
    */
-  Accessible* GetAccessibleOrContainer(nsINode* aNode) const;
+  enum {
+    eIgnoreARIAHidden = 0,
+    eNoContainerIfARIAHidden = 1
+  };
+  Accessible* GetAccessibleOrContainer(nsINode* aNode,
+                                       int aARIAHiddenFlag = eIgnoreARIAHidden) const;
 
   /**
    * Return a container accessible for the given DOM node.
    */
   Accessible* GetContainerAccessible(nsINode* aNode) const
   {
     return aNode ? GetAccessibleOrContainer(aNode->GetParentNode()) : nullptr;
   }
 
   /**
    * Return an accessible for the given node if any, or an immediate accessible
    * container for it.
    */
-  Accessible* AccessibleOrTrueContainer(nsINode* aNode) const;
+  Accessible* AccessibleOrTrueContainer(nsINode* aNode,
+                                        int aARIAHiddenFlag = eIgnoreARIAHidden) const;
 
   /**
    * Return an accessible for the given node or its first accessible descendant.
    */
   Accessible* GetAccessibleOrDescendant(nsINode* aNode) const;
 
   /**
    * Returns aria-owns seized child at the given index.
--- a/accessible/interfaces/nsIAccessiblePivot.idl
+++ b/accessible/interfaces/nsIAccessiblePivot.idl
@@ -224,18 +224,17 @@ interface nsIAccessibleTraversalRule : n
   const unsigned short FILTER_MATCH = 0x1;
   /* Don't traverse accessibles children */
   const unsigned short FILTER_IGNORE_SUBTREE = 0x2;
 
   /* Pre-filters */
   const unsigned long PREFILTER_INVISIBLE     = 0x00000001;
   const unsigned long PREFILTER_OFFSCREEN     = 0x00000002;
   const unsigned long PREFILTER_NOT_FOCUSABLE = 0x00000004;
-  const unsigned long PREFILTER_ARIA_HIDDEN   = 0x00000008;
-  const unsigned long PREFILTER_TRANSPARENT   = 0x00000010;
+  const unsigned long PREFILTER_TRANSPARENT   = 0x00000008;
 
   /**
    * Pre-filter bitfield to filter out obviously ignorable nodes and lighten
    * the load on match().
    */
   readonly attribute unsigned long preFilter;
 
   /**
--- a/accessible/jsat/EventManager.jsm
+++ b/accessible/jsat/EventManager.jsm
@@ -210,31 +210,16 @@ this.EventManager.prototype = {
         // on this one..
         let state = Utils.getState(acc);
         if (state.contains(States.FOCUSED) && state.contains(States.EDITABLE)) {
           this.present(Presentation.textSelectionChanged(acc.getText(0, -1),
             caretOffset, caretOffset, 0, 0, aEvent.isFromUserInput));
         }
         break;
       }
-      case Events.OBJECT_ATTRIBUTE_CHANGED:
-      {
-        let evt = aEvent.QueryInterface(
-          Ci.nsIAccessibleObjectAttributeChangedEvent);
-        if (evt.changedAttribute !== "aria-hidden") {
-          // Only handle aria-hidden attribute change.
-          break;
-        }
-        let hidden = Utils.isHidden(aEvent.accessible);
-        this[hidden ? "_handleHide" : "_handleShow"](evt);
-        if (this.inTest) {
-          this.sendMsgFunc("AccessFu:AriaHidden", { hidden });
-        }
-        break;
-      }
       case Events.SHOW:
       {
         this._handleShow(aEvent);
         break;
       }
       case Events.HIDE:
       {
         let evt = aEvent.QueryInterface(Ci.nsIAccessibleHideEvent);
@@ -624,17 +609,26 @@ const AccessibilityEventObserver = {
     let event = aSubject.QueryInterface(Ci.nsIAccessibleEvent);
     if (!event.accessibleDocument) {
       Logger.warning(
         "AccessibilityEventObserver.observe: no accessible document:",
         Logger.eventToString(event), "accessible:",
         Logger.accessibleToString(event.accessible));
       return;
     }
-    let content = event.accessibleDocument.window;
+    let content;
+    try {
+      content = event.accessibleDocument.window;
+    } catch (e) {
+      Logger.warning(
+        "AccessibilityEventObserver.observe: no window for accessible document:",
+        Logger.eventToString(event), "accessible:",
+        Logger.accessibleToString(event.accessible));
+      return;
+    }
     // Match the content window to its EventManager.
     let eventManager = this.getListener(content);
     if (!eventManager || !eventManager._started) {
       if (Utils.MozBuildApp === "browser" && !content.isChromeWindow) {
         Logger.warning(
           "AccessibilityEventObserver.observe: ignored event:",
           Logger.eventToString(event), "accessible:",
           Logger.accessibleToString(event.accessible), "document:",
--- a/accessible/jsat/Traversal.jsm
+++ b/accessible/jsat/Traversal.jsm
@@ -172,25 +172,24 @@ var gSimpleMatchFunc = function gSimpleM
     // the same content that was already presented by its parent.
     return Filters.MATCH |
       Filters.IGNORE_SUBTREE;
   }
 };
 
 var gSimplePreFilter = Prefilters.DEFUNCT |
   Prefilters.INVISIBLE |
-  Prefilters.ARIA_HIDDEN |
   Prefilters.TRANSPARENT;
 
 var TraversalRules = { // jshint ignore:line
   Simple: new BaseTraversalRule(gSimpleTraversalRoles, gSimpleMatchFunc),
 
   SimpleOnScreen: new BaseTraversalRule(
     gSimpleTraversalRoles, gSimpleMatchFunc,
-    Prefilters.DEFUNCT | Prefilters.INVISIBLE | Prefilters.ARIA_HIDDEN |
+    Prefilters.DEFUNCT | Prefilters.INVISIBLE |
     Prefilters.TRANSPARENT | Prefilters.OFFSCREEN),
 
   Anchor: new BaseTraversalRule(
     [Roles.LINK],
     function Anchor_match(aAccessible) {
       // We want to ignore links, only focus named anchors.
       if (Utils.getState(aAccessible).contains(States.LINKED)) {
         return Filters.IGNORE;
--- a/accessible/jsat/Utils.jsm
+++ b/accessible/jsat/Utils.jsm
@@ -272,52 +272,33 @@ var Utils = { // jshint ignore:line
         Logger.debug("Failed to get parent:", x);
         acc = null;
       }
     }
 
     return false;
   },
 
-  isHidden: function isHidden(aAccessible) {
-    // Need to account for aria-hidden, so can't just check for INVISIBLE
-    // state.
-    let hidden = Utils.getAttributes(aAccessible).hidden;
-    return hidden && hidden === "true";
-  },
-
   visibleChildCount: function visibleChildCount(aAccessible) {
     let count = 0;
     for (let child = aAccessible.firstChild; child; child = child.nextSibling) {
-      if (!this.isHidden(child)) {
-        ++count;
-      }
+      ++count;
     }
     return count;
   },
 
-  inHiddenSubtree: function inHiddenSubtree(aAccessible) {
-    for (let acc = aAccessible; acc; acc = acc.parent) {
-      if (this.isHidden(acc)) {
-        return true;
-      }
-    }
-    return false;
-  },
-
   isAliveAndVisible: function isAliveAndVisible(aAccessible, aIsOnScreen) {
     if (!aAccessible) {
       return false;
     }
 
     try {
       let state = this.getState(aAccessible);
       if (state.contains(States.DEFUNCT) || state.contains(States.INVISIBLE) ||
-          (aIsOnScreen && state.contains(States.OFFSCREEN)) ||
-          Utils.inHiddenSubtree(aAccessible)) {
+          (aIsOnScreen && state.contains(States.OFFSCREEN))) {
         return false;
       }
     } catch (x) {
       return false;
     }
 
     return true;
   },
@@ -726,22 +707,17 @@ PivotContext.prototype = {
    * whether aAccessible's subtree is required.
    */
   _traverse: function* _traverse(aAccessible, aPreorder, aStop) {
     if (aStop && aStop(aAccessible)) {
       return;
     }
     let child = aAccessible.firstChild;
     while (child) {
-      let include;
-      if (this._includeInvisible) {
-        include = true;
-      } else {
-        include = !Utils.isHidden(child);
-      }
+      let include = true;
       if (include) {
         if (aPreorder) {
           yield child;
           for (let node of this._traverse(child, aPreorder, aStop)) {
             yield node;
           }
         } else {
           for (let node of this._traverse(child, aPreorder, aStop)) {
--- a/accessible/tests/mochitest/attributes/test_obj.html
+++ b/accessible/tests/mochitest/attributes/test_obj.html
@@ -39,18 +39,16 @@ https://bugzilla.mozilla.org/show_bug.cg
       testAttrs("grabbed", {"grabbed": "true"}, true);
       testAttrs("haspopupTrue", { "haspopup": "true" }, true);
       testAbsentAttrs("haspopupFalse", { "haspopup": "false" });
       testAbsentAttrs("haspopupEmpty", { "haspopup": "" });
       testAttrs("haspopupDialog", { "haspopup": "dialog" }, true);
       testAttrs("haspopupListbox", { "haspopup": "listbox" }, true);
       testAttrs("haspopupMenu", { "haspopup": "menu" }, true);
       testAttrs("haspopupTree", { "haspopup": "tree" }, true);
-      testAttrs("hidden", {"hidden": "true"}, true);
-      testAbsentAttrs("hidden_false", { "hidden": "false" });
       testAbsentAttrs("modal", {"modal": "true"});
       testAttrs("sortAscending", {"sort": "ascending"}, true);
       testAttrs("sortDescending", {"sort": "descending"}, true);
       testAttrs("sortNone", {"sort": "none"}, true);
       testAttrs("sortOther", {"sort": "other"}, true);
       testAttrs("roledescr", {"roledescription": "spreadshit"}, true);
       testAttrs("currentPage", {"current": "page"}, true);
 
@@ -150,61 +148,16 @@ https://bugzilla.mozilla.org/show_bug.cg
       SimpleTest.finish();
     }
 
     SimpleTest.waitForExplicitFinish();
     addA11yLoadEvent(doTest);
   </script>
 </head>
 <body>
-  <a target="_blank"
-     href="https://bugzilla.mozilla.org/show_bug.cgi?id=475006"
-     title="Extend nsARIAMap to capture ARIA attribute characteristics">
-    Mozilla Bug 475006
-  </a>
-  <a target="_blank"
-     href="https://bugzilla.mozilla.org/show_bug.cgi?id=391829"
-     title="Add support for container-live-role to object attributes">
-    Mozilla Bug 391829
-  </a>
-  <a target="_blank"
-     href="https://bugzilla.mozilla.org/show_bug.cgi?id=581952"
-     title="Make explicit that aria-label is not an object attribute">
-    Mozilla Bug 475006
-  </a>
-  <a target="_blank"
-     href="https://bugzilla.mozilla.org/show_bug.cgi?id=558036"
-     title="make HTML <output> accessible">
-    Mozilla Bug 558036
-  </a>
-  <a target="_blank"
-     href="https://bugzilla.mozilla.org/show_bug.cgi?id=896400"
-     title="Tablist should no longer be an implicit live region">
-    Mozilla Bug 896400
-  </a>
-  <a target="_blank"
-     href="https://bugzilla.mozilla.org/show_bug.cgi?id=563862"
-     title="Expand support for nsIAccessibleEvent::OBJECT_ATTRIBUTE_CHANGE">
-    Mozilla Bug 563862
-  </a>
-  <a target="_blank"
-     href="https://bugzilla.mozilla.org/show_bug.cgi?id=819303"
-     title="crash in nsTextEquivUtils::AppendTextEquivFromTextContent">
-    Mozilla Bug 819303
-  </a>
-  <a target="_blank"
-     href="https://bugzilla.mozilla.org/show_bug.cgi?id=838407"
-     title="aria-hidden false value shouldn't be exposed via object attributes">
-    Mozilla Bug 838407
-  </a>
-  <a target="_blank"
-     href="https://bugzilla.mozilla.org/show_bug.cgi?id=1121518"
-     title="ARIA 1.1: Support role 'searchbox'">
-    Mozilla Bug 1121518
-  </a>
   <p id="display"></p>
   <div id="content" style="display: none"></div>
   <pre id="test">
   </pre>
 
   <!-- aria -->
   <div id="atomic" aria-atomic="true">live region</div>
   <div id="atomic_false" aria-atomic="false">live region</div>
@@ -221,18 +174,16 @@ https://bugzilla.mozilla.org/show_bug.cg
   <div id="grabbed" aria-grabbed="true"></div>
   <div id="haspopupTrue" aria-haspopup="true"></div>
   <div id="haspopupFalse" aria-haspopup="false"></div>
   <div id="haspopupEmpty" aria-haspopup=""></div>
   <div id="haspopupDialog" aria-haspopup="dialog"></div>
   <div id="haspopupListbox" aria-haspopup="listbox"></div>
   <div id="haspopupMenu" aria-haspopup="menu"></div>
   <div id="haspopupTree" aria-haspopup="tree"></div>
-  <div id="hidden" aria-hidden="true"></div>
-  <div id="hidden_false" aria-hidden="false"></div>
   <div id="modal" aria-modal="true"></div>
   <div id="sortAscending" role="columnheader" aria-sort="ascending"></div>
   <div id="sortDescending" role="columnheader" aria-sort="descending"></div>
   <div id="sortNone" role="columnheader" aria-sort="none"></div>
   <div id="sortOther" role="columnheader" aria-sort="other"></div>
   <div id="roledescr" aria-roledescription="spreadshit"></div>
   <div id="currentPage" aria-current="page"></div>
 
--- a/accessible/tests/mochitest/events.js
+++ b/accessible/tests/mochitest/events.js
@@ -109,16 +109,38 @@ function waitForEvent(aEventType, aTarge
       );
     }
   };
 
   registerA11yEventListener(aEventType, handler);
 }
 
 /**
+ * A promise based version of waitForEvent function.
+ */
+function waitForEventPromise(eventType, target) {
+  return new Promise(resolve => {
+    let eventObserver = {
+      observe(subject, topic, data) {
+        let event = subject.QueryInterface(nsIAccessibleEvent);
+        if (event.eventType !== eventType) {
+          return;
+        }
+
+        if (event.accessible == getAccessible(target)) {
+          Services.obs.removeObserver(this, "accessible-event");
+          resolve(event);
+        }
+      }
+    };
+    Services.obs.addObserver(eventObserver, "accessible-event");
+  });
+}
+
+/**
  * Generate mouse move over image map what creates image map accessible (async).
  * See waitForImageMap() function.
  */
 function waveOverImageMap(aImageMapID) {
   var imageMapNode = getNode(aImageMapID);
   synthesizeMouse(imageMapNode, 10, 10, { type: "mousemove" },
                   imageMapNode.ownerGlobal);
 }
--- a/accessible/tests/mochitest/events/test_aria_objattr.html
+++ b/accessible/tests/mochitest/events/test_aria_objattr.html
@@ -34,79 +34,36 @@
         this.node.setAttribute(aAttr, aValue);
       };
 
       this.getID = function updateAttribute_getID() {
         return aAttr + " for " + aID + " " + aValue;
       };
     }
 
-    function updateARIAHidden(aID, aIsDefined, aChildId) {
-      this.__proto__ = new updateAttribute(aID, "aria-hidden",
-                                           aIsDefined ? "true" : "false");
-
-      this.finalCheck = function updateARIAHidden_finalCheck() {
-        if (aIsDefined) {
-          testAttrs(aID, {"hidden": "true"}, true);
-          testAttrs(aChildId, {"hidden": "true"}, true);
-        } else {
-          testAbsentAttrs(aID, { "hidden": "true"});
-          testAbsentAttrs(aChildId, { "hidden": "true"});
-        }
-      };
-    }
-
-    // Debug stuff.
-    // gA11yEventDumpID = "eventdump";
     // gA11yEventDumpToConsole = true;
-
     function doTests() {
       gQueue = new eventQueue();
 
-      gQueue.push(new updateARIAHidden("hideable", true, "hideable_child"));
-      gQueue.push(new updateARIAHidden("hideable", false, "hideable_child"));
-
       gQueue.push(new updateAttribute("sortable", "aria-sort", "ascending"));
 
       // For experimental ARIA extensions
       gQueue.push(new updateAttribute("custom", "aria-blah", "true"));
 
       gQueue.invoke(); // Will call SimpleTest.finish();
     }
 
     SimpleTest.waitForExplicitFinish();
     addA11yLoadEvent(doTests);
   </script>
 </head>
 
 <body>
-
-  <a target="_blank"
-     href="https://bugzilla.mozilla.org/show_bug.cgi?id=581096"
-     title="Add support for aria-hidden">
-    Mozilla Bug 581096
-  </a>
-
-  <a target="_blank"
-     href="https://bugzilla.mozilla.org/show_bug.cgi?id=640707"
-     title="Add event support for aria-sort">
-    Mozilla Bug 640707
-  </a>
-
-  <a target="_blank"
-     href="https://bugzilla.mozilla.org/show_bug.cgi?id=640707"
-     title="Expand support for aria attribute change events">
-    Mozilla Bug 563862
-  </a>
-
   <p id="display"></p>
   <div id="content" style="display: none"></div>
   <pre id="test">
   </pre>
-  <div id="eventdump"></div>
-
-  <div id="hideable"><div id="hideable_child">Hi</div><div>there</div></div>
 
   <div id="sortable" role="columnheader" aria-sort="none">aria-sort</div>
 
   <div id="custom" role="custom" aria-blah="false">Fat free cheese</div>
 </body>
 </html>
--- a/accessible/tests/mochitest/jsat/test_content_integration.html
+++ b/accessible/tests/mochitest/jsat/test_content_integration.html
@@ -289,53 +289,59 @@
       evt = await runner.expectAndroidEvents(() => {
         doc.getElementById("back").setAttribute("aria-hidden", true);
       }, AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED);
       runner.eventTextMatches(evt, ["such app", "wow", "heading level 1"]);
 
       // Changing aria-hidden attribute twice and making sure that the event
       // is fired only once when the actual change happens.
       doc.getElementById("back").setAttribute("aria-hidden", true);
+      let onShow = waitForEventPromise(EVENT_SHOW, doc.getElementById("back"));
       doc.getElementById("back").setAttribute("aria-hidden", false);
+      await onShow;
+
       evt = await runner.movePrevious("Simple",
         AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED);
       runner.eventTextMatches(evt, ["Back", "button"]);
       await runner.clearCursor();
 
       // aria-hidden on the iframe that has the vc.
       evt = await runner.moveNext("Simple",
         AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED);
       runner.eventTextMatches(evt, ["Traversal Rule test document", "Phone status bar"]);
       evt = await runner.moveNext("Simple",
         AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED);
       runner.eventTextMatches(evt, ["Back", "button"]);
       evt = await runner.moveNext("Simple",
         AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED);
       runner.eventTextMatches(evt, ["such app", "wow", "heading level 1"]);
 
-
       evt = await runner.expectAndroidEvents(() => {
         doc.getElementById("iframe").setAttribute("aria-hidden", true);
       }, AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED);
-      runner.eventTextMatches(evt, ["Home", "button"]);
+      runner.eventTextMatches(evt, ["Traversal Rule test document", "Home", "button"]);
 
+      onShow = waitForEventPromise(EVENT_SHOW, doc.getElementById("iframe"));
       doc.getElementById("iframe").setAttribute("aria-hidden", false);
+      await onShow;
       await runner.clearCursor();
 
       // aria-hidden element and auto Move
       evt = await runner.moveNext("Simple",
         AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED);
       runner.eventTextMatches(evt, ["Traversal Rule test document", "Phone status bar"]);
 
       doc.getElementById("back").setAttribute("aria-hidden", true);
       evt = await runner.focusSelector("button#back",
         AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED);
       runner.eventTextMatches(evt, ["such app", "wow", "heading level 1"]);
 
+      onShow = waitForEventPromise(EVENT_SHOW, doc.getElementById("back"));
       doc.getElementById("back").setAttribute("aria-hidden", false);
+      await onShow;
       runner.blur();
       await runner.clearCursor();
 
       // Open dialog in outer doc, while cursor is also in outer doc
       evt = await runner.moveLast("Simple",
         AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED);
       runner.eventTextMatches(evt, ["Traversal Rule test document", "mover", "medium", "slider", "live"]);
 
--- a/accessible/tests/mochitest/pivot.js
+++ b/accessible/tests/mochitest/pivot.js
@@ -1,15 +1,14 @@
 ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
 
 // //////////////////////////////////////////////////////////////////////////////
 // Constants
 
 const PREFILTER_INVISIBLE = nsIAccessibleTraversalRule.PREFILTER_INVISIBLE;
-const PREFILTER_ARIA_HIDDEN = nsIAccessibleTraversalRule.PREFILTER_ARIA_HIDDEN;
 const PREFILTER_TRANSPARENT = nsIAccessibleTraversalRule.PREFILTER_TRANSPARENT;
 const FILTER_MATCH = nsIAccessibleTraversalRule.FILTER_MATCH;
 const FILTER_IGNORE = nsIAccessibleTraversalRule.FILTER_IGNORE;
 const FILTER_IGNORE_SUBTREE = nsIAccessibleTraversalRule.FILTER_IGNORE_SUBTREE;
 const CHAR_BOUNDARY = nsIAccessiblePivot.CHAR_BOUNDARY;
 const WORD_BOUNDARY = nsIAccessiblePivot.WORD_BOUNDARY;
 
 const NS_ERROR_NOT_IN_TREE = 0x80780026;
@@ -42,17 +41,17 @@ var HeadersTraversalRule =
  */
 var ObjectTraversalRule =
 {
   getMatchRoles(aRules) {
     aRules.value = [];
     return 0;
   },
 
-  preFilter: PREFILTER_INVISIBLE | PREFILTER_ARIA_HIDDEN | PREFILTER_TRANSPARENT,
+  preFilter: PREFILTER_INVISIBLE | PREFILTER_TRANSPARENT,
 
   match(aAccessible) {
     var rv = FILTER_IGNORE;
     var role = aAccessible.role;
     if (hasState(aAccessible, STATE_FOCUSABLE) &&
         (role != ROLE_DOCUMENT && role != ROLE_INTERNAL_FRAME))
       rv = FILTER_IGNORE_SUBTREE | FILTER_MATCH;
     else if (aAccessible.childCount == 0 &&
--- a/accessible/tests/mochitest/pivot/test_virtualcursor.html
+++ b/accessible/tests/mochitest/pivot/test_virtualcursor.html
@@ -39,17 +39,17 @@
 
       gQueue = new eventQueue();
 
       gQueue.onFinish = function onFinish() {
         closeBrowserWindow();
       };
 
       queueTraversalSequence(gQueue, docAcc, HeadersTraversalRule, null,
-                             ["heading-1-1", "heading-2-1", "heading-2-2"]);
+                             ["heading-1-1", "heading-2-2"]);
 
       queueTraversalSequence(
         gQueue, docAcc, ObjectTraversalRule, null,
         ["Main Title", "Lorem ipsum ",
          "dolor", " sit amet. Integer vitae urna leo, id ",
          "semper", " nulla. ", "Second Section Title",
          "Sed accumsan luctus lacus, vitae mollis arcu tristique vulputate.",
          "An ", "embedded", " document.", "Hide me", "Link 1", "Link 2",
@@ -88,23 +88,17 @@
         gQueue, docAcc, ObjectTraversalRule,
         getAccessible(doc.getElementById("paragraph-1")),
         ["Lorem ipsum ", "dolor", " sit amet. Integer vitae urna leo, id ",
          "semper", " nulla. "]);
 
       gQueue.push(new setModalRootInvoker(docAcc, docAcc.parent,
                                           NS_ERROR_INVALID_ARG));
 
-      // Put cursor in an ignored subtree
-      // set isFromUserInput to false, just to test..
-      gQueue.push(new setVCPosInvoker(docAcc, null, null,
-                                      getAccessible(doc.getElementById("hidden-link")),
-                                      false));
-      // Next item shoud be outside of that subtree
-      gQueue.push(new setVCPosInvoker(docAcc, "moveNext", ObjectTraversalRule, "An "));
+      gQueue.push(new setVCPosInvoker(docAcc, "moveNext", ObjectTraversalRule, "dolor"));
 
       gQueue.invoke();
     }
 
     SimpleTest.waitForExplicitFinish();
     addLoadEvent(function() {
       /* We open a new browser because we need to test with a top-level content
          document. */
--- a/accessible/tests/mochitest/tree/test_aria_globals.html
+++ b/accessible/tests/mochitest/tree/test_aria_globals.html
@@ -20,17 +20,16 @@
         "busy",
         "controls",
         "describedby",
         "disabled",
         "dropeffect",
         "flowto",
         "grabbed",
         "haspopup",
-        "hidden",
         "invalid",
         "label",
         "labelledby",
         "live",
         "owns",
         "relevant"
       ];
 
@@ -89,17 +88,16 @@
     <span id="busy" aria-busy="false"></span>
     <span id="controls" aria-controls="pawn"></span>
     <span id="describedby" aria-describedby="pawn"></span>
     <span id="disabled" aria-disabled="true"></span>
     <span id="dropeffect" aria-dropeffect="move"></span>
     <span id="flowto" aria-flowto="pawn"></span>
     <span id="grabbed" aria-grabbed="false"></span>
     <span id="haspopup" aria-haspopup="false"></span>
-    <span id="hidden" aria-hidden="true"></span>
     <span id="invalid" aria-invalid="false"></span>
     <span id="label" aria-label="hi"></span>
     <span id="labelledby" aria-labelledby="label"></span>
     <span id="live" aria-live="polite"></span>
     <span id="owns" aria-owns="pawn"></span>
     <span id="relevant" aria-relevant="additions"></span>
   </div>
 
@@ -110,17 +108,16 @@
       <td id="td_busy" aria-busy="false"></td>
       <td id="td_controls" aria-controls="pawn"></td>
       <td id="td_describedby" aria-describedby="pawn"></td>
       <td id="td_disabled" aria-disabled="true"></td>
       <td id="td_dropeffect" aria-dropeffect="move"></td>
       <td id="td_flowto" aria-flowto="pawn"></td>
       <td id="td_grabbed" aria-grabbed="false"></td>
       <td id="td_haspopup" aria-haspopup="false"></td>
-      <td id="td_hidden" aria-hidden="true"></td>
       <td id="td_invalid" aria-invalid="false"></td>
       <td id="td_label" aria-label="hi"></td>
       <td id="td_labelledby" aria-labelledby="label"></td>
       <td id="td_live" aria-live="polite"></td>
       <td id="td_owns" aria-owns="pawn"></td>
       <td id="td_relevant" aria-relevant="additions"></td>
     </tr>
   </table>
--- a/accessible/tests/mochitest/tree/test_media.html
+++ b/accessible/tests/mochitest/tree/test_media.html
@@ -39,27 +39,16 @@ https://bugzilla.mozilla.org/show_bug.cg
             role: ROLE_PROGRESSBAR,
             children: []
           },
           { // slider of progress bar
             role: ROLE_SLIDER,
             // name: "0:00 of 0:02 elapsed",
             children: []
           },
-          {
-            role: ROLE_TEXT_CONTAINER,
-            children: [
-              {
-                role: ROLE_TEXT_LEAF, // position text
-              },
-              {
-                role: ROLE_TEXT_LEAF, // duration text
-              }
-            ]
-          },
           { // mute button
             role: ROLE_PUSHBUTTON,
             name: "Mute",
             children: []
           },
           { // slider of volume bar
             role: ROLE_SLIDER,
             children: []
--- a/accessible/tests/mochitest/treeupdate/a11y.ini
+++ b/accessible/tests/mochitest/treeupdate/a11y.ini
@@ -1,15 +1,16 @@
 [DEFAULT]
 support-files =
   !/accessible/tests/mochitest/*.js
   !/accessible/tests/mochitest/letters.gif
   !/accessible/tests/mochitest/moz.png
 
 [test_ariadialog.html]
+[test_ariahidden.html]
 [test_ariaowns.html]
 [test_bug852150.xhtml]
 [test_bug883708.xhtml]
 [test_bug884251.xhtml]
 [test_bug895082.html]
 [test_bug1040735.html]
 [test_bug1100602.html]
 [test_bug1175913.html]
new file mode 100644
--- /dev/null
+++ b/accessible/tests/mochitest/treeupdate/test_ariahidden.html
@@ -0,0 +1,119 @@
+<html>
+
+<head>
+  <title>aria-hidden tree update tests</title>
+
+  <link rel="stylesheet" type="text/css"
+        href="chrome://mochikit/content/tests/SimpleTest/test.css" />
+
+  <script type="application/javascript"
+          src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+
+  <script type="application/javascript"
+          src="../common.js"></script>
+  <script type="application/javascript"
+          src="../role.js"></script>
+  <script type="application/javascript"
+          src="../events.js"></script>
+
+  <script type="application/javascript">
+    function t1_setARIAHidden() {
+      this.eventSeq = [
+        new invokerChecker(EVENT_REORDER, "t1")
+      ];
+
+      this.invoke = function t1_setARIAHidden_invoke() {
+        getNode("t1_child").setAttribute("aria-hidden", "true");
+      };
+
+      this.finalCheck = function t1_setARIAHidden_finalCheck() {
+        ok(!isAccessible("t1_child"), "No accessible for aria-hidden");
+      };
+
+      this.getID = function t1_setARIAHidden_getID() {
+        return "aria-hidden set to true";
+      };
+    }
+
+    function t1_removeARIAHidden() {
+      this.eventSeq = [
+        new invokerChecker(EVENT_REORDER, "t1")
+      ];
+
+      this.invoke = function t1_removeARIAHidden_invoke() {
+        getNode("t1_child").removeAttribute("aria-hidden");
+      };
+
+      this.finalCheck = function t1_removeARIAHidden_finalCheck() {
+        ok(isAccessible("t1_child"), "No aria-hidden, has to be accessible");
+      };
+
+      this.getID = function t1_removeARIAHidden_getID() {
+        return "remove aria-hidden";
+      };
+    }
+
+    function t2_setARIAHidden() {
+      this.eventSeq = [
+        new invokerChecker(EVENT_REORDER, "t2")
+      ];
+
+      this.invoke = function t2_setARIAHidden_invoke() {
+        getNode("t2_child").setAttribute("aria-hidden", "true");
+      };
+
+      this.finalCheck = function t2_setARIAHidden_finalCheck() {
+        testAccessibleTree("t2", { SECTION: []});
+      };
+
+      this.getID = function t2_setARIAHidden_getID() {
+        return "t2: set aria-hidden";
+      };
+    }
+
+    function t2_insertUnderARIAHidden() {
+      this.eventSeq = [
+        new unexpectedInvokerChecker(EVENT_REORDER, "t2")
+      ];
+
+      this.invoke = function t2_insertUnderARIAHidden_invoke() {
+        getNode("t2_child").innerHTML = "<input>";
+      };
+
+      this.finalCheck = function t2_insertUnderARIAHidden_finalCheck() {
+        testAccessibleTree("t2", { SECTION: []});
+      };
+
+      this.getID = function t2_insertUnderARIAHidden_getID() {
+        return "t2: insert under aria-hidden";
+      };
+    }
+
+    // gA11yEventDumpToConsole = true;
+    function doTests() {
+      ok(!isAccessible("t1_child"), "No accessible for aria-hidden");
+
+      gQueue = new eventQueue();
+      gQueue.push(new t1_removeARIAHidden());
+      gQueue.push(new t1_setARIAHidden());
+      gQueue.push(new t2_setARIAHidden());
+      gQueue.push(new t2_insertUnderARIAHidden());
+      gQueue.invoke(); // Will call SimpleTest.finish();
+    }
+
+    SimpleTest.waitForExplicitFinish();
+    addA11yLoadEvent(doTests);
+  </script>
+</head>
+
+<body>
+  <p id="display"></p>
+  <div id="content" style="display: none"></div>
+  <pre id="test">
+  </pre>
+  <div id="t1"><div id="t1_child" aria-hidden="true">Hi</div><div>there</div></div>
+  <div id="t2">
+    <span id="t2_child">hoho</span>
+  </div>
+</body>
+</html>
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -245,18 +245,19 @@ pref("browser.defaultbrowser.notificatio
 // 0 = blank, 1 = home (browser.startup.homepage), 2 = last visited page, 3 = resume previous browser session
 // The behavior of option 3 is detailed at: http://wiki.mozilla.org/Session_Restore
 pref("browser.startup.page",                1);
 pref("browser.startup.homepage",            "chrome://branding/locale/browserconfig.properties");
 // Whether we should skip the homepage when opening the first-run page
 pref("browser.startup.firstrunSkipsHomepage", true);
 
 // Show an about:blank window as early as possible for quick startup feedback.
+// Held to nightly on Linux due to bug 1450626.
 // Disabled on Mac because the bouncing dock icon already provides feedback.
-#if !defined(XP_MACOSX) && defined(NIGHTLY_BUILD)
+#if defined(XP_WIN) || defined(MOZ_WIDGET_GTK) && defined(NIGHTLY_BUILD)
 pref("browser.startup.blankWindow", true);
 #else
 pref("browser.startup.blankWindow", false);
 #endif
 
 pref("browser.slowStartup.notificationDisabled", false);
 pref("browser.slowStartup.timeThreshold", 20000);
 pref("browser.slowStartup.maxSamples", 5);
--- a/browser/base/content/browser-window.css
+++ b/browser/base/content/browser-window.css
@@ -1,16 +1,23 @@
 /* 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/. */
 
+/*
+ * The "global.css" stylesheet is imported first to allow other stylesheets to
+ * override rules using selectors with the same specificity. This applies to
+ * both "content" and "skin" packages, which bug 1385444 will unify later.
+ */
+@import url("chrome://global/skin/");
+
 @import url("chrome://browser/content/browser.css");
+@import url("chrome://browser/content/tabbrowser.css");
 @import url("chrome://browser/content/downloads/downloads.css");
 @import url("chrome://browser/content/places/places.css");
 @import url("chrome://browser/content/usercontext/usercontext.css");
+@import url("chrome://browser/skin/");
 @import url("chrome://browser/skin/controlcenter/panel.css");
 @import url("chrome://browser/skin/customizableui/panelUI.css");
 @import url("chrome://browser/skin/downloads/downloads.css");
 @import url("chrome://browser/skin/searchbar.css");
 @import url("chrome://browser/skin/places/places.css");
 @import url("chrome://browser/skin/places/editBookmark.css");
-@import url("chrome://browser/skin/");
-@import url("chrome://browser/content/tabbrowser.css");
--- a/browser/themes/linux/browser.css
+++ b/browser/themes/linux/browser.css
@@ -1,16 +1,14 @@
 %if 0
 /* 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/. */
 %endif
 
-@import url("chrome://global/skin/");
-
 @namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
 @namespace html url("http://www.w3.org/1999/xhtml");
 
 %include ../shared/browser.inc.css
 
 :root {
   --toolbar-non-lwt-bgcolor: -moz-dialog;
   --toolbar-non-lwt-textcolor: -moz-dialogtext;
--- a/browser/themes/osx/browser.css
+++ b/browser/themes/osx/browser.css
@@ -1,14 +1,12 @@
 /* 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/. */
 
-@import url("chrome://global/skin/");
-
 %include shared.inc
 %define toolbarButtonPressed :hover:active:not([disabled="true"]):not([cui-areatype="menu-panel"])
 
 @namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
 @namespace html url("http://www.w3.org/1999/xhtml");
 
 %include ../shared/browser.inc.css
 
--- a/browser/themes/windows/browser.css
+++ b/browser/themes/windows/browser.css
@@ -1,14 +1,12 @@
 /* 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/. */
 
-@import url("chrome://global/skin/");
-
 @namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
 @namespace html url("http://www.w3.org/1999/xhtml");
 
 %include ../shared/browser.inc.css
 %filter substitution
 %define glassShadowColor hsla(240,5%,5%,0.3)
 
 :root {
--- a/devtools/client/inspector/markup/views/element-container.js
+++ b/devtools/client/inspector/markup/views/element-container.js
@@ -29,47 +29,66 @@ loader.lazyRequireGetter(this, "setEvent
  *         The markup view that owns this container.
  * @param  {NodeFront} node
  *         The node to display.
  */
 function MarkupElementContainer(markupView, node) {
   MarkupContainer.prototype.initialize.call(this, markupView, node,
     "elementcontainer");
 
+  this.onFlexboxHighlighterChange = this.onFlexboxHighlighterChange.bind(this);
   this.onGridHighlighterChange = this.onGridHighlighterChange.bind(this);
 
+  this.markup.highlighters.on("flexbox-highlighter-hidden",
+    this.onFlexboxHighlighterChange);
+  this.markup.highlighters.on("flexbox-highlighter-shown",
+    this.onFlexboxHighlighterChange);
   this.markup.highlighters.on("grid-highlighter-hidden", this.onGridHighlighterChange);
   this.markup.highlighters.on("grid-highlighter-shown", this.onGridHighlighterChange);
 
   if (node.nodeType === nodeConstants.ELEMENT_NODE) {
     this.editor = new ElementEditor(this, node);
   } else {
     throw new Error("Invalid node for MarkupElementContainer");
   }
 
   this.tagLine.appendChild(this.editor.elt);
 }
 
 MarkupElementContainer.prototype = extend(MarkupContainer.prototype, {
   destroy: function() {
+    this.markup.highlighters.off("flexbox-highlighter-hidden",
+      this.onFlexboxHighlighterChange);
+    this.markup.highlighters.off("flexbox-highlighter-shown",
+      this.onFlexboxHighlighterChange);
     this.markup.highlighters.off("grid-highlighter-hidden", this.onGridHighlighterChange);
     this.markup.highlighters.off("grid-highlighter-shown", this.onGridHighlighterChange);
 
     MarkupContainer.prototype.destroy.call(this);
   },
 
   onContainerClick: function(event) {
     if (!event.target.hasAttribute("data-event")) {
       return;
     }
 
     this._buildEventTooltipContent(event.target);
   },
 
   /**
+   * Handler for "flexbox-highlighter-hidden" and "flexbox-highlighter-shown" event
+   * emitted from the HighlightersOverlay. Toggles the active state of the display badge
+   * if it matches the highlighted flex container node.
+   */
+  onFlexboxHighlighterChange: function() {
+    this.editor.displayBadge.classList.toggle("active",
+      this.markup.highlighters.flexboxHighlighterShown === this.node);
+  },
+
+  /**
    * Handler for "grid-highlighter-hidden" and "grid-highlighter-shown" event emitted from
    * the HighlightersOverlay. Toggles the active state of the display badge if it matches
    * the highlighted grid node.
    */
   onGridHighlighterChange: function() {
     this.editor.displayBadge.classList.toggle("active",
       this.markup.highlighters.gridHighlighterShown === this.node);
   },
--- a/devtools/client/inspector/markup/views/element-editor.js
+++ b/devtools/client/inspector/markup/views/element-editor.js
@@ -290,17 +290,21 @@ ElementEditor.prototype = {
   updateDisplayBadge: function() {
     const showDisplayBadge = this.node.displayType in DISPLAY_TYPES;
     this.displayBadge.textContent = this.node.displayType;
     this.displayBadge.dataset.display = showDisplayBadge ? this.node.displayType : "";
     this.displayBadge.style.display = showDisplayBadge ? "inline-block" : "none";
     this.displayBadge.title = showDisplayBadge ?
       DISPLAY_TYPES[this.node.displayType] : "";
     this.displayBadge.classList.toggle("active",
+      this.highlighters.flexboxHighlighterShown === this.node ||
       this.highlighters.gridHighlighterShown === this.node);
+    this.displayBadge.classList.toggle("interactive",
+      Services.prefs.getBoolPref("devtools.inspector.flexboxHighlighter.enabled") &&
+      (this.node.displayType === "flex" || this.node.displayType === "inline-flex"));
   },
 
   /**
    * Update the inline text editor in case of a single text child node.
    */
   updateTextEditor: function() {
     const node = this.node.inlineTextChild;
 
@@ -643,21 +647,27 @@ ElementEditor.prototype = {
   /**
    * Called when the display badge is clicked. Toggles on the grid highlighter for the
    * selected node if it is a grid container.
    */
   onDisplayBadgeClick: function(event) {
     event.stopPropagation();
 
     const target = event.target;
-    if (target.dataset.display !== "grid" && target.dataset.display !== "inline-grid") {
-      return;
+
+    if (Services.prefs.getBoolPref("devtools.inspector.flexboxHighlighter.enabled") &&
+        (target.dataset.display === "flex" || target.dataset.display === "inline-flex")) {
+      this.highlighters.toggleFlexboxHighlighter(this.inspector.selection.nodeFront,
+        "markup");
     }
 
-    this.highlighters.toggleGridHighlighter(this.inspector.selection.nodeFront, "markup");
+    if (target.dataset.display === "grid" || target.dataset.display === "inline-grid") {
+      this.highlighters.toggleGridHighlighter(this.inspector.selection.nodeFront,
+        "markup");
+    }
   },
 
   /**
    * Called when the tag name editor has is done editing.
    */
   onTagEdit: function(newTagName, isCommit) {
     if (!isCommit ||
         newTagName.toLowerCase() === this.node.tagName.toLowerCase() ||
--- a/devtools/client/themes/markup.css
+++ b/devtools/client/themes/markup.css
@@ -413,19 +413,28 @@ ul.children + .tag-line::before {
 }
 
 .markup-badge.active {
   background-color: var(--markup-badge-active-background-color);
   border-color: var(--theme-selection-color);
   color: var(--theme-selection-color);
 }
 
+.markup-badge[data-display="flex"].interactive,
 .markup-badge[data-display="grid"],
+.markup-badge[data-display="inline-flex"],
+.markup-badge[data-display="inline-grid"],
 .markup-badge[data-event] {
   cursor: pointer;
 }
 
+.markup-badge[data-display="flex"].interactive:focus,
+.markup-badge[data-display="flex"].interactive:hover,
 .markup-badge[data-display="grid"]:focus,
 .markup-badge[data-display="grid"]:hover,
+.markup-badge[data-display="inline-flex"].interactive:focus,
+.markup-badge[data-display="inline-flex"].interactive:hover,
+.markup-badge[data-display="inline-grid"]:focus,
+.markup-badge[data-display="inline-grid"]:hover,
 .markup-badge[data-event]:focus,
 .markup-badge[data-event]:hover {
   background-color: var(--markup-badge-hover-background-color);
 }
--- a/dom/base/nsDocument.cpp
+++ b/dom/base/nsDocument.cpp
@@ -9588,57 +9588,25 @@ void
 nsIDocument::SetNavigationTiming(nsDOMNavigationTiming* aTiming)
 {
   mTiming = aTiming;
   if (!mLoadingTimeStamp.IsNull() && mTiming) {
     mTiming->SetDOMLoadingTimeStamp(GetDocumentURI(), mLoadingTimeStamp);
   }
 }
 
-Element*
-nsIDocument::FindImageMap(const nsAString& aUseMapValue)
-{
-  if (aUseMapValue.IsEmpty()) {
-    return nullptr;
-  }
-
-  nsAString::const_iterator start, end;
-  aUseMapValue.BeginReading(start);
-  aUseMapValue.EndReading(end);
-
-  int32_t hash = aUseMapValue.FindChar('#');
-  if (hash < 0) {
-    return nullptr;
-  }
-  // aUsemap contains a '#', set start to point right after the '#'
-  start.advance(hash + 1);
-
-  if (start == end) {
-    return nullptr; // aUsemap == "#"
-  }
-
-  const nsAString& mapName = Substring(start, end);
-
+nsContentList*
+nsIDocument::ImageMapList()
+{
   if (!mImageMaps) {
-    mImageMaps = new nsContentList(this, kNameSpaceID_XHTML, nsGkAtoms::map, nsGkAtoms::map);
-  }
-
-  uint32_t i, n = mImageMaps->Length(true);
-  nsString name;
-  for (i = 0; i < n; ++i) {
-    nsIContent* map = mImageMaps->Item(i);
-    if (map->AsElement()->AttrValueIs(kNameSpaceID_None, nsGkAtoms::id, mapName,
-                                      eCaseMatters) ||
-        map->AsElement()->AttrValueIs(kNameSpaceID_None, nsGkAtoms::name, mapName,
-                                      eCaseMatters)) {
-      return map->AsElement();
-    }
-  }
-
-  return nullptr;
+    mImageMaps = new nsContentList(this, kNameSpaceID_XHTML,
+                                   nsGkAtoms::map, nsGkAtoms::map);
+  }
+
+  return mImageMaps;
 }
 
 #define DEPRECATED_OPERATION(_op) #_op "Warning",
 static const char* kDeprecationWarnings[] = {
 #include "nsDeprecatedOperationList.h"
   nullptr
 };
 #undef DEPRECATED_OPERATION
--- a/dom/base/nsFocusManager.cpp
+++ b/dom/base/nsFocusManager.cpp
@@ -43,16 +43,17 @@
 #include "TabChild.h"
 #include "nsFrameLoader.h"
 #include "nsNumberControlFrame.h"
 #include "nsNetUtil.h"
 #include "nsRange.h"
 
 #include "mozilla/ContentEvents.h"
 #include "mozilla/dom/Element.h"
+#include "mozilla/dom/HTMLImageElement.h"
 #include "mozilla/dom/HTMLInputElement.h"
 #include "mozilla/dom/HTMLSlotElement.h"
 #include "mozilla/dom/Text.h"
 #include "mozilla/EventDispatcher.h"
 #include "mozilla/EventStateManager.h"
 #include "mozilla/EventStates.h"
 #include "mozilla/HTMLEditor.h"
 #include "mozilla/IMEStateManager.h"
@@ -3852,22 +3853,22 @@ nsFocusManager::TryToMoveFocusToSubDocum
 }
 
 nsIContent*
 nsFocusManager::GetNextTabbableMapArea(bool aForward,
                                        int32_t aCurrentTabIndex,
                                        Element* aImageContent,
                                        nsIContent* aStartContent)
 {
-  nsAutoString useMap;
-  aImageContent->GetAttr(kNameSpaceID_None, nsGkAtoms::usemap, useMap);
-
-  nsCOMPtr<nsIDocument> doc = aImageContent->GetComposedDoc();
-  if (doc) {
-    nsCOMPtr<nsIContent> mapContent = doc->FindImageMap(useMap);
+  if (aImageContent->IsInComposedDoc()) {
+    HTMLImageElement* imgElement = HTMLImageElement::FromNode(aImageContent);
+    // The caller should check the element type, so we can assert here.
+    MOZ_ASSERT(imgElement);
+
+    nsCOMPtr<nsIContent> mapContent = imgElement->FindImageMap();
     if (!mapContent)
       return nullptr;
     uint32_t count = mapContent->GetChildCount();
     // First see if the the start content is in this map
 
     int32_t index = mapContent->ComputeIndexOf(aStartContent);
     int32_t tabIndex;
     if (index < 0 || (aStartContent->IsFocusable(&tabIndex) &&
--- a/dom/base/nsIDocument.h
+++ b/dom/base/nsIDocument.h
@@ -2928,17 +2928,17 @@ public:
 
   nsDOMNavigationTiming* GetNavigationTiming() const
   {
     return mTiming;
   }
 
   void SetNavigationTiming(nsDOMNavigationTiming* aTiming);
 
-  Element* FindImageMap(const nsAString& aNormalizedMapName);
+  nsContentList* ImageMapList();
 
   // Add aLink to the set of links that need their status resolved.
   void RegisterPendingLinkUpdate(mozilla::dom::Link* aLink);
 
   // Update state on links in mLinksToUpdate.  This function must be called
   // prior to selector matching that needs to differentiate between :link and
   // :visited.  In particular, it does _not_ need to be called before doing any
   // selector matching that uses TreeMatchContext::eNeverMatchVisited.  The only
--- a/dom/base/nsImageLoadingContent.cpp
+++ b/dom/base/nsImageLoadingContent.cpp
@@ -12,16 +12,17 @@
 
 #include "nsImageLoadingContent.h"
 #include "nsError.h"
 #include "nsIContent.h"
 #include "nsIDocument.h"
 #include "nsIScriptGlobalObject.h"
 #include "nsIDOMWindow.h"
 #include "nsServiceManagerUtils.h"
+#include "nsContentList.h"
 #include "nsContentPolicyUtils.h"
 #include "nsIURI.h"
 #include "nsILoadGroup.h"
 #include "imgIContainer.h"
 #include "imgLoader.h"
 #include "imgRequestProxy.h"
 #include "nsThreadUtils.h"
 #include "nsNetUtil.h"
@@ -1731,8 +1732,66 @@ nsImageLoadingContent::ScriptedImageObse
 
 // Only HTMLInputElement.h overrides this for <img> tags
 // all other subclasses use this one, i.e. ignore referrer attributes
 mozilla::net::ReferrerPolicy
 nsImageLoadingContent::GetImageReferrerPolicy()
 {
   return mozilla::net::RP_Unset;
 }
+
+Element*
+nsImageLoadingContent::FindImageMap()
+{
+  nsIContent* thisContent = AsContent();
+  Element* thisElement = thisContent->AsElement();
+
+  nsAutoString useMap;
+  thisElement->GetAttr(kNameSpaceID_None, nsGkAtoms::usemap, useMap);
+  if (useMap.IsEmpty()) {
+    return nullptr;
+  }
+
+  nsAString::const_iterator start, end;
+  useMap.BeginReading(start);
+  useMap.EndReading(end);
+
+  int32_t hash = useMap.FindChar('#');
+  if (hash < 0) {
+    return nullptr;
+  }
+  // useMap contains a '#', set start to point right after the '#'
+  start.advance(hash + 1);
+
+  if (start == end) {
+    return nullptr; // useMap == "#"
+  }
+
+  RefPtr<nsContentList> imageMapList;
+  if (thisElement->IsInUncomposedDoc()) {
+    // Optimize the common case and use document level image map.
+    imageMapList = thisElement->OwnerDoc()->ImageMapList();
+  } else {
+    // Per HTML spec image map should be searched in the element's scope,
+    // so using SubtreeRoot() here.
+    // Because this is a temporary list, we don't need to make it live.
+    imageMapList = new nsContentList(thisElement->SubtreeRoot(),
+                                     kNameSpaceID_XHTML,
+                                     nsGkAtoms::map, nsGkAtoms::map,
+                                     true, /* deep */
+                                     false /* live */);
+  }
+
+  nsAutoString mapName(Substring(start, end));
+
+  uint32_t i, n = imageMapList->Length(true);
+  for (i = 0; i < n; ++i) {
+    nsIContent* map = imageMapList->Item(i);
+    if (map->AsElement()->AttrValueIs(kNameSpaceID_None, nsGkAtoms::id,
+                                      mapName, eCaseMatters) ||
+        map->AsElement()->AttrValueIs(kNameSpaceID_None, nsGkAtoms::name,
+                                      mapName, eCaseMatters)) {
+      return map->AsElement();
+    }
+  }
+
+  return nullptr;
+}
--- a/dom/base/nsImageLoadingContent.h
+++ b/dom/base/nsImageLoadingContent.h
@@ -28,16 +28,19 @@
 class nsIURI;
 class nsIDocument;
 class nsPresContext;
 class nsIContent;
 class imgRequestProxy;
 
 namespace mozilla {
 class AsyncEventDispatcher;
+namespace dom {
+class Element;
+} // namespace Element;
 } // namespace mozilla
 
 #ifdef LoadImage
 // Undefine LoadImage to prevent naming conflict with Windows.
 #undef LoadImage
 #endif
 
 class nsImageLoadingContent : public nsIImageLoadingContent
@@ -70,16 +73,18 @@ public:
   already_AddRefed<imgIRequest>
     GetRequest(int32_t aRequestType, mozilla::ErrorResult& aError);
   int32_t
     GetRequestType(imgIRequest* aRequest, mozilla::ErrorResult& aError);
   already_AddRefed<nsIURI> GetCurrentURI(mozilla::ErrorResult& aError);
   already_AddRefed<nsIURI> GetCurrentRequestFinalURI();
   void ForceReload(bool aNotify, mozilla::ErrorResult& aError);
 
+  mozilla::dom::Element* FindImageMap();
+
 protected:
   enum ImageLoadType {
     // Most normal image loads
     eImageLoadType_Normal,
     // From a <img srcset> or <picture> context. Affects type given to content
     // policy.
     eImageLoadType_Imageset
   };
--- a/dom/base/test/mochitest.ini
+++ b/dom/base/test/mochitest.ini
@@ -612,16 +612,17 @@ skip-if = toolkit == 'android'
 [test_bug1381710.html]
 [test_bug1384661.html]
 [test_bug1399605.html]
 [test_bug1404385.html]
 [test_bug1406102.html]
 [test_bug1421568.html]
 [test_bug1453693.html]
 skip-if = os == "mac"
+[test_bug1472427.html]
 [test_caretPositionFromPoint.html]
 [test_change_policy.html]
 [test_clearTimeoutIntervalNoArg.html]
 [test_constructor-assignment.html]
 [test_constructor.html]
 [test_copyimage.html]
 subsuite = clipboard
 skip-if = toolkit == 'android' #bug 904183
new file mode 100644
--- /dev/null
+++ b/dom/base/test/test_bug1472427.html
@@ -0,0 +1,89 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1472427
+-->
+<head>
+  <meta charset="utf-8">
+  <title>Test for Bug 1472427</title>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+  <script type="application/javascript">
+
+  /** Test for Bug 1472427 **/
+
+  SimpleTest.waitForExplicitFinish();
+  var image100x100 = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAABkCAYAAABw4pVUAAAAnUlEQVR42u3RAQ0AAAQAMLJqqCA1zP4Kz+qe4IwUIgQhQhAiBCFCECJEiBCECEGIEIQIQYgQhCBECEKEIEQIQoQgBCFCECIEIUIQIgQhCBGCECEIEYIQIQhBiBCECEGIEIQIQQhChCBECEKEIEQIQhAiBCFCECIEIUIQghAhCBGCECEIEYIQhAhBiBCECEGIEIQIESIEIUIQIgQh3y1XQhXMIlaKKwAAAABJRU5ErkJggg==";
+  var ifr;
+  var doc;
+  var img;
+  var host;
+  var root;
+  var map;
+  var area;
+
+  function initPage() {
+    ifr = document.createElement("iframe");
+    ifr.src = "about:blank";
+    document.body.appendChild(ifr);
+    ifr.onload = initIframe;
+  }
+
+  function initIframe() {
+    ifr.contentWindow.focus();
+    doc = ifr.contentDocument;
+    host = doc.createElement("div");
+    doc.body.appendChild(host);
+    root = host.attachShadow({mode: "open"});
+
+    img = document.createElement("img");
+    img.useMap = "#map"
+    img.src = image100x100;
+    img.onload = runTest;
+    root.appendChild(img);
+
+    map = doc.createElement("map");
+    map.name = "map";
+    root.appendChild(map);
+
+    area = doc.createElement("area");
+    area.shape = "rect";
+    area.href = "#area";
+    area.coords = "0,0,100,100";
+    map.appendChild(area);
+  }
+
+  function runTest() {
+    var gotClick = false;
+    var expectedTarget = area;
+    root.addEventListener("click",
+                          function(e) {
+                            gotClick = true;
+                            is(e.target, expectedTarget,
+                                expectedTarget.localName + " element should be the target for the click.");
+                            e.preventDefault();
+                          });
+    synthesizeMouse(img, 50, 50, {}, ifr.contentWindow);
+    ok(gotClick, "Should have got a click event.");
+
+    gotclick = false;
+    map.name = "wrongNameMap";
+    expectedTarget = img;
+    synthesizeMouse(img, 50, 50, {}, ifr.contentWindow);
+    ok(gotClick, "Should have got a click event.");
+    SimpleTest.finish();
+  }
+
+  </script>
+</head>
+<body onload="SpecialPowers.pushPrefEnv({'set':[['dom.webcomponents.shadowdom.enabled', true]]}, initPage);">
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1472427">Mozilla Bug 1472427</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+</pre>
+</body>
+</html>
--- a/dom/html/HTMLFormElement.cpp
+++ b/dom/html/HTMLFormElement.cpp
@@ -393,16 +393,18 @@ CollectOrphans(nsINode* aRemovalRoot,
     }
 #endif /* DEBUG */
   }
 }
 
 void
 HTMLFormElement::UnbindFromTree(bool aDeep, bool aNullParent)
 {
+  // Note, this is explicitly using uncomposed doc, since we count
+  // only forms in document.
   nsCOMPtr<nsIHTMLDocument> oldDocument = do_QueryInterface(GetUncomposedDoc());
 
   // Mark all of our controls as maybe being orphans
   MarkOrphans(mControls->mElements);
   MarkOrphans(mControls->mNotInElements);
   MarkOrphans(mImageElements);
 
   nsGenericHTMLElement::UnbindFromTree(aDeep, aNullParent);
@@ -1642,17 +1644,17 @@ HTMLFormElement::GetActionURL(nsIURI** a
 
   //
   // Form the full action URL
   //
 
   // Get the document to form the URL.
   // We'll also need it later to get the DOM window when notifying form submit
   // observers (bug 33203)
-  if (!IsInUncomposedDoc()) {
+  if (!IsInComposedDoc()) {
     return NS_OK; // No doc means don't submit, see Bug 28988
   }
 
   // Get base URL
   nsIDocument *document = OwnerDoc();
   nsIURI *docURI = document->GetDocumentURI();
   NS_ENSURE_TRUE(docURI, NS_ERROR_UNEXPECTED);
 
--- a/dom/html/HTMLImageElement.cpp
+++ b/dom/html/HTMLImageElement.cpp
@@ -515,33 +515,26 @@ HTMLImageElement::GetEventTargetParent(E
 }
 
 bool
 HTMLImageElement::IsHTMLFocusable(bool aWithMouse,
                                   bool *aIsFocusable, int32_t *aTabIndex)
 {
   int32_t tabIndex = TabIndex();
 
-  if (IsInUncomposedDoc()) {
-    nsAutoString usemap;
-    GetUseMap(usemap);
-    // XXXbz which document should this be using?  sXBL/XBL2 issue!  I
-    // think that OwnerDoc() is right, since we don't want to
-    // assume stuff about the document we're bound to.
-    if (OwnerDoc()->FindImageMap(usemap)) {
-      if (aTabIndex) {
-        // Use tab index on individual map areas
-        *aTabIndex = (sTabFocusModel & eTabFocus_linksMask)? 0 : -1;
-      }
-      // Image map is not focusable itself, but flag as tabbable
-      // so that image map areas get walked into.
-      *aIsFocusable = false;
+  if (IsInComposedDoc() && FindImageMap()) {
+    if (aTabIndex) {
+      // Use tab index on individual map areas
+      *aTabIndex = (sTabFocusModel & eTabFocus_linksMask)? 0 : -1;
+    }
+    // Image map is not focusable itself, but flag as tabbable
+    // so that image map areas get walked into.
+    *aIsFocusable = false;
 
-      return false;
-    }
+    return false;
   }
 
   if (aTabIndex) {
     // Can be in tab order if tabindex >=0 and form controls are tabbable.
     *aTabIndex = (sTabFocusModel & eTabFocus_formElementsMask)? tabIndex : -1;
   }
 
   *aIsFocusable =
--- a/dom/html/test/mochitest.ini
+++ b/dom/html/test/mochitest.ini
@@ -590,16 +590,17 @@ skip-if = (os == 'android' || os == 'mac
 [test_allowMedia.html]
 skip-if = (verify && (os == 'linux' || os == 'win'))
 [test_bug1292522_same_domain_with_different_port_number.html]
 [test_bug1295719_event_sequence_for_arrow_keys.html]
 skip-if = os == "android" # up/down arrow keys not supported on android
 [test_bug1295719_event_sequence_for_number_keys.html]
 [test_bug1310865.html]
 [test_bug1315146.html]
+[test_bug1472426.html]
 [test_fakepath.html]
 [test_script_module.html]
 support-files =
   file_script_module.html
   file_script_nomodule.html
 [test_getElementsByName_after_mutation.html]
 [test_bug1279218.html]
 [test_set_input_files.html]
new file mode 100644
--- /dev/null
+++ b/dom/html/test/test_bug1472426.html
@@ -0,0 +1,123 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1472426
+-->
+<head>
+  <meta charset="utf-8">
+  <title>Test for Bug 1472426</title>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+  <script type="application/javascript">
+
+  /** Test for Bug 1472426 **/
+
+  var shadowIframe;
+  var targetIframe;
+  var form;
+  var sr;
+
+  function checkMPSubmission(sub, expected, test) {
+    function getPropCount(o) {
+      var x, l = 0;
+      for (x in o) ++l;
+      return l;
+    }
+    function mpquote(s) {
+      return s.replace(/\r\n/g, " ")
+              .replace(/\r/g, " ")
+              .replace(/\n/g, " ")
+              .replace(/\"/g, "\\\"");
+    }
+
+    is(sub.length, expected.length,
+       "Correct number of multipart items in " + test);
+
+    if (sub.length != expected.length) {
+      alert(JSON.stringify(sub));
+    }
+
+    var i;
+    for (i = 0; i < expected.length; ++i) {
+      if (!("fileName" in expected[i])) {
+        is(sub[i].headers["Content-Disposition"],
+           "form-data; name=\"" + mpquote(expected[i].name) + "\"",
+           "Correct name in " + test);
+        is (getPropCount(sub[i].headers), 1,
+            "Wrong number of headers in " + test);
+        is(sub[i].body,
+           expected[i].value.replace(/\r\n|\r|\n/, "\r\n"),
+           "Correct value in " + test);
+      }
+      else {
+        is(sub[i].headers["Content-Disposition"],
+           "form-data; name=\"" + mpquote(expected[i].name) + "\"; filename=\"" +
+             mpquote(expected[i].fileName) + "\"",
+           "Correct name in " + test);
+        is(sub[i].headers["Content-Type"],
+           expected[i].contentType,
+           "Correct content type in " + test);
+        is (getPropCount(sub[i].headers), 2,
+            "Wrong number of headers in " + test);
+        is(sub[i].body,
+           expected[i].value,
+           "Correct value in " + test);
+      }
+    }
+  }
+
+  function testFormSubmissionInShadowDOM() {
+    targetIframe = document.getElementById("target_iframe");
+    shadowIframe = document.createElement("iframe");
+    shadowIframe.src = "about:blank";
+    shadowIframe.onload = shadowFrameCreated;
+    document.body.appendChild(shadowIframe);
+  }
+
+  function shadowFrameCreated() {
+    var doc = shadowIframe.contentDocument;
+    var body = doc.body;
+    var host = doc.createElement("div");
+    body.appendChild(host);
+    sr = host.attachShadow({ mode: "open" });
+    sr.appendChild(document.getElementById('template').content.cloneNode(true));
+    targetIframe.onload = checkSubmitValues;
+    sr.getElementById("form").submit();
+  }
+
+  function checkSubmitValues() {
+    submission = JSON.parse(targetIframe.contentDocument.documentElement.textContent);
+    var expected = [
+       { name: "text", value: "textvalue" },
+       { name: "hidden", value: "hiddenvalue" },
+       { name: "select", value: "selectvalue" },
+       { name: "textarea", value: "textareavalue" }
+      ];
+    checkMPSubmission(submission, expected, "form submission inside shadow DOM");
+    SimpleTest.finish();
+  }
+
+  window.onload = function() {
+    SimpleTest.waitForExplicitFinish();
+    SpecialPowers.pushPrefEnv({"set":[["dom.webcomponents.shadowdom.enabled", true]]},
+                              () => {
+                                testFormSubmissionInShadowDOM();
+                              });
+  }
+
+  </script>
+  <template id="template">
+    <form action="form_submit_server.sjs" target="target_iframe" id="form"
+          method="POST" enctype="multipart/form-data">
+      <input name="text" value="textvalue">
+      <input name="hidden" value="hiddenvalue" type="hidden">
+      <select name="select"><option selected>selectvalue</option></select>
+      <textarea name="textarea">textareavalue</textarea>
+    </form>
+  </template>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1472426">Mozilla Bug 1472426</a>
+<iframe name="target_iframe" id="target_iframe"></iframe>
+</body>
+</html>
--- a/gfx/2d/2D.h
+++ b/gfx/2d/2D.h
@@ -893,23 +893,28 @@ public:
     mUserData.RemoveAndDestroy(key);
   }
 
   const RefPtr<UnscaledFont>& GetUnscaledFont() const { return mUnscaledFont; }
 
   virtual cairo_scaled_font_t* GetCairoScaledFont() { return nullptr; }
   virtual void SetCairoScaledFont(cairo_scaled_font_t* font) {}
 
+  Float GetSyntheticObliqueAngle() const { return mSyntheticObliqueAngle; }
+  void SetSyntheticObliqueAngle(Float aAngle) { mSyntheticObliqueAngle = aAngle; }
+
 protected:
   explicit ScaledFont(const RefPtr<UnscaledFont>& aUnscaledFont)
     : mUnscaledFont(aUnscaledFont)
+    , mSyntheticObliqueAngle(0.0f)
   {}
 
   UserData mUserData;
   RefPtr<UnscaledFont> mUnscaledFont;
+  Float mSyntheticObliqueAngle;
 
 private:
   static Atomic<uint32_t> sDeletionCounter;
 };
 
 /**
  * Derived classes hold a native font resource from which to create
  * ScaledFonts.
--- a/gfx/2d/CaptureCommandList.h
+++ b/gfx/2d/CaptureCommandList.h
@@ -8,73 +8,86 @@
 #define mozilla_gfx_2d_CaptureCommandList_h
 
 #include "mozilla/Move.h"
 #include "mozilla/PodOperations.h"
 #include <vector>
 
 #include "DrawCommand.h"
 #include "Logging.h"
+#include "RwAssert.h"
 
 namespace mozilla {
 namespace gfx {
 
 class CaptureCommandList
 {
 public:
   CaptureCommandList()
     : mLastCommand(nullptr)
   {}
   CaptureCommandList(CaptureCommandList&& aOther)
-   : mStorage(std::move(aOther.mStorage)), mLastCommand(aOther.mLastCommand)
+    : mStorage(std::move(aOther.mStorage))
+    , mLastCommand(aOther.mLastCommand)
   {
     aOther.mLastCommand = nullptr;
   }
   ~CaptureCommandList();
 
-  CaptureCommandList& operator =(CaptureCommandList&& aOther) {
+  CaptureCommandList& operator=(CaptureCommandList&& aOther) {
+    RwAssert::Writer lock(mAssert);
     mStorage = std::move(aOther.mStorage);
     mLastCommand = aOther.mLastCommand;
     aOther.mLastCommand = nullptr;
     return *this;
   }
 
   template <typename T>
   T* Append() {
+    RwAssert::Writer lock(mAssert);
     size_t oldSize = mStorage.size();
     mStorage.resize(mStorage.size() + sizeof(T) + sizeof(uint32_t));
     uint8_t* nextDrawLocation = &mStorage.front() + oldSize;
     *(uint32_t*)(nextDrawLocation) = sizeof(T) + sizeof(uint32_t);
     T* newCommand = reinterpret_cast<T*>(nextDrawLocation + sizeof(uint32_t));
     mLastCommand = newCommand;
     return newCommand;
   }
 
   template <typename T>
   T* ReuseOrAppend() {
-    if (mLastCommand != nullptr &&
-      mLastCommand->GetType() == T::Type) {
-      return reinterpret_cast<T*>(mLastCommand);
+    { // Scope lock
+      RwAssert::Writer lock(mAssert);
+      if (mLastCommand != nullptr &&
+        mLastCommand->GetType() == T::Type) {
+        return reinterpret_cast<T*>(mLastCommand);
+      }
     }
     return Append<T>();
   }
 
   class iterator
   {
   public:
     explicit iterator(CaptureCommandList& aParent)
      : mParent(aParent),
        mCurrent(nullptr),
        mEnd(nullptr)
     {
+      mParent.mAssert.BeginReading();
       if (!mParent.mStorage.empty()) {
         mCurrent = &mParent.mStorage.front();
         mEnd = mCurrent + mParent.mStorage.size();
       }
     }
+    ~iterator()
+    {
+      mParent.mAssert.EndReading();
+    }
+
     bool Done() const {
       return mCurrent >= mEnd;
     }
     void Next() {
       MOZ_ASSERT(!Done());
       mCurrent += *reinterpret_cast<uint32_t*>(mCurrent);
     }
     DrawingCommand* Get() {
@@ -99,14 +112,15 @@ public:
 
 private:
   CaptureCommandList(const CaptureCommandList& aOther) = delete;
   void operator =(const CaptureCommandList& aOther) = delete;
 
 private:
   std::vector<uint8_t> mStorage;
   DrawingCommand* mLastCommand;
+  RwAssert mAssert;
 };
 
 } // namespace gfx
 } // namespace mozilla
 
 #endif // mozilla_gfx_2d_CaptureCommandList_h
new file mode 100644
--- /dev/null
+++ b/gfx/2d/RwAssert.h
@@ -0,0 +1,98 @@
+/* -*- 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/. */
+
+#ifndef mozilla_gfx_2d_RwAssert_h
+#define mozilla_gfx_2d_RwAssert_h
+
+#include "mozilla/Attributes.h"
+#include "mozilla/Mutex.h"
+
+namespace mozilla {
+namespace gfx {
+
+class RwAssert {
+public:
+  RwAssert()
+    : mLock("RwAssert::mLock")
+    , mReaders(0)
+    , mWriting(false)
+  { }
+
+  ~RwAssert()
+  {
+    MOZ_RELEASE_ASSERT(!mReaders && !mWriting);
+  }
+
+  class MOZ_RAII Writer {
+  public:
+    MOZ_IMPLICIT Writer(RwAssert& aAssert)
+      : mAssert(aAssert)
+    {
+      mAssert.BeginWriting();
+    }
+    ~Writer()
+    {
+      mAssert.EndWriting();
+    }
+
+  private:
+    RwAssert& mAssert;
+  };
+
+  class MOZ_RAII Reader {
+  public:
+    MOZ_IMPLICIT Reader(RwAssert& aAssert)
+      : mAssert(aAssert)
+    {
+      mAssert.BeginReading();
+    }
+    ~Reader()
+    {
+      mAssert.EndReading();
+    }
+
+  private:
+    RwAssert& mAssert;
+  };
+
+  void BeginWriting()
+  {
+    MutexAutoLock lock(mLock);
+    MOZ_RELEASE_ASSERT(!mReaders && !mWriting);
+    mWriting = true;
+  }
+
+  void EndWriting()
+  {
+    MutexAutoLock lock(mLock);
+    MOZ_ASSERT(mWriting);
+    mWriting = false;
+  }
+
+  void BeginReading()
+  {
+    MutexAutoLock lock(mLock);
+    MOZ_RELEASE_ASSERT(!mWriting);
+    mReaders += 1;
+  }
+
+  void EndReading()
+  {
+    MutexAutoLock lock(mLock);
+    MOZ_ASSERT(mReaders > 0);
+    mReaders -= 1;
+  }
+
+private:
+  Mutex mLock;
+  uint32_t mReaders;
+  bool mWriting;
+};
+
+} // namespace gfx
+} // namespace mozilla
+
+#endif // mozilla_gfx_2d_RwAssert_h
--- a/gfx/2d/ScaledFontDWrite.cpp
+++ b/gfx/2d/ScaledFontDWrite.cpp
@@ -469,16 +469,17 @@ ScaledFontDWrite::GetWRFontInstanceOptio
   }
   if (UseEmbeddedBitmaps()) {
     options.flags |= wr::FontInstanceFlags::EMBEDDED_BITMAPS;
   }
   if (ForceGDIMode()) {
     options.flags |= wr::FontInstanceFlags::FORCE_GDI;
   }
   options.bg_color = wr::ToColorU(Color());
+  options.synthetic_italics = wr::DegreesToSyntheticItalics(GetSyntheticObliqueAngle());
   *aOutOptions = Some(options);
   return true;
 }
 
 // Helper for UnscaledFontDWrite::CreateScaledFont: create a clone of the
 // given IDWriteFontFace, with specified variation-axis values applied.
 // Returns nullptr in case of failure.
 static already_AddRefed<IDWriteFontFace5>
--- a/gfx/2d/ScaledFontFontconfig.cpp
+++ b/gfx/2d/ScaledFontFontconfig.cpp
@@ -236,16 +236,17 @@ ScaledFontFontconfig::GetWRFontInstanceO
                                                std::vector<FontVariation>* aOutVariations)
 {
   wr::FontInstanceOptions options;
   options.render_mode = wr::FontRenderMode::Alpha;
   // FIXME: Cairo-FT metrics are not compatible with subpixel positioning.
   // options.flags = wr::FontInstanceFlags::SUBPIXEL_POSITION;
   options.flags = 0;
   options.bg_color = wr::ToColorU(Color());
+  options.synthetic_italics = wr::DegreesToSyntheticItalics(GetSyntheticObliqueAngle());
 
   wr::FontInstancePlatformOptions platformOptions;
   platformOptions.lcd_filter = wr::FontLCDFilter::Legacy;
   platformOptions.hinting = wr::FontHinting::Normal;
 
   FcBool autohint;
   if (FcPatternGetBool(mPattern, FC_AUTOHINT, 0, &autohint) == FcResultMatch && autohint) {
     options.flags |= wr::FontInstanceFlags::FORCE_AUTOHINT;
--- a/gfx/2d/ScaledFontFreeType.cpp
+++ b/gfx/2d/ScaledFontFreeType.cpp
@@ -63,16 +63,17 @@ ScaledFontFreeType::GetWRFontInstanceOpt
                                              std::vector<FontVariation>* aOutVariations)
 {
   wr::FontInstanceOptions options;
   options.render_mode = wr::FontRenderMode::Alpha;
   // FIXME: Cairo-FT metrics are not compatible with subpixel positioning.
   // options.flags = wr::FontInstanceFlags::SUBPIXEL_POSITION;
   options.flags = 0;
   options.bg_color = wr::ToColorU(Color());
+  options.synthetic_italics = wr::DegreesToSyntheticItalics(GetSyntheticObliqueAngle());
 
   wr::FontInstancePlatformOptions platformOptions;
   platformOptions.lcd_filter = wr::FontLCDFilter::None;
   platformOptions.hinting = wr::FontHinting::None;
 
   *aOutOptions = Some(options);
   *aOutPlatformOptions = Some(platformOptions);
 
--- a/gfx/2d/ScaledFontMac.cpp
+++ b/gfx/2d/ScaledFontMac.cpp
@@ -447,16 +447,17 @@ ScaledFontMac::GetWRFontInstanceOptions(
   options.flags = wr::FontInstanceFlags::SUBPIXEL_POSITION;
   if (mUseFontSmoothing) {
     options.flags |= wr::FontInstanceFlags::FONT_SMOOTHING;
   }
   if (mApplySyntheticBold) {
     options.flags |= wr::FontInstanceFlags::SYNTHETIC_BOLD;
   }
   options.bg_color = wr::ToColorU(mFontSmoothingBackgroundColor);
+  options.synthetic_italics = wr::DegreesToSyntheticItalics(GetSyntheticObliqueAngle());
   *aOutOptions = Some(options);
   return true;
 }
 
 static CFDictionaryRef
 CreateVariationDictionaryOrNull(CGFontRef aCGFont, uint32_t aVariationCount,
                                 const FontVariation* aVariations)
 {
--- a/gfx/layers/LayerTreeInvalidation.cpp
+++ b/gfx/layers/LayerTreeInvalidation.cpp
@@ -600,62 +600,16 @@ public:
     AddTransformedRegion(aOutRegion, boundsDiff, mTransform);
     return true;
   }
 
   Color mColor;
   IntRect mBounds;
 };
 
-struct BorderLayerProperties : public LayerPropertiesBase
-{
-  explicit BorderLayerProperties(BorderLayer *aLayer)
-    : LayerPropertiesBase(aLayer)
-    , mColors(aLayer->GetColors())
-    , mRect(aLayer->GetRect())
-    , mCorners(aLayer->GetCorners())
-    , mWidths(aLayer->GetWidths())
-  { }
-
-protected:
-  BorderLayerProperties(const BorderLayerProperties& a) = delete;
-  BorderLayerProperties& operator=(const BorderLayerProperties& a) = delete;
-
-public:
-  bool ComputeChangeInternal(const char* aPrefix,
-                             nsIntRegion& aOutRegion,
-                             NotifySubDocInvalidationFunc aCallback) override
-  {
-    BorderLayer* border = static_cast<BorderLayer*>(mLayer.get());
-
-    if (!border->GetLocalVisibleRegion().ToUnknownRegion().IsEqual(mVisibleRegion)) {
-      IntRect result = NewTransformedBoundsForLeaf();
-      result = result.Union(OldTransformedBoundsForLeaf());
-      aOutRegion = result;
-      return true;
-    }
-
-    if (!PodEqual(&mColors[0], &border->GetColors()[0], 4) ||
-        !PodEqual(&mWidths[0], &border->GetWidths()[0], 4) ||
-        !PodEqual(&mCorners[0], &border->GetCorners()[0], 4) ||
-        !mRect.IsEqualEdges(border->GetRect())) {
-      LTI_DUMP(NewTransformedBoundsForLeaf(), "bounds");
-      aOutRegion = NewTransformedBoundsForLeaf();
-      return true;
-    }
-
-    return true;
-  }
-
-  BorderColors mColors;
-  LayerRect mRect;
-  BorderCorners mCorners;
-  BorderWidths mWidths;
-};
-
 static ImageHost* GetImageHost(Layer* aLayer)
 {
   HostLayer* compositor = aLayer->AsHostLayer();
   if (compositor) {
     return static_cast<ImageHost*>(compositor->GetCompositableHost());
   }
   return nullptr;
 }
@@ -780,18 +734,16 @@ CloneLayerTreePropertiesInternal(Layer* 
     case Layer::TYPE_REF:
       return MakeUnique<ContainerLayerProperties>(aRoot->AsContainerLayer());
     case Layer::TYPE_COLOR:
       return MakeUnique<ColorLayerProperties>(static_cast<ColorLayer*>(aRoot));
     case Layer::TYPE_IMAGE:
       return MakeUnique<ImageLayerProperties>(static_cast<ImageLayer*>(aRoot), aIsMask);
     case Layer::TYPE_CANVAS:
       return MakeUnique<CanvasLayerProperties>(static_cast<CanvasLayer*>(aRoot));
-    case Layer::TYPE_BORDER:
-      return MakeUnique<BorderLayerProperties>(static_cast<BorderLayer*>(aRoot));
     case Layer::TYPE_DISPLAYITEM:
     case Layer::TYPE_READBACK:
     case Layer::TYPE_SHADOW:
     case Layer::TYPE_PAINTED:
       return MakeUnique<LayerPropertiesBase>(aRoot);
   }
 
   MOZ_ASSERT_UNREACHABLE("Unexpected root layer type");
--- a/gfx/layers/Layers.cpp
+++ b/gfx/layers/Layers.cpp
@@ -2124,28 +2124,16 @@ ColorLayer::DumpPacket(layerscope::Layer
   Layer::DumpPacket(aPacket, aParent);
   // Get this layer data
   using namespace layerscope;
   LayersPacket::Layer* layer = aPacket->mutable_layer(aPacket->layer_size()-1);
   layer->set_type(LayersPacket::Layer::ColorLayer);
   layer->set_color(mColor.ToABGR());
 }
 
-void
-BorderLayer::PrintInfo(std::stringstream& aStream, const char* aPrefix)
-{
-  Layer::PrintInfo(aStream, aPrefix);
-}
-
-void
-BorderLayer::DumpPacket(layerscope::LayersPacket* aPacket, const void* aParent)
-{
-  Layer::DumpPacket(aPacket, aParent);
-}
-
 CanvasLayer::CanvasLayer(LayerManager* aManager, void* aImplData)
   : Layer(aManager, aImplData)
   , mSamplingFilter(SamplingFilter::GOOD)
 {
 }
 
 CanvasLayer::~CanvasLayer() = default;
 
--- a/gfx/layers/Layers.h
+++ b/gfx/layers/Layers.h
@@ -85,17 +85,16 @@ class Layer;
 class LayerMetricsWrapper;
 class PaintedLayer;
 class ContainerLayer;
 class ImageLayer;
 class ColorLayer;
 class CompositorAnimations;
 class CompositorBridgeChild;
 class CanvasLayer;
-class BorderLayer;
 class ReadbackLayer;
 class ReadbackProcessor;
 class RefLayer;
 class HostLayer;
 class FocusTarget;
 class KnowsCompositor;
 class ShadowableLayer;
 class ShadowLayerForwarder;
@@ -419,21 +418,16 @@ public:
   virtual already_AddRefed<ImageLayer> CreateImageLayer() = 0;
   /**
    * CONSTRUCTION PHASE ONLY
    * Create a ColorLayer for this manager's layer tree.
    */
   virtual already_AddRefed<ColorLayer> CreateColorLayer() = 0;
   /**
    * CONSTRUCTION PHASE ONLY
-   * Create a BorderLayer for this manager's layer tree.
-   */
-  virtual already_AddRefed<BorderLayer> CreateBorderLayer() = 0;
-  /**
-   * CONSTRUCTION PHASE ONLY
    * Create a CanvasLayer for this manager's layer tree.
    */
   virtual already_AddRefed<CanvasLayer> CreateCanvasLayer() = 0;
   /**
    * CONSTRUCTION PHASE ONLY
    * Create a ReadbackLayer for this manager's layer tree.
    */
   virtual already_AddRefed<ReadbackLayer> CreateReadbackLayer() { return nullptr; }
@@ -786,17 +780,16 @@ class Layer {
 public:
   // Keep these in alphabetical order
   enum LayerType {
     TYPE_CANVAS,
     TYPE_COLOR,
     TYPE_CONTAINER,
     TYPE_DISPLAYITEM,
     TYPE_IMAGE,
-    TYPE_BORDER,
     TYPE_READBACK,
     TYPE_REF,
     TYPE_SHADOW,
     TYPE_PAINTED
   };
 
   /**
    * Returns the LayerManager this Layer belongs to. Note that the layer
@@ -1509,22 +1502,16 @@ public:
 
    /**
     * Dynamic cast to a Color. Returns null if this is not a
     * ColorLayer.
     */
   virtual ColorLayer* AsColorLayer() { return nullptr; }
 
   /**
-    * Dynamic cast to a Border. Returns null if this is not a
-    * ColorLayer.
-    */
-  virtual BorderLayer* AsBorderLayer() { return nullptr; }
-
-  /**
     * Dynamic cast to a Canvas. Returns null if this is not a
     * ColorLayer.
     */
   virtual CanvasLayer* AsCanvasLayer() { return nullptr; }
 
   /**
     * Dynamic cast to an Image. Returns null if this is not a
     * ColorLayer.
@@ -2412,96 +2399,16 @@ protected:
 
   virtual void DumpPacket(layerscope::LayersPacket* aPacket, const void* aParent) override;
 
   gfx::IntRect mBounds;
   gfx::Color mColor;
 };
 
 /**
- * A Layer which renders a rounded rect.
- */
-class BorderLayer : public Layer {
-public:
-  virtual BorderLayer* AsBorderLayer() override { return this; }
-
-  /**
-   * CONSTRUCTION PHASE ONLY
-   * Set the color of the layer.
-   */
-
-  // Colors of each side as in css::Side
-  virtual void SetColors(const BorderColors& aColors)
-  {
-    MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) Colors", this));
-    PodCopy(&mColors[0], &aColors[0], 4);
-    Mutated();
-  }
-
-  virtual void SetRect(const LayerRect& aRect)
-  {
-    MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) Rect", this));
-    mRect = aRect;
-    Mutated();
-  }
-
-  // Size of each rounded corner as in css::Corner, 0.0 means a
-  // rectangular corner.
-  virtual void SetCornerRadii(const BorderCorners& aCorners)
-  {
-    MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) Corners", this));
-    PodCopy(&mCorners[0], &aCorners[0], 4);
-    Mutated();
-  }
-
-  virtual void SetWidths(const BorderWidths& aWidths)
-  {
-    MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) Widths", this));
-    PodCopy(&mWidths[0], &aWidths[0], 4);
-    Mutated();
-  }
-
-  virtual void SetStyles(const BorderStyles& aBorderStyles)
-  {
-    MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) Widths", this));
-    PodCopy(&mBorderStyles[0], &aBorderStyles[0], 4);
-    Mutated();
-  }
-
-  MOZ_LAYER_DECL_NAME("BorderLayer", TYPE_BORDER)
-
-  virtual void ComputeEffectiveTransforms(const gfx::Matrix4x4& aTransformToSurface) override
-  {
-    gfx::Matrix4x4 idealTransform = GetLocalTransform() * aTransformToSurface;
-    mEffectiveTransform = SnapTransformTranslation(idealTransform, nullptr);
-    ComputeEffectiveTransformForMaskLayers(aTransformToSurface);
-  }
-
-  const BorderColors& GetColors() { return mColors; }
-  const LayerRect& GetRect() { return mRect; }
-  const BorderCorners& GetCorners() { return mCorners; }
-  const BorderWidths& GetWidths() { return mWidths; }
-
-protected:
-  BorderLayer(LayerManager* aManager, void* aImplData)
-    : Layer(aManager, aImplData)
-  {}
-
-  virtual void PrintInfo(std::stringstream& aStream, const char* aPrefix) override;
-
-  virtual void DumpPacket(layerscope::LayersPacket* aPacket, const void* aParent) override;
-
-  BorderColors mColors;
-  LayerRect mRect;
-  BorderCorners mCorners;
-  BorderWidths mWidths;
-  BorderStyles mBorderStyles;
-};
-
-/**
  * A Layer for HTML Canvas elements.  It's backed by either a
  * gfxASurface or a GLContext (for WebGL layers), and has some control
  * for intelligent updating from the source if necessary (for example,
  * if hardware compositing is not available, for reading from the GL
  * buffer into an image surface that we can layer composite.)
  *
  * After Initialize is called, the underlying canvas Surface/GLContext
  * must not be modified during a layer transaction.
deleted file mode 100644
--- a/gfx/layers/basic/BasicBorderLayer.cpp
+++ /dev/null
@@ -1,84 +0,0 @@
-/* -*- 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 "BasicLayersImpl.h"            // for FillRectWithMask, etc
-#include "Layers.h"                     // for ColorLayer, etc
-#include "BasicImplData.h"              // for BasicImplData
-#include "BasicLayers.h"                // for BasicLayerManager
-#include "gfxContext.h"                 // for gfxContext, etc
-#include "gfxRect.h"                    // for gfxRect
-#include "gfx2DGlue.h"
-#include "mozilla/mozalloc.h"           // for operator new
-#include "nsCOMPtr.h"                   // for already_AddRefed
-#include "nsDebug.h"                    // for NS_ASSERTION
-#include "nsISupportsImpl.h"            // for Layer::AddRef, etc
-#include "nsRect.h"                     // for mozilla::gfx::IntRect
-#include "nsRegion.h"                   // for nsIntRegion
-#include "mozilla/gfx/PathHelpers.h"
-
-using namespace mozilla::gfx;
-
-namespace mozilla {
-namespace layers {
-
-class BasicBorderLayer : public BorderLayer, public BasicImplData {
-public:
-  explicit BasicBorderLayer(BasicLayerManager* aLayerManager) :
-    BorderLayer(aLayerManager, static_cast<BasicImplData*>(this))
-  {
-    MOZ_COUNT_CTOR(BasicBorderLayer);
-  }
-
-protected:
-  virtual ~BasicBorderLayer()
-  {
-    MOZ_COUNT_DTOR(BasicBorderLayer);
-  }
-
-public:
-  virtual void SetVisibleRegion(const LayerIntRegion& aRegion) override
-  {
-    NS_ASSERTION(BasicManager()->InConstruction(),
-                 "Can only set properties in construction phase");
-    BorderLayer::SetVisibleRegion(aRegion);
-  }
-
-  virtual void Paint(DrawTarget* aDT,
-                     const gfx::Point& aDeviceOffset,
-                     Layer* aMaskLayer) override
-  {
-    if (IsHidden()) {
-      return;
-    }
-
-    // We currently assume that we never have rounded corners,
-    // and that all borders have the same width and color.
-
-    ColorPattern color(mColors[0]);
-    StrokeOptions strokeOptions(mWidths[0]);
-
-    Rect rect = mRect.ToUnknownRect();
-    rect.Deflate(mWidths[0] / 2.0);
-    aDT->StrokeRect(rect, color, strokeOptions);
-  }
-
-protected:
-  BasicLayerManager* BasicManager()
-  {
-    return static_cast<BasicLayerManager*>(mManager);
-  }
-};
-
-already_AddRefed<BorderLayer>
-BasicLayerManager::CreateBorderLayer()
-{
-  NS_ASSERTION(InConstruction(), "Only allowed in construction phase");
-  RefPtr<BorderLayer> layer = new BasicBorderLayer(this);
-  return layer.forget();
-}
-
-} // namespace layers
-} // namespace mozilla
--- a/gfx/layers/basic/BasicLayers.h
+++ b/gfx/layers/basic/BasicLayers.h
@@ -109,17 +109,16 @@ public:
 
   virtual void SetRoot(Layer* aLayer) override;
 
   virtual already_AddRefed<PaintedLayer> CreatePaintedLayer() override;
   virtual already_AddRefed<ContainerLayer> CreateContainerLayer() override;
   virtual already_AddRefed<ImageLayer> CreateImageLayer() override;
   virtual already_AddRefed<CanvasLayer> CreateCanvasLayer() override;
   virtual already_AddRefed<ColorLayer> CreateColorLayer() override;
-  virtual already_AddRefed<BorderLayer> CreateBorderLayer() override;
   virtual already_AddRefed<ReadbackLayer> CreateReadbackLayer() override;
   virtual ImageFactory *GetImageFactory();
 
   virtual LayersBackend GetBackendType() override { return LayersBackend::LAYERS_BASIC; }
   virtual void GetBackendName(nsAString& name) override { name.AssignLiteral("Basic"); }
 
   bool InConstruction() { return mPhase == PHASE_CONSTRUCTION; }
 #ifdef DEBUG
deleted file mode 100644
--- a/gfx/layers/client/ClientBorderLayer.cpp
+++ /dev/null
@@ -1,75 +0,0 @@
-/* -*- 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 "ClientLayerManager.h"         // for ClientLayerManager, etc
-#include "Layers.h"                     // for ColorLayer, etc
-#include "mozilla/layers/LayersMessages.h"  // for ColorLayerAttributes, etc
-#include "mozilla/mozalloc.h"           // for operator new
-#include "nsCOMPtr.h"                   // for already_AddRefed
-#include "nsDebug.h"                    // for NS_ASSERTION
-#include "nsISupportsImpl.h"            // for Layer::AddRef, etc
-#include "nsRegion.h"                   // for nsIntRegion
-
-namespace mozilla {
-namespace layers {
-
-using namespace mozilla::gfx;
-
-class ClientBorderLayer : public BorderLayer,
-                          public ClientLayer {
-public:
-  explicit ClientBorderLayer(ClientLayerManager* aLayerManager) :
-    BorderLayer(aLayerManager, static_cast<ClientLayer*>(this))
-  {
-    MOZ_COUNT_CTOR(ClientBorderLayer);
-  }
-
-protected:
-  virtual ~ClientBorderLayer()
-  {
-    MOZ_COUNT_DTOR(ClientBorderLayer);
-  }
-
-public:
-  virtual void SetVisibleRegion(const LayerIntRegion& aRegion) override
-  {
-    NS_ASSERTION(ClientManager()->InConstruction(),
-                 "Can only set properties in construction phase");
-    BorderLayer::SetVisibleRegion(aRegion);
-  }
-
-  virtual void RenderLayer() override
-  {
-    RenderMaskLayers(this);
-  }
-
-  virtual void FillSpecificAttributes(SpecificLayerAttributes& aAttrs) override
-  {
-    aAttrs = BorderLayerAttributes(mRect, mColors, mCorners, mWidths);
-  }
-
-  virtual Layer* AsLayer() override { return this; }
-  virtual ShadowableLayer* AsShadowableLayer() override { return this; }
-
-protected:
-  ClientLayerManager* ClientManager()
-  {
-    return static_cast<ClientLayerManager*>(mManager);
-  }
-};
-
-already_AddRefed<BorderLayer>
-ClientLayerManager::CreateBorderLayer()
-{
-  NS_ASSERTION(InConstruction(), "Only allowed in construction phase");
-  RefPtr<ClientBorderLayer> layer =
-    new ClientBorderLayer(this);
-  CREATE_SHADOW(Border);
-  return layer.forget();
-}
-
-} // namespace layers
-} // namespace mozilla
--- a/gfx/layers/client/ClientLayerManager.cpp
+++ b/gfx/layers/client/ClientLayerManager.cpp
@@ -431,19 +431,25 @@ ClientLayerManager::EndTransaction(DrawP
     mWidget->PrepareWindowEffects();
   }
   EndTransactionInternal(aCallback, aCallbackData, aFlags);
   ForwardTransaction(!(aFlags & END_NO_REMOTE_COMPOSITE));
 
   if (mRepeatTransaction) {
     mRepeatTransaction = false;
     mIsRepeatTransaction = true;
+
+    // BeginTransaction will reset the transaction start time, but we
+    // would like to keep the original time for telemetry purposes.
+    TimeStamp transactionStart = mTransactionStart;
     if (BeginTransaction()) {
+      mTransactionStart = transactionStart;
       ClientLayerManager::EndTransaction(aCallback, aCallbackData, aFlags);
     }
+
     mIsRepeatTransaction = false;
   } else {
     MakeSnapshotIfRequired();
   }
 
   mInTransaction = false;
   mTransactionStart = TimeStamp();
 }
@@ -750,32 +756,28 @@ ClientLayerManager::ForwardTransaction(b
     PaintThread::Get()->EndLayerTransaction(syncObject);
   } else if (syncObject) {
     syncObject->Synchronize();
   }
 
   mPhase = PHASE_FORWARD;
 
   mLatestTransactionId = mTransactionIdAllocator->GetTransactionId(!mIsRepeatTransaction);
-  TimeStamp transactionStart;
-  if (!mTransactionIdAllocator->GetTransactionStart().IsNull()) {
-    transactionStart = mTransactionIdAllocator->GetTransactionStart();
-  } else {
-    transactionStart = mTransactionStart;
-  }
+  TimeStamp refreshStart = mTransactionIdAllocator->GetTransactionStart();
 
   if (gfxPrefs::AlwaysPaint() && XRE_IsContentProcess()) {
     mForwarder->SendPaintTime(mLatestTransactionId, mLastPaintTime);
   }
 
   // forward this transaction's changeset to our LayerManagerComposite
   bool sent = false;
   bool ok = mForwarder->EndTransaction(
     mRegionToClear, mLatestTransactionId, aScheduleComposite,
-    mPaintSequenceNumber, mIsRepeatTransaction, transactionStart,
+    mPaintSequenceNumber, mIsRepeatTransaction,
+    refreshStart, mTransactionStart,
     &sent);
   if (ok) {
     if (sent) {
       mNeedsComposite = false;
     }
   } else if (HasShadowManager()) {
     NS_WARNING("failed to forward Layers transaction");
   }
--- a/gfx/layers/client/ClientLayerManager.h
+++ b/gfx/layers/client/ClientLayerManager.h
@@ -101,17 +101,16 @@ public:
 
   virtual already_AddRefed<PaintedLayer> CreatePaintedLayer() override;
   virtual already_AddRefed<PaintedLayer> CreatePaintedLayerWithHint(PaintedLayerCreationHint aHint) override;
   virtual already_AddRefed<ContainerLayer> CreateContainerLayer() override;
   virtual already_AddRefed<ImageLayer> CreateImageLayer() override;
   virtual already_AddRefed<CanvasLayer> CreateCanvasLayer() override;
   virtual already_AddRefed<ReadbackLayer> CreateReadbackLayer() override;
   virtual already_AddRefed<ColorLayer> CreateColorLayer() override;
-  virtual already_AddRefed<BorderLayer> CreateBorderLayer() override;
   virtual already_AddRefed<RefLayer> CreateRefLayer() override;
 
   virtual void UpdateTextureFactoryIdentifier(const TextureFactoryIdentifier& aNewIdentifier) override;
   virtual TextureFactoryIdentifier GetTextureFactoryIdentifier() override
   {
     return AsShadowForwarder()->GetTextureFactoryIdentifier();
   }
 
--- a/gfx/layers/composite/LayerManagerComposite.cpp
+++ b/gfx/layers/composite/LayerManagerComposite.cpp
@@ -1237,60 +1237,16 @@ LayerManagerComposite::HandlePixelsTarge
   GLContext* gl = compositor->gl();
   MOZ_ASSERT(gl);
   gl->fReadPixels(0, 0, bufferWidth, bufferHeight, LOCAL_GL_RGBA, LOCAL_GL_UNSIGNED_BYTE, mem.get<uint8_t>());
   Unused << mScreenPixelsTarget->SendScreenPixels(mem, ScreenIntSize(bufferWidth, bufferHeight));
   mScreenPixelsTarget = nullptr;
 }
 #endif
 
-class BorderLayerComposite : public BorderLayer,
-                             public LayerComposite
-{
-public:
-  explicit BorderLayerComposite(LayerManagerComposite *aManager)
-    : BorderLayer(aManager, nullptr)
-    , LayerComposite(aManager)
-  {
-    MOZ_COUNT_CTOR(BorderLayerComposite);
-    mImplData = static_cast<LayerComposite*>(this);
-  }
-
-protected:
-  ~BorderLayerComposite()
-  {
-    MOZ_COUNT_DTOR(BorderLayerComposite);
-    Destroy();
-  }
-
-public:
-  // LayerComposite Implementation
-  virtual Layer* GetLayer() override { return this; }
-
-  virtual void SetLayerManager(HostLayerManager* aManager) override
-  {
-    LayerComposite::SetLayerManager(aManager);
-    mManager = aManager;
-  }
-
-  virtual void Destroy() override { mDestroyed = true; }
-
-  virtual void RenderLayer(const gfx::IntRect& aClipRect,
-                           const Maybe<gfx::Polygon>& aGeometry) override {}
-  virtual void CleanupResources() override {};
-
-  virtual void GenEffectChain(EffectChain& aEffect) override {}
-
-  CompositableHost* GetCompositableHost() override { return nullptr; }
-
-  virtual HostLayer* AsHostLayer() override { return this; }
-
-  virtual const char* Name() const override { return "BorderLayerComposite"; }
-};
-
 already_AddRefed<PaintedLayer>
 LayerManagerComposite::CreatePaintedLayer()
 {
   if (mDestroyed) {
     NS_WARNING("Call on destroyed layer manager");
     return nullptr;
   }
   return RefPtr<PaintedLayer>(new PaintedLayerComposite(this)).forget();
@@ -1341,26 +1297,16 @@ LayerManagerComposite::CreateRefLayer()
 {
   if (LayerManagerComposite::mDestroyed) {
     NS_WARNING("Call on destroyed layer manager");
     return nullptr;
   }
   return RefPtr<RefLayer>(new RefLayerComposite(this)).forget();
 }
 
-already_AddRefed<BorderLayer>
-LayerManagerComposite::CreateBorderLayer()
-{
-  if (LayerManagerComposite::mDestroyed) {
-    NS_WARNING("Call on destroyed layer manager");
-    return nullptr;
-  }
-  return RefPtr<BorderLayer>(new BorderLayerComposite(this)).forget();
-}
-
 LayerManagerComposite::AutoAddMaskEffect::AutoAddMaskEffect(Layer* aMaskLayer,
                                                             EffectChain& aEffects)
   : mCompositable(nullptr), mFailed(false)
 {
   if (!aMaskLayer) {
     return;
   }
 
--- a/gfx/layers/composite/LayerManagerComposite.h
+++ b/gfx/layers/composite/LayerManagerComposite.h
@@ -301,17 +301,16 @@ public:
   virtual bool CanUseCanvasLayerForSize(const gfx::IntSize &aSize) override;
 
   virtual void ClearCachedResources(Layer* aSubtree = nullptr) override;
 
   virtual already_AddRefed<PaintedLayer> CreatePaintedLayer() override;
   virtual already_AddRefed<ContainerLayer> CreateContainerLayer() override;
   virtual already_AddRefed<ImageLayer> CreateImageLayer() override;
   virtual already_AddRefed<ColorLayer> CreateColorLayer() override;
-  virtual already_AddRefed<BorderLayer> CreateBorderLayer() override;
   virtual already_AddRefed<CanvasLayer> CreateCanvasLayer() override;
   virtual already_AddRefed<RefLayer> CreateRefLayer() override;
 
   virtual bool AreComponentAlphaLayersEnabled() override;
 
   virtual already_AddRefed<DrawTarget>
     CreateOptimalMaskDrawTarget(const IntSize &aSize) override;
 
--- a/gfx/layers/ipc/CompositorBridgeChild.cpp
+++ b/gfx/layers/ipc/CompositorBridgeChild.cpp
@@ -151,16 +151,19 @@ CompositorBridgeChild::Destroy()
     mSectionAllocator = nullptr;
   }
 
   if (mLayerManager) {
     mLayerManager->Destroy();
     mLayerManager = nullptr;
   }
 
+  // Flush async paints before we destroy texture data.
+  FlushAsyncPaints();
+
   if (!mCanSend) {
     // We may have already called destroy but still have lingering references
     // or CompositorBridgeChild::ActorDestroy was called. Ensure that we do our
     // post destroy clean up no matter what. It is safe to call multiple times.
     MessageLoop::current()->PostTask(NewRunnableMethod(
       "CompositorBridgeChild::AfterDestroy",
       selfRef, &CompositorBridgeChild::AfterDestroy));
     return;
@@ -177,19 +180,16 @@ CompositorBridgeChild::Destroy()
   AutoTArray<PWebRenderBridgeChild*, 16> wrBridges;
   ManagedPWebRenderBridgeChild(wrBridges);
   for (int i = wrBridges.Length() - 1; i >= 0; --i) {
     RefPtr<WebRenderBridgeChild> wrBridge =
       static_cast<WebRenderBridgeChild*>(wrBridges[i]);
     wrBridge->Destroy(/* aIsSync */ false);
   }
 
-  // Flush async paints before we destroy texture data.
-  FlushAsyncPaints();
-
   const ManagedContainer<PTextureChild>& textures = ManagedPTextureChild();
   for (auto iter = textures.ConstIter(); !iter.Done(); iter.Next()) {
     RefPtr<TextureClient> texture = TextureClient::AsTextureClient(iter.Get()->GetKey());
 
     if (texture) {
       texture->Destroy();
     }
   }
--- a/gfx/layers/ipc/CompositorBridgeParent.cpp
+++ b/gfx/layers/ipc/CompositorBridgeParent.cpp
@@ -1323,16 +1323,17 @@ CompositorBridgeParent::ShadowLayersUpda
     }
   }
 
   // The transaction ID might get reset to 1 if the page gets reloaded, see
   // https://bugzilla.mozilla.org/show_bug.cgi?id=1145295#c41
   // Otherwise, it should be continually increasing.
   MOZ_ASSERT(aInfo.id() == TransactionId{1} || aInfo.id() > mPendingTransaction);
   mPendingTransaction = aInfo.id();
+  mRefreshStartTime = aInfo.refreshStart();
   mTxnStartTime = aInfo.transactionStart();
   mFwdTime = aInfo.fwdTime();
 
   if (root) {
     SetShadowProperties(root);
   }
   if (aInfo.scheduleComposite()) {
     ScheduleComposition();
@@ -1631,24 +1632,24 @@ CompositorBridgeParent::AllocPLayerTrans
                                                      const LayersId& aId)
 {
   MOZ_ASSERT(!aId.IsValid());
 
   InitializeLayerManager(aBackendHints);
 
   if (!mLayerManager) {
     NS_WARNING("Failed to initialise Compositor");
-    LayerTransactionParent* p = new LayerTransactionParent(/* aManager */ nullptr, this, /* aAnimStorage */ nullptr, mRootLayerTreeID);
+    LayerTransactionParent* p = new LayerTransactionParent(/* aManager */ nullptr, this, /* aAnimStorage */ nullptr, mRootLayerTreeID, mVsyncRate);
     p->AddIPDLReference();
     return p;
   }
 
   mCompositionManager = new AsyncCompositionManager(this, mLayerManager);
 
-  LayerTransactionParent* p = new LayerTransactionParent(mLayerManager, this, GetAnimationStorage(), mRootLayerTreeID);
+  LayerTransactionParent* p = new LayerTransactionParent(mLayerManager, this, GetAnimationStorage(), mRootLayerTreeID, mVsyncRate);
   p->AddIPDLReference();
   return p;
 }
 
 bool
 CompositorBridgeParent::DeallocPLayerTransactionParent(PLayerTransactionParent* actor)
 {
   static_cast<LayerTransactionParent*>(actor)->ReleaseIPDLReference();
@@ -1868,17 +1869,17 @@ CompositorBridgeParent::AllocPWebRenderB
     return mWrBridge;
   }
   mAsyncImageManager = new AsyncImagePipelineManager(api->Clone());
   RefPtr<AsyncImagePipelineManager> asyncMgr = mAsyncImageManager;
   wr::TransactionBuilder txn;
   txn.SetRootPipeline(aPipelineId);
   api->SendTransaction(txn);
   RefPtr<CompositorAnimationStorage> animStorage = GetAnimationStorage();
-  mWrBridge = new WebRenderBridgeParent(this, aPipelineId, mWidget, nullptr, std::move(api), std::move(asyncMgr), std::move(animStorage));
+  mWrBridge = new WebRenderBridgeParent(this, aPipelineId, mWidget, nullptr, std::move(api), std::move(asyncMgr), std::move(animStorage), mVsyncRate);
   mWrBridge.get()->AddRef(); // IPDL reference
 
   *aIdNamespace = mWrBridge->GetIdNamespace();
   mCompositorScheduler = mWrBridge->CompositorScheduler();
   MOZ_ASSERT(mCompositorScheduler);
   { // scope lock
     MonitorAutoLock lock(*sIndirectLayerTreesLock);
     MOZ_ASSERT(sIndirectLayerTrees[mRootLayerTreeID].mWrBridge == nullptr);
@@ -2126,25 +2127,26 @@ CompositorBridgeParent::DidComposite(Tim
                                      TimeStamp& aCompositeEnd)
 {
   if (mWrBridge) {
     NotifyDidComposite(mWrBridge->FlushPendingTransactionIds(), aCompositeStart, aCompositeEnd);
   } else {
     NotifyDidComposite(mPendingTransaction, aCompositeStart, aCompositeEnd);
 #if defined(ENABLE_FRAME_LATENCY_LOG)
     if (mPendingTransaction.IsValid()) {
-      if (mTxnStartTime) {
-        uint32_t latencyMs = round((aCompositeEnd - mTxnStartTime).ToMilliseconds());
+      if (mRefreshStartTime) {
+        int32_t latencyMs = lround((aCompositeEnd - mRefreshStartTime).ToMilliseconds());
         printf_stderr("From transaction start to end of generate frame latencyMs %d this %p\n", latencyMs, this);
       }
       if (mFwdTime) {
-        uint32_t latencyMs = round((aCompositeEnd - mFwdTime).ToMilliseconds());
+        int32_t latencyMs = lround((aCompositeEnd - mFwdTime).ToMilliseconds());
         printf_stderr("From forwarding transaction to end of generate frame latencyMs %d this %p\n", latencyMs, this);
       }
     }
+    mRefreshStartTime = TimeStamp();
     mTxnStartTime = TimeStamp();
     mFwdTime = TimeStamp();
 #endif
     mPendingTransaction = TransactionId{0};
   }
 }
 
 void
--- a/gfx/layers/ipc/CompositorBridgeParent.h
+++ b/gfx/layers/ipc/CompositorBridgeParent.h
@@ -596,16 +596,17 @@ protected:
   RefPtr<AsyncImagePipelineManager> mAsyncImageManager;
   RefPtr<WebRenderBridgeParent> mWrBridge;
   widget::CompositorWidget* mWidget;
   Maybe<TimeStamp> mTestTime;
   CSSToLayoutDeviceScale mScale;
   TimeDuration mVsyncRate;
 
   TransactionId mPendingTransaction;
+  TimeStamp mRefreshStartTime;
   TimeStamp mTxnStartTime;
   TimeStamp mFwdTime;
 
   bool mPaused;
 
   bool mUseExternalSurfaceSize;
   gfx::IntSize mEGLSurfaceSize;
 
--- a/gfx/layers/ipc/CrossProcessCompositorBridgeParent.cpp
+++ b/gfx/layers/ipc/CrossProcessCompositorBridgeParent.cpp
@@ -89,24 +89,25 @@ CrossProcessCompositorBridgeParent::Allo
   if (sIndirectLayerTrees.end() != itr) {
     state = &itr->second;
   }
 
   if (state && state->mLayerManager) {
     state->mCrossProcessParent = this;
     HostLayerManager* lm = state->mLayerManager;
     CompositorAnimationStorage* animStorage = state->mParent ? state->mParent->GetAnimationStorage() : nullptr;
-    LayerTransactionParent* p = new LayerTransactionParent(lm, this, animStorage, aId);
+    TimeDuration vsyncRate = state->mParent ? state->mParent->GetVsyncInterval() : TimeDuration();
+    LayerTransactionParent* p = new LayerTransactionParent(lm, this, animStorage, aId, vsyncRate);
     p->AddIPDLReference();
     sIndirectLayerTrees[aId].mLayerTree = p;
     return p;
   }
 
   NS_WARNING("Created child without a matching parent?");
-  LayerTransactionParent* p = new LayerTransactionParent(/* aManager */ nullptr, this, /* aAnimStorage */ nullptr, aId);
+  LayerTransactionParent* p = new LayerTransactionParent(/* aManager */ nullptr, this, /* aAnimStorage */ nullptr, aId, TimeDuration());
   p->AddIPDLReference();
   return p;
 }
 
 bool
 CrossProcessCompositorBridgeParent::DeallocPLayerTransactionParent(PLayerTransactionParent* aLayers)
 {
   LayerTransactionParent* slp = static_cast<LayerTransactionParent*>(aLayers);
@@ -238,17 +239,17 @@ CrossProcessCompositorBridgeParent::Allo
     *aTextureFactoryIdentifier = TextureFactoryIdentifier(LayersBackend::LAYERS_NONE);
     return parent;
   }
 
   api = api->Clone();
   RefPtr<AsyncImagePipelineManager> holder = root->AsyncImageManager();
   RefPtr<CompositorAnimationStorage> animStorage = cbp->GetAnimationStorage();
   WebRenderBridgeParent* parent = new WebRenderBridgeParent(
-          this, aPipelineId, nullptr, root->CompositorScheduler(), std::move(api), std::move(holder), std::move(animStorage));
+          this, aPipelineId, nullptr, root->CompositorScheduler(), std::move(api), std::move(holder), std::move(animStorage), cbp->GetVsyncInterval());
   parent->AddRef(); // IPDL reference
 
   { // scope lock
     MonitorAutoLock lock(*sIndirectLayerTreesLock);
     sIndirectLayerTrees[layersId].mCrossProcessParent = this;
     sIndirectLayerTrees[layersId].mWrBridge = parent;
   }
   *aTextureFactoryIdentifier = parent->GetTextureFactoryIdentifier();
@@ -367,17 +368,17 @@ CrossProcessCompositorBridgeParent::Shad
   }
 
   if (aLayerTree->ShouldParentObserveEpoch()) {
     // Note that we send this through the window compositor, since this needs
     // to reach the widget owning the tab.
     Unused << state->mParent->SendObserveLayerUpdate(id, aLayerTree->GetChildEpoch(), true);
   }
 
-  aLayerTree->SetPendingTransactionId(aInfo.id(), aInfo.transactionStart(), aInfo.fwdTime());
+  aLayerTree->SetPendingTransactionId(aInfo.id(), aInfo.refreshStart(), aInfo.transactionStart(), aInfo.fwdTime());
 }
 
 void
 CrossProcessCompositorBridgeParent::DidComposite(
   LayersId aId,
   TimeStamp& aCompositeStart,
   TimeStamp& aCompositeEnd)
 {
--- a/gfx/layers/ipc/LayerTransactionParent.cpp
+++ b/gfx/layers/ipc/LayerTransactionParent.cpp
@@ -21,16 +21,17 @@
 #include "mozilla/layers/ImageBridgeParent.h" // for ImageBridgeParent
 #include "mozilla/layers/ImageLayerComposite.h"
 #include "mozilla/layers/LayerManagerComposite.h"
 #include "mozilla/layers/LayersMessages.h"  // for EditReply, etc
 #include "mozilla/layers/LayersTypes.h"  // for MOZ_LAYERS_LOG
 #include "mozilla/layers/TextureHostOGL.h"  // for TextureHostOGL
 #include "mozilla/layers/PaintedLayerComposite.h"
 #include "mozilla/mozalloc.h"           // for operator delete, etc
+#include "mozilla/Telemetry.h"
 #include "mozilla/Unused.h"
 #include "nsCoord.h"                    // for NSAppUnitsToFloatPixels
 #include "nsISupportsImpl.h"            // for Layer::Release, etc
 #include "nsLayoutUtils.h"              // for nsLayoutUtils
 #include "nsMathUtils.h"                // for NS_round
 #include "nsPoint.h"                    // for nsPoint
 #include "nsTArray.h"                   // for nsTArray, nsTArray_Impl, etc
 #include "TreeTraversal.h"              // for ForEachNode
@@ -43,23 +44,25 @@ using mozilla::layout::RenderFrameParent
 namespace mozilla {
 namespace layers {
 
 //--------------------------------------------------
 // LayerTransactionParent
 LayerTransactionParent::LayerTransactionParent(HostLayerManager* aManager,
                                                CompositorBridgeParentBase* aBridge,
                                                CompositorAnimationStorage* aAnimStorage,
-                                               LayersId aId)
+                                               LayersId aId,
+                                               TimeDuration aVsyncRate)
   : mLayerManager(aManager)
   , mCompositorBridge(aBridge)
   , mAnimStorage(aAnimStorage)
   , mId(aId)
   , mChildEpoch(0)
   , mParentEpoch(0)
+  , mVsyncRate(aVsyncRate)
   , mPendingTransaction{0}
   , mDestroyed(false)
   , mIPCOpen(false)
 {
   MOZ_ASSERT(mId.IsValid());
 }
 
 LayerTransactionParent::~LayerTransactionParent()
@@ -231,27 +234,16 @@ LayerTransactionParent::RecvUpdate(const
       RefPtr<ColorLayer> layer = mLayerManager->CreateColorLayer();
       if (!BindLayer(layer, edit.get_OpCreateColorLayer())) {
         return IPC_FAIL_NO_REASON(this);
       }
 
       UpdateHitTestingTree(layer, "CreateColorLayer");
       break;
     }
-    case Edit::TOpCreateBorderLayer: {
-      MOZ_LAYERS_LOG(("[ParentSide] CreateBorderLayer"));
-
-      RefPtr<BorderLayer> layer = mLayerManager->CreateBorderLayer();
-      if (!BindLayer(layer, edit.get_OpCreateBorderLayer())) {
-        return IPC_FAIL_NO_REASON(this);
-      }
-
-      UpdateHitTestingTree(layer, "CreateBorderLayer");
-      break;
-    }
     case Edit::TOpCreateCanvasLayer: {
       MOZ_LAYERS_LOG(("[ParentSide] CreateCanvasLayer"));
 
       RefPtr<CanvasLayer> layer = mLayerManager->CreateCanvasLayer();
       if (!BindLayer(layer, edit.get_OpCreateCanvasLayer())) {
         return IPC_FAIL_NO_REASON(this);
       }
 
@@ -596,29 +588,16 @@ LayerTransactionParent::SetLayerAttribut
     ColorLayer* colorLayer = layer->AsColorLayer();
     if (!colorLayer) {
       return false;
     }
     colorLayer->SetColor(specific.get_ColorLayerAttributes().color().value());
     colorLayer->SetBounds(specific.get_ColorLayerAttributes().bounds());
     break;
   }
-  case Specific::TBorderLayerAttributes: {
-    MOZ_LAYERS_LOG(("[ParentSide]   border layer"));
-
-    BorderLayer* borderLayer = layer->AsBorderLayer();
-    if (!borderLayer) {
-      return false;
-    }
-    borderLayer->SetRect(specific.get_BorderLayerAttributes().rect());
-    borderLayer->SetColors(specific.get_BorderLayerAttributes().colors());
-    borderLayer->SetCornerRadii(specific.get_BorderLayerAttributes().corners());
-    borderLayer->SetWidths(specific.get_BorderLayerAttributes().widths());
-    break;
-  }
   case Specific::TCanvasLayerAttributes: {
     MOZ_LAYERS_LOG(("[ParentSide]   canvas layer"));
 
     CanvasLayer* canvasLayer = layer->AsCanvasLayer();
     if (!canvasLayer) {
       return false;
     }
     canvasLayer->SetSamplingFilter(specific.get_CanvasLayerAttributes().samplingFilter());
@@ -954,30 +933,39 @@ LayerTransactionParent::DeallocShmem(ipc
 bool LayerTransactionParent::IsSameProcess() const
 {
   return OtherPid() == base::GetCurrentProcId();
 }
 
 TransactionId
 LayerTransactionParent::FlushTransactionId(TimeStamp& aCompositeEnd)
 {
+  if (mId.IsValid() && mPendingTransaction.IsValid() && !mVsyncRate.IsZero()) {
+    double latencyMs = (aCompositeEnd - mTxnStartTime).ToMilliseconds();
+    double latencyNorm = latencyMs / mVsyncRate.ToMilliseconds();
+    int32_t fracLatencyNorm = lround(latencyNorm * 100.0);
+    Telemetry::Accumulate(Telemetry::CONTENT_FRAME_TIME, fracLatencyNorm);
+  }
+
 #if defined(ENABLE_FRAME_LATENCY_LOG)
   if (mPendingTransaction.IsValid()) {
-    if (mTxnStartTime) {
-      uint32_t latencyMs = round((aCompositeEnd - mTxnStartTime).ToMilliseconds());
+    if (mRefreshStartTime) {
+      int32_t latencyMs = lround((aCompositeEnd - mRefreshStartTime).ToMilliseconds());
       printf_stderr("From transaction start to end of generate frame latencyMs %d this %p\n", latencyMs, this);
     }
     if (mFwdTime) {
-      uint32_t latencyMs = round((aCompositeEnd - mFwdTime).ToMilliseconds());
+      int32_t latencyMs = lround((aCompositeEnd - mFwdTime).ToMilliseconds());
       printf_stderr("From forwarding transaction to end of generate frame latencyMs %d this %p\n", latencyMs, this);
     }
   }
+#endif
+
+  mRefreshStartTime = TimeStamp();
   mTxnStartTime = TimeStamp();
   mFwdTime = TimeStamp();
-#endif
   TransactionId id = mPendingTransaction;
   mPendingTransaction = TransactionId{0};
   return id;
 }
 
 void
 LayerTransactionParent::SendAsyncMessage(const InfallibleTArray<AsyncParentMessageData>& aMessage)
 {
--- a/gfx/layers/ipc/LayerTransactionParent.h
+++ b/gfx/layers/ipc/LayerTransactionParent.h
@@ -43,17 +43,18 @@ class LayerTransactionParent final : pub
   typedef InfallibleTArray<Edit> EditArray;
   typedef InfallibleTArray<OpDestroy> OpDestroyArray;
   typedef InfallibleTArray<PluginWindowData> PluginsArray;
 
 public:
   LayerTransactionParent(HostLayerManager* aManager,
                          CompositorBridgeParentBase* aBridge,
                          CompositorAnimationStorage* aAnimStorage,
-                         LayersId aId);
+                         LayersId aId,
+                         TimeDuration aVsyncRate);
 
 protected:
   ~LayerTransactionParent();
 
 public:
   void Destroy();
 
   void SetLayerManager(HostLayerManager* aLayerManager, CompositorAnimationStorage* aAnimStorage);
@@ -74,19 +75,23 @@ public:
                         ipc::SharedMemory::SharedMemoryType aType,
                         ipc::Shmem* aShmem) override;
 
   void DeallocShmem(ipc::Shmem& aShmem) override;
 
   bool IsSameProcess() const override;
 
   const TransactionId& GetPendingTransactionId() { return mPendingTransaction; }
-  void SetPendingTransactionId(TransactionId aId, const TimeStamp& aTxnStartTime, const TimeStamp& aFwdTime)
+  void SetPendingTransactionId(TransactionId aId,
+                               const TimeStamp& aRefreshStartTime,
+                               const TimeStamp& aTxnStartTime,
+                               const TimeStamp& aFwdTime)
   {
     mPendingTransaction = aId;
+    mRefreshStartTime = aRefreshStartTime;
     mTxnStartTime = aTxnStartTime;
     mFwdTime = aFwdTime;
   }
   TransactionId FlushTransactionId(TimeStamp& aCompositeEnd);
 
   // CompositableParentManager
   void SendAsyncMessage(const InfallibleTArray<AsyncParentMessageData>& aMessage) override;
 
@@ -191,17 +196,20 @@ private:
 
   // These fields keep track of the latest epoch values in the child and the
   // parent. mChildEpoch is the latest epoch value received from the child.
   // mParentEpoch is the latest epoch value that we have told TabParent about
   // (via ObserveLayerUpdate).
   uint64_t mChildEpoch;
   uint64_t mParentEpoch;
 
+  TimeDuration mVsyncRate;
+
   TransactionId mPendingTransaction;
+  TimeStamp mRefreshStartTime;
   TimeStamp mTxnStartTime;
   TimeStamp mFwdTime;
 
   // When the widget/frame/browser stuff in this process begins its
   // destruction process, we need to Disconnect() all the currently
   // live shadow layers, because some of them might be orphaned from
   // the layer tree.  This happens in Destroy() above.  After we
   // Destroy() ourself, there's a window in which that information
--- a/gfx/layers/ipc/LayersMessages.ipdlh
+++ b/gfx/layers/ipc/LayersMessages.ipdlh
@@ -41,19 +41,16 @@ using mozilla::layers::EventRegions from
 using mozilla::layers::EventRegionsOverride from "mozilla/layers/LayersTypes.h";
 using mozilla::layers::DiagnosticTypes from "mozilla/layers/CompositorTypes.h";
 using mozilla::layers::FocusTarget from "mozilla/layers/FocusTarget.h";
 using struct mozilla::layers::ScrollMetadata from "FrameMetrics.h";
 using mozilla::layers::FrameMetrics::ViewID from "FrameMetrics.h";
 using mozilla::layers::LayersBackend from "mozilla/layers/LayersTypes.h";
 using mozilla::layers::MaybeLayerClip from "FrameMetrics.h";
 using mozilla::gfx::Glyph from "Layers.h";
-using mozilla::layers::BorderColors from "mozilla/layers/LayersTypes.h";
-using mozilla::layers::BorderCorners from "mozilla/layers/LayersTypes.h";
-using mozilla::layers::BorderWidths from "mozilla/layers/LayersTypes.h";
 using mozilla::layers::LayerHandle from "mozilla/layers/LayersTypes.h";
 using mozilla::layers::CompositableHandle from "mozilla/layers/LayersTypes.h";
 using mozilla::layers::SimpleLayerAttributes from "mozilla/layers/LayerAttributes.h";
 using mozilla::CrossProcessSemaphoreHandle from "mozilla/ipc/CrossProcessSemaphore.h";
 using struct mozilla::void_t from "ipc/IPCMessageUtils.h";
 using mozilla::layers::LayersId from "mozilla/layers/LayersTypes.h";
 using mozilla::layers::TransactionId from "mozilla/layers/LayersTypes.h";
 
@@ -67,17 +64,16 @@ struct TargetConfig {
   nsIntRegion clearRegion;
 };
 
 // Create a shadow layer for |layer|
 struct OpCreatePaintedLayer    { LayerHandle layer; };
 struct OpCreateContainerLayer  { LayerHandle layer; };
 struct OpCreateImageLayer      { LayerHandle layer; };
 struct OpCreateColorLayer      { LayerHandle layer; };
-struct OpCreateBorderLayer       { LayerHandle layer; };
 struct OpCreateCanvasLayer     { LayerHandle layer; };
 struct OpCreateRefLayer        { LayerHandle layer; };
 
 struct OpAttachCompositable {
   LayerHandle layer;
   CompositableHandle compositable;
 };
 
@@ -306,32 +302,25 @@ struct GlyphArray
 
 struct ColorLayerAttributes     { LayerColor color; IntRect bounds; };
 struct CanvasLayerAttributes    { SamplingFilter samplingFilter; IntRect bounds; };
 struct RefLayerAttributes {
   LayersId id;
   EventRegionsOverride eventRegionsOverride;
 };
 struct ImageLayerAttributes     { SamplingFilter samplingFilter; IntSize scaleToSize; ScaleMode scaleMode; };
-struct BorderLayerAttributes {
-  LayerRect rect;
-  BorderColors colors;
-  BorderCorners corners;
-  BorderWidths widths;
-};
 
 union SpecificLayerAttributes {
   null_t;
   PaintedLayerAttributes;
   ContainerLayerAttributes;
   ColorLayerAttributes;
   CanvasLayerAttributes;
   RefLayerAttributes;
   ImageLayerAttributes;
-  BorderLayerAttributes;
 };
 
 struct LayerAttributes {
   CommonLayerAttributes common;
   SpecificLayerAttributes specific;
 };
 
 // See nsIWidget Configurations
@@ -492,17 +481,16 @@ struct CompositableOperation {
 // A unit of a changeset; a set of these comprise a changeset
 // If adding a new edit type that requires the hit testing tree to be updated,
 // set the updateHitTestingTree flag to true in RecvUpdate()
 union Edit {
   OpCreatePaintedLayer;
   OpCreateContainerLayer;
   OpCreateImageLayer;
   OpCreateColorLayer;
-  OpCreateBorderLayer;
   OpCreateCanvasLayer;
   OpCreateRefLayer;
 
   OpSetDiagnosticTypes;
   OpWindowOverlayChanged;
 
   OpSetRoot;
   OpInsertAfter;
@@ -567,16 +555,17 @@ struct TransactionInfo
   TransactionId id;
   TargetConfig targetConfig;
   PluginWindowData[] plugins;
   bool isFirstPaint;
   FocusTarget focusTarget;
   bool scheduleComposite;
   uint32_t paintSequenceNumber;
   bool isRepeatTransaction;
+  TimeStamp refreshStart;
   TimeStamp transactionStart;
   TimeStamp fwdTime;
 };
 
 union MaybeTransform {
   Matrix4x4;
   void_t;
 };
--- a/gfx/layers/ipc/PWebRenderBridge.ipdl
+++ b/gfx/layers/ipc/PWebRenderBridge.ipdl
@@ -38,20 +38,20 @@ parent:
   async ReleaseCompositable(CompositableHandle compositable);
 
   sync Create(IntSize aSize);
   async DeleteCompositorAnimations(uint64_t[] aIds);
   async SetDisplayList(IntSize aSize, WebRenderParentCommand[] commands, OpDestroy[] toDestroy, uint64_t fwdTransactionId, TransactionId transactionId,
                        LayoutSize aContentSize, ByteBuf aDL, BuiltDisplayListDescriptor aDLDesc,
                        WebRenderScrollData aScrollData,
                        OpUpdateResource[] aResourceUpdates, RefCountedShmem[] aSmallShmems, Shmem[] aLargeShmems,
-                       IdNamespace aIdNamespace, TimeStamp txnStartTime, TimeStamp fwdTime);
+                       IdNamespace aIdNamespace, TimeStamp refreshStartTime, TimeStamp txnStartTime, TimeStamp fwdTime);
   async EmptyTransaction(FocusTarget focusTarget, ScrollUpdatesMap scrollUpdates, uint32_t aPaintSequenceNumber,
                          WebRenderParentCommand[] commands, OpDestroy[] toDestroy, uint64_t fwdTransactionId, TransactionId transactionId,
-                         IdNamespace aIdNamespace, TimeStamp txnStartTime, TimeStamp fwdTime);
+                         IdNamespace aIdNamespace, TimeStamp refreshStartTime, TimeStamp txnStartTime, TimeStamp fwdTime);
   async SetFocusTarget(FocusTarget focusTarget);
   async UpdateResources(OpUpdateResource[] aResourceUpdates, RefCountedShmem[] aSmallShmems, Shmem[] aLargeShmems);
   async ParentCommands(WebRenderParentCommand[] commands);
   sync GetSnapshot(PTexture texture);
   async SetLayerObserverEpoch(uint64_t layerObserverEpoch);
   async ClearCachedResources();
   // Schedule a composite if one isn't already scheduled.
   async ScheduleComposite();
--- a/gfx/layers/ipc/ShadowLayers.cpp
+++ b/gfx/layers/ipc/ShadowLayers.cpp
@@ -318,21 +318,16 @@ ShadowLayerForwarder::CreatedImageLayer(
   CreatedLayer<OpCreateImageLayer>(mTxn, aImage);
 }
 void
 ShadowLayerForwarder::CreatedColorLayer(ShadowableLayer* aColor)
 {
   CreatedLayer<OpCreateColorLayer>(mTxn, aColor);
 }
 void
-ShadowLayerForwarder::CreatedBorderLayer(ShadowableLayer* aBorder)
-{
-  CreatedLayer<OpCreateBorderLayer>(mTxn, aBorder);
-}
-void
 ShadowLayerForwarder::CreatedCanvasLayer(ShadowableLayer* aCanvas)
 {
   CreatedLayer<OpCreateCanvasLayer>(mTxn, aCanvas);
 }
 void
 ShadowLayerForwarder::CreatedRefLayer(ShadowableLayer* aRef)
 {
   CreatedLayer<OpCreateRefLayer>(mTxn, aRef);
@@ -599,16 +594,17 @@ ShadowLayerForwarder::SendPaintTime(Tran
 }
 
 bool
 ShadowLayerForwarder::EndTransaction(const nsIntRegion& aRegionToClear,
                                      TransactionId aId,
                                      bool aScheduleComposite,
                                      uint32_t aPaintSequenceNumber,
                                      bool aIsRepeatTransaction,
+                                     const mozilla::TimeStamp& aRefreshStart,
                                      const mozilla::TimeStamp& aTransactionStart,
                                      bool* aSent)
 {
   *aSent = false;
 
   TransactionInfo info;
 
   MOZ_ASSERT(IPCOpen(), "no manager to forward to");
@@ -740,16 +736,17 @@ ShadowLayerForwarder::EndTransaction(con
   info.fwdTransactionId() = GetFwdTransactionId();
   info.id() = aId;
   info.plugins() = mPluginWindowData;
   info.isFirstPaint() = mIsFirstPaint;
   info.focusTarget() = mFocusTarget;
   info.scheduleComposite() = aScheduleComposite;
   info.paintSequenceNumber() = aPaintSequenceNumber;
   info.isRepeatTransaction() = aIsRepeatTransaction;
+  info.refreshStart() = aRefreshStart;
   info.transactionStart() = aTransactionStart;
 #if defined(ENABLE_FRAME_LATENCY_LOG)
   info.fwdTime() = TimeStamp::Now();
 #endif
 
   TargetConfig targetConfig(mTxn->mTargetBounds,
                             mTxn->mTargetRotation,
                             mTxn->mTargetOrientation,
--- a/gfx/layers/ipc/ShadowLayers.h
+++ b/gfx/layers/ipc/ShadowLayers.h
@@ -172,17 +172,16 @@ public:
    * the compositing process.
    */
   void CreatedPaintedLayer(ShadowableLayer* aThebes);
   void CreatedContainerLayer(ShadowableLayer* aContainer);
   void CreatedImageLayer(ShadowableLayer* aImage);
   void CreatedColorLayer(ShadowableLayer* aColor);
   void CreatedCanvasLayer(ShadowableLayer* aCanvas);
   void CreatedRefLayer(ShadowableLayer* aRef);
-  void CreatedBorderLayer(ShadowableLayer* aRef);
 
   /**
    * At least one attribute of |aMutant| has changed, and |aMutant|
    * needs to sync to its shadow layer.  This initial implementation
    * forwards all attributes when any of the appropriate attribute
    * set is mutated.
    */
   void Mutated(ShadowableLayer* aMutant);
@@ -253,16 +252,17 @@ public:
    * |aReplies| are directions from the LayerManagerComposite to the
    * caller of EndTransaction().
    */
   bool EndTransaction(const nsIntRegion& aRegionToClear,
                       TransactionId aId,
                       bool aScheduleComposite,
                       uint32_t aPaintSequenceNumber,
                       bool aIsRepeatTransaction,
+                      const mozilla::TimeStamp& aRefreshStart,
                       const mozilla::TimeStamp& aTransactionStart,
                       bool* aSent);
 
   /**
    * Set an actor through which layer updates will be pushed.
    */
   void SetShadowManager(PLayerTransactionChild* aShadowManager);
 
--- a/gfx/layers/mlgpu/LayerManagerMLGPU.cpp
+++ b/gfx/layers/mlgpu/LayerManagerMLGPU.cpp
@@ -152,23 +152,16 @@ LayerManagerMLGPU::CreatePaintedLayer()
 }
 
 already_AddRefed<ImageLayer>
 LayerManagerMLGPU::CreateImageLayer()
 {
   return MakeAndAddRef<ImageLayerMLGPU>(this);
 }
 
-already_AddRefed<BorderLayer>
-LayerManagerMLGPU::CreateBorderLayer()
-{
-  MOZ_ASSERT_UNREACHABLE("Not yet implemented");
-  return nullptr;
-}
-
 already_AddRefed<CanvasLayer>
 LayerManagerMLGPU::CreateCanvasLayer()
 {
   return MakeAndAddRef<CanvasLayerMLGPU>(this);
 }
 
 TextureFactoryIdentifier
 LayerManagerMLGPU::GetTextureFactoryIdentifier()
--- a/gfx/layers/mlgpu/LayerManagerMLGPU.h
+++ b/gfx/layers/mlgpu/LayerManagerMLGPU.h
@@ -41,17 +41,16 @@ public:
   void BeginTransactionWithDrawTarget(gfx::DrawTarget* aTarget, const gfx::IntRect& aRect) override;
   void SetRoot(Layer* aLayer) override;
   already_AddRefed<PaintedLayer> CreatePaintedLayer() override;
   already_AddRefed<ContainerLayer> CreateContainerLayer() override;
   already_AddRefed<ImageLayer> CreateImageLayer() override;
   already_AddRefed<ColorLayer> CreateColorLayer() override;
   already_AddRefed<CanvasLayer> CreateCanvasLayer() override;
   already_AddRefed<RefLayer> CreateRefLayer() override;
-  already_AddRefed<BorderLayer> CreateBorderLayer() override;
 
   bool AreComponentAlphaLayersEnabled() override;
   bool BlendingRequiresIntermediateSurface() override;
 
   // HostLayerManager methods
   void ForcePresent() override;
   TextureFactoryIdentifier GetTextureFactoryIdentifier() override;
   LayersBackend GetBackendType() override;
--- a/gfx/layers/moz.build
+++ b/gfx/layers/moz.build
@@ -335,32 +335,30 @@ UNIFIED_SOURCES += [
     'apz/util/ContentProcessController.cpp',
     'apz/util/DoubleTapToZoom.cpp',
     'apz/util/InputAPZContext.cpp',
     'apz/util/ScrollLinkedEffectDetector.cpp',
     'apz/util/TouchActionHelper.cpp',
     'AsyncCanvasRenderer.cpp',
     'AxisPhysicsModel.cpp',
     'AxisPhysicsMSDModel.cpp',
-    'basic/BasicBorderLayer.cpp',
     'basic/BasicCanvasLayer.cpp',
     'basic/BasicColorLayer.cpp',
     'basic/BasicCompositor.cpp',
     'basic/BasicContainerLayer.cpp',
     'basic/BasicImages.cpp',
     'basic/BasicLayerManager.cpp',
     'basic/BasicLayersImpl.cpp',
     'basic/BasicPaintedLayer.cpp',
     'basic/TextureHostBasic.cpp',
     'BSPTree.cpp',
     'BufferTexture.cpp',
     'BufferUnrotate.cpp',
     'CanvasRenderer.cpp',
     'client/CanvasClient.cpp',
-    'client/ClientBorderLayer.cpp',
     'client/ClientCanvasLayer.cpp',
     'client/ClientCanvasRenderer.cpp',
     'client/ClientColorLayer.cpp',
     'client/ClientContainerLayer.cpp',
     'client/ClientImageLayer.cpp',
     'client/ClientLayerManager.cpp',
     'client/ClientPaintedLayer.cpp',
     'client/ClientTiledPaintedLayer.cpp',
--- a/gfx/layers/wr/WebRenderBridgeChild.cpp
+++ b/gfx/layers/wr/WebRenderBridgeChild.cpp
@@ -117,16 +117,17 @@ WebRenderBridgeChild::UpdateResources(wr
 
 void
 WebRenderBridgeChild::EndTransaction(const wr::LayoutSize& aContentSize,
                                      wr::BuiltDisplayList& aDL,
                                      wr::IpcResourceUpdateQueue& aResources,
                                      const gfx::IntSize& aSize,
                                      TransactionId aTransactionId,
                                      const WebRenderScrollData& aScrollData,
+                                     const mozilla::TimeStamp& aRefreshStartTime,
                                      const mozilla::TimeStamp& aTxnStartTime)
 {
   MOZ_ASSERT(!mDestroyed);
   MOZ_ASSERT(mIsInTransaction);
 
   ByteBuf dlData(aDL.dl.inner.data, aDL.dl.inner.length, aDL.dl.inner.capacity);
   aDL.dl.inner.capacity = 0;
   aDL.dl.inner.data = nullptr;
@@ -140,42 +141,43 @@ WebRenderBridgeChild::EndTransaction(con
   nsTArray<RefCountedShmem> smallShmems;
   nsTArray<ipc::Shmem> largeShmems;
   aResources.Flush(resourceUpdates, smallShmems, largeShmems);
 
   this->SendSetDisplayList(aSize, mParentCommands, mDestroyedActors,
                            GetFwdTransactionId(), aTransactionId,
                            aContentSize, dlData, aDL.dl_desc, aScrollData,
                            std::move(resourceUpdates), std::move(smallShmems), largeShmems,
-                           mIdNamespace, aTxnStartTime, fwdTime);
+                           mIdNamespace, aRefreshStartTime, aTxnStartTime, fwdTime);
 
   mParentCommands.Clear();
   mDestroyedActors.Clear();
   mIsInTransaction = false;
 }
 
 void
 WebRenderBridgeChild::EndEmptyTransaction(const FocusTarget& aFocusTarget,
                                           const ScrollUpdatesMap& aUpdates,
                                           uint32_t aPaintSequenceNumber,
                                           TransactionId aTransactionId,
+                                          const mozilla::TimeStamp& aRefreshStartTime,
                                           const mozilla::TimeStamp& aTxnStartTime)
 {
   MOZ_ASSERT(!mDestroyed);
   MOZ_ASSERT(mIsInTransaction);
 
   TimeStamp fwdTime;
 #if defined(ENABLE_FRAME_LATENCY_LOG)
   fwdTime = TimeStamp::Now();
 #endif
 
   this->SendEmptyTransaction(aFocusTarget, aUpdates, aPaintSequenceNumber,
                              mParentCommands, mDestroyedActors,
                              GetFwdTransactionId(), aTransactionId,
-                             mIdNamespace, aTxnStartTime, fwdTime);
+                             mIdNamespace, aRefreshStartTime, aTxnStartTime, fwdTime);
   mParentCommands.Clear();
   mDestroyedActors.Clear();
   mIsInTransaction = false;
 }
 
 void
 WebRenderBridgeChild::ProcessWebRenderParentCommands()
 {
--- a/gfx/layers/wr/WebRenderBridgeChild.h
+++ b/gfx/layers/wr/WebRenderBridgeChild.h
@@ -69,21 +69,23 @@ public:
   void UpdateResources(wr::IpcResourceUpdateQueue& aResources);
   void BeginTransaction();
   void EndTransaction(const wr::LayoutSize& aContentSize,
                       wr::BuiltDisplayList& dl,
                       wr::IpcResourceUpdateQueue& aResources,
                       const gfx::IntSize& aSize,
                       TransactionId aTransactionId,
                       const WebRenderScrollData& aScrollData,
+                      const mozilla::TimeStamp& aRefreshStartTime,
                       const mozilla::TimeStamp& aTxnStartTime);
   void EndEmptyTransaction(const FocusTarget& aFocusTarget,
                            const ScrollUpdatesMap& aUpdates,
                            uint32_t aPaintSequenceNumber,
                            TransactionId aTransactionId,
+                           const mozilla::TimeStamp& aRefreshStartTime,
                            const mozilla::TimeStamp& aTxnStartTime);
   void ProcessWebRenderParentCommands();
 
   CompositorBridgeChild* GetCompositorBridgeChild();
 
   wr::PipelineId GetPipeline() { return mPipelineId; }
 
   // KnowsCompositor
--- a/gfx/layers/wr/WebRenderBridgeParent.cpp
+++ b/gfx/layers/wr/WebRenderBridgeParent.cpp
@@ -179,37 +179,39 @@ private:
 };
 
 WebRenderBridgeParent::WebRenderBridgeParent(CompositorBridgeParentBase* aCompositorBridge,
                                              const wr::PipelineId& aPipelineId,
                                              widget::CompositorWidget* aWidget,
                                              CompositorVsyncScheduler* aScheduler,
                                              RefPtr<wr::WebRenderAPI>&& aApi,
                                              RefPtr<AsyncImagePipelineManager>&& aImageMgr,
-                                             RefPtr<CompositorAnimationStorage>&& aAnimStorage)
+                                             RefPtr<CompositorAnimationStorage>&& aAnimStorage,
+                                             TimeDuration aVsyncRate)
   : mCompositorBridge(aCompositorBridge)
   , mPipelineId(aPipelineId)
   , mWidget(aWidget)
   , mApi(aApi)
   , mAsyncImageManager(aImageMgr)
   , mCompositorScheduler(aScheduler)
   , mAnimStorage(aAnimStorage)
+  , mVsyncRate(aVsyncRate)
   , mChildLayerObserverEpoch(0)
   , mParentLayerObserverEpoch(0)
   , mWrEpoch{0}
   , mIdNamespace(aApi->GetNamespace())
   , mPaused(false)
   , mDestroyed(false)
   , mForceRendering(false)
   , mReceivedDisplayList(false)
 {
   MOZ_ASSERT(mAsyncImageManager);
   MOZ_ASSERT(mAnimStorage);
   mAsyncImageManager->AddPipeline(mPipelineId);
-  if (mWidget) {
+  if (IsRootWebRenderBridgeParent()) {
     MOZ_ASSERT(!mCompositorScheduler);
     mCompositorScheduler = new CompositorVsyncScheduler(this, mWidget);
   }
 }
 
 WebRenderBridgeParent::WebRenderBridgeParent(const wr::PipelineId& aPipelineId)
   : mCompositorBridge(nullptr)
   , mPipelineId(aPipelineId)
@@ -517,24 +519,30 @@ WebRenderBridgeParent::RemoveEpochDataPr
       } else {
         NS_ERROR("Tried to delete invalid animation");
       }
     }
     mCompositorAnimationsToDelete.pop();
   }
 }
 
+bool
+WebRenderBridgeParent::IsRootWebRenderBridgeParent() const
+{
+  return !!mWidget;
+}
+
 CompositorBridgeParent*
 WebRenderBridgeParent::GetRootCompositorBridgeParent() const
 {
   if (!mCompositorBridge) {
     return nullptr;
   }
 
-  if (mWidget) {
+  if (IsRootWebRenderBridgeParent()) {
     // This WebRenderBridgeParent is attached to the root
     // CompositorBridgeParent.
     return static_cast<CompositorBridgeParent*>(mCompositorBridge);
   }
 
   // Otherwise, this WebRenderBridgeParent is attached to a
   // CrossProcessCompositorBridgeParent so we have an extra level of
   // indirection to unravel.
@@ -627,16 +635,17 @@ WebRenderBridgeParent::RecvSetDisplayLis
                                           const wr::LayoutSize& aContentSize,
                                           ipc::ByteBuf&& dl,
                                           const wr::BuiltDisplayListDescriptor& dlDesc,
                                           const WebRenderScrollData& aScrollData,
                                           nsTArray<OpUpdateResource>&& aResourceUpdates,
                                           nsTArray<RefCountedShmem>&& aSmallShmems,
                                           nsTArray<ipc::Shmem>&& aLargeShmems,
                                           const wr::IdNamespace& aIdNamespace,
+                                          const TimeStamp& aRefreshStartTime,
                                           const TimeStamp& aTxnStartTime,
                                           const TimeStamp& aFwdTime)
 {
   if (mDestroyed) {
     for (const auto& op : aToDestroy) {
       DestroyActor(op);
     }
     return IPC_OK();
@@ -674,17 +683,17 @@ WebRenderBridgeParent::RecvSetDisplayLis
   UpdateAPZScrollData(wrEpoch, std::move(const_cast<WebRenderScrollData&>(aScrollData)));
 
   wr::Vec<uint8_t> dlData(std::move(dl));
 
   // If id namespaces do not match, it means the command is obsolete, probably
   // because the tab just moved to a new window.
   // In that case do not send the commands to webrender.
   if (mIdNamespace == aIdNamespace) {
-    if (mWidget) {
+    if (IsRootWebRenderBridgeParent()) {
       LayoutDeviceIntSize widgetSize = mWidget->GetClientSize();
       LayoutDeviceIntRect docRect(LayoutDeviceIntPoint(), widgetSize);
       txn.SetWindowParameters(widgetSize, docRect);
     }
     gfx::Color clearColor(0.f, 0.f, 0.f, 0.f);
     txn.SetDisplayList(clearColor, wrEpoch, LayerSize(aSize.width, aSize.height),
                        mPipelineId, aContentSize,
                        dlDesc, dlData);
@@ -700,17 +709,17 @@ WebRenderBridgeParent::RecvSetDisplayLis
 
     if (!gfxPrefs::WebRenderAsyncSceneBuild()) {
       // With async-scene-build enabled, we will trigger this after the scene
       // build is done, so we don't need to do it here.
       ScheduleGenerateFrame();
     }
   }
 
-  HoldPendingTransactionId(wrEpoch, aTransactionId, aTxnStartTime, aFwdTime);
+  HoldPendingTransactionId(wrEpoch, aTransactionId, aRefreshStartTime, aTxnStartTime, aFwdTime);
 
   if (mIdNamespace != aIdNamespace) {
     // Pretend we composited since someone is wating for this event,
     // though DisplayList was not pushed to webrender.
     TimeStamp now = TimeStamp::Now();
     mCompositorBridge->DidComposite(GetLayersId(), now, now);
   }
 
@@ -727,16 +736,17 @@ mozilla::ipc::IPCResult
 WebRenderBridgeParent::RecvEmptyTransaction(const FocusTarget& aFocusTarget,
                                             const ScrollUpdatesMap& aUpdates,
                                             const uint32_t& aPaintSequenceNumber,
                                             InfallibleTArray<WebRenderParentCommand>&& aCommands,
                                             InfallibleTArray<OpDestroy>&& aToDestroy,
                                             const uint64_t& aFwdTransactionId,
                                             const TransactionId& aTransactionId,
                                             const wr::IdNamespace& aIdNamespace,
+                                            const TimeStamp& aRefreshStartTime,
                                             const TimeStamp& aTxnStartTime,
                                             const TimeStamp& aFwdTime)
 {
   if (mDestroyed) {
     for (const auto& op : aToDestroy) {
       DestroyActor(op);
     }
     return IPC_OK();
@@ -778,17 +788,17 @@ WebRenderBridgeParent::RecvEmptyTransact
     // transactions inflight, then set sendDidComposite to false because we will
     // send the DidComposite message after the composite occurs.
     // If there are no pending transactions and we're not going to do a
     // composite, then we leave sendDidComposite as true so we just send
     // the DidComposite notification now.
     sendDidComposite = false;
   }
 
-  HoldPendingTransactionId(WrEpoch(), aTransactionId, aTxnStartTime, aFwdTime);
+  HoldPendingTransactionId(WrEpoch(), aTransactionId, aRefreshStartTime, aTxnStartTime, aFwdTime);
 
   if (scheduleComposite) {
     ScheduleGenerateFrame();
   } else if (sendDidComposite) {
     TimeStamp now = TimeStamp::Now();
     mCompositorBridge->DidComposite(GetLayersId(), now, now);
   }
 
@@ -910,17 +920,17 @@ WebRenderBridgeParent::FlushSceneBuilds(
     ScheduleGenerateFrame();
   }
 }
 
 void
 WebRenderBridgeParent::FlushFrameGeneration()
 {
   MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
-  MOZ_ASSERT(mWidget); // This function is only useful on the root WRBP
+  MOZ_ASSERT(IsRootWebRenderBridgeParent()); // This function is only useful on the root WRBP
 
   // This forces a new GenerateFrame transaction to be sent to the render
   // backend thread, if one is pending. This doesn't block on any other threads.
   mForceRendering = true;
   mCompositorScheduler->FlushPendingComposite();
   mForceRendering = false;
 }
 
@@ -945,17 +955,17 @@ WebRenderBridgeParent::RecvGetSnapshot(P
   }
   MOZ_ASSERT(!mPaused);
 
   // This function should only get called in the root WRBP. If this function
   // gets called in a non-root WRBP, we will set mForceRendering in this WRBP
   // but it will have no effect because CompositeToTarget (which reads the
   // flag) only gets invoked in the root WRBP. So we assert that this is the
   // root WRBP (i.e. has a non-null mWidget) to catch violations of this rule.
-  MOZ_ASSERT(mWidget);
+  MOZ_ASSERT(IsRootWebRenderBridgeParent());
 
   RefPtr<TextureHost> texture = TextureHost::AsTextureHost(aTexture);
   if (!texture) {
     // We kill the content process rather than have it continue with an invalid
     // snapshot, that may be too harsh and we could decide to return some sort
     // of error to the child process and let it deal with it...
     return IPC_FAIL_NO_REASON(this);
   }
@@ -1140,17 +1150,17 @@ WebRenderBridgeParent::RecvClearCachedRe
 
 void
 WebRenderBridgeParent::UpdateWebRender(CompositorVsyncScheduler* aScheduler,
                                        wr::WebRenderAPI* aApi,
                                        AsyncImagePipelineManager* aImageMgr,
                                        CompositorAnimationStorage* aAnimStorage,
                                        const TextureFactoryIdentifier& aTextureFactoryIdentifier)
 {
-  MOZ_ASSERT(!mWidget);
+  MOZ_ASSERT(!IsRootWebRenderBridgeParent());
   MOZ_ASSERT(aScheduler);
   MOZ_ASSERT(aApi);
   MOZ_ASSERT(aImageMgr);
   MOZ_ASSERT(aAnimStorage);
 
   if (mDestroyed) {
     return;
   }
@@ -1394,17 +1404,17 @@ WebRenderBridgeParent::SampleAnimations(
 
   return isAnimating;
 }
 
 void
 WebRenderBridgeParent::CompositeToTarget(gfx::DrawTarget* aTarget, const gfx::IntRect* aRect)
 {
   // This function should only get called in the root WRBP
-  MOZ_ASSERT(mWidget);
+  MOZ_ASSERT(IsRootWebRenderBridgeParent());
 
   // The two arguments are part of the CompositorVsyncSchedulerOwner API but in
   // this implementation they should never be non-null.
   MOZ_ASSERT(aTarget == nullptr);
   MOZ_ASSERT(aRect == nullptr);
 
   AUTO_PROFILER_TRACING("Paint", "CompositeToTraget");
   if (mPaused || !mReceivedDisplayList) {
@@ -1476,21 +1486,26 @@ WebRenderBridgeParent::CompositeToTarget
   txn.GenerateFrame();
 
   mApi->SendTransaction(txn);
 }
 
 void
 WebRenderBridgeParent::HoldPendingTransactionId(const wr::Epoch& aWrEpoch,
                                                 TransactionId aTransactionId,
+                                                const TimeStamp& aRefreshStartTime,
                                                 const TimeStamp& aTxnStartTime,
                                                 const TimeStamp& aFwdTime)
 {
   MOZ_ASSERT(aTransactionId > LastPendingTransactionId());
-  mPendingTransactionIds.push(PendingTransactionId(aWrEpoch, aTransactionId, aTxnStartTime, aFwdTime));
+  mPendingTransactionIds.push(PendingTransactionId(aWrEpoch,
+                                                   aTransactionId,
+                                                   aRefreshStartTime,
+                                                   aTxnStartTime,
+                                                   aFwdTime));
 }
 
 TransactionId
 WebRenderBridgeParent::LastPendingTransactionId()
 {
   TransactionId id{0};
   if (!mPendingTransactionIds.empty()) {
     id = mPendingTransactionIds.back().mId;
@@ -1512,23 +1527,31 @@ WebRenderBridgeParent::FlushPendingTrans
 TransactionId
 WebRenderBridgeParent::FlushTransactionIdsForEpoch(const wr::Epoch& aEpoch, const TimeStamp& aEndTime)
 {
   TransactionId id{0};
   while (!mPendingTransactionIds.empty()) {
     if (aEpoch.mHandle < mPendingTransactionIds.front().mEpoch.mHandle) {
       break;
     }
+
+    if (!IsRootWebRenderBridgeParent() && !mVsyncRate.IsZero()) {
+      double latencyMs = (aEndTime - mPendingTransactionIds.front().mTxnStartTime).ToMilliseconds();
+      double latencyNorm = latencyMs / mVsyncRate.ToMilliseconds();
+      int32_t fracLatencyNorm = lround(latencyNorm * 100.0);
+      Telemetry::Accumulate(Telemetry::CONTENT_FRAME_TIME, fracLatencyNorm);
+    }
+
 #if defined(ENABLE_FRAME_LATENCY_LOG)
-    if (mPendingTransactionIds.front().mTxnStartTime) {
-      uint32_t latencyMs = round((aEndTime - mPendingTransactionIds.front().mTxnStartTime).ToMilliseconds());
+    if (mPendingTransactionIds.front().mRefreshStartTime) {
+      int32_t latencyMs = lround((aEndTime - mPendingTransactionIds.front().mRefreshStartTime).ToMilliseconds());
       printf_stderr("From transaction start to end of generate frame latencyMs %d this %p\n", latencyMs, this);
     }
     if (mPendingTransactionIds.front().mFwdTime) {
-      uint32_t latencyMs = round((aEndTime - mPendingTransactionIds.front().mFwdTime).ToMilliseconds());
+      int32_t latencyMs = lround((aEndTime - mPendingTransactionIds.front().mFwdTime).ToMilliseconds());
       printf_stderr("From forwarding transaction to end of generate frame latencyMs %d this %p\n", latencyMs, this);
     }
 #endif
     id = mPendingTransactionIds.front().mId;
     mPendingTransactionIds.pop();
   }
   return id;
 }
@@ -1568,32 +1591,32 @@ WebRenderBridgeParent::FlushRenderingAsy
   }
 
   mCompositorScheduler->FlushPendingComposite();
 }
 
 void
 WebRenderBridgeParent::Pause()
 {
-  MOZ_ASSERT(mWidget);
+  MOZ_ASSERT(IsRootWebRenderBridgeParent());
 #ifdef MOZ_WIDGET_ANDROID
-  if (!mWidget || mDestroyed) {
+  if (!IsRootWebRenderBridgeParent() || mDestroyed) {
     return;
   }
   mApi->Pause();
 #endif
   mPaused = true;
 }
 
 bool
 WebRenderBridgeParent::Resume()
 {
-  MOZ_ASSERT(mWidget);
+  MOZ_ASSERT(IsRootWebRenderBridgeParent());
 #ifdef MOZ_WIDGET_ANDROID
-  if (!mWidget || mDestroyed) {
+  if (!IsRootWebRenderBridgeParent() || mDestroyed) {
     return false;
   }
 
   if (!mApi->Resume()) {
     return false;
   }
 #endif
   mPaused = false;
@@ -1639,17 +1662,17 @@ WebRenderBridgeParent::ClearResources()
   mApi->SendTransaction(txn);
 
   for (std::unordered_set<uint64_t>::iterator iter = mActiveAnimations.begin(); iter != mActiveAnimations.end(); iter++) {
     mAnimStorage->ClearById(*iter);
   }
   mActiveAnimations.clear();
   std::queue<CompositorAnimationIdsForEpoch>().swap(mCompositorAnimationsToDelete); // clear queue
 
-  if (mWidget) {
+  if (IsRootWebRenderBridgeParent()) {
     mCompositorScheduler->Destroy();
   }
 
   // Before tearing down mApi we should make sure the above transaction has been
   // flushed back to the render backend thread. Otherwise the cleanup messages
   // that the WebRenderAPI destructor triggers can race ahead of the transaction
   // (because it goes directly to the RB thread, bypassing the scene builder
   // thread) and clear caches etc. that are still in use.
@@ -1755,17 +1778,17 @@ WebRenderBridgeParent::GetNextWrEpoch()
   MOZ_RELEASE_ASSERT(mWrEpoch.mHandle != UINT32_MAX);
   mWrEpoch.mHandle++;
   return mWrEpoch;
 }
 
 void
 WebRenderBridgeParent::ExtractImageCompositeNotifications(nsTArray<ImageCompositeNotificationInfo>* aNotifications)
 {
-  MOZ_ASSERT(mWidget);
+  MOZ_ASSERT(IsRootWebRenderBridgeParent());
   if (mDestroyed) {
     return;
   }
   mAsyncImageManager->FlushImageNotifications(aNotifications);
 }
 
 } // namespace layers
 } // namespace mozilla
--- a/gfx/layers/wr/WebRenderBridgeParent.h
+++ b/gfx/layers/wr/WebRenderBridgeParent.h
@@ -48,17 +48,18 @@ class WebRenderBridgeParent final : publ
 {
 public:
   WebRenderBridgeParent(CompositorBridgeParentBase* aCompositorBridge,
                         const wr::PipelineId& aPipelineId,
                         widget::CompositorWidget* aWidget,
                         CompositorVsyncScheduler* aScheduler,
                         RefPtr<wr::WebRenderAPI>&& aApi,
                         RefPtr<AsyncImagePipelineManager>&& aImageMgr,
-                        RefPtr<CompositorAnimationStorage>&& aAnimStorage);
+                        RefPtr<CompositorAnimationStorage>&& aAnimStorage,
+                        TimeDuration aVsyncRate);
 
   static WebRenderBridgeParent* CreateDestroyed(const wr::PipelineId& aPipelineId);
 
   wr::PipelineId PipelineId() { return mPipelineId; }
   already_AddRefed<wr::WebRenderAPI> GetWebRenderAPI() { return do_AddRef(mApi); }
   wr::Epoch WrEpoch() const { return mWrEpoch; }
   AsyncImagePipelineManager* AsyncImageManager() { return mAsyncImageManager; }
   CompositorVsyncScheduler* CompositorScheduler() { return mCompositorScheduler.get(); }
@@ -82,26 +83,28 @@ public:
                                              const wr::LayoutSize& aContentSize,
                                              ipc::ByteBuf&& dl,
                                              const wr::BuiltDisplayListDescriptor& dlDesc,
                                              const WebRenderScrollData& aScrollData,
                                              nsTArray<OpUpdateResource>&& aResourceUpdates,
                                              nsTArray<RefCountedShmem>&& aSmallShmems,
                                              nsTArray<ipc::Shmem>&& aLargeShmems,
                                              const wr::IdNamespace& aIdNamespace,
+                                             const TimeStamp& aRefreshStartTime,
                                              const TimeStamp& aTxnStartTime,
                                              const TimeStamp& aFwdTime) override;
   mozilla::ipc::IPCResult RecvEmptyTransaction(const FocusTarget& aFocusTarget,
                                                const ScrollUpdatesMap& aUpdates,
                                                const uint32_t& aPaintSequenceNumber,
                                                InfallibleTArray<WebRenderParentCommand>&& aCommands,
                                                InfallibleTArray<OpDestroy>&& aToDestroy,
                                                const uint64_t& aFwdTransactionId,
                                                const TransactionId& aTransactionId,
                                                const wr::IdNamespace& aIdNamespace,
+                                               const TimeStamp& aRefreshStartTime,
                                                const TimeStamp& aTxnStartTime,
                                                const TimeStamp& aFwdTime) override;
   mozilla::ipc::IPCResult RecvSetFocusTarget(const FocusTarget& aFocusTarget) override;
   mozilla::ipc::IPCResult RecvParentCommands(nsTArray<WebRenderParentCommand>&& commands) override;
   mozilla::ipc::IPCResult RecvGetSnapshot(PTextureParent* aTexture) override;
 
   mozilla::ipc::IPCResult RecvSetLayerObserverEpoch(const uint64_t& aLayerObserverEpoch) override;
 
@@ -145,16 +148,17 @@ public:
   base::ProcessId GetChildProcessId() override;
   void NotifyNotUsed(PTextureParent* aTexture, uint64_t aTransactionId) override;
   void SendAsyncMessage(const InfallibleTArray<AsyncParentMessageData>& aMessage) override;
   void SendPendingAsyncMessages() override;
   void SetAboutToSendAsyncMessages() override;
 
   void HoldPendingTransactionId(const wr::Epoch& aWrEpoch,
                                 TransactionId aTransactionId,
+                                const TimeStamp& aRefreshStartTime,
                                 const TimeStamp& aTxnStartTime,
                                 const TimeStamp& aFwdTime);
   TransactionId LastPendingTransactionId();
   TransactionId FlushPendingTransactionIds();
   TransactionId FlushTransactionIdsForEpoch(const wr::Epoch& aEpoch, const TimeStamp& aEndTime);
 
   TextureFactoryIdentifier GetTextureFactoryIdentifier();
 
@@ -225,39 +229,47 @@ private:
   mozilla::ipc::IPCResult HandleShutdown();
 
   // Returns true if there is any animation (including animations in delay
   // phase).
   bool AdvanceAnimations();
   bool SampleAnimations(nsTArray<wr::WrOpacityProperty>& aOpacityArray,
                         nsTArray<wr::WrTransformProperty>& aTransformArray);
 
+  bool IsRootWebRenderBridgeParent() const;
+
   CompositorBridgeParent* GetRootCompositorBridgeParent() const;
 
   RefPtr<WebRenderBridgeParent> GetRootWebRenderBridgeParent() const;
 
   // Tell APZ what the subsequent sampling's timestamp should be.
   void SetAPZSampleTime();
 
   wr::Epoch GetNextWrEpoch();
 
   void FlushSceneBuilds();
   void FlushFrameGeneration();
   void FlushFramePresentation();
 
 private:
   struct PendingTransactionId {
-    PendingTransactionId(const wr::Epoch& aEpoch, TransactionId aId, const TimeStamp& aTxnStartTime, const TimeStamp& aFwdTime)
+    PendingTransactionId(const wr::Epoch& aEpoch,
+                         TransactionId aId,
+                         const TimeStamp& aRefreshStartTime,
+                         const TimeStamp& aTxnStartTime,
+                         const TimeStamp& aFwdTime)
       : mEpoch(aEpoch)
       , mId(aId)
+      , mRefreshStartTime(aRefreshStartTime)
       , mTxnStartTime(aTxnStartTime)
       , mFwdTime(aFwdTime)
     {}
     wr::Epoch mEpoch;
     TransactionId mId;
+    TimeStamp mRefreshStartTime;
     TimeStamp mTxnStartTime;
     TimeStamp mFwdTime;
   };
 
   struct CompositorAnimationIdsForEpoch {
     CompositorAnimationIdsForEpoch(const wr::Epoch& aEpoch, InfallibleTArray<uint64_t>&& aIds)
       : mEpoch(aEpoch)
       , mIds(std::move(aIds))
@@ -277,16 +289,17 @@ private:
   RefPtr<CompositorAnimationStorage> mAnimStorage;
   // mActiveAnimations is used to avoid leaking animations when WebRenderBridgeParent is
   // destroyed abnormally and Tab move between different windows.
   std::unordered_set<uint64_t> mActiveAnimations;
   nsDataHashtable<nsUint64HashKey, RefPtr<WebRenderImageHost>> mAsyncCompositables;
   nsDataHashtable<nsUint64HashKey, RefPtr<WebRenderImageHost>> mExternalImageIds;
   nsTHashtable<nsUint64HashKey> mSharedSurfaceIds;
 
+  TimeDuration mVsyncRate;
   TimeStamp mPreviousFrameTimeStamp;
   // These fields keep track of the latest layer observer epoch values in the child and the
   // parent. mChildLayerObserverEpoch is the latest epoch value received from the child.
   // mParentLayerObserverEpoch is the latest epoch value that we have told TabParent about
   // (via ObserveLayerUpdate).
   uint64_t mChildLayerObserverEpoch;
   uint64_t mParentLayerObserverEpoch;
 
--- a/gfx/layers/wr/WebRenderLayerManager.cpp
+++ b/gfx/layers/wr/WebRenderLayerManager.cpp
@@ -163,16 +163,18 @@ WebRenderLayerManager::BeginTransactionW
 bool
 WebRenderLayerManager::BeginTransaction()
 {
   if (!WrBridge()->IPCOpen()) {
     gfxCriticalNote << "IPC Channel is already torn down unexpectedly\n";
     return false;
   }
 
+  mTransactionStart = TimeStamp::Now();
+
   // Increment the paint sequence number even if test logging isn't
   // enabled in this process; it may be enabled in the parent process,
   // and the parent process expects unique sequence numbers.
   ++mPaintSequenceNumber;
   if (gfxPrefs::APZTestLoggingEnabled()) {
     mApzTestData.StartNewPaint(mPaintSequenceNumber);
   }
   return true;
@@ -203,31 +205,33 @@ WebRenderLayerManager::EndEmptyTransacti
   }
 
   LayoutDeviceIntSize size = mWidget->GetClientSize();
   WrBridge()->BeginTransaction();
 
   mWebRenderCommandBuilder.EmptyTransaction();
 
   mLatestTransactionId = mTransactionIdAllocator->GetTransactionId(/*aThrottle*/ true);
-  TimeStamp transactionStart = mTransactionIdAllocator->GetTransactionStart();
+  TimeStamp refreshStart = mTransactionIdAllocator->GetTransactionStart();
 
   // Skip the synchronization for buffer since we also skip the painting during
   // device-reset status.
   if (!gfxPlatform::GetPlatform()->DidRenderingDeviceReset()) {
     if (WrBridge()->GetSyncObject() &&
         WrBridge()->GetSyncObject()->IsSyncObjectValid()) {
       WrBridge()->GetSyncObject()->Synchronize();
     }
   }
 
   WrBridge()->EndEmptyTransaction(mFocusTarget, mPendingScrollUpdates,
-      mPaintSequenceNumber, mLatestTransactionId, transactionStart);
+      mPaintSequenceNumber, mLatestTransactionId, refreshStart, mTransactionStart);
   ClearPendingScrollInfoUpdate();
 
+  mTransactionStart = TimeStamp();
+
   MakeSnapshotIfRequired(size);
   return true;
 }
 
 void
 WebRenderLayerManager::EndTransaction(DrawPaintedLayerCallback aCallback,
                                       void* aCallbackData,
                                       EndTransactionFlags aFlags)
@@ -303,17 +307,17 @@ WebRenderLayerManager::EndTransactionWit
     mScrollData.SetPaintSequenceNumber(mPaintSequenceNumber);
   }
   // Since we're sending a full mScrollData that will include the new scroll
   // offsets, and we can throw away the pending scroll updates we had kept for
   // an empty transaction.
   ClearPendingScrollInfoUpdate();
 
   mLatestTransactionId = mTransactionIdAllocator->GetTransactionId(/*aThrottle*/ true);
-  TimeStamp transactionStart = mTransactionIdAllocator->GetTransactionStart();
+  TimeStamp refreshStart = mTransactionIdAllocator->GetTransactionStart();
 
   for (const auto& key : mImageKeysToDelete) {
     resourceUpdates.DeleteImage(key);
   }
   mImageKeysToDelete.Clear();
 
   WrBridge()->RemoveExpiredFontKeys(resourceUpdates);
 
@@ -332,19 +336,21 @@ WebRenderLayerManager::EndTransactionWit
 
   wr::BuiltDisplayList dl;
   builder.Finalize(contentSize, dl);
   mLastDisplayListSize = dl.dl.inner.capacity;
 
   {
     AUTO_PROFILER_TRACING("Paint", "ForwardDPTransaction");
     WrBridge()->EndTransaction(contentSize, dl, resourceUpdates, size.ToUnknownSize(),
-                               mLatestTransactionId, mScrollData, transactionStart);
+                               mLatestTransactionId, mScrollData, refreshStart, mTransactionStart);
   }
 
+  mTransactionStart = TimeStamp();
+
   MakeSnapshotIfRequired(size);
   mNeedsComposite = false;
 }
 
 void
 WebRenderLayerManager::SetFocusTarget(const FocusTarget& aFocusTarget)
 {
   mFocusTarget = aFocusTarget;
--- a/gfx/layers/wr/WebRenderLayerManager.h
+++ b/gfx/layers/wr/WebRenderLayerManager.h
@@ -82,17 +82,16 @@ public:
   virtual const char* Name() const override { return "WebRender"; }
 
   virtual void SetRoot(Layer* aLayer) override;
 
   already_AddRefed<PaintedLayer> CreatePaintedLayer() override { return nullptr; }
   already_AddRefed<ContainerLayer> CreateContainerLayer() override { return nullptr; }
   already_AddRefed<ImageLayer> CreateImageLayer() override { return nullptr; }
   already_AddRefed<ColorLayer> CreateColorLayer() override { return nullptr; }
-  already_AddRefed<BorderLayer> CreateBorderLayer() override { return nullptr; }
   already_AddRefed<CanvasLayer> CreateCanvasLayer() override { return nullptr; }
 
   virtual bool NeedsWidgetInvalidation() override { return false; }
 
   virtual void SetLayerObserverEpoch(uint64_t aLayerObserverEpoch) override;
 
   virtual void DidComposite(TransactionId aTransactionId,
                             const mozilla::TimeStamp& aCompositeStart,
@@ -207,16 +206,17 @@ private:
   // back to mTarget.
   RefPtr<gfxContext> mTarget;
 
   // See equivalent field in ClientLayerManager
   uint32_t mPaintSequenceNumber;
   // See equivalent field in ClientLayerManager
   APZTestData mApzTestData;
 
+  TimeStamp mTransactionStart;
   WebRenderCommandBuilder mWebRenderCommandBuilder;
 
   size_t mLastDisplayListSize;
 };
 
 } // namespace layers
 } // namespace mozilla
 
--- a/gfx/tests/gtest/TestLayers.cpp
+++ b/gfx/tests/gtest/TestLayers.cpp
@@ -71,19 +71,16 @@ public:
   }
   virtual already_AddRefed<PaintedLayer> CreatePaintedLayer() {
     RefPtr<PaintedLayer> layer = new TestPaintedLayer(this);
     return layer.forget();
   }
   virtual already_AddRefed<ColorLayer> CreateColorLayer() {
     MOZ_CRASH("Not implemented.");
   }
-  virtual already_AddRefed<BorderLayer> CreateBorderLayer() {
-    MOZ_CRASH("Not implemented.");
-  }
   virtual void SetRoot(Layer* aLayer) {}
   virtual bool BeginTransactionWithTarget(gfxContext* aTarget) { return true; }
   virtual already_AddRefed<CanvasLayer> CreateCanvasLayer() {
     MOZ_CRASH("Not implemented.");
   }
   virtual void EndTransaction(DrawPaintedLayerCallback aCallback,
                               void* aCallbackData,
                               EndTransactionFlags aFlags = END_DEFAULT) {}
--- a/gfx/thebes/gfxDWriteFonts.cpp
+++ b/gfx/thebes/gfxDWriteFonts.cpp
@@ -692,16 +692,17 @@ gfxDWriteFont::GetScaledFont(mozilla::gf
                                                    useEmbeddedBitmap,
                                                    forceGDI,
                                                    params,
                                                    params->GetGamma(),
                                                    params->GetEnhancedContrast());
         if (!mAzureScaledFont) {
             return nullptr;
         }
+        InitializeScaledFont();
         mAzureScaledFontUsedClearType = sUseClearType;
     }
 
     if (aTarget->GetBackendType() == BackendType::CAIRO) {
         if (!mAzureScaledFont->GetCairoScaledFont()) {
             cairo_scaled_font_t* cairoScaledFont = InitCairoScaledFont();
             if (!cairoScaledFont) {
                 return nullptr;
--- a/gfx/thebes/gfxFT2Fonts.cpp
+++ b/gfx/thebes/gfxFT2Fonts.cpp
@@ -187,16 +187,17 @@ gfxFT2Font::GetScaledFont(DrawTarget *aT
         nativeFont.mType = NativeFontType::FREETYPE_FACE;
         nativeFont.mFont = mFTFace;
 
         mAzureScaledFont =
           Factory::CreateScaledFontForNativeFont(nativeFont,
                                                  GetUnscaledFont(),
                                                  GetAdjustedSize(),
                                                  GetCairoScaledFont());
+        InitializeScaledFont();
     }
 
     RefPtr<ScaledFont> scaledFont(mAzureScaledFont);
     return scaledFont.forget();
 }
 
 void
 gfxFT2Font::FillGlyphDataForChar(FT_Face face, uint32_t ch, CachedGlyphData *gd)
--- a/gfx/thebes/gfxFcPlatformFontList.cpp
+++ b/gfx/thebes/gfxFcPlatformFontList.cpp
@@ -1462,16 +1462,17 @@ gfxFontconfigFont::GetScaledFont(mozilla
         nativeFont.mType = NativeFontType::FONTCONFIG_PATTERN;
         nativeFont.mFont = GetPattern();
 
         mAzureScaledFont =
           Factory::CreateScaledFontForNativeFont(nativeFont,
                                                  GetUnscaledFont(),
                                                  GetAdjustedSize(),
                                                  GetCairoScaledFont());
+        InitializeScaledFont();
     }
 
     RefPtr<ScaledFont> scaledFont(mAzureScaledFont);
     return scaledFont.forget();
 }
 
 gfxFcPlatformFontList::gfxFcPlatformFontList()
     : mLocalNames(64)
--- a/gfx/thebes/gfxFont.cpp
+++ b/gfx/thebes/gfxFont.cpp
@@ -747,39 +747,52 @@ gfxShapedText::AdjustAdvancesForSyntheti
                      details[detailedLength - 1].mAdvance += synAppUnitOffset;
                  }
              }
          }
     }
 }
 
 float
-gfxFont::SkewForSyntheticOblique() const
+gfxFont::AngleForSyntheticOblique() const
 {
-    // Precomputed value of tan(14deg), the default italic/oblique slant;
-    // avoids calling tan() at runtime except for custom oblique values.
-    const float kTan14deg = 0.249328f;
-
     // If the style doesn't call for italic/oblique, or if the face already
     // provides it, no synthetic style should be added.
     if (mStyle.style == FontSlantStyle::Normal() ||
         !mStyle.allowSyntheticStyle ||
         !mFontEntry->IsUpright()) {
         return 0.0f;
     }
 
     // If style calls for italic, and face doesn't support it, use default
     // oblique angle as a simulation.
     if (mStyle.style.IsItalic()) {
-        return mFontEntry->SupportsItalic() ? 0.0f : kTan14deg;
+        return mFontEntry->SupportsItalic() ? 0.0f : FontSlantStyle::kDefaultAngle;
     }
 
-    // Default oblique angle
-    return mStyle.style == FontSlantStyle::Oblique()
-           ? kTan14deg : tan(mStyle.style.ObliqueAngle() * (M_PI / 180.0));
+    // Default or custom oblique angle
+    return mStyle.style.ObliqueAngle();
+}
+
+float
+gfxFont::SkewForSyntheticOblique() const
+{
+    // Precomputed value of tan(kDefaultAngle), the default italic/oblique slant;
+    // avoids calling tan() at runtime except for custom oblique values.
+    static const float kTanDefaultAngle =
+        tan(FontSlantStyle::kDefaultAngle * (M_PI / 180.0));
+
+    float angle = AngleForSyntheticOblique();
+    if (angle == 0.0f) {
+        return 0.0f;
+    } else if (angle == FontSlantStyle::kDefaultAngle) {
+        return kTanDefaultAngle;
+    } else {
+        return tan(angle * (M_PI / 180.0));
+    }
 }
 
 void
 gfxFont::RunMetrics::CombineWith(const RunMetrics& aOther, bool aOtherIsOnLeft)
 {
     mAscent = std::max(mAscent, aOther.mAscent);
     mDescent = std::max(mDescent, aOther.mDescent);
     if (aOtherIsOnLeft) {
@@ -1622,16 +1635,29 @@ gfxFont::HasFeatureSet(uint32_t aFeature
             featureSet = true;
             aFeatureOn = (feature.mValue != 0);
         }
     }
 
     return featureSet;
 }
 
+void
+gfxFont::InitializeScaledFont()
+{
+    if (!mAzureScaledFont) {
+        return;
+    }
+
+    float angle = AngleForSyntheticOblique();
+    if (angle != 0.0f) {
+        mAzureScaledFont->SetSyntheticObliqueAngle(angle);
+    }
+}
+
 /**
  * A helper function in case we need to do any rounding or other
  * processing here.
  */
 #define ToDeviceUnits(aAppUnits, aDevUnitsPerAppUnit) \
     (double(aAppUnits)*double(aDevUnitsPerAppUnit))
 
 static AntialiasMode Get2DAAMode(gfxFont::AntialiasOption aAAOption) {
@@ -2299,37 +2325,31 @@ gfxFont::Draw(const gfxTextRun *aTextRun
         // [1] See http://www.microsoft.com/typography/otspec/base.htm
         if (aTextRun->UseCenterBaseline()) {
             const Metrics& metrics = GetMetrics(eHorizontal);
             float baseAdj = (metrics.emAscent - metrics.emDescent) / 2;
             baseline += baseAdj * aTextRun->GetAppUnitsPerDevUnit() * baselineDir;
         }
     }
 
-    if (fontParams.obliqueSkew != 0.0f) {
-        if (textDrawer) {
-            glyphFlagsRestore.Save(textDrawer);
-            textDrawer->SetWRGlyphFlags(textDrawer->GetWRGlyphFlags() |
-                                        wr::FontInstanceFlags::SYNTHETIC_ITALICS);
-        } else if (!fontParams.isVerticalFont) {
-            // Adjust matrix for synthetic-oblique, except if we're doing vertical-
-            // upright text, in which case this will be handled for each glyph
-            // individually in DrawOneGlyph.
-            if (!matrixRestore.HasMatrix()) {
-                matrixRestore.SetContext(aRunParams.context);
-            }
-            gfx::Point p(aPt->x * aRunParams.devPerApp,
-                         aPt->y * aRunParams.devPerApp);
-            gfx::Matrix mat =
-                aRunParams.context->CurrentMatrix().
-                PreTranslate(p).
-                PreMultiply(gfx::Matrix(1, 0, -fontParams.obliqueSkew, 1, 0, 0)).
-                PreTranslate(-p);
-            aRunParams.context->SetMatrix(mat);
+    if (fontParams.obliqueSkew != 0.0f && !fontParams.isVerticalFont && !textDrawer) {
+        // Adjust matrix for synthetic-oblique, except if we're doing vertical-
+        // upright text, in which case this will be handled for each glyph
+        // individually in DrawOneGlyph.
+        if (!matrixRestore.HasMatrix()) {
+            matrixRestore.SetContext(aRunParams.context);
         }
+        gfx::Point p(aPt->x * aRunParams.devPerApp,
+                     aPt->y * aRunParams.devPerApp);
+        gfx::Matrix mat =
+            aRunParams.context->CurrentMatrix().
+            PreTranslate(p).
+            PreMultiply(gfx::Matrix(1, 0, -fontParams.obliqueSkew, 1, 0, 0)).
+            PreTranslate(-p);
+        aRunParams.context->SetMatrix(mat);
     }
 
     RefPtr<SVGContextPaint> contextPaint;
     if (fontParams.haveSVGGlyphs && !fontParams.contextPaint) {
         // If no pattern is specified for fill, use the current pattern
         NS_ASSERTION((int(aRunParams.drawMode) & int(DrawMode::GLYPH_STROKE)) == 0,
                      "no pattern supplied for stroking text");
         RefPtr<gfxPattern> fillPattern = aRunParams.context->GetPattern();
--- a/gfx/thebes/gfxFont.h
+++ b/gfx/thebes/gfxFont.h
@@ -1825,16 +1825,17 @@ public:
 
     // This is called by the default Draw() implementation above.
     virtual bool SetupCairoFont(DrawTarget* aDrawTarget) = 0;
 
     virtual bool AllowSubpixelAA() { return true; }
 
     bool IsSyntheticBold() const { return mApplySyntheticBold; }
 
+    float AngleForSyntheticOblique() const;
     float SkewForSyntheticOblique() const;
 
     // Amount by which synthetic bold "fattens" the glyphs:
     // For size S up to a threshold size T, we use (0.25 + 3S / 4T),
     // so that the result ranges from 0.25 to 1.0; thereafter,
     // simply use (S / T).
     gfxFloat GetSyntheticBoldOffset() {
         gfxFloat size = GetAdjustedSize();
@@ -1945,16 +1946,18 @@ public:
     virtual FontType GetType() const = 0;
 
     const RefPtr<mozilla::gfx::UnscaledFont>& GetUnscaledFont() const {
         return mUnscaledFont;
     }
 
     virtual already_AddRefed<mozilla::gfx::ScaledFont> GetScaledFont(DrawTarget* aTarget) = 0;
 
+    void InitializeScaledFont();
+
     bool KerningDisabled() {
         return mKerningSet && !mKerningEnabled;
     }
 
     /**
      * Subclass this object to be notified of glyph changes. Delete the object
      * when no longer needed.
      */
--- a/gfx/thebes/gfxGDIFont.cpp
+++ b/gfx/thebes/gfxGDIFont.cpp
@@ -146,16 +146,17 @@ gfxGDIFont::GetScaledFont(DrawTarget *aT
         GetObject(GetHFONT(), sizeof(LOGFONT), &lf);
         nativeFont.mFont = &lf;
 
         mAzureScaledFont =
           Factory::CreateScaledFontForNativeFont(nativeFont,
                                                  GetUnscaledFont(),
                                                  GetAdjustedSize(),
                                                  GetCairoScaledFont());
+        InitializeScaledFont();
     }
 
     RefPtr<ScaledFont> scaledFont(mAzureScaledFont);
     return scaledFont.forget();
 }
 
 gfxFont::RunMetrics
 gfxGDIFont::Measure(const gfxTextRun *aTextRun,
--- a/gfx/thebes/gfxMacFont.cpp
+++ b/gfx/thebes/gfxMacFont.cpp
@@ -609,17 +609,17 @@ gfxMacFont::GetScaledFont(DrawTarget *aT
                                                 GetUnscaledFont(),
                                                 GetAdjustedSize(),
                                                 Color::FromABGR(mFontSmoothingBackgroundColor),
                                                 !mStyle.useGrayscaleAntialiasing,
                                                 IsSyntheticBold());
         if (!mAzureScaledFont) {
             return nullptr;
         }
-
+        InitializeScaledFont();
         mAzureScaledFont->SetCairoScaledFont(mScaledFont);
     }
 
     RefPtr<ScaledFont> scaledFont(mAzureScaledFont);
     return scaledFont.forget();
 }
 
 void
--- a/gfx/thebes/gfxPrefs.h
+++ b/gfx/thebes/gfxPrefs.h
@@ -553,17 +553,16 @@ private:
   DECL_GFX_PREF(Once, "image.multithreaded_decoding.limit",    ImageMTDecodingLimit, int32_t, -1);
   DECL_GFX_PREF(Once, "image.multithreaded_decoding.idle_timeout", ImageMTDecodingIdleTimeout, int32_t, -1);
 
   DECL_GFX_PREF(Once, "layers.acceleration.disabled",          LayersAccelerationDisabledDoNotUseDirectly, bool, false);
   DECL_GFX_PREF(Live, "layers.acceleration.draw-fps",          LayersDrawFPS, bool, false);
   DECL_GFX_PREF(Live, "layers.acceleration.draw-fps.print-histogram",  FPSPrintHistogram, bool, false);
   DECL_GFX_PREF(Live, "layers.acceleration.draw-fps.write-to-file", WriteFPSToFile, bool, false);
   DECL_GFX_PREF(Once, "layers.acceleration.force-enabled",     LayersAccelerationForceEnabledDoNotUseDirectly, bool, false);
-  DECL_GFX_PREF(Live, "layers.advanced.border-layers",           LayersAllowBorderLayers, bool, false);
   DECL_GFX_PREF(Live, "layers.advanced.basic-layer.enabled",          LayersAdvancedBasicLayerEnabled, bool, false);
   DECL_GFX_PREF(Once, "layers.amd-switchable-gfx.enabled",     LayersAMDSwitchableGfxEnabled, bool, false);
   DECL_GFX_PREF(Once, "layers.async-pan-zoom.enabled",         AsyncPanZoomEnabledDoNotUseDirectly, bool, true);
   DECL_GFX_PREF(Once, "layers.async-pan-zoom.separate-event-thread", AsyncPanZoomSeparateEventThread, bool, false);
   DECL_GFX_PREF(Live, "layers.bench.enabled",                  LayersBenchEnabled, bool, false);
   DECL_GFX_PREF(Once, "layers.bufferrotation.enabled",         BufferRotationEnabled, bool, true);
   DECL_GFX_PREF(Live, "layers.child-process-shutdown",         ChildProcessShutdown, bool, true);
 #ifdef MOZ_GFX_OPTIMIZE_MOBILE
--- a/gfx/webrender/src/display_list_flattener.rs
+++ b/gfx/webrender/src/display_list_flattener.rs
@@ -1827,16 +1827,17 @@ impl<'a> DisplayListFlattener<'a> {
 
             let prim_font = FontInstance::new(
                 font_instance.font_key,
                 font_instance.size,
                 *text_color,
                 font_instance.bg_color,
                 render_mode,
                 flags,
+                font_instance.synthetic_italics,
                 font_instance.platform_options,
                 font_instance.variations.clone(),
             );
             TextRunPrimitiveCpu::new(
                 prim_font,
                 run_offset,
                 glyph_range,
                 Vec::new(),
--- a/gfx/webrender/src/glyph_rasterizer/mod.rs
+++ b/gfx/webrender/src/glyph_rasterizer/mod.rs
@@ -1,16 +1,16 @@
 /* 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 api::{ColorF, ColorU, DevicePoint};
 use api::{FontInstanceFlags, FontInstancePlatformOptions};
 use api::{FontKey, FontRenderMode, FontTemplate, FontVariation};
-use api::{GlyphIndex, GlyphDimensions};
+use api::{GlyphIndex, GlyphDimensions, SyntheticItalics};
 use api::{LayoutPoint, LayoutToWorldTransform, WorldPoint};
 use app_units::Au;
 use euclid::approxeq::ApproxEq;
 use internal_types::ResourceCacheError;
 use platform::font::FontContext;
 use rayon::ThreadPool;
 use std::cmp;
 use std::hash::{Hash, Hasher};
@@ -106,17 +106,18 @@ impl FontTransform {
         )
     }
 
     #[allow(dead_code)]
     pub fn invert_scale(&self, x_scale: f64, y_scale: f64) -> Self {
         self.pre_scale(x_scale.recip() as f32, y_scale.recip() as f32)
     }
 
-    pub fn synthesize_italics(&self, skew_factor: f32) -> Self {
+    pub fn synthesize_italics(&self, angle: SyntheticItalics) -> Self {
+        let skew_factor = angle.to_skew();
         FontTransform::new(
             self.scale_x,
             self.skew_x - self.scale_x * skew_factor,
             self.skew_y,
             self.scale_y - self.skew_y * skew_factor,
         )
     }
 
@@ -171,43 +172,46 @@ pub struct FontInstance {
     // can't store as a f32 due to use of this type as a hash key.
     // TODO(gw): Perhaps consider having LogicalAu and DeviceAu
     //           or something similar to that.
     pub size: Au,
     pub color: ColorU,
     pub bg_color: ColorU,
     pub render_mode: FontRenderMode,
     pub flags: FontInstanceFlags,
+    pub synthetic_italics: SyntheticItalics,
     pub platform_options: Option<FontInstancePlatformOptions>,
     pub variations: Vec<FontVariation>,
     pub transform: FontTransform,
 }
 
 impl FontInstance {
     pub fn new(
         font_key: FontKey,
         size: Au,
         color: ColorF,
         bg_color: ColorU,
         render_mode: FontRenderMode,
         flags: FontInstanceFlags,
+        synthetic_italics: SyntheticItalics,
         platform_options: Option<FontInstancePlatformOptions>,
         variations: Vec<FontVariation>,
     ) -> Self {
         // If a background color is enabled, it only makes sense
         // for it to be completely opaque.
         debug_assert!(bg_color.a == 0 || bg_color.a == 255);
 
         FontInstance {
             font_key,
             size,
             color: color.into(),
             bg_color,
             render_mode,
             flags,
+            synthetic_italics,
             platform_options,
             variations,
             transform: FontTransform::identity(),
         }
     }
 
     pub fn get_alpha_glyph_format(&self) -> GlyphFormat {
         if self.transform.is_identity() { GlyphFormat::Alpha } else { GlyphFormat::TransformedAlpha }
@@ -704,16 +708,17 @@ mod test_glyph_rasterizer {
 
         let font = FontInstance::new(
             font_key,
             Au::from_px(32),
             ColorF::new(0.0, 0.0, 0.0, 1.0),
             ColorU::new(0, 0, 0, 0),
             FontRenderMode::Subpixel,
             Default::default(),
+            Default::default(),
             None,
             Vec::new(),
         );
         let subpx_dir = font.get_subpx_dir();
 
         let mut glyph_keys = Vec::with_capacity(200);
         for i in 0 .. 200 {
             glyph_keys.push(GlyphKey::new(
--- a/gfx/webrender/src/platform/macos/font.rs
+++ b/gfx/webrender/src/platform/macos/font.rs
@@ -265,19 +265,16 @@ fn new_ct_font_with_variations(cg_font: 
     }
 }
 
 fn is_bitmap_font(ct_font: &CTFont) -> bool {
     let traits = ct_font.symbolic_traits();
     (traits & kCTFontColorGlyphsTrait) != 0
 }
 
-// Skew factor matching Gecko/CG.
-const OBLIQUE_SKEW_FACTOR: f32 = 0.25;
-
 impl FontContext {
     pub fn new() -> Result<FontContext, ResourceCacheError> {
         debug!("Test for subpixel AA support: {}", supports_subpixel_aa());
 
         // Force CG to use sRGB color space to gamma correct.
         let contrast = 0.0;
         let gamma = 0.0;
 
@@ -362,32 +359,32 @@ impl FontContext {
         font: &FontInstance,
         key: &GlyphKey,
     ) -> Option<GlyphDimensions> {
         self.get_ct_font(font.font_key, font.size, &font.variations)
             .and_then(|ref ct_font| {
                 let glyph = key.index as CGGlyph;
                 let bitmap = is_bitmap_font(ct_font);
                 let (x_offset, y_offset) = if bitmap { (0.0, 0.0) } else { font.get_subpx_offset(key) };
-                let transform = if font.flags.intersects(FontInstanceFlags::SYNTHETIC_ITALICS |
-                                                         FontInstanceFlags::TRANSPOSE |
+                let transform = if font.synthetic_italics.is_enabled() ||
+                                   font.flags.intersects(FontInstanceFlags::TRANSPOSE |
                                                          FontInstanceFlags::FLIP_X |
                                                          FontInstanceFlags::FLIP_Y) {
                     let mut shape = FontTransform::identity();
                     if font.flags.contains(FontInstanceFlags::FLIP_X) {
                         shape = shape.flip_x();
                     }
                     if font.flags.contains(FontInstanceFlags::FLIP_Y) {
                         shape = shape.flip_y();
                     }
                     if font.flags.contains(FontInstanceFlags::TRANSPOSE) {
                         shape = shape.swap_xy();
                     }
-                    if font.flags.contains(FontInstanceFlags::SYNTHETIC_ITALICS) {
-                        shape = shape.synthesize_italics(OBLIQUE_SKEW_FACTOR);
+                    if font.synthetic_italics.is_enabled() {
+                        shape = shape.synthesize_italics(font.synthetic_italics);
                     }
                     Some(CGAffineTransform {
                         a: shape.scale_x as f64,
                         b: -shape.skew_y as f64,
                         c: -shape.skew_x as f64,
                         d: shape.scale_y as f64,
                         tx: 0.0,
                         ty: 0.0,
@@ -507,18 +504,18 @@ impl FontContext {
             shape = shape.flip_x();
         }
         if font.flags.contains(FontInstanceFlags::FLIP_Y) {
             shape = shape.flip_y();
         }
         if font.flags.contains(FontInstanceFlags::TRANSPOSE) {
             shape = shape.swap_xy();
         }
-        if font.flags.contains(FontInstanceFlags::SYNTHETIC_ITALICS) {
-            shape = shape.synthesize_italics(OBLIQUE_SKEW_FACTOR);
+        if font.synthetic_italics.is_enabled() {
+            shape = shape.synthesize_italics(font.synthetic_italics);
         }
         let transform = if !shape.is_identity() {
             Some(CGAffineTransform {
                 a: shape.scale_x as f64,
                 b: -shape.skew_y as f64,
                 c: -shape.skew_x as f64,
                 d: shape.scale_y as f64,
                 tx: 0.0,
--- a/gfx/webrender/src/platform/unix/font.rs
+++ b/gfx/webrender/src/platform/unix/font.rs
@@ -55,35 +55,39 @@ pub struct FontContext {
 // are not concurrently accessed. In our case, everything is hidden inside
 // a given FontContext so it is safe to move the latter between threads.
 unsafe impl Send for FontContext {}
 
 extern "C" {
     fn FT_GlyphSlot_Embolden(slot: FT_GlyphSlot);
 }
 
-// Skew factor matching Gecko/FreeType.
-const OBLIQUE_SKEW_FACTOR: f32 = 0.2;
-
-fn get_skew_bounds(bottom: i32, top: i32) -> (f32, f32) {
-    let skew_min = ((bottom as f32 + 0.5) * OBLIQUE_SKEW_FACTOR).floor();
-    let skew_max = ((top as f32 - 0.5) * OBLIQUE_SKEW_FACTOR).ceil();
+fn get_skew_bounds(bottom: i32, top: i32, skew_factor: f32) -> (f32, f32) {
+    let skew_min = ((bottom as f32 + 0.5) * skew_factor).floor();
+    let skew_max = ((top as f32 - 0.5) * skew_factor).ceil();
     (skew_min, skew_max)
 }
 
-fn skew_bitmap(bitmap: &[u8], width: usize, height: usize, left: i32, top: i32) -> (Vec<u8>, usize, i32) {
+fn skew_bitmap(
+    bitmap: &[u8],
+    width: usize,
+    height: usize,
+    left: i32,
+    top: i32,
+    skew_factor: f32,
+) -> (Vec<u8>, usize, i32) {
     let stride = width * 4;
     // Calculate the skewed horizontal offsets of the bottom and top of the glyph.
-    let (skew_min, skew_max) = get_skew_bounds(top - height as i32, top);
+    let (skew_min, skew_max) = get_skew_bounds(top - height as i32, top, skew_factor);
     // Allocate enough extra width for the min/max skew offsets.
     let skew_width = width + (skew_max - skew_min) as usize;
     let mut skew_buffer = vec![0u8; skew_width * height * 4];
     for y in 0 .. height {
         // Calculate a skew offset at the vertical center of the current row.
-        let offset = (top as f32 - y as f32 - 0.5) * OBLIQUE_SKEW_FACTOR - skew_min;
+        let offset = (top as f32 - y as f32 - 0.5) * skew_factor - skew_min;
         // Get a blend factor in 0..256 constant across all pixels in the row.
         let blend = (offset.fract() * 256.0) as u32;
         let src_row = y * stride;
         let dest_row = (y * skew_width + offset.floor() as usize) * 4;
         let mut prev_px = [0u32; 4];
         for (src, dest) in
             bitmap[src_row .. src_row + stride].chunks(4).zip(
                 skew_buffer[dest_row .. dest_row + stride].chunks_mut(4)
@@ -238,17 +242,17 @@ impl FontContext {
 
     fn load_glyph(&self, font: &FontInstance, glyph: &GlyphKey) -> Option<(FT_GlyphSlot, f32)> {
         debug_assert!(self.faces.contains_key(&font.font_key));
         let face = self.faces.get(&font.font_key).unwrap();
 
         let mut load_flags = FT_LOAD_DEFAULT;
         let FontInstancePlatformOptions { mut hinting, .. } = font.platform_options.unwrap_or_default();
         // Disable hinting if there is a non-axis-aligned transform.
-        if font.flags.contains(FontInstanceFlags::SYNTHETIC_ITALICS) ||
+        if font.synthetic_italics.is_enabled() ||
            ((font.transform.scale_x != 0.0 || font.transform.scale_y != 0.0) &&
             (font.transform.skew_x != 0.0 || font.transform.skew_y != 0.0)) {
             hinting = FontHinting::None;
         }
         match (hinting, font.render_mode) {
             (FontHinting::None, _) => load_flags |= FT_LOAD_NO_HINTING,
             (FontHinting::Mono, _) => load_flags = FT_LOAD_TARGET_MONO,
             (FontHinting::Light, _) => load_flags = FT_LOAD_TARGET_LIGHT,
@@ -297,18 +301,18 @@ impl FontContext {
                 shape = shape.flip_x();
             }
             if font.flags.contains(FontInstanceFlags::FLIP_Y) {
                 shape = shape.flip_y();
             }
             if font.flags.contains(FontInstanceFlags::TRANSPOSE) {
                 shape = shape.swap_xy();
             }
-            if font.flags.contains(FontInstanceFlags::SYNTHETIC_ITALICS) {
-                shape = shape.synthesize_italics(OBLIQUE_SKEW_FACTOR);
+            if font.synthetic_italics.is_enabled() {
+                shape = shape.synthesize_italics(font.synthetic_italics);
             };
             let mut ft_shape = FT_Matrix {
                 xx: (shape.scale_x * 65536.0) as FT_Fixed,
                 xy: (shape.skew_x * -65536.0) as FT_Fixed,
                 yx: (shape.skew_y * -65536.0) as FT_Fixed,
                 yy: (shape.scale_y * 65536.0) as FT_Fixed,
             };
             unsafe {
@@ -452,18 +456,22 @@ impl FontContext {
                 top = y1.round() as i32;
                 width = (x1.ceil() - x0.floor()) as u32;
                 height = (y1.ceil() - y0.floor()) as u32;
                 advance *= scale;
             }
             // An outline glyph's cbox would have already been transformed inside FT_Load_Glyph,
             // so only handle bitmap glyphs which are not handled by FT_Load_Glyph.
             if format == FT_Glyph_Format::FT_GLYPH_FORMAT_BITMAP {
-                if font.flags.contains(FontInstanceFlags::SYNTHETIC_ITALICS) {
-                    let (skew_min, skew_max) = get_skew_bounds(top - height as i32, top);
+                if font.synthetic_italics.is_enabled() {
+                    let (skew_min, skew_max) = get_skew_bounds(
+                        top - height as i32,
+                        top,
+                        font.synthetic_italics.to_skew(),
+                    );
                     left += skew_min as i32;
                     width += (skew_max - skew_min) as u32;
                 }
                 if font.flags.contains(FontInstanceFlags::TRANSPOSE) {
                     mem::swap(&mut width, &mut height);
                     mem::swap(&mut left, &mut top);
                     left -= width as i32;
                     top += height as i32;
@@ -738,19 +746,25 @@ impl FontContext {
                 _ => panic!("Unsupported mode"),
             }
             src_row = unsafe { src_row.offset(bitmap.pitch as isize) };
             dest = row_end;
         }
 
         match format {
             FT_Glyph_Format::FT_GLYPH_FORMAT_BITMAP => {
-                if font.flags.contains(FontInstanceFlags::SYNTHETIC_ITALICS) {
-                    let (skew_buffer, skew_width, skew_left) =
-                        skew_bitmap(&final_buffer, actual_width, actual_height, left, top);
+                if font.synthetic_italics.is_enabled() {
+                    let (skew_buffer, skew_width, skew_left) = skew_bitmap(
+                        &final_buffer,
+                        actual_width,
+                        actual_height,
+                        left,
+                        top,
+                        font.synthetic_italics.to_skew(),
+                    );
                     final_buffer = skew_buffer;
                     actual_width = skew_width;
                     left = skew_left;
                 }
                 if font.flags.contains(FontInstanceFlags::TRANSPOSE) {
                     final_buffer = transpose_bitmap(&final_buffer, actual_width, actual_height);
                     mem::swap(&mut actual_width, &mut actual_height);
                     mem::swap(&mut left, &mut top);
--- a/gfx/webrender/src/platform/windows/font.rs
+++ b/gfx/webrender/src/platform/windows/font.rs
@@ -92,19 +92,16 @@ fn dwrite_render_mode(
 
 fn is_bitmap_font(font: &FontInstance) -> bool {
     // If bitmaps are requested, then treat as a bitmap font to disable transforms.
     // If mono AA is requested, let that take priority over using bitmaps.
     font.render_mode != FontRenderMode::Mono &&
         font.flags.contains(FontInstanceFlags::EMBEDDED_BITMAPS)
 }
 
-// Skew factor matching Gecko/DWrite.
-const OBLIQUE_SKEW_FACTOR: f32 = 0.3;
-
 impl FontContext {
     pub fn new() -> Result<FontContext, ResourceCacheError> {
         // These are the default values we use in Gecko.
         // We use a gamma value of 2.3 for gdi fonts
         // TODO: Fetch this data from Gecko itself.
         cfg_if! {
             if #[cfg(not(feature = "pathfinder"))] {
                 const CONTRAST: f32 = 1.0;
@@ -252,32 +249,32 @@ impl FontContext {
 
     pub fn get_glyph_dimensions(
         &mut self,
         font: &FontInstance,
         key: &GlyphKey,
     ) -> Option<GlyphDimensions> {
         let size = font.size.to_f32_px();
         let bitmaps = is_bitmap_font(font);
-        let transform = if font.flags.intersects(FontInstanceFlags::SYNTHETIC_ITALICS |
-                                                 FontInstanceFlags::TRANSPOSE |
+        let transform = if font.synthetic_italics.is_enabled() ||
+                           font.flags.intersects(FontInstanceFlags::TRANSPOSE |
                                                  FontInstanceFlags::FLIP_X |
                                                  FontInstanceFlags::FLIP_Y) {
             let mut shape = FontTransform::identity();
             if font.flags.contains(FontInstanceFlags::FLIP_X) {
                 shape = shape.flip_x();
             }
             if font.flags.contains(FontInstanceFlags::FLIP_Y) {
                 shape = shape.flip_y();
             }
             if font.flags.contains(FontInstanceFlags::TRANSPOSE) {
                 shape = shape.swap_xy();
             }
-            if font.flags.contains(FontInstanceFlags::SYNTHETIC_ITALICS) {
-                shape = shape.synthesize_italics(OBLIQUE_SKEW_FACTOR);
+            if font.synthetic_italics.is_enabled() {
+                shape = shape.synthesize_italics(font.synthetic_italics);
             }
             Some(dwrote::DWRITE_MATRIX {
                 m11: shape.scale_x,
                 m12: shape.skew_y,
                 m21: shape.skew_x,
                 m22: shape.scale_y,
                 dx: 0.0,
                 dy: 0.0,
@@ -398,18 +395,18 @@ impl FontContext {
             shape = shape.flip_x();
         }
         if font.flags.contains(FontInstanceFlags::FLIP_Y) {
             shape = shape.flip_y();
         }
         if font.flags.contains(FontInstanceFlags::TRANSPOSE) {
             shape = shape.swap_xy();
         }
-        if font.flags.contains(FontInstanceFlags::SYNTHETIC_ITALICS) {
-            shape = shape.synthesize_italics(OBLIQUE_SKEW_FACTOR);
+        if font.synthetic_italics.is_enabled() {
+            shape = shape.synthesize_italics(font.synthetic_italics);
         }
         let transform = if !shape.is_identity() || (x_offset, y_offset) != (0.0, 0.0) {
             Some(dwrote::DWRITE_MATRIX {
                 m11: shape.scale_x,
                 m12: shape.skew_y,
                 m21: shape.skew_x,
                 m22: shape.scale_y,
                 dx: x_offset as f32,
--- a/gfx/webrender/src/prim_store.rs
+++ b/gfx/webrender/src/prim_store.rs
@@ -23,17 +23,17 @@ use gpu_cache::{GpuBlockData, GpuCache, 
 use gpu_types::BrushFlags;
 use image::{for_each_tile, for_each_repetition};
 use picture::{PictureCompositeMode, PictureId, PicturePrimitive};
 #[cfg(debug_assertions)]
 use render_backend::FrameId;
 use render_task::{BlitSource, RenderTask, RenderTaskCacheKey};
 use render_task::{RenderTaskCacheKeyKind, RenderTaskId, RenderTaskCacheEntryHandle};
 use renderer::{MAX_VERTEX_TEXTURE_WIDTH};
-use resource_cache::{ImageProperties, ImageRequest};
+use resource_cache::{ImageProperties, ImageRequest, ResourceCache};
 use scene::SceneProperties;
 use segment::SegmentBuilder;
 use std::{mem, usize};
 use std::sync::Arc;
 use util::{MatrixHelpers, WorldToLayoutFastTransform, calculate_screen_bounding_rect};
 use util::{pack_as_float, recycle_vec};
 
 
@@ -323,20 +323,27 @@ pub enum BrushKind {
         visible_tiles: Vec<VisibleGradientTile>,
     },
     Border {
         source: BorderSource,
     },
 }
 
 impl BrushKind {
-    fn supports_segments(&self) -> bool {
+    fn supports_segments(&self, resource_cache: &ResourceCache) -> bool {
         match *self {
+            BrushKind::Image { ref request, .. } => {
+                // tiled images don't support segmentation
+                resource_cache
+                    .get_image_properties(request.key)
+                    .and_then(|properties| properties.tiling)
+                    .is_none()
+            }
+
             BrushKind::Solid { .. } |
-            BrushKind::Image { .. } |
             BrushKind::YuvImage { .. } |
             BrushKind::RadialGradient { .. } |
             BrushKind::Border { .. } |
             BrushKind::LinearGradient { .. } => true,
 
             // TODO(gw): Allow batch.rs to add segment instances
             //           for Picture primitives.
             BrushKind::Picture { .. } => false,
@@ -1999,17 +2006,17 @@ impl PrimitiveStore {
                 // clips list if we haven't already determined the mask kind.
                 if segment_desc.clip_mask_kind != BrushClipMaskKind::Unknown {
                     return;
                 }
             }
             None => {
                 // If no segment descriptor built yet, see if it is a brush
                 // type that wants to be segmented.
-                if !brush.kind.supports_segments() {
+                if !brush.kind.supports_segments(frame_state.resource_cache) {
                     return;
                 }
             }
         }
 
         // If the brush is small, we generally want to skip building segments
         // and just draw it as a single primitive with clip mask. However,
         // if the clips are purely rectangles that have no per-fragment
--- a/gfx/webrender/src/resource_cache.rs
+++ b/gfx/webrender/src/resource_cache.rs
@@ -446,25 +446,27 @@ impl ResourceCache {
         options: Option<FontInstanceOptions>,
         platform_options: Option<FontInstancePlatformOptions>,
         variations: Vec<FontVariation>,
     ) {
         let FontInstanceOptions {
             render_mode,
             flags,
             bg_color,
+            synthetic_italics,
             ..
         } = options.unwrap_or_default();
         let instance = FontInstance::new(
             font_key,
             glyph_size,
             ColorF::new(0.0, 0.0, 0.0, 1.0),
             bg_color,
             render_mode,
             flags,
+            synthetic_italics,
             platform_options,
             variations,
         );
         self.resources.font_instances
             .write()
             .unwrap()
             .insert(instance_key, instance);
     }
--- a/gfx/webrender_api/src/font.rs
+++ b/gfx/webrender_api/src/font.rs
@@ -150,17 +150,16 @@ impl Default for GlyphOptions {
     }
 }
 
 bitflags! {
     #[repr(C)]
     #[derive(Deserialize, Serialize)]
     pub struct FontInstanceFlags: u32 {
         // Common flags
-        const SYNTHETIC_ITALICS = 1 << 0;
         const SYNTHETIC_BOLD    = 1 << 1;
         const EMBEDDED_BITMAPS  = 1 << 2;
         const SUBPIXEL_BGR      = 1 << 3;
         const TRANSPOSE         = 1 << 4;
         const FLIP_X            = 1 << 5;
         const FLIP_Y            = 1 << 6;
         const SUBPIXEL_POSITION = 1 << 7;
 
@@ -194,31 +193,78 @@ impl Default for FontInstanceFlags {
     fn default() -> FontInstanceFlags {
         FontInstanceFlags::SUBPIXEL_POSITION
     }
 }
 
 
 #[repr(C)]
 #[derive(Clone, Copy, Debug, Deserialize, Hash, Eq, PartialEq, PartialOrd, Ord, Serialize)]
+pub struct SyntheticItalics {
+    // Angle in degrees (-90..90) for synthetic italics in 8.8 fixed-point.
+    pub angle: i16,
+}
+
+impl SyntheticItalics {
+    pub const ANGLE_SCALE: f32 = 256.0;
+
+    pub fn from_degrees(degrees: f32) -> Self {
+        SyntheticItalics { angle: (degrees.max(-89.0).min(89.0) * Self::ANGLE_SCALE) as i16 }
+    }
+
+    pub fn to_degrees(&self) -> f32 {
+        self.angle as f32 / Self::ANGLE_SCALE
+    }
+
+    pub fn to_radians(&self) -> f32 {
+        self.to_degrees().to_radians()
+    }
+
+    pub fn to_skew(&self) -> f32 {
+        self.to_radians().tan()
+    }
+
+    pub fn enabled() -> Self {
+        Self::from_degrees(14.0)
+    }
+
+    pub fn disabled() -> Self {
+        SyntheticItalics { angle: 0 }
+    }
+
+    pub fn is_enabled(&self) -> bool {
+        self.angle != 0
+    }
+}
+
+impl Default for SyntheticItalics {
+    fn default() -> Self {
+        SyntheticItalics::disabled()
+    }
+}
+
+#[repr(C)]
+#[derive(Clone, Copy, Debug, Deserialize, Hash, Eq, PartialEq, PartialOrd, Ord, Serialize)]
 pub struct FontInstanceOptions {
     pub render_mode: FontRenderMode,
     pub flags: FontInstanceFlags,
     /// When bg_color.a is != 0 and render_mode is FontRenderMode::Subpixel,
     /// the text will be rendered with bg_color.r/g/b as an opaque estimated
     /// background color.
     pub bg_color: ColorU,
+    pub synthetic_italics: SyntheticItalics,
 }
 
 impl Default for FontInstanceOptions {
     fn default() -> FontInstanceOptions {
         FontInstanceOptions {
             render_mode: FontRenderMode::Subpixel,
             flags: Default::default(),
             bg_color: ColorU::new(0, 0, 0, 0),
+            synthetic_italics: SyntheticItalics::disabled(),
         }
     }
 }
 
 #[cfg(target_os = "windows")]
 #[repr(C)]
 #[derive(Clone, Copy, Debug, Deserialize, Hash, Eq, PartialEq, PartialOrd, Ord, Serialize)]
 pub struct FontInstancePlatformOptions {
--- a/gfx/webrender_bindings/WebRenderTypes.h
+++ b/gfx/webrender_bindings/WebRenderTypes.h
@@ -799,12 +799,18 @@ static inline wr::WrYuvColorSpace ToWrYu
     case YUVColorSpace::BT709:
       return wr::WrYuvColorSpace::Rec709;
     default:
       MOZ_ASSERT_UNREACHABLE("Tried to convert invalid YUVColorSpace.");
   }
   return wr::WrYuvColorSpace::Rec601;
 }
 
+static inline wr::SyntheticItalics DegreesToSyntheticItalics(float aDegrees) {
+  wr::SyntheticItalics synthetic_italics;
+  synthetic_italics.angle = int16_t(std::min(std::max(aDegrees, -89.0f), 89.0f) * 256.0f);
+  return synthetic_italics;
+}
+
 } // namespace wr
 } // namespace mozilla
 
 #endif /* GFX_WEBRENDERTYPES_H */
--- a/gfx/webrender_bindings/revision.txt
+++ b/gfx/webrender_bindings/revision.txt
@@ -1,1 +1,1 @@
-cdfaaeb5f74e416f39af1081c9a676c752d23896
+34a498f7e46c385a189299e7369e204e1cb2060c
--- a/gfx/webrender_bindings/webrender_ffi.h
+++ b/gfx/webrender_bindings/webrender_ffi.h
@@ -62,17 +62,16 @@ struct FontInstanceFlags {
   }
 
   FontInstanceFlags operator&(uint32_t aBits) {
     FontInstanceFlags flags = { bits & aBits };
     return flags;
   }
 
   enum : uint32_t {
-    SYNTHETIC_ITALICS = 1 << 0,
     SYNTHETIC_BOLD    = 1 << 1,
     EMBEDDED_BITMAPS  = 1 << 2,
     SUBPIXEL_BGR      = 1 << 3,
     TRANSPOSE         = 1 << 4,
     FLIP_X            = 1 << 5,
     FLIP_Y            = 1 << 6,
     SUBPIXEL_POSITION = 1 << 7,
 
--- a/gfx/webrender_bindings/webrender_ffi_generated.h
+++ b/gfx/webrender_bindings/webrender_ffi_generated.h
@@ -578,28 +578,16 @@ struct BorderSide {
   BorderStyle style;
 
   bool operator==(const BorderSide& aOther) const {
     return color == aOther.color &&
            style == aOther.style;
   }
 };
 
-using LayoutPoint = TypedPoint2D<float, LayoutPixel>;
-
-struct GradientStop {
-  float offset;
-  ColorF color;
-
-  bool operator==(const GradientStop& aOther) const {
-    return offset == aOther.offset &&
-           color == aOther.color;
-  }
-};
-
 template<typename T, typename U>
 struct TypedSideOffsets2D {
   T top;
   T right;
   T bottom;
   T left;
 
   bool operator==(const TypedSideOffsets2D& aOther) const {
@@ -609,16 +597,28 @@ struct TypedSideOffsets2D {
            left == aOther.left;
   }
 };
 
 // The default side offset type with no unit.
 template<typename T>
 using SideOffsets2D = TypedSideOffsets2D<T, UnknownUnit>;
 
+using LayoutPoint = TypedPoint2D<float, LayoutPixel>;
+
+struct GradientStop {
+  float offset;
+  ColorF color;
+
+  bool operator==(const GradientStop& aOther) const {
+    return offset == aOther.offset &&
+           color == aOther.color;
+  }
+};
+
 struct Shadow {
   LayoutVector2D offset;
   ColorF color;
   float blur_radius;
 
   bool operator==(const Shadow& aOther) const {
     return offset == aOther.offset &&
            color == aOther.color &&
@@ -883,28 +883,38 @@ struct ColorU {
   bool operator==(const ColorU& aOther) const {
     return r == aOther.r &&
            g == aOther.g &&
            b == aOther.b &&
            a == aOther.a;
   }
 };
 
+struct SyntheticItalics {
+  int16_t angle;
+
+  bool operator==(const SyntheticItalics& aOther) const {
+    return angle == aOther.angle;
+  }
+};
+
 struct FontInstanceOptions {
   FontRenderMode render_mode;
   FontInstanceFlags flags;
   // When bg_color.a is != 0 and render_mode is FontRenderMode::Subpixel,
   // the text will be rendered with bg_color.r/g/b as an opaque estimated
   // background color.
   ColorU bg_color;
+  SyntheticItalics synthetic_italics;
 
   bool operator==(const FontInstanceOptions& aOther) const {
     return render_mode == aOther.render_mode &&
            flags == aOther.flags &&
-           bg_color == aOther.bg_color;
+           bg_color == aOther.bg_color &&
+           synthetic_italics == aOther.synthetic_italics;
   }
 };
 
 #if defined(XP_WIN)
 struct FontInstancePlatformOptions {
   uint32_t unused;
 
   bool operator==(const FontInstancePlatformOptions& aOther) const {
--- a/gfx/wrench/src/wrench.rs
+++ b/gfx/wrench/src/wrench.rs
@@ -455,27 +455,29 @@ impl Wrench {
     }
 
     pub fn add_font_instance(&mut self,
         font_key: FontKey,
         size: Au,
         flags: FontInstanceFlags,
         render_mode: Option<FontRenderMode>,
         bg_color: Option<ColorU>,
+        synthetic_italics: SyntheticItalics,
     ) -> FontInstanceKey {
         let key = self.api.generate_font_instance_key();
         let mut txn = Transaction::new();
         let mut options: FontInstanceOptions = Default::default();
         options.flags |= flags;
         if let Some(render_mode) = render_mode {
             options.render_mode = render_mode;
         }
         if let Some(bg_color) = bg_color {
             options.bg_color = bg_color;
         }
+        options.synthetic_italics = synthetic_italics;
         txn.add_font_instance(key, font_key, size, Some(options), None, Vec::new());
         self.api.update_resources(txn.resource_updates);
         key
     }
 
     #[allow(dead_code)]
     pub fn delete_font_instance(&mut self, key: FontInstanceKey) {
         let mut txn = Transaction::new();
--- a/gfx/wrench/src/yaml_frame_reader.rs
+++ b/gfx/wrench/src/yaml_frame_reader.rs
@@ -194,17 +194,17 @@ pub struct YamlFrameReader {
 
     /// A HashMap of offsets which specify what scroll offsets particular
     /// scroll layers should be initialized with.
     scroll_offsets: HashMap<ExternalScrollId, LayoutPoint>,
 
     image_map: HashMap<(PathBuf, Option<i64>), (ImageKey, LayoutSize)>,
 
     fonts: HashMap<FontDescriptor, FontKey>,
-    font_instances: HashMap<(FontKey, Au, FontInstanceFlags, Option<ColorU>), FontInstanceKey>,
+    font_instances: HashMap<(FontKey, Au, FontInstanceFlags, Option<ColorU>, SyntheticItalics), FontInstanceKey>,
     font_render_mode: Option<FontRenderMode>,
     allow_mipmaps: bool,
 
     /// A HashMap that allows specifying a numeric id for clip and clip chains in YAML
     /// and having each of those ids correspond to a unique ClipId.
     clip_id_map: HashMap<u64, ClipId>,
 }
 
@@ -558,29 +558,31 @@ impl YamlFrameReader {
     }
 
     fn get_or_create_font_instance(
         &mut self,
         font_key: FontKey,
         size: Au,
         bg_color: Option<ColorU>,
         flags: FontInstanceFlags,
+        synthetic_italics: SyntheticItalics,
         wrench: &mut Wrench,
     ) -> FontInstanceKey {
         let font_render_mode = self.font_render_mode;
 
         *self.font_instances
-            .entry((font_key, size, flags, bg_color))
+            .entry((font_key, size, flags, bg_color, synthetic_italics))
             .or_insert_with(|| {
                 wrench.add_font_instance(
                     font_key,
                     size,
                     flags,
                     font_render_mode,
                     bg_color,
+                    synthetic_italics,
                 )
             })
     }
 
     fn to_image_mask(&mut self, item: &Yaml, wrench: &mut Wrench) -> Option<ImageMask> {
         if item.as_hash().is_none() {
             return None;
         }
@@ -1129,21 +1131,25 @@ impl YamlFrameReader {
         dl: &mut DisplayListBuilder,
         wrench: &mut Wrench,
         item: &Yaml,
         info: &mut LayoutPrimitiveInfo,
     ) {
         let size = item["size"].as_pt_to_au().unwrap_or(Au::from_f32_px(16.0));
         let color = item["color"].as_colorf().unwrap_or(*BLACK_COLOR);
         let bg_color = item["bg-color"].as_colorf().map(|c| c.into());
+        let synthetic_italics = if let Some(angle) = item["synthetic-italics"].as_f32() {
+            SyntheticItalics::from_degrees(angle)
+        } else if item["synthetic-italics"].as_bool().unwrap_or(false) {
+            SyntheticItalics::enabled()
+        } else {
+            SyntheticItalics::disabled()
+        };
 
         let mut flags = FontInstanceFlags::empty();
-        if item["synthetic-italics"].as_bool().unwrap_or(false) {
-            flags |= FontInstanceFlags::SYNTHETIC_ITALICS;
-        }
         if item["synthetic-bold"].as_bool().unwrap_or(false) {
             flags |= FontInstanceFlags::SYNTHETIC_BOLD;
         }
         if item["embedded-bitmaps"].as_bool().unwrap_or(false) {
             flags |= FontInstanceFlags::EMBEDDED_BITMAPS;
         }
         if item["transpose"].as_bool().unwrap_or(false) {
             flags |= FontInstanceFlags::TRANSPOSE;
@@ -1161,16 +1167,17 @@ impl YamlFrameReader {
         );
 
         let desc = FontDescriptor::from_yaml(item, &self.aux_dir);
         let font_key = self.get_or_create_font(desc, wrench);
         let font_instance_key = self.get_or_create_font_instance(font_key,
                                                                  size,
                                                                  bg_color,
                                                                  flags,
+                                                                 synthetic_italics,
                                                                  wrench);
 
         assert!(
             !(item["glyphs"].is_badvalue() && item["text"].is_badvalue()),
             "text item had neither text nor glyphs!"
         );
 
         let (glyphs, rect) = if item["text"].is_badvalue() {
--- a/js/src/jit/AliasAnalysis.cpp
+++ b/js/src/jit/AliasAnalysis.cpp
@@ -3,17 +3,16 @@
  * 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 "jit/AliasAnalysis.h"
 
 #include <stdio.h>
 
-#include "jit/AliasAnalysisShared.h"
 #include "jit/Ion.h"
 #include "jit/IonBuilder.h"
 #include "jit/JitSpewer.h"
 #include "jit/MIR.h"
 #include "jit/MIRGraph.h"
 
 #include "vm/Printer.h"
 
@@ -50,20 +49,183 @@ class LoopAliasInfo : public TempObject
     MInstruction* firstInstruction() const {
         return *loopHeader_->begin();
     }
 };
 
 } // namespace jit
 } // namespace js
 
-AliasAnalysis::AliasAnalysis(MIRGenerator* mir, MIRGraph& graph)
-  : AliasAnalysisShared(mir, graph),
-    loop_(nullptr)
+void
+AliasAnalysis::spewDependencyList()
+{
+#ifdef JS_JITSPEW
+    if (JitSpewEnabled(JitSpew_AliasSummaries)) {
+        Fprinter &print = JitSpewPrinter();
+        JitSpewHeader(JitSpew_AliasSummaries);
+        print.printf("Dependency list for other passes:\n");
+
+        for (ReversePostorderIterator block(graph_.rpoBegin()); block != graph_.rpoEnd(); block++) {
+            for (MInstructionIterator def(block->begin()), end(block->begin(block->lastIns()));
+                 def != end;
+                 ++def)
+            {
+                if (!def->dependency())
+                    continue;
+                if (!def->getAliasSet().isLoad())
+                    continue;
+
+                JitSpewHeader(JitSpew_AliasSummaries);
+                print.printf(" ");
+                MDefinition::PrintOpcodeName(print, def->op());
+                print.printf("%d marked depending on ", def->id());
+                MDefinition::PrintOpcodeName(print, def->dependency()->op());
+                print.printf("%d\n", def->dependency()->id());
+            }
+        }
+    }
+#endif
+}
+
+// Unwrap any slot or element to its corresponding object.
+static inline const MDefinition*
+MaybeUnwrap(const MDefinition* object)
+{
+
+    while (object->isSlots() || object->isElements() || object->isConvertElementsToDoubles()) {
+        MOZ_ASSERT(object->numOperands() == 1);
+        object = object->getOperand(0);
+    }
+
+    if (object->isTypedArrayElements())
+        return nullptr;
+    if (object->isTypedObjectElements())
+        return nullptr;
+    if (object->isConstantElements())
+        return nullptr;
+
+    return object;
+}
+
+// Get the object of any load/store. Returns nullptr if not tied to
+// an object.
+static inline const MDefinition*
+GetObject(const MDefinition* ins)
 {
+    if (!ins->getAliasSet().isStore() && !ins->getAliasSet().isLoad())
+        return nullptr;
+
+    // Note: only return the object if that objects owns that property.
+    // I.e. the poperty isn't on the prototype chain.
+    const MDefinition* object = nullptr;
+    switch (ins->op()) {
+      case MDefinition::Opcode::InitializedLength:
+      case MDefinition::Opcode::LoadElement:
+      case MDefinition::Opcode::LoadUnboxedScalar:
+      case MDefinition::Opcode::LoadUnboxedObjectOrNull:
+      case MDefinition::Opcode::LoadUnboxedString:
+      case MDefinition::Opcode::StoreElement:
+      case MDefinition::Opcode::StoreUnboxedObjectOrNull:
+      case MDefinition::Opcode::StoreUnboxedString:
+      case MDefinition::Opcode::StoreUnboxedScalar:
+      case MDefinition::Opcode::SetInitializedLength:
+      case MDefinition::Opcode::ArrayLength:
+      case MDefinition::Opcode::SetArrayLength:
+      case MDefinition::Opcode::StoreElementHole:
+      case MDefinition::Opcode::FallibleStoreElement:
+      case MDefinition::Opcode::TypedObjectDescr:
+      case MDefinition::Opcode::Slots:
+      case MDefinition::Opcode::Elements:
+      case MDefinition::Opcode::MaybeCopyElementsForWrite:
+      case MDefinition::Opcode::MaybeToDoubleElement:
+      case MDefinition::Opcode::TypedArrayLength:
+      case MDefinition::Opcode::SetTypedObjectOffset:
+      case MDefinition::Opcode::SetDisjointTypedElements:
+      case MDefinition::Opcode::ArrayPopShift:
+      case MDefinition::Opcode::ArrayPush:
+      case MDefinition::Opcode::ArraySlice:
+      case MDefinition::Opcode::LoadTypedArrayElementHole:
+      case MDefinition::Opcode::StoreTypedArrayElementHole:
+      case MDefinition::Opcode::LoadFixedSlot:
+      case MDefinition::Opcode::LoadFixedSlotAndUnbox:
+      case MDefinition::Opcode::StoreFixedSlot:
+      case MDefinition::Opcode::GetPropertyPolymorphic:
+      case MDefinition::Opcode::SetPropertyPolymorphic:
+      case MDefinition::Opcode::GuardShape:
+      case MDefinition::Opcode::GuardReceiverPolymorphic:
+      case MDefinition::Opcode::GuardObjectGroup:
+      case MDefinition::Opcode::GuardObjectIdentity:
+      case MDefinition::Opcode::GuardUnboxedExpando:
+      case MDefinition::Opcode::LoadUnboxedExpando:
+      case MDefinition::Opcode::LoadSlot:
+      case MDefinition::Opcode::StoreSlot:
+      case MDefinition::Opcode::InArray:
+      case MDefinition::Opcode::LoadElementHole:
+      case MDefinition::Opcode::TypedArrayElements:
+      case MDefinition::Opcode::TypedObjectElements:
+      case MDefinition::Opcode::CopyLexicalEnvironmentObject:
+      case MDefinition::Opcode::IsPackedArray:
+        object = ins->getOperand(0);
+        break;
+      case MDefinition::Opcode::GetPropertyCache:
+      case MDefinition::Opcode::GetDOMProperty:
+      case MDefinition::Opcode::GetDOMMember:
+      case MDefinition::Opcode::Call:
+      case MDefinition::Opcode::Compare:
+      case MDefinition::Opcode::GetArgumentsObjectArg:
+      case MDefinition::Opcode::SetArgumentsObjectArg:
+      case MDefinition::Opcode::GetFrameArgument:
+      case MDefinition::Opcode::SetFrameArgument:
+      case MDefinition::Opcode::CompareExchangeTypedArrayElement:
+      case MDefinition::Opcode::AtomicExchangeTypedArrayElement:
+      case MDefinition::Opcode::AtomicTypedArrayElementBinop:
+      case MDefinition::Opcode::AsmJSLoadHeap:
+      case MDefinition::Opcode::AsmJSStoreHeap:
+      case MDefinition::Opcode::WasmLoadTls:
+      case MDefinition::Opcode::WasmLoad:
+      case MDefinition::Opcode::WasmStore:
+      case MDefinition::Opcode::WasmCompareExchangeHeap:
+      case MDefinition::Opcode::WasmAtomicBinopHeap:
+      case MDefinition::Opcode::WasmAtomicExchangeHeap:
+      case MDefinition::Opcode::WasmLoadGlobalVar:
+      case MDefinition::Opcode::WasmStoreGlobalVar:
+      case MDefinition::Opcode::ArrayJoin:
+        return nullptr;
+      default:
+#ifdef DEBUG
+        // Crash when the default aliasSet is overriden, but when not added in the list above.
+        if (!ins->getAliasSet().isStore() || ins->getAliasSet().flags() != AliasSet::Flag::Any)
+            MOZ_CRASH("Overridden getAliasSet without updating AliasAnalysis GetObject");
+#endif
+
+        return nullptr;
+    }
+
+    MOZ_ASSERT(!ins->getAliasSet().isStore() || ins->getAliasSet().flags() != AliasSet::Flag::Any);
+    object = MaybeUnwrap(object);
+    MOZ_ASSERT_IF(object, object->type() == MIRType::Object);
+    return object;
+}
+
+// Generic comparing if a load aliases a store using TI information.
+MDefinition::AliasType
+AliasAnalysis::genericMightAlias(const MDefinition* load, const MDefinition* store)
+{
+    const MDefinition* loadObject = GetObject(load);
+    const MDefinition* storeObject = GetObject(store);
+    if (!loadObject || !storeObject)
+        return MDefinition::AliasType::MayAlias;
+
+    if (!loadObject->resultTypeSet() || !storeObject->resultTypeSet())
+        return MDefinition::AliasType::MayAlias;
+
+    if (loadObject->resultTypeSet()->objectsIntersect(storeObject->resultTypeSet()))
+        return MDefinition::AliasType::MayAlias;
+
+    return MDefinition::AliasType::NoAlias;
 }
 
 // Whether there might be a path from src to dest, excluding loop backedges. This is
 // approximate and really ought to depend on precomputed reachability information.
 static inline bool
 BlockMightReach(MBasicBlock* src, MBasicBlock* dest)
 {
     while (src->id() <= dest->id()) {
@@ -283,9 +445,9 @@ AliasAnalysis::analyze()
             loop_ = loop_->outer();
         }
     }
 
     spewDependencyList();
 
     MOZ_ASSERT(loop_ == nullptr);
     return true;
-}
+}
\ No newline at end of file
--- a/js/src/jit/AliasAnalysis.h
+++ b/js/src/jit/AliasAnalysis.h
@@ -2,30 +2,78 @@
  * vim: set ts=8 sts=4 et sw=4 tw=99:
  * 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 jit_AliasAnalysis_h
 #define jit_AliasAnalysis_h
 
-#include "jit/AliasAnalysisShared.h"
+
 #include "jit/MIR.h"
 #include "jit/MIRGraph.h"
 
 namespace js {
 namespace jit {
 
 class LoopAliasInfo;
 
-class AliasAnalysis : public AliasAnalysisShared
+class AliasAnalysis
 {
+    MIRGenerator* mir;
+    MIRGraph& graph_;
     LoopAliasInfo* loop_;
 
+    void spewDependencyList();
+
+    TempAllocator& alloc() const {
+        return graph_.alloc();
+    }
+
   public:
-    AliasAnalysis(MIRGenerator* mir, MIRGraph& graph);
-    MOZ_MUST_USE bool analyze() override;
+    AliasAnalysis(MIRGenerator* mir, MIRGraph& graph)
+      :  mir(mir),
+         graph_(graph),
+         loop_(nullptr)
+    {}
+
+    MOZ_MUST_USE bool analyze();
+
+    static MDefinition::AliasType genericMightAlias(const MDefinition* load,
+                                                    const MDefinition* store);
+};
+
+// Iterates over the flags in an AliasSet.
+class AliasSetIterator
+{
+  private:
+    uint32_t flags;
+    unsigned pos;
+
+  public:
+    explicit AliasSetIterator(AliasSet set)
+      : flags(set.flags()), pos(0)
+    {
+        while (flags && (flags & 1) == 0) {
+            flags >>= 1;
+            pos++;
+        }
+    }
+    AliasSetIterator& operator ++(int) {
+        do {
+            flags >>= 1;
+            pos++;
+        } while (flags && (flags & 1) == 0);
+        return *this;
+    }
+    explicit operator bool() const {
+        return !!flags;
+    }
+    unsigned operator*() const {
+        MOZ_ASSERT(pos < AliasSet::NumCategories);
+        return pos;
+    }
 };
 
 } // namespace jit
 } // namespace js
 
 #endif /* jit_AliasAnalysis_h */
deleted file mode 100644
--- a/js/src/jit/AliasAnalysisShared.cpp
+++ /dev/null
@@ -1,185 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- * vim: set ts=8 sts=4 et sw=4 tw=99:
- * 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 "jit/AliasAnalysisShared.h"
-
-#include "jit/MIR.h"
-
-namespace js {
-namespace jit {
-
-void
-AliasAnalysisShared::spewDependencyList()
-{
-#ifdef JS_JITSPEW
-    if (JitSpewEnabled(JitSpew_AliasSummaries)) {
-        Fprinter &print = JitSpewPrinter();
-        JitSpewHeader(JitSpew_AliasSummaries);
-        print.printf("Dependency list for other passes:\n");
-
-        for (ReversePostorderIterator block(graph_.rpoBegin()); block != graph_.rpoEnd(); block++) {
-            for (MInstructionIterator def(block->begin()), end(block->begin(block->lastIns()));
-                 def != end;
-                 ++def)
-            {
-                if (!def->dependency())
-                    continue;
-                if (!def->getAliasSet().isLoad())
-                    continue;
-
-                JitSpewHeader(JitSpew_AliasSummaries);
-                print.printf(" ");
-                MDefinition::PrintOpcodeName(print, def->op());
-                print.printf("%d marked depending on ", def->id());
-                MDefinition::PrintOpcodeName(print, def->dependency()->op());
-                print.printf("%d\n", def->dependency()->id());
-            }
-        }
-    }
-#endif
-}
-
-// Unwrap any slot or element to its corresponding object.
-static inline const MDefinition*
-MaybeUnwrap(const MDefinition* object)
-{
-
-    while (object->isSlots() || object->isElements() || object->isConvertElementsToDoubles()) {
-        MOZ_ASSERT(object->numOperands() == 1);
-        object = object->getOperand(0);
-    }
-
-    if (object->isTypedArrayElements())
-        return nullptr;
-    if (object->isTypedObjectElements())
-        return nullptr;
-    if (object->isConstantElements())
-        return nullptr;
-
-    return object;
-}
-
-// Get the object of any load/store. Returns nullptr if not tied to
-// an object.
-static inline const MDefinition*
-GetObject(const MDefinition* ins)
-{
-    if (!ins->getAliasSet().isStore() && !ins->getAliasSet().isLoad())
-        return nullptr;
-
-    // Note: only return the object if that objects owns that property.
-    // I.e. the poperty isn't on the prototype chain.
-    const MDefinition* object = nullptr;
-    switch (ins->op()) {
-      case MDefinition::Opcode::InitializedLength:
-      case MDefinition::Opcode::LoadElement:
-      case MDefinition::Opcode::LoadUnboxedScalar:
-      case MDefinition::Opcode::LoadUnboxedObjectOrNull:
-      case MDefinition::Opcode::LoadUnboxedString:
-      case MDefinition::Opcode::StoreElement:
-      case MDefinition::Opcode::StoreUnboxedObjectOrNull:
-      case MDefinition::Opcode::StoreUnboxedString:
-      case MDefinition::Opcode::StoreUnboxedScalar:
-      case MDefinition::Opcode::SetInitializedLength:
-      case MDefinition::Opcode::ArrayLength:
-      case MDefinition::Opcode::SetArrayLength:
-      case MDefinition::Opcode::StoreElementHole:
-      case MDefinition::Opcode::FallibleStoreElement:
-      case MDefinition::Opcode::TypedObjectDescr:
-      case MDefinition::Opcode::Slots:
-      case MDefinition::Opcode::Elements:
-      case MDefinition::Opcode::MaybeCopyElementsForWrite:
-      case MDefinition::Opcode::MaybeToDoubleElement:
-      case MDefinition::Opcode::TypedArrayLength:
-      case MDefinition::Opcode::SetTypedObjectOffset:
-      case MDefinition::Opcode::SetDisjointTypedElements:
-      case MDefinition::Opcode::ArrayPopShift:
-      case MDefinition::Opcode::ArrayPush:
-      case MDefinition::Opcode::ArraySlice:
-      case MDefinition::Opcode::LoadTypedArrayElementHole:
-      case MDefinition::Opcode::StoreTypedArrayElementHole:
-      case MDefinition::Opcode::LoadFixedSlot:
-      case MDefinition::Opcode::LoadFixedSlotAndUnbox:
-      case MDefinition::Opcode::StoreFixedSlot:
-      case MDefinition::Opcode::GetPropertyPolymorphic:
-      case MDefinition::Opcode::SetPropertyPolymorphic:
-      case MDefinition::Opcode::GuardShape:
-      case MDefinition::Opcode::GuardReceiverPolymorphic:
-      case MDefinition::Opcode::GuardObjectGroup:
-      case MDefinition::Opcode::GuardObjectIdentity:
-      case MDefinition::Opcode::GuardUnboxedExpando:
-      case MDefinition::Opcode::LoadUnboxedExpando:
-      case MDefinition::Opcode::LoadSlot:
-      case MDefinition::Opcode::StoreSlot:
-      case MDefinition::Opcode::InArray:
-      case MDefinition::Opcode::LoadElementHole:
-      case MDefinition::Opcode::TypedArrayElements:
-      case MDefinition::Opcode::TypedObjectElements:
-      case MDefinition::Opcode::CopyLexicalEnvironmentObject:
-      case MDefinition::Opcode::IsPackedArray:
-        object = ins->getOperand(0);
-        break;
-      case MDefinition::Opcode::GetPropertyCache:
-      case MDefinition::Opcode::GetDOMProperty:
-      case MDefinition::Opcode::GetDOMMember:
-      case MDefinition::Opcode::Call:
-      case MDefinition::Opcode::Compare:
-      case MDefinition::Opcode::GetArgumentsObjectArg:
-      case MDefinition::Opcode::SetArgumentsObjectArg:
-      case MDefinition::Opcode::GetFrameArgument:
-      case MDefinition::Opcode::SetFrameArgument:
-      case MDefinition::Opcode::CompareExchangeTypedArrayElement:
-      case MDefinition::Opcode::AtomicExchangeTypedArrayElement:
-      case MDefinition::Opcode::AtomicTypedArrayElementBinop:
-      case MDefinition::Opcode::AsmJSLoadHeap:
-      case MDefinition::Opcode::AsmJSStoreHeap:
-      case MDefinition::Opcode::WasmLoadTls:
-      case MDefinition::Opcode::WasmLoad:
-      case MDefinition::Opcode::WasmStore:
-      case MDefinition::Opcode::WasmCompareExchangeHeap:
-      case MDefinition::Opcode::WasmAtomicBinopHeap:
-      case MDefinition::Opcode::WasmAtomicExchangeHeap:
-      case MDefinition::Opcode::WasmLoadGlobalVar:
-      case MDefinition::Opcode::WasmStoreGlobalVar:
-      case MDefinition::Opcode::ArrayJoin:
-        return nullptr;
-      default:
-#ifdef DEBUG
-        // Crash when the default aliasSet is overriden, but when not added in the list above.
-        if (!ins->getAliasSet().isStore() || ins->getAliasSet().flags() != AliasSet::Flag::Any)
-            MOZ_CRASH("Overridden getAliasSet without updating AliasAnalysisShared GetObject");
-#endif
-
-        return nullptr;
-    }
-
-    MOZ_ASSERT(!ins->getAliasSet().isStore() || ins->getAliasSet().flags() != AliasSet::Flag::Any);
-    object = MaybeUnwrap(object);
-    MOZ_ASSERT_IF(object, object->type() == MIRType::Object);
-    return object;
-}
-
-// Generic comparing if a load aliases a store using TI information.
-MDefinition::AliasType
-AliasAnalysisShared::genericMightAlias(const MDefinition* load, const MDefinition* store)
-{
-    const MDefinition* loadObject = GetObject(load);
-    const MDefinition* storeObject = GetObject(store);
-    if (!loadObject || !storeObject)
-        return MDefinition::AliasType::MayAlias;
-
-    if (!loadObject->resultTypeSet() || !storeObject->resultTypeSet())
-        return MDefinition::AliasType::MayAlias;
-
-    if (loadObject->resultTypeSet()->objectsIntersect(storeObject->resultTypeSet()))
-        return MDefinition::AliasType::MayAlias;
-
-    return MDefinition::AliasType::NoAlias;
-}
-
-
-} // namespace jit
-} // namespace js
deleted file mode 100644
--- a/js/src/jit/AliasAnalysisShared.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- * vim: set ts=8 sts=4 et sw=4 tw=99:
- * 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 jit_AliasAnalysisShared_h
-#define jit_AliasAnalysisShared_h
-
-#include "jit/MIR.h"
-#include "jit/MIRGraph.h"
-
-namespace js {
-namespace jit {
-
-class MIRGraph;
-
-class AliasAnalysisShared
-{
-  protected:
-    MIRGenerator* mir;
-    MIRGraph& graph_;
-
-  public:
-    AliasAnalysisShared(MIRGenerator* mir, MIRGraph& graph)
-      : mir(mir),
-        graph_(graph)
-    {}
-
-    virtual MOZ_MUST_USE bool analyze() {
-        return true;
-    }
-
-    static MDefinition::AliasType genericMightAlias(const MDefinition* load,
-                                                    const MDefinition* store);
-
-
-  protected:
-    void spewDependencyList();
-
-    TempAllocator& alloc() const {
-        return graph_.alloc();
-    }
-};
-
-// Iterates over the flags in an AliasSet.
-class AliasSetIterator
-{
-  private:
-    uint32_t flags;
-    unsigned pos;
-
-  public:
-    explicit AliasSetIterator(AliasSet set)
-      : flags(set.flags()), pos(0)
-    {
-        while (flags && (flags & 1) == 0) {
-            flags >>= 1;
-            pos++;
-        }
-    }
-    AliasSetIterator& operator ++(int) {
-        do {
-            flags >>= 1;
-            pos++;
-        } while (flags && (flags & 1) == 0);
-        return *this;
-    }
-    explicit operator bool() const {
-        return !!flags;
-    }
-    unsigned operator*() const {
-        MOZ_ASSERT(pos < AliasSet::NumCategories);
-        return pos;
-    }
-};
-
-} // namespace jit
-} // namespace js
-
-#endif /* jit_AliasAnalysisShared_h */
--- a/js/src/jit/IonCacheIRCompiler.cpp
+++ b/js/src/jit/IonCacheIRCompiler.cpp
@@ -26,16 +26,18 @@ using namespace js;
 using namespace js::jit;
 
 using mozilla::DebugOnly;
 using mozilla::Maybe;
 
 namespace js {
 namespace jit {
 
+class AutoSaveLiveRegisters;
+
 // IonCacheIRCompiler compiles CacheIR to IonIC native code.
 class MOZ_RAII IonCacheIRCompiler : public CacheIRCompiler
 {
   public:
     friend class AutoSaveLiveRegisters;
 
     IonCacheIRCompiler(JSContext* cx, const CacheIRWriter& writer, IonIC* ic, IonScript* ionScript,
                        IonICStub* stub, const PropertyTypeCheckInfo* typeCheckInfo, uint32_t stubDataOffset)
@@ -94,17 +96,17 @@ class MOZ_RAII IonCacheIRCompiler : publ
     uint64_t* expandoGenerationStubFieldPtr(uint32_t offset) {
         DebugOnly<uint64_t> generation =
             readStubInt64(offset, StubField::Type::DOMExpandoGeneration);
         uint64_t* ptr = reinterpret_cast<uint64_t*>(stub_->stubDataStart() + offset);
         MOZ_ASSERT(*ptr == generation);
         return ptr;
     }
 
-    void prepareVMCall(MacroAssembler& masm);
+    void prepareVMCall(MacroAssembler& masm, const AutoSaveLiveRegisters&);
     MOZ_MUST_USE bool callVM(MacroAssembler& masm, const VMFunction& fun);
 
     MOZ_MUST_USE bool emitAddAndStoreSlotShared(CacheOp op);
 
     bool needsPostBarrier() const {
         return ic_->asSetPropertyIC()->needsPostBarrier();
     }
 
@@ -298,18 +300,19 @@ GetReturnAddressToIonCode(JSContext* cx)
     void* returnAddr = frame.returnAddress();
 #ifdef DEBUG
     ++frame;
     MOZ_ASSERT(frame.isIonJS());
 #endif
     return returnAddr;
 }
 
+// The AutoSaveLiveRegisters parameter is used to ensure registers were saved
 void
-IonCacheIRCompiler::prepareVMCall(MacroAssembler& masm)
+IonCacheIRCompiler::prepareVMCall(MacroAssembler& masm, const AutoSaveLiveRegisters&)
 {
     uint32_t descriptor = MakeFrameDescriptor(masm.framePushed(), JitFrame_IonJS,
                                               IonICCallFrameLayout::Size());
     pushStubCodePointer();
     masm.Push(Imm32(descriptor));
     masm.Push(ImmPtr(GetReturnAddressToIonCode(cx_)));
 
 #ifdef DEBUG
@@ -1165,17 +1168,17 @@ IonCacheIRCompiler::emitCallProxyGetByVa
     AutoSaveLiveRegisters save(*this);
     AutoOutputRegister output(*this);
 
     Register obj = allocator.useRegister(masm, reader.objOperandId());
     ValueOperand idVal = allocator.useValueRegister(masm, reader.valOperandId());
 
     allocator.discardStack(masm);
 
-    prepareVMCall(masm);
+    prepareVMCall(masm, save);
 
     masm.Push(idVal);
     masm.Push(obj);
 
     if (!callVM(masm, ProxyGetPropertyByValueInfo))
         return false;
 
     masm.storeCallResultValue(output);
@@ -1195,17 +1198,17 @@ IonCacheIRCompiler::emitCallProxyHasProp
     AutoOutputRegister output(*this);
 
     Register obj = allocator.useRegister(masm, reader.objOperandId());
     ValueOperand idVal = allocator.useValueRegister(masm, reader.valOperandId());
     bool hasOwn = reader.readBool();
 
     allocator.discardStack(masm);
 
-    prepareVMCall(masm);
+    prepareVMCall(masm, save);
 
     masm.Push(idVal);
     masm.Push(obj);
 
     if (hasOwn) {
         if (!callVM(masm, ProxyHasOwnInfo))
             return false;
     } else {
@@ -1315,54 +1318,51 @@ IonCacheIRCompiler::emitCallStringSplitR
     AutoOutputRegister output(*this);
 
     Register str = allocator.useRegister(masm, reader.stringOperandId());
     Register sep = allocator.useRegister(masm, reader.stringOperandId());
     ObjectGroup* group = groupStubField(reader.stubOffset());
 
     allocator.discardStack(masm);
 
-    prepareVMCall(masm);
+    prepareVMCall(masm, save);
 
     masm.Push(str);
     masm.Push(sep);
     masm.Push(ImmGCPtr(group));
     masm.Push(Imm32(INT32_MAX));
 
     if (!callVM(masm, StringSplitHelperInfo))
         return false;
 
     masm.storeCallResultValue(output);
     return true;
 }
 
 bool
 IonCacheIRCompiler::emitCompareStringResult()
 {
+    AutoSaveLiveRegisters save(*this);
     AutoOutputRegister output(*this);
 
     Register left = allocator.useRegister(masm, reader.stringOperandId());
     Register right = allocator.useRegister(masm, reader.stringOperandId());
     JSOp op = reader.jsop();
 
     AutoScratchRegisterMaybeOutput scratch(allocator, masm, output);
 
-    FailurePath* failure;
-    if (!addFailurePath(&failure))
-        return false;
-
     allocator.discardStack(masm);
 
     Label slow, done;
     masm.compareStrings(op, left, right, scratch, &slow);
 
     masm.jump(&done);
     masm.bind(&slow);
 
-    prepareVMCall(masm);
+    prepareVMCall(masm, save);
     masm.Push(right);
     masm.Push(left);
 
     if (!callVM(masm, (op == JSOP_EQ || op == JSOP_STRICTEQ) ?
                             StringsEqualInfo :
                             StringsNotEqualInfo))
     {
         return false;
@@ -2182,17 +2182,17 @@ IonCacheIRCompiler::emitCallSetArrayLeng
 {
     AutoSaveLiveRegisters save(*this);
 
     Register obj = allocator.useRegister(masm, reader.objOperandId());
     bool strict = reader.readBool();
     ConstantOrRegister val = allocator.useConstantOrRegister(masm, reader.valOperandId());
 
     allocator.discardStack(masm);
-    prepareVMCall(masm);
+    prepareVMCall(masm, save);
 
     masm.Push(Imm32(strict));
     masm.Push(val);
     masm.Push(obj);
 
     return callVM(masm, SetArrayLengthInfo);
 }
 
@@ -2208,17 +2208,17 @@ IonCacheIRCompiler::emitCallProxySet()
     Register obj = allocator.useRegister(masm, reader.objOperandId());
     ConstantOrRegister val = allocator.useConstantOrRegister(masm, reader.valOperandId());
     jsid id = idStubField(reader.stubOffset());
     bool strict = reader.readBool();
 
     AutoScratchRegister scratch(allocator, masm);
 
     allocator.discardStack(masm);
-    prepareVMCall(masm);
+    prepareVMCall(masm, save);
 
     masm.Push(Imm32(strict));
     masm.Push(val);
     masm.Push(id, scratch);
     masm.Push(obj);
 
     return callVM(masm, ProxySetPropertyInfo);
 }
@@ -2233,17 +2233,17 @@ IonCacheIRCompiler::emitCallProxySetByVa
     AutoSaveLiveRegisters save(*this);
 
     Register obj = allocator.useRegister(masm, reader.objOperandId());
     ConstantOrRegister idVal = allocator.useConstantOrRegister(masm, reader.valOperandId());
     ConstantOrRegister val = allocator.useConstantOrRegister(masm, reader.valOperandId());
     bool strict = reader.readBool();
 
     allocator.discardStack(masm);
-    prepareVMCall(masm);
+    prepareVMCall(masm, save);
 
     masm.Push(Imm32(strict));
     masm.Push(val);
     masm.Push(idVal);
     masm.Push(obj);
 
     return callVM(masm, ProxySetPropertyByValueInfo);
 }
@@ -2254,17 +2254,17 @@ IonCacheIRCompiler::emitMegamorphicSetEl
     AutoSaveLiveRegisters save(*this);
 
     Register obj = allocator.useRegister(masm, reader.objOperandId());
     ConstantOrRegister idVal = allocator.useConstantOrRegister(masm, reader.valOperandId());
     ConstantOrRegister val = allocator.useConstantOrRegister(masm, reader.valOperandId());
     bool strict = reader.readBool();
 
     allocator.discardStack(masm);
-    prepareVMCall(masm);
+    prepareVMCall(masm, save);
 
     masm.Push(Imm32(strict));
     masm.Push(TypedOrValueRegister(MIRType::Object, AnyRegister(obj)));
     masm.Push(val);
     masm.Push(idVal);
     masm.Push(obj);
 
     return callVM(masm, SetObjectElementInfo);
--- a/js/src/moz.build
+++ b/js/src/moz.build
@@ -234,17 +234,16 @@ UNIFIED_SOURCES += [
     'irregexp/RegExpAST.cpp',
     'irregexp/RegExpCharacters.cpp',
     'irregexp/RegExpEngine.cpp',
     'irregexp/RegExpInterpreter.cpp',
     'irregexp/RegExpMacroAssembler.cpp',
     'irregexp/RegExpParser.cpp',
     'irregexp/RegExpStack.cpp',
     'jit/AliasAnalysis.cpp',
-    'jit/AliasAnalysisShared.cpp',
     'jit/AlignmentMaskAnalysis.cpp',
     'jit/BacktrackingAllocator.cpp',
     'jit/Bailouts.cpp',
     'jit/BaselineBailouts.cpp',
     'jit/BaselineCacheIRCompiler.cpp',
     'jit/BaselineCompiler.cpp',
     'jit/BaselineDebugModeOSR.cpp',
     'jit/BaselineFrame.cpp',
--- a/layout/base/PresShell.h
+++ b/layout/base/PresShell.h
@@ -714,17 +714,17 @@ private:
   // The callback for the mReflowContinueTimer timer.
   static void sReflowContinueCallback(nsITimer* aTimer, void* aPresShell);
   bool ScheduleReflowOffTimer();
 
   // Widget notificiations
   void WindowSizeMoveDone() override;
   void SysColorChanged() override { mPresContext->SysColorChanged(); }
   void ThemeChanged() override { mPresContext->ThemeChanged(); }
-  void BackingScaleFactorChanged() override { mPresContext->UIResolutionChanged(); }
+  void BackingScaleFactorChanged() override { mPresContext->UIResolutionChangedSync(); }
   nsIDocument* GetPrimaryContentDocument() override;
 
   void PausePainting() override;
   void ResumePainting() override;
 
   //////////////////////////////////////////////////////////////////////////////
   // Approximate frame visibility tracking implementation.
   //////////////////////////////////////////////////////////////////////////////
--- a/layout/generic/nsImageFrame.cpp
+++ b/layout/generic/nsImageFrame.cpp
@@ -22,16 +22,17 @@
 #include "mozilla/dom/ResponsiveImageSelector.h"
 #include "mozilla/layers/WebRenderLayerManager.h"
 #include "mozilla/MouseEvents.h"
 #include "mozilla/Unused.h"
 
 #include "nsCOMPtr.h"
 #include "nsFontMetrics.h"
 #include "nsIImageLoadingContent.h"
+#include "nsImageLoadingContent.h"
 #include "nsString.h"
 #include "nsPrintfCString.h"
 #include "nsPresContext.h"
 #include "nsIPresShell.h"
 #include "nsGkAtoms.h"
 #include "nsIDocument.h"
 #include "nsContentUtils.h"
 #include "nsCSSAnonBoxes.h"
@@ -946,23 +947,20 @@ nsRect
 nsImageFrame::GetInnerArea() const
 {
   return GetContentRectRelativeToSelf();
 }
 
 Element*
 nsImageFrame::GetMapElement() const
 {
-  nsAutoString usemap;
-  if (mContent->AsElement()->GetAttr(kNameSpaceID_None,
-                                     nsGkAtoms::usemap,
-                                     usemap)) {
-    return mContent->OwnerDoc()->FindImageMap(usemap);
-  }
-  return nullptr;
+  nsCOMPtr<nsIImageLoadingContent> imageLoader = do_QueryInterface(mContent);
+  return imageLoader ?
+    static_cast<nsImageLoadingContent*>(imageLoader.get())->FindImageMap() :
+    nullptr;
 }
 
 // get the offset into the content area of the image where aImg starts if it is a continuation.
 nscoord
 nsImageFrame::GetContinuationOffset() const
 {
   nscoord offset = 0;
   for (nsIFrame *f = GetPrevInFlow(); f; f = f->GetPrevInFlow()) {
--- a/layout/painting/nsDisplayList.cpp
+++ b/layout/painting/nsDisplayList.cpp
@@ -5195,17 +5195,16 @@ nsDisplayCaret::CreateWebRenderCommands(
                       !BackfaceIsHidden(),
                       wr::ToColorF(color));
   }
   return true;
 }
 
 nsDisplayBorder::nsDisplayBorder(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame)
   : nsDisplayItem(aBuilder, aFrame)
-  , mBorderIsEmpty(false)
 {
   MOZ_COUNT_CTOR(nsDisplayBorder);
 
   mBounds = CalculateBounds<nsRect>(*mFrame->StyleBorder());
 }
 
 bool
 nsDisplayBorder::IsInvisibleInRect(const nsRect& aRect) const
@@ -5255,99 +5254,17 @@ nsDisplayBorder::ComputeInvalidationRegi
   }
 }
 
 LayerState
 nsDisplayBorder::GetLayerState(nsDisplayListBuilder* aBuilder,
                                LayerManager* aManager,
                                const ContainerLayerParameters& aParameters)
 {
-  if (!ShouldUseAdvancedLayer(aManager, gfxPrefs::LayersAllowBorderLayers)) {
-    return LAYER_NONE;
-  }
-
-  mBorderIsEmpty = false;
-  nsPoint offset = ToReferenceFrame();
-  Maybe<nsCSSBorderRenderer> br =
-    nsCSSRendering::CreateBorderRenderer(mFrame->PresContext(),
-                                         nullptr,
-                                         mFrame,
-                                         nsRect(),
-                                         nsRect(offset, mFrame->GetSize()),
-                                         mFrame->Style(),
-                                         &mBorderIsEmpty,
-                                         mFrame->GetSkipSides());
-
-  mBorderRenderer = Nothing();
-  mBorderImageRenderer = Nothing();
-  if (!br) {
-    if (mBorderIsEmpty) {
-      return LAYER_ACTIVE;
-    }
-    return LAYER_NONE;
-  }
-
-  if (!br->AllBordersSolid()) {
-    return LAYER_NONE;
-  }
-
-  // We don't support this yet as we don't copy the values to
-  // the layer, and BasicBorderLayer doesn't support it yet.
-  if (!br->mNoBorderRadius) {
-    return LAYER_NONE;
-  }
-
-  // We copy these values correctly to the layer, but BasicBorderLayer
-  // won't render them
-  if (!br->AreBorderSideFinalStylesSame(eSideBitsAll) ||
-      !br->AllBordersSameWidth()) {
-    return LAYER_NONE;
-  }
-
-  NS_FOR_CSS_SIDES(i) {
-    if (br->mBorderStyles[i] == NS_STYLE_BORDER_STYLE_SOLID) {
-      mColors[i] = ToDeviceColor(br->mBorderColors[i]);
-      mWidths[i] = br->mBorderWidths[i];
-      mBorderStyles[i] = br->mBorderStyles[i];
-    } else {
-      mWidths[i] = 0;
-    }
-  }
-  NS_FOR_CSS_FULL_CORNERS(corner) {
-    mCorners[corner] = LayerSize(br->mBorderRadii[corner].width, br->mBorderRadii[corner].height);
-  }
-
-  mRect = ViewAs<LayerPixel>(br->mOuterRect);
-  return LAYER_ACTIVE;
-}
-
-already_AddRefed<Layer>
-nsDisplayBorder::BuildLayer(nsDisplayListBuilder* aBuilder,
-                            LayerManager* aManager,
-                            const ContainerLayerParameters& aContainerParameters)
-{
-  if (mBorderIsEmpty) {
-    return nullptr;
-  }
-
-  RefPtr<BorderLayer> layer = static_cast<BorderLayer*>
-    (aManager->GetLayerBuilder()->GetLeafLayerFor(aBuilder, this));
-  if (!layer) {
-    layer = aManager->CreateBorderLayer();
-    if (!layer)
-      return nullptr;
-  }
-  layer->SetRect(mRect);
-  layer->SetCornerRadii(mCorners);
-  layer->SetColors(mColors);
-  layer->SetWidths(mWidths);
-  layer->SetStyles(mBorderStyles);
-  layer->SetBaseTransform(gfx::Matrix4x4::Translation(aContainerParameters.mOffset.x,
-                                                      aContainerParameters.mOffset.y, 0));
-  return layer.forget();
+  return LAYER_NONE;
 }
 
 bool
 nsDisplayBorder::CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
                                          mozilla::wr::IpcResourceUpdateQueue& aResources,
                                          const StackingContextHelper& aSc,
                                          mozilla::layers::WebRenderLayerManager* aManager,
                                          nsDisplayListBuilder* aDisplayListBuilder)
@@ -5360,139 +5277,16 @@ nsDisplayBorder::CreateWebRenderCommands
                                                           aBuilder,
                                                           aResources,
                                                           aSc,
                                                           aManager,
                                                           aDisplayListBuilder);
 };
 
 void
-nsDisplayBorder::CreateBorderImageWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
-                                                    mozilla::wr::IpcResourceUpdateQueue& aResources,
-                                                    const StackingContextHelper& aSc,
-                                                    mozilla::layers::WebRenderLayerManager* aManager,
-                                                    nsDisplayListBuilder* aDisplayListBuilder)
-{
-  MOZ_ASSERT(mBorderImageRenderer);
-  if (!mBorderImageRenderer->mImageRenderer.IsReady()) {
-    return;
-  }
-
-  float widths[4];
-  float slice[4];
-  float outset[4];
-  const int32_t appUnitsPerDevPixel = mFrame->PresContext()->AppUnitsPerDevPixel();
-  NS_FOR_CSS_SIDES(i) {
-    slice[i] = (float)(mBorderImageRenderer->mSlice.Side(i)) / appUnitsPerDevPixel;
-    widths[i] = (float)(mBorderImageRenderer->mWidths.Side(i)) / appUnitsPerDevPixel;
-    outset[i] = (float)(mBorderImageRenderer->mImageOutset.Side(i)) / appUnitsPerDevPixel;
-  }
-
-  LayoutDeviceRect destRect = LayoutDeviceRect::FromAppUnits(
-    mBorderImageRenderer->mArea, appUnitsPerDevPixel);
-  wr::LayoutRect dest = wr::ToRoundedLayoutRect(destRect);
-
-  wr::LayoutRect clip = dest;
-  if (!mBorderImageRenderer->mClip.IsEmpty()) {
-    LayoutDeviceRect clipRect = LayoutDeviceRect::FromAppUnits(
-      mBorderImageRenderer->mClip, appUnitsPerDevPixel);
-    clip = wr::ToRoundedLayoutRect(clipRect);
-  }
-
-  switch (mBorderImageRenderer->mImageRenderer.GetType()) {
-    case eStyleImageType_Image:
-    {
-      uint32_t flags = imgIContainer::FLAG_ASYNC_NOTIFY;
-      if (aDisplayListBuilder->IsPaintingToWindow()) {
-        flags |= imgIContainer::FLAG_HIGH_QUALITY_SCALING;
-      }
-      if (aDisplayListBuilder->ShouldSyncDecodeImages()) {
-        flags |= imgIContainer::FLAG_SYNC_DECODE;
-      }
-
-      RefPtr<imgIContainer> img = mBorderImageRenderer->mImageRenderer.GetImage();
-      Maybe<SVGImageContext> svgContext;
-      gfx::IntSize decodeSize =
-        nsLayoutUtils::ComputeImageContainerDrawingParameters(img, mFrame, destRect,
-                                                              aSc, flags, svgContext);
-      RefPtr<layers::ImageContainer> container =
-        img->GetImageContainerAtSize(aManager, decodeSize, svgContext, flags);
-      if (!container) {
-        return;
-      }
-
-      gfx::IntSize size;
-      Maybe<wr::ImageKey> key = aManager->CommandBuilder().CreateImageKey(this, container, aBuilder,
-                                                                          aResources, aSc, size, Nothing());
-      if (key.isNothing()) {
-        return;
-      }
-
-      aBuilder.PushBorderImage(dest,
-                               clip,
-                               !BackfaceIsHidden(),
-                               wr::ToBorderWidths(widths[0], widths[1], widths[2], widths[3]),
-                               key.value(),
-                               (float)(mBorderImageRenderer->mImageSize.width) / appUnitsPerDevPixel,
-                               (float)(mBorderImageRenderer->mImageSize.height) / appUnitsPerDevPixel,
-                               wr::ToSideOffsets2D_u32(slice[0], slice[1], slice[2], slice[3]),
-                               wr::ToSideOffsets2D_f32(outset[0], outset[1], outset[2], outset[3]),
-                               wr::ToRepeatMode(mBorderImageRenderer->mRepeatModeHorizontal),
-                               wr::ToRepeatMode(mBorderImageRenderer->mRepeatModeVertical));
-      break;
-    }
-    case eStyleImageType_Gradient:
-    {
-      RefPtr<nsStyleGradient> gradientData = mBorderImageRenderer->mImageRenderer.GetGradientData();
-      nsCSSGradientRenderer renderer =
-        nsCSSGradientRenderer::Create(mFrame->PresContext(), mFrame->Style(),
-                                      gradientData, mBorderImageRenderer->mImageSize);
-
-      wr::ExtendMode extendMode;
-      nsTArray<wr::GradientStop> stops;
-      LayoutDevicePoint lineStart;
-      LayoutDevicePoint lineEnd;
-      LayoutDeviceSize gradientRadius;
-      renderer.BuildWebRenderParameters(1.0, extendMode, stops, lineStart, lineEnd, gradientRadius);
-
-      if (gradientData->mShape == NS_STYLE_GRADIENT_SHAPE_LINEAR) {
-        LayoutDevicePoint startPoint = LayoutDevicePoint(dest.origin.x, dest.origin.y) + lineStart;
-        LayoutDevicePoint endPoint = LayoutDevicePoint(dest.origin.x, dest.origin.y) + lineEnd;
-
-        aBuilder.PushBorderGradient(dest,
-                                    clip,
-                                    !BackfaceIsHidden(),
-                                    wr::ToBorderWidths(widths[0], widths[1], widths[2], widths[3]),
-                                    (float)(mBorderImageRenderer->mImageSize.width) / appUnitsPerDevPixel,
-                                    (float)(mBorderImageRenderer->mImageSize.height) / appUnitsPerDevPixel,
-                                    wr::ToSideOffsets2D_u32(slice[0], slice[1], slice[2], slice[3]),
-                                    wr::ToLayoutPoint(startPoint),
-                                    wr::ToLayoutPoint(endPoint),
-                                    stops,
-                                    extendMode,
-                                    wr::ToSideOffsets2D_f32(outset[0], outset[1], outset[2], outset[3]));
-      } else {
-        aBuilder.PushBorderRadialGradient(dest,
-                                          clip,
-                                          !BackfaceIsHidden(),
-                                          wr::ToBorderWidths(widths[0], widths[1], widths[2], widths[3]),
-                                          wr::ToLayoutPoint(lineStart),
-                                          wr::ToLayoutSize(gradientRadius),
-                                          stops,
-                                          extendMode,
-                                          wr::ToSideOffsets2D_f32(outset[0], outset[1], outset[2], outset[3]));
-      }
-      break;
-    }
-    default:
-      MOZ_ASSERT_UNREACHABLE("Unsupport border image type");
-  }
-}
-
-void
 nsDisplayBorder::Paint(nsDisplayListBuilder* aBuilder,
                        gfxContext* aCtx) {
   nsPoint offset = ToReferenceFrame();
 
   PaintBorderFlags flags = aBuilder->ShouldSyncDecodeImages()
                          ? PaintBorderFlags::SYNC_DECODE_IMAGES
                          : PaintBorderFlags();
 
--- a/layout/painting/nsDisplayList.h
+++ b/layout/painting/nsDisplayList.h
@@ -3735,19 +3735,16 @@ public:
 
   virtual bool IsInvisibleInRect(const nsRect& aRect) const override;
   virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder,
                            bool* aSnap) const override;
   virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
                                    LayerManager* aManager,
                                    const ContainerLayerParameters& aParameters) override;
 
-  virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
-                                             LayerManager* aManager,
-                                             const ContainerLayerParameters& aContainerParameters) override;
   virtual bool CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
                                        mozilla::wr::IpcResourceUpdateQueue& aResources,
                                        const StackingContextHelper& aSc,
                                        mozilla::layers::WebRenderLayerManager* aManager,
                                        nsDisplayListBuilder* aDisplayListBuilder) override;
 
   virtual void Paint(nsDisplayListBuilder* aBuilder, gfxContext* aCtx) override;
 
@@ -3762,21 +3759,16 @@ public:
   virtual nsRegion GetTightBounds(nsDisplayListBuilder* aBuilder,
                                   bool* aSnap) const override
   {
     *aSnap = true;
     return CalculateBounds<nsRegion>(*mFrame->StyleBorder());
   }
 
 protected:
-  void CreateBorderImageWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
-                                          mozilla::wr::IpcResourceUpdateQueue& aResource,
-                                          const StackingContextHelper& aSc,
-                                          mozilla::layers::WebRenderLayerManager* aManager,
-                                          nsDisplayListBuilder* aDisplayListBuilder);
   template<typename T>
   T CalculateBounds(const nsStyleBorder& aStyleBorder) const
   {
     nsRect borderBounds(ToReferenceFrame(), mFrame->GetSize());
     if (aStyleBorder.IsBorderImageLoaded()) {
       borderBounds.Inflate(aStyleBorder.GetImageOutset());
       return borderBounds;
     } else {
@@ -3813,27 +3805,17 @@ protected:
           nsSize cornerSize(radii[mozilla::eCornerBottomLeftX], radii[mozilla::eCornerBottomLeftY]);
           result.OrWith(nsRect(borderBounds.BottomLeft() - nsPoint(0, cornerSize.height), cornerSize));
         }
       }
       return result;
     }
   }
 
-  mozilla::Array<mozilla::gfx::Color, 4> mColors;
-  mozilla::Array<mozilla::LayerCoord, 4> mWidths;
-  mozilla::Array<mozilla::LayerSize, 4> mCorners;
-  mozilla::Array<uint8_t, 4> mBorderStyles;
-  mozilla::LayerRect mRect;
-
-  mozilla::Maybe<nsCSSBorderRenderer> mBorderRenderer;
-  mozilla::Maybe<nsCSSBorderImageRenderer> mBorderImageRenderer;
-
   nsRect mBounds;
-  bool mBorderIsEmpty;
 };
 
 /**
  * A simple display item that just renders a solid color across the
  * specified bounds. For canvas frames (in the CSS sense) we split off the
  * drawing of the background color into this class (from nsDisplayBackground
  * via nsDisplayCanvasBackground). This is done so that we can always draw a
  * background color to avoid ugly flashes of white when we can't draw a full
--- a/layout/reftests/mathml/reftest.list
+++ b/layout/reftests/mathml/reftest.list
@@ -84,17 +84,17 @@ fails-if(gtkWidget) random-if(/^Windows\
 fails == stretchy-mover-2a.html stretchy-mover-2-ref.html
 != stretchy-mover-2b.html stretchy-mover-2-ref.html
 == stretchy-mover-3.html stretchy-mover-3-ref.html
 == stretchy-largeop-1.html stretchy-largeop-1-ref.html
 == stretchy-largeop-2.html stretchy-largeop-2-ref.html
 == stretchy-largeop-3.html stretchy-largeop-3-ref.html
 == table-width-1.xhtml table-width-1-ref.xhtml
 == table-width-2.html table-width-2-ref.html
-fails-if(webrender&&winWidget) == table-width-3.html table-width-3-ref.html # bug 1460259
+== table-width-3.html table-width-3-ref.html
 == table-width-4.html table-width-4-ref.html
 == underbar-width-1.xhtml underbar-width-1-ref.xhtml
 == mathml-type-supported.xhtml mathml-type-supported-ref.xml
 == mtable-align-negative-rownumber.html mtable-align-negative-rownumber-ref.html
 == mtable-align-negative-rownumber-2.html mtable-align-negative-rownumber-2-ref.html
 != embellished-op-1-1.html embellished-op-1-1-ref.html
 != embellished-op-1-2.html embellished-op-1-2-ref.html
 != embellished-op-1-3.html embellished-op-1-3-ref.html
--- a/modules/libpref/init/all.js
+++ b/modules/libpref/init/all.js
@@ -5809,17 +5809,17 @@ pref("dom.clients.openwindow_favors_same
 pref("toolkit.crashreporter.include_context_heap", false);
 #else
 pref("toolkit.crashreporter.include_context_heap", true);
 #endif
 
 // Open noopener links in a new process
 pref("dom.noopener.newprocess.enabled", true);
 
-#if defined(XP_WIN) || defined(XP_MACOSX)
+#if defined(XP_WIN) || defined(XP_MACOSX) || defined(MOZ_WIDGET_GTK)
 pref("layers.omtp.enabled", true);
 #else
 pref("layers.omtp.enabled", false);
 #endif
 pref("layers.omtp.paint-workers", -1);
 pref("layers.omtp.release-capture-on-main-thread", false);
 pref("layers.omtp.dump-capture", false);
 
--- a/testing/marionette/accessibility.js
+++ b/testing/marionette/accessibility.js
@@ -265,16 +265,20 @@ accessibility.Checks = class {
    *
    * @param {nsIAccessible} accessible
    *     Accessible object.
    *
    * @return {boolean}
    *     True if element is hidden from user, false otherwise.
    */
   isHidden(accessible) {
+    if (!accessible) {
+      return true;
+    }
+
     while (accessible) {
       if (this.hasHiddenAttribute(accessible)) {
         return true;
       }
       accessible = accessible.parent;
     }
     return false;
   }
@@ -290,20 +294,16 @@ accessibility.Checks = class {
    * @param {boolean} visible
    *     Visibility state of |element|.
    *
    * @throws ElementNotAccessibleError
    *     If |element|'s visibility state does not correspond to
    *     |accessible|'s.
    */
   assertVisible(accessible, element, visible) {
-    if (!accessible) {
-      return;
-    }
-
     let hiddenAccessibility = this.isHidden(accessible);
 
     let message;
     if (visible && hiddenAccessibility) {
       message = "Element is not currently visible via the accessibility API " +
           "and may not be manipulated by it";
     } else if (!visible && !hiddenAccessibility) {
       message = "Element is currently only visible via the accessibility API " +
--- a/testing/marionette/harness/marionette_harness/tests/unit/test_accessibility.py
+++ b/testing/marionette/harness/marionette_harness/tests/unit/test_accessibility.py
@@ -71,23 +71,28 @@ class TestAccessibility(MarionetteTestCa
     falsy_elements = [
         # Element is only visible to the accessibility API and may be
         # manipulated by it
         "button9",
         # Element is not currently visible
         "button10"
     ]
 
-    displayed_elementIDs = [
-        "button1", "button2", "button3", "button4", "button5", "button6",
+    displayed_elementIDs = ["button1", "button2", "button4", "button5", "button6"]
+
+    displayed_but_have_no_accessible_elementIDs = [
+        # Button3 does not have an accessible object
+        "button3",
+        # Button 7 is hidden with aria-hidden set to true
+        "button7",
+        # Button 8 is inside an element with aria-hidden set to true
+        "button8",
         "no_accessible_but_displayed"
     ]
 
-    displayed_but_a11y_hidden_elementIDs = ["button7", "button8"]
-
     disabled_elementIDs = ["button11", "no_accessible_but_disabled"]
 
     # Elements that are enabled but otherwise disabled or not explorable
     # via the accessibility API
     aria_disabled_elementIDs = ["button12"]
 
     # pointer-events: "none", which will return
     # ElementClickInterceptedException if clicked
@@ -159,17 +164,17 @@ class TestAccessibility(MarionetteTestCa
         # Elements are invisible
         self.run_element_test(self.falsy_elements,
                               lambda button: self.assertRaises(ElementNotInteractableException,
                                                                button.click))
 
     def test_element_visible_but_not_visible_to_accessbility(self):
         self.setup_accessibility()
         # Elements are displayed but hidden from accessibility API
-        self.run_element_test(self.displayed_but_a11y_hidden_elementIDs,
+        self.run_element_test(self.displayed_but_have_no_accessible_elementIDs,
                               lambda element: self.assertRaises(ElementNotAccessibleException,
                                                                 element.is_displayed))
 
     def test_element_is_visible_to_accessibility(self):
         self.setup_accessibility()
         # No exception should be raised
         self.run_element_test(self.displayed_elementIDs, lambda element: element.is_displayed())
 
--- a/testing/web-platform/meta/2dcontext/drawing-text-to-the-canvas/2d.text.draw.fontface.notinpage.html.ini
+++ b/testing/web-platform/meta/2dcontext/drawing-text-to-the-canvas/2d.text.draw.fontface.notinpage.html.ini
@@ -1,4 +1,3 @@
 [2d.text.draw.fontface.notinpage.html]
   disabled:
     if verify: fails in verify mode
-
--- a/testing/web-platform/meta/FileAPI/idlharness.html.ini
+++ b/testing/web-platform/meta/FileAPI/idlharness.html.ini
@@ -12,8 +12,11 @@
     expected: FAIL
 
   [FileReaderSync interface: operation readAsText(Blob,DOMString)]
     expected: FAIL
 
   [FileReaderSync interface: operation readAsDataURL(Blob)]
     expected: FAIL
 
+  [Partial interface URL: valid exposure set]
+    expected: FAIL
+
--- a/testing/web-platform/meta/FileAPI/idlharness.worker.js.ini
+++ b/testing/web-platform/meta/FileAPI/idlharness.worker.js.ini
@@ -17,8 +17,14 @@
     expected: FAIL
 
   [EventTarget interface: existence and properties of interface object]
     expected: FAIL
 
   [Event interface: existence and properties of interface object]
     expected: FAIL
 
+  [Partial interface URL: valid exposure set]
+    expected: FAIL
+
+  [URL interface: existence and properties of interface object]
+    expected: FAIL
+
--- a/testing/web-platform/meta/IndexedDB/interfaces.any.js.ini
+++ b/testing/web-platform/meta/IndexedDB/interfaces.any.js.ini
@@ -1,12 +1,6 @@
 [interfaces.any.worker.html]
   [ImageBitmapRenderingContext interface: existence and properties of interface object]
     expected: FAIL
 
-  [Test driver]
-    expected: FAIL
-
 
 [interfaces.any.html]
-  [Test driver]
-    expected: FAIL
-
--- a/testing/web-platform/meta/MANIFEST.json
+++ b/testing/web-platform/meta/MANIFEST.json
@@ -102110,28 +102110,16 @@
       [
        "/css/css-animations/animation-common-ref.html",
        "=="
       ]
      ],
      {}
     ]
    ],
-   "css/css-animations/set-animation-play-state-to-paused-002.html": [
-    [
-     "/css/css-animations/set-animation-play-state-to-paused-002.html",
-     [
-      [
-       "/css/css-animations/set-animation-play-state-to-paused-002-ref.html",
-       "=="
-      ]
-     ],
-     {}
-    ]
-   ],
    "css/css-backgrounds/background-334.html": [
     [
      "/css/css-backgrounds/background-334.html",
      [
       [
        "/css/css-backgrounds/reference/background-334-ref.xht",
        "=="
       ]
@@ -162326,16 +162314,64 @@
       [
        "/css/css-writing-modes/text-orientation-upright-vrl-100-ref.html",
        "=="
       ]
      ],
      {}
     ]
    ],
+   "css/css-writing-modes/three-levels-of-orthogonal-flows.html": [
+    [
+     "/css/css-writing-modes/three-levels-of-orthogonal-flows.html",
+     [
+      [
+       "/css/css-writing-modes/reference/three-levels-of-orthogonal-flows.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/css-writing-modes/two-levels-of-orthogonal-flows-fixed.html": [
+    [
+     "/css/css-writing-modes/two-levels-of-orthogonal-flows-fixed.html",
+     [
+      [
+       "/css/css-writing-modes/reference/two-levels-of-orthogonal-flows-fixed.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/css-writing-modes/two-levels-of-orthogonal-flows-percentage.html": [
+    [
+     "/css/css-writing-modes/two-levels-of-orthogonal-flows-percentage.html",
+     [
+      [
+       "/css/css-writing-modes/reference/two-levels-of-orthogonal-flows-percentage.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/css-writing-modes/two-levels-of-orthogonal-flows.html": [
+    [
+     "/css/css-writing-modes/two-levels-of-orthogonal-flows.html",
+     [
+      [
+       "/css/css-writing-modes/reference/two-levels-of-orthogonal-flows.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
    "css/css-writing-modes/vertical-alignment-002.xht": [
     [
      "/css/css-writing-modes/vertical-alignment-002.xht",
      [
       [
        "/css/css-writing-modes/vertical-alignment-002-ref.xht",
        "=="
       ]
@@ -165962,16 +165998,28 @@
       [
        "/css/vendor-imports/mozilla/mozilla-central-reftests/contain/contain-paint-clip-003-ref.html",
        "=="
       ]
      ],
      {}
     ]
    ],
+   "css/vendor-imports/mozilla/mozilla-central-reftests/contain/contain-paint-clip-006.html": [
+    [
+     "/css/vendor-imports/mozilla/mozilla-central-reftests/contain/contain-paint-clip-006.html",
+     [
+      [
+       "/css/vendor-imports/mozilla/mozilla-central-reftests/contain/contain-paint-clip-006-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
    "css/vendor-imports/mozilla/mozilla-central-reftests/contain/contain-paint-containing-block-absolute-001.html": [
     [
      "/css/vendor-imports/mozilla/mozilla-central-reftests/contain/contain-paint-containing-block-absolute-001.html",
      [
       [
        "/css/vendor-imports/mozilla/mozilla-central-reftests/contain/contain-paint-containing-block-absolute-001-ref.html",
        "=="
       ]
@@ -172934,16 +172982,64 @@
       [
        "/css/vendor-imports/mozilla/mozilla-central-reftests/selectors4/focus-within-3-ref.html",
        "=="
       ]
      ],
      {}
     ]
    ],
+   "css/vendor-imports/mozilla/mozilla-central-reftests/shapes1/float-retry-push-circle.html": [
+    [
+     "/css/vendor-imports/mozilla/mozilla-central-reftests/shapes1/float-retry-push-circle.html",
+     [
+      [
+       "/css/vendor-imports/mozilla/mozilla-central-reftests/shapes1/float-retry-push-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/vendor-imports/mozilla/mozilla-central-reftests/shapes1/float-retry-push-image.html": [
+    [
+     "/css/vendor-imports/mozilla/mozilla-central-reftests/shapes1/float-retry-push-image.html",
+     [
+      [
+       "/css/vendor-imports/mozilla/mozilla-central-reftests/shapes1/float-retry-push-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/vendor-imports/mozilla/mozilla-central-reftests/shapes1/float-retry-push-inset.html": [
+    [
+     "/css/vendor-imports/mozilla/mozilla-central-reftests/shapes1/float-retry-push-inset.html",
+     [
+      [
+       "/css/vendor-imports/mozilla/mozilla-central-reftests/shapes1/float-retry-push-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/vendor-imports/mozilla/mozilla-central-reftests/shapes1/float-retry-push-polygon.html": [
+    [
+     "/css/vendor-imports/mozilla/mozilla-central-reftests/shapes1/float-retry-push-polygon.html",
+     [
+      [
+       "/css/vendor-imports/mozilla/mozilla-central-reftests/shapes1/float-retry-push-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
    "css/vendor-imports/mozilla/mozilla-central-reftests/shapes1/shape-outside-border-box-001.html": [
     [
      "/css/vendor-imports/mozilla/mozilla-central-reftests/shapes1/shape-outside-border-box-001.html",
      [
       [
        "/css/vendor-imports/mozilla/mozilla-central-reftests/shapes1/shape-outside-border-box-001-ref.html",
        "=="
       ]
@@ -239136,21 +239232,16 @@
      {}
     ]
    ],
    "css/css-animations/animationevent-interface.js": [
     [
      {}
     ]
    ],
-   "css/css-animations/set-animation-play-state-to-paused-002-ref.html": [
-    [
-     {}
-    ]
-   ],
    "css/css-animations/support/testcommon.js": [
     [
      {}
     ]
    ],
    "css/css-backgrounds/OWNERS": [
     [
      {}
@@ -262246,16 +262337,36 @@
      {}
     ]
    ],
    "css/css-writing-modes/reference/text-combine-upright-value-single-character.html": [
     [
      {}
     ]
    ],
+   "css/css-writing-modes/reference/three-levels-of-orthogonal-flows.html": [
+    [
+     {}
+    ]
+   ],
+   "css/css-writing-modes/reference/two-levels-of-orthogonal-flows-fixed.html": [
+    [
+     {}
+    ]
+   ],
+   "css/css-writing-modes/reference/two-levels-of-orthogonal-flows-percentage.html": [
+    [
+     {}
+    ]
+   ],
+   "css/css-writing-modes/reference/two-levels-of-orthogonal-flows.html": [
+    [
+     {}
+    ]
+   ],
    "css/css-writing-modes/reference/vertical-ahem-1x1-ref.html": [
     [
      {}
     ]
    ],
    "css/css-writing-modes/reference/vertical-ahem-1x3-ref.html": [
     [
      {}
@@ -267796,16 +267907,21 @@
      {}
     ]
    ],
    "css/vendor-imports/mozilla/mozilla-central-reftests/contain/contain-paint-clip-004-ref.html": [
     [
      {}
     ]
    ],
+   "css/vendor-imports/mozilla/mozilla-central-reftests/contain/contain-paint-clip-006-ref.html": [
+    [
+     {}
+    ]
+   ],
    "css/vendor-imports/mozilla/mozilla-central-reftests/contain/contain-paint-containing-block-absolute-001-ref.html": [
     [
      {}
     ]
    ],
    "css/vendor-imports/mozilla/mozilla-central-reftests/contain/contain-paint-containing-block-fixed-001-ref.html": [
     [
      {}
@@ -269831,16 +269947,21 @@
      {}
     ]
    ],
    "css/vendor-imports/mozilla/mozilla-central-reftests/selectors4/reftest.list": [
     [
      {}
     ]
    ],
+   "css/vendor-imports/mozilla/mozilla-central-reftests/shapes1/float-retry-push-ref.html": [
+    [
+     {}
+    ]
+   ],
    "css/vendor-imports/mozilla/mozilla-central-reftests/shapes1/reftest.list": [
     [
      {}
     ]
    ],
    "css/vendor-imports/mozilla/mozilla-central-reftests/shapes1/shape-outside-border-box-001-ref.html": [
     [
      {}
@@ -276841,16 +276962,21 @@
      {}
     ]
    ],
    "html/browsers/origin/cross-origin-objects/win-documentdomain.sub.html": [
     [
      {}
     ]
    ],
+   "html/browsers/origin/relaxing-the-same-origin-restriction/sandboxed-document_domain.html.headers": [
+    [
+     {}
+    ]
+   ],
    "html/browsers/origin/relaxing-the-same-origin-restriction/support/document_domain_frame.html": [
     [
      {}
     ]
    ],
    "html/browsers/origin/relaxing-the-same-origin-restriction/support/document_domain_setter_iframe.html": [
     [
      {}
@@ -288016,16 +288142,21 @@
      {}
     ]
    ],
    "infrastructure/webdriver/tests/conftest.py": [
     [
      {}
     ]
    ],
+   "input-device-capabilities/OWNERS": [
+    [
+     {}
+    ]
+   ],
    "input-events/OWNERS": [
     [
      {}
     ]
    ],
    "interfaces/BackgroundSync.idl": [
     [
      {}
@@ -288041,21 +288172,31 @@
      {}
     ]
    ],
    "interfaces/IndexedDB.idl": [
     [
      {}
     ]
    ],
+   "interfaces/InputDeviceCapabilities.idl": [
+    [
+     {}
+    ]
+   ],
    "interfaces/OWNERS": [
     [
      {}
     ]
    ],
+   "interfaces/ResizeObserver.idl": [
+    [
+     {}
+    ]
+   ],
    "interfaces/ServiceWorker.idl": [
     [
      {}
     ]
    ],
    "interfaces/WebCryptoAPI.idl": [
     [
      {}
@@ -288111,16 +288252,21 @@
      {}
     ]
    ],
    "interfaces/css-fonts.idl": [
     [
      {}
     ]
    ],
+   "interfaces/css-masking.idl": [
+    [
+     {}
+    ]
+   ],
    "interfaces/css-typed-om.idl": [
     [
      {}
     ]
    ],
    "interfaces/cssom-view.idl": [
     [
      {}
@@ -288251,16 +288397,21 @@
      {}
     ]
    ],
    "interfaces/payment-request.idl": [
     [
      {}
     ]
    ],
+   "interfaces/performance-timeline.idl": [
+    [
+     {}
+    ]
+   ],
    "interfaces/permissions.idl": [
     [
      {}
     ]
    ],
    "interfaces/pointerevents.idl": [
     [
      {}
@@ -288311,16 +288462,21 @@
      {}
     ]
    ],
    "interfaces/url.idl": [
     [
      {}
     ]
    ],
+   "interfaces/user-timing.idl": [
+    [
+     {}
+    ]
+   ],
    "interfaces/vibration.idl": [
     [
      {}
     ]
    ],
    "interfaces/wake-lock.idl": [
     [
      {}
@@ -288346,16 +288502,21 @@
      {}
     ]
    ],
    "interfaces/webauthn.idl": [
     [
      {}
     ]
    ],
+   "interfaces/webdriver.idl": [
+    [
+     {}
+    ]
+   ],
    "interfaces/webidl.idl": [
     [
      {}
     ]
    ],
    "interfaces/webrtc-pc.idl": [
     [
      {}
@@ -288446,16 +288607,21 @@
      {}
     ]
    ],
    "keyboard-map/OWNERS": [
     [
      {}
     ]
    ],
+   "keyboard-map/resources/iframe-keyboard-map-helper.html": [
+    [
+     {}
+    ]
+   ],
    "lifecycle/resources/foo.txt": [
     [
      {}
     ]
    ],
    "lifecycle/resources/window.html": [
     [
      {}
@@ -318409,16 +318575,22 @@
     ]
    ],
    "css/css-logical/logicalprops-quirklength.html": [
     [
      "/css/css-logical/logicalprops-quirklength.html",
      {}
     ]
    ],
+   "css/css-masking/idlharness.html": [
+    [
+     "/css/css-masking/idlharness.html",
+     {}
+    ]
+   ],
    "css/css-masking/parsing/clip-invalid.html": [
     [
      "/css/css-masking/parsing/clip-invalid.html",
      {}
     ]
    ],
    "css/css-masking/parsing/clip-path-invalid.html": [
     [
@@ -320965,16 +321137,22 @@
     ]
    ],
    "css/css-text/i18n/zh/css-text-line-break-zh-po-strict.html": [
     [
      "/css/css-text/i18n/zh/css-text-line-break-zh-po-strict.html",
      {}
     ]
    ],
+   "css/css-text/overflow-wrap/word-wrap-alias.html": [
+    [
+     "/css/css-text/overflow-wrap/word-wrap-alias.html",
+     {}
+    ]
+   ],
    "css/css-text/white-space/seg-break-transformation-000.html": [
     [
      "/css/css-text/white-space/seg-break-transformation-000.html",
      {}
     ]
    ],
    "css/css-text/white-space/seg-break-transformation-001.html": [
     [
@@ -339231,16 +339409,22 @@
     ]
    ],
    "html/browsers/origin/relaxing-the-same-origin-restriction/document_domain_setter_srcdoc.html": [
     [
      "/html/browsers/origin/relaxing-the-same-origin-restriction/document_domain_setter_srcdoc.html",
      {}
     ]
    ],
+   "html/browsers/origin/relaxing-the-same-origin-restriction/sandboxed-document_domain.html": [
+    [
+     "/html/browsers/origin/relaxing-the-same-origin-restriction/sandboxed-document_domain.html",
+     {}
+    ]
+   ],
    "html/browsers/sandboxing/sandbox-allow-same-origin.html": [
     [
      "/html/browsers/sandboxing/sandbox-allow-same-origin.html",
      {}
     ]
    ],
    "html/browsers/sandboxing/sandbox-allow-scripts.html": [
     [
@@ -339533,17 +339717,29 @@
    "html/browsers/the-window-object/window-named-properties.html": [
     [
      "/html/browsers/the-window-object/window-named-properties.html",
      {}
     ]
    ],
    "html/browsers/the-window-object/window-open-noopener.html": [
     [
-     "/html/browsers/the-window-object/window-open-noopener.html",
+     "/html/browsers/the-window-object/window-open-noopener.html?_parent",
+     {}
+    ],
+    [
+     "/html/browsers/the-window-object/window-open-noopener.html?_self",
+     {}
+    ],
+    [
+     "/html/browsers/the-window-object/window-open-noopener.html?_top",
+     {}
+    ],
+    [
+     "/html/browsers/the-window-object/window-open-noopener.html?indexed",
      {}
     ]
    ],
    "html/browsers/the-window-object/window-properties.https.html": [
     [
      "/html/browsers/the-window-object/window-properties.https.html",
      {}
     ]
@@ -350581,16 +350777,22 @@
    "infrastructure/testdriver/send_keys.html": [
     [
      "/infrastructure/testdriver/send_keys.html",
      {
       "testdriver": true
      }
     ]
    ],
+   "input-device-capabilities/interfaces.html": [
+    [
+     "/input-device-capabilities/interfaces.html",
+     {}
+    ]
+   ],
    "input-events/idlharness.html": [
     [
      "/input-events/idlharness.html",
      {}
     ]
    ],
    "input-events/input-events-exec-command.html": [
     [
@@ -350869,19 +351071,49 @@
     ]
    ],
    "keyboard-map/idlharness.https.html": [
     [
      "/keyboard-map/idlharness.https.html",
      {}
     ]
    ],
-   "keyboard-map/keyboard-map-https.html": [
-    [
-     "/keyboard-map/keyboard-map-https.html",
+   "keyboard-map/keyboard-map-two-parallel-requests.https.html": [
+    [
+     "/keyboard-map/keyboard-map-two-parallel-requests.https.html",
+     {}
+    ]
+   ],
+   "keyboard-map/navigator-keyboard-map-blocked-from-cross-origin-iframe.https.html": [
+    [
+     "/keyboard-map/navigator-keyboard-map-blocked-from-cross-origin-iframe.https.html",
+     {}
+    ]
+   ],
+   "keyboard-map/navigator-keyboard-map-blocked-from-iframe.https.html": [
+    [
+     "/keyboard-map/navigator-keyboard-map-blocked-from-iframe.https.html",
+     {}
+    ]
+   ],
+   "keyboard-map/navigator-keyboard-map-two-parallel-requests.https.html": [
+    [
+     "/keyboard-map/navigator-keyboard-map-two-parallel-requests.https.html",
+     {}
+    ]
+   ],
+   "keyboard-map/navigator-keyboard-map-two-sequential-requests.https.html": [
+    [
+     "/keyboard-map/navigator-keyboard-map-two-sequential-requests.https.html",
+     {}
+    ]
+   ],
+   "keyboard-map/navigator-keyboard-map.https.html": [
+    [
+     "/keyboard-map/navigator-keyboard-map.https.html",
      {}
     ]
    ],
    "lifecycle/freeze.html": [
     [
      "/lifecycle/freeze.html",
      {}
     ]
@@ -351145,19 +351377,23 @@
     ]
    ],
    "media-capabilities/decodingInfo.html": [
     [
      "/media-capabilities/decodingInfo.html",
      {}
     ]
    ],
-   "media-capabilities/idlharness.html": [
-    [
-     "/media-capabilities/idlharness.html",
+   "media-capabilities/idlharness.any.js": [
+    [
+     "/media-capabilities/idlharness.any.html",
+     {}
+    ],
+    [
+     "/media-capabilities/idlharness.any.worker.html",
      {}
     ]
    ],
    "media-source/SourceBuffer-abort-readyState.html": [
     [
      "/media-source/SourceBuffer-abort-readyState.html",
      {
       "timeout": "long"
@@ -362901,19 +363137,31 @@
      "/performance-timeline/case-sensitivity.any.html",
      {}
     ],
     [
      "/performance-timeline/case-sensitivity.any.worker.html",
      {}
     ]
    ],
-   "performance-timeline/idlharness.html": [
-    [
-     "/performance-timeline/idlharness.html",
+   "performance-timeline/idlharness.any.js": [
+    [
+     "/performance-timeline/idlharness.any.html",
+     {}
+    ],
+    [
+     "/performance-timeline/idlharness.any.sharedworker.html",
+     {}
+    ],
+    [
+     "/performance-timeline/idlharness.any.worker.html",
+     {}
+    ],
+    [
+     "/performance-timeline/idlharness.https.any.serviceworker.html",
      {}
     ]
    ],
    "performance-timeline/performanceentry-tojson.html": [
     [
      "/performance-timeline/performanceentry-tojson.html",
      {}
     ]
@@ -372245,16 +372493,22 @@
     ]
    ],
    "resize-observer/eventloop.html": [
     [
      "/resize-observer/eventloop.html",
      {}
     ]
    ],
+   "resize-observer/idlharness.html": [
+    [
+     "/resize-observer/idlharness.html",
+     {}
+    ]
+   ],
    "resize-observer/notify.html": [
     [
      "/resize-observer/notify.html",
      {}
     ]
    ],
    "resize-observer/observe.html": [
     [
@@ -374048,17 +374302,19 @@
     [
      "/service-workers/service-worker/registration-service-worker-attributes.https.html",
      {}
     ]
    ],
    "service-workers/service-worker/registration-updateviacache.https.html": [
     [
      "/service-workers/service-worker/registration-updateviacache.https.html",
-     {}
+     {
+      "timeout": "long"
+     }
     ]
    ],
    "service-workers/service-worker/rejections.https.html": [
     [
      "/service-workers/service-worker/rejections.https.html",
      {}
     ]
    ],
@@ -377167,19 +377423,31 @@
      "/user-timing/entry_type.any.html",
      {}
     ],
     [
      "/user-timing/entry_type.any.worker.html",
      {}
     ]
    ],
-   "user-timing/idlharness.html": [
-    [
-     "/user-timing/idlharness.html",
+   "user-timing/idlharness.any.js": [
+    [
+     "/user-timing/idlharness.any.html",
+     {}
+    ],
+    [
+     "/user-timing/idlharness.any.sharedworker.html",
+     {}
+    ],
+    [
+     "/user-timing/idlharness.any.worker.html",
+     {}
+    ],
+    [
+     "/user-timing/idlharness.https.any.serviceworker.html",
      {}
     ]
    ],
    "user-timing/invoke_with_timing_attributes.html": [
     [
      "/user-timing/invoke_with_timing_attributes.html",
      {}
     ]
@@ -405675,17 +405943,17 @@
    "cfedb92777a36954d6e285461bf224cb6d2b5407",
    "support"
   ],
   "./LICENSE.md": [
    "722729a1062b97ad2fdd43896b2c6a45b1fff144",
    "support"
   ],
   "./README.md": [
-   "ce5fb6c1b9f899ffab603cbfc4086b00dbff5384",
+   "bbaa29655c73c0be3dc1e5e1aae85607284cc7b9",
    "support"
   ],
   "./check_stability.ini": [
    "5addd67f09e895336644c5a9f5049c03e1ffe615",
    "support"
   ],
   "./lint.whitelist": [
    "808677b142f2245d3127428fb75caea24db8bc00",
@@ -416343,17 +416611,17 @@
    "417d39a317f55a95180c806d28047c85dd959d65",
    "testharness"
   ],
   "budget-api/OWNERS": [
    "ed48014d817ef034062db60403704ed2c0cf9aeb",
    "support"
   ],
   "budget-api/interfaces.any.js": [
-   "7532e03a56725728052d4b5a973630e2b86686da",
+   "36404f7f6ec3674ae74cd2ea1969b6260dc8f47c",
    "testharness"
   ],
   "clear-site-data/OWNERS": [
    "58a011d159fc7581c33fee75b7837c689e704289",
    "support"
   ],
   "clear-site-data/navigation-insecure.html": [
    "97c069cf7c938e1ebdba3f243ad48369a7fb5542",
@@ -497878,24 +498146,16 @@
   "css/css-animations/event-order.tentative.html": [
    "0115580619b629e47ae0f2635cc84e1e80442a8f",
    "testharness"
   ],
   "css/css-animations/pending-style-changes-001.html": [
    "5f2bf4b6712dd230109be62407cd31800451a271",
    "testharness"
   ],
-  "css/css-animations/set-animation-play-state-to-paused-002-ref.html": [
-   "8156c889e4af141b1bdf3df52626c4337b20c611",
-   "support"
-  ],
-  "css/css-animations/set-animation-play-state-to-paused-002.html": [
-   "bd0740fea0d8b0fae749539c9702d3929b0a8093",
-   "reftest"
-  ],
   "css/css-animations/support/testcommon.js": [
    "3e2b733b29fca0963c95c0d069b7a518db266004",
    "support"
   ],
   "css/css-backgrounds/OWNERS": [
    "656d9f4e3a66f8cb955910171b9997140e4bbd8e",
    "support"
   ],
@@ -518623,17 +518883,17 @@
    "9bd26d717f34f9ebf1f09cbb2eb7c2242df6b3c8",
    "testharness"
   ],
   "css/css-logical/logicalprops-inline-size.html": [
    "4f3bdbc5d9e38770050d963c32942a63272f0e67",
    "testharness"
   ],
   "css/css-logical/logicalprops-quirklength.html": [
-   "3024bbd54e4cbe1ee55e59684188587e2a56fda6",
+   "04c724e71003824ad8c9fe37c5d4b309d2954282",
    "testharness"
   ],
   "css/css-logical/resources/test-box-properties.js": [
    "132f6024928641f0cd1f0580e69126a8ab02eba8",
    "support"
   ],
   "css/css-masking/OWNERS": [
    "388433ab37e52bf8982700fad3ffd34b8ecae122",
@@ -519430,16 +519690,20 @@
   "css/css-masking/clip/reference/clip-rect-top-ref.html": [
    "700d9d78427c2f60e62859073e8144b4fc096686",
    "support"
   ],
   "css/css-masking/clip/reference/clip-vertical-stripe-ref.html": [
    "8853e79d6e9c3d262ebb38c569e97932f3b27cd4",
    "support"
   ],
+  "css/css-masking/idlharness.html": [
+   "527fb8b8884e00d898c047f092221af56211bbcd",
+   "testharness"
+  ],
   "css/css-masking/parsing/clip-invalid.html": [
    "81cd98170ea4abe216c0cf155aa493c58079bd53",
    "testharness"
   ],
   "css/css-masking/parsing/clip-path-invalid.html": [
    "791ea3c564f629ed8d679499f5483e122ad9f602",
    "testharness"
   ],
@@ -529222,16 +529486,20 @@
   "css/css-text/overflow-wrap/word-wrap-004.html": [
    "b1ac7133b3e5ba3336e1d18366ae009c78b2b029",
    "reftest"
   ],
   "css/css-text/overflow-wrap/word-wrap-005.html": [
    "5f656293d6ce705ad0278ee0dca22201c2cdcb3b",
    "reftest"
   ],
+  "css/css-text/overflow-wrap/word-wrap-alias.html": [
+   "3169acee2991fd327d30f3fbebc1e3a85e6a3bb1",
+   "testharness"
+  ],
   "css/css-text/support/1x1-green.png": [
    "51e7b6974a09eda6cb31337717c5eaeb9c44b443",
    "support"
   ],
   "css/css-text/support/1x1-lime.png": [
    "b040eb633a35c0648ad72a2902361faf25bc419d",
    "support"
   ],
@@ -545370,16 +545638,32 @@
   "css/css-writing-modes/reference/text-combine-upright-layout-rules-001-ref.html": [
    "b3bf86e793af46ec4fc4cb8538b12333e9603ef9",
    "support"
   ],
   "css/css-writing-modes/reference/text-combine-upright-value-single-character.html": [
    "63c8138947a0fecc134d04797d383f7974acc79c",
    "support"
   ],
+  "css/css-writing-modes/reference/three-levels-of-orthogonal-flows.html": [
+   "7033482677726f890c27fa874df37ece0fc1749b",
+   "support"
+  ],
+  "css/css-writing-modes/reference/two-levels-of-orthogonal-flows-fixed.html": [
+   "2684e3f55cb6212e4faea21efe97dea5270f3f6f",
+   "support"
+  ],
+  "css/css-writing-modes/reference/two-levels-of-orthogonal-flows-percentage.html": [
+   "0f13b9fce43596cff43f7d53c44f4b24e3332392",
+   "support"
+  ],
+  "css/css-writing-modes/reference/two-levels-of-orthogonal-flows.html": [
+   "0e0c5ff7f2441575f4faca99fc853c46ea656a89",
+   "support"
+  ],
   "css/css-writing-modes/reference/vertical-ahem-1x1-ref.html": [
    "109ecb842ebdb0c4a515d0942b0b78ab631d8e59",
    "support"
   ],
   "css/css-writing-modes/reference/vertical-ahem-1x3-ref.html": [
    "1c597e2aee017a453aad709798d2fe2d4b456bf7",
    "support"
   ],
@@ -547658,16 +547942,20 @@
   "css/css-writing-modes/text-underline-position-right-002.xht": [
    "58cd457123f61dd092d711bb208558fe98d53cac",
    "visual"
   ],
   "css/css-writing-modes/text-underline-position-under-001.xht": [
    "47a4aeecb4971b3ddd9589465c868fa71096ce93",
    "visual"
   ],
+  "css/css-writing-modes/three-levels-of-orthogonal-flows.html": [
+   "816df1a7e476da22dadb8afb381a188e458f66ff",
+   "reftest"
+  ],
   "css/css-writing-modes/tools/generators/.gitignore": [
    "8b894ec0b3bbc33011392ad9bafeb1df2634db45",
    "support"
   ],
   "css/css-writing-modes/tools/generators/README.md": [
    "bb8dc58366d520524d28fa550b6f51e5c1a06a7a",
    "support"
   ],
@@ -547706,16 +547994,28 @@
   "css/css-writing-modes/tools/generators/ucd/VerticalOrientation-16.txt": [
    "1447e4253eb776224ae991b2242dbc1746a59aaf",
    "support"
   ],
   "css/css-writing-modes/tools/generators/unicode-data.js": [
    "4d0d0734df208147f8cbf1fd3714bdb28a1a9ff5",
    "support"
   ],
+  "css/css-writing-modes/two-levels-of-orthogonal-flows-fixed.html": [
+   "69aacc3dd5e1ac08b06bbc7864eb7e17d4654814",
+   "reftest"
+  ],
+  "css/css-writing-modes/two-levels-of-orthogonal-flows-percentage.html": [
+   "4eec4534650ef7d9d432f2d8973daa580c28bf04",
+   "reftest"
+  ],
+  "css/css-writing-modes/two-levels-of-orthogonal-flows.html": [
+   "f21ac2df2a7b2d90efd8c555382ccb474592d370",
+   "reftest"
+  ],
   "css/css-writing-modes/underline-font-size-vlr-003.xht": [
    "6ebc3c3fc822319472f93b736aca59eaf6e9d95d",
    "visual"
   ],
   "css/css-writing-modes/underline-font-size-vlr-005.xht": [
    "63596e294809a9028a1cf3b3b45bce9448e10f11",
    "visual"
   ],
@@ -548543,17 +548843,17 @@
    "aece414b89e0fdea1030e4ca9011ab7d22f1b275",
    "testharness"
   ],
   "css/cssom/computed-style-004.html": [
    "55010cf90dc7fc2ef8ec6cbd13d1ec947a823aed",
    "testharness"
   ],
   "css/cssom/computed-style-set-property.html": [
-   "ce05e756acf5a53d37d854e5e635bb68febf84a1",
+   "cb05ff525eb659d43bf234d932fd860795959c9e",
    "testharness"
   ],
   "css/cssom/css-style-attr-decl-block.html": [
    "1d68a3fd1560308c0d2f3478864d84f4361e4ab9",
    "testharness"
   ],
   "css/cssom/css-style-attribute-modifications.html": [
    "935cae926defd9fe2203ef37af25288b9fdf92e1",
@@ -553315,25 +553615,25 @@
    "4a52e1328a6d3ce87d325803f9b21c934dcdf54b",
    "support"
   ],
   "css/vendor-imports/mozilla/mozilla-central-reftests/contain/contain-paint-clip-001-ref.html": [
    "1e710115a6ddf673f771a4f668c0be2912609442",
    "support"
   ],
   "css/vendor-imports/mozilla/mozilla-central-reftests/contain/contain-paint-clip-001.html": [
-   "2b106c772e9005287270f741a0ca8786e18d33c0",
+   "3688553c5cfd25d76feee6021794cc7273fe6cff",
    "reftest"
   ],
   "css/vendor-imports/mozilla/mozilla-central-reftests/contain/contain-paint-clip-002-ref.html": [
-   "2d4ada43bfe8c6863f56e1e0d2599d9151c6b4c6",
+   "185fa9ad94e9045ca490303e7256fd6ffb2cda03",
    "support"
   ],
   "css/vendor-imports/mozilla/mozilla-central-reftests/contain/contain-paint-clip-002.html": [
-   "c5538062ce33e225a09c01a48714187d206c6114",
+   "449b89844cf89f6ba2e3d27620255dab114a0755",
    "reftest"
   ],
   "css/vendor-imports/mozilla/mozilla-central-reftests/contain/contain-paint-clip-003-ref.html": [
    "3189218f9d3312f56f4ffaa04be17db936004c57",
    "support"
   ],
   "css/vendor-imports/mozilla/mozilla-central-reftests/contain/contain-paint-clip-003.html": [
    "354b9a2fdc94912d917d9528a268e46cae3ff83c",
@@ -553346,16 +553646,24 @@
   "css/vendor-imports/mozilla/mozilla-central-reftests/contain/contain-paint-clip-004.html": [
    "14271abdfab8e9495dd4c8e73bc7ea72ec45dfab",
    "reftest"
   ],
   "css/vendor-imports/mozilla/mozilla-central-reftests/contain/contain-paint-clip-005.html": [
    "5ab4438dae36c8fa2af8ee2bba12bb60be3837ac",
    "reftest"
   ],
+  "css/vendor-imports/mozilla/mozilla-central-reftests/contain/contain-paint-clip-006-ref.html": [
+   "a54e26fbb340e92d8049ae84191f7a59149e8bc2",
+   "support"
+  ],
+  "css/vendor-imports/mozilla/mozilla-central-reftests/contain/contain-paint-clip-006.html": [
+   "64b9266835318fb192c4d82319f98f64a8a1c03a",
+   "reftest"
+  ],
   "css/vendor-imports/mozilla/mozilla-central-reftests/contain/contain-paint-containing-block-absolute-001-ref.html": [
    "15047fbe1c488711c1d6c309242eb2d5838f8c7e",
    "support"
   ],
   "css/vendor-imports/mozilla/mozilla-central-reftests/contain/contain-paint-containing-block-absolute-001.html": [
    "e4c76a59f93fe875cd85be120d9b492621c6b13b",
    "reftest"
   ],
@@ -553391,17 +553699,17 @@
    "5e3d3c92160892f27ad68f404df1b4268ade951b",
    "reftest"
   ],
   "css/vendor-imports/mozilla/mozilla-central-reftests/contain/contain-paint-stacking-context-001b.html": [
    "eb0fef0df552a64733d7e46a1b8752d6825f1f8b",
    "reftest"
   ],
   "css/vendor-imports/mozilla/mozilla-central-reftests/contain/reftest.list": [
-   "361cc42bb96b840d65cdda9593a543388173c4a8",
+   "f13efa449db3e07a7fcec53072121e9d906f8562",
    "support"
   ],
   "css/vendor-imports/mozilla/mozilla-central-reftests/counter-styles-3/dependent-builtin-ref.html": [
    "d69196dab17976f19490ad2df62117f0317ecb32",
    "support"
   ],
   "css/vendor-imports/mozilla/mozilla-central-reftests/counter-styles-3/dependent-builtin.html": [
    "f689b57d004dc9b4de367c98b777291e954d3632",
@@ -557498,18 +557806,38 @@
   "css/vendor-imports/mozilla/mozilla-central-reftests/selectors4/focus-within-3.html": [
    "77a40c794be3488c77edc9528d53755dfc7214b5",
    "reftest"
   ],
   "css/vendor-imports/mozilla/mozilla-central-reftests/selectors4/reftest.list": [
    "76c907a127aec740e17d009a517acccd5d3e9fd4",
    "support"
   ],
+  "css/vendor-imports/mozilla/mozilla-central-reftests/shapes1/float-retry-push-circle.html": [
+   "64690b09c57ca1ef452e951b0f30f0815a36b87c",
+   "reftest"
+  ],
+  "css/vendor-imports/mozilla/mozilla-central-reftests/shapes1/float-retry-push-image.html": [
+   "c3f18f590da1061b2f6ac91fddd380d9c5faad84",
+   "reftest"
+  ],
+  "css/vendor-imports/mozilla/mozilla-central-reftests/shapes1/float-retry-push-inset.html": [
+   "d9bc1367e6f301b950703d58fae47193465350c5",
+   "reftest"
+  ],
+  "css/vendor-imports/mozilla/mozilla-central-reftests/shapes1/float-retry-push-polygon.html": [
+   "740aa634c9078e93554d81fa08d7ae17347dedfd",
+   "reftest"
+  ],
+  "css/vendor-imports/mozilla/mozilla-central-reftests/shapes1/float-retry-push-ref.html": [
+   "e4736754b5c44b272e94a2988dce8feb2e5478f2",
+   "support"
+  ],
   "css/vendor-imports/mozilla/mozilla-central-reftests/shapes1/reftest.list": [
-   "d2d4e66a63a2545ef445b286ed0f54123cb2ab4c",
+   "cb57bc22f6439ecdb953205569754e4cd23dfede",
    "support"
   ],
   "css/vendor-imports/mozilla/mozilla-central-reftests/shapes1/shape-outside-border-box-001-ref.html": [
    "f60b429f37b066f9a16dceeb19bfa8ed4f2b0623",
    "support"
   ],
   "css/vendor-imports/mozilla/mozilla-central-reftests/shapes1/shape-outside-border-box-001.html": [
    "633f57d18aa6315c4073ecfefb9d6ab2220e0fc1",
@@ -562707,17 +563035,17 @@
    "3825b5adbbd61c2eee537956079ec671e0d31911",
    "testharness"
   ],
   "dom/nodes/rootNode.html": [
    "9e57a68d7e39fcee75bdfb737de93bd6b6236b3a",
    "testharness"
   ],
   "dom/nodes/selectors.js": [
-   "3a0cb94b7778771dc6c5aefebf3441e393c5d155",
+   "d23a6e88e198f4f0f4495d6fd2775408d0635371",
    "support"
   ],
   "dom/ranges/Range-attributes.html": [
    "26309db23c48cfbd5aacdb970bc71a588f24e3eb",
    "testharness"
   ],
   "dom/ranges/Range-cloneContents.html": [
    "a932f2c082bf805d33dfcbc52f2ecf930d50da29",
@@ -570719,31 +571047,39 @@
    "37d2be417bbc3b8473c2d4bfaa3b7a9973140ce9",
    "support"
   ],
   "html/browsers/origin/origin-of-data-document.html": [
    "844b162882b27fd3ec0a07c8d4c1a6a6254b69ca",
    "testharness"
   ],
   "html/browsers/origin/relaxing-the-same-origin-restriction/document_domain.html": [
-   "9839a9c24ce78ec42da8a60d2175df06e19983c1",
+   "ecf33d6811deb94a89046b0ba6a82773f23ec44e",
    "testharness"
   ],
   "html/browsers/origin/relaxing-the-same-origin-restriction/document_domain_setter.html": [
-   "13210ebcc5093d24f7072e1dc43769ad6cb71048",
+   "dc537c0b9ac283297de91070195fc7f9a6f62c1b",
    "testharness"
   ],
   "html/browsers/origin/relaxing-the-same-origin-restriction/document_domain_setter_null.tentative.html": [
    "212e7be483bcb35413156231afcda8fe074558fc",
    "testharness"
   ],
   "html/browsers/origin/relaxing-the-same-origin-restriction/document_domain_setter_srcdoc.html": [
    "f707d1f40216d35afd04f4cd68cce66feaadddfd",
    "testharness"
   ],
+  "html/browsers/origin/relaxing-the-same-origin-restriction/sandboxed-document_domain.html": [
+   "a001d3c2e5215d1a33a336318d569322f5d159ab",
+   "testharness"
+  ],
+  "html/browsers/origin/relaxing-the-same-origin-restriction/sandboxed-document_domain.html.headers": [
+   "cb54f8c0ec6302182e257592a0dd933a316dfd08",
+   "support"
+  ],
   "html/browsers/origin/relaxing-the-same-origin-restriction/support/document_domain_frame.html": [
    "80d3d94c22642b2c07dae8f9cd8a50b563d36ef3",
    "support"
   ],
   "html/browsers/origin/relaxing-the-same-origin-restriction/support/document_domain_setter_iframe.html": [
    "d33427abcc87693bce1f5610f460aad12cb99759",
    "support"
   ],
@@ -571131,17 +571467,17 @@
    "06d489f3668c963c46c1ed31e9263d8717eab4e7",
    "testharness"
   ],
   "html/browsers/the-window-object/window-named-properties.html": [
    "21bb2b7a30381decf8b55152ba33cd723b67b8d5",
    "testharness"
   ],
   "html/browsers/the-window-object/window-open-noopener.html": [
-   "2e20bfcd1dfe9bee00a9747b87cdaf42004d6415",
+   "ee8d53b12b8034d1c0ede3b2c6516a345890915e",
    "testharness"
   ],
   "html/browsers/the-window-object/window-properties.https.html": [
    "ee0ade0a8de422597c362d15cf4a9dd446e4af00",
    "testharness"
   ],
   "html/browsers/the-window-object/window-prototype-chain.html": [
    "e2811af34d54079cbc716b51b2fc73aec1baba74",
@@ -588486,16 +588822,24 @@
   "infrastructure/webdriver/tests/conftest.py": [
    "6d9586273b0fd6c4bc1cc697402bb86af58f4d8c",
    "support"
   ],
   "infrastructure/webdriver/tests/test_load_file.py": [
    "c11d6b875af47f6134c98a23a7d2ce4fe4baa8c2",
    "wdspec"
   ],
+  "input-device-capabilities/OWNERS": [
+   "d4e4ff1ad12e54c45e32ff0b4938fe9a9b1f0f4d",
+   "support"
+  ],
+  "input-device-capabilities/interfaces.html": [
+   "327ff946ec80b347be627814ea9260ebd7ef6c1d",
+   "testharness"
+  ],
   "input-events/OWNERS": [
    "9e7b0206de5d60e7e0cf529e7b8987367c84c0f6",
    "support"
   ],
   "input-events/idlharness.html": [
    "51c7e4864c9ec4ce110cacbfc4cad2114f5eae01",
    "testharness"
   ],
@@ -588511,87 +588855,99 @@
    "1c8c1e8d43593ac85807f22fc221d72de0d792a2",
    "manual"
   ],
   "input-events/input-events-typing-manual.html": [
    "f585014db144083ee2f70f6fd65f78bf2e289093",
    "manual"
   ],
   "interfaces/BackgroundSync.idl": [
-   "f4812cb04b153d5f39e12e373b184c04d29b00fd",
+   "3f9bbca50917a8a3e27d4983fa792b6d2686552e",
    "support"
   ],
   "interfaces/DOM-Parsing.idl": [
    "4324fb1908608583b898ae01ad44d9f8e1da89ac",
    "support"
   ],
   "interfaces/FileAPI.idl": [
    "3fb06078e603a6010c2eb0fb45715c8cbda35678",
    "support"
   ],
   "interfaces/IndexedDB.idl": [
    "149cca0098cf37769391b4caa0650a7182ed8212",
    "support"
   ],
+  "interfaces/InputDeviceCapabilities.idl": [
+   "75bf10b0d1bda48c56cb5cd2ac1c73eb59f744fc",
+   "support"
+  ],
   "interfaces/OWNERS": [
    "389275a34cb76282af66797b3cd06b72a3b9ddbe",
    "support"
   ],
+  "interfaces/ResizeObserver.idl": [
+   "2835174993c1648c5f8e2a4639727118d62e2d77",
+   "support"
+  ],
   "interfaces/ServiceWorker.idl": [
    "7884feabcb4c9d0a447cccfa2359e3c45eef5455",
    "support"
   ],
   "interfaces/WebCryptoAPI.idl": [
    "1fa169a6badb1c21608f1e1a68075939e913603f",
    "support"
   ],
   "interfaces/accelerometer.idl": [
-   "a834258dac3ad510dec10425b9f79648547e0b42",
+   "07fc457b582a7abb689f923522c65fcce10d27a4",
    "support"
   ],
   "interfaces/ambient-light.idl": [
-   "bdede54deab80b5465f904a9726ee86f1260858d",
+   "623852530c2645b51347c82cea8fa72c0cb22f18",
    "support"
   ],
   "interfaces/background-fetch.idl": [
    "f2c8fc84af7bf785ba42f1398181e2ab08c3826a",
    "support"
   ],
   "interfaces/battery.idl": [
    "37550560186be55b56d226be2fdecc1e36574a6d",
    "support"
   ],
   "interfaces/budget-api.idl": [
-   "99f4eacad964a3ca3bcc034b48a2f4c4a2bd6f72",
+   "caba22c23688d761adef48dae1b58cc13a3e90ea",
    "support"
   ],
   "interfaces/clipboard-apis.idl": [
-   "66b014c6a2ba5cd8e0fbc83081d4c16ac4d46d39",
+   "f117178bf9731a8f33da624f48530b84f1ca90f4",
    "support"
   ],
   "interfaces/compat.idl": [
-   "5169148beaeb622da36a824a892421e86bf36c15",
+   "e674e142d1348afd587b566d86b9390ad8bc56a0",
    "support"
   ],
   "interfaces/console.idl": [
    "43ced34008dc73d05c79140d8dc33c60e2d9df3a",
    "support"
   ],
   "interfaces/cookie-store.idl": [
    "bb4c385873deafd746f186058b111193c8aebf01",
    "support"
   ],
   "interfaces/css-font-loading.idl": [
-   "a0d53cc4e88f38cce9fd45759963e5da9a6f3dc3",
+   "9f2f252c5b63c159d9680de46a932bfa4335bf11",
    "support"
   ],
   "interfaces/css-fonts.idl": [
    "ff2d83e9468c743993c9b4a1ecf3fab09684dc16",
    "support"
   ],
+  "interfaces/css-masking.idl": [
+   "5f4ed3d8922e30ab3ddb714d185c6e6f794e5a29",
+   "support"
+  ],
   "interfaces/css-typed-om.idl": [
    "36526913c07a04f9fd329a5650430db82407d766",
    "support"
   ],
   "interfaces/cssom-view.idl": [
    "3f575def818098d376ddf069673692530fcf8896",
    "support"
   ],
@@ -588611,73 +588967,73 @@
    "0dd77d1c6d854b0bdd003107c2385a224e1953f8",
    "support"
   ],
   "interfaces/encrypted-media.idl": [
    "ef1f1432c42fc6d01f3bfbd576fa5c7de349de96",
    "support"
   ],
   "interfaces/entries-api.idl": [
-   "6bb93df3e14e49931f54eead37a009649e035bd1",
+   "894cdcbceaa9834b8c90db155e1220482dfcc015",
    "support"
   ],
   "interfaces/feature-policy.idl": [
-   "cba4a18b5a6b69c467067dc4a7ac7449f39be6a1",
+   "ace338bf245dde3b21d3c65da64a5d0f6ad40fb2",
    "support"
   ],
   "interfaces/fetch.idl": [
-   "dd0830114bbed129ffd6af96b76ad0b1ec6ee5b5",
+   "e65b90887799ac8ea3d3e9cbde053d76466bd704",
    "support"
   ],
   "interfaces/filter-effects.idl": [
    "901c6d05e91de736ae1d627eca584e5c024786fa",
    "support"
   ],
   "interfaces/fullscreen.idl": [
-   "fda57b55aabdc54d674851851451c6c69c514ed1",
+   "7b193c37494543f8b0db4d9aea9e8e3b7c7b6212",
    "support"
   ],
   "interfaces/gamepad.idl": [
    "f112b177a27816085e46d4949b404f2d5666881a",
    "support"
   ],
   "interfaces/geolocation-sensor.idl": [
-   "7f5defe8969fd21ed1b8eeaedc9a766cb4b695c1",
+   "28bc4d15ea571290fe9e48e7c136bc3684e08660",
    "support"
   ],
   "interfaces/geometry.idl": [
-   "c757c625c0f5df3d677b5646bef04ac7075dbb64",
+   "8e057047db53832d0976414190a73eebb0b23f47",
    "support"
   ],
   "interfaces/gyroscope.idl": [
-   "7c37c98eb39d994a89314c45c216bcb27b51f2d1",
+   "cbc81fd6697557a4fe06090ec6351385539d2d36",
    "support"
   ],
   "interfaces/hr-time.idl": [
    "db4f313176e4fdfb8efd78545079da42cbb0729b",
    "support"
   ],
   "interfaces/html.idl": [
    "fe86c7370a537be87884d1b9da1f7b7630c6af41",
    "support"
   ],
   "interfaces/input-events.idl": [
    "99bcfa971e6b2628ab8ba174b772d56b23dee38b",
    "support"
   ],
   "interfaces/keyboard-lock.idl": [
-   "7188a9233db3acc741650d46156e16e9e7a132fa",
+   "de86b3ca38839202b4b31e055cfb6e18591b7857",
    "support"
   ],
   "interfaces/keyboard-map.idl": [
    "1e9e311a4d347d9f036702d29ef0bc82fca04162",
    "support"
   ],
   "interfaces/magnetometer.idl": [
-   "ffac480912edba82886fef6d5368092d237a0c7f",
+   "5839955446fafc91d9bd63d1549d7bc2e7afe499",
    "support"
   ],
   "interfaces/media-capabilities.idl": [
    "17413896d6281553091cf2c369c29de42d450962",
    "support"
   ],
   "interfaces/mediacapture-main.idl": [
    "3400c775504ebf32af3f8e1165a53ca60f258495",
@@ -588691,33 +589047,37 @@
    "1f0698a8611726b1ba724a5d7a0961e836c7b07e",
    "support"
   ],
   "interfaces/payment-handler.idl": [
    "6d9157e515e419c7a2fffc61a1f8e3b23a4550ba",
    "support"
   ],
   "interfaces/payment-request.idl": [
-   "594179265efe3f056059ba834da5e1873c3e6174",
+   "669b8faf18cb5c12f135e991279b90a48d71ee97",
+   "support"
+  ],
+  "interfaces/performance-timeline.idl": [
+   "57f26fe863d12c7672905d185e9a2c7ab9cb98a0",
    "support"
   ],
   "interfaces/permissions.idl": [
    "7fec46d25cf175390524b681cdbec7b0b76c89b9",
    "support"
   ],
   "interfaces/pointerevents.idl": [
    "29ca4e05813256592af7e9804e8135aaffdcc995",
    "support"
   ],
   "interfaces/pointerlock.idl": [
    "6d3ff2b3f8b4015f3cb282db2cd2dbb8c2e90db5",
    "support"
   ],
   "interfaces/proximity.idl": [
-   "74f2bf81a497589e7b3ed323368df218a70925a3",
+   "5416752c31de2d0f7a3b72941e24a0030d98599c",
    "support"
   ],
   "interfaces/remote-playback.idl": [
    "9ddb3a7bfce2454a3f7d835785db912f70521449",
    "support"
   ],
   "interfaces/screen-orientation.idl": [
    "ace5a4ae79933cdfd7ecf5c3801e93f0636fe57b",
@@ -588727,41 +589087,45 @@
    "c8c9e45b541e511673dbe8ddd1321dceef2856b4",
    "support"
   ],
   "interfaces/sensors.idl": [
    "3b2cb524838f2274463664621fddc7c927ac95af",
    "support"
   ],
   "interfaces/storage.idl": [
-   "7c3221be9fdf6be4965cf5aeca2063f93c2110d6",
+   "a1ad440d60e04902f494ecaced1fceb8560adc5c",
    "support"
   ],
   "interfaces/touchevents.idl": [
    "6ce4f601cda6cd3b99a300e0b28d2886647f06d3",
    "support"
   ],
   "interfaces/uievents.idl": [
-   "9e107e1ac2ed7195f802291f1d3827c53468a002",
+   "872f7b943e89660d3491bcb176dd1976ce21dc0f",
    "support"
   ],
   "interfaces/url.idl": [
-   "416ee65b3ba9e438a3178c6c04a414f42d759fc8",
+   "642e1ec46c8e57b579900f7cd10e99a8f80d552e",
+   "support"
+  ],
+  "interfaces/user-timing.idl": [
+   "41c00eec8e9c1b2137bd05e85bdc029b7a87c349",
    "support"
   ],
   "interfaces/vibration.idl": [
    "d1f3f51b0c6a46958d4bb3e9cc8bbc85e8a74512",
    "support"
   ],
   "interfaces/wake-lock.idl": [
    "7d0ee3d60a923bf454e18f9116cded1cc3a16f9b",
    "support"
   ],
   "interfaces/web-animations.idl": [
-   "8d00ee62fafedfd3e24925f48eed6ba26b5aafc7",
+   "a68224b17684bd43309bef57e7ad835f5f324a3a",
    "support"
   ],
   "interfaces/web-audio-api.idl": [
    "6e6a41a2b1dfde69171a8d28252cc3354c86b83e",
    "support"
   ],
   "interfaces/web-nfc.idl": [
    "c81f70e3dd5a703ce38211227017a56a6262cadf",
@@ -588770,30 +589134,34 @@
   "interfaces/web-share.idl": [
    "21b54128664c5962c29fd708ebba3d8d90987f26",
    "support"
   ],
   "interfaces/webauthn.idl": [
    "1ae8b428644479b352fd5b1996677fd4dcdbb84b",
    "support"
   ],
+  "interfaces/webdriver.idl": [
+   "6f6ce7d142a9b548988c9ab2a7a13f0f1793cf6a",
+   "support"
+  ],
   "interfaces/webidl.idl": [
    "d466ddd18ed621e15cc416863502069ffccfa5b9",
    "support"
   ],
   "interfaces/webrtc-pc.idl": [
    "a631e2e0ea0f451c64b5d5f74fe7cbeafc231b8e",
    "support"
   ],
   "interfaces/webusb.idl": [
    "1567268ad97c23f6709c835ba5d272c0982c0a59",
    "support"
   ],
   "interfaces/webvtt.idl": [
-   "3e7ab31795b8339de3d6904f0d68dab68ca24148",
+   "c48af511eb0260e34f3530457257d5eaaf879f57",
    "support"
   ],
   "interfaces/webxr.idl": [
    "b1bbaa67765ce6eb20c39e6f2234912e4853e148",
    "support"
   ],
   "interfaces/xhr.idl": [
    "00b3847513bf63b69f94a75662f31bc71f16b597",
@@ -588995,17 +589363,17 @@
    "581702f5f6b8f6e547918ae8f8a8547b103a9b6c",
    "testharness"
   ],
   "keyboard-lock/OWNERS": [
    "723bcf4599ad389962b61dd830818fc167049e7b",
    "support"
   ],
   "keyboard-lock/idlharness.https.html": [
-   "010771094a9dc58e03a2c1ca2d8416866284fc2b",
+   "d196b06e8606572e1e6c1a9e81e2f0920641c069",
    "testharness"
   ],
   "keyboard-lock/navigator-keyboard-lock-blocked-from-cross-origin-iframe.https.html": [
    "c51c1780a7c25938ee362234345f43711561fc73",
    "testharness"
   ],
   "keyboard-lock/navigator-keyboard-lock-blocked-from-iframe.https.html": [
    "381b3ce858035d2829b6a004b007fa1d06c9938b",
@@ -589015,17 +589383,17 @@
    "8d0517d7f78890aead8376dfa314220180d48b3e",
    "testharness"
   ],
   "keyboard-lock/navigator-keyboard-lock-two-sequential-requests.https.html": [
    "3bb9f7f6103efd0d58d394e65071d3aedb02035d",
    "testharness"
   ],
   "keyboard-lock/navigator-keyboard-lock.https.html": [
-   "6162fc3da9b7b104453e24b5da10d816a1a9425e",
+   "7fd35e9ffffeaa36a7fca0e57869cbc93e780e48",
    "testharness"
   ],
   "keyboard-lock/navigator-keyboard-unlock.https.html": [
    "f5cc2141ea7c74964d308784901d6d2c242f4369",
    "testharness"
   ],
   "keyboard-lock/resources/iframe-lock-helper.html": [
    "2ac2738dd428f3937fc2fd15dae2f98df5e3feb1",
@@ -589034,30 +589402,54 @@
   "keyboard-map/OWNERS": [
    "3151ee04a3b456d750df980594a192161868a337",
    "support"
   ],
   "keyboard-map/idlharness.https.html": [
    "3215b6729d83ca2841baf6eb33445eb07e0a7c25",
    "testharness"
   ],
-  "keyboard-map/keyboard-map-https.html": [
-   "28b559875ce9514702d181cb4cb5e0a207083e2d",
-   "testharness"
+  "keyboard-map/keyboard-map-two-parallel-requests.https.html": [
+   "44ead37a7118fb121dea19d9e381f647dbe6d6df",
+   "testharness"
+  ],
+  "keyboard-map/navigator-keyboard-map-blocked-from-cross-origin-iframe.https.html": [
+   "f49b379f64d6c83ad6ee8a8b9fcb34932a96ea08",
+   "testharness"
+  ],
+  "keyboard-map/navigator-keyboard-map-blocked-from-iframe.https.html": [
+   "df67fcd5adc8bc1c77a2b3abe2f7dd4c1b000958",
+   "testharness"
+  ],
+  "keyboard-map/navigator-keyboard-map-two-parallel-requests.https.html": [
+   "44ead37a7118fb121dea19d9e381f647dbe6d6df",
+   "testharness"
+  ],
+  "keyboard-map/navigator-keyboard-map-two-sequential-requests.https.html": [
+   "2d1166c6b09274bdce552a931d947a3fd1582ecc",
+   "testharness"
+  ],
+  "keyboard-map/navigator-keyboard-map.https.html": [
+   "a94a3c2ccc5c5a7f8ca96ba2035a4d7dd2a3b03e",
+   "testharness"
+  ],
+  "keyboard-map/resources/iframe-keyboard-map-helper.html": [
+   "545a86cb977d49303debac90d00339f1348f7f76",
+   "support"
   ],
   "lifecycle/freeze.html": [
    "79f45af08ff1cfe5c29d318fe6a32d281e990960",
    "testharness"
   ],
   "lifecycle/resources/foo.txt": [
    "b909d6288b51d2b2dfe06382f057a5892826949b",
    "support"
   ],
   "lifecycle/resources/window.html": [
-   "63fc6c451359b4efc3a72c9908d71dd999e43122",
+   "6ec159fbf686750e2866db1c1467c8f7e09c7e3c",
    "support"
   ],
   "longtask-timing/OWNERS": [
    "30a9c29ba53bac131c0cca801c01dddb4779824e",
    "support"
   ],
   "longtask-timing/longtask-attributes.html": [
    "247359327818f59871be00d22942f6ecde5281a7",
@@ -589638,18 +590030,18 @@
   "media-capabilities/README.md": [
    "7d6ceec9a74d5485a6f7d51504f22e5eaf81bfee",
    "support"
   ],
   "media-capabilities/decodingInfo.html": [
    "3cafa5d2375c8f42abee8f22293705eaa6dca019",
    "testharness"
   ],
-  "media-capabilities/idlharness.html": [
-   "47b8077cfff98cf07d5794ab32974ed4bc8d8a01",
+  "media-capabilities/idlharness.any.js": [
+   "23dff2a720b31aa5066a96a373ecc25e649719e7",
    "testharness"
   ],
   "media-source/OWNERS": [
    "90e737b8379ed92920c5f9f37ec653c758b93d9c",
    "support"
   ],
   "media-source/SourceBuffer-abort-readyState.html": [
    "37a54dbcd043c9bb53f51ccfc58ca42f91df0a24",
@@ -590371,17 +590763,17 @@
    "4704befc950341a16c061872e3d57fe9f0f743bf",
    "support"
   ],
   "mediasession/README.md": [
    "5ceecb2611837e6c52a303cec32d8cb9fabe93a6",
    "support"
   ],
   "mediasession/idlharness.html": [
-   "96a3bd3eb15a373ca1c68d528ff6514b3d7cddc1",
+   "e5b4267255f62b4505b3c656d2b377380f8dfab5",
    "testharness"
   ],
   "mediasession/mediametadata.html": [
    "0f0c1f7e3b58321a76229fa5a93e80b6863f181f",
    "testharness"
   ],
   "mediasession/playbackstate.html": [
    "e9edd18778d437b039bc45f2e3f35db725528447",
@@ -598874,18 +599266,18 @@
   "performance-timeline/OWNERS": [
    "b82f9756b15ef3ea45fb250e304031d9ceaee9c7",
    "support"
   ],
   "performance-timeline/case-sensitivity.any.js": [
    "9c6b6edf19800a2730de2dfe601a7cd2503cf87d",
    "testharness"
   ],
-  "performance-timeline/idlharness.html": [
-   "d6ce8e5c21b42843caea8e61c1637d75c2e51d64",
+  "performance-timeline/idlharness.any.js": [
+   "0a3ea0b532a1634008b776489b7409b348952d6f",
    "testharness"
   ],
   "performance-timeline/performanceentry-tojson.html": [
    "bc8a6f3fb13af9df11781a21b96f342e7d7ddf4e",
    "testharness"
   ],
   "performance-timeline/performanceobservers.js": [
    "0faeecf506da5b8a5c722a1ce8c7b5854227bca0",
@@ -607902,16 +608294,20 @@
   "resize-observer/OWNERS": [
    "59d77bdffdf0b2a5132447d23642f7a71bd3ba71",
    "support"
   ],
   "resize-observer/eventloop.html": [
    "a508a8bd68ef64bd826f76cc6f0967d2a5f1d3e9",
    "testharness"
   ],
+  "resize-observer/idlharness.html": [
+   "2b1960834f7164e351cdbba119694830055dcf17",
+   "testharness"
+  ],
   "resize-observer/notify.html": [
    "29f22b18a6ae894b80bec599dd71fc5050dbb292",
    "testharness"
   ],
   "resize-observer/observe.html": [
    "d86de600a53f4a804b0b88b751ca764d97c4c24a",
    "testharness"
   ],
@@ -610247,17 +610643,17 @@
    "c0d8abc53c14cefb1e58e8a3e7149b8bdae062a0",
    "testharness"
   ],
   "service-workers/service-worker/registration-service-worker-attributes.https.html": [
    "04a6fd8d3ff62fa4d969b629eb5f541c6447ae12",
    "testharness"
   ],
   "service-workers/service-worker/registration-updateviacache.https.html": [
-   "c5fe71cfb142f80d451f541accaa0120d9923f2b",
+   "7a640f15203c284cfa9b228da98c55efe5a2219d",
    "testharness"
   ],
   "service-workers/service-worker/rejections.https.html": [
    "785a18ac3c8001034f583a8e97195aa47093bd0d",
    "testharness"
   ],
   "service-workers/service-worker/request-end-to-end.https.html": [
    "e93efe04f35ff8c9ce15969a7b3f6373b098c4a8",
@@ -617039,17 +617435,17 @@
    "7c9707c02714de9a17989ecc71775978e994ae8a",
    "support"
   ],
   "url/resources/toascii.json": [
    "e8f5d819b9b4608d730a0a601e16ac2dd6c2d134",
    "support"
   ],
   "url/resources/urltestdata.json": [
-   "442c5f9d5faeb6752c8b33a04c73f3f3ba82ccb7",
+   "a0acd65cc414b97083cb92fa0f6fb4d12ba26288",
    "support"
   ],
   "url/toascii.window.js": [
    "0b9d59d1900f3440a5e631a9488207c2947ebf69",
    "testharness"
   ],
   "url/url-constructor.html": [
    "e1cc6dfc07040b019201dd7695b5171572f2fb8f",
@@ -617146,18 +617542,18 @@
   "user-timing/clear_one_measure.any.js": [
    "6759560cec2edbefa2e552ba86a0336d9d2274e7",
    "testharness"
   ],
   "user-timing/entry_type.any.js": [
    "bb08ac2ee06bc12e75cc44b76f06d3f0262f44ba",
    "testharness"
   ],
-  "user-timing/idlharness.html": [
-   "b24d4d5faf5df5d67135560d5fe362cc6d72c28f",
+  "user-timing/idlharness.any.js": [
+   "6a0dcd26b5ff16b18603c50b9257d55e6e25f0ce",
    "testharness"
   ],
   "user-timing/invoke_with_timing_attributes.html": [
    "05283be9a7230ba0c4af09fb5dac98d828bfaf2e",
    "testharness"
   ],
   "user-timing/invoke_with_timing_attributes.worker.js": [
    "f86e2132ced139cfe712a20ee4f64ba9e44459d2",
@@ -620267,17 +620663,17 @@
    "8d687026889e601f4c1987996f4e5306b0f627f9",
    "wdspec"
   ],
   "webdriver/tests/get_window_rect/user_prompts.py": [
    "c91b4d09f4f76067c159236b016b375c34baa117",
    "wdspec"
   ],
   "webdriver/tests/interface.html": [
-   "f7b2c45ff8b1b5790dd390fbe2ab997766f5d9a8",
+   "0b88587deabc7a4577da90bdf6d874e596b9a240",
    "testharness"
   ],
   "webdriver/tests/is_element_selected/__init__.py": [
    "da39a3ee5e6b4b0d3255bfef95601890afd80709",
    "support"
   ],
   "webdriver/tests/is_element_selected/selected.py": [
    "afed5bfc86527410e0fb521f7f75d79bee1fb060",
@@ -621079,17 +621475,17 @@
    "913cbc3d2aaf724e70108e7854f56ad5bb9b2283",
    "testharness"
   ],
   "webrtc/RTCPeerConnection-getTransceivers.html": [
    "b4c97af4f907a3d02fe1ebd24f00ab110b387575",
    "testharness"
   ],
   "webrtc/RTCPeerConnection-helper.js": [
-   "52be74a05870c95a459b1dade4af3290a2cfa05c",
+   "8c1a170c3afeca86cbac1fc06069e9732227aaae",
    "support"
   ],
   "webrtc/RTCPeerConnection-iceConnectionState.html": [
    "dad0787100a817c05dd871bf892a94464916a74a",
    "testharness"
   ],
   "webrtc/RTCPeerConnection-iceGatheringState.html": [
    "ed3226f9673bc0b69c2a9f9ec6e1ccfa8e83e2e2",
@@ -621155,25 +621551,25 @@
    "38f2588fadab58203a7f22d25e0d828b1373fbd3",
    "testharness"
   ],
   "webrtc/RTCPeerConnection-setRemoteDescription-rollback.html": [
    "6614b5b0febd718a94bbec110568b9aaf80dc9eb",
    "testharness"
   ],
   "webrtc/RTCPeerConnection-setRemoteDescription-tracks.https.html": [
-   "16fe3b155e55d1b66181788c93e570b36e5cc67d",
+   "3f1bcf8c14486cac9baf7fba1d4cedab16e172f1",
    "testharness"
   ],
   "webrtc/RTCPeerConnection-setRemoteDescription.html": [
    "8a3e2f1e157e1ceed18ac66e57040a941b658f24",
    "testharness"
   ],
   "webrtc/RTCPeerConnection-track-stats.https.html": [
-   "401279780028dc08d5d9315748d83e29665685f1",
+   "c764f697b787a50882375dec88d32c6be515a9d4",
    "testharness"
   ],
   "webrtc/RTCPeerConnectionIceEvent-constructor.html": [
    "f273bd7fdfc883a15e8fb16fef5309061254c6cc",
    "testharness"
   ],
   "webrtc/RTCRtpCapabilities-helper.js": [
    "22881ddd3cda1a64ff22474562de1568522e9745",
--- a/testing/web-platform/meta/WebCryptoAPI/wrapKey_unwrapKey/test_wrapKey_unwrapKey.https.html.ini
+++ b/testing/web-platform/meta/WebCryptoAPI/wrapKey_unwrapKey/test_wrapKey_unwrapKey.https.html.ini
@@ -1,12 +1,11 @@
 [test_wrapKey_unwrapKey.https.html]
   disabled:
     if verify and not debug: fails in verify mode
-
   [Can wrap and unwrap AES-KW keys using raw and AES-CBC]
     expected: FAIL
 
   [Can wrap and unwrap AES-KW keys as non-extractable using raw and AES-CBC]
     expected: FAIL
 
   [Can wrap and unwrap AES-KW keys using jwk and AES-CBC]
     expected: FAIL
--- a/testing/web-platform/meta/accelerometer/idlharness.https.html.ini
+++ b/testing/web-platform/meta/accelerometer/idlharness.https.html.ini
@@ -369,11 +369,8 @@
     expected: FAIL
 
   [Sensor interface: new LinearAccelerationSensor(); must inherit property "hasReading" with the proper type]
     expected: FAIL
 
   [Sensor interface: new GravitySensor(); must inherit property "hasReading" with the proper type]
     expected: FAIL
 
-  [Test IDL implementation of Accelerometer Sensor]
-    expected: FAIL
-
--- a/testing/web-platform/meta/ambient-light/idlharness.https.html.ini
+++ b/testing/web-platform/meta/ambient-light/idlharness.https.html.ini
@@ -183,11 +183,8 @@
     expected: FAIL
 
   [Sensor interface: new AmbientLightSensor() must inherit property "onactivate" with the proper type]
     expected: FAIL
 
   [Sensor interface: new AmbientLightSensor() must inherit property "onerror" with the proper type]
     expected: FAIL
 
-  [Test IDL implementation of Ambient Light Sensor]
-    expected: FAIL
-
--- a/testing/web-platform/meta/budget-api/interfaces.any.js.ini
+++ b/testing/web-platform/meta/budget-api/interfaces.any.js.ini
@@ -1,9 +1,111 @@
 [interfaces.any.html]
-  [budget-api interfaces.]
+  [Navigator interface: attribute budget]
+    expected: FAIL
+
+  [BudgetService interface: existence and properties of interface object]
+    expected: FAIL
+
+  [BudgetService interface object length]
+    expected: FAIL
+
+  [BudgetService interface object name]
+    expected: FAIL
+
+  [BudgetService interface: existence and properties of interface prototype object]
+    expected: FAIL
+
+  [BudgetService interface: existence and properties of interface prototype object's "constructor" property]
+    expected: FAIL
+
+  [BudgetService interface: existence and properties of interface prototype object's @@unscopables property]
+    expected: FAIL
+
+  [BudgetService interface: operation getCost(OperationType)]
+    expected: FAIL
+
+  [BudgetService interface: operation getBudget()]
+    expected: FAIL
+
+  [BudgetService interface: operation reserve(OperationType)]
+    expected: FAIL
+
+  [BudgetState interface: existence and properties of interface object]
+    expected: FAIL
+
+  [BudgetState interface object length]
+    expected: FAIL
+
+  [BudgetState interface object name]
+    expected: FAIL
+
+  [BudgetState interface: existence and properties of interface prototype object]
+    expected: FAIL
+
+  [BudgetState interface: existence and properties of interface prototype object's "constructor" property]
+    expected: FAIL
+
+  [BudgetState interface: existence and properties of interface prototype object's @@unscopables property]
+    expected: FAIL
+
+  [BudgetState interface: attribute budgetAt]
+    expected: FAIL
+
+  [BudgetState interface: attribute time]
     expected: FAIL
 
 
 [interfaces.any.worker.html]
-  [budget-api interfaces.]
+  [WorkerNavigator interface: attribute budget]
+    expected: FAIL
+
+  [BudgetService interface: existence and properties of interface object]
+    expected: FAIL
+
+  [BudgetService interface object length]
+    expected: FAIL
+
+  [BudgetService interface object name]
+    expected: FAIL
+
+  [BudgetService interface: existence and properties of interface prototype object]
+    expected: FAIL
+
+  [BudgetService interface: existence and properties of interface prototype object's "constructor" property]
+    expected: FAIL
+
+  [BudgetService interface: existence and properties of interface prototype object's @@unscopables property]
+    expected: FAIL
+
+  [BudgetService interface: operation getCost(OperationType)]
+    expected: FAIL
+
+  [BudgetService interface: operation getBudget()]
     expected: FAIL
 
+  [BudgetService interface: operation reserve(OperationType)]
+    expected: FAIL
+
+  [BudgetState interface: existence and properties of interface object]
+    expected: FAIL
+
+  [BudgetState interface object length]
+    expected: FAIL
+
+  [BudgetState interface object name]
+    expected: FAIL
+
+  [BudgetState interface: existence and properties of interface prototype object]
+    expected: FAIL
+
+  [BudgetState interface: existence and properties of interface prototype object's "constructor" property]
+    expected: FAIL
+
+  [BudgetState interface: existence and properties of interface prototype object's @@unscopables property]
+    expected: FAIL
+
+  [BudgetState interface: attribute budgetAt]
+    expected: FAIL
+
+  [BudgetState interface: attribute time]
+    expected: FAIL
+
--- a/testing/web-platform/meta/content-security-policy/reporting/report-strips-fragment.html.ini
+++ b/testing/web-platform/meta/content-security-policy/reporting/report-strips-fragment.html.ini
@@ -1,8 +1,7 @@
 [report-strips-fragment.html]
   disabled:
     if verify: fails in verify mode
-
   expected: TIMEOUT
   [Reported document URI does not contain fragments.]
     expected: TIMEOUT
 
--- a/testing/web-platform/meta/cookies/http-state/attribute-tests.html.ini
+++ b/testing/web-platform/meta/cookies/http-state/attribute-tests.html.ini
@@ -1,12 +1,11 @@
 [attribute-tests.html]
   disabled:
     if verify: fails in verify mode
-
   [attribute0004 - Ignore cookie for for Secure= attribute.]
     expected: FAIL
 
   [attribute0005 - Ignore cookie for Secure=aaaa]
     expected: FAIL
 
   [attribute0007 - Ignore cookie for Secure space equals.]
     expected: FAIL
--- a/testing/web-platform/meta/cookies/http-state/general-tests.html.ini
+++ b/testing/web-platform/meta/cookies/http-state/general-tests.html.ini
@@ -1,12 +1,11 @@
 [general-tests.html]
   disabled:
     if verify: fails in verify mode
-
   [0004 - Ignore cookie without key.]
     expected: FAIL
 
   [0005 - Set cookie with age.]
     expected: FAIL
 
   [0006 - Set no cookie with max-age=0.]
     expected: FAIL
--- a/testing/web-platform/meta/cookies/secure/cookie-forcing.html.ini
+++ b/testing/web-platform/meta/cookies/secure/cookie-forcing.html.ini
@@ -1,8 +1,7 @@
 [cookie-forcing.html]
   disabled:
     if debug and not e10s and (os == "linux"): https://bugzilla.mozilla.org/show_bug.cgi?id=1461905
     if verify and not debug: fails in verify mode
-
   [non-secure origins should be able to force out insecure cookies.]
     expected: FAIL
 
deleted file mode 100644
--- a/testing/web-platform/meta/css/css-animations/set-animation-play-state-to-paused-002.html.ini
+++ /dev/null
@@ -1,5 +0,0 @@
-[set-animation-play-state-to-paused-002.html]
-  expected:
-    if not debug and webrender and e10s and (os == "linux") and (version == "Ubuntu 16.04") and (processor == "x86_64") and (bits == 64): PASS
-    if debug and webrender and e10s and (os == "linux") and (version == "Ubuntu 16.04") and (processor == "x86_64") and (bits == 64): PASS
-    FAIL
--- a/testing/web-platform/meta/css/css-font-loading/idlharness.https.html.ini
+++ b/testing/web-platform/meta/css/css-font-loading/idlharness.https.html.ini
@@ -1,10 +1,7 @@
 [idlharness.https.html]
   [FontFace interface: attribute variationSettings]
     expected: FAIL
 
   [FontFaceSet interface object length]
     expected: FAIL
 
-  [Test IDL implementation of CSS Font Loading]
-    expected: FAIL
-
--- a/testing/web-platform/meta/css/css-multicol/zero-column-width-layout.html.ini
+++ b/testing/web-platform/meta/css/css-multicol/zero-column-width-layout.html.ini
@@ -1,2 +1,3 @@
 [zero-column-width-layout.html]
-  expected: FAIL
+  expected:
+    FAIL
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/css/css-writing-modes/three-levels-of-orthogonal-flows.html.ini
@@ -0,0 +1,2 @@
+[three-levels-of-orthogonal-flows.html]
+  expected: FAIL
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/css/css-writing-modes/two-levels-of-orthogonal-flows-fixed.html.ini
@@ -0,0 +1,2 @@
+[two-levels-of-orthogonal-flows-fixed.html]
+  expected: FAIL
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/css/css-writing-modes/two-levels-of-orthogonal-flows-percentage.html.ini
@@ -0,0 +1,2 @@
+[two-levels-of-orthogonal-flows-percentage.html]
+  expected: FAIL
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/css/css-writing-modes/two-levels-of-orthogonal-flows.html.ini
@@ -0,0 +1,2 @@
+[two-levels-of-orthogonal-flows.html]
+  expected: FAIL
--- a/testing/web-platform/meta/css/vendor-imports/mozilla/mozilla-central-reftests/images3/object-position-svg-001e.html.ini
+++ b/testing/web-platform/meta/css/vendor-imports/mozilla/mozilla-central-reftests/images3/object-position-svg-001e.html.ini
@@ -1,3 +1,3 @@
 [object-position-svg-001e.html]
-  expected:
-    FAIL
+  expected: FAIL
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/css/vendor-imports/mozilla/mozilla-central-reftests/shapes1/float-retry-push-image.html.ini
@@ -0,0 +1,2 @@
+[float-retry-push-image.html]
+  expected: FAIL
--- a/testing/web-platform/meta/custom-elements/Document-createElement.html.ini
+++ b/testing/web-platform/meta/custom-elements/Document-createElement.html.ini
@@ -2,8 +2,9 @@
   [document.createElement must report a NotSupportedError when the element is adopted into a the document of an iframe during construction]
     expected: FAIL
 
   [document.createElement must report a NotSupportedError when the element is inserted into a the document of an iframe during construction]
     expected: FAIL
 
   [document.createElement must not report a NotSupportedError when the element is adopted back from a the document of an iframe during construction]
     expected: FAIL
+
--- a/testing/web-platform/meta/custom-elements/Document-createElementNS.html.ini
+++ b/testing/web-platform/meta/custom-elements/Document-createElementNS.html.ini
@@ -1,3 +1,4 @@
 [Document-createElementNS.html]
   [autonomous: document.createElementNS should create custom elements with prefixes.]
     expected: FAIL
+
--- a/testing/web-platform/meta/domparsing/interfaces.any.js.ini
+++ b/testing/web-platform/meta/domparsing/interfaces.any.js.ini
@@ -1,12 +1,6 @@
 [interfaces.any.html]
   [Text interface: attribute serializeAsCDATA]
     expected: FAIL
 
-  [Test driver]
-    expected: FAIL
-
 
 [interfaces.any.worker.html]
-  [Test driver]
-    expected: FAIL
-
--- a/testing/web-platform/meta/fetch/api/request/destination/fetch-destination-no-load-event.https.html.ini
+++ b/testing/web-platform/meta/fetch/api/request/destination/fetch-destination-no-load-event.https.html.ini
@@ -1,4 +1,3 @@
 [fetch-destination-no-load-event.https.html]
   disabled:
     if verify: fails in verify mode
-
deleted file mode 100644
--- a/testing/web-platform/meta/fetch/api/request/fetch-destination-no-load-event.https.html.ini
+++ /dev/null
@@ -1,4 +0,0 @@
-[fetch-destination-no-load-event.https.html]
-  disabled:
-    if verify && (os == "linux") && not debug: fails in verify mode
-
--- a/testing/web-platform/meta/fullscreen/interfaces.html.ini
+++ b/testing/web-platform/meta/fullscreen/interfaces.html.ini
@@ -21,11 +21,8 @@
     expected: FAIL
 
   [Element interface: document.createElementNS(null, "test") must inherit property "onfullscreenchange" with the proper type]
     expected: FAIL
 
   [Element interface: document.createElementNS(null, "test") must inherit property "onfullscreenerror" with the proper type]
     expected: FAIL
 
-  [Test driver]
-    expected: FAIL
-
--- a/testing/web-platform/meta/generic-sensor/idlharness.https.html.ini
+++ b/testing/web-platform/meta/generic-sensor/idlharness.https.html.ini
@@ -66,11 +66,8 @@
     expected: FAIL
 
   [Stringification of new SensorErrorEvent("error", { error: new DOMException });]
     expected: FAIL
 
   [SensorErrorEvent interface: new SensorErrorEvent("error", { error: new DOMException }); must inherit property "error" with the proper type]
     expected: FAIL
 
-  [Test IDL implementation of Generic Sensor]
-    expected: FAIL
-
--- a/testing/web-platform/meta/gyroscope/idlharness.https.html.ini
+++ b/testing/web-platform/meta/gyroscope/idlharness.https.html.ini
@@ -189,11 +189,8 @@
     expected: FAIL
 
   [Sensor interface: attribute hasReading]
     expected: FAIL
 
   [Sensor interface: new Gyroscope(); must inherit property "hasReading" with the proper type]
     expected: FAIL
 
-  [Test IDL implementation of Gyroscope Sensor]
-    expected: FAIL
-
--- a/testing/web-platform/meta/html/browsers/offline/appcache/workers/appcache-worker.https.html.ini
+++ b/testing/web-platform/meta/html/browsers/offline/appcache/workers/appcache-worker.https.html.ini
@@ -1,12 +1,11 @@
 [appcache-worker.https.html]
   disabled:
     if verify: fails in verify mode
-
   expected: TIMEOUT
   [Shared worker of the cached script]
     expected: FAIL
 
   [Shared worker of the fallbacked script]
     expected: TIMEOUT
 
   [Shared worker of the not-in-cache script]
--- a/testing/web-platform/meta/html/browsers/origin/relaxing-the-same-origin-restriction/document_domain.html.ini
+++ b/testing/web-platform/meta/html/browsers/origin/relaxing-the-same-origin-restriction/document_domain.html.ini
@@ -1,4 +1,7 @@
 [document_domain.html]
   [new document]
     expected: FAIL
 
+  [new Document()]
+    expected: FAIL
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/html/browsers/origin/relaxing-the-same-origin-restriction/document_domain_setter.html.ini
@@ -0,0 +1,4 @@
+[document_domain_setter.html]
+  [failed setting of document.domain for documents without browsing context]
+    expected: FAIL
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/html/browsers/origin/relaxing-the-same-origin-restriction/sandboxed-document_domain.html.ini
@@ -0,0 +1,13 @@
+[sandboxed-document_domain.html]
+  [Sandboxed document.domain 1]
+    expected: FAIL
+
+  [Sandboxed document.domain 2]
+    expected: FAIL
+
+  [Sandboxed document.domain 3]
+    expected: FAIL
+
+  [Sandboxed document.domain 4]
+    expected: FAIL
+
--- a/testing/web-platform/meta/html/browsers/the-window-object/apis-for-creating-and-navigating-browsing-contexts-by-name/open-features-tokenization-screenx-screeny.html.ini
+++ b/testing/web-platform/meta/html/browsers/the-window-object/apis-for-creating-and-navigating-browsing-contexts-by-name/open-features-tokenization-screenx-screeny.html.ini
@@ -1,11 +1,10 @@
 [open-features-tokenization-screenx-screeny.html]
   disabled:
     if webrender and not debug: bug 1425588
     if verify and (os == "linux") and not debug: fails in verify mode
-
   ["screenx==141" should set left position of opened window]
     expected: FAIL
 
   ["screeny==142" should set top position of opened window]
     expected: FAIL
 
--- a/testing/web-platform/meta/html/browsers/the-window-object/apis-for-creating-and-navigating-browsing-contexts-by-name/open-features-tokenization-top-left.html.ini
+++ b/testing/web-platform/meta/html/browsers/the-window-object/apis-for-creating-and-navigating-browsing-contexts-by-name/open-features-tokenization-top-left.html.ini
@@ -1,13 +1,12 @@
 [open-features-tokenization-top-left.html]
   disabled:
     if webrender and not debug: bug 1425588
     if verify and (os == "linux") and not debug: fails in verify mode
-
   ["left==141" should set left position of opened window]
     expected: FAIL
 
   ["top==142" should set top position of opened window]
     expected: FAIL
 
   ["top=152==left=152" should set top and left position of opened window]
     expected: FAIL
deleted file mode 100644
--- a/testing/web-platform/meta/html/browsers/the-window-object/window-open-noopener.html.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[window-open-noopener.html]
-  disabled:
-    if webrender: bug 1425588
--- a/testing/web-platform/meta/html/browsers/windows/noreferrer-window-name.html.ini
+++ b/testing/web-platform/meta/html/browsers/windows/noreferrer-window-name.html.ini
@@ -1,4 +1,3 @@
 [noreferrer-window-name.html]
   disabled:
     if verify: fails in verify mode
-
--- a/testing/web-platform/meta/html/infrastructure/urls/resolving-urls/query-encoding/attributes.sub.html.ini
+++ b/testing/web-platform/meta/html/infrastructure/urls/resolving-urls/query-encoding/attributes.sub.html.ini
@@ -1,10 +1,8 @@
-[attributes.sub.html?encoding=utf8]
-
 [attributes.sub.html?encoding=x-cp1251]
   [getComputedStyle <body background>]
     expected: FAIL
 
   [getComputedStyle <table background>]
     expected: FAIL
 
   [getComputedStyle <thead background>]
@@ -68,8 +66,10 @@
     expected: FAIL
 
   [Getting <button>.formAction]
     expected: FAIL
 
   [Getting <script>.src]
     expected: FAIL
 
+
+[attributes.sub.html?encoding=utf8]
--- a/testing/web-platform/meta/html/rendering/bindings/the-textarea-element-0/cols-zero.html.ini
+++ b/testing/web-platform/meta/html/rendering/bindings/the-textarea-element-0/cols-zero.html.ini
@@ -1,6 +1,5 @@
 [cols-zero.html]
   disabled:
     if verify and (os == "mac"): fails in verify mode
-
   expected:
     if os == "mac": FAIL
--- a/testing/web-platform/meta/html/rendering/bindings/the-textarea-element-0/rows-zero.html.ini
+++ b/testing/web-platform/meta/html/rendering/bindings/the-textarea-element-0/rows-zero.html.ini
@@ -1,6 +1,5 @@
 [rows-zero.html]
   disabled:
     if verify and (os == "mac"): fails in verify mode
-
   expected:
     if e10s and (os == "mac") and (version == "OS X 10.10.5") and (processor == "x86_64") and (bits == 64): FAIL
--- a/testing/web-platform/meta/html/rendering/non-replaced-elements/lists/ol-type-unsupported-invalid.html.ini
+++ b/testing/web-platform/meta/html/rendering/non-replaced-elements/lists/ol-type-unsupported-invalid.html.ini
@@ -1,6 +1,5 @@
 [ol-type-unsupported-invalid.html]
   disabled:
     if verify and (os == "mac"): fails in verify mode
-
   expected:
     if e10s and (os == "mac") and (version == "OS X 10.10.5") and (processor == "x86_64") and (bits == 64): FAIL
--- a/testing/web-platform/meta/html/rendering/non-replaced-elements/lists/ul-type-supported-xhtml.xhtml.ini
+++ b/testing/web-platform/meta/html/rendering/non-replaced-elements/lists/ul-type-supported-xhtml.xhtml.ini
@@ -1,6 +1,5 @@
 [ul-type-supported-xhtml.xhtml]
   disabled:
     if verify and (os == "mac"): fails in verify mode
-
   expected:
     if e10s and (os == "mac") and (version == "OS X 10.10.5") and (processor == "x86_64") and (bits == 64): FAIL
--- a/testing/web-platform/meta/html/rendering/non-replaced-elements/lists/ul-type-supported.html.ini
+++ b/testing/web-platform/meta/html/rendering/non-replaced-elements/lists/ul-type-supported.html.ini
@@ -1,6 +1,5 @@
 [ul-type-supported.html]
   disabled:
     if verify and (os == "mac"): fails in verify mode
-
   expected:
     if e10s and (os == "mac") and (version == "OS X 10.10.5") and (processor == "x86_64") and (bits == 64): FAIL
--- a/testing/web-platform/meta/html/rendering/non-replaced-elements/lists/ul-type-unsupported-invalid.html.ini
+++ b/testing/web-platform/meta/html/rendering/non-replaced-elements/lists/ul-type-unsupported-invalid.html.ini
@@ -1,6 +1,5 @@
 [ul-type-unsupported-invalid.html]
   disabled:
     if verify and (os == "mac"): fails in verify mode
-
   expected:
     if e10s and (os == "mac") and (version == "OS X 10.10.5") and (processor == "x86_64") and (bits == 64): FAIL
--- a/testing/web-platform/meta/html/rendering/the-details-element/details-before.html.ini
+++ b/testing/web-platform/meta/html/rendering/the-details-element/details-before.html.ini
@@ -1,8 +1,7 @@
 [details-before.html]
   disabled:
     if verify and (os == "mac"): fails in verify mode
-
   expected:
     if debug and not webrender and e10s and (os == "mac") and (version == "OS X 10.10.5") and (processor == "x86_64") and (bits == 64): PASS
     if not debug and not webrender and e10s and (os == "mac") and (version == "OS X 10.10.5") and (processor == "x86_64") and (bits == 64): PASS
     FAIL
--- a/testing/web-platform/meta/html/semantics/embedded-content/image-maps/image-map-processing-model/hash-name-reference.html.ini
+++ b/testing/web-platform/meta/html/semantics/embedded-content/image-maps/image-map-processing-model/hash-name-reference.html.ini
@@ -1,12 +1,11 @@
 [hash-name-reference.html]
   disabled:
     if verify and debug: fails in verify mode
-
   max-asserts: 52
   [HTML (standards) IMG usemap="#hash-name"]
     expected: FAIL
 
   [HTML (standards) OBJECT usemap="#hash-name"]
     expected: FAIL
 
   [HTML (standards) IMG usemap="#hash-id"]
--- a/testing/web-platform/meta/html/semantics/embedded-content/media-elements/video_008.htm.ini
+++ b/testing/web-platform/meta/html/semantics/embedded-content/media-elements/video_008.htm.ini
@@ -1,4 +1,3 @@
 [video_008.htm]
   disabled:
     if verify and (os == "win") and not debug: fails in verify mode
-
--- a/testing/web-platform/meta/html/semantics/embedded-content/the-iframe-element/iframe-with-base.html.ini
+++ b/testing/web-platform/meta/html/semantics/embedded-content/the-iframe-element/iframe-with-base.html.ini
@@ -1,6 +1,5 @@
 [iframe-with-base.html]
   disabled:
     if verify and (os == "mac"): fails in verify mode
-
   expected:
     if e10s and (os == "mac") and (version == "OS X 10.10.5") and (processor == "x86_64") and (bits == 64): FAIL
--- a/testing/web-platform/meta/html/semantics/embedded-content/the-img-element/document-adopt-base-url.html.ini
+++ b/testing/web-platform/meta/html/semantics/embedded-content/the-img-element/document-adopt-base-url.html.ini
@@ -1,6 +1,5 @@
 [document-adopt-base-url.html]
   disabled:
     if verify and (os == "mac"): fails in verify mode
-
   expected:
     if os == "mac": FAIL
--- a/testing/web-platform/meta/infrastructure/reftest/reftest_match.html.ini
+++ b/testing/web-platform/meta/infrastructure/reftest/reftest_match.html.ini
@@ -1,7 +1,6 @@
 [reftest_match.html]
   disabled:
     if verify and (os == "mac"): fails in verify mode
-
   expected:
     if debug and not webrender and e10s and (os == "mac") and (version == "OS X 10.10.5") and (processor == "x86_64") and (bits == 64): FAIL
     if not debug and not webrender and e10s and (os == "mac") and (version == "OS X 10.10.5") and (processor == "x86_64") and (bits == 64): FAIL
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/input-device-capabilities/interfaces.html.ini
@@ -0,0 +1,40 @@
+[interfaces.html]
+  [InputDeviceCapabilities interface: existence and properties of interface object]
+    expected: FAIL
+
+  [InputDeviceCapabilities interface object length]
+    expected: FAIL
+
+  [InputDeviceCapabilities interface object name]
+    expected: FAIL
+
+  [InputDeviceCapabilities interface: existence and properties of interface prototype object]
+    expected: FAIL
+
+  [InputDeviceCapabilities interface: existence and properties of interface prototype object's "constructor" property]
+    expected: FAIL
+
+  [InputDeviceCapabilities interface: existence and properties of interface prototype object's @@unscopables property]
+    expected: FAIL
+
+  [InputDeviceCapabilities interface: attribute firesTouchEvents]
+    expected: FAIL
+
+  [InputDeviceCapabilities interface: attribute pointerMovementScrolls]
+    expected: FAIL
+
+  [InputDeviceCapabilities must be primary interface of new InputDeviceCapabilities]
+    expected: FAIL
+
+  [Stringification of new InputDeviceCapabilities]
+    expected: FAIL
+
+  [InputDeviceCapabilities interface: new InputDeviceCapabilities must inherit property "firesTouchEvents" with the proper type]
+    expected: FAIL
+
+  [InputDeviceCapabilities interface: new InputDeviceCapabilities must inherit property "pointerMovementScrolls" with the proper type]
+    expected: FAIL
+
+  [UIEvent interface: attribute sourceCapabilities]
+    expected: FAIL
+
--- a/testing/web-platform/meta/keyboard-lock/navigator-keyboard-lock.https.html.ini
+++ b/testing/web-platform/meta/keyboard-lock/navigator-keyboard-lock.https.html.ini
@@ -1,4 +1,13 @@
 [navigator-keyboard-lock.https.html]
   [[Keyboard Lock\] keyboard.lock]
     expected: FAIL
 
+  [navigator.keyboard instanceof Keyboard]
+    expected: FAIL
+
+  [navigator.keyboard.lock instanceof Function]
+    expected: FAIL
+
+  [navigator.keyboard.unlock instanceof Function]
+    expected: FAIL
+
deleted file mode 100644
--- a/testing/web-platform/meta/keyboard-map/keyboard-map-https.html.ini
+++ /dev/null
@@ -1,7 +0,0 @@
-[keyboard-map-https.html]
-  [navigator.keyboard instanceof Keyboard]
-    expected: FAIL
-
-  [navigator.keyboard.getLayoutMap() returns a Promise<KeyboardLayoutMap> when successful]
-    expected: FAIL
-
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/keyboard-map/keyboard-map-two-parallel-requests.https.html.ini
@@ -0,0 +1,4 @@
+[keyboard-map-two-parallel-requests.https.html]
+  [[Keyboard Map\] getLayoutMap() twice in parallel]
+    expected: FAIL
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/keyboard-map/navigator-keyboard-map-blocked-from-cross-origin-iframe.https.html.ini
@@ -0,0 +1,5 @@
+[navigator-keyboard-map-blocked-from-cross-origin-iframe.https.html]
+  expected: TIMEOUT
+  [[Keyboard Map\] getLayoutMap() blocked from within cross-origin iframe]
+    expected: TIMEOUT
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/keyboard-map/navigator-keyboard-map-blocked-from-iframe.https.html.ini
@@ -0,0 +1,5 @@
+[navigator-keyboard-map-blocked-from-iframe.https.html]
+  expected: TIMEOUT
+  [[Keyboard Map\] getLayoutMap() blocked from within iframe]
+    expected: TIMEOUT
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/keyboard-map/navigator-keyboard-map-two-parallel-requests.https.html.ini
@@ -0,0 +1,4 @@
+[navigator-keyboard-map-two-parallel-requests.https.html]
+  [[Keyboard Map\] getLayoutMap() twice in parallel]
+    expected: FAIL
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/keyboard-map/navigator-keyboard-map-two-sequential-requests.https.html.ini
@@ -0,0 +1,4 @@
+[navigator-keyboard-map-two-sequential-requests.https.html]
+  [[Keyboard Map\] getLayoutMap() called twice sequentially]
+    expected: FAIL
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/keyboard-map/navigator-keyboard-map.https.html.ini
@@ -0,0 +1,10 @@
+[navigator-keyboard-map.https.html]
+  [navigator.keyboard instanceof Keyboard]
+    expected: FAIL
+
+  [navigator.keyboard.getLayoutMap instanceof Function]
+    expected: FAIL
+
+  [navigator.keyboard.getLayoutMap() returns a Promise<KeyboardLayoutMap> when successful]
+    expected: FAIL
+
--- a/testing/web-platform/meta/magnetometer/idlharness.https.html.ini
+++ b/testing/web-platform/meta/magnetometer/idlharness.https.html.ini
@@ -291,11 +291,8 @@
     expected: FAIL
 
   [Sensor interface: new Magnetometer(); must inherit property "hasReading" with the proper type]
     expected: FAIL
 
   [Sensor interface: new UncalibratedMagnetometer(); must inherit property "hasReading" with the proper type]
     expected: FAIL
 
-  [Test IDL implementation of Magnetometer Sensor]
-    expected: FAIL
-
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/media-capabilities/idlharness.any.js.ini
@@ -0,0 +1,123 @@
+[idlharness.any.html]
+  [MediaCapabilitiesInfo interface: existence and properties of interface object]
+    expected: FAIL
+
+  [MediaCapabilitiesInfo interface object length]
+    expected: FAIL
+
+  [MediaCapabilitiesInfo interface object name]
+    expected: FAIL
+
+  [MediaCapabilitiesInfo interface: existence and properties of interface prototype object]
+    expected: FAIL
+
+  [MediaCapabilitiesInfo interface: existence and properties of interface prototype object's "constructor" property]
+    expected: FAIL
+
+  [MediaCapabilitiesInfo interface: existence and properties of interface prototype object's @@unscopables property]
+    expected: FAIL
+
+  [MediaCapabilitiesInfo interface: attribute supported]
+    expected: FAIL
+
+  [MediaCapabilitiesInfo interface: attribute smooth]
+    expected: FAIL
+
+  [MediaCapabilitiesInfo interface: attribute powerEfficient]
+    expected: FAIL
+
+  [MediaCapabilities interface: existence and properties of interface object]
+    expected: FAIL
+
+  [MediaCapabilities interface object length]
+    expected: FAIL
+
+  [MediaCapabilities interface object name]
+    expected: FAIL
+
+  [MediaCapabilities interface: existence and properties of interface prototype object]
+    expected: FAIL
+
+  [MediaCapabilities interface: existence and properties of interface prototype object's "constructor" property]
+    expected: FAIL
+
+  [MediaCapabilities interface: existence and properties of interface prototype object's @@unscopables property]
+    expected: FAIL
+
+  [MediaCapabilities interface: operation decodingInfo(MediaDecodingConfiguration)]
+    expected: FAIL
+
+  [MediaCapabilities interface: operation encodingInfo(MediaEncodingConfiguration)]
+    expected: FAIL
+
+  [ScreenLuminance interface: existence and properties of interface object]
+    expected: FAIL
+
+  [ScreenLuminance interface object length]
+    expected: FAIL
+
+  [ScreenLuminance interface object name]
+    expected: FAIL
+
+  [ScreenLuminance interface: existence and properties of interface prototype object]
+    expected: FAIL
+
+  [ScreenLuminance interface: existence and properties of interface prototype object's "constructor" property]
+    expected: FAIL
+
+  [ScreenLuminance interface: existence and properties of interface prototype object's @@unscopables property]
+    expected: FAIL
+
+  [ScreenLuminance interface: attribute min]
+    expected: FAIL
+
+  [ScreenLuminance interface: attribute max]
+    expected: FAIL
+
+  [ScreenLuminance interface: attribute maxAverage]
+    expected: FAIL
+
+  [Navigator interface: attribute mediaCapabilities]
+    expected: FAIL
+
+  [Navigator interface: navigator must inherit property "mediaCapabilities" with the proper type]
+    expected: FAIL
+
+  [Screen interface: attribute colorGamut]
+    expected: FAIL
+
+  [Screen interface: attribute luminance]
+    expected: FAIL
+
+  [Screen interface: attribute onchange]
+    expected: FAIL
+
+
+[idlharness.any.worker.html]
+  [MediaCapabilities interface: existence and properties of interface object]
+    expected: FAIL
+
+  [MediaCapabilities interface object length]
+    expected: FAIL
+
+  [MediaCapabilities interface object name]
+    expected: FAIL
+
+  [MediaCapabilities interface: existence and properties of interface prototype object]
+    expected: FAIL
+
+  [MediaCapabilities interface: existence and properties of interface prototype object's "constructor" property]
+    expected: FAIL
+
+  [MediaCapabilities interface: existence and properties of interface prototype object's @@unscopables property]
+    expected: FAIL
+
+  [MediaCapabilities interface: operation decodingInfo(MediaDecodingConfiguration)]
+    expected: FAIL
+
+  [MediaCapabilities interface: operation encodingInfo(MediaEncodingConfiguration)]
+    expected: FAIL
+
+  [WorkerNavigator interface: attribute mediaCapabilities]
+    expected: FAIL
+
deleted file mode 100644
--- a/testing/web-platform/meta/media-capabilities/idlharness.html.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[idlharness.html]
-  prefs: [media.media-capabilities.enabled:true]
-
--- a/testing/web-platform/meta/mediacapture-streams/MediaStreamTrack-idl.https.html.ini
+++ b/testing/web-platform/meta/mediacapture-streams/MediaStreamTrack-idl.https.html.ini
@@ -12,11 +12,8 @@
     expected: FAIL
 
   [MediaStreamTrack interface: track must inherit property "onoverconstrained" with the proper type]
     expected: FAIL
 
   [MediaStreamTrack interface: track must inherit property "getCapabilities()" with the proper type]
     expected: FAIL
 
-  [Test driver]
-    expected: FAIL
-
--- a/testing/web-platform/meta/mixed-content/link-prefetch-tag/http-csp/same-host-https/top-level/keep-scheme-redirect/allowed/allowed.https.html.ini
+++ b/testing/web-platform/meta/mixed-content/link-prefetch-tag/http-csp/same-host-https/top-level/keep-scheme-redirect/allowed/allowed.https.html.ini
@@ -1,7 +1,6 @@
 [allowed.https.html]
   disabled:
     if verify and (os == "win") and not debug: fails in verify mode
-
   [opt_in_method: http-csp\n                                 origin: same-host-https\n                                 source_scheme: https\n                                 context_nesting: top-level\n                                 redirection: keep-scheme-redirect\n                                 subresource: link-prefetch-tag\n                                 expectation: allowed]
     bug: the test case uses "no-cache" HTTP header. send an error until we have conclusion at https://github.com/w3c/resource-hints/issues/62
 
--- a/testing/web-platform/meta/mozilla-sync
+++ b/testing/web-platform/meta/mozilla-sync
@@ -1,2 +1,2 @@
-local: d9198dceb4cb870f4705a0af6893f071201ddeef
-upstream: 97f9d19d172ad73e50446852713e311f57490ec3
+local: 3da3f1e65b135c9be70f022037a1ea19305650e4
+upstream: 7b2cd8b78d938ea8879adc6419f2ea14b6af8bad
--- a/testing/web-platform/meta/orientation-sensor/idlharness.https.html.ini
+++ b/testing/web-platform/meta/orientation-sensor/idlharness.https.html.ini
@@ -207,11 +207,8 @@
     expected: FAIL
 
   [Sensor interface: new AbsoluteOrientationSensor(); must inherit property "hasReading" with the proper type]
     expected: FAIL
 
   [Sensor interface: new RelativeOrientationSensor(); must inherit property "hasReading" with the proper type]
     expected: FAIL
 
-  [Test IDL implementation of Orientation Sensor]
-    expected: FAIL
-
--- a/testing/web-platform/meta/payment-request/interfaces.https.html.ini
+++ b/testing/web-platform/meta/payment-request/interfaces.https.html.ini
@@ -337,11 +337,8 @@
     expected: FAIL
 
   [PaymentRequest interface: new PaymentRequest([{supportedMethods: 'foo'}\], {total: {label: 'bar', amount: {currency: 'USD', value: '0'}} }) must inherit property "show([object Object\])" with the proper type]
     expected: FAIL
 
   [PaymentRequest interface: calling show([object Object\]) on new PaymentRequest([{supportedMethods: 'foo'}\], {total: {label: 'bar', amount: {currency: 'USD', value: '0'}} }) with too few arguments must throw TypeError]
     expected: FAIL
 
-  [Setup for Payment Request API IDL tests.]
-    expected: FAIL
-
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/performance-timeline/idlharness.any.js.ini
@@ -0,0 +1,8 @@
+[idlharness.any.worker.html]
+
+[idlharness.any.html]
+
+[idlharness.any.sharedworker.html]
+
+[idlharness.https.any.serviceworker.html]
+  expected: TIMEOUT
--- a/testing/web-platform/meta/permissions/interfaces.any.js.ini
+++ b/testing/web-platform/meta/permissions/interfaces.any.js.ini
@@ -1,6 +1,12 @@
 [interfaces.any.worker.html]
   [Test IDL implementation of Permissions API]
     expected: FAIL
 
 
 [interfaces.any.html]
+  [Partial interface WorkerNavigator: valid exposure set]
+    expected: FAIL
+
+  [WorkerNavigator interface: member permissions]
+    expected: FAIL
+
--- a/testing/web-platform/meta/proximity/idlharness.https.html.ini
+++ b/testing/web-platform/meta/proximity/idlharness.https.html.ini
@@ -102,11 +102,8 @@
     expected: FAIL
 
   [Sensor interface: new ProximitySensor(); must inherit property "onactivate" with the proper type]
     expected: FAIL
 
   [Sensor interface: new ProximitySensor(); must inherit property "onerror" with the proper type]
     expected: FAIL
 
-  [Test IDL implementation of Proximity Sensor]
-    expected: FAIL
-
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/resize-observer/idlharness.html.ini
@@ -0,0 +1,103 @@
+[idlharness.html]
+  [ResizeObserver interface: existence and properties of interface object]
+    expected: FAIL
+
+  [ResizeObserver interface object length]
+    expected: FAIL
+
+  [ResizeObserver interface object name]
+    expected: FAIL
+
+  [ResizeObserver interface: existence and properties of interface prototype object]
+    expected: FAIL
+
+  [ResizeObserver interface: existence and properties of interface prototype object's "constructor" property]
+    expected: FAIL
+
+  [ResizeObserver interface: existence and properties of interface prototype object's @@unscopables property]
+    expected: FAIL
+
+  [ResizeObserver interface: operation observe(Element)]
+    expected: FAIL
+
+  [ResizeObserver interface: operation unobserve(Element)]
+    expected: FAIL
+
+  [ResizeObserver interface: operation disconnect()]
+    expected: FAIL
+
+  [ResizeObserver must be primary interface of new ResizeObserver(entries => {})]
+    expected: FAIL
+
+  [Stringification of new ResizeObserver(entries => {})]
+    expected: FAIL
+
+  [ResizeObserver interface: new ResizeObserver(entries => {}) must inherit property "observe(Element)" with the proper type]
+    expected: FAIL
+
+  [ResizeObserver interface: calling observe(Element) on new ResizeObserver(entries => {}) with too few arguments must throw TypeError]
+    expected: FAIL
+
+  [ResizeObserver interface: new ResizeObserver(entries => {}) must inherit property "unobserve(Element)" with the proper type]
+    expected: FAIL
+
+  [ResizeObserver interface: calling unobserve(Element) on new ResizeObserver(entries => {}) with too few arguments must throw TypeError]
+    expected: FAIL
+
+  [ResizeObserver interface: new ResizeObserver(entries => {}) must inherit property "disconnect()" with the proper type]
+    expected: FAIL
+
+  [ResizeObserverEntry interface: existence and properties of interface object]
+    expected: FAIL
+
+  [ResizeObserverEntry interface object length]
+    expected: FAIL
+
+  [ResizeObserverEntry interface object name]
+    expected: FAIL
+
+  [ResizeObserverEntry interface: existence and properties of interface prototype object]
+    expected: FAIL
+
+  [ResizeObserverEntry interface: existence and properties of interface prototype object's "constructor" property]
+    expected: FAIL
+
+  [ResizeObserverEntry interface: existence and properties of interface prototype object's @@unscopables property]
+    expected: FAIL
+
+  [ResizeObserverEntry interface: attribute target]
+    expected: FAIL
+
+  [ResizeObserverEntry interface: attribute contentRect]
+    expected: FAIL
+
+  [ResizeObservation interface: existence and properties of interface object]
+    expected: FAIL
+
+  [ResizeObservation interface object length]
+    expected: FAIL
+
+  [ResizeObservation interface object name]
+    expected: FAIL
+
+  [ResizeObservation interface: existence and properties of interface prototype object]
+    expected: FAIL
+
+  [ResizeObservation interface: existence and properties of interface prototype object's "constructor" property]
+    expected: FAIL
+
+  [ResizeObservation interface: existence and properties of interface prototype object's @@unscopables property]
+    expected: FAIL
+
+  [ResizeObservation interface: attribute target]
+    expected: FAIL
+
+  [ResizeObservation interface: attribute broadcastWidth]
+    expected: FAIL
+
+  [ResizeObservation interface: attribute broadcastHeight]
+    expected: FAIL
+
+  [ResizeObservation interface: operation isActive()]
+    expected: FAIL
+
--- a/testing/web-platform/meta/resource-timing/resource_initiator_types.html.ini
+++ b/testing/web-platform/meta/resource-timing/resource_initiator_types.html.ini
@@ -1,12 +1,11 @@
 [resource_initiator_types.html]
   disabled:
     if verify: fails in verify mode
-
   [http://web-platform.test:8000/fonts/Ahem.ttf is expected to have initiatorType css]
     expected: FAIL
 
   [http://web-platform.test:8000/fonts/Ahem.ttf?id=n1 is expected to have initiatorType css]
     expected: FAIL
 
   [http://web-platform.test:8000/resource-timing/resources/blue.png?id=body is expected to have initiatorType body]
     expected: FAIL
deleted file mode 100644
--- a/testing/web-platform/meta/screen-orientation/interfaces.html.ini
+++ /dev/null
@@ -1,4 +0,0 @@
-[interfaces.html]
-  [Test IDL implementation of Screen Orientation API]
-    expected: FAIL
-
--- a/testing/web-platform/meta/service-workers/service-worker/fetch-canvas-tainting-video-cache.https.html.ini
+++ b/testing/web-platform/meta/service-workers/service-worker/fetch-canvas-tainting-video-cache.https.html.ini
@@ -1,13 +1,12 @@
 [fetch-canvas-tainting-video-cache.https.html]
   disabled:
     if os == "linux": https://bugzilla.mozilla.org/show_bug.cgi?id=1464898
     if (os == "win") and (version == "6.1.7601") and (bits == 32): https://bugzilla.mozilla.org/show_bug.cgi?id=1464898
     if verify and (os == "linux"): fails in verify mode
     if verify and (os == "win"): fails in verify mode
-
   [url "https://web-platform.test:8443/service-workers/service-worker/resources/fetch-access-control.py?VIDEO&cache=true&mode=cors&credentials=same-origin&url=https%3A%2F%2Fwww1.web-platform.test%3A8443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FVIDEO%26cache%3Dtrue%26ACAOrigin%3Dhttps%3A%2F%2Fweb-platform.test%3A8443" with crossOrigin "" should be NOT_TAINTED]
     expected: FAIL
 
   [url "https://www1.web-platform.test:8443/service-workers/service-worker/resources/fetch-access-control.py?VIDEO&cache=true&mode=cors&credentials=same-origin&url=https%3A%2F%2Fwww1.web-platform.test%3A8443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FVIDEO%26cache%3Dtrue%26ACAOrigin%3Dhttps%3A%2F%2Fweb-platform.test%3A8443" with crossOrigin "" should be NOT_TAINTED]
     expected: FAIL
 
--- a/testing/web-platform/meta/service-workers/service-worker/installing.https.html.ini
+++ b/testing/web-platform/meta/service-workers/service-worker/installing.https.html.ini
@@ -1,7 +1,6 @@
 [installing.https.html]
   disabled:
     if verify: fails in verify mode
-
   [installing is set]
     expected: FAIL
 
--- a/testing/web-platform/meta/streams/readable-streams/tee.dedicatedworker.html.ini
+++ b/testing/web-platform/meta/streams/readable-streams/tee.dedicatedworker.html.ini
@@ -1,12 +1,11 @@
 [tee.dedicatedworker.html]
   disabled:
     if verify: fails in verify mode
-
   expected:
     if debug and not webrender and e10s and (os == "linux") and (version == "Ubuntu 16.04") and (processor == "x86") and (bits == 32): CRASH
     if debug and not webrender and not e10s and (os == "linux") and (version == "Ubuntu 16.04") and (processor == "x86") and (bits == 32): CRASH
     if debug and not webrender and e10s and (os == "mac") and (version == "OS X 10.10.5") and (processor == "x86_64") and (bits == 64): CRASH
     if debug and not webrender and e10s and (os == "win") and (version == "6.1.7601") and (processor == "x86") and (bits == 32): CRASH
     if debug and not webrender and e10s and (os == "win") and (version == "10.0.15063") and (processor == "x86_64") and (bits == 64): CRASH
     if debug and not webrender and e10s and (os == "linux") and (version == "Ubuntu 16.04") and (processor == "x86_64") and (bits == 64): CRASH
     if debug and webrender and e10s and (os == "linux") and (version == "Ubuntu 16.04") and (processor == "x86_64") and (bits == 64): CRASH
--- a/testing/web-platform/meta/streams/readable-streams/templated.dedicatedworker.html.ini
+++ b/testing/web-platform/meta/streams/readable-streams/templated.dedicatedworker.html.ini
@@ -1,12 +1,11 @@
 [templated.dedicatedworker.html]
   disabled:
     if verify and (os == "linux") and debug: fails in verify mode
-
   [instances have the correct methods and properties]
     expected: FAIL
 
   [calling getReader with invalid arguments should throw appropriate errors]
     expected: FAIL
 
   [locked should be true]
     expected: FAIL
deleted file mode 100644
--- a/testing/web-platform/meta/streams/readable-streams/templated.html.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[single-download-preload.html]
-  disabled:
-    if verify and (os == "linux") and debug: fails in verify mode
--- a/testing/web-platform/meta/streams/readable-streams/templated.serviceworker.https.html.ini
+++ b/testing/web-platform/meta/streams/readable-streams/templated.serviceworker.https.html.ini
@@ -1,12 +1,11 @@
 [templated.serviceworker.https.html]
   disabled:
     if verify and (os == "linux") and debug: fails in verify mode
-
   [instances have the correct methods and properties]
     expected: FAIL
 
   [calling getReader with invalid arguments should throw appropriate errors]
     expected: FAIL
 
   [locked should be true]
     expected: FAIL
--- a/testing/web-platform/meta/uievents/interfaces.html.ini
+++ b/testing/web-platform/meta/uievents/interfaces.html.ini
@@ -1,10 +1,7 @@
 [interfaces.html]
   [InputEvent interface: attribute data]
     expected: FAIL
 
   [InputEvent interface: new InputEvent("event") must inherit property "data" with the proper type]
     expected: FAIL
 
-  [Test driver]
-    expected: FAIL
-
--- a/testing/web-platform/meta/url/a-element-xhtml.xhtml.ini
+++ b/testing/web-platform/meta/url/a-element-xhtml.xhtml.ini
@@ -772,8 +772,11 @@
     expected: FAIL
 
   [Parsing: <a/> against <about:blank>]
     expected: FAIL
 
   [Parsing: <a//> against <about:blank>]
     expected: FAIL
 
+  [Parsing: <notspecial://host/?'> against <about:blank>]
+    expected: FAIL
+
--- a/testing/web-platform/meta/url/a-element.html.ini
+++ b/testing/web-platform/meta/url/a-element.html.ini
@@ -781,8 +781,11 @@
     expected: FAIL
 
   [Parsing: <a/> against <about:blank>]
     expected: FAIL
 
   [Parsing: <a//> against <about:blank>]
     expected: FAIL
 
+  [Parsing: <notspecial://host/?'> against <about:blank>]
+    expected: FAIL
+
--- a/testing/web-platform/meta/url/url-constructor.html.ini
+++ b/testing/web-platform/meta/url/url-constructor.html.ini
@@ -442,8 +442,11 @@
     expected: FAIL
 
   [Parsing: <test-a-colon-slash-b.html> against <a:/b>]
     expected: FAIL
 
   [Parsing: <test-a-colon-slash-slash-b.html> against <a://b>]
     expected: FAIL
 
+  [Parsing: <notspecial://host/?'> against <about:blank>]
+    expected: FAIL
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/user-timing/idlharness.any.js.ini
@@ -0,0 +1,8 @@
+[idlharness.any.html]
+
+[idlharness.any.worker.html]
+
+[idlharness.any.sharedworker.html]
+
+[idlharness.https.any.serviceworker.html]
+  expected: TIMEOUT
--- a/testing/web-platform/meta/webdriver/tests/new_session/merge.py.ini
+++ b/testing/web-platform/meta/webdriver/tests/new_session/merge.py.ini
@@ -5,8 +5,9 @@
 
   [test_platform_name[body0\]]
     expected:
       if os != "linux": FAIL
 
   [test_platform_name[body1\]]
     expected:
       if os != "linux": FAIL
+
--- a/testing/web-platform/meta/webrtc/RTCDTMFSender-ontonechange.https.html.ini
+++ b/testing/web-platform/meta/webrtc/RTCDTMFSender-ontonechange.https.html.ini
@@ -1,11 +1,10 @@
 [RTCDTMFSender-ontonechange.https.html]
   disabled: appears to fail everywhere
-
   [insertDTMF() with default duration and intertoneGap should fire tonechange events at the expected time]
     expected: FAIL
 
   [insertDTMF() with explicit duration and intertoneGap should fire tonechange events at the expected time]
     expected: FAIL
 
   [insertDTMF() with transceiver stopped in the middle should stop future tonechange events from firing]
     expected: FAIL
--- a/testing/web-platform/meta/webrtc/RTCPeerConnection-createDataChannel.html.ini
+++ b/testing/web-platform/meta/webrtc/RTCPeerConnection-createDataChannel.html.ini
@@ -1,12 +1,11 @@
 [RTCPeerConnection-createDataChannel.html]
   disabled:
     if verify and (os == "linux") and debug: fails in verify mode
-
   [createDataChannel defaults]
     expected: FAIL
 
   [createDataChannel with both maxPacketLifeTime and maxRetransmits]
     expected: FAIL
 
   [createDataChannel with negotiated true]
     expected: FAIL
--- a/testing/web-platform/meta/webrtc/RTCPeerConnection-setRemoteDescription-tracks.https.html.ini
+++ b/testing/web-platform/meta/webrtc/RTCPeerConnection-setRemoteDescription-tracks.https.html.ini
@@ -10,41 +10,29 @@
     expected: FAIL
 
   [addTrack() with a track and two streams makes ontrack fire with a track and two streams.]
     expected: FAIL
 
   [addTrack() with a track and a stream makes ontrack fire with a track and a stream.]
     expected: FAIL
 
-  [ontrack fires before setRemoteDescription resolves.]
-    expected: FAIL
-
   [ontrack's receiver matches getReceivers().]
     expected: FAIL
 
   [removeTrack() does not remove the receiver.]
     expected: FAIL
 
   [removeTrack() causes onremovetrack and the track to be removed from the stream.]
     expected: TIMEOUT
 
   [removeTrack() causes onmute and the track to be muted.]
     expected: FAIL
 
-  [stream.onaddtrack fires before setRemoteDescription resolves.]
-    expected: TIMEOUT
-
-  [removeTrack() makes stream.onremovetrack fire and the track to be removed from the stream.]
-    expected: TIMEOUT
-
-  [stream.onremovetrack fires before setRemoteDescription resolves.]
+  [removeTrack() makes track.onmute fire and the track to be muted.]
     expected: TIMEOUT
 
-  [removeTrack() makes track.onmute fire and the track to be muted.]
-    expected: FAIL
-
   [track.onmute fires before setRemoteDescription resolves.]
-    expected: FAIL
+    expected: NOTRUN
 
   [removeTrack() twice is safe.]
-    expected: FAIL
+    expected: NOTRUN
 
--- a/testing/web-platform/meta/webstorage/storage_setitem.html.ini
+++ b/testing/web-platform/meta/webstorage/storage_setitem.html.ini
@@ -1,4 +1,3 @@
 [storage_setitem.html]
   disabled:
     if verify: fails in verify mode
-
--- a/testing/web-platform/meta/webvtt/rendering/cues-with-video/processing-model/selectors/default_styles/italic_object_default_font-style.html.ini
+++ b/testing/web-platform/meta/webvtt/rendering/cues-with-video/processing-model/selectors/default_styles/italic_object_default_font-style.html.ini
@@ -1,6 +1,5 @@
 [italic_object_default_font-style.html]
   disabled:
     if verify and (os == "mac"): fails in verify mode
-
   expected:
-    if (os == "mac"): FAIL
+    if os == "mac": FAIL
--- a/testing/web-platform/meta/webvtt/rendering/cues-with-video/processing-model/selectors/default_styles/underline_object_default_font-style.html.ini
+++ b/testing/web-platform/meta/webvtt/rendering/cues-with-video/processing-model/selectors/default_styles/underline_object_default_font-style.html.ini
@@ -1,6 +1,5 @@
 [underline_object_default_font-style.html]
   disabled:
     if verify and (os == "mac"): fails in verify mode
-
   expected:
-    if (os == "mac"): FAIL
+    if os == "mac": FAIL
--- a/testing/web-platform/meta/webxr/interfaces.https.html.ini
+++ b/testing/web-platform/meta/webxr/interfaces.https.html.ini
@@ -441,11 +441,8 @@
     expected: FAIL
 
   [XRCoordinateSystemEvent interface: attribute coordinateSystem]
     expected: FAIL
 
   [XRWebGLLayer interface: operation getViewport(XRView)]
     expected: FAIL
 
-  [Test IDL implementation of WebXR API]
-    expected: FAIL
-
--- a/testing/web-platform/meta/workers/semantics/reporting-errors/003.html.ini
+++ b/testing/web-platform/meta/workers/semantics/reporting-errors/003.html.ini
@@ -1,8 +1,7 @@
 [003.html]
   disabled:
     if verify and (os == "linux") and debug: fails in verify mode
     if verify and (os == "win") and debug: fails in verify mode
-
   [shared worker, no error event on worker or port]
     expected: FAIL
 
deleted file mode 100644
--- a/testing/web-platform/meta/xhr/interfaces.html.ini
+++ /dev/null
@@ -1,4 +0,0 @@
-[interfaces.html]
-  [Test driver]
-    expected: FAIL
-
--- a/testing/web-platform/meta/xhr/send-authentication-basic-setrequestheader-existing-session.htm.ini
+++ b/testing/web-platform/meta/xhr/send-authentication-basic-setrequestheader-existing-session.htm.ini
@@ -1,4 +1,3 @@
 [send-authentication-basic-setrequestheader-existing-session.htm]
   disabled:
     if verify: fails in verify mode
-
--- a/testing/web-platform/meta/xhr/send-authentication-basic.htm.ini
+++ b/testing/web-platform/meta/xhr/send-authentication-basic.htm.ini
@@ -1,7 +1,6 @@
 [send-authentication-basic.htm]
   disabled:
     if verify and (os == "linux"): fails in verify mode