merge mozilla-central to autoland. r=merge a=merge
authorSebastian Hengst <archaeopteryx@coole-files.de>
Sat, 30 Sep 2017 10:22:53 +0200
changeset 383878 677ef6087ae191f36f2e500f82621ffac12128ee
parent 383870 64df7d87f40ae3eafe1be7c5b30c956219342850 (current diff)
parent 383877 19f368b1267d67f1bc214abae058ec20cb532c64 (diff)
child 383879 d9c1d98878cb54dc6a0afcc7092d2ea8f3077265
push id52410
push userarchaeopteryx@coole-files.de
push dateSat, 30 Sep 2017 08:23:19 +0000
treeherderautoland@677ef6087ae1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge, merge
milestone58.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. r=merge a=merge
dom/interfaces/html/nsIDOMHTMLButtonElement.idl
gfx/layers/apz/src/AsyncPanZoomController.cpp
--- a/browser/modules/FormSubmitObserver.jsm
+++ b/browser/modules/FormSubmitObserver.jsm
@@ -8,21 +8,16 @@
  */
 
 "use strict";
 
 var Cc = Components.classes;
 var Ci = Components.interfaces;
 var Cu = Components.utils;
 
-var HTMLInputElement = Ci.nsIDOMHTMLInputElement;
-var HTMLTextAreaElement = Ci.nsIDOMHTMLTextAreaElement;
-var HTMLSelectElement = Ci.nsIDOMHTMLSelectElement;
-var HTMLButtonElement = Ci.nsIDOMHTMLButtonElement;
-
 this.EXPORTED_SYMBOLS = [ "FormSubmitObserver" ];
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/BrowserUtils.jsm");
 
 function FormSubmitObserver(aWindow, aTabChildGlobal) {
   this.init(aWindow, aTabChildGlobal);
@@ -105,20 +100,20 @@ FormSubmitObserver.prototype =
     for (let i = 0; i < aInvalidElements.length; i++) {
       // Insure that this is the FormSubmitObserver associated with the
       // element / window this notification is about.
       let element = aInvalidElements.queryElementAt(i, Ci.nsISupports);
       if (this._content != element.ownerGlobal.top.document.defaultView) {
         return;
       }
 
-      if (!(element instanceof HTMLInputElement ||
-            element instanceof HTMLTextAreaElement ||
-            element instanceof HTMLSelectElement ||
-            element instanceof HTMLButtonElement)) {
+      if (!(ChromeUtils.getClassName(element) === "HTMLInputElement" ||
+            ChromeUtils.getClassName(element) === "HTMLTextAreaElement" ||
+            ChromeUtils.getClassName(element) === "HTMLSelectElement" ||
+            ChromeUtils.getClassName(element) === "HTMLButtonElement")) {
         continue;
       }
 
       if (!Services.focus.elementIsFocusable(element, 0)) {
         continue;
       }
 
       // Update validation message before showing notification
--- a/dom/html/HTMLButtonElement.cpp
+++ b/dom/html/HTMLButtonElement.cpp
@@ -73,17 +73,16 @@ HTMLButtonElement::~HTMLButtonElement()
 // nsISupports
 
 NS_IMPL_CYCLE_COLLECTION_INHERITED(HTMLButtonElement,
                                    nsGenericHTMLFormElementWithState,
                                    mValidity)
 
 NS_IMPL_ISUPPORTS_CYCLE_COLLECTION_INHERITED(HTMLButtonElement,
                                              nsGenericHTMLFormElementWithState,
-                                             nsIDOMHTMLButtonElement,
                                              nsIConstraintValidation)
 
 void
 HTMLButtonElement::SetCustomValidity(const nsAString& aError)
 {
   nsIConstraintValidation::SetCustomValidity(aError);
 
   UpdateState(true);
@@ -105,42 +104,35 @@ HTMLButtonElement::FieldSetDisabledChang
   // UpdateBarredFromConstraintValidation, because the latter depends on our
   // disabled state.
   nsGenericHTMLFormElementWithState::FieldSetDisabledChanged(aNotify);
 
   UpdateBarredFromConstraintValidation();
   UpdateState(aNotify);
 }
 
-// nsIDOMHTMLButtonElement
-
 NS_IMPL_ELEMENT_CLONE(HTMLButtonElement)
 
-
-// nsIDOMHTMLButtonElement
-
-NS_IMETHODIMP
-HTMLButtonElement::GetForm(nsIDOMHTMLFormElement** aForm)
+void
+HTMLButtonElement::GetFormEnctype(nsAString& aFormEncType)
 {
-  return nsGenericHTMLFormElementWithState::GetForm(aForm);
+  GetEnumAttr(nsGkAtoms::formenctype, "", kFormDefaultEnctype->tag, aFormEncType);
 }
 
-NS_IMPL_BOOL_ATTR(HTMLButtonElement, Autofocus, autofocus)
-NS_IMPL_BOOL_ATTR(HTMLButtonElement, Disabled, disabled)
-NS_IMPL_ACTION_ATTR(HTMLButtonElement, FormAction, formaction)
-NS_IMPL_ENUM_ATTR_DEFAULT_MISSING_INVALID_VALUES(HTMLButtonElement, FormEnctype, formenctype,
-                                                 "", kFormDefaultEnctype->tag)
-NS_IMPL_ENUM_ATTR_DEFAULT_MISSING_INVALID_VALUES(HTMLButtonElement, FormMethod, formmethod,
-                                                 "", kFormDefaultMethod->tag)
-NS_IMPL_BOOL_ATTR(HTMLButtonElement, FormNoValidate, formnovalidate)
-NS_IMPL_STRING_ATTR(HTMLButtonElement, FormTarget, formtarget)
-NS_IMPL_STRING_ATTR(HTMLButtonElement, Name, name)
-NS_IMPL_STRING_ATTR(HTMLButtonElement, Value, value)
-NS_IMPL_ENUM_ATTR_DEFAULT_VALUE(HTMLButtonElement, Type, type,
-                                kButtonDefaultType->tag)
+void
+HTMLButtonElement::GetFormMethod(nsAString& aFormMethod)
+{
+  GetEnumAttr(nsGkAtoms::formmethod, "", kFormDefaultMethod->tag, aFormMethod);
+}
+
+void
+HTMLButtonElement::GetType(nsAString& aType)
+{
+  GetEnumAttr(nsGkAtoms::type, kButtonDefaultType->tag, aType);
+}
 
 int32_t
 HTMLButtonElement::TabIndexDefault()
 {
   return 0;
 }
 
 bool
@@ -370,29 +362,26 @@ HTMLButtonElement::SubmitNamesValues(HTM
   if (IsDisabled()) {
     return NS_OK;
   }
 
   //
   // Get the name (if no name, no submit)
   //
   nsAutoString name;
-  GetAttr(kNameSpaceID_None, nsGkAtoms::name, name);
+  GetHTMLAttr(nsGkAtoms::name, name);
   if (name.IsEmpty()) {
     return NS_OK;
   }
 
   //
   // Get the value
   //
   nsAutoString value;
-  nsresult rv = GetValue(value);
-  if (NS_FAILED(rv)) {
-    return rv;
-  }
+  GetHTMLAttr(nsGkAtoms::value, value);
 
   //
   // Submit
   //
   return aFormSubmission->AddNameValuePair(name, value);
 }
 
 void
@@ -466,17 +455,18 @@ HTMLButtonElement::SaveState()
 
   return NS_OK;
 }
 
 bool
 HTMLButtonElement::RestoreState(nsPresState* aState)
 {
   if (aState && aState->IsDisabledSet() && !aState->GetDisabled()) {
-    SetDisabled(false);
+    IgnoredErrorResult rv;
+    SetDisabled(false, rv);
   }
 
   return false;
 }
 
 EventStates
 HTMLButtonElement::IntrinsicState() const
 {
--- a/dom/html/HTMLButtonElement.h
+++ b/dom/html/HTMLButtonElement.h
@@ -4,31 +4,28 @@
  * 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_dom_HTMLButtonElement_h
 #define mozilla_dom_HTMLButtonElement_h
 
 #include "mozilla/Attributes.h"
 #include "nsGenericHTMLElement.h"
-#include "nsIDOMHTMLButtonElement.h"
 #include "nsIConstraintValidation.h"
 
 namespace mozilla {
 class EventChainPostVisitor;
 class EventChainPreVisitor;
 namespace dom {
 
 class HTMLButtonElement final : public nsGenericHTMLFormElementWithState,
-                                public nsIDOMHTMLButtonElement,
                                 public nsIConstraintValidation
 {
 public:
   using nsIConstraintValidation::GetValidationMessage;
-  using nsGenericHTMLFormElementWithState::GetFormAction;
 
   explicit HTMLButtonElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo,
                              FromParser aFromParser = NOT_FROM_PARSER);
 
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(HTMLButtonElement,
                                            nsGenericHTMLFormElementWithState)
 
   // nsISupports
@@ -39,19 +36,16 @@ public:
   NS_IMPL_FROMCONTENT_HTML_WITH_TAG(HTMLButtonElement, button)
 
   // Element
   virtual bool IsInteractiveHTMLContent(bool aIgnoreTabindex) const override
   {
     return true;
   }
 
-  // nsIDOMHTMLButtonElement
-  NS_DECL_NSIDOMHTMLBUTTONELEMENT
-
   // overriden nsIFormControl methods
   NS_IMETHOD Reset() override;
   NS_IMETHOD SubmitNamesValues(HTMLFormSubmission* aFormSubmission) override;
   NS_IMETHOD SaveState() override;
   bool RestoreState(nsPresState* aState) override;
   virtual bool IsDisabledForEvents(EventMessage aMessage) override;
 
   virtual void FieldSetDisabledChanged(bool aNotify) override;
@@ -115,55 +109,64 @@ public:
     return GetBoolAttr(nsGkAtoms::disabled);
   }
   void SetDisabled(bool aDisabled, ErrorResult& aError)
   {
     SetHTMLBoolAttr(nsGkAtoms::disabled, aDisabled, aError);
   }
   // nsGenericHTMLFormElement::GetForm is fine.
   using nsGenericHTMLFormElement::GetForm;
-  // XPCOM GetFormAction is fine.
+  // GetFormAction implemented in superclass
   void SetFormAction(const nsAString& aFormAction, ErrorResult& aRv)
   {
     SetHTMLAttr(nsGkAtoms::formaction, aFormAction, aRv);
   }
-  // XPCOM GetFormEnctype is fine.
+  void GetFormEnctype(nsAString& aFormEncType);
   void SetFormEnctype(const nsAString& aFormEnctype, ErrorResult& aRv)
   {
     SetHTMLAttr(nsGkAtoms::formenctype, aFormEnctype, aRv);
   }
-  // XPCOM GetFormMethod is fine.
+  void GetFormMethod(nsAString& aFormMethod);
   void SetFormMethod(const nsAString& aFormMethod, ErrorResult& aRv)
   {
     SetHTMLAttr(nsGkAtoms::formmethod, aFormMethod, aRv);
   }
   bool FormNoValidate() const
   {
     return GetBoolAttr(nsGkAtoms::formnovalidate);
   }
   void SetFormNoValidate(bool aFormNoValidate, ErrorResult& aError)
   {
     SetHTMLBoolAttr(nsGkAtoms::formnovalidate, aFormNoValidate, aError);
   }
-  // XPCOM GetFormTarget is fine.
+  void GetFormTarget(DOMString& aFormTarget)
+  {
+    GetHTMLAttr(nsGkAtoms::formtarget, aFormTarget);
+  }
   void SetFormTarget(const nsAString& aFormTarget, ErrorResult& aRv)
   {
     SetHTMLAttr(nsGkAtoms::formtarget, aFormTarget, aRv);
   }
-  // XPCOM GetName is fine.
+  void GetName(DOMString& aName)
+  {
+    GetHTMLAttr(nsGkAtoms::name, aName);
+  }
   void SetName(const nsAString& aName, ErrorResult& aRv)
   {
     SetHTMLAttr(nsGkAtoms::name, aName, aRv);
   }
-  // XPCOM GetType is fine.
+  void GetType(nsAString& aType);
   void SetType(const nsAString& aType, ErrorResult& aRv)
   {
     SetHTMLAttr(nsGkAtoms::type, aType, aRv);
   }
-  // XPCOM GetValue is fine.
+  void GetValue(DOMString& aValue)
+  {
+    GetHTMLAttr(nsGkAtoms::value, aValue);
+  }
   void SetValue(const nsAString& aValue, ErrorResult& aRv)
   {
     SetHTMLAttr(nsGkAtoms::value, aValue, aRv);
   }
 
   // Override SetCustomValidity so we update our state properly when it's called
   // via bindings.
   void SetCustomValidity(const nsAString& aError);
--- a/dom/html/HTMLFormElement.cpp
+++ b/dom/html/HTMLFormElement.cpp
@@ -61,23 +61,23 @@
 
 #include "nsLayoutUtils.h"
 
 #include "mozAutoDocUpdate.h"
 #include "nsIHTMLCollection.h"
 
 #include "nsIConstraintValidation.h"
 
-#include "nsIDOMHTMLButtonElement.h"
 #include "nsSandboxFlags.h"
 
 #include "nsIContentSecurityPolicy.h"
 
 // images
 #include "mozilla/dom/HTMLImageElement.h"
+#include "mozilla/dom/HTMLButtonElement.h"
 
 // construction, destruction
 NS_IMPL_NS_NEW_HTML_ELEMENT(Form)
 
 namespace mozilla {
 namespace dom {
 
 static const uint8_t NS_FORM_AUTOCOMPLETE_ON  = 1;
@@ -1644,17 +1644,17 @@ HTMLFormElement::GetActionURL(nsIURI** a
     NS_ASSERTION(formControl && formControl->IsSubmitControl(),
                  "The originating element must be a submit form control!");
 #endif // DEBUG
 
     nsCOMPtr<nsIDOMHTMLInputElement> inputElement = do_QueryInterface(aOriginatingElement);
     if (inputElement) {
       inputElement->GetFormAction(action);
     } else {
-      nsCOMPtr<nsIDOMHTMLButtonElement> buttonElement = do_QueryInterface(aOriginatingElement);
+      auto buttonElement = HTMLButtonElement::FromContent(aOriginatingElement);
       if (buttonElement) {
         buttonElement->GetFormAction(action);
       } else {
         NS_ERROR("Originating element must be an input or button element!");
         return NS_ERROR_UNEXPECTED;
       }
     }
   } else {
--- a/dom/interfaces/html/moz.build
+++ b/dom/interfaces/html/moz.build
@@ -4,17 +4,16 @@
 # 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/.
 
 with Files("**"):
     BUG_COMPONENT = ("Core", "DOM")
 
 XPIDL_SOURCES += [
     'nsIDOMHTMLBaseElement.idl',
-    'nsIDOMHTMLButtonElement.idl',
     'nsIDOMHTMLCanvasElement.idl',
     'nsIDOMHTMLCollection.idl',
     'nsIDOMHTMLDocument.idl',
     'nsIDOMHTMLElement.idl',
     'nsIDOMHTMLFormElement.idl',
     'nsIDOMHTMLFrameElement.idl',
     'nsIDOMHTMLHtmlElement.idl',
     'nsIDOMHTMLIFrameElement.idl',
deleted file mode 100644
--- a/dom/interfaces/html/nsIDOMHTMLButtonElement.idl
+++ /dev/null
@@ -1,37 +0,0 @@
-/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* 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 "nsIDOMHTMLElement.idl"
-
-/**
- * The nsIDOMHTMLButtonElement interface is the interface to a [X]HTML
- * button element.
- *
- * This interface is trying to follow the DOM Level 2 HTML specification:
- * http://www.w3.org/TR/DOM-Level-2-HTML/
- *
- * with changes from the work-in-progress WHATWG HTML specification:
- * http://www.whatwg.org/specs/web-apps/current-work/
- */
-
-interface nsIDOMValidityState;
-
-[uuid(44b7a468-7dba-4f0c-9b4e-ee46dc0f26c7)]
-interface nsIDOMHTMLButtonElement : nsISupports
-{
-           attribute boolean               autofocus;
-           attribute boolean               disabled;
-  readonly attribute nsIDOMHTMLFormElement form;
-           attribute DOMString             formAction;
-           attribute DOMString             formEnctype;
-           attribute DOMString             formMethod;
-           attribute boolean               formNoValidate;
-           attribute DOMString             formTarget;
-
-           attribute DOMString             name;
-           attribute DOMString             type;
-           attribute DOMString             value;
-};
-
--- a/gfx/layers/apz/src/APZCTreeManager.h
+++ b/gfx/layers/apz/src/APZCTreeManager.h
@@ -49,17 +49,17 @@ class InputQueue;
 class GeckoContentController;
 class HitTestingTreeNode;
 class WebRenderScrollData;
 
 /**
  * ****************** NOTE ON LOCK ORDERING IN APZ **************************
  *
  * There are two kinds of locks used by APZ: APZCTreeManager::mTreeLock
- * ("the tree lock") and AsyncPanZoomController::mMonitor ("APZC locks").
+ * ("the tree lock") and AsyncPanZoomController::mRecursiveMutex ("APZC locks").
  *
  * To avoid deadlock, we impose a lock ordering between these locks, which is:
  *
  *      tree lock -> APZC locks
  *
  * The interpretation of the lock ordering is that if lock A precedes lock B
  * in the ordering sequence, then you must NOT wait on A while holding B.
  *
--- a/gfx/layers/apz/src/AndroidAPZ.cpp
+++ b/gfx/layers/apz/src/AndroidAPZ.cpp
@@ -85,21 +85,21 @@ AndroidFlingAnimation::AndroidFlingAnima
   mOverScroller = state->mOverScroller;
   MOZ_ASSERT(mOverScroller);
 
   // Drop any velocity on axes where we don't have room to scroll anyways
   // (in this APZC, or an APZC further in the handoff chain).
   // This ensures that we don't take the 'overscroll' path in Sample()
   // on account of one axis which can't scroll having a velocity.
   if (!mOverscrollHandoffChain->CanScrollInDirection(&mApzc, ScrollDirection::HORIZONTAL)) {
-    ReentrantMonitorAutoEnter lock(mApzc.mMonitor);
+    RecursiveMutexAutoLock lock(mApzc.mRecursiveMutex);
     mApzc.mX.SetVelocity(0);
   }
   if (!mOverscrollHandoffChain->CanScrollInDirection(&mApzc, ScrollDirection::VERTICAL)) {
-    ReentrantMonitorAutoEnter lock(mApzc.mMonitor);
+    RecursiveMutexAutoLock lock(mApzc.mRecursiveMutex);
     mApzc.mY.SetVelocity(0);
   }
 
   ParentLayerPoint velocity = mApzc.GetVelocityVector();
 
   float scrollRangeStartX = mApzc.mX.GetPageStart().value;
   float scrollRangeEndX = mApzc.mX.GetScrollRangeEnd().value;
   float scrollRangeStartY = mApzc.mY.GetPageStart().value;
--- a/gfx/layers/apz/src/AsyncPanZoomController.cpp
+++ b/gfx/layers/apz/src/AsyncPanZoomController.cpp
@@ -32,17 +32,17 @@
 #include "mozilla/Assertions.h"         // for MOZ_ASSERT, etc
 #include "mozilla/BasicEvents.h"        // for Modifiers, MODIFIER_*
 #include "mozilla/ClearOnShutdown.h"    // for ClearOnShutdown
 #include "mozilla/ComputedTimingFunction.h" // for ComputedTimingFunction
 #include "mozilla/EventForwards.h"      // for nsEventStatus_*
 #include "mozilla/EventStateManager.h"  // for EventStateManager
 #include "mozilla/MouseEvents.h"        // for WidgetWheelEvent
 #include "mozilla/Preferences.h"        // for Preferences
-#include "mozilla/ReentrantMonitor.h"   // for ReentrantMonitorAutoEnter, etc
+#include "mozilla/RecursiveMutex.h"     // for RecursiveMutexAutoLock, etc
 #include "mozilla/RefPtr.h"             // for RefPtr
 #include "mozilla/StaticPtr.h"          // for StaticAutoPtr
 #include "mozilla/Telemetry.h"          // for Telemetry
 #include "mozilla/TimeStamp.h"          // for TimeDuration, TimeStamp
 #include "mozilla/dom/CheckerboardReportService.h" // for CheckerboardEventStorage
              // note: CheckerboardReportService.h actually lives in gfx/layers/apz/util/
 #include "mozilla/dom/Touch.h"          // for Touch
 #include "mozilla/gfx/BasePoint.h"      // for BasePoint
@@ -496,26 +496,26 @@ AsyncPanZoomController::GetFrameTime() c
   return treeManagerLocal ? treeManagerLocal->GetFrameTime() : TimeStamp::Now();
 }
 
 class MOZ_STACK_CLASS StateChangeNotificationBlocker {
 public:
   explicit StateChangeNotificationBlocker(AsyncPanZoomController* aApzc)
     : mApzc(aApzc)
   {
-    ReentrantMonitorAutoEnter lock(mApzc->mMonitor);
+    RecursiveMutexAutoLock lock(mApzc->mRecursiveMutex);
     mInitialState = mApzc->mState;
     mApzc->mNotificationBlockers++;
   }
 
   ~StateChangeNotificationBlocker()
   {
     AsyncPanZoomController::PanZoomState newState;
     {
-      ReentrantMonitorAutoEnter lock(mApzc->mMonitor);
+      RecursiveMutexAutoLock lock(mApzc->mRecursiveMutex);
       mApzc->mNotificationBlockers--;
       newState = mApzc->mState;
     }
     mApzc->DispatchStateChangeNotification(mInitialState, newState);
   }
 
 private:
   AsyncPanZoomController* mApzc;
@@ -680,20 +680,20 @@ public:
       // To hand off the fling, we attempt to find a target APZC and start a new
       // fling with the same velocity on that APZC. For simplicity, the actual
       // overscroll of the current sample is discarded rather than being handed
       // off. The compositor should sample animations sufficiently frequently
       // that this is not noticeable. The target APZC is chosen by seeing if
       // there is an APZC further in the handoff chain which is pannable; if
       // there isn't, we take the new fling ourselves, entering an overscrolled
       // state.
-      // Note: APZC is holding mMonitor, so directly calling
+      // Note: APZC is holding mRecursiveMutex, so directly calling
       // HandleSmoothScrollOverscroll() (which acquires the tree lock) would violate
       // the lock ordering. Instead we schedule HandleSmoothScrollOverscroll() to be
-      // called after mMonitor is released.
+      // called after mRecursiveMutex is released.
       mDeferredTasks.AppendElement(NewRunnableMethod<ParentLayerPoint>(
         "layers::AsyncPanZoomController::HandleSmoothScrollOverscroll",
         &mApzc,
         &AsyncPanZoomController::HandleSmoothScrollOverscroll,
         velocity));
       return false;
     }
 
@@ -750,17 +750,17 @@ AsyncPanZoomController::AsyncPanZoomCont
                                                GeckoContentController* aGeckoContentController,
                                                GestureBehavior aGestures)
   :  mLayersId(aLayersId),
      mGeckoContentController(aGeckoContentController),
      mRefPtrMonitor("RefPtrMonitor"),
      // mTreeManager must be initialized before GetFrameTime() is called
      mTreeManager(aTreeManager),
      mFrameMetrics(mScrollMetadata.GetMetrics()),
-     mMonitor("AsyncPanZoomController"),
+     mRecursiveMutex("AsyncPanZoomController"),
      mLastContentPaintMetrics(mLastContentPaintMetadata.GetMetrics()),
      mX(this),
      mY(this),
      mPanDirRestricted(false),
      mZoomConstraints(false, false,
         mFrameMetrics.GetDevPixelsPerCSSPixel() * kViewportMinScale / ParentLayerToScreenScale(1),
         mFrameMetrics.GetDevPixelsPerCSSPixel() * kViewportMaxScale / ParentLayerToScreenScale(1)),
      mLastSampleTime(GetFrameTime()),
@@ -830,17 +830,17 @@ AsyncPanZoomController::Destroy()
   mTreeManager = nullptr;
 
   // Only send the release message if the SharedFrameMetrics has been created.
   if (mMetricsSharingController && mSharedFrameMetricsBuffer) {
     Unused << mMetricsSharingController->StopSharingMetrics(mFrameMetrics.GetScrollId(), mAPZCId);
   }
 
   { // scope the lock
-    ReentrantMonitorAutoEnter lock(mMonitor);
+    RecursiveMutexAutoLock lock(mRecursiveMutex);
     mSharedFrameMetricsBuffer = nullptr;
     delete mSharedLock;
     mSharedLock = nullptr;
   }
 }
 
 bool
 AsyncPanZoomController::IsDestroyed() const
@@ -940,17 +940,17 @@ nsEventStatus AsyncPanZoomController::Ha
     ParentLayerCoord thumbWidth = GetAxisLength(otherDirection, thumbRect);
     // Avoid triggering this condition spuriously when the thumb is
     // offscreen and its visible region is therefore empty.
     if (thumbWidth > 0 && thumbWidth * snapMultiplier < distance) {
       isMouseAwayFromThumb = true;
     }
   }
 
-  ReentrantMonitorAutoEnter lock(mMonitor);
+  RecursiveMutexAutoLock lock(mRecursiveMutex);
   CSSCoord thumbPosition;
   if (isMouseAwayFromThumb) {
     thumbPosition = aInitialThumbPos;
   } else {
     thumbPosition = ConvertScrollbarPoint(aEvent.mLocalOrigin, thumbData) -
                     aDragMetrics.mScrollbarDragOffset;
   }
 
@@ -1240,17 +1240,17 @@ nsEventStatus AsyncPanZoomController::On
   OnTouchEndOrCancel();
 
   // In case no touch behavior triggered previously we can avoid sending
   // scroll events or requesting content repaint. This condition is added
   // to make tests consistent - in case touch-action is NONE (and therefore
   // no pans/zooms can be performed) we expected neither scroll or repaint
   // events.
   if (mState != NOTHING) {
-    ReentrantMonitorAutoEnter lock(mMonitor);
+    RecursiveMutexAutoLock lock(mRecursiveMutex);
   }
 
   switch (mState) {
   case FLING:
     // Should never happen.
     NS_WARNING("Received impossible touch end in OnTouchEnd.");
     MOZ_FALLTHROUGH;
   case ANIMATING_ZOOM:
@@ -1388,17 +1388,17 @@ nsEventStatus AsyncPanZoomController::On
   // different x and y scales. If it did, the calculations in this function
   // would have to be adjusted (as e.g. it would no longer be valid to take
   // the minimum or maximum of the ratios of the widths and heights of the
   // page rect and the composition bounds).
   MOZ_ASSERT(mFrameMetrics.IsRootContent());
   MOZ_ASSERT(mFrameMetrics.GetZoom().AreScalesSame());
 
   {
-    ReentrantMonitorAutoEnter lock(mMonitor);
+    RecursiveMutexAutoLock lock(mRecursiveMutex);
 
     CSSToParentLayerScale userZoom = mFrameMetrics.GetZoom().ToScaleFactor();
     ParentLayerPoint focusPoint = aEvent.mLocalFocusPoint - mFrameMetrics.GetCompositionBounds().TopLeft();
     CSSPoint cssFocusPoint = focusPoint / mFrameMetrics.GetZoom();
 
     ParentLayerPoint focusChange = mLastZoomFocus - focusPoint;
     mLastZoomFocus = focusPoint;
     // If displacing by the change in focus point will take us off page bounds,
@@ -1504,17 +1504,17 @@ nsEventStatus AsyncPanZoomController::On
 
   if (!gfxPrefs::APZAllowZooming()) {
     if (RefPtr<GeckoContentController> controller = GetGeckoContentController()) {
       controller->NotifyPinchGesture(aEvent.mType, GetGuid(), 0, aEvent.modifiers);
     }
   }
 
   {
-    ReentrantMonitorAutoEnter lock(mMonitor);
+    RecursiveMutexAutoLock lock(mRecursiveMutex);
     ScheduleComposite();
     RequestContentRepaint();
     UpdateSharedCompositorFrameMetrics();
   }
 
   // Non-negative focus point would indicate that one finger is still down
   if (aEvent.mLocalFocusPoint.x != -1 && aEvent.mLocalFocusPoint.y != -1) {
     if (mZoomConstraints.mAllowZoom) {
@@ -1525,17 +1525,17 @@ nsEventStatus AsyncPanZoomController::On
     } else {
       // If zooming isn't allowed, StartTouch() was already called
       // in OnScaleBegin().
       StartPanning(aEvent.mLocalFocusPoint);
     }
   } else {
     // Otherwise, handle the fingers being lifted.
     if (mZoomConstraints.mAllowZoom) {
-      ReentrantMonitorAutoEnter lock(mMonitor);
+      RecursiveMutexAutoLock lock(mRecursiveMutex);
 
       // We can get into a situation where we are overscrolled at the end of a
       // pinch if we go into overscroll with a two-finger pan, and then turn
       // that into a pinch by increasing the span sufficiently. In such a case,
       // there is no snap-back animation to get us out of overscroll, so we need
       // to get out of it somehow.
       // Moreover, in cases of scroll handoff, the overscroll can be on an APZC
       // further up in the handoff chain rather than on the current APZC, so
@@ -1624,17 +1624,17 @@ AsyncPanZoomController::ConvertToGecko(c
   }
   return false;
 }
 
 CSSCoord
 AsyncPanZoomController::ConvertScrollbarPoint(const ParentLayerPoint& aScrollbarPoint,
                                               const ScrollThumbData& aThumbData) const
 {
-  ReentrantMonitorAutoEnter lock(mMonitor);
+  RecursiveMutexAutoLock lock(mRecursiveMutex);
 
   // First, get it into the right coordinate space.
   CSSPoint scrollbarPoint = aScrollbarPoint / mFrameMetrics.GetZoom();
   // The scrollbar can be transformed with the frame but the pres shell
   // resolution is only applied to the scroll frame.
   scrollbarPoint = scrollbarPoint * mFrameMetrics.GetPresShellResolution();
 
   // Now, get it to be relative to the beginning of the scroll track.
@@ -1655,17 +1655,17 @@ AllowsScrollingMoreThanOnePage(double aM
 ParentLayerPoint
 AsyncPanZoomController::GetScrollWheelDelta(const ScrollWheelInput& aEvent) const
 {
   ParentLayerSize scrollAmount;
   ParentLayerSize pageScrollSize;
 
   {
     // Grab the lock to access the frame metrics.
-    ReentrantMonitorAutoEnter lock(mMonitor);
+    RecursiveMutexAutoLock lock(mRecursiveMutex);
     LayoutDeviceIntSize scrollAmountLD = mScrollMetadata.GetLineScrollAmount();
     LayoutDeviceIntSize pageScrollSizeLD = mScrollMetadata.GetPageScrollAmount();
     scrollAmount = scrollAmountLD /
       mFrameMetrics.GetDevPixelsPerCSSPixel() * mFrameMetrics.GetZoom();
     pageScrollSize = pageScrollSizeLD /
       mFrameMetrics.GetDevPixelsPerCSSPixel() * mFrameMetrics.GetZoom();
   }
 
@@ -1800,17 +1800,17 @@ AsyncPanZoomController::OnKeyboard(const
     SetState(NOTHING);
 
     return nsEventStatus_eConsumeDoDefault;
   }
 
   // The lock must be held across the entire update operation, so the
   // compositor doesn't end the animation before we get a chance to
   // update it.
-  ReentrantMonitorAutoEnter lock(mMonitor);
+  RecursiveMutexAutoLock lock(mRecursiveMutex);
 
   if (scrollSnapped) {
     // If we're scroll snapping, use a smooth scroll animation to get
     // the desired physics. Note that SmoothScrollTo() will re-use an
     // existing smooth scroll animation if there is one.
     APZC_LOG("%p keyboard scrolling to snap point %s\n", this, Stringify(destination).c_str());
     SmoothScrollTo(destination);
     return nsEventStatus_eConsumeDoDefault;
@@ -1847,17 +1847,17 @@ AsyncPanZoomController::GetKeyboardDesti
 {
   CSSSize lineScrollSize;
   CSSSize pageScrollSize;
   CSSPoint scrollOffset;
   CSSRect scrollRect;
 
   {
     // Grab the lock to access the frame metrics.
-    ReentrantMonitorAutoEnter lock(mMonitor);
+    RecursiveMutexAutoLock lock(mRecursiveMutex);
 
     lineScrollSize = mScrollMetadata.GetLineScrollAmount() /
       mFrameMetrics.GetDevPixelsPerCSSPixel();
     pageScrollSize = mScrollMetadata.GetPageScrollAmount() /
       mFrameMetrics.GetDevPixelsPerCSSPixel();
 
     if (mState == WHEEL_SCROLL) {
       scrollOffset = mAnimation->AsWheelScrollAnimation()->GetDestination();
@@ -1933,30 +1933,30 @@ AsyncPanZoomController::CanScroll(const 
   }
 
   return CanScrollWithWheel(delta);
 }
 
 bool
 AsyncPanZoomController::CanScrollWithWheel(const ParentLayerPoint& aDelta) const
 {
-  ReentrantMonitorAutoEnter lock(mMonitor);
+  RecursiveMutexAutoLock lock(mRecursiveMutex);
   if (mX.CanScroll(aDelta.x)) {
     return true;
   }
   if (mY.CanScroll(aDelta.y) && mScrollMetadata.AllowVerticalScrollWithWheel()) {
     return true;
   }
   return false;
 }
 
 bool
 AsyncPanZoomController::CanScroll(ScrollDirection aDirection) const
 {
-  ReentrantMonitorAutoEnter lock(mMonitor);
+  RecursiveMutexAutoLock lock(mRecursiveMutex);
   switch (aDirection) {
   case ScrollDirection::HORIZONTAL: return mX.CanScroll();
   case ScrollDirection::VERTICAL:   return mY.CanScroll();
 
   case ScrollDirection::NONE:
     MOZ_ASSERT_UNREACHABLE("Invalid value");
     break;
   }
@@ -1976,17 +1976,17 @@ AsyncPanZoomController::AllowScrollHando
     }
   }
   return result;
 }
 
 void AsyncPanZoomController::DoDelayedRequestContentRepaint()
 {
   if (!IsDestroyed() && mPinchPaintTimerSet) {
-    ReentrantMonitorAutoEnter lock(mMonitor);
+    RecursiveMutexAutoLock lock(mRecursiveMutex);
     RequestContentRepaint();
   }
   mPinchPaintTimerSet = false;
 }
 
 static ScrollInputMethod
 ScrollInputMethodForWheelDeltaType(ScrollWheelInput::ScrollDeltaType aDeltaType)
 {
@@ -2054,27 +2054,27 @@ nsEventStatus AsyncPanZoomController::On
       ParentLayerPoint startPoint = aEvent.mLocalOrigin;
       ParentLayerPoint endPoint = aEvent.mLocalOrigin - delta;
       CallDispatchScroll(startPoint, endPoint, handoffState);
 
       SetState(NOTHING);
 
       // The calls above handle their own locking; moreover,
       // ToScreenCoordinates() and CallDispatchScroll() can grab the tree lock.
-      ReentrantMonitorAutoEnter lock(mMonitor);
+      RecursiveMutexAutoLock lock(mRecursiveMutex);
       RequestContentRepaint();
 
       break;
     }
 
     case ScrollWheelInput::SCROLLMODE_SMOOTH: {
       // The lock must be held across the entire update operation, so the
       // compositor doesn't end the animation before we get a chance to
       // update it.
-      ReentrantMonitorAutoEnter lock(mMonitor);
+      RecursiveMutexAutoLock lock(mRecursiveMutex);
 
       // Perform scroll snapping if appropriate.
       CSSPoint startPosition = mFrameMetrics.GetScrollOffset();
       // If we're already in a wheel scroll or smooth scroll animation,
       // the delta is applied to its destination, not to the current
       // scroll position. Take this into account when finding a snap point.
       if (mState == WHEEL_SCROLL) {
         startPosition = mAnimation->AsWheelScrollAnimation()->GetDestination();
@@ -2474,27 +2474,27 @@ bool AsyncPanZoomController::Contains(co
   ScreenToParentLayerMatrix4x4 transformToThis = GetTransformToThis();
   Maybe<ParentLayerIntPoint> point = UntransformBy(transformToThis, aPoint);
   if (!point) {
     return false;
   }
 
   ParentLayerIntRect cb;
   {
-    ReentrantMonitorAutoEnter lock(mMonitor);
+    RecursiveMutexAutoLock lock(mRecursiveMutex);
     GetFrameMetrics().GetCompositionBounds().ToIntRect(&cb);
   }
   return cb.Contains(*point);
 }
 
 ScreenCoord AsyncPanZoomController::PanDistance() const {
   ParentLayerPoint panVector;
   ParentLayerPoint panStart;
   {
-    ReentrantMonitorAutoEnter lock(mMonitor);
+    RecursiveMutexAutoLock lock(mRecursiveMutex);
     panVector = ParentLayerPoint(mX.PanDistance(), mY.PanDistance());
     panStart = PanStart();
   }
   return ToScreenCoordinates(panVector, panStart).Length();
 }
 
 ParentLayerPoint AsyncPanZoomController::PanStart() const {
   return ParentLayerPoint(mX.PanStart(), mY.PanStart());
@@ -2563,17 +2563,17 @@ void AsyncPanZoomController::HandlePanni
     // make sure to clear any leftover velocity from the pre-threshold
     // touchmoves.
     mX.SetVelocity(0);
     mY.SetVelocity(0);
   }
 }
 
 void AsyncPanZoomController::HandlePanning(double aAngle) {
-  ReentrantMonitorAutoEnter lock(mMonitor);
+  RecursiveMutexAutoLock lock(mRecursiveMutex);
   MOZ_ASSERT(GetCurrentInputBlock());
   RefPtr<const OverscrollHandoffChain> overscrollHandoffChain =
     GetCurrentInputBlock()->GetOverscrollHandoffChain();
   bool canScrollHorizontal = !mX.IsAxisLocked() &&
     overscrollHandoffChain->CanScrollInDirection(this, ScrollDirection::HORIZONTAL);
   bool canScrollVertical = !mY.IsAxisLocked() &&
     overscrollHandoffChain->CanScrollInDirection(this, ScrollDirection::VERTICAL);
 
@@ -2616,17 +2616,17 @@ void AsyncPanZoomController::HandlePanni
         }
       }
     }
   }
 }
 
 nsEventStatus
 AsyncPanZoomController::StartPanning(const ParentLayerPoint& aStartPoint) {
-  ReentrantMonitorAutoEnter lock(mMonitor);
+  RecursiveMutexAutoLock lock(mRecursiveMutex);
 
   float dx = mX.PanDistance(aStartPoint.x);
   float dy = mY.PanDistance(aStartPoint.y);
 
   double angle = atan2(dy, dx); // range [-pi, pi]
   angle = fabs(angle); // range [0, pi]
 
   if (gfxPrefs::TouchActionEnabled()) {
@@ -2672,17 +2672,17 @@ bool AsyncPanZoomController::AttemptScro
   // the earlier APZC was scrolled to its extent in the original direction).
   // We want to disallow this.
   bool scrollThisApzc = false;
   if (InputBlockState* block = GetCurrentInputBlock()) {
     scrollThisApzc = !block->GetScrolledApzc() || block->IsDownchainOfScrolledApzc(this);
   }
 
   if (scrollThisApzc) {
-    ReentrantMonitorAutoEnter lock(mMonitor);
+    RecursiveMutexAutoLock lock(mRecursiveMutex);
 
     ParentLayerPoint adjustedDisplacement;
     bool forceVerticalOverscroll =
       (aOverscrollHandoffState.mScrollSource == ScrollSource::Wheel &&
        !mScrollMetadata.AllowVerticalScrollWithWheel());
     bool yChanged = mY.AdjustDisplacement(displacement.y, adjustedDisplacement.y, overscroll.y,
                                           forceVerticalOverscroll);
     bool xChanged = mX.AdjustDisplacement(displacement.x, adjustedDisplacement.x, overscroll.x);
@@ -2762,17 +2762,17 @@ void AsyncPanZoomController::OverscrollF
   OverscrollBy(aOverscroll);
 }
 
 void AsyncPanZoomController::OverscrollBy(ParentLayerPoint& aOverscroll) {
   if (!gfxPrefs::APZOverscrollEnabled()) {
     return;
   }
 
-  ReentrantMonitorAutoEnter lock(mMonitor);
+  RecursiveMutexAutoLock lock(mRecursiveMutex);
   // Do not go into overscroll in a direction in which we have no room to
   // scroll to begin with.
   bool xCanScroll = mX.CanScroll();
   bool yCanScroll = mY.CanScroll();
   bool xConsumed = FuzzyEqualsAdditive(aOverscroll.x, 0.0f, COORDINATE_EPSILON);
   bool yConsumed = FuzzyEqualsAdditive(aOverscroll.y, 0.0f, COORDINATE_EPSILON);
 
   bool shouldOverscrollX = xCanScroll && !xConsumed;
@@ -2789,17 +2789,17 @@ RefPtr<const OverscrollHandoffChain> Asy
   // This APZC IsDestroyed(). To avoid callers having to special-case this
   // scenario, just build a 1-element chain containing ourselves.
   OverscrollHandoffChain* result = new OverscrollHandoffChain;
   result->Add(this);
   return result;
 }
 
 void AsyncPanZoomController::AcceptFling(FlingHandoffState& aHandoffState) {
-  ReentrantMonitorAutoEnter lock(mMonitor);
+  RecursiveMutexAutoLock lock(mRecursiveMutex);
 
   // We may have a pre-existing velocity for whatever reason (for example,
   // a previously handed off fling). We don't want to clobber that.
   APZC_LOG("%p accepting fling with velocity %s\n", this,
            Stringify(aHandoffState.mVelocity).c_str());
   if (mX.CanScroll()) {
     mX.SetVelocity(mX.GetVelocity() + aHandoffState.mVelocity.x);
     aHandoffState.mVelocity.x = 0;
@@ -2929,24 +2929,24 @@ void AsyncPanZoomController::TrackTouch(
 }
 
 ParentLayerPoint AsyncPanZoomController::GetFirstTouchPoint(const MultiTouchInput& aEvent) {
   return ((SingleTouchData&)aEvent.mTouches[0]).mLocalScreenPoint;
 }
 
 void AsyncPanZoomController::StartAnimation(AsyncPanZoomAnimation* aAnimation)
 {
-  ReentrantMonitorAutoEnter lock(mMonitor);
+  RecursiveMutexAutoLock lock(mRecursiveMutex);
   mAnimation = aAnimation;
   mLastSampleTime = GetFrameTime();
   ScheduleComposite();
 }
 
 void AsyncPanZoomController::CancelAnimation(CancelAnimationFlags aFlags) {
-  ReentrantMonitorAutoEnter lock(mMonitor);
+  RecursiveMutexAutoLock lock(mRecursiveMutex);
   APZC_LOG("%p running CancelAnimation(0x%x) in state %d\n", this, aFlags, mState);
 
   if ((aFlags & ExcludeWheel) && mState == WHEEL_SCROLL) {
     return;
   }
 
   if (mAnimation) {
     mAnimation->Cancel(aFlags);
@@ -2979,34 +2979,34 @@ void AsyncPanZoomController::CancelAnima
   if (repaint) {
     RequestContentRepaint();
     ScheduleComposite();
     UpdateSharedCompositorFrameMetrics();
   }
 }
 
 void AsyncPanZoomController::ClearOverscroll() {
-  ReentrantMonitorAutoEnter lock(mMonitor);
+  RecursiveMutexAutoLock lock(mRecursiveMutex);
   mX.ClearOverscroll();
   mY.ClearOverscroll();
 }
 
 void AsyncPanZoomController::SetCompositorController(CompositorController* aCompositorController)
 {
   mCompositorController = aCompositorController;
 }
 
 void AsyncPanZoomController::SetMetricsSharingController(MetricsSharingController* aMetricsSharingController)
 {
   mMetricsSharingController = aMetricsSharingController;
 }
 
 void AsyncPanZoomController::AdjustScrollForSurfaceShift(const ScreenPoint& aShift)
 {
-  ReentrantMonitorAutoEnter lock(mMonitor);
+  RecursiveMutexAutoLock lock(mRecursiveMutex);
   CSSPoint adjustment =
     ViewAs<ParentLayerPixel>(aShift, PixelCastJustification::ScreenIsParentLayerForRoot)
     / mFrameMetrics.GetZoom();
   APZC_LOG("%p adjusting scroll position by %s for surface shift\n",
     this, Stringify(adjustment).c_str());
   CSSRect scrollRange = mFrameMetrics.CalculateScrollRange();
   // Apply shift to mFrameMetrics.mScrollOffset.
   mFrameMetrics.SetScrollOffset(scrollRange.ClampPoint(
@@ -3177,31 +3177,31 @@ void AsyncPanZoomController::ScheduleCom
 }
 
 void AsyncPanZoomController::ScheduleCompositeAndMaybeRepaint() {
   ScheduleComposite();
   RequestContentRepaint();
 }
 
 void AsyncPanZoomController::FlushRepaintForOverscrollHandoff() {
-  ReentrantMonitorAutoEnter lock(mMonitor);
+  RecursiveMutexAutoLock lock(mRecursiveMutex);
   RequestContentRepaint();
   UpdateSharedCompositorFrameMetrics();
 }
 
 void AsyncPanZoomController::FlushRepaintForNewInputBlock() {
   APZC_LOG("%p flushing repaint for new input block\n", this);
 
-  ReentrantMonitorAutoEnter lock(mMonitor);
+  RecursiveMutexAutoLock lock(mRecursiveMutex);
   RequestContentRepaint();
   UpdateSharedCompositorFrameMetrics();
 }
 
 bool AsyncPanZoomController::SnapBackIfOverscrolled() {
-  ReentrantMonitorAutoEnter lock(mMonitor);
+  RecursiveMutexAutoLock lock(mRecursiveMutex);
   // It's possible that we're already in the middle of an overscroll
   // animation - if so, don't start a new one.
   if (IsOverscrolled() && mState != OVERSCROLL_ANIMATION) {
     APZC_LOG("%p is overscrolled, starting snap-back\n", this);
     StartOverscrollAnimation(ParentLayerPoint(0, 0));
     return true;
   }
   // If we don't kick off an overscroll animation, we still need to ask the
@@ -3209,32 +3209,32 @@ bool AsyncPanZoomController::SnapBackIfO
   // done so when we started this fling
   if (mState != FLING) {
     ScrollSnap();
   }
   return false;
 }
 
 bool AsyncPanZoomController::IsFlingingFast() const {
-  ReentrantMonitorAutoEnter lock(mMonitor);
+  RecursiveMutexAutoLock lock(mRecursiveMutex);
   if (mState == FLING &&
       GetVelocityVector().Length() > gfxPrefs::APZFlingStopOnTapThreshold()) {
     APZC_LOG("%p is moving fast\n", this);
     return true;
   }
   return false;
 }
 
 bool AsyncPanZoomController::IsPannable() const {
-  ReentrantMonitorAutoEnter lock(mMonitor);
+  RecursiveMutexAutoLock lock(mRecursiveMutex);
   return mX.CanScroll() || mY.CanScroll();
 }
 
 bool AsyncPanZoomController::IsScrollInfoLayer() const {
-  ReentrantMonitorAutoEnter lock(mMonitor);
+  RecursiveMutexAutoLock lock(mRecursiveMutex);
   return mFrameMetrics.IsScrollInfoLayer();
 }
 
 int32_t AsyncPanZoomController::GetLastTouchIdentifier() const {
   RefPtr<GestureEventListener> listener = GetGestureEventListener();
   return listener ? listener->GetLastTouchIdentifier() : -1;
 }
 
@@ -3256,17 +3256,17 @@ void AsyncPanZoomController::RequestCont
       this,
       func,
       aUserAction));
     return;
   }
 
   MOZ_ASSERT(controller->IsRepaintThread());
 
-  ReentrantMonitorAutoEnter lock(mMonitor);
+  RecursiveMutexAutoLock lock(mRecursiveMutex);
   ParentLayerPoint velocity = GetVelocityVector();
   mFrameMetrics.SetDisplayPortMargins(CalculatePendingDisplayPort(mFrameMetrics, velocity));
   mFrameMetrics.SetUseDisplayPortMargins(true);
   mFrameMetrics.SetPaintRequestTime(TimeStamp::Now());
   mFrameMetrics.SetRepaintDrivenByUserAction(aUserAction);
   RequestContentRepaint(mFrameMetrics, velocity);
 }
 
@@ -3375,17 +3375,17 @@ bool AsyncPanZoomController::UpdateAnima
     needComposite = true;
   }
   return needComposite;
 }
 
 AsyncTransformComponentMatrix
 AsyncPanZoomController::GetOverscrollTransform(AsyncTransformConsumer aMode) const
 {
-  ReentrantMonitorAutoEnter lock(mMonitor);
+  RecursiveMutexAutoLock lock(mRecursiveMutex);
 
   if (aMode == eForCompositing && mScrollMetadata.IsApzForceDisabled()) {
     return AsyncTransformComponentMatrix();
   }
 
   if (!IsOverscrolled()) {
     return AsyncTransformComponentMatrix();
   }
@@ -3410,17 +3410,17 @@ bool AsyncPanZoomController::AdvanceAnim
   // fling is happening, it has to keep compositing so that the animation is
   // smooth. If an animation frame is requested, it is the compositor's
   // responsibility to schedule a composite.
   mAsyncTransformAppliedToContent = false;
   bool requestAnimationFrame = false;
   nsTArray<RefPtr<Runnable>> deferredTasks;
 
   {
-    ReentrantMonitorAutoEnter lock(mMonitor);
+    RecursiveMutexAutoLock lock(mRecursiveMutex);
 
     requestAnimationFrame = UpdateAnimation(aSampleTime, &deferredTasks);
 
     { // scope lock
       MutexAutoLock lock(mCheckerboardEventLock);
       if (mCheckerboardEvent) {
         mCheckerboardEvent->UpdateRendertraceProperty(
             CheckerboardEvent::UserVisible,
@@ -3444,41 +3444,41 @@ bool AsyncPanZoomController::AdvanceAnim
   requestAnimationFrame |= (mAnimation != nullptr);
 
   return requestAnimationFrame;
 }
 
 ParentLayerPoint
 AsyncPanZoomController::GetCurrentAsyncScrollOffset(AsyncTransformConsumer aMode) const
 {
-  ReentrantMonitorAutoEnter lock(mMonitor);
+  RecursiveMutexAutoLock lock(mRecursiveMutex);
 
   if (aMode == eForCompositing && mScrollMetadata.IsApzForceDisabled()) {
     return mLastContentPaintMetrics.GetScrollOffset() * mLastContentPaintMetrics.GetZoom();
   }
 
   return (GetEffectiveScrollOffset(aMode) + mTestAsyncScrollOffset)
       * GetEffectiveZoom(aMode) * mTestAsyncZoom.scale;
 }
 
 CSSPoint
 AsyncPanZoomController::GetCurrentAsyncScrollOffsetInCssPixels(AsyncTransformConsumer aMode) const {
-  ReentrantMonitorAutoEnter lock(mMonitor);
+  RecursiveMutexAutoLock lock(mRecursiveMutex);
 
   if (aMode == eForCompositing && mScrollMetadata.IsApzForceDisabled()) {
     return mLastContentPaintMetrics.GetScrollOffset();
   }
 
   return GetEffectiveScrollOffset(aMode) + mTestAsyncScrollOffset;
 }
 
 AsyncTransform
 AsyncPanZoomController::GetCurrentAsyncTransform(AsyncTransformConsumer aMode) const
 {
-  ReentrantMonitorAutoEnter lock(mMonitor);
+  RecursiveMutexAutoLock lock(mRecursiveMutex);
 
   if (aMode == eForCompositing && mScrollMetadata.IsApzForceDisabled()) {
     return AsyncTransform();
   }
 
   CSSPoint lastPaintScrollOffset;
   if (mLastContentPaintMetrics.IsScrollable()) {
     lastPaintScrollOffset = mLastContentPaintMetrics.GetScrollOffset();
@@ -3533,17 +3533,17 @@ AsyncPanZoomController::GetEffectiveZoom
     return mCompositedZoom;
   }
   return mFrameMetrics.GetZoom();
 }
 
 bool
 AsyncPanZoomController::SampleCompositedAsyncTransform()
 {
-  ReentrantMonitorAutoEnter lock(mMonitor);
+  RecursiveMutexAutoLock lock(mRecursiveMutex);
   if (mCompositedScrollOffset != mFrameMetrics.GetScrollOffset() ||
       mCompositedZoom != mFrameMetrics.GetZoom()) {
     mCompositedScrollOffset = mFrameMetrics.GetScrollOffset();
     mCompositedZoom = mFrameMetrics.GetZoom();
     return true;
   }
   return false;
 }
@@ -3551,17 +3551,17 @@ AsyncPanZoomController::SampleComposited
 AsyncTransformComponentMatrix
 AsyncPanZoomController::GetCurrentAsyncTransformWithOverscroll(AsyncTransformConsumer aMode) const
 {
   return AsyncTransformComponentMatrix(GetCurrentAsyncTransform(aMode))
        * GetOverscrollTransform(aMode);
 }
 
 Matrix4x4 AsyncPanZoomController::GetTransformToLastDispatchedPaint() const {
-  ReentrantMonitorAutoEnter lock(mMonitor);
+  RecursiveMutexAutoLock lock(mRecursiveMutex);
 
   LayerPoint scrollChange =
     (mLastContentPaintMetrics.GetScrollOffset() - mExpectedGeckoMetrics.GetScrollOffset())
     * mLastContentPaintMetrics.GetDevPixelsPerCSSPixel()
     * mLastContentPaintMetrics.GetCumulativeResolution();
 
   // We're interested in the async zoom change. Factor out the content scale
   // that may change when dragging the window to a monitor with a different
@@ -3574,17 +3574,17 @@ Matrix4x4 AsyncPanZoomController::GetTra
 
   return Matrix4x4::Translation(scrollChange.x, scrollChange.y, 0).
            PostScale(zoomChange.width, zoomChange.height, 1);
 }
 
 uint32_t
 AsyncPanZoomController::GetCheckerboardMagnitude() const
 {
-  ReentrantMonitorAutoEnter lock(mMonitor);
+  RecursiveMutexAutoLock lock(mRecursiveMutex);
 
   CSSPoint currentScrollOffset = mFrameMetrics.GetScrollOffset() + mTestAsyncScrollOffset;
   CSSRect painted = mLastContentPaintMetrics.GetDisplayPort() + mLastContentPaintMetrics.GetScrollOffset();
   CSSRect visible = CSSRect(currentScrollOffset, mFrameMetrics.CalculateCompositedSizeInCssPixels());
 
   CSSIntRegion checkerboard;
   // Round so as to minimize checkerboarding; if we're only showing fractional
   // pixels of checkerboarding it's not really worth counting
@@ -3650,17 +3650,17 @@ AsyncPanZoomController::FlushActiveCheck
 {
   MutexAutoLock lock(mCheckerboardEventLock);
   // Pretend like we got a frame with 0 pixels checkerboarded. This will
   // terminate the checkerboard event and flush it out
   UpdateCheckerboardEvent(lock, 0);
 }
 
 bool AsyncPanZoomController::IsCurrentlyCheckerboarding() const {
-  ReentrantMonitorAutoEnter lock(mMonitor);
+  RecursiveMutexAutoLock lock(mRecursiveMutex);
 
   if (!gfxPrefs::APZAllowCheckerboarding() || mScrollMetadata.IsApzForceDisabled()) {
     return false;
   }
 
   CSSPoint currentScrollOffset = mFrameMetrics.GetScrollOffset() + mTestAsyncScrollOffset;
   CSSRect painted = mLastContentPaintMetrics.GetDisplayPort() + mLastContentPaintMetrics.GetScrollOffset();
   painted.Inflate(CSSMargin::FromAppUnits(nsMargin(1, 1, 1, 1)));   // fuzz for rounding error
@@ -3674,17 +3674,17 @@ bool AsyncPanZoomController::IsCurrently
 }
 
 void AsyncPanZoomController::NotifyLayersUpdated(const ScrollMetadata& aScrollMetadata,
                                                  bool aIsFirstPaint,
                                                  bool aThisLayerTreeUpdated)
 {
   APZThreadUtils::AssertOnCompositorThread();
 
-  ReentrantMonitorAutoEnter lock(mMonitor);
+  RecursiveMutexAutoLock lock(mRecursiveMutex);
   bool isDefault = mScrollMetadata.IsDefault();
 
   const FrameMetrics& aLayerMetrics = aScrollMetadata.GetMetrics();
 
   if ((aScrollMetadata == mLastContentPaintMetadata) && !isDefault) {
     // No new information here, skip it.
     APZC_LOG("%p NotifyLayersUpdated short-circuit\n", this);
     return;
@@ -3925,22 +3925,22 @@ void AsyncPanZoomController::NotifyLayer
   if (needContentRepaint) {
     // This repaint request is not driven by a user action on the APZ side
     RequestContentRepaint(false);
   }
   UpdateSharedCompositorFrameMetrics();
 }
 
 const FrameMetrics& AsyncPanZoomController::GetFrameMetrics() const {
-  mMonitor.AssertCurrentThreadIn();
+  mRecursiveMutex.AssertCurrentThreadIn();
   return mFrameMetrics;
 }
 
 APZCTreeManager* AsyncPanZoomController::GetApzcTreeManager() const {
-  mMonitor.AssertNotCurrentThreadIn();
+  mRecursiveMutex.AssertNotCurrentThreadIn();
   return mTreeManager;
 }
 
 void AsyncPanZoomController::ZoomToRect(CSSRect aRect, const uint32_t aFlags) {
   if (!aRect.IsFinite()) {
     NS_WARNING("ZoomToRect got called with a non-finite rect; ignoring...");
     return;
   } else if (aRect.IsEmpty() && (aFlags & DISABLE_ZOOM_OUT)) {
@@ -3957,17 +3957,17 @@ void AsyncPanZoomController::ZoomToRect(
   // the minimum or maximum of the ratios of the widths and heights of the
   // page rect and the composition bounds).
   MOZ_ASSERT(mFrameMetrics.IsRootContent());
   MOZ_ASSERT(mFrameMetrics.GetZoom().AreScalesSame());
 
   SetState(ANIMATING_ZOOM);
 
   {
-    ReentrantMonitorAutoEnter lock(mMonitor);
+    RecursiveMutexAutoLock lock(mRecursiveMutex);
 
     ParentLayerRect compositionBounds = mFrameMetrics.GetCompositionBounds();
     CSSRect cssPageRect = mFrameMetrics.GetScrollableRect();
     CSSPoint scrollOffset = mFrameMetrics.GetScrollOffset();
     CSSToParentLayerScale currentZoom = mFrameMetrics.GetZoom().ToScaleFactor();
     CSSToParentLayerScale targetZoom;
 
     // The minimum zoom to prevent over-zoom-out.
@@ -4144,30 +4144,30 @@ AsyncPanZoomController::HasReadyTouchBlo
 }
 
 void AsyncPanZoomController::SetState(PanZoomState aNewState)
 {
   PanZoomState oldState;
 
   // Intentional scoping for mutex
   {
-    ReentrantMonitorAutoEnter lock(mMonitor);
+    RecursiveMutexAutoLock lock(mRecursiveMutex);
     APZC_LOG("%p changing from state %d to %d\n", this, mState, aNewState);
     oldState = mState;
     mState = aNewState;
   }
 
   DispatchStateChangeNotification(oldState, aNewState);
 }
 
 void AsyncPanZoomController::DispatchStateChangeNotification(PanZoomState aOldState,
                                                              PanZoomState aNewState)
 {
   { // scope the lock
-    ReentrantMonitorAutoEnter lock(mMonitor);
+    RecursiveMutexAutoLock lock(mRecursiveMutex);
     if (mNotificationBlockers > 0) {
       return;
     }
   }
 
   if (RefPtr<GeckoContentController> controller = GetGeckoContentController()) {
     if (!IsTransformingState(aOldState) && IsTransformingState(aNewState)) {
       controller->NotifyAPZStateChange(
@@ -4271,17 +4271,17 @@ void AsyncPanZoomController::GetGuid(Scr
 
 ScrollableLayerGuid AsyncPanZoomController::GetGuid() const
 {
   return ScrollableLayerGuid(mLayersId, mFrameMetrics);
 }
 
 void AsyncPanZoomController::UpdateSharedCompositorFrameMetrics()
 {
-  mMonitor.AssertCurrentThreadIn();
+  mRecursiveMutex.AssertCurrentThreadIn();
 
   FrameMetrics* frame = mSharedFrameMetricsBuffer ?
       static_cast<FrameMetrics*>(mSharedFrameMetricsBuffer->memory()) : nullptr;
 
   if (frame && mSharedLock && gfxPrefs::ProgressivePaint()) {
     mSharedLock->Lock();
     *frame = mFrameMetrics;
     mSharedLock->Unlock();
@@ -4302,17 +4302,17 @@ void AsyncPanZoomController::ShareCompos
     FrameMetrics* frame = nullptr;
     mSharedFrameMetricsBuffer->Create(sizeof(FrameMetrics));
     mSharedFrameMetricsBuffer->Map(sizeof(FrameMetrics));
     frame = static_cast<FrameMetrics*>(mSharedFrameMetricsBuffer->memory());
 
     if (frame) {
 
       { // scope the monitor, only needed to copy the FrameMetrics.
-        ReentrantMonitorAutoEnter lock(mMonitor);
+        RecursiveMutexAutoLock lock(mRecursiveMutex);
         *frame = mFrameMetrics;
       }
 
       // Get the process id of the content process
       base::ProcessId otherPid = mMetricsSharingController->RemotePid();
       ipc::SharedMemoryBasic::Handle mem = ipc::SharedMemoryBasic::NULLHandle();
 
       // Get the shared memory handle to share with the content process
@@ -4329,17 +4329,17 @@ void AsyncPanZoomController::ShareCompos
         APZC_LOG("%p failed to share FrameMetrics with content process.", this);
       }
     }
   }
 }
 
 Maybe<CSSPoint> AsyncPanZoomController::FindSnapPointNear(
     const CSSPoint& aDestination, nsIScrollableFrame::ScrollUnit aUnit) {
-  mMonitor.AssertCurrentThreadIn();
+  mRecursiveMutex.AssertCurrentThreadIn();
   APZC_LOG("%p scroll snapping near %s\n", this, Stringify(aDestination).c_str());
   CSSRect scrollRange = mFrameMetrics.CalculateScrollRange();
   if (Maybe<nsPoint> snapPoint = ScrollSnapUtils::GetSnapPointForDestination(
           mScrollMetadata.GetSnapInfo(),
           aUnit,
           CSSSize::ToAppUnits(mFrameMetrics.CalculateCompositedSizeInCssPixels()),
           CSSRect::ToAppUnits(scrollRange),
           CSSPoint::ToAppUnits(mFrameMetrics.GetScrollOffset()),
@@ -4360,22 +4360,22 @@ void AsyncPanZoomController::ScrollSnapN
     if (*snapPoint != mFrameMetrics.GetScrollOffset()) {
       APZC_LOG("%p smooth scrolling to snap point %s\n", this, Stringify(*snapPoint).c_str());
       SmoothScrollTo(*snapPoint);
     }
   }
 }
 
 void AsyncPanZoomController::ScrollSnap() {
-  ReentrantMonitorAutoEnter lock(mMonitor);
+  RecursiveMutexAutoLock lock(mRecursiveMutex);
   ScrollSnapNear(mFrameMetrics.GetScrollOffset());
 }
 
 void AsyncPanZoomController::ScrollSnapToDestination() {
-  ReentrantMonitorAutoEnter lock(mMonitor);
+  RecursiveMutexAutoLock lock(mRecursiveMutex);
 
   float friction = gfxPrefs::APZFlingFriction();
   ParentLayerPoint velocity(mX.GetVelocity(), mY.GetVelocity());
   ParentLayerPoint predictedDelta;
   // "-velocity / log(1.0 - friction)" is the integral of the deceleration
   // curve modeled for flings in the "Axis" class.
   if (velocity.x != 0.0f) {
     predictedDelta.x = -velocity.x / log(1.0 - friction);
@@ -4408,17 +4408,17 @@ bool AsyncPanZoomController::MaybeAdjust
     CSSPoint& aStartPosition)
 {
   // Don't scroll snap for pixel scrolls. This matches the main thread
   // behaviour in EventStateManager::DoScrollText().
   if (aEvent.mDeltaType == ScrollWheelInput::SCROLLDELTA_PIXEL) {
     return false;
   }
 
-  ReentrantMonitorAutoEnter lock(mMonitor);
+  RecursiveMutexAutoLock lock(mRecursiveMutex);
   CSSToParentLayerScale2D zoom = mFrameMetrics.GetZoom();
   CSSPoint destination = mFrameMetrics.CalculateScrollRange().ClampPoint(
       aStartPosition + (aDelta / zoom));
   nsIScrollableFrame::ScrollUnit unit =
       ScrollWheelInput::ScrollUnitForDeltaType(aEvent.mDeltaType);
 
   if (Maybe<CSSPoint> snapPoint = FindSnapPointNear(destination, unit)) {
     aDelta = (*snapPoint - aStartPosition) * zoom;
@@ -4427,17 +4427,17 @@ bool AsyncPanZoomController::MaybeAdjust
   }
   return false;
 }
 
 bool AsyncPanZoomController::MaybeAdjustDestinationForScrollSnapping(
     const KeyboardInput& aEvent,
     CSSPoint& aDestination)
 {
-  ReentrantMonitorAutoEnter lock(mMonitor);
+  RecursiveMutexAutoLock lock(mRecursiveMutex);
   nsIScrollableFrame::ScrollUnit unit =
       KeyboardScrollAction::GetScrollUnit(aEvent.mAction.mType);
 
   if (Maybe<CSSPoint> snapPoint = FindSnapPointNear(aDestination, unit)) {
     aDestination = *snapPoint;
     return true;
   }
   return false;
--- a/gfx/layers/apz/src/AsyncPanZoomController.h
+++ b/gfx/layers/apz/src/AsyncPanZoomController.h
@@ -9,17 +9,17 @@
 
 #include "CrossProcessMutex.h"
 #include "mozilla/layers/GeckoContentController.h"
 #include "mozilla/layers/APZCTreeManager.h"
 #include "mozilla/layers/AsyncPanZoomAnimation.h"
 #include "mozilla/Attributes.h"
 #include "mozilla/EventForwards.h"
 #include "mozilla/Monitor.h"
-#include "mozilla/ReentrantMonitor.h"
+#include "mozilla/RecursiveMutex.h"
 #include "mozilla/RefPtr.h"
 #include "mozilla/UniquePtr.h"
 #include "mozilla/Atomics.h"
 #include "InputData.h"
 #include "Axis.h"
 #include "InputQueue.h"
 #include "APZUtils.h"
 #include "Layers.h"                     // for Layer::ScrollDirection
@@ -384,38 +384,38 @@ public:
    * this APZC. This should only be called when the last touch event contained
    * only one touch.
    */
   int32_t GetLastTouchIdentifier() const;
 
   /**
    * Returns the matrix that transforms points from global screen space into
    * this APZC's ParentLayer space.
-   * To respect the lock ordering, mMonitor must NOT be held when calling
+   * To respect the lock ordering, mRecursiveMutex must NOT be held when calling
    * this function (since this function acquires the tree lock).
    */
   ScreenToParentLayerMatrix4x4 GetTransformToThis() const;
 
   /**
    * Convert the vector |aVector|, rooted at the point |aAnchor|, from
    * this APZC's ParentLayer coordinates into screen coordinates.
    * The anchor is necessary because with 3D tranforms, the location of the
    * vector can affect the result of the transform.
-   * To respect the lock ordering, mMonitor must NOT be held when calling
+   * To respect the lock ordering, mRecursiveMutex must NOT be held when calling
    * this function (since this function acquires the tree lock).
    */
   ScreenPoint ToScreenCoordinates(const ParentLayerPoint& aVector,
                                   const ParentLayerPoint& aAnchor) const;
 
   /**
    * Convert the vector |aVector|, rooted at the point |aAnchor|, from
    * screen coordinates into this APZC's ParentLayer coordinates.
    * The anchor is necessary because with 3D tranforms, the location of the
    * vector can affect the result of the transform.
-   * To respect the lock ordering, mMonitor must NOT be held when calling
+   * To respect the lock ordering, mRecursiveMutex must NOT be held when calling
    * this function (since this function acquires the tree lock).
    */
   ParentLayerPoint ToParentLayerCoordinates(const ScreenPoint& aVector,
                                             const ScreenPoint& aAnchor) const;
 
   // Return whether or not a wheel event will be able to scroll in either
   // direction.
   bool CanScroll(const InputData& aEvent) const;
@@ -732,17 +732,17 @@ protected:
 
   // Protects |mFrameMetrics|, |mLastContentPaintMetrics|, and |mState|.
   // Before manipulating |mFrameMetrics| or |mLastContentPaintMetrics|, the
   // monitor should be held. When setting |mState|, either the SetState()
   // function can be used, or the monitor can be held and then |mState| updated.
   // IMPORTANT: See the note about lock ordering at the top of APZCTreeManager.h.
   // This is mutable to allow entering it from 'const' methods; doing otherwise
   // would significantly limit what methods could be 'const'.
-  mutable ReentrantMonitor mMonitor;
+  mutable RecursiveMutex mRecursiveMutex;
 
 private:
   // Metadata of the container layer corresponding to this APZC. This is
   // stored here so that it is accessible from the UI/controller thread.
   // These are the metrics at last content paint, the most recent
   // values we were notified of in NotifyLayersUpdate(). Since it represents
   // the Gecko state, it should be used as a basis for untransformation when
   // sending messages back to Gecko.
@@ -799,17 +799,17 @@ public:
    * while holding the APZC lock required to access |mLastContentPaintMetrics|.
    * This allows code outside of an AsyncPanZoomController method implementation
    * to access |mLastContentPaintMetrics| without having to make a copy of it.
    * Passes through the return value of |callable|.
    */
   template <typename Callable>
   auto CallWithLastContentPaintMetrics(const Callable& callable) const
     -> decltype(callable(mLastContentPaintMetrics)) {
-    ReentrantMonitorAutoEnter lock(mMonitor);
+    RecursiveMutexAutoLock lock(mRecursiveMutex);
     return callable(mLastContentPaintMetrics);
   }
 
   /* ===================================================================
    * The functions and members in this section are used to expose
    * the current async transform state to callers.
    */
 public:
@@ -913,27 +913,26 @@ protected:
     OVERSCROLL_ANIMATION,     /* Spring-based animation used to relieve overscroll once
                                  the finger is lifted. */
     SMOOTH_SCROLL,            /* Smooth scrolling to destination. Used by
                                  CSSOM-View smooth scroll-behavior */
     WHEEL_SCROLL,             /* Smooth scrolling to a destination for a wheel event. */
     KEYBOARD_SCROLL,          /* Smooth scrolling to a destination for a keyboard event. */
     AUTOSCROLL                /* Autoscroll animation. */
   };
-
-  // This is in theory protected by |mMonitor|; that is, it should be held whenever
+  // This is in theory protected by |mRecursiveMutex|; that is, it should be held whenever
   // this is updated. In practice though... see bug 897017.
   PanZoomState mState;
 
 private:
   friend class StateChangeNotificationBlocker;
   /**
    * A counter of how many StateChangeNotificationBlockers are active.
    * A non-zero count will prevent state change notifications from
-   * being dispatched. Only code that holds mMonitor should touch this.
+   * being dispatched. Only code that holds mRecursiveMutex should touch this.
    */
   int mNotificationBlockers;
 
   /**
    * Helper to set the current state. Holds the monitor before actually setting
    * it and fires content controller events based on state changes. Always set
    * the state using this call, do not set it directly.
    */
@@ -1070,22 +1069,22 @@ public:
   /* Returns true if there is no APZC higher in the tree with the same
    * layers id.
    */
   bool HasNoParentWithSameLayersId() const {
     return !mParent || (mParent->mLayersId != mLayersId);
   }
 
   bool IsRootForLayersId() const {
-    ReentrantMonitorAutoEnter lock(mMonitor);
+    RecursiveMutexAutoLock lock(mRecursiveMutex);
     return mScrollMetadata.IsLayersIdRoot();
   }
 
   bool IsRootContent() const {
-    ReentrantMonitorAutoEnter lock(mMonitor);
+    RecursiveMutexAutoLock lock(mRecursiveMutex);
     return mFrameMetrics.IsRootContent();
   }
 
 private:
   // |mTreeManager| belongs in this section but it's declaration is a bit
   // further above due to initialization-order constraints.
 
   RefPtr<AsyncPanZoomController> mParent;
--- a/gfx/layers/apz/src/GenericFlingAnimation.h
+++ b/gfx/layers/apz/src/GenericFlingAnimation.h
@@ -41,21 +41,21 @@ public:
     MOZ_ASSERT(mOverscrollHandoffChain);
     TimeStamp now = aApzc.GetFrameTime();
 
     // Drop any velocity on axes where we don't have room to scroll anyways
     // (in this APZC, or an APZC further in the handoff chain).
     // This ensures that we don't take the 'overscroll' path in Sample()
     // on account of one axis which can't scroll having a velocity.
     if (!mOverscrollHandoffChain->CanScrollInDirection(&mApzc, ScrollDirection::HORIZONTAL)) {
-      ReentrantMonitorAutoEnter lock(mApzc.mMonitor);
+      RecursiveMutexAutoLock lock(mApzc.mRecursiveMutex);
       mApzc.mX.SetVelocity(0);
     }
     if (!mOverscrollHandoffChain->CanScrollInDirection(&mApzc, ScrollDirection::VERTICAL)) {
-      ReentrantMonitorAutoEnter lock(mApzc.mMonitor);
+      RecursiveMutexAutoLock lock(mApzc.mRecursiveMutex);
       mApzc.mY.SetVelocity(0);
     }
 
     ParentLayerPoint velocity = mApzc.GetVelocityVector();
 
     // If the last fling was very recent and in the same direction as this one,
     // boost the velocity to be the sum of the two. Check separate axes separately
     // because we could have two vertical flings with small horizontal components
@@ -103,17 +103,17 @@ public:
          shouldContinueFlingY = mApzc.mY.FlingApplyFrictionOrCancel(aDelta, friction, threshold);
     // If we shouldn't continue the fling, let's just stop and repaint.
     if (!shouldContinueFlingX && !shouldContinueFlingY) {
       FLING_LOG("%p ending fling animation. overscrolled=%d\n", &mApzc, mApzc.IsOverscrolled());
       // This APZC or an APZC further down the handoff chain may be be overscrolled.
       // Start a snap-back animation on the overscrolled APZC.
       // Note:
       //   This needs to be a deferred task even though it can safely run
-      //   while holding mMonitor, because otherwise, if the overscrolled APZC
+      //   while holding mRecursiveMutex, because otherwise, if the overscrolled APZC
       //   is this one, then the SetState(NOTHING) in UpdateAnimation will
       //   stomp on the SetState(SNAP_BACK) it does.
       mDeferredTasks.AppendElement(NewRunnableMethod<AsyncPanZoomController*>(
         "layers::OverscrollHandoffChain::SnapBackOverscrolledApzc",
         mOverscrollHandoffChain.get(),
         &OverscrollHandoffChain::SnapBackOverscrolledApzc,
         &mApzc));
       return false;
@@ -154,20 +154,20 @@ public:
       // To hand off the fling, we attempt to find a target APZC and start a new
       // fling with the same velocity on that APZC. For simplicity, the actual
       // overscroll of the current sample is discarded rather than being handed
       // off. The compositor should sample animations sufficiently frequently
       // that this is not noticeable. The target APZC is chosen by seeing if
       // there is an APZC further in the handoff chain which is pannable; if
       // there isn't, we take the new fling ourselves, entering an overscrolled
       // state.
-      // Note: APZC is holding mMonitor, so directly calling
+      // Note: APZC is holding mRecursiveMutex, so directly calling
       // HandleFlingOverscroll() (which acquires the tree lock) would violate
       // the lock ordering. Instead we schedule HandleFlingOverscroll() to be
-      // called after mMonitor is released.
+      // called after mRecursiveMutex is released.
       FLING_LOG("%p fling went into overscroll, handing off with velocity %s\n", &mApzc, Stringify(velocity).c_str());
       mDeferredTasks.AppendElement(
         NewRunnableMethod<ParentLayerPoint,
                           RefPtr<const OverscrollHandoffChain>,
                           RefPtr<const AsyncPanZoomController>>(
           "layers::AsyncPanZoomController::HandleFlingOverscroll",
           &mApzc,
           &AsyncPanZoomController::HandleFlingOverscroll,
--- a/gfx/layers/apz/test/gtest/APZTestCommon.h
+++ b/gfx/layers/apz/test/gtest/APZTestCommon.h
@@ -226,49 +226,49 @@ public:
     GetInputQueue()->SetConfirmedTargetApzc(aInputBlockId, target);
   }
 
   void SetAllowedTouchBehavior(uint64_t aInputBlockId, const nsTArray<TouchBehaviorFlags>& aBehaviors) {
     GetInputQueue()->SetAllowedTouchBehavior(aInputBlockId, aBehaviors);
   }
 
   void SetFrameMetrics(const FrameMetrics& metrics) {
-    ReentrantMonitorAutoEnter lock(mMonitor);
+    RecursiveMutexAutoLock lock(mRecursiveMutex);
     mFrameMetrics = metrics;
   }
 
   FrameMetrics& GetFrameMetrics() {
-    ReentrantMonitorAutoEnter lock(mMonitor);
+    RecursiveMutexAutoLock lock(mRecursiveMutex);
     return mFrameMetrics;
   }
 
   ScrollMetadata& GetScrollMetadata() {
-    ReentrantMonitorAutoEnter lock(mMonitor);
+    RecursiveMutexAutoLock lock(mRecursiveMutex);
     return mScrollMetadata;
   }
 
   const FrameMetrics& GetFrameMetrics() const {
-    ReentrantMonitorAutoEnter lock(mMonitor);
+    RecursiveMutexAutoLock lock(mRecursiveMutex);
     return mFrameMetrics;
   }
 
   using AsyncPanZoomController::GetVelocityVector;
 
   void AssertStateIsReset() const {
-    ReentrantMonitorAutoEnter lock(mMonitor);
+    RecursiveMutexAutoLock lock(mRecursiveMutex);
     EXPECT_EQ(NOTHING, mState);
   }
 
   void AssertStateIsFling() const {
-    ReentrantMonitorAutoEnter lock(mMonitor);
+    RecursiveMutexAutoLock lock(mRecursiveMutex);
     EXPECT_EQ(FLING, mState);
   }
 
   void AssertAxisLocked(ScrollDirection aDirection) const {
-    ReentrantMonitorAutoEnter lock(mMonitor);
+    RecursiveMutexAutoLock lock(mRecursiveMutex);
     switch (aDirection) {
     case ScrollDirection::NONE:
       EXPECT_EQ(PANNING, mState);
       break;
     case ScrollDirection::HORIZONTAL:
       EXPECT_EQ(PANNING_LOCKED_X, mState);
       break;
     case ScrollDirection::VERTICAL:
--- a/mobile/android/components/BrowserCLH.js
+++ b/mobile/android/components/BrowserCLH.js
@@ -133,20 +133,20 @@ BrowserCLH.prototype = {
             mozSystemGroup: true,
           },
         });
 
         GeckoViewUtils.addLazyEventListener(win, [
           "focus", "blur", "click", "input",
         ], {
           handler: event => {
-            if (event.target instanceof Ci.nsIDOMHTMLInputElement ||
-                event.target instanceof Ci.nsIDOMHTMLTextAreaElement ||
-                event.target instanceof Ci.nsIDOMHTMLSelectElement ||
-                event.target instanceof Ci.nsIDOMHTMLButtonElement) {
+            if (ChromeUtils.getClassName(event.target) === "HTMLInputElement" ||
+                ChromeUtils.getClassName(event.target) === "HTMLTextAreaElement" ||
+                ChromeUtils.getClassName(event.target) === "HTMLSelectElement" ||
+                ChromeUtils.getClassName(event.target) === "HTMLButtonElement") {
               // Only load FormAssistant when the event target is what we care about.
               return this.FormAssistant;
             }
             return null;
           },
           options: {
             capture: true,
             mozSystemGroup: true,
--- a/mobile/android/modules/FormAssistant.jsm
+++ b/mobile/android/modules/FormAssistant.jsm
@@ -291,20 +291,20 @@ var FormAssistant = {
     };
 
     this._getAutoCompleteSuggestions(aElement.value, aElement, resultsAvailable);
   },
 
   // Only show a validation message if the user submitted an invalid form,
   // there's a non-empty message string, and the element is the correct type
   _isValidateable: function(aElement) {
-    return (aElement instanceof Ci.nsIDOMHTMLInputElement ||
-            aElement instanceof Ci.nsIDOMHTMLTextAreaElement ||
-            aElement instanceof Ci.nsIDOMHTMLSelectElement ||
-            aElement instanceof Ci.nsIDOMHTMLButtonElement) &&
+    return (ChromeUtils.getClassName(aElement) === "HTMLInputElement" ||
+            ChromeUtils.getClassName(aElement) === "HTMLTextAreaElement" ||
+            ChromeUtils.getClassName(aElement) === "HTMLSelectElement" ||
+            ChromeUtils.getClassName(aElement) === "HTMLButtonElement") &&
            aElement.matches(":-moz-ui-invalid") &&
            aElement.validationMessage;
   },
 
   // Sends a validation message and position data for an element to the Java UI.
   // Returns true if there's a validation message to show, false otherwise.
   _showValidationMessage: function(aElement) {
     if (!this._isValidateable(aElement)) {
--- a/widget/gtk/WindowSurfaceX11Image.cpp
+++ b/widget/gtk/WindowSurfaceX11Image.cpp
@@ -88,17 +88,17 @@ WindowSurfaceX11Image::Commit(const Layo
     gfx::Factory::CreateSourceSurfaceForCairoSurface(mImageSurface->CairoSurface(),
                                                      mImageSurface->GetSize(),
                                                      mImageSurface->Format());
   if (!dt || !surf) {
     return;
   }
 
   gfx::IntRect bounds = aInvalidRegion.GetBounds().ToUnknownRect();
-  gfx::Rect rect(0, 0, bounds.XMost(), bounds.YMost());
+  gfx::Rect rect(bounds);
   if (rect.IsEmpty()) {
     return;
   }
 
   uint32_t numRects = aInvalidRegion.GetNumRects();
   if (numRects != 1) {
     AutoTArray<IntRect, 32> rects;
     rects.SetCapacity(numRects);
--- a/xpcom/reflect/xptinfo/ShimInterfaceInfo.cpp
+++ b/xpcom/reflect/xptinfo/ShimInterfaceInfo.cpp
@@ -41,17 +41,16 @@
 #include "nsIDOMEvent.h"
 #include "nsIDOMEventTarget.h"
 #include "nsIDOMFileList.h"
 #include "nsIDOMFocusEvent.h"
 #include "nsIDOMFormData.h"
 #include "nsIDOMGeoPositionError.h"
 #include "nsIDOMHistory.h"
 #include "nsIDOMHTMLBaseElement.h"
-#include "nsIDOMHTMLButtonElement.h"
 #include "nsIDOMHTMLCanvasElement.h"
 #include "nsIDOMHTMLCollection.h"
 #include "nsIDOMHTMLDocument.h"
 #include "nsIDOMHTMLElement.h"
 #include "nsIDOMHTMLFormElement.h"
 #include "nsIDOMHTMLFrameElement.h"
 #include "nsIDOMHTMLHtmlElement.h"
 #include "nsIDOMHTMLIFrameElement.h"
@@ -315,17 +314,16 @@ const ComponentsInterfaceShimEntry kComp
   DEFINE_SHIM(EventTarget),
   DEFINE_SHIM(FileList),
   DEFINE_SHIM(FocusEvent),
   DEFINE_SHIM(FormData),
   DEFINE_SHIM_WITH_CUSTOM_INTERFACE(nsIFrameLoader, FrameLoader),
   DEFINE_SHIM_WITH_CUSTOM_INTERFACE(nsIDOMGeoPositionError, PositionError),
   DEFINE_SHIM(History),
   DEFINE_SHIM(HTMLBaseElement),
-  DEFINE_SHIM(HTMLButtonElement),
   DEFINE_SHIM(HTMLCanvasElement),
   DEFINE_SHIM(HTMLCollection),
   DEFINE_SHIM(HTMLDocument),
   DEFINE_SHIM(HTMLElement),
   DEFINE_SHIM(HTMLFormElement),
   DEFINE_SHIM(HTMLFrameElement),
   DEFINE_SHIM(HTMLHtmlElement),
   DEFINE_SHIM(HTMLIFrameElement),
--- a/xpcom/threads/RecursiveMutex.h
+++ b/xpcom/threads/RecursiveMutex.h
@@ -28,22 +28,31 @@ public:
 #ifdef DEBUG
   void Lock();
   void Unlock();
 #else
   void Lock() { LockInternal(); }
   void Unlock() { UnlockInternal(); }
 #endif
 
-  void AssertCurrentThreadIn()
 #ifdef DEBUG
-    ;
+  /**
+   * AssertCurrentThreadIn
+   **/
+  void AssertCurrentThreadIn();
+  /**
+   * AssertNotCurrentThreadIn
+   **/
+  void AssertNotCurrentThreadIn()
+  {
+    //Not currently implemented. See bug 476536 for discussion.
+  }
 #else
-  {
-  }
+  void AssertCurrentThreadIn() {}
+  void AssertNotCurrentThreadIn() {}
 #endif
 
 private:
   RecursiveMutex() = delete;
   RecursiveMutex(const RecursiveMutex&) = delete;
   RecursiveMutex& operator=(const RecursiveMutex&) = delete;
 
   void LockInternal();