Merge mozilla-central to autoland. CLOSED TREE
authorCsoregi Natalia <ncsoregi@mozilla.com>
Fri, 25 Jan 2019 19:02:11 +0200
changeset 515474 1eff1054beb1fc230fe23e00a2d955228b13a2a7
parent 515473 9d660bf33923903f095e06f0653ee8a5433d9403 (current diff)
parent 515463 90fb8bea5ef5e2868713f6cbc5a7be3001234a8b (diff)
child 515475 847b1ed7c06011fb07e153cf09e6b4775ba9768c
push id1953
push userffxbld-merge
push dateMon, 11 Mar 2019 12:10:20 +0000
treeherdermozilla-release@9c35dcbaa899 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone66.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge mozilla-central to autoland. CLOSED TREE
dom/smil/nsISMILAttr.h
gfx/wr/wrench/reftests/border/reftest.list
--- a/browser/base/content/test/sanitize/browser_cookiePermission.js
+++ b/browser/base/content/test/sanitize/browser_cookiePermission.js
@@ -245,16 +245,36 @@ tests.forEach(methods => {
           expectedForOrg: true,
           expectedForCom: false,
           fullHost: true,
         });
     });
   });
 });
 
+// Session mode, but with unsupported custom permission, data in
+// www.example.com, cookie permission set for www.example.com
+tests.forEach(methods => {
+  attributes.forEach(originAttributes => {
+    add_task(async function deleteStorageOnlyCustomPermission() {
+      info(methods.name + ": All is session only, but with unsupported custom custom permission, data in www.example.com, cookie permission set for www.example.com - OA: " + originAttributes.name);
+      await deleteOnShutdown(
+        { lifetimePolicy: Ci.nsICookieService.ACCEPT_SESSION,
+          createData: methods.createData,
+          checkData: methods.checkData,
+          originAttributes: originAttributes.oa,
+          cookiePermission: 123, // invalid cookie permission
+          expectedForOrg: false,
+          expectedForCom: false,
+          fullHost: true,
+        });
+    });
+  });
+});
+
 add_task(async function deleteStorageInAboutURL() {
   info("Test about:newtab");
 
   // Let's clean up all the data.
   await new Promise(resolve => {
     Services.clearData.deleteData(Ci.nsIClearDataService.CLEAR_ALL, value => resolve());
   });
 
--- a/browser/modules/Sanitizer.jsm
+++ b/browser/modules/Sanitizer.jsm
@@ -683,17 +683,16 @@ async function sanitizeOnShutdown(progre
   // are also other ways to think about and accomplish this, but this is what
   // the logic below currently does!
   if (Services.prefs.getIntPref(PREF_COOKIE_LIFETIME,
                                 Ci.nsICookieService.ACCEPT_NORMALLY) == Ci.nsICookieService.ACCEPT_SESSION) {
     let principals = await getAllPrincipals();
     await maybeSanitizeSessionPrincipals(principals);
   }
 
-
   // Let's see if we have to forget some particular site.
   for (let permission of Services.perms.enumerator) {
     if (permission.type != "cookie" ||
         permission.capability != Ci.nsICookiePermission.ACCESS_SESSION) {
       continue;
     }
 
     // We consider just permissions set for http, https and file URLs.
@@ -803,16 +802,21 @@ function cookiesAllowedForDomainOrSubDom
     return true;
   }
 
   if (p == Ci.nsICookiePermission.ACCESS_DENY ||
       p == Ci.nsICookiePermission.ACCESS_SESSION) {
     return false;
   }
 
+  // This is an old profile with unsupported permission values
+  if (p != Ci.nsICookiePermission.ACCESS_DEFAULT) {
+    return false;
+  }
+
   for (let perm of Services.perms.enumerator) {
     if (perm.type != "cookie") {
       continue;
     }
 
     // We consider just permissions set for http, https and file URLs.
     if (!isSupportedURI(perm.principal.URI)) {
       continue;
--- a/dom/base/CharacterData.h
+++ b/dom/base/CharacterData.h
@@ -15,17 +15,16 @@
 #include "mozilla/Attributes.h"
 #include "nsIContent.h"
 
 #include "nsTextFragment.h"
 #include "nsError.h"
 #include "mozilla/dom/Element.h"
 #include "nsCycleCollectionParticipant.h"
 
-#include "nsISMILAttr.h"
 #include "mozilla/dom/ShadowRoot.h"
 
 namespace mozilla {
 namespace dom {
 class HTMLSlotElement;
 }  // namespace dom
 }  // namespace mozilla
 
--- a/dom/base/Element.h
+++ b/dom/base/Element.h
@@ -8,62 +8,61 @@
  * Base class for all element classes; this provides an implementation
  * of DOM Core's Element, implements nsIContent, provides
  * utility methods for subclasses, and so forth.
  */
 
 #ifndef mozilla_dom_Element_h__
 #define mozilla_dom_Element_h__
 
-#include "mozilla/dom/FragmentOrElement.h"  // for base class
-#include "nsChangeHint.h"                   // for enum
-#include "mozilla/EventStates.h"            // for member
-#include "mozilla/RustCell.h"
-#include "mozilla/dom/DirectionalityUtils.h"
+#include "AttrArray.h"
+#include "DOMIntersectionObserver.h"
+#include "nsAttrValue.h"
+#include "nsAttrValueInlines.h"
+#include "nsChangeHint.h"
+#include "nsContentUtils.h"
+#include "nsDOMAttributeMap.h"
 #include "nsILinkHandler.h"
 #include "nsINodeList.h"
+#include "nsIScrollableFrame.h"
 #include "nsNodeUtils.h"
-#include "AttrArray.h"
+#include "nsPresContext.h"
+#include "Units.h"
+#include "mozilla/Attributes.h"
+#include "mozilla/CORSMode.h"
+#include "mozilla/EventForwards.h"
+#include "mozilla/EventStates.h"
 #include "mozilla/FlushType.h"
-#include "nsDOMAttributeMap.h"
-#include "nsPresContext.h"
-#include "mozilla/CORSMode.h"
-#include "mozilla/Attributes.h"
-#include "nsIScrollableFrame.h"
+#include "mozilla/RustCell.h"
+#include "mozilla/SMILAttr.h"
+#include "mozilla/UniquePtr.h"
 #include "mozilla/dom/Attr.h"
-#include "nsISMILAttr.h"
+#include "mozilla/dom/BindingDeclarations.h"
+#include "mozilla/dom/DirectionalityUtils.h"
+#include "mozilla/dom/FragmentOrElement.h"
 #include "mozilla/dom/DOMRect.h"
-#include "nsAttrValue.h"
-#include "nsAttrValueInlines.h"
-#include "mozilla/EventForwards.h"
-#include "mozilla/dom/BindingDeclarations.h"
 #include "mozilla/dom/DOMTokenListSupportedTokens.h"
-#include "mozilla/dom/WindowBinding.h"
 #include "mozilla/dom/ElementBinding.h"
 #include "mozilla/dom/Nullable.h"
 #include "mozilla/dom/PointerEventHandler.h"
-#include "mozilla/UniquePtr.h"
-#include "Units.h"
-#include "DOMIntersectionObserver.h"
-#include "nsContentUtils.h"
+#include "mozilla/dom/WindowBinding.h"
 
 class mozAutoDocUpdate;
 class nsIFrame;
 class nsIMozBrowserFrame;
 class nsIURI;
 class nsIScrollableFrame;
 class nsAttrValueOrString;
 class nsContentList;
 class nsDOMTokenList;
 struct nsRect;
 class nsFocusManager;
 class nsGlobalWindowInner;
 class nsGlobalWindowOuter;
 class nsDOMCSSAttributeDeclaration;
-class nsISMILAttr;
 class nsDOMStringMap;
 struct ServoNodeData;
 
 class nsIDOMXULButtonElement;
 class nsIDOMXULContainerElement;
 class nsIDOMXULContainerItemElement;
 class nsIDOMXULControlElement;
 class nsIDOMXULMenuListElement;
@@ -351,21 +350,21 @@ class Element : public FragmentOrElement
    * Set the SMIL override style declaration for this element. If
    * aNotify is true, this method will notify the document's pres
    * context, so that the style changes will be noticed.
    */
   nsresult SetSMILOverrideStyleDeclaration(DeclarationBlock* aDeclaration,
                                            bool aNotify);
 
   /**
-   * Returns a new nsISMILAttr that allows the caller to animate the given
+   * Returns a new SMILAttr that allows the caller to animate the given
    * attribute on this element.
    */
-  virtual UniquePtr<nsISMILAttr> GetAnimatedAttr(int32_t aNamespaceID,
-                                                 nsAtom* aName) {
+  virtual UniquePtr<SMILAttr> GetAnimatedAttr(int32_t aNamespaceID,
+                                              nsAtom* aName) {
     return nullptr;
   }
 
   /**
    * Get the SMIL override style for this element. This is a style declaration
    * that is applied *after* the inline style, and it can be used e.g. to store
    * animated style values.
    *
--- a/dom/smil/SMILAnimationController.cpp
+++ b/dom/smil/SMILAnimationController.cpp
@@ -94,18 +94,18 @@ void SMILAnimationController::Resume(uin
   SMILTimeContainer::Resume(aType);
 
   if (wasPaused && !mPauseState && mChildContainerTable.Count()) {
     MaybeStartSampling(GetRefreshDriver());
     Sample();  // Run the first sample manually
   }
 }
 
-nsSMILTime SMILAnimationController::GetParentTime() const {
-  return (nsSMILTime)(mCurrentSampleTime - mStartTime).ToMilliseconds();
+SMILTime SMILAnimationController::GetParentTime() const {
+  return (SMILTime)(mCurrentSampleTime - mStartTime).ToMilliseconds();
 }
 
 //----------------------------------------------------------------------
 // nsARefreshObserver methods:
 NS_IMPL_ADDREF(SMILAnimationController)
 NS_IMPL_RELEASE(SMILAnimationController)
 
 // nsRefreshDriver Callback function
@@ -127,34 +127,34 @@ void SMILAnimationController::WillRefres
   // Smoothing of coefficient for the average function. 0.2 should let us track
   // the sample rate reasonably tightly without being overly affected by
   // occasional delays.
   static const double SAMPLE_DUR_WEIGHTING = 0.2;
   // If the elapsed time exceeds our expectation by this number of times we'll
   // initiate special behaviour to basically ignore the intervening time.
   static const double SAMPLE_DEV_THRESHOLD = 200.0;
 
-  nsSMILTime elapsedTime =
-      (nsSMILTime)(aTime - mCurrentSampleTime).ToMilliseconds();
+  SMILTime elapsedTime =
+      (SMILTime)(aTime - mCurrentSampleTime).ToMilliseconds();
   if (mAvgTimeBetweenSamples == 0) {
     // First sample.
     mAvgTimeBetweenSamples = elapsedTime;
   } else {
     if (elapsedTime > SAMPLE_DEV_THRESHOLD * mAvgTimeBetweenSamples) {
       // Unexpectedly long delay between samples.
       NS_WARNING(
           "Detected really long delay between samples, continuing from "
           "previous sample");
       mParentOffset += elapsedTime - mAvgTimeBetweenSamples;
     }
     // Update the moving average. Due to truncation here the average will
     // normally be a little less than it should be but that's probably ok.
     mAvgTimeBetweenSamples =
-        (nsSMILTime)(elapsedTime * SAMPLE_DUR_WEIGHTING +
-                     mAvgTimeBetweenSamples * (1.0 - SAMPLE_DUR_WEIGHTING));
+        (SMILTime)(elapsedTime * SAMPLE_DUR_WEIGHTING +
+                   mAvgTimeBetweenSamples * (1.0 - SAMPLE_DUR_WEIGHTING));
   }
   mCurrentSampleTime = aTime;
 
   Sample();
 }
 
 //----------------------------------------------------------------------
 // Animation element registration methods:
@@ -459,17 +459,17 @@ void SMILAnimationController::DoMileston
   // endpoint-exclusive timing model.
   //
   // So we have the animations (specifically the timed elements) register the
   // next significant moment (called a milestone) in their lifetime and then we
   // step through the model at each of these moments and sample those animations
   // registered for those times. This way events can fire in the correct order,
   // dependencies can be resolved etc.
 
-  nsSMILTime sampleTime = INT64_MIN;
+  SMILTime sampleTime = INT64_MIN;
 
   while (true) {
     // We want to find any milestones AT OR BEFORE the current sample time so we
     // initialise the next milestone to the moment after (1ms after, to be
     // precise) the current sample time and see if there are any milestones
     // before that. Any other milestones will be dealt with in a subsequent
     // sample.
     SMILMilestone nextMilestone(GetCurrentTimeAsSMILTime() + 1, true);
@@ -521,18 +521,18 @@ void SMILAnimationController::DoMileston
         // its parent since registering a milestone.
         continue;
 
       SMILTimeValue containerTimeValue =
           container->ParentToContainerTime(sampleTime);
       if (!containerTimeValue.IsDefinite()) continue;
 
       // Clamp the converted container time to non-negative values.
-      nsSMILTime containerTime =
-          std::max<nsSMILTime>(0, containerTimeValue.GetMillis());
+      SMILTime containerTime =
+          std::max<SMILTime>(0, containerTimeValue.GetMillis());
 
       if (nextMilestone.mIsEnd) {
         elem->TimedElement().SampleEndAt(containerTime);
       } else {
         elem->TimedElement().SampleAt(containerTime);
       }
     }
   }
@@ -549,17 +549,17 @@ void SMILAnimationController::DoMileston
   // containers so the paused ones don't need a sample any more and they'll
   // return false.
   //
   // Instead we build up a hashmap of active time containers during the previous
   // step (SampleTimeContainer) and then test here if the container for this
   // timed element is in the list.
   if (!aActiveContainers->GetEntry(timeContainer)) return;
 
-  nsSMILTime containerTime = timeContainer->GetCurrentTimeAsSMILTime();
+  SMILTime containerTime = timeContainer->GetCurrentTimeAsSMILTime();
 
   MOZ_ASSERT(!timeContainer->IsSeeking(),
              "Doing a regular sample but the time container is still seeking");
   aElement->TimedElement().SampleAt(containerTime);
 }
 
 /*static*/ void SMILAnimationController::AddAnimationToCompositorTable(
     SVGAnimationElement* aElement, SMILCompositorTable* aCompositorTable,
--- a/dom/smil/SMILAnimationController.h
+++ b/dom/smil/SMILAnimationController.h
@@ -1,16 +1,16 @@
 /* -*- 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 NS_SMILANIMATIONCONTROLLER_H_
-#define NS_SMILANIMATIONCONTROLLER_H_
+#ifndef mozilla_SMILAnimationController_h
+#define mozilla_SMILAnimationController_h
 
 #include "mozilla/Attributes.h"
 #include "mozilla/SMILCompositorTable.h"
 #include "mozilla/SMILMilestone.h"
 #include "mozilla/SMILTimeContainer.h"
 #include "nsAutoPtr.h"
 #include "nsCOMPtr.h"
 #include "nsTArray.h"
@@ -43,20 +43,20 @@ class SMILAnimationController final : pu
                                       public nsARefreshObserver {
  public:
   explicit SMILAnimationController(mozilla::dom::Document* aDoc);
 
   // Clears mDocument pointer. (Called by our mozilla::dom::Document when it's
   // going away)
   void Disconnect();
 
-  // nsSMILContainer
+  // SMILContainer
   virtual void Pause(uint32_t aType) override;
   virtual void Resume(uint32_t aType) override;
-  virtual nsSMILTime GetParentTime() const override;
+  virtual SMILTime GetParentTime() const override;
 
   // nsARefreshObserver
   NS_IMETHOD_(MozExternalRefCountType) AddRef() override;
   NS_IMETHOD_(MozExternalRefCountType) Release() override;
 
   virtual void WillRefresh(mozilla::TimeStamp aTime) override;
 
   // Methods for registering and enumerating animation elements
@@ -174,17 +174,17 @@ class SMILAnimationController final : pu
   //
   // Note that we only do this for SMIL and not CSS transitions (which doesn't
   // have so much work to do to catch up) nor scripted animations (which expect
   // animation time to follow real time).
   //
   // This behaviour does not affect pausing (since we're not *expecting* any
   // samples then) nor seeking (where the SMIL model behaves somewhat
   // differently such as not dispatching events).
-  nsSMILTime mAvgTimeBetweenSamples;
+  SMILTime mAvgTimeBetweenSamples;
 
   bool mResampleNeeded;
   // If we're told to start sampling but there are no animation elements we just
   // record the time, set the following flag, and then wait until we have an
   // animation element. Then we'll reset this flag and actually start sampling.
   bool mDeferredStartSampling;
   bool mRunningSample;
 
@@ -202,9 +202,9 @@ class SMILAnimationController final : pu
   // so we can detect when an element/attribute used to be animated,
   // but isn't anymore for some reason. (e.g. if its <animate> element is
   // removed or retargeted)
   nsAutoPtr<SMILCompositorTable> mLastCompositorTable;
 };
 
 }  // namespace mozilla
 
-#endif  // NS_SMILANIMATIONCONTROLLER_H_
+#endif  // mozilla_SMILAnimationController_h
--- a/dom/smil/SMILAnimationFunction.cpp
+++ b/dom/smil/SMILAnimationFunction.cpp
@@ -2,22 +2,23 @@
 /* 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 "SMILAnimationFunction.h"
 
 #include "mozilla/dom/SVGAnimationElement.h"
+#include "mozilla/DebugOnly.h"
 #include "mozilla/Move.h"
+#include "mozilla/SMILAttr.h"
 #include "mozilla/SMILCSSValueType.h"
 #include "mozilla/SMILNullType.h"
 #include "mozilla/SMILParserUtils.h"
 #include "mozilla/SMILTimedElement.h"
-#include "nsISMILAttr.h"
 #include "nsAttrValueInlines.h"
 #include "nsGkAtoms.h"
 #include "nsCOMPtr.h"
 #include "nsCOMArray.h"
 #include "nsIContent.h"
 #include "nsContentUtils.h"
 #include "nsReadableUtils.h"
 #include "nsString.h"
@@ -125,17 +126,17 @@ bool SMILAnimationFunction::UnsetAttr(ns
     UnsetKeySplines();
   } else {
     foundMatch = false;
   }
 
   return foundMatch;
 }
 
-void SMILAnimationFunction::SampleAt(nsSMILTime aSampleTime,
+void SMILAnimationFunction::SampleAt(SMILTime aSampleTime,
                                      const SMILTimeValue& aSimpleDuration,
                                      uint32_t aRepeatIteration) {
   // * Update mHasChanged ("Might this sample be different from prev one?")
   // Were we previously sampling a fill="freeze" final val? (We're not anymore.)
   mHasChanged |= mLastValue;
 
   // Are we sampling at a new point in simple duration? And does that matter?
   mHasChanged |=
@@ -157,30 +158,30 @@ void SMILAnimationFunction::SampleLastVa
   if (mHasChanged || !mLastValue || mRepeatIteration != aRepeatIteration) {
     mHasChanged = true;
   }
 
   mRepeatIteration = aRepeatIteration;
   mLastValue = true;
 }
 
-void SMILAnimationFunction::Activate(nsSMILTime aBeginTime) {
+void SMILAnimationFunction::Activate(SMILTime aBeginTime) {
   mBeginTime = aBeginTime;
   mIsActive = true;
   mIsFrozen = false;
   mHasChanged = true;
 }
 
 void SMILAnimationFunction::Inactivate(bool aIsFrozen) {
   mIsActive = false;
   mIsFrozen = aIsFrozen;
   mHasChanged = true;
 }
 
-void SMILAnimationFunction::ComposeResult(const nsISMILAttr& aSMILAttr,
+void SMILAnimationFunction::ComposeResult(const SMILAttr& aSMILAttr,
                                           SMILValue& aResult) {
   mHasChanged = false;
   mPrevSampleWasSingleValueAnimation = false;
   mWasSkippedInPrevSample = false;
 
   // Skip animations that are inactive or in error
   if (!IsActiveOrFrozen() || mErrorFlags != 0) return;
 
@@ -315,33 +316,33 @@ nsresult SMILAnimationFunction::Interpol
   // Get the normalised progress through the simple duration.
   //
   // If we have an indefinite simple duration, just set the progress to be
   // 0 which will give us the expected behaviour of the animation being fixed at
   // its starting point.
   double simpleProgress = 0.0;
 
   if (mSimpleDuration.IsDefinite()) {
-    nsSMILTime dur = mSimpleDuration.GetMillis();
+    SMILTime dur = mSimpleDuration.GetMillis();
 
     MOZ_ASSERT(dur >= 0, "Simple duration should not be negative");
     MOZ_ASSERT(mSampleTime >= 0, "Sample time should not be negative");
 
     if (mSampleTime >= dur || mSampleTime < 0) {
       NS_ERROR("Animation sampled outside interval");
       return NS_ERROR_FAILURE;
     }
 
     if (dur > 0) {
       simpleProgress = (double)mSampleTime / dur;
     }  // else leave simpleProgress at 0.0 (e.g. if mSampleTime == dur == 0)
   }
 
   nsresult rv = NS_OK;
-  nsSMILCalcMode calcMode = GetCalcMode();
+  SMILCalcMode calcMode = GetCalcMode();
 
   // Force discrete calcMode for visibility since StyleAnimationValue will
   // try to interpolate it using the special clamping behavior defined for
   // CSS.
   if (SMILCSSValueType::PropertyFromValue(aValues[0]) ==
       eCSSProperty_visibility) {
     calcMode = CALC_DISCRETE;
   }
@@ -518,19 +519,17 @@ nsresult SMILAnimationFunction::ComputeP
   for (uint32_t i = 0; i < aValues.Length() - 1; i++) {
     // Note: The following assertion is valid because remainingDist should
     // start out non-negative, and this loop never shaves off more than its
     // current value.
     NS_ASSERTION(remainingDist >= 0, "distance values must be non-negative");
 
     double curIntervalDist;
 
-#ifdef DEBUG
-    nsresult rv =
-#endif
+    DebugOnly<nsresult> rv =
         aValues[i].ComputeDistance(aValues[i + 1], curIntervalDist);
     MOZ_ASSERT(NS_SUCCEEDED(rv),
                "If we got through ComputePacedTotalDistance, we should "
                "be able to recompute each sub-distance without errors");
 
     NS_ASSERTION(curIntervalDist >= 0, "distance values must be non-negative");
     // Clamp distance value at 0, just in case ComputeDistance is evil.
     curIntervalDist = std::max(curIntervalDist, 0.0);
@@ -587,17 +586,17 @@ double SMILAnimationFunction::ComputePac
 
     totalDistance += tmpDist;
   }
 
   return totalDistance;
 }
 
 double SMILAnimationFunction::ScaleSimpleProgress(double aProgress,
-                                                  nsSMILCalcMode aCalcMode) {
+                                                  SMILCalcMode aCalcMode) {
   if (!HasAttr(nsGkAtoms::keyTimes)) return aProgress;
 
   uint32_t numTimes = mKeyTimes.Length();
 
   if (numTimes < 2) return aProgress;
 
   uint32_t i = 0;
   for (; i < numTimes - 2 && aProgress >= mKeyTimes[i + 1]; ++i) {
@@ -658,23 +657,23 @@ bool SMILAnimationFunction::GetAttr(nsAt
  *
  * @param aAttName    The attribute name (in the global namespace).
  * @param aSMILAttr   The SMIL attribute to perform the parsing.
  * @param[out] aResult        The resulting SMILValue.
  * @param[out] aPreventCachingOfSandwich
  *                    If |aResult| contains dependencies on its context that
  *                    should prevent the result of the animation sandwich from
  *                    being cached and reused in future samples (as reported
- *                    by nsISMILAttr::ValueFromString), then this outparam
+ *                    by SMILAttr::ValueFromString), then this outparam
  *                    will be set to true. Otherwise it is left unmodified.
  *
  * Returns false if a parse error occurred, otherwise returns true.
  */
 bool SMILAnimationFunction::ParseAttr(nsAtom* aAttName,
-                                      const nsISMILAttr& aSMILAttr,
+                                      const SMILAttr& aSMILAttr,
                                       SMILValue& aResult,
                                       bool& aPreventCachingOfSandwich) const {
   nsAutoString attValue;
   if (GetAttr(aAttName, attValue)) {
     bool preventCachingOfSandwich = false;
     nsresult rv = aSMILAttr.ValueFromString(attValue, mAnimationElement,
                                             aResult, preventCachingOfSandwich);
     if (NS_FAILED(rv)) return false;
@@ -695,17 +694,17 @@ bool SMILAnimationFunction::ParseAttr(ns
  * (3) if both by and to are specified only to will be used, by will be ignored
  * (4) if by is specified without from (by animation), forces additive behaviour
  * (5) if to is specified without from (to animation), special care needs to be
  *     taken when compositing animation as such animations are composited last.
  *
  * This helper method applies these rules to fill in the values list and to set
  * some internal state.
  */
-nsresult SMILAnimationFunction::GetValues(const nsISMILAttr& aSMILAttr,
+nsresult SMILAnimationFunction::GetValues(const SMILAttr& aSMILAttr,
                                           SMILValueArray& aResult) {
   if (!mAnimationElement) return NS_ERROR_FAILURE;
 
   mValueNeedsReparsingEverySample = false;
   SMILValueArray result;
 
   // If "values" is set, use it
   if (HasAttr(nsGkAtoms::values)) {
@@ -779,17 +778,17 @@ void SMILAnimationFunction::CheckValueLi
 /**
  * Performs checks for the keyTimes attribute required by the SMIL spec but
  * which depend on other attributes and therefore needs to be updated as
  * dependent attributes are set.
  */
 void SMILAnimationFunction::CheckKeyTimes(uint32_t aNumValues) {
   if (!HasAttr(nsGkAtoms::keyTimes)) return;
 
-  nsSMILCalcMode calcMode = GetCalcMode();
+  SMILCalcMode calcMode = GetCalcMode();
 
   // attribute is ignored for calcMode = paced
   if (calcMode == CALC_PACED) {
     SetKeyTimesErrorFlag(false);
     return;
   }
 
   uint32_t numKeyTimes = mKeyTimes.Length();
@@ -876,22 +875,21 @@ bool SMILAnimationFunction::GetAccumulat
 
 bool SMILAnimationFunction::GetAdditive() const {
   const nsAttrValue* value = GetAttr(nsGkAtoms::additive);
   if (!value) return false;
 
   return value->GetEnumValue();
 }
 
-SMILAnimationFunction::nsSMILCalcMode SMILAnimationFunction::GetCalcMode()
-    const {
+SMILAnimationFunction::SMILCalcMode SMILAnimationFunction::GetCalcMode() const {
   const nsAttrValue* value = GetAttr(nsGkAtoms::calcMode);
   if (!value) return CALC_LINEAR;
 
-  return nsSMILCalcMode(value->GetEnumValue());
+  return SMILCalcMode(value->GetEnumValue());
 }
 
 //----------------------------------------------------------------------
 // Property setters / un-setters:
 
 nsresult SMILAnimationFunction::SetAccumulate(const nsAString& aAccumulate,
                                               nsAttrValue& aResult) {
   mHasChanged = true;
--- a/dom/smil/SMILAnimationFunction.h
+++ b/dom/smil/SMILAnimationFunction.h
@@ -1,25 +1,25 @@
 /* -*- 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 NS_SMILANIMATIONFUNCTION_H_
-#define NS_SMILANIMATIONFUNCTION_H_
+#ifndef mozilla_SMILAnimationFunction_h
+#define mozilla_SMILAnimationFunction_h
 
+#include "mozilla/SMILAttr.h"
 #include "mozilla/SMILKeySpline.h"
 #include "mozilla/SMILTargetIdentifier.h"
 #include "mozilla/SMILTimeValue.h"
 #include "mozilla/SMILTypes.h"
 #include "mozilla/SMILValue.h"
 #include "nsAttrValue.h"
 #include "nsGkAtoms.h"
-#include "nsISMILAttr.h"
 #include "nsString.h"
 #include "nsTArray.h"
 
 namespace mozilla {
 namespace dom {
 class SVGAnimationElement;
 }  // namespace dom
 
@@ -74,17 +74,17 @@ class SMILAnimationFunction {
    * Indicate a new sample has occurred.
    *
    * @param aSampleTime The sample time for this timed element expressed in
    *                    simple time.
    * @param aSimpleDuration The simple duration for this timed element.
    * @param aRepeatIteration  The repeat iteration for this sample. The first
    *                          iteration has a value of 0.
    */
-  void SampleAt(nsSMILTime aSampleTime, const SMILTimeValue& aSimpleDuration,
+  void SampleAt(SMILTime aSampleTime, const SMILTimeValue& aSimpleDuration,
                 uint32_t aRepeatIteration);
 
   /**
    * Indicate to sample using the last value defined for the animation function.
    * This value is not normally sampled due to the end-point exclusive timing
    * model but only occurs when the fill mode is "freeze" and the active
    * duration is an even multiple of the simple duration.
    *
@@ -97,17 +97,17 @@ class SMILAnimationFunction {
    * Indicate that this animation is now active. This is used to instruct the
    * animation function that it should now add its result to the animation
    * sandwich. The begin time is also provided for proper prioritization of
    * animation functions, and for this reason, this method must be called
    * before either of the Sample methods.
    *
    * @param aBeginTime The begin time for the newly active interval.
    */
-  void Activate(nsSMILTime aBeginTime);
+  void Activate(SMILTime aBeginTime);
 
   /**
    * Indicate that this animation is no longer active. This is used to instruct
    * the animation function that it should no longer add its result to the
    * animation sandwich.
    *
    * @param aIsFrozen true if this animation should continue to contribute
    *                  to the animation sandwich using the most recent sample
@@ -119,17 +119,17 @@ class SMILAnimationFunction {
    * Combines the result of this animation function for the last sample with the
    * specified value.
    *
    * @param aSMILAttr This animation's target attribute. Used here for
    *                  doing attribute-specific parsing of from/to/by/values.
    *
    * @param aResult   The value to compose with.
    */
-  void ComposeResult(const nsISMILAttr& aSMILAttr, SMILValue& aResult);
+  void ComposeResult(const SMILAttr& aSMILAttr, SMILValue& aResult);
 
   /**
    * Returns the relative priority of this animation to another. The priority is
    * used for determining the position of the animation in the animation
    * sandwich -- higher priority animations are applied on top of lower
    * priority animations.
    *
    * @return  -1 if this animation has lower priority or 1 if this animation has
@@ -256,30 +256,30 @@ class SMILAnimationFunction {
     }
   };
 
  protected:
   // Typedefs
   typedef FallibleTArray<SMILValue> SMILValueArray;
 
   // Types
-  enum nsSMILCalcMode : uint8_t {
+  enum SMILCalcMode : uint8_t {
     CALC_LINEAR,
     CALC_DISCRETE,
     CALC_PACED,
     CALC_SPLINE
   };
 
   // Used for sorting SMILAnimationFunctions
-  nsSMILTime GetBeginTime() const { return mBeginTime; }
+  SMILTime GetBeginTime() const { return mBeginTime; }
 
   // Property getters
   bool GetAccumulate() const;
   bool GetAdditive() const;
-  virtual nsSMILCalcMode GetCalcMode() const;
+  virtual SMILCalcMode GetCalcMode() const;
 
   // Property setters
   nsresult SetAccumulate(const nsAString& aAccumulate, nsAttrValue& aResult);
   nsresult SetAdditive(const nsAString& aAdditive, nsAttrValue& aResult);
   nsresult SetCalcMode(const nsAString& aCalcMode, nsAttrValue& aResult);
   nsresult SetKeyTimes(const nsAString& aKeyTimes, nsAttrValue& aResult);
   nsresult SetKeySplines(const nsAString& aKeySplines, nsAttrValue& aResult);
 
@@ -300,33 +300,33 @@ class SMILAnimationFunction {
                                 double& aIntervalProgress,
                                 const SMILValue*& aFrom, const SMILValue*& aTo);
   double ComputePacedTotalDistance(const SMILValueArray& aValues) const;
 
   /**
    * Adjust the simple progress, that is, the point within the simple duration,
    * by applying any keyTimes.
    */
-  double ScaleSimpleProgress(double aProgress, nsSMILCalcMode aCalcMode);
+  double ScaleSimpleProgress(double aProgress, SMILCalcMode aCalcMode);
   /**
    * Adjust the progress within an interval, that is, between two animation
    * values, by applying any keySplines.
    */
   double ScaleIntervalProgress(double aProgress, uint32_t aIntervalIndex);
 
   // Convenience attribute getters -- use these instead of querying
   // mAnimationElement as these may need to be overridden by subclasses
   virtual bool HasAttr(nsAtom* aAttName) const;
   virtual const nsAttrValue* GetAttr(nsAtom* aAttName) const;
   virtual bool GetAttr(nsAtom* aAttName, nsAString& aResult) const;
 
-  bool ParseAttr(nsAtom* aAttName, const nsISMILAttr& aSMILAttr,
+  bool ParseAttr(nsAtom* aAttName, const SMILAttr& aSMILAttr,
                  SMILValue& aResult, bool& aPreventCachingOfSandwich) const;
 
-  virtual nsresult GetValues(const nsISMILAttr& aSMILAttr,
+  virtual nsresult GetValues(const SMILAttr& aSMILAttr,
                              SMILValueArray& aResult);
 
   virtual void CheckValueListDependentAttrs(uint32_t aNumValues);
   void CheckKeyTimes(uint32_t aNumValues);
   void CheckKeySplines(uint32_t aNumValues);
 
   virtual bool IsToAnimation() const {
     return !HasAttr(nsGkAtoms::values) && HasAttr(nsGkAtoms::to) &&
@@ -400,43 +400,43 @@ class SMILAnimationFunction {
   FallibleTArray<double> mKeyTimes;
   FallibleTArray<SMILKeySpline> mKeySplines;
 
   // These are the parameters provided by the previous sample. Currently we
   // perform lazy calculation. That is, we only calculate the result if and when
   // instructed by the compositor. This allows us to apply the result directly
   // to the animation value and allows the compositor to filter out functions
   // that it determines will not contribute to the final result.
-  nsSMILTime mSampleTime;  // sample time within simple dur
+  SMILTime mSampleTime;  // sample time within simple dur
   SMILTimeValue mSimpleDuration;
   uint32_t mRepeatIteration;
 
-  nsSMILTime mBeginTime;  // document time
+  SMILTime mBeginTime;  // document time
 
   // The owning animation element. This is used for sorting based on document
   // position and for fetching attribute values stored in the element.
   // Raw pointer is OK here, because this SMILAnimationFunction can't outlive
   // its owning animation element.
   mozilla::dom::SVGAnimationElement* mAnimationElement;
 
   // Which attributes have been set but have had errors. This is not used for
   // all attributes but only those which have specified error behaviour
   // associated with them.
   uint16_t mErrorFlags;
 
   // Allows us to check whether an animation function has changed target from
   // sample to sample (because if neither target nor animated value have
   // changed, we don't have to do anything).
-  nsSMILWeakTargetIdentifier mLastTarget;
+  SMILWeakTargetIdentifier mLastTarget;
 
   // Boolean flags
   bool mIsActive : 1;
   bool mIsFrozen : 1;
   bool mLastValue : 1;
   bool mHasChanged : 1;
   bool mValueNeedsReparsingEverySample : 1;
   bool mPrevSampleWasSingleValueAnimation : 1;
   bool mWasSkippedInPrevSample : 1;
 };
 
 }  // namespace mozilla
 
-#endif  // NS_SMILANIMATIONFUNCTION_H_
+#endif  // mozilla_SMILAnimationFunction_h
rename from dom/smil/nsISMILAttr.h
rename to dom/smil/SMILAttr.h
--- a/dom/smil/nsISMILAttr.h
+++ b/dom/smil/SMILAttr.h
@@ -1,43 +1,41 @@
 /* -*- 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 NS_ISMILATTR_H_
-#define NS_ISMILATTR_H_
+#ifndef mozilla_SMILAttr_h
+#define mozilla_SMILAttr_h
 
 #include "nscore.h"
 #include "nsStringFwd.h"
 
 class nsIContent;
 
 namespace mozilla {
 
 class SMILValue;
 
 namespace dom {
 class SVGAnimationElement;
 }  // namespace dom
-}  // namespace mozilla
 
 ////////////////////////////////////////////////////////////////////////
-// nsISMILAttr: A variable targeted by SMIL for animation and can therefore have
+// SMILAttr: A variable targeted by SMIL for animation and can therefore have
 // an underlying (base) value and an animated value For example, an attribute of
 // a particular SVG element.
 //
 // These objects only exist during the compositing phase of SMIL animation
 // calculations. They have a single owner who is responsible for deleting the
 // object.
 
-class nsISMILAttr {
+class SMILAttr {
  public:
-  typedef mozilla::SMILValue SMILValue;
   /**
    * Creates a new SMILValue for this attribute from a string. The string is
    * parsed in the context of this attribute so that context-dependent values
    * such as em-based units can be resolved into a canonical form suitable for
    * animation (including interpolation etc.).
    *
    * @param aStr        A string defining the new value to be created.
    * @param aSrcElement The source animation element. This may be needed to
@@ -77,24 +75,26 @@ class nsISMILAttr {
    * Sets the presentation value of this attribute.
    *
    * @param aValue  The value to set.
    * @return NS_OK on success or an error code if setting failed.
    */
   virtual nsresult SetAnimValue(const SMILValue& aValue) = 0;
 
   /**
-   * Returns the targeted content node, for any nsISMILAttr implementations
+   * Returns the targeted content node, for any SMILAttr implementations
    * that want to expose that to the animation logic.  Otherwise, returns
    * null.
    *
-   * @return the targeted content node, if this nsISMILAttr implementation
+   * @return the targeted content node, if this SMILAttr implementation
    * wishes to make it avaiable.  Otherwise, nullptr.
    */
   virtual const nsIContent* GetTargetNode() const { return nullptr; }
 
   /**
    * Virtual destructor, to make sure subclasses can clean themselves up.
    */
-  virtual ~nsISMILAttr() {}
+  virtual ~SMILAttr() {}
 };
 
-#endif  // NS_ISMILATTR_H_
+}  // namespace mozilla
+
+#endif  // mozilla_SMILAttr_h
--- a/dom/smil/SMILBoolType.h
+++ b/dom/smil/SMILBoolType.h
@@ -1,16 +1,16 @@
 /* -*- 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_SMILBOOLTYPE_H_
-#define MOZILLA_SMILBOOLTYPE_H_
+#ifndef mozilla_SMILBoolType_h
+#define mozilla_SMILBoolType_h
 
 #include "mozilla/Attributes.h"
 #include "mozilla/SMILType.h"
 
 namespace mozilla {
 
 class SMILBoolType : public SMILType {
  public:
@@ -39,9 +39,9 @@ class SMILBoolType : public SMILType {
 
  private:
   // Private constructor: prevent instances beyond my singleton.
   constexpr SMILBoolType() {}
 };
 
 }  // namespace mozilla
 
-#endif  // MOZILLA_SMILBOOLTYPE_H_
+#endif  // mozilla_SMILBoolType_h
--- a/dom/smil/SMILCSSProperty.h
+++ b/dom/smil/SMILCSSProperty.h
@@ -1,51 +1,51 @@
 /* -*- 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/. */
 
 /* representation of a SMIL-animatable CSS property on an element */
 
-#ifndef NS_SMILCSSPROPERTY_H_
-#define NS_SMILCSSPROPERTY_H_
+#ifndef mozilla_SMILCSSProperty_h
+#define mozilla_SMILCSSProperty_h
 
 #include "mozilla/Attributes.h"
-#include "nsISMILAttr.h"
+#include "mozilla/SMILAttr.h"
 #include "nsAtom.h"
 #include "nsCSSPropertyID.h"
 #include "nsCSSValue.h"
 
 namespace mozilla {
 class ComputedStyle;
 namespace dom {
 class Element;
 }  // namespace dom
 
 /**
- * SMILCSSProperty: Implements the nsISMILAttr interface for SMIL animations
+ * SMILCSSProperty: Implements the SMILAttr interface for SMIL animations
  * that target CSS properties.  Represents a particular animation-targeted CSS
  * property on a particular element.
  */
-class SMILCSSProperty : public nsISMILAttr {
+class SMILCSSProperty : public SMILAttr {
  public:
   /**
    * Constructs a new SMILCSSProperty.
    * @param  aPropID   The CSS property we're interested in animating.
    * @param  aElement  The element whose CSS property is being animated.
    * @param  aBaseComputedStyle  The ComputedStyle to use when getting the base
    *                             value. If this is nullptr and GetBaseValue is
    *                             called, an empty SMILValue initialized with
    *                             the SMILCSSValueType will be returned.
    */
   SMILCSSProperty(nsCSSPropertyID aPropID, dom::Element* aElement,
                   ComputedStyle* aBaseComputedStyle);
 
-  // nsISMILAttr methods
+  // SMILAttr methods
   virtual nsresult ValueFromString(
       const nsAString& aStr, const dom::SVGAnimationElement* aSrcElement,
       SMILValue& aValue, bool& aPreventCachingOfSandwich) const override;
   virtual SMILValue GetBaseValue() const override;
   virtual nsresult SetAnimValue(const SMILValue& aValue) override;
   virtual void ClearAnimValue() override;
 
   /**
@@ -59,24 +59,24 @@ class SMILCSSProperty : public nsISMILAt
    * @return  true if the given property is supported for SMIL animation, or
    *          false otherwise
    */
   static bool IsPropertyAnimatable(nsCSSPropertyID aPropID);
 
  protected:
   nsCSSPropertyID mPropID;
   // Using non-refcounted pointer for mElement -- we know mElement will stay
-  // alive for my lifetime because a nsISMILAttr (like me) only lives as long
+  // alive for my lifetime because a SMILAttr (like me) only lives as long
   // as the Compositing step, and DOM elements don't get a chance to die during
   // that time.
   dom::Element* mElement;
 
   // The style to use when fetching base styles.
   //
-  // As with mElement, since an nsISMILAttr only lives as long as the
+  // As with mElement, since a SMILAttr only lives as long as the
   // compositing step and since ComposeAttribute holds an owning reference to
   // the base ComputedStyle, we can use a non-owning reference here.
   ComputedStyle* mBaseComputedStyle;
 };
 
 }  // namespace mozilla
 
-#endif  // NS_SMILCSSPROPERTY_H_
+#endif  // mozilla_SMILCSSProperty_h
--- a/dom/smil/SMILCSSValueType.h
+++ b/dom/smil/SMILCSSValueType.h
@@ -1,18 +1,18 @@
 /* -*- 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/. */
 
 /* representation of a value for a SMIL-animated CSS property */
 
-#ifndef NS_SMILCSSVALUETYPE_H_
-#define NS_SMILCSSVALUETYPE_H_
+#ifndef mozilla_SMILCSSValueType_h
+#define mozilla_SMILCSSValueType_h
 
 #include "mozilla/Attributes.h"
 #include "mozilla/SMILType.h"
 #include "nsCSSPropertyID.h"
 #include "nsStringFwd.h"
 
 namespace mozilla {
 struct AnimationValue;
@@ -21,19 +21,16 @@ namespace dom {
 class Element;
 }  // namespace dom
 
 /*
  * SMILCSSValueType: Represents a SMIL-animated CSS value.
  */
 class SMILCSSValueType : public SMILType {
  public:
-  typedef mozilla::dom::Element Element;
-  typedef mozilla::AnimationValue AnimationValue;
-
   // Singleton for SMILValue objects to hold onto.
   static SMILCSSValueType sSingleton;
 
  protected:
   // SMILType Methods
   // -------------------
   void Init(SMILValue& aValue) const override;
   void Destroy(SMILValue&) const override;
@@ -69,33 +66,34 @@ class SMILCSSValueType : public SMILType
    *                                  a different |aValue| depending on other
    *                                  CSS properties on |aTargetElement|
    *                                  or its ancestors (e.g. 'inherit).
    *                                  false otherwise. May be nullptr.
    *                                  Not set if the method fails.
    * @pre  aValue.IsNull()
    * @post aValue.IsNull() || aValue.mType == SMILCSSValueType::sSingleton
    */
-  static void ValueFromString(nsCSSPropertyID aPropID, Element* aTargetElement,
+  static void ValueFromString(nsCSSPropertyID aPropID,
+                              dom::Element* aTargetElement,
                               const nsAString& aString, SMILValue& aValue,
                               bool* aIsContextSensitive);
 
   /**
    * Creates a SMILValue to wrap the given animation value.
    *
    * @param aPropID         The property that |aValue| corresponds to.
    * @param aTargetElement  The target element to which the animation value
    *                        applies.
    * @param aValue          The animation value to use.
    * @return                A new SMILValue. On failure, returns a
    *                        SMILValue with the null type (i.e. rv.IsNull()
    *                        returns true).
    */
   static SMILValue ValueFromAnimationValue(nsCSSPropertyID aPropID,
-                                           Element* aTargetElement,
+                                           dom::Element* aTargetElement,
                                            const AnimationValue& aValue);
 
   /**
    * Sets the relevant property values in the declaration block.
    *
    * Returns whether the declaration changed.
    */
   static bool SetPropertyValues(const SMILValue&, mozilla::DeclarationBlock&);
@@ -127,9 +125,9 @@ class SMILCSSValueType : public SMILType
 
  private:
   // Private constructor: prevent instances beyond my singleton.
   constexpr SMILCSSValueType() {}
 };
 
 }  // namespace mozilla
 
-#endif  // NS_SMILCSSVALUETYPE_H_
+#endif  // mozilla_SMILCSSValueType_h
--- a/dom/smil/SMILCompositor.cpp
+++ b/dom/smil/SMILCompositor.cpp
@@ -41,26 +41,26 @@ void SMILCompositor::AddAnimationFunctio
     mAnimationFunctions.AppendElement(aFunc);
   }
 }
 
 void SMILCompositor::ComposeAttribute(bool& aMightHavePendingStyleUpdates) {
   if (!mKey.mElement) return;
 
   // If we might need to resolve base styles, grab a suitable ComputedStyle
-  // for initializing our nsISMILAttr with.
+  // for initializing our SMILAttr with.
   RefPtr<ComputedStyle> baseComputedStyle;
   if (MightNeedBaseStyle()) {
     baseComputedStyle = nsComputedDOMStyle::GetUnanimatedComputedStyleNoFlush(
         mKey.mElement, nullptr);
   }
 
-  // FIRST: Get the nsISMILAttr (to grab base value from, and to eventually
+  // FIRST: Get the SMILAttr (to grab base value from, and to eventually
   // give animated value to)
-  UniquePtr<nsISMILAttr> smilAttr = CreateSMILAttr(baseComputedStyle);
+  UniquePtr<SMILAttr> smilAttr = CreateSMILAttr(baseComputedStyle);
   if (!smilAttr) {
     // Target attribute not found (or, out of memory)
     return;
   }
   if (mAnimationFunctions.IsEmpty()) {
     // No active animation functions. (We can still have a SMILCompositor in
     // that case if an animation function has *just* become inactive)
     smilAttr->ClearAnimValue();
@@ -97,34 +97,34 @@ void SMILCompositor::ComposeAttribute(bo
   if (sandwichResultValue.IsNull()) {
     smilAttr->ClearAnimValue();
     return;
   }
 
   // SIXTH: Set the animated value to the final composited result.
   nsresult rv = smilAttr->SetAnimValue(sandwichResultValue);
   if (NS_FAILED(rv)) {
-    NS_WARNING("nsISMILAttr::SetAnimValue failed");
+    NS_WARNING("SMILAttr::SetAnimValue failed");
   }
 }
 
 void SMILCompositor::ClearAnimationEffects() {
   if (!mKey.mElement || !mKey.mAttributeName) return;
 
-  UniquePtr<nsISMILAttr> smilAttr = CreateSMILAttr(nullptr);
+  UniquePtr<SMILAttr> smilAttr = CreateSMILAttr(nullptr);
   if (!smilAttr) {
     // Target attribute not found (or, out of memory)
     return;
   }
   smilAttr->ClearAnimValue();
 }
 
 // Protected Helper Functions
 // --------------------------
-UniquePtr<nsISMILAttr> SMILCompositor::CreateSMILAttr(
+UniquePtr<SMILAttr> SMILCompositor::CreateSMILAttr(
     ComputedStyle* aBaseComputedStyle) {
   nsCSSPropertyID propID = GetCSSPropertyToAnimate();
 
   if (propID != eCSSProperty_UNKNOWN) {
     return MakeUnique<SMILCSSProperty>(propID, mKey.mElement.get(),
                                        aBaseComputedStyle);
   }
 
--- a/dom/smil/SMILCompositor.h
+++ b/dom/smil/SMILCompositor.h
@@ -1,16 +1,16 @@
 /* -*- 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 NS_SMILCOMPOSITOR_H_
-#define NS_SMILCOMPOSITOR_H_
+#ifndef mozilla_SMILCompositor_h
+#define mozilla_SMILCompositor_h
 
 #include "mozilla/Move.h"
 #include "mozilla/UniquePtr.h"
 #include "mozilla/SMILAnimationFunction.h"
 #include "mozilla/SMILCompositorTable.h"
 #include "nsTHashtable.h"
 #include "nsString.h"
 #include "SMILTargetIdentifier.h"
@@ -67,21 +67,21 @@ class SMILCompositor : public PLDHashEnt
   void ToggleForceCompositing() { mForceCompositing = true; }
 
   // Transfers |aOther|'s mCachedBaseValue to |this|
   void StealCachedBaseValue(SMILCompositor* aOther) {
     mCachedBaseValue = std::move(aOther->mCachedBaseValue);
   }
 
  private:
-  // Create a nsISMILAttr for my target, on the heap.
+  // Create a SMILAttr for my target, on the heap.
   //
   // @param aBaseComputedStyle  An optional ComputedStyle which, if set, will be
   //                           used when fetching the base style.
-  UniquePtr<nsISMILAttr> CreateSMILAttr(ComputedStyle* aBaseComputedStyle);
+  UniquePtr<SMILAttr> CreateSMILAttr(ComputedStyle* aBaseComputedStyle);
 
   // Returns the CSS property this compositor should animate, or
   // eCSSProperty_UNKNOWN if this compositor does not animate a CSS property.
   nsCSSPropertyID GetCSSPropertyToAnimate() const;
 
   // Returns true if we might need to refer to base styles (i.e. we are
   // targeting a CSS property and have one or more animation functions that
   // don't just replace the underlying value).
@@ -117,9 +117,9 @@ class SMILCompositor : public PLDHashEnt
   // from one sample to the next. (SMILAnimationController moves this
   // forward from the previous sample's compositor by calling
   // StealCachedBaseValue.)
   SMILValue mCachedBaseValue;
 };
 
 }  // namespace mozilla
 
-#endif  // NS_SMILCOMPOSITOR_H_
+#endif  // mozilla_SMILCompositor_h
--- a/dom/smil/SMILCompositorTable.h
+++ b/dom/smil/SMILCompositorTable.h
@@ -1,16 +1,16 @@
 /* -*- 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 NS_SMILCOMPOSITORTABLE_H_
-#define NS_SMILCOMPOSITORTABLE_H_
+#ifndef mozilla_SMILCompositorTable_h
+#define mozilla_SMILCompositorTable_h
 
 #include "nsTHashtable.h"
 
 //----------------------------------------------------------------------
 // SMILCompositorTable : A hashmap of SMILCompositors
 //
 // This is just a forward-declaration because it is included in
 // SMILAnimationController which is used in Document. We don't want to
@@ -20,9 +20,9 @@
 namespace mozilla {
 
 class SMILCompositor;
 
 typedef nsTHashtable<SMILCompositor> SMILCompositorTable;
 
 }  // namespace mozilla
 
-#endif  // NS_SMILCOMPOSITORTABLE_H_
+#endif  // mozilla_SMILCompositorTable_h
--- a/dom/smil/SMILEnumType.h
+++ b/dom/smil/SMILEnumType.h
@@ -1,16 +1,16 @@
 /* -*- 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_SMILENUMTYPE_H_
-#define MOZILLA_SMILENUMTYPE_H_
+#ifndef mozilla_SMILEnumType_h
+#define mozilla_SMILEnumType_h
 
 #include "mozilla/Attributes.h"
 #include "mozilla/SMILType.h"
 
 namespace mozilla {
 
 class SMILEnumType : public SMILType {
  public:
@@ -39,9 +39,9 @@ class SMILEnumType : public SMILType {
 
  private:
   // Private constructor: prevent instances beyond my singleton.
   constexpr SMILEnumType() {}
 };
 
 }  // namespace mozilla
 
-#endif  // MOZILLA_SMILENUMTYPE_H_
+#endif  // mozilla_SMILEnumType_h
--- a/dom/smil/SMILFloatType.h
+++ b/dom/smil/SMILFloatType.h
@@ -1,16 +1,16 @@
 /* -*- 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 NS_SMILFLOATTYPE_H_
-#define NS_SMILFLOATTYPE_H_
+#ifndef mozilla_SMILFloatType_h
+#define mozilla_SMILFloatType_h
 
 #include "mozilla/Attributes.h"
 #include "mozilla/SMILType.h"
 
 namespace mozilla {
 
 class SMILFloatType : public SMILType {
  public:
@@ -39,9 +39,9 @@ class SMILFloatType : public SMILType {
 
  private:
   // Private constructor: prevent instances beyond my singleton.
   constexpr SMILFloatType() {}
 };
 
 }  // namespace mozilla
 
-#endif  // NS_SMILFLOATTYPE_H_
+#endif  // mozilla_SMILFloatType_h
--- a/dom/smil/SMILInstanceTime.h
+++ b/dom/smil/SMILInstanceTime.h
@@ -1,16 +1,16 @@
 /* -*- 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 NS_SMILINSTANCETIME_H_
-#define NS_SMILINSTANCETIME_H_
+#ifndef mozilla_SMILInstanceTime_h
+#define mozilla_SMILInstanceTime_h
 
 #include "nsISupportsImpl.h"
 #include "mozilla/SMILTimeValue.h"
 
 namespace mozilla {
 class SMILInterval;
 class SMILTimeContainer;
 class SMILTimeValueSpec;
@@ -158,9 +158,9 @@ class SMILInstanceTime final {
                                 // us. (currently only needed for syncbase
                                 // instance times.)
   SMILInterval* mBaseInterval;  // Interval from which this time is derived
                                 // (only used for syncbase instance times)
 };
 
 }  // namespace mozilla
 
-#endif  // NS_SMILINSTANCETIME_H_
+#endif  // mozilla_SMILInstanceTime_h
--- a/dom/smil/SMILIntegerType.h
+++ b/dom/smil/SMILIntegerType.h
@@ -1,16 +1,16 @@
 /* -*- 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_SMILINTEGERTYPE_H_
-#define MOZILLA_SMILINTEGERTYPE_H_
+#ifndef mozilla_SMILIntegerType_h
+#define mozilla_SMILIntegerType_h
 
 #include "mozilla/Attributes.h"
 #include "mozilla/SMILType.h"
 
 namespace mozilla {
 
 class SMILIntegerType : public SMILType {
  public:
@@ -34,9 +34,9 @@ class SMILIntegerType : public SMILType 
   }
 
  private:
   constexpr SMILIntegerType() {}
 };
 
 }  // namespace mozilla
 
-#endif  // MOZILLA_SMILINTEGERTYPE_H_
+#endif  // mozilla_SMILIntegerType_h
--- a/dom/smil/SMILInterval.cpp
+++ b/dom/smil/SMILInterval.cpp
@@ -1,16 +1,18 @@
 /* -*- 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 "SMILInterval.h"
 
+#include "mozilla/DebugOnly.h"
+
 namespace mozilla {
 
 SMILInterval::SMILInterval() : mBeginFixed(false), mEndFixed(false) {}
 
 SMILInterval::SMILInterval(const SMILInterval& aOther)
     : mBegin(aOther.mBegin),
       mEnd(aOther.mEnd),
       mBeginFixed(false),
@@ -106,20 +108,17 @@ void SMILInterval::AddDependentTime(SMIL
   RefPtr<SMILInstanceTime>* inserted =
       mDependentTimes.InsertElementSorted(&aTime);
   if (!inserted) {
     NS_WARNING("Insufficient memory to insert instance time.");
   }
 }
 
 void SMILInterval::RemoveDependentTime(const SMILInstanceTime& aTime) {
-#ifdef DEBUG
-  bool found =
-#endif
-      mDependentTimes.RemoveElementSorted(&aTime);
+  DebugOnly<bool> found = mDependentTimes.RemoveElementSorted(&aTime);
   MOZ_ASSERT(found, "Couldn't find instance time to delete.");
 }
 
 void SMILInterval::GetDependentTimes(InstanceTimeList& aTimes) {
   aTimes = mDependentTimes;
 }
 
 bool SMILInterval::IsDependencyChainLink() const {
--- a/dom/smil/SMILInterval.h
+++ b/dom/smil/SMILInterval.h
@@ -1,16 +1,16 @@
 /* -*- 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 NS_SMILINTERVAL_H_
-#define NS_SMILINTERVAL_H_
+#ifndef mozilla_SMILInterval_h
+#define mozilla_SMILInterval_h
 
 #include "mozilla/SMILInstanceTime.h"
 #include "nsTArray.h"
 
 namespace mozilla {
 
 //----------------------------------------------------------------------
 // SMILInterval class
@@ -78,9 +78,9 @@ class SMILInterval {
   // However, if mBegin/EndFixed is true, then BOTH the SMILInstanceTime
   // OBJECT returned for that end point and its TIME value will not change.
   bool mBeginFixed;
   bool mEndFixed;
 };
 
 }  // namespace mozilla
 
-#endif  // NS_SMILINTERVAL_H_
+#endif  // mozilla_SMILInterval_h
--- a/dom/smil/SMILKeySpline.h
+++ b/dom/smil/SMILKeySpline.h
@@ -1,16 +1,16 @@
 /* -*- 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 NS_SMILKEYSPLINE_H_
-#define NS_SMILKEYSPLINE_H_
+#ifndef mozilla_SMILKeySpline_h
+#define mozilla_SMILKeySpline_h
 
 #include "mozilla/ArrayUtils.h"
 #include "mozilla/PodOperations.h"
 
 namespace mozilla {
 
 /**
  * Utility class to provide scaling defined in a keySplines element.
@@ -99,9 +99,9 @@ class SMILKeySpline {
     enum { kSplineTableSize = 11 };
     double mSampleValues[kSplineTableSize];
 
     static const double kSampleStepSize;
 };
 
 }  // namespace mozilla
 
-#endif  // NS_SMILKEYSPLINE_H_
+#endif  // mozilla_SMILKeySpline_h
--- a/dom/smil/SMILMilestone.h
+++ b/dom/smil/SMILMilestone.h
@@ -1,16 +1,16 @@
 /* -*- 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 NS_SMILMILESTONE_H_
-#define NS_SMILMILESTONE_H_
+#ifndef mozilla_SMILMilestone_h
+#define mozilla_SMILMilestone_h
 
 #include "mozilla/SMILTypes.h"
 
 namespace mozilla {
 
 /*
  * A significant moment in an SMILTimedElement's lifetime where a sample is
  * required.
@@ -33,17 +33,17 @@ namespace mozilla {
  * a regular sample is used within the timing model (specifically in
  * SMILTimedElement) to ensure that all intervals ending at time t are sampled
  * before any new intervals are entered so that we have a fully up-to-date set
  * of instance times available before committing to a new interval. Once an
  * interval is entered, the begin time is fixed.
  */
 class SMILMilestone {
  public:
-  SMILMilestone(nsSMILTime aTime, bool aIsEnd) : mTime(aTime), mIsEnd(aIsEnd) {}
+  SMILMilestone(SMILTime aTime, bool aIsEnd) : mTime(aTime), mIsEnd(aIsEnd) {}
 
   SMILMilestone() : mTime(0), mIsEnd(false) {}
 
   bool operator==(const SMILMilestone& aOther) const {
     return mTime == aOther.mTime && mIsEnd == aOther.mIsEnd;
   }
 
   bool operator!=(const SMILMilestone& aOther) const {
@@ -59,17 +59,17 @@ class SMILMilestone {
   bool operator<=(const SMILMilestone& aOther) const {
     return *this == aOther || *this < aOther;
   }
 
   bool operator>=(const SMILMilestone& aOther) const {
     return !(*this < aOther);
   }
 
-  nsSMILTime mTime;  // The milestone time. This may be in container time or
+  SMILTime mTime;    // The milestone time. This may be in container time or
                      // parent container time depending on where it is used.
   bool mIsEnd;       // true if this milestone corresponds to an interval
                      // end, false otherwise.
 };
 
 }  // namespace mozilla
 
-#endif  // NS_SMILMILESTONE_H_
+#endif  // mozilla_SMILMilestone_h
--- a/dom/smil/SMILNullType.h
+++ b/dom/smil/SMILNullType.h
@@ -1,16 +1,16 @@
 /* -*- 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 NS_SMILNULLTYPE_H_
-#define NS_SMILNULLTYPE_H_
+#ifndef mozilla_SMILNullType_h
+#define mozilla_SMILNullType_h
 
 #include "mozilla/Attributes.h"
 #include "mozilla/SMILType.h"
 
 namespace mozilla {
 
 class SMILNullType : public SMILType {
  public:
@@ -39,9 +39,9 @@ class SMILNullType : public SMILType {
 
  private:
   // Private constructor: prevent instances beyond my singleton.
   constexpr SMILNullType() {}
 };
 
 }  // namespace mozilla
 
-#endif  // NS_SMILNULLTYPE_H_
+#endif  // mozilla_SMILNullType_h
--- a/dom/smil/SMILParserUtils.cpp
+++ b/dom/smil/SMILParserUtils.cpp
@@ -1,25 +1,25 @@
 /* -*- 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 "SMILParserUtils.h"
 
+#include "mozilla/SMILAttr.h"
 #include "mozilla/SMILKeySpline.h"
 #include "mozilla/SMILRepeatCount.h"
 #include "mozilla/SMILTimeValue.h"
 #include "mozilla/SMILTimeValueSpecParams.h"
 #include "mozilla/SMILTypes.h"
 #include "mozilla/SMILValue.h"
 #include "mozilla/SVGContentUtils.h"
 #include "mozilla/TextUtils.h"
-#include "nsISMILAttr.h"
 #include "nsContentUtils.h"
 #include "nsCharSeparatedTokenizer.h"
 
 using namespace mozilla::dom;
 //------------------------------------------------------------------------------
 // Helper functions and Constants
 
 namespace {
@@ -181,33 +181,33 @@ bool ParseClockValue(RangedPtr<const cha
           !ParseColon(iter, aEnd) ||
           !ParseSecondsOrMinutes(iter, aEnd, seconds)) {
         return false;
       }
       if (iter != aEnd && (*iter != '.' || !SVGContentUtils::ParseNumber(
                                                iter, aEnd, fraction))) {
         return false;
       }
-      aResult->SetMillis(nsSMILTime(hours) * MSEC_PER_HOUR +
+      aResult->SetMillis(SMILTime(hours) * MSEC_PER_HOUR +
                          minutes * MSEC_PER_MIN + seconds * MSEC_PER_SEC +
                          NS_round(fraction * MSEC_PER_SEC));
       aIter = iter;
       return true;
     case TIMECOUNT_VALUE:
       if (!SVGContentUtils::ParseInteger(iter, aEnd, timecount)) {
         return false;
       }
       if (iter != aEnd && *iter == '.' &&
           !SVGContentUtils::ParseNumber(iter, aEnd, fraction)) {
         return false;
       }
       if (!ParseClockMetric(iter, aEnd, multiplier)) {
         return false;
       }
-      aResult->SetMillis(nsSMILTime(timecount) * multiplier +
+      aResult->SetMillis(SMILTime(timecount) * multiplier +
                          NS_round(fraction * multiplier));
       aIter = iter;
       return true;
   }
 
   return false;
 }
 
@@ -486,17 +486,17 @@ bool SMILParserUtils::ParseSemicolonDeli
   return !aArray.IsEmpty();
 }
 
 // Helper class for ParseValues
 class MOZ_STACK_CLASS SMILValueParser
     : public SMILParserUtils::GenericValueParser {
  public:
   SMILValueParser(const SVGAnimationElement* aSrcElement,
-                  const nsISMILAttr* aSMILAttr,
+                  const SMILAttr* aSMILAttr,
                   FallibleTArray<SMILValue>* aValuesArray,
                   bool* aPreventCachingOfSandwich)
       : mSrcElement(aSrcElement),
         mSMILAttr(aSMILAttr),
         mValuesArray(aValuesArray),
         mPreventCachingOfSandwich(aPreventCachingOfSandwich) {}
 
   virtual bool Parse(const nsAString& aValueStr) override {
@@ -512,24 +512,24 @@ class MOZ_STACK_CLASS SMILValueParser
     if (tmpPreventCachingOfSandwich) {
       *mPreventCachingOfSandwich = true;
     }
     return true;
   }
 
  protected:
   const SVGAnimationElement* mSrcElement;
-  const nsISMILAttr* mSMILAttr;
+  const SMILAttr* mSMILAttr;
   FallibleTArray<SMILValue>* mValuesArray;
   bool* mPreventCachingOfSandwich;
 };
 
 bool SMILParserUtils::ParseValues(const nsAString& aSpec,
                                   const SVGAnimationElement* aSrcElement,
-                                  const nsISMILAttr& aAttribute,
+                                  const SMILAttr& aAttribute,
                                   FallibleTArray<SMILValue>& aValuesArray,
                                   bool& aPreventCachingOfSandwich) {
   // Assume all results can be cached, until we find one that can't.
   aPreventCachingOfSandwich = false;
   SMILValueParser valueParser(aSrcElement, &aAttribute, &aValuesArray,
                               &aPreventCachingOfSandwich);
   return ParseValuesGeneric(aSpec, valueParser);
 }
--- a/dom/smil/SMILParserUtils.h
+++ b/dom/smil/SMILParserUtils.h
@@ -1,24 +1,23 @@
 /* -*- 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 NS_SMILPARSERUTILS_H_
-#define NS_SMILPARSERUTILS_H_
+#ifndef mozilla_SMILParserUtils_h
+#define mozilla_SMILParserUtils_h
 
 #include "nsTArray.h"
 #include "nsStringFwd.h"
 
-class nsISMILAttr;
-
 namespace mozilla {
 
+class SMILAttr;
 class SMILKeySpline;
 class SMILRepeatCount;
 class SMILTimeValue;
 class SMILTimeValueSpecParams;
 class SMILValue;
 
 namespace dom {
 class SVGAnimationElement;
@@ -44,17 +43,17 @@ class SMILParserUtils {
 
   // Used for parsing the |keyTimes| and |keyPoints| attributes.
   static bool ParseSemicolonDelimitedProgressList(
       const nsAString& aSpec, bool aNonDecreasing,
       FallibleTArray<double>& aArray);
 
   static bool ParseValues(const nsAString& aSpec,
                           const mozilla::dom::SVGAnimationElement* aSrcElement,
-                          const nsISMILAttr& aAttribute,
+                          const SMILAttr& aAttribute,
                           FallibleTArray<SMILValue>& aValuesArray,
                           bool& aPreventCachingOfSandwich);
 
   // Generic method that will run some code on each sub-section of an animation
   // element's "values" list.
   static bool ParseValuesGeneric(const nsAString& aSpec,
                                  GenericValueParser& aParser);
 
@@ -82,9 +81,9 @@ class SMILParserUtils {
    * method returns the index of the first character after the '-' sign
    * (i.e. the index of the absolute value).  If not, this method returns -1.
    */
   static int32_t CheckForNegativeNumber(const nsAString& aStr);
 };
 
 }  // namespace mozilla
 
-#endif  // NS_SMILPARSERUTILS_H_
+#endif  // mozilla_SMILParserUtils_h
--- a/dom/smil/SMILRepeatCount.h
+++ b/dom/smil/SMILRepeatCount.h
@@ -1,16 +1,16 @@
 /* -*- 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 SMILRepeatCount_h
-#define SMILRepeatCount_h
+#ifndef mozilla_SMILRepeatCount_h
+#define mozilla_SMILRepeatCount_h
 
 #include "nsDebug.h"
 #include <math.h>
 
 namespace mozilla {
 
 //----------------------------------------------------------------------
 // SMILRepeatCount
@@ -54,9 +54,9 @@ class SMILRepeatCount {
   static const double kNotSet;
   static const double kIndefinite;
 
   double mCount;
 };
 
 }  // namespace mozilla
 
-#endif
+#endif  // mozilla_SMILRepeatCount_h
--- a/dom/smil/SMILSetAnimationFunction.h
+++ b/dom/smil/SMILSetAnimationFunction.h
@@ -1,16 +1,16 @@
 /* -*- 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 NS_SMILSETANIMATIONFUNCTION_H_
-#define NS_SMILSETANIMATIONFUNCTION_H_
+#ifndef mozilla_SMILSetAnimationFunction_h
+#define mozilla_SMILSetAnimationFunction_h
 
 #include "mozilla/Attributes.h"
 #include "mozilla/SMILAnimationFunction.h"
 
 namespace mozilla {
 
 //----------------------------------------------------------------------
 // SMILSetAnimationFunction
@@ -59,9 +59,9 @@ class SMILSetAnimationFunction : public 
   virtual bool GetAttr(nsAtom* aAttName, nsAString& aResult) const override;
   virtual bool WillReplace() const override;
 
   bool IsDisallowedAttribute(const nsAtom* aAttribute) const;
 };
 
 }  // namespace mozilla
 
-#endif  // NS_SMILSETANIMATIONFUNCTION_H_
+#endif  // mozilla_SMILSetAnimationFunction_h
--- a/dom/smil/SMILStringType.h
+++ b/dom/smil/SMILStringType.h
@@ -1,16 +1,16 @@
 /* -*- 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_SMILSTRINGTYPE_H_
-#define MOZILLA_SMILSTRINGTYPE_H_
+#ifndef mozilla_SMILStringType_h
+#define mozilla_SMILStringType_h
 
 #include "mozilla/Attributes.h"
 #include "mozilla/SMILType.h"
 
 namespace mozilla {
 
 class SMILStringType : public SMILType {
  public:
@@ -39,9 +39,9 @@ class SMILStringType : public SMILType {
 
  private:
   // Private constructor: prevent instances beyond my singleton.
   constexpr SMILStringType() {}
 };
 
 }  // namespace mozilla
 
-#endif  // MOZILLA_SMILSTRINGTYPE_H_
+#endif  // mozilla_SMILStringType_h
--- a/dom/smil/SMILTargetIdentifier.h
+++ b/dom/smil/SMILTargetIdentifier.h
@@ -1,16 +1,16 @@
 /* -*- 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 NS_SMILTARGETIDENTIFIER_H_
-#define NS_SMILTARGETIDENTIFIER_H_
+#ifndef mozilla_SMILTargetIdentifier_h
+#define mozilla_SMILTargetIdentifier_h
 
 #include "mozilla/dom/Element.h"
 
 namespace mozilla {
 
 /**
  * Struct: SMILTargetIdentifier
  *
@@ -37,32 +37,32 @@ struct SMILTargetIdentifier {
   }
 
   RefPtr<mozilla::dom::Element> mElement;
   RefPtr<nsAtom> mAttributeName;
   int32_t mAttributeNamespaceID;
 };
 
 /**
- * Class: nsSMILWeakTargetIdentifier
+ * Class: SMILWeakTargetIdentifier
  *
  * Version of the above struct that uses non-owning pointers.  These are kept
  * private, to ensure that they aren't ever dereferenced (or used at all,
  * outside of Equals()).
  *
  * This is solely for comparisons to determine if a target has changed
  * from one sample to the next.
  */
-class nsSMILWeakTargetIdentifier {
+class SMILWeakTargetIdentifier {
  public:
   // Trivial constructor
-  nsSMILWeakTargetIdentifier() : mElement(nullptr), mAttributeName(nullptr) {}
+  SMILWeakTargetIdentifier() : mElement(nullptr), mAttributeName(nullptr) {}
 
   // Allow us to update a weak identifier to match a given non-weak identifier
-  nsSMILWeakTargetIdentifier& operator=(const SMILTargetIdentifier& aOther) {
+  SMILWeakTargetIdentifier& operator=(const SMILTargetIdentifier& aOther) {
     mElement = aOther.mElement;
     mAttributeName = aOther.mAttributeName;
     return *this;
   }
 
   // Allow for comparison vs. non-weak identifier
   inline bool Equals(const SMILTargetIdentifier& aOther) const {
     return (aOther.mElement == mElement &&
@@ -71,9 +71,9 @@ class nsSMILWeakTargetIdentifier {
 
  private:
   const nsIContent* mElement;
   const nsAtom* mAttributeName;
 };
 
 }  // namespace mozilla
 
-#endif  // NS_SMILTARGETIDENTIFIER_H_
+#endif  // mozilla_SMILTargetIdentifier_h
--- a/dom/smil/SMILTimeContainer.cpp
+++ b/dom/smil/SMILTimeContainer.cpp
@@ -29,26 +29,26 @@ SMILTimeContainer::SMILTimeContainer()
 
 SMILTimeContainer::~SMILTimeContainer() {
   if (mParent) {
     mParent->RemoveChild(*this);
   }
 }
 
 SMILTimeValue SMILTimeContainer::ContainerToParentTime(
-    nsSMILTime aContainerTime) const {
+    SMILTime aContainerTime) const {
   // If we're paused, then future times are indefinite
   if (IsPaused() && aContainerTime > mCurrentTime)
     return SMILTimeValue::Indefinite();
 
   return SMILTimeValue(aContainerTime + mParentOffset);
 }
 
 SMILTimeValue SMILTimeContainer::ParentToContainerTime(
-    nsSMILTime aParentTime) const {
+    SMILTime aParentTime) const {
   // If we're paused, then any time after when we paused is indefinite
   if (IsPaused() && aParentTime > mPauseStart)
     return SMILTimeValue::Indefinite();
 
   return SMILTimeValue(aParentTime - mParentOffset);
 }
 
 void SMILTimeContainer::Begin() {
@@ -84,44 +84,44 @@ void SMILTimeContainer::Pause(uint32_t a
 }
 
 void SMILTimeContainer::Resume(uint32_t aType) {
   if (!mPauseState) return;
 
   mPauseState &= ~aType;
 
   if (!mPauseState) {
-    nsSMILTime extraOffset = GetParentTime() - mPauseStart;
+    SMILTime extraOffset = GetParentTime() - mPauseStart;
     mParentOffset += extraOffset;
     NotifyTimeChange();
   }
 }
 
-nsSMILTime SMILTimeContainer::GetCurrentTimeAsSMILTime() const {
+SMILTime SMILTimeContainer::GetCurrentTimeAsSMILTime() const {
   // The following behaviour is consistent with:
   // http://www.w3.org/2003/01/REC-SVG11-20030114-errata
   //  #getCurrentTime_setCurrentTime_undefined_before_document_timeline_begin
   // which says that if GetCurrentTime is called before the document timeline
   // has begun we should just return 0.
   if (IsPausedByType(PAUSE_BEGIN)) return 0L;
 
   return mCurrentTime;
 }
 
-void SMILTimeContainer::SetCurrentTime(nsSMILTime aSeekTo) {
+void SMILTimeContainer::SetCurrentTime(SMILTime aSeekTo) {
   // SVG 1.1 doesn't specify what to do for negative times so we adopt SVGT1.2's
   // behaviour of clamping negative times to 0.
-  aSeekTo = std::max<nsSMILTime>(0, aSeekTo);
+  aSeekTo = std::max<SMILTime>(0, aSeekTo);
 
   // The following behaviour is consistent with:
   // http://www.w3.org/2003/01/REC-SVG11-20030114-errata
   //  #getCurrentTime_setCurrentTime_undefined_before_document_timeline_begin
   // which says that if SetCurrentTime is called before the document timeline
   // has begun we should still adjust the offset.
-  nsSMILTime parentTime = GetParentTime();
+  SMILTime parentTime = GetParentTime();
   mParentOffset = parentTime - aSeekTo;
   mIsSeeking = true;
 
   if (IsPaused()) {
     mNeedsPauseSample = true;
     mPauseStart = parentTime;
   }
 
@@ -133,26 +133,26 @@ void SMILTimeContainer::SetCurrentTime(n
 
   // Force an update to the current time in case we get a call to GetCurrentTime
   // before another call to Sample().
   UpdateCurrentTime();
 
   NotifyTimeChange();
 }
 
-nsSMILTime SMILTimeContainer::GetParentTime() const {
+SMILTime SMILTimeContainer::GetParentTime() const {
   if (mParent) return mParent->GetCurrentTimeAsSMILTime();
 
   return 0L;
 }
 
 void SMILTimeContainer::SyncPauseTime() {
   if (IsPaused()) {
-    nsSMILTime parentTime = GetParentTime();
-    nsSMILTime extraOffset = parentTime - mPauseStart;
+    SMILTime parentTime = GetParentTime();
+    SMILTime extraOffset = parentTime - mPauseStart;
     mParentOffset += extraOffset;
     mPauseStart = parentTime;
   }
 }
 
 void SMILTimeContainer::Sample() {
   if (!NeedsSample()) return;
 
@@ -256,17 +256,17 @@ void SMILTimeContainer::Traverse(
 }
 
 void SMILTimeContainer::Unlink() {
   MOZ_ASSERT(!mHoldingEntries);
   mMilestoneEntries.Clear();
 }
 
 void SMILTimeContainer::UpdateCurrentTime() {
-  nsSMILTime now = IsPaused() ? mPauseStart : GetParentTime();
+  SMILTime now = IsPaused() ? mPauseStart : GetParentTime();
   mCurrentTime = now - mParentOffset;
   MOZ_ASSERT(mCurrentTime >= 0, "Container has negative time");
 }
 
 void SMILTimeContainer::NotifyTimeChange() {
   // Called when the container time is changed with respect to the document
   // time. When this happens time dependencies in other time containers need to
   // re-resolve their times because begin and end times are stored in container
--- a/dom/smil/SMILTimeContainer.h
+++ b/dom/smil/SMILTimeContainer.h
@@ -1,16 +1,16 @@
 /* -*- 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 NS_SMILTIMECONTAINER_H_
-#define NS_SMILTIMECONTAINER_H_
+#ifndef mozilla_SMILTimeContainer_h
+#define mozilla_SMILTimeContainer_h
 
 #include "mozilla/dom/SVGAnimationElement.h"
 #include "mozilla/SMILMilestone.h"
 #include "mozilla/SMILTypes.h"
 #include "nscore.h"
 #include "nsTPriorityQueue.h"
 
 namespace mozilla {
@@ -80,48 +80,48 @@ class SMILTimeContainer {
    * @return true if this container is paused, false otherwise.
    */
   bool IsPaused() const { return mPauseState != 0; }
 
   /*
    * Return the time elapsed since this time container's begin time (expressed
    * in parent time) minus any accumulated offset from pausing.
    */
-  nsSMILTime GetCurrentTimeAsSMILTime() const;
+  SMILTime GetCurrentTimeAsSMILTime() const;
 
   /*
    * Seek the document timeline to the specified time.
    *
    * @param aSeekTo The time to seek to, expressed in this time container's time
    * base (i.e. the same units as GetCurrentTime).
    */
-  void SetCurrentTime(nsSMILTime aSeekTo);
+  void SetCurrentTime(SMILTime aSeekTo);
 
   /*
    * Return the current time for the parent time container if any.
    */
-  virtual nsSMILTime GetParentTime() const;
+  virtual SMILTime GetParentTime() const;
 
   /*
    * Convert container time to parent time.
    *
    * @param   aContainerTime The container time to convert.
    * @return  The equivalent parent time or indefinite if the container is
    *          paused and the time is in the future.
    */
-  SMILTimeValue ContainerToParentTime(nsSMILTime aContainerTime) const;
+  SMILTimeValue ContainerToParentTime(SMILTime aContainerTime) const;
 
   /*
    * Convert from parent time to container time.
    *
    * @param   aParentTime The parent time to convert.
    * @return  The equivalent container time or indefinite if the container is
    *          paused and aParentTime is after the time when the pause began.
    */
-  SMILTimeValue ParentToContainerTime(nsSMILTime aParentTime) const;
+  SMILTimeValue ParentToContainerTime(SMILTime aParentTime) const;
 
   /*
    * If the container is paused, causes the pause time to be updated to the
    * current parent time. This should be called before updating
    * cross-container dependencies that will call ContainerToParentTime in order
    * to provide more intuitive results.
    */
   void SyncPauseTime();
@@ -242,28 +242,28 @@ class SMILTimeContainer {
    * container time has changed with respect to the document time.
    */
   void NotifyTimeChange();
 
   // The parent time container, if any
   SMILTimeContainer* mParent;
 
   // The current time established at the last call to Sample()
-  nsSMILTime mCurrentTime;
+  SMILTime mCurrentTime;
 
   // The number of milliseconds for which the container has been paused
   // (excluding the current pause interval if the container is currently
   // paused).
   //
   //  Current time = parent time - mParentOffset
   //
-  nsSMILTime mParentOffset;
+  SMILTime mParentOffset;
 
   // The timestamp in parent time when the container was paused
-  nsSMILTime mPauseStart;
+  SMILTime mPauseStart;
 
   // Whether or not a pause sample is required
   bool mNeedsPauseSample;
 
   bool mNeedsRewind;  // Backwards seek performed
   bool mIsSeeking;    // Currently in the middle of a seek operation
 
 #ifdef DEBUG
@@ -292,9 +292,9 @@ class SMILTimeContainer {
   // re-register their milestones when they're sampled this is reset once we've
   // taken care of the milestones before the current sample time but before we
   // actually do the full sample.
   nsTPriorityQueue<MilestoneEntry> mMilestoneEntries;
 };
 
 }  // namespace mozilla
 
-#endif  // NS_SMILTIMECONTAINER_H_
+#endif  // mozilla_SMILTimeContainer_h
--- a/dom/smil/SMILTimeValue.cpp
+++ b/dom/smil/SMILTimeValue.cpp
@@ -3,18 +3,18 @@
 /* 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 "SMILTimeValue.h"
 
 namespace mozilla {
 
-const nsSMILTime SMILTimeValue::kUnresolvedMillis =
-    std::numeric_limits<nsSMILTime>::max();
+const SMILTime SMILTimeValue::kUnresolvedMillis =
+    std::numeric_limits<SMILTime>::max();
 
 //----------------------------------------------------------------------
 // SMILTimeValue methods:
 
 static inline int8_t Cmp(int64_t aA, int64_t aB) {
   return aA == aB ? 0 : (aA > aB ? 1 : -1);
 }
 
--- a/dom/smil/SMILTimeValue.h
+++ b/dom/smil/SMILTimeValue.h
@@ -1,30 +1,30 @@
 /* -*- 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 NS_SMILTIMEVALUE_H_
-#define NS_SMILTIMEVALUE_H_
+#ifndef mozilla_SMILTimeValue_h
+#define mozilla_SMILTimeValue_h
 
 #include "mozilla/SMILTypes.h"
 #include "nsDebug.h"
 
 namespace mozilla {
 
 /*----------------------------------------------------------------------
  * SMILTimeValue class
  *
  * A tri-state time value.
  *
  * First a quick overview of the SMIL time data types:
  *
- * nsSMILTime        -- a timestamp in milliseconds.
+ * SMILTime          -- a timestamp in milliseconds.
  * SMILTimeValue     -- (this class) a timestamp that can take the additional
  *                      states 'indefinite' and 'unresolved'
  * SMILInstanceTime  -- an SMILTimeValue used for constructing intervals. It
  *                      contains additional fields to govern reset behavior
  *                      and track timing dependencies (e.g. syncbase timing).
  * SMILInterval      -- a pair of SMILInstanceTimes that defines a begin and
  *                      an end time for animation.
  * SMILTimeValueSpec -- a component of a begin or end attribute, such as the
@@ -53,17 +53,17 @@ namespace mozilla {
 
 class SMILTimeValue {
  public:
   // Creates an unresolved time value
   SMILTimeValue()
       : mMilliseconds(kUnresolvedMillis), mState(STATE_UNRESOLVED) {}
 
   // Creates a resolved time value
-  explicit SMILTimeValue(nsSMILTime aMillis)
+  explicit SMILTimeValue(SMILTime aMillis)
       : mMilliseconds(aMillis), mState(STATE_DEFINITE) {}
 
   // Named constructor to create an indefinite time value
   static SMILTimeValue Indefinite() {
     SMILTimeValue value;
     value.SetIndefinite();
     return value;
   }
@@ -76,24 +76,24 @@ class SMILTimeValue {
 
   bool IsResolved() const { return mState != STATE_UNRESOLVED; }
   void SetUnresolved() {
     mState = STATE_UNRESOLVED;
     mMilliseconds = kUnresolvedMillis;
   }
 
   bool IsDefinite() const { return mState == STATE_DEFINITE; }
-  nsSMILTime GetMillis() const {
+  SMILTime GetMillis() const {
     MOZ_ASSERT(mState == STATE_DEFINITE,
                "GetMillis() called for unresolved or indefinite time");
 
     return mState == STATE_DEFINITE ? mMilliseconds : kUnresolvedMillis;
   }
 
-  void SetMillis(nsSMILTime aMillis) {
+  void SetMillis(SMILTime aMillis) {
     mState = STATE_DEFINITE;
     mMilliseconds = aMillis;
   }
 
   int8_t CompareTo(const SMILTimeValue& aOther) const;
 
   bool operator==(const SMILTimeValue& aOther) const {
     return CompareTo(aOther) == 0;
@@ -115,17 +115,17 @@ class SMILTimeValue {
     return CompareTo(aOther) <= 0;
   }
 
   bool operator>=(const SMILTimeValue& aOther) const {
     return CompareTo(aOther) >= 0;
   }
 
  private:
-  static const nsSMILTime kUnresolvedMillis;
+  static const SMILTime kUnresolvedMillis;
 
-  nsSMILTime mMilliseconds;
+  SMILTime mMilliseconds;
   enum { STATE_DEFINITE, STATE_INDEFINITE, STATE_UNRESOLVED } mState;
 };
 
 }  // namespace mozilla
 
-#endif  // NS_SMILTIMEVALUE_H_
+#endif  // mozilla_SMILTimeValue_h
--- a/dom/smil/SMILTimeValueSpec.cpp
+++ b/dom/smil/SMILTimeValueSpec.cpp
@@ -111,17 +111,17 @@ void SMILTimeValueSpec::HandleNewInterva
     SMILInterval& aInterval, const SMILTimeContainer* aSrcContainer) {
   const SMILInstanceTime& baseInstance =
       mParams.mSyncBegin ? *aInterval.Begin() : *aInterval.End();
   SMILTimeValue newTime =
       ConvertBetweenTimeContainers(baseInstance.Time(), aSrcContainer);
 
   // Apply offset
   if (!ApplyOffset(newTime)) {
-    NS_WARNING("New time overflows nsSMILTime, ignoring");
+    NS_WARNING("New time overflows SMILTime, ignoring");
     return;
   }
 
   // Create the instance time and register it with the interval
   RefPtr<SMILInstanceTime> newInstance = new SMILInstanceTime(
       newTime, SMILInstanceTime::SOURCE_SYNCBASE, this, &aInterval);
   mOwner->AddInstanceTime(newInstance, mIsBegin);
 }
@@ -139,17 +139,17 @@ void SMILTimeValueSpec::HandleChangedIns
   // time of an active or postactive interval) we just ignore the change.
   if (aInstanceTimeToUpdate.IsFixedTime()) return;
 
   SMILTimeValue updatedTime =
       ConvertBetweenTimeContainers(aBaseTime.Time(), aSrcContainer);
 
   // Apply offset
   if (!ApplyOffset(updatedTime)) {
-    NS_WARNING("Updated time overflows nsSMILTime, ignoring");
+    NS_WARNING("Updated time overflows SMILTime, ignoring");
     return;
   }
 
   // The timed element that owns the instance time does the updating so it can
   // re-sort its array of instance times more efficiently
   if (aInstanceTimeToUpdate.Time() != updatedTime || aObjectChanged) {
     mOwner->UpdateInstanceTime(&aInstanceTimeToUpdate, updatedTime, mIsBegin);
   }
@@ -295,20 +295,20 @@ void SMILTimeValueSpec::HandleEvent(Even
   SMILTimeContainer* container = mOwner->GetTimeContainer();
   if (!container) return;
 
   if (mParams.mType == SMILTimeValueSpecParams::REPEAT &&
       !CheckRepeatEventDetail(aEvent)) {
     return;
   }
 
-  nsSMILTime currentTime = container->GetCurrentTimeAsSMILTime();
+  SMILTime currentTime = container->GetCurrentTimeAsSMILTime();
   SMILTimeValue newTime(currentTime);
   if (!ApplyOffset(newTime)) {
-    NS_WARNING("New time generated from event overflows nsSMILTime, ignoring");
+    NS_WARNING("New time generated from event overflows SMILTime, ignoring");
     return;
   }
 
   RefPtr<SMILInstanceTime> newInstance =
       new SMILInstanceTime(newTime, SMILInstanceTime::SOURCE_EVENT);
   mOwner->AddInstanceTime(newInstance, mIsBegin);
 }
 
@@ -354,17 +354,17 @@ SMILTimeValue SMILTimeValueSpec::Convert
 bool SMILTimeValueSpec::ApplyOffset(SMILTimeValue& aTime) const {
   // indefinite + offset = indefinite. Likewise for unresolved times.
   if (!aTime.IsDefinite()) {
     return true;
   }
 
   double resultAsDouble =
       (double)aTime.GetMillis() + mParams.mOffset.GetMillis();
-  if (resultAsDouble > std::numeric_limits<nsSMILTime>::max() ||
-      resultAsDouble < std::numeric_limits<nsSMILTime>::min()) {
+  if (resultAsDouble > std::numeric_limits<SMILTime>::max() ||
+      resultAsDouble < std::numeric_limits<SMILTime>::min()) {
     return false;
   }
   aTime.SetMillis(aTime.GetMillis() + mParams.mOffset.GetMillis());
   return true;
 }
 
 }  // namespace mozilla
--- a/dom/smil/SMILTimeValueSpec.h
+++ b/dom/smil/SMILTimeValueSpec.h
@@ -1,16 +1,16 @@
 /* -*- 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 NS_SMILTIMEVALUESPEC_H_
-#define NS_SMILTIMEVALUESPEC_H_
+#ifndef mozilla_SMILTimeValueSpec_h
+#define mozilla_SMILTimeValueSpec_h
 
 #include "mozilla/Attributes.h"
 #include "mozilla/SMILTimeValueSpecParams.h"
 #include "mozilla/dom/IDTracker.h"
 #include "nsStringFwd.h"
 #include "nsIDOMEventListener.h"
 
 namespace mozilla {
@@ -132,9 +132,9 @@ class SMILTimeValueSpec {
    private:
     SMILTimeValueSpec* mSpec;
   };
   RefPtr<EventListener> mEventListener;
 };
 
 }  // namespace mozilla
 
-#endif  // NS_SMILTIMEVALUESPEC_H_
+#endif  // mozilla_SMILTimeValueSpec_h
--- a/dom/smil/SMILTimeValueSpecParams.h
+++ b/dom/smil/SMILTimeValueSpecParams.h
@@ -1,16 +1,16 @@
 /* -*- 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 NS_SMILTIMEVALUESPECPARAMS_H_
-#define NS_SMILTIMEVALUESPECPARAMS_H_
+#ifndef mozilla_SMILTimeValueSpecParams_h
+#define mozilla_SMILTimeValueSpecParams_h
 
 #include "mozilla/SMILTimeValue.h"
 #include "nsAtom.h"
 
 namespace mozilla {
 
 //----------------------------------------------------------------------
 // SMILTimeValueSpecParams
@@ -50,9 +50,9 @@ class SMILTimeValueSpecParams {
 
   // The repeat iteration to respond to.
   // Only used for mType=REPEAT.
   uint32_t mRepeatIteration;
 };
 
 }  // namespace mozilla
 
-#endif  // NS_SMILTIMEVALUESPECPARAMS_H_
+#endif  // mozilla_SMILTimeValueSpecParams_h
--- a/dom/smil/SMILTimedElement.cpp
+++ b/dom/smil/SMILTimedElement.cpp
@@ -194,17 +194,17 @@ const nsAttrValue::EnumTable SMILTimedEl
 
 const nsAttrValue::EnumTable SMILTimedElement::sRestartModeTable[] = {
     {"always", RESTART_ALWAYS},
     {"whenNotActive", RESTART_WHENNOTACTIVE},
     {"never", RESTART_NEVER},
     {nullptr, 0}};
 
 const SMILMilestone SMILTimedElement::sMaxMilestone(
-    std::numeric_limits<nsSMILTime>::max(), false);
+    std::numeric_limits<SMILTime>::max(), false);
 
 // The thresholds at which point we start filtering intervals and instance times
 // indiscriminately.
 // See FilterIntervals and FilterInstanceTimes.
 const uint8_t SMILTimedElement::sMaxNumIntervals = 20;
 const uint8_t SMILTimedElement::sMaxNumInstanceTimes = 100;
 
 // Detect if we arrive in some sort of undetected recursive syncbase dependency
@@ -293,25 +293,25 @@ dom::Element* SMILTimedElement::GetTarge
 //
 // which favours the definition in SMIL, i.e. instance times are just added
 // without first checking the restart mode.
 
 nsresult SMILTimedElement::BeginElementAt(double aOffsetSeconds) {
   SMILTimeContainer* container = GetTimeContainer();
   if (!container) return NS_ERROR_FAILURE;
 
-  nsSMILTime currentTime = container->GetCurrentTimeAsSMILTime();
+  SMILTime currentTime = container->GetCurrentTimeAsSMILTime();
   return AddInstanceTimeFromCurrentTime(currentTime, aOffsetSeconds, true);
 }
 
 nsresult SMILTimedElement::EndElementAt(double aOffsetSeconds) {
   SMILTimeContainer* container = GetTimeContainer();
   if (!container) return NS_ERROR_FAILURE;
 
-  nsSMILTime currentTime = container->GetCurrentTimeAsSMILTime();
+  SMILTime currentTime = container->GetCurrentTimeAsSMILTime();
   return AddInstanceTimeFromCurrentTime(currentTime, aOffsetSeconds, false);
 }
 
 //----------------------------------------------------------------------
 // nsSVGAnimationElement methods
 
 SMILTimeValue SMILTimedElement::GetStartTime() const {
   return mElementState == STATE_WAITING || mElementState == STATE_ACTIVE
@@ -454,26 +454,26 @@ void SMILTimedElement::SetTimeClient(SMI
   //
   // No need to check for nullptr. A nullptr parameter simply means to remove
   // the previous client which we do by setting to nullptr anyway.
   //
 
   mClient = aClient;
 }
 
-void SMILTimedElement::SampleAt(nsSMILTime aContainerTime) {
+void SMILTimedElement::SampleAt(SMILTime aContainerTime) {
   if (mIsDisabled) return;
 
   // Milestones are cleared before a sample
   mPrevRegisteredMilestone = sMaxMilestone;
 
   DoSampleAt(aContainerTime, false);
 }
 
-void SMILTimedElement::SampleEndAt(nsSMILTime aContainerTime) {
+void SMILTimedElement::SampleEndAt(SMILTime aContainerTime) {
   if (mIsDisabled) return;
 
   // Milestones are cleared before a sample
   mPrevRegisteredMilestone = sMaxMilestone;
 
   // If the current interval changes, we don't bother trying to remove any old
   // milestones we'd registered. So it's possible to get a call here to end an
   // interval at a time that no longer reflects the end of the current interval.
@@ -487,17 +487,17 @@ void SMILTimedElement::SampleEndAt(nsSMI
     DoSampleAt(aContainerTime, true);  // End sample
   } else {
     // Even if this was an unnecessary milestone sample we want to be sure that
     // our next real milestone is registered.
     RegisterMilestone();
   }
 }
 
-void SMILTimedElement::DoSampleAt(nsSMILTime aContainerTime, bool aEndOnly) {
+void SMILTimedElement::DoSampleAt(SMILTime aContainerTime, bool aEndOnly) {
   MOZ_ASSERT(mAnimationElement,
              "Got sample before being registered with an animation element");
   MOZ_ASSERT(GetTimeContainer(),
              "Got sample without being registered with a time container");
 
   // This could probably happen if we later implement externalResourcesRequired
   // (bug 277955) and whilst waiting for those resources (and the animation to
   // start) we transfer a node from another document fragment that has already
@@ -617,18 +617,18 @@ void SMILTimedElement::DoSampleAt(nsSMIL
           }
           if (mElementState == STATE_WAITING) {
             NotifyNewInterval();
           }
           FilterHistory();
           stateChanged = true;
         } else if (mCurrentInterval->Begin()->Time() <= sampleTime) {
           MOZ_ASSERT(!didApplyEarlyEnd, "We got an early end, but didn't end");
-          nsSMILTime beginTime = mCurrentInterval->Begin()->Time().GetMillis();
-          nsSMILTime activeTime = aContainerTime - beginTime;
+          SMILTime beginTime = mCurrentInterval->Begin()->Time().GetMillis();
+          SMILTime activeTime = aContainerTime - beginTime;
 
           // The 'min' attribute can cause the active interval to be longer than
           // the 'repeating interval'.
           // In that extended period we apply the fill mode.
           if (GetRepeatDuration() <= SMILTimeValue(activeTime)) {
             if (mClient && mClient->IsActive()) {
               mClient->Inactivate(mFillMode == FILL_FREEZE);
             }
@@ -931,17 +931,17 @@ void SMILTimedElement::UnsetMax() {
   mMax.SetIndefinite();
   UpdateCurrentInterval();
 }
 
 nsresult SMILTimedElement::SetRestart(const nsAString& aRestartSpec) {
   nsAttrValue temp;
   bool parseResult = temp.ParseEnumValue(aRestartSpec, sRestartModeTable, true);
   mRestartMode =
-      parseResult ? nsSMILRestartMode(temp.GetEnumValue()) : RESTART_ALWAYS;
+      parseResult ? SMILRestartMode(temp.GetEnumValue()) : RESTART_ALWAYS;
   UpdateCurrentInterval();
   return parseResult ? NS_OK : NS_ERROR_FAILURE;
 }
 
 void SMILTimedElement::UnsetRestart() {
   mRestartMode = RESTART_ALWAYS;
   UpdateCurrentInterval();
 }
@@ -992,17 +992,17 @@ void SMILTimedElement::UnsetRepeatDur() 
   UpdateCurrentInterval();
 }
 
 nsresult SMILTimedElement::SetFillMode(const nsAString& aFillModeSpec) {
   uint16_t previousFillMode = mFillMode;
 
   nsAttrValue temp;
   bool parseResult = temp.ParseEnumValue(aFillModeSpec, sFillModeTable, true);
-  mFillMode = parseResult ? nsSMILFillMode(temp.GetEnumValue()) : FILL_REMOVE;
+  mFillMode = parseResult ? SMILFillMode(temp.GetEnumValue()) : FILL_REMOVE;
 
   // Update fill mode of client
   if (mFillMode != previousFillMode && HasClientInFillRange()) {
     mClient->Inactivate(mFillMode == FILL_FREEZE);
     SampleFillValue();
   }
 
   return parseResult ? NS_OK : NS_ERROR_FAILURE;
@@ -1686,42 +1686,42 @@ SMILTimeValue SMILTimedElement::CalcActi
   MOZ_ASSERT(mSimpleDur.IsResolved(),
              "Unresolved simple duration in CalcActiveEnd");
   MOZ_ASSERT(aBegin.IsDefinite(),
              "Indefinite or unresolved begin time in CalcActiveEnd");
 
   result = GetRepeatDuration();
 
   if (aEnd.IsDefinite()) {
-    nsSMILTime activeDur = aEnd.GetMillis() - aBegin.GetMillis();
+    SMILTime activeDur = aEnd.GetMillis() - aBegin.GetMillis();
 
     if (result.IsDefinite()) {
       result.SetMillis(std::min(result.GetMillis(), activeDur));
     } else {
       result.SetMillis(activeDur);
     }
   }
 
   result = ApplyMinAndMax(result);
 
   if (result.IsDefinite()) {
-    nsSMILTime activeEnd = result.GetMillis() + aBegin.GetMillis();
+    SMILTime activeEnd = result.GetMillis() + aBegin.GetMillis();
     result.SetMillis(activeEnd);
   }
 
   return result;
 }
 
 SMILTimeValue SMILTimedElement::GetRepeatDuration() const {
   SMILTimeValue multipliedDuration;
   if (mRepeatCount.IsDefinite() && mSimpleDur.IsDefinite()) {
     if (mRepeatCount * double(mSimpleDur.GetMillis()) <=
-        std::numeric_limits<nsSMILTime>::max()) {
+        std::numeric_limits<SMILTime>::max()) {
       multipliedDuration.SetMillis(
-          nsSMILTime(mRepeatCount * mSimpleDur.GetMillis()));
+          SMILTime(mRepeatCount * mSimpleDur.GetMillis()));
     }
   } else {
     multipliedDuration.SetIndefinite();
   }
 
   SMILTimeValue repeatDuration;
 
   if (mRepeatDur.IsResolved()) {
@@ -1753,19 +1753,19 @@ SMILTimeValue SMILTimedElement::ApplyMin
     result = mMin;
   } else {
     result = aDuration;
   }
 
   return result;
 }
 
-nsSMILTime SMILTimedElement::ActiveTimeToSimpleTime(
-    nsSMILTime aActiveTime, uint32_t& aRepeatIteration) {
-  nsSMILTime result;
+SMILTime SMILTimedElement::ActiveTimeToSimpleTime(SMILTime aActiveTime,
+                                                  uint32_t& aRepeatIteration) {
+  SMILTime result;
 
   MOZ_ASSERT(mSimpleDur.IsResolved(),
              "Unresolved simple duration in ActiveTimeToSimpleTime");
   MOZ_ASSERT(aActiveTime >= 0, "Expecting non-negative active time");
   // Note that a negative aActiveTime will give us a negative value for
   // aRepeatIteration, which is bad because aRepeatIteration is unsigned
 
   if (mSimpleDur.IsIndefinite() || mSimpleDur.GetMillis() == 0L) {
@@ -1909,29 +1909,28 @@ void SMILTimedElement::UpdateCurrentInte
       AutoRestore<uint8_t> deleteCountRestorer(mDeleteCount);
       ++mDeleteCount;
       mElementState = STATE_POSTACTIVE;
       ResetCurrentInterval();
     }
   }
 }
 
-void SMILTimedElement::SampleSimpleTime(nsSMILTime aActiveTime) {
+void SMILTimedElement::SampleSimpleTime(SMILTime aActiveTime) {
   if (mClient) {
     uint32_t repeatIteration;
-    nsSMILTime simpleTime =
-        ActiveTimeToSimpleTime(aActiveTime, repeatIteration);
+    SMILTime simpleTime = ActiveTimeToSimpleTime(aActiveTime, repeatIteration);
     mClient->SampleAt(simpleTime, mSimpleDur, repeatIteration);
   }
 }
 
 void SMILTimedElement::SampleFillValue() {
   if (mFillMode != FILL_FREEZE || !mClient) return;
 
-  nsSMILTime activeTime;
+  SMILTime activeTime;
 
   if (mElementState == STATE_WAITING || mElementState == STATE_POSTACTIVE) {
     const SMILInterval* prevInterval = GetPreviousInterval();
     MOZ_ASSERT(prevInterval,
                "Attempting to sample fill value but there is no previous "
                "interval");
     MOZ_ASSERT(prevInterval->End()->Time().IsDefinite() &&
                    prevInterval->End()->IsFixedTime(),
@@ -1958,31 +1957,32 @@ void SMILTimedElement::SampleFillValue()
     // have a repeat duration shorter than the active duration so use that.
     MOZ_ASSERT(GetRepeatDuration().IsDefinite(),
                "Attempting to sample fill value of an active animation with "
                "an indefinite repeat duration");
     activeTime = GetRepeatDuration().GetMillis();
   }
 
   uint32_t repeatIteration;
-  nsSMILTime simpleTime = ActiveTimeToSimpleTime(activeTime, repeatIteration);
+  SMILTime simpleTime = ActiveTimeToSimpleTime(activeTime, repeatIteration);
 
   if (simpleTime == 0L && repeatIteration) {
     mClient->SampleLastValue(--repeatIteration);
   } else {
     mClient->SampleAt(simpleTime, mSimpleDur, repeatIteration);
   }
 }
 
-nsresult SMILTimedElement::AddInstanceTimeFromCurrentTime(
-    nsSMILTime aCurrentTime, double aOffsetSeconds, bool aIsBegin) {
+nsresult SMILTimedElement::AddInstanceTimeFromCurrentTime(SMILTime aCurrentTime,
+                                                          double aOffsetSeconds,
+                                                          bool aIsBegin) {
   double offset = NS_round(aOffsetSeconds * PR_MSEC_PER_SEC);
 
-  // Check we won't overflow the range of nsSMILTime
-  if (aCurrentTime + offset > std::numeric_limits<nsSMILTime>::max())
+  // Check we won't overflow the range of SMILTime
+  if (aCurrentTime + offset > std::numeric_limits<SMILTime>::max())
     return NS_ERROR_ILLEGAL_VALUE;
 
   SMILTimeValue timeVal(aCurrentTime + int64_t(offset));
 
   RefPtr<SMILInstanceTime> instanceTime =
       new SMILInstanceTime(timeVal, SMILInstanceTime::SOURCE_DOM);
 
   AddInstanceTime(instanceTime, aIsBegin);
@@ -2039,17 +2039,17 @@ bool SMILTimedElement::GetNextMilestone(
       aNextMilestone.mIsEnd = false;
       aNextMilestone.mTime = mCurrentInterval->Begin()->Time().GetMillis();
       return true;
 
     case STATE_ACTIVE: {
       // Work out what comes next: the interval end or the next repeat iteration
       SMILTimeValue nextRepeat;
       if (mSeekState == SEEK_NOT_SEEKING && mSimpleDur.IsDefinite()) {
-        nsSMILTime nextRepeatActiveTime =
+        SMILTime nextRepeatActiveTime =
             (mCurrentRepeatIteration + 1) * mSimpleDur.GetMillis();
         // Check that the repeat fits within the repeat duration
         if (SMILTimeValue(nextRepeatActiveTime) < GetRepeatDuration()) {
           nextRepeat.SetMillis(mCurrentInterval->Begin()->Time().GetMillis() +
                                nextRepeatActiveTime);
         }
       }
       SMILTimeValue nextMilestone =
--- a/dom/smil/SMILTimedElement.h
+++ b/dom/smil/SMILTimedElement.h
@@ -1,16 +1,16 @@
 /* -*- 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 NS_SMILTIMEDELEMENT_H_
-#define NS_SMILTIMEDELEMENT_H_
+#ifndef mozilla_SMILTimedElement_h
+#define mozilla_SMILTimedElement_h
 
 #include "mozilla/EventForwards.h"
 #include "mozilla/Move.h"
 #include "mozilla/SMILMilestone.h"
 #include "mozilla/SMILInstanceTime.h"
 #include "mozilla/SMILInterval.h"
 #include "mozilla/SMILRepeatCount.h"
 #include "mozilla/SMILTimeValueSpec.h"
@@ -199,31 +199,31 @@ class SMILTimedElement {
 
   /**
    * Samples the object at the given container time. Timing intervals are
    * updated and if this element is active at the given time the associated time
    * client will be sampled with the appropriate simple time.
    *
    * @param aContainerTime The container time at which to sample.
    */
-  void SampleAt(nsSMILTime aContainerTime);
+  void SampleAt(SMILTime aContainerTime);
 
   /**
    * Performs a special sample for the end of an interval. Such a sample should
    * only advance the timed element (and any dependent elements) to the waiting
    * or postactive state. It should not cause a transition to the active state.
    * Transition to the active state is only performed on a regular SampleAt.
    *
    * This allows all interval ends at a given time to be processed first and
    * hence the new interval can be established based on full information of the
    * available instance times.
    *
    * @param aContainerTime The container time at which to sample.
    */
-  void SampleEndAt(nsSMILTime aContainerTime);
+  void SampleEndAt(SMILTime aContainerTime);
 
   /**
    * Informs the timed element that its time container has changed time
    * relative to document time. The timed element therefore needs to update its
    * dependent elements (which may belong to a different time container) so they
    * can re-resolve their times.
    */
   void HandleContainerTimeChange();
@@ -393,17 +393,17 @@ class SMILTimedElement {
   void UnsetRepeatDur();
   void UnsetFillMode();
 
   nsresult SetBeginOrEndSpec(const nsAString& aSpec, Element& aContextElement,
                              bool aIsBegin, RemovalTestFunction aRemove);
   void ClearSpecs(TimeValueSpecList& aSpecs, InstanceTimeList& aInstances,
                   RemovalTestFunction aRemove);
   void ClearIntervals();
-  void DoSampleAt(nsSMILTime aContainerTime, bool aEndOnly);
+  void DoSampleAt(SMILTime aContainerTime, bool aEndOnly);
 
   /**
    * Helper function to check for an early end and, if necessary, update the
    * current interval accordingly.
    *
    * See SMIL 3.0, section 5.4.5, Element life cycle, "Active Time - Playing an
    * interval" for a description of ending early.
    *
@@ -456,17 +456,17 @@ class SMILTimedElement {
    * Unmarks instance times that were previously preserved because they were
    * considered important historical milestones but are no longer such because
    * a backwards seek has been performed.
    */
   void UnpreserveInstanceTimes(InstanceTimeList& aList);
 
   /**
    * Helper function to iterate through this element's accumulated timing
-   * information (specifically old SMILIntervals and nsSMILTimeInstanceTimes)
+   * information (specifically old SMILIntervals and SMILTimeInstanceTimes)
    * and discard items that are no longer needed or exceed some threshold of
    * accumulated state.
    */
   void FilterHistory();
 
   // Helper functions for FilterHistory to clear old SMILIntervals and
   // SMILInstanceTimes respectively.
   void FilterIntervals();
@@ -503,23 +503,23 @@ class SMILTimedElement {
                                    int32_t& aPosition) const;
   SMILInstanceTime* GetNextGreaterOrEqual(const InstanceTimeList& aList,
                                           const SMILTimeValue& aBase,
                                           int32_t& aPosition) const;
   SMILTimeValue CalcActiveEnd(const SMILTimeValue& aBegin,
                               const SMILTimeValue& aEnd) const;
   SMILTimeValue GetRepeatDuration() const;
   SMILTimeValue ApplyMinAndMax(const SMILTimeValue& aDuration) const;
-  nsSMILTime ActiveTimeToSimpleTime(nsSMILTime aActiveTime,
-                                    uint32_t& aRepeatIteration);
+  SMILTime ActiveTimeToSimpleTime(SMILTime aActiveTime,
+                                  uint32_t& aRepeatIteration);
   SMILInstanceTime* CheckForEarlyEnd(const SMILTimeValue& aContainerTime) const;
   void UpdateCurrentInterval(bool aForceChangeNotice = false);
-  void SampleSimpleTime(nsSMILTime aActiveTime);
+  void SampleSimpleTime(SMILTime aActiveTime);
   void SampleFillValue();
-  nsresult AddInstanceTimeFromCurrentTime(nsSMILTime aCurrentTime,
+  nsresult AddInstanceTimeFromCurrentTime(SMILTime aCurrentTime,
                                           double aOffsetSeconds, bool aIsBegin);
   void RegisterMilestone();
   bool GetNextMilestone(SMILMilestone& aNextMilestone) const;
 
   // Notification methods. Note that these notifications can result in nested
   // calls to this same object. Therefore,
   // (i)  we should not perform notification until this object is in
   //      a consistent state to receive callbacks, and
@@ -559,26 +559,26 @@ class SMILTimedElement {
   SMILTimeValue mSimpleDur;
 
   SMILRepeatCount mRepeatCount;
   SMILTimeValue mRepeatDur;
 
   SMILTimeValue mMin;
   SMILTimeValue mMax;
 
-  enum nsSMILFillMode : uint8_t { FILL_REMOVE, FILL_FREEZE };
-  nsSMILFillMode mFillMode;
+  enum SMILFillMode : uint8_t { FILL_REMOVE, FILL_FREEZE };
+  SMILFillMode mFillMode;
   static const nsAttrValue::EnumTable sFillModeTable[];
 
-  enum nsSMILRestartMode : uint8_t {
+  enum SMILRestartMode : uint8_t {
     RESTART_ALWAYS,
     RESTART_WHENNOTACTIVE,
     RESTART_NEVER
   };
-  nsSMILRestartMode mRestartMode;
+  SMILRestartMode mRestartMode;
   static const nsAttrValue::EnumTable sRestartModeTable[];
 
   InstanceTimeList mBeginInstances;
   InstanceTimeList mEndInstances;
   uint32_t mInstanceSerialIndex;
 
   SMILAnimationFunction* mClient;
   UniquePtr<SMILInterval> mCurrentInterval;
@@ -596,32 +596,32 @@ class SMILTimedElement {
   // [weak] The SMILTimeValueSpec objects register themselves and unregister
   // on destruction. Likewise, we notify them when we are destroyed.
   TimeValueSpecHashSet mTimeDependents;
 
   /**
    * The state of the element in its life-cycle. These states are based on the
    * element life-cycle described in SMILANIM 3.6.8
    */
-  enum nsSMILElementState {
+  enum SMILElementState {
     STATE_STARTUP,
     STATE_WAITING,
     STATE_ACTIVE,
     STATE_POSTACTIVE
   };
-  nsSMILElementState mElementState;
+  SMILElementState mElementState;
 
-  enum nsSMILSeekState {
+  enum SMILSeekState {
     SEEK_NOT_SEEKING,
     SEEK_FORWARD_FROM_ACTIVE,
     SEEK_FORWARD_FROM_INACTIVE,
     SEEK_BACKWARD_FROM_ACTIVE,
     SEEK_BACKWARD_FROM_INACTIVE
   };
-  nsSMILSeekState mSeekState;
+  SMILSeekState mSeekState;
 
   // Used to batch updates to the timing model
   class AutoIntervalUpdateBatcher;
   bool mDeferIntervalUpdates;
   bool mDoDeferredUpdate;  // Set if an update to the current interval was
                            // requested while mDeferIntervalUpdates was set
   bool mIsDisabled;
 
@@ -641,9 +641,9 @@ inline void ImplCycleCollectionUnlink(SM
 inline void ImplCycleCollectionTraverse(
     nsCycleCollectionTraversalCallback& aCallback, SMILTimedElement& aField,
     const char* aName, uint32_t aFlags = 0) {
   aField.Traverse(&aCallback);
 }
 
 }  // namespace mozilla
 
-#endif  // NS_SMILTIMEDELEMENT_H_
+#endif  // mozilla_SMILTimedElement_h
--- a/dom/smil/SMILType.h
+++ b/dom/smil/SMILType.h
@@ -1,16 +1,16 @@
 /* -*- 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 NS_ISMILTYPE_H_
-#define NS_ISMILTYPE_H_
+#ifndef mozilla_SMILType_h
+#define mozilla_SMILType_h
 
 #include "mozilla/Attributes.h"
 #include "nscore.h"
 
 namespace mozilla {
 
 class SMILValue;
 
@@ -204,9 +204,9 @@ class SMILType {
    */
   virtual nsresult Interpolate(const SMILValue& aStartVal,
                                const SMILValue& aEndVal, double aUnitDistance,
                                SMILValue& aResult) const = 0;
 };
 
 }  // namespace mozilla
 
-#endif  // NS_ISMILTYPE_H_
+#endif  // mozilla_SMILType_h
--- a/dom/smil/SMILTypes.h
+++ b/dom/smil/SMILTypes.h
@@ -1,16 +1,16 @@
 /* -*- 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 NS_SMILTYPES_H_
-#define NS_SMILTYPES_H_
+#ifndef mozilla_SMILTypes_h
+#define mozilla_SMILTypes_h
 
 #include <stdint.h>
 
 namespace mozilla {
 
 // A timestamp in milliseconds
 //
 // A time may represent:
@@ -18,13 +18,13 @@ namespace mozilla {
 //   simple time -- offset within the simple duration
 //   active time -- offset within the active duration
 //   document time -- offset since the document begin
 //   wallclock time -- "real" time -- offset since the epoch
 //
 // For an overview of how this class is related to other SMIL time classes see
 // the documentation in SMILTimeValue.h
 //
-typedef int64_t nsSMILTime;
+typedef int64_t SMILTime;
 
 }  // namespace mozilla
 
-#endif  // NS_SMILTYPES_H_
+#endif  // mozilla_SMILTypes_h
--- a/dom/smil/SMILValue.h
+++ b/dom/smil/SMILValue.h
@@ -1,16 +1,16 @@
 /* -*- 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 NS_SMILVALUE_H_
-#define NS_SMILVALUE_H_
+#ifndef mozilla_SMILValue_h
+#define mozilla_SMILValue_h
 
 #include "mozilla/SMILNullType.h"
 #include "mozilla/SMILType.h"
 
 namespace mozilla {
 
 /**
  * Although objects of this type are generally only created on the stack and
@@ -67,9 +67,9 @@ class SMILValue {
  protected:
   void InitAndCheckPostcondition(const SMILType* aNewType);
   void DestroyAndCheckPostcondition();
   void DestroyAndReinit(const SMILType* aNewType);
 };
 
 }  // namespace mozilla
 
-#endif  // NS_SMILVALUE_H_
+#endif  // mozilla_SMILValue_h
--- a/dom/smil/TimeEvent.h
+++ b/dom/smil/TimeEvent.h
@@ -1,16 +1,16 @@
 /* -*- 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_dom_TimeEvent_h_
-#define mozilla_dom_TimeEvent_h_
+#ifndef mozilla_dom_TimeEvent_h
+#define mozilla_dom_TimeEvent_h
 
 #include "nsDocShell.h"
 #include "mozilla/dom/Event.h"
 #include "mozilla/dom/TimeEventBinding.h"
 #include "mozilla/dom/Nullable.h"
 #include "mozilla/dom/WindowProxyHolder.h"
 
 class nsGlobalWindowInner;
@@ -55,9 +55,9 @@ class TimeEvent final : public Event {
 
 }  // namespace dom
 }  // namespace mozilla
 
 already_AddRefed<mozilla::dom::TimeEvent> NS_NewDOMTimeEvent(
     mozilla::dom::EventTarget* aOwner, nsPresContext* aPresContext,
     mozilla::InternalSMILTimeEvent* aEvent);
 
-#endif  // mozilla_dom_TimeEvent_h_
+#endif  // mozilla_dom_TimeEvent_h
--- a/dom/smil/moz.build
+++ b/dom/smil/moz.build
@@ -4,23 +4,20 @@
 # 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", "SVG")
 
 MOCHITEST_MANIFESTS += ['test/mochitest.ini']
 
-EXPORTS += [
-    'nsISMILAttr.h',
-]
-
 EXPORTS.mozilla += [
     'SMILAnimationController.h',
     'SMILAnimationFunction.h',
+    'SMILAttr.h',
     'SMILCompositorTable.h',
     'SMILCSSValueType.h',
     'SMILInstanceTime.h',
     'SMILInterval.h',
     'SMILKeySpline.h',
     'SMILMilestone.h',
     'SMILNullType.h',
     'SMILParserUtils.h',
--- a/dom/svg/SVGAngle.cpp
+++ b/dom/svg/SVGAngle.cpp
@@ -292,17 +292,17 @@ already_AddRefed<SVGAnimatedAngle> SVGAn
 
   return domAnimatedAngle.forget();
 }
 
 SVGAnimatedAngle::~SVGAnimatedAngle() {
   sSVGAnimatedAngleTearoffTable.RemoveTearoff(mVal);
 }
 
-UniquePtr<nsISMILAttr> SVGAngle::ToSMILAttr(SVGElement* aSVGElement) {
+UniquePtr<SMILAttr> SVGAngle::ToSMILAttr(SVGElement* aSVGElement) {
   if (aSVGElement->NodeInfo()->Equals(nsGkAtoms::marker, kNameSpaceID_SVG)) {
     SVGMarkerElement* marker = static_cast<SVGMarkerElement*>(aSVGElement);
     return MakeUnique<SMILOrient>(marker->GetOrientType(), this, aSVGElement);
   }
   // SMILOrient would not be useful for general angle attributes (also,
   // "orient" is the only animatable <angle>-valued attribute in SVG 1.1).
   MOZ_ASSERT_UNREACHABLE("Trying to animate unknown angle attribute.");
   return nullptr;
--- a/dom/svg/SVGAngle.h
+++ b/dom/svg/SVGAngle.h
@@ -3,19 +3,19 @@
 /* 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 __NS_SVGANGLE_H__
 #define __NS_SVGANGLE_H__
 
 #include "nsError.h"
-#include "nsISMILAttr.h"
 #include "mozilla/AlreadyAddRefed.h"
 #include "mozilla/Attributes.h"
+#include "mozilla/SMILAttr.h"
 #include "mozilla/dom/SVGAngleBinding.h"
 #include "mozilla/UniquePtr.h"
 
 class nsISupports;
 
 namespace mozilla {
 
 class SMILValue;
@@ -62,17 +62,17 @@ class SVGAngle {
   uint8_t GetBaseValueUnit() const { return mBaseValUnit; }
   uint8_t GetAnimValueUnit() const { return mAnimValUnit; }
   float GetBaseValInSpecifiedUnits() const { return mBaseVal; }
   float GetAnimValInSpecifiedUnits() const { return mAnimVal; }
 
   static nsresult ToDOMSVGAngle(nsISupports** aResult);
   already_AddRefed<mozilla::dom::SVGAnimatedAngle> ToDOMAnimatedAngle(
       SVGElement* aSVGElement);
-  mozilla::UniquePtr<nsISMILAttr> ToSMILAttr(SVGElement* aSVGElement);
+  mozilla::UniquePtr<SMILAttr> ToSMILAttr(SVGElement* aSVGElement);
 
   static bool GetValueFromString(const nsAString& aString, float& aValue,
                                  uint16_t* aUnitType);
   static float GetDegreesPerUnit(uint8_t aUnit);
 
  private:
   float mAnimVal;
   float mBaseVal;
@@ -91,30 +91,30 @@ class SVGAngle {
       SVGElement* aSVGElement);
 
  public:
   // We do not currently implemente a SMILAngle struct because in SVG 1.1 the
   // only *animatable* attribute that takes an <angle> is 'orient', on the
   // 'marker' element, and 'orient' must be special cased since it can also
   // take the value 'auto', making it a more complex type.
 
-  struct SMILOrient final : public nsISMILAttr {
+  struct SMILOrient final : public SMILAttr {
    public:
     SMILOrient(mozilla::dom::nsSVGOrientType* aOrientType, SVGAngle* aAngle,
                SVGElement* aSVGElement)
         : mOrientType(aOrientType), mAngle(aAngle), mSVGElement(aSVGElement) {}
 
-    // These will stay alive because a nsISMILAttr only lives as long
+    // These will stay alive because a SMILAttr only lives as long
     // as the Compositing step, and DOM elements don't get a chance to
     // die during that.
     mozilla::dom::nsSVGOrientType* mOrientType;
     SVGAngle* mAngle;
     SVGElement* mSVGElement;
 
-    // nsISMILAttr methods
+    // SMILAttr methods
     virtual nsresult ValueFromString(
         const nsAString& aStr,
         const mozilla::dom::SVGAnimationElement* aSrcElement, SMILValue& aValue,
         bool& aPreventCachingOfSandwich) const override;
     virtual SMILValue GetBaseValue() const override;
     virtual void ClearAnimValue() override;
     virtual nsresult SetAnimValue(const SMILValue& aValue) override;
   };
--- a/dom/svg/SVGAnimateMotionElement.cpp
+++ b/dom/svg/SVGAnimateMotionElement.cpp
@@ -34,16 +34,16 @@ NS_IMPL_ELEMENT_CLONE_WITH_INIT(SVGAnima
 SMILAnimationFunction& SVGAnimateMotionElement::AnimationFunction() {
   return mAnimationFunction;
 }
 
 bool SVGAnimateMotionElement::GetTargetAttributeName(
     int32_t* aNamespaceID, nsAtom** aLocalName) const {
   // <animateMotion> doesn't take an attributeName, since it doesn't target an
   // 'attribute' per se.  We'll use a unique dummy attribute-name so that our
-  // nsSMILTargetIdentifier logic (which requires a attribute name) still works.
+  // SMILTargetIdentifier logic (which requires a attribute name) still works.
   *aNamespaceID = kNameSpaceID_None;
   *aLocalName = nsGkAtoms::mozAnimateMotionDummyAttr;
   return true;
 }
 
 }  // namespace dom
 }  // namespace mozilla
--- a/dom/svg/SVGAnimatedLengthList.cpp
+++ b/dom/svg/SVGAnimatedLengthList.cpp
@@ -108,19 +108,20 @@ void SVGAnimatedLengthList::ClearAnimVal
     // must do that before touching mAnimVal. See comments above.
     //
     domWrapper->InternalAnimValListWillChangeTo(mBaseVal);
   }
   mAnimVal = nullptr;
   aElement->DidAnimateLengthList(aAttrEnum);
 }
 
-UniquePtr<nsISMILAttr> SVGAnimatedLengthList::ToSMILAttr(
-    SVGElement *aSVGElement, uint8_t aAttrEnum, uint8_t aAxis,
-    bool aCanZeroPadList) {
+UniquePtr<SMILAttr> SVGAnimatedLengthList::ToSMILAttr(SVGElement *aSVGElement,
+                                                      uint8_t aAttrEnum,
+                                                      uint8_t aAxis,
+                                                      bool aCanZeroPadList) {
   return MakeUnique<SMILAnimatedLengthList>(this, aSVGElement, aAttrEnum, aAxis,
                                             aCanZeroPadList);
 }
 
 nsresult SVGAnimatedLengthList::SMILAnimatedLengthList::ValueFromString(
     const nsAString &aStr, const dom::SVGAnimationElement * /*aSrcElement*/,
     SMILValue &aValue, bool &aPreventCachingOfSandwich) const {
   SMILValue val(&SVGLengthListSMILType::sSingleton);
--- a/dom/svg/SVGAnimatedLengthList.h
+++ b/dom/svg/SVGAnimatedLengthList.h
@@ -3,19 +3,19 @@
 /* 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_SVGANIMATEDLENGTHLIST_H__
 #define MOZILLA_SVGANIMATEDLENGTHLIST_H__
 
 #include "mozilla/Attributes.h"
+#include "mozilla/SMILAttr.h"
 #include "mozilla/UniquePtr.h"
 #include "nsAutoPtr.h"
-#include "nsISMILAttr.h"
 #include "SVGLengthList.h"
 
 namespace mozilla {
 
 class SMILValue;
 
 namespace dom {
 class SVGAnimationElement;
@@ -63,50 +63,50 @@ class SVGAnimatedLengthList {
 
   nsresult SetAnimValue(const SVGLengthList& aValue, dom::SVGElement* aElement,
                         uint32_t aAttrEnum);
 
   void ClearAnimValue(dom::SVGElement* aElement, uint32_t aAttrEnum);
 
   bool IsAnimating() const { return !!mAnimVal; }
 
-  UniquePtr<nsISMILAttr> ToSMILAttr(dom::SVGElement* aSVGElement,
-                                    uint8_t aAttrEnum, uint8_t aAxis,
-                                    bool aCanZeroPadList);
+  UniquePtr<SMILAttr> ToSMILAttr(dom::SVGElement* aSVGElement,
+                                 uint8_t aAttrEnum, uint8_t aAxis,
+                                 bool aCanZeroPadList);
 
  private:
   // mAnimVal is a pointer to allow us to determine if we're being animated or
   // not. Making it a non-pointer member and using mAnimVal.IsEmpty() to check
   // if we're animating is not an option, since that would break animation *to*
   // the empty string (<set to="">).
 
   SVGLengthList mBaseVal;
   nsAutoPtr<SVGLengthList> mAnimVal;
 
-  struct SMILAnimatedLengthList : public nsISMILAttr {
+  struct SMILAnimatedLengthList : public SMILAttr {
    public:
     SMILAnimatedLengthList(SVGAnimatedLengthList* aVal,
                            dom::SVGElement* aSVGElement, uint8_t aAttrEnum,
                            uint8_t aAxis, bool aCanZeroPadList)
         : mVal(aVal),
           mElement(aSVGElement),
           mAttrEnum(aAttrEnum),
           mAxis(aAxis),
           mCanZeroPadList(aCanZeroPadList) {}
 
-    // These will stay alive because a nsISMILAttr only lives as long
+    // These will stay alive because a SMILAttr only lives as long
     // as the Compositing step, and DOM elements don't get a chance to
     // die during that.
     SVGAnimatedLengthList* mVal;
     dom::SVGElement* mElement;
     uint8_t mAttrEnum;
     uint8_t mAxis;
     bool mCanZeroPadList;  // See SVGLengthListAndInfo::CanZeroPadList
 
-    // nsISMILAttr methods
+    // SMILAttr methods
     virtual nsresult ValueFromString(
         const nsAString& aStr, const dom::SVGAnimationElement* aSrcElement,
         SMILValue& aValue, bool& aPreventCachingOfSandwich) const override;
     virtual SMILValue GetBaseValue() const override;
     virtual void ClearAnimValue() override;
     virtual nsresult SetAnimValue(const SMILValue& aValue) override;
   };
 };
--- a/dom/svg/SVGAnimatedNumberList.cpp
+++ b/dom/svg/SVGAnimatedNumberList.cpp
@@ -109,18 +109,18 @@ void SVGAnimatedNumberList::ClearAnimVal
     // must do that before touching mAnimVal. See comments above.
     //
     domWrapper->InternalAnimValListWillChangeTo(mBaseVal);
   }
   mAnimVal = nullptr;
   aElement->DidAnimateNumberList(aAttrEnum);
 }
 
-UniquePtr<nsISMILAttr> SVGAnimatedNumberList::ToSMILAttr(
-    SVGElement *aSVGElement, uint8_t aAttrEnum) {
+UniquePtr<SMILAttr> SVGAnimatedNumberList::ToSMILAttr(SVGElement *aSVGElement,
+                                                      uint8_t aAttrEnum) {
   return MakeUnique<SMILAnimatedNumberList>(this, aSVGElement, aAttrEnum);
 }
 
 nsresult SVGAnimatedNumberList::SMILAnimatedNumberList::ValueFromString(
     const nsAString &aStr, const dom::SVGAnimationElement * /*aSrcElement*/,
     SMILValue &aValue, bool &aPreventCachingOfSandwich) const {
   SMILValue val(&SVGNumberListSMILType::sSingleton);
   SVGNumberListAndInfo *nlai = static_cast<SVGNumberListAndInfo *>(val.mU.mPtr);
--- a/dom/svg/SVGAnimatedNumberList.h
+++ b/dom/svg/SVGAnimatedNumberList.h
@@ -3,19 +3,19 @@
 /* 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_SVGANIMATEDNUMBERLIST_H__
 #define MOZILLA_SVGANIMATEDNUMBERLIST_H__
 
 #include "mozilla/Attributes.h"
+#include "mozilla/SMILAttr.h"
 #include "mozilla/UniquePtr.h"
 #include "nsAutoPtr.h"
-#include "nsISMILAttr.h"
 #include "SVGNumberList.h"
 
 namespace mozilla {
 
 class SMILValue;
 
 namespace dom {
 class SVGAnimationElement;
@@ -70,43 +70,43 @@ class SVGAnimatedNumberList {
   // set (either by animation, or by taking on the base value which has been
   // explicitly set by markup or a DOM call), false otherwise.
   // If this returns false, the animated value is still valid, that is,
   // usable, and represents the default base value of the attribute.
   bool IsExplicitlySet() const { return !!mAnimVal || mIsBaseSet; }
 
   bool IsAnimating() const { return !!mAnimVal; }
 
-  UniquePtr<nsISMILAttr> ToSMILAttr(dom::SVGElement* aSVGElement,
-                                    uint8_t aAttrEnum);
+  UniquePtr<SMILAttr> ToSMILAttr(dom::SVGElement* aSVGElement,
+                                 uint8_t aAttrEnum);
 
  private:
   // mAnimVal is a pointer to allow us to determine if we're being animated or
   // not. Making it a non-pointer member and using mAnimVal.IsEmpty() to check
   // if we're animating is not an option, since that would break animation *to*
   // the empty string (<set to="">).
 
   SVGNumberList mBaseVal;
   nsAutoPtr<SVGNumberList> mAnimVal;
   bool mIsBaseSet;
 
-  struct SMILAnimatedNumberList : public nsISMILAttr {
+  struct SMILAnimatedNumberList : public SMILAttr {
    public:
     SMILAnimatedNumberList(SVGAnimatedNumberList* aVal,
                            dom::SVGElement* aSVGElement, uint8_t aAttrEnum)
         : mVal(aVal), mElement(aSVGElement), mAttrEnum(aAttrEnum) {}
 
-    // These will stay alive because a nsISMILAttr only lives as long
+    // These will stay alive because a SMILAttr only lives as long
     // as the Compositing step, and DOM elements don't get a chance to
     // die during that.
     SVGAnimatedNumberList* mVal;
     dom::SVGElement* mElement;
     uint8_t mAttrEnum;
 
-    // nsISMILAttr methods
+    // SMILAttr methods
     virtual nsresult ValueFromString(
         const nsAString& aStr, const dom::SVGAnimationElement* aSrcElement,
         SMILValue& aValue, bool& aPreventCachingOfSandwich) const override;
     virtual SMILValue GetBaseValue() const override;
     virtual void ClearAnimValue() override;
     virtual nsresult SetAnimValue(const SMILValue& aValue) override;
   };
 };
--- a/dom/svg/SVGAnimatedPathSegList.cpp
+++ b/dom/svg/SVGAnimatedPathSegList.cpp
@@ -136,18 +136,17 @@ void SVGAnimatedPathSegList::ClearAnimVa
   mAnimVal = nullptr;
   aElement->DidAnimatePathSegList();
 }
 
 bool SVGAnimatedPathSegList::IsRendered() const {
   return mAnimVal ? !mAnimVal->IsEmpty() : !mBaseVal.IsEmpty();
 }
 
-UniquePtr<nsISMILAttr> SVGAnimatedPathSegList::ToSMILAttr(
-    SVGElement *aElement) {
+UniquePtr<SMILAttr> SVGAnimatedPathSegList::ToSMILAttr(SVGElement *aElement) {
   return MakeUnique<SMILAnimatedPathSegList>(this, aElement);
 }
 
 nsresult SVGAnimatedPathSegList::SMILAnimatedPathSegList::ValueFromString(
     const nsAString &aStr, const dom::SVGAnimationElement * /*aSrcElement*/,
     SMILValue &aValue, bool &aPreventCachingOfSandwich) const {
   SMILValue val(SVGPathSegListSMILType::Singleton());
   SVGPathDataAndInfo *list = static_cast<SVGPathDataAndInfo *>(val.mU.mPtr);
--- a/dom/svg/SVGAnimatedPathSegList.h
+++ b/dom/svg/SVGAnimatedPathSegList.h
@@ -4,19 +4,19 @@
  * 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_SVGANIMATEDPATHSEGLIST_H__
 #define MOZILLA_SVGANIMATEDPATHSEGLIST_H__
 
 #include "mozilla/Attributes.h"
 #include "mozilla/MemoryReporting.h"
+#include "mozilla/SMILAttr.h"
 #include "mozilla/UniquePtr.h"
 #include "nsAutoPtr.h"
-#include "nsISMILAttr.h"
 #include "SVGPathData.h"
 
 namespace mozilla {
 
 class SMILValue;
 
 namespace dom {
 class SVGAnimationElement;
@@ -78,42 +78,42 @@ class SVGAnimatedPathSegList final {
    * Needed for correct DOM wrapper construction since GetAnimValue may
    * actually return the baseVal!
    */
   void* GetBaseValKey() const { return (void*)&mBaseVal; }
   void* GetAnimValKey() const { return (void*)&mAnimVal; }
 
   bool IsAnimating() const { return !!mAnimVal; }
 
-  UniquePtr<nsISMILAttr> ToSMILAttr(dom::SVGElement* aElement);
+  UniquePtr<SMILAttr> ToSMILAttr(dom::SVGElement* aElement);
 
   size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const;
 
  private:
   // mAnimVal is a pointer to allow us to determine if we're being animated or
   // not. Making it a non-pointer member and using mAnimVal.IsEmpty() to check
   // if we're animating is not an option, since that would break animation *to*
   // the empty string (<set to="">).
 
   SVGPathData mBaseVal;
   nsAutoPtr<SVGPathData> mAnimVal;
 
-  struct SMILAnimatedPathSegList : public nsISMILAttr {
+  struct SMILAnimatedPathSegList : public SMILAttr {
    public:
     SMILAnimatedPathSegList(SVGAnimatedPathSegList* aVal,
                             dom::SVGElement* aElement)
         : mVal(aVal), mElement(aElement) {}
 
-    // These will stay alive because a nsISMILAttr only lives as long
+    // These will stay alive because a SMILAttr only lives as long
     // as the Compositing step, and DOM elements don't get a chance to
     // die during that.
     SVGAnimatedPathSegList* mVal;
     dom::SVGElement* mElement;
 
-    // nsISMILAttr methods
+    // SMILAttr methods
     virtual nsresult ValueFromString(
         const nsAString& aStr, const dom::SVGAnimationElement* aSrcElement,
         SMILValue& aValue, bool& aPreventCachingOfSandwich) const override;
     virtual SMILValue GetBaseValue() const override;
     virtual void ClearAnimValue() override;
     virtual nsresult SetAnimValue(const SMILValue& aValue) override;
   };
 };
--- a/dom/svg/SVGAnimatedPointList.cpp
+++ b/dom/svg/SVGAnimatedPointList.cpp
@@ -135,17 +135,17 @@ void SVGAnimatedPointList::ClearAnimValu
     // a different number of items to the last active animated value.
     //
     domWrapper->InternalListWillChangeTo(mBaseVal);
   }
   mAnimVal = nullptr;
   aElement->DidAnimatePointList();
 }
 
-UniquePtr<nsISMILAttr> SVGAnimatedPointList::ToSMILAttr(SVGElement *aElement) {
+UniquePtr<SMILAttr> SVGAnimatedPointList::ToSMILAttr(SVGElement *aElement) {
   return MakeUnique<SMILAnimatedPointList>(this, aElement);
 }
 
 nsresult SVGAnimatedPointList::SMILAnimatedPointList::ValueFromString(
     const nsAString &aStr, const dom::SVGAnimationElement * /*aSrcElement*/,
     SMILValue &aValue, bool &aPreventCachingOfSandwich) const {
   SMILValue val(&SVGPointListSMILType::sSingleton);
   SVGPointListAndInfo *list = static_cast<SVGPointListAndInfo *>(val.mU.mPtr);
--- a/dom/svg/SVGAnimatedPointList.h
+++ b/dom/svg/SVGAnimatedPointList.h
@@ -3,19 +3,19 @@
 /* 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_SVGANIMATEDPOINTLIST_H__
 #define MOZILLA_SVGANIMATEDPOINTLIST_H__
 
 #include "mozilla/Attributes.h"
+#include "mozilla/SMILAttr.h"
 #include "mozilla/UniquePtr.h"
 #include "nsAutoPtr.h"
-#include "nsISMILAttr.h"
 #include "SVGPointList.h"
 
 namespace mozilla {
 
 class SMILValue;
 
 namespace dom {
 class SVGAnimationElement;
@@ -72,39 +72,39 @@ class SVGAnimatedPointList {
    * Needed for correct DOM wrapper construction since GetAnimValue may
    * actually return the baseVal!
    */
   void* GetBaseValKey() const { return (void*)&mBaseVal; }
   void* GetAnimValKey() const { return (void*)&mAnimVal; }
 
   bool IsAnimating() const { return !!mAnimVal; }
 
-  UniquePtr<nsISMILAttr> ToSMILAttr(dom::SVGElement* aElement);
+  UniquePtr<SMILAttr> ToSMILAttr(dom::SVGElement* aElement);
 
  private:
   // mAnimVal is a pointer to allow us to determine if we're being animated or
   // not. Making it a non-pointer member and using mAnimVal.IsEmpty() to check
   // if we're animating is not an option, since that would break animation *to*
   // the empty string (<set to="">).
 
   SVGPointList mBaseVal;
   nsAutoPtr<SVGPointList> mAnimVal;
 
-  struct SMILAnimatedPointList : public nsISMILAttr {
+  struct SMILAnimatedPointList : public SMILAttr {
    public:
     SMILAnimatedPointList(SVGAnimatedPointList* aVal, dom::SVGElement* aElement)
         : mVal(aVal), mElement(aElement) {}
 
-    // These will stay alive because a nsISMILAttr only lives as long
+    // These will stay alive because a SMILAttr only lives as long
     // as the Compositing step, and DOM elements don't get a chance to
     // die during that.
     SVGAnimatedPointList* mVal;
     dom::SVGElement* mElement;
 
-    // nsISMILAttr methods
+    // SMILAttr methods
     virtual nsresult ValueFromString(
         const nsAString& aStr, const dom::SVGAnimationElement* aSrcElement,
         SMILValue& aValue, bool& aPreventCachingOfSandwich) const override;
     virtual SMILValue GetBaseValue() const override;
     virtual void ClearAnimValue() override;
     virtual nsresult SetAnimValue(const SMILValue& aValue) override;
   };
 };
--- a/dom/svg/SVGAnimatedPreserveAspectRatio.cpp
+++ b/dom/svg/SVGAnimatedPreserveAspectRatio.cpp
@@ -163,17 +163,17 @@ SVGAnimatedPreserveAspectRatio::ToDOMAni
   }
   return domAnimatedPAspectRatio.forget();
 }
 
 DOMSVGAnimatedPreserveAspectRatio::~DOMSVGAnimatedPreserveAspectRatio() {
   sSVGAnimatedPAspectRatioTearoffTable.RemoveTearoff(mVal);
 }
 
-UniquePtr<nsISMILAttr> SVGAnimatedPreserveAspectRatio::ToSMILAttr(
+UniquePtr<SMILAttr> SVGAnimatedPreserveAspectRatio::ToSMILAttr(
     SVGElement* aSVGElement) {
   return MakeUnique<SMILPreserveAspectRatio>(this, aSVGElement);
 }
 
 // typedef for inner class, to make function signatures shorter below:
 typedef SVGAnimatedPreserveAspectRatio::SMILPreserveAspectRatio
     SMILPreserveAspectRatio;
 
--- a/dom/svg/SVGAnimatedPreserveAspectRatio.h
+++ b/dom/svg/SVGAnimatedPreserveAspectRatio.h
@@ -4,21 +4,21 @@
  * 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_SVGANIMATEDPRESERVEASPECTRATIO_H__
 #define MOZILLA_SVGANIMATEDPRESERVEASPECTRATIO_H__
 
 #include "nsCycleCollectionParticipant.h"
 #include "nsError.h"
-#include "nsISMILAttr.h"
-#include "SVGElement.h"
 #include "SVGPreserveAspectRatio.h"
 #include "mozilla/Attributes.h"
+#include "mozilla/SMILAttr.h"
 #include "mozilla/UniquePtr.h"
+#include "mozilla/dom/SVGElement.h"
 
 namespace mozilla {
 
 class SMILValue;
 
 namespace dom {
 class DOMSVGAnimatedPreserveAspectRatio;
 class SVGAnimationElement;
@@ -64,38 +64,38 @@ class SVGAnimatedPreserveAspectRatio fin
 
   const SVGPreserveAspectRatio& GetBaseValue() const { return mBaseVal; }
   const SVGPreserveAspectRatio& GetAnimValue() const { return mAnimVal; }
   bool IsAnimated() const { return mIsAnimated; }
   bool IsExplicitlySet() const { return mIsAnimated || mIsBaseSet; }
 
   already_AddRefed<mozilla::dom::DOMSVGAnimatedPreserveAspectRatio>
   ToDOMAnimatedPreserveAspectRatio(dom::SVGElement* aSVGElement);
-  UniquePtr<nsISMILAttr> ToSMILAttr(dom::SVGElement* aSVGElement);
+  UniquePtr<SMILAttr> ToSMILAttr(dom::SVGElement* aSVGElement);
 
  private:
   SVGPreserveAspectRatio mAnimVal;
   SVGPreserveAspectRatio mBaseVal;
   bool mIsAnimated;
   bool mIsBaseSet;
 
  public:
-  struct SMILPreserveAspectRatio final : public nsISMILAttr {
+  struct SMILPreserveAspectRatio final : public SMILAttr {
    public:
     SMILPreserveAspectRatio(SVGAnimatedPreserveAspectRatio* aVal,
                             dom::SVGElement* aSVGElement)
         : mVal(aVal), mSVGElement(aSVGElement) {}
 
-    // These will stay alive because a nsISMILAttr only lives as long
+    // These will stay alive because a SMILAttr only lives as long
     // as the Compositing step, and DOM elements don't get a chance to
     // die during that.
     SVGAnimatedPreserveAspectRatio* mVal;
     dom::SVGElement* mSVGElement;
 
-    // nsISMILAttr methods
+    // SMILAttr methods
     virtual nsresult ValueFromString(
         const nsAString& aStr, const dom::SVGAnimationElement* aSrcElement,
         SMILValue& aValue, bool& aPreventCachingOfSandwich) const override;
     virtual SMILValue GetBaseValue() const override;
     virtual void ClearAnimValue() override;
     virtual nsresult SetAnimValue(const SMILValue& aValue) override;
   };
 };
--- a/dom/svg/SVGAnimatedTransformList.cpp
+++ b/dom/svg/SVGAnimatedTransformList.cpp
@@ -156,17 +156,17 @@ bool SVGAnimatedTransformList::IsExplici
   //    SVGElement::UnsetAttr or a failed SVGElement::ParseAttribute)
   // 2) DOM call -- simply fetching the baseVal doesn't mean the transform value
   //    has been set. It is set if that baseVal has one or more transforms in
   //    the list.
   // 3) Animation -- which will cause the mAnimVal member to be allocated
   return mIsAttrSet || !mBaseVal.IsEmpty() || mAnimVal;
 }
 
-UniquePtr<nsISMILAttr> SVGAnimatedTransformList::ToSMILAttr(
+UniquePtr<SMILAttr> SVGAnimatedTransformList::ToSMILAttr(
     SVGElement* aSVGElement) {
   return MakeUnique<SMILAnimatedTransformList>(this, aSVGElement);
 }
 
 nsresult SVGAnimatedTransformList::SMILAnimatedTransformList::ValueFromString(
     const nsAString& aStr, const dom::SVGAnimationElement* aSrcElement,
     SMILValue& aValue, bool& aPreventCachingOfSandwich) const {
   NS_ENSURE_TRUE(aSrcElement, NS_ERROR_FAILURE);
--- a/dom/svg/SVGAnimatedTransformList.h
+++ b/dom/svg/SVGAnimatedTransformList.h
@@ -3,19 +3,19 @@
 /* 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_SVGANIMATEDTRANSFORMLIST_H__
 #define MOZILLA_SVGANIMATEDTRANSFORMLIST_H__
 
 #include "mozilla/Attributes.h"
+#include "mozilla/SMILAttr.h"
 #include "mozilla/UniquePtr.h"
 #include "nsAutoPtr.h"
-#include "nsISMILAttr.h"
 #include "SVGTransformList.h"
 
 class nsAtom;
 
 namespace mozilla {
 
 class SMILValue;
 
@@ -103,51 +103,51 @@ class SVGAnimatedTransformList {
    * accessor lets it detect cases where the "modification" is actually adding
    * a transform where we previously had none. These cases require a more
    * thorough nsChangeHint.)
    */
   bool RequiresFrameReconstruction() const {
     return mRequiresFrameReconstruction;
   }
 
-  mozilla::UniquePtr<nsISMILAttr> ToSMILAttr(dom::SVGElement* aSVGElement);
+  mozilla::UniquePtr<SMILAttr> ToSMILAttr(dom::SVGElement* aSVGElement);
 
  private:
   // mAnimVal is a pointer to allow us to determine if we're being animated or
   // not. Making it a non-pointer member and using mAnimVal.IsEmpty() to check
   // if we're animating is not an option, since that would break animation *to*
   // the empty string (<set to="">).
 
   SVGTransformList mBaseVal;
   nsAutoPtr<SVGTransformList> mAnimVal;
   bool mIsAttrSet;
   // (See documentation for accessor, RequiresFrameReconstruction.)
   bool mRequiresFrameReconstruction;
 
-  struct SMILAnimatedTransformList : public nsISMILAttr {
+  struct SMILAnimatedTransformList : public SMILAttr {
    public:
     SMILAnimatedTransformList(SVGAnimatedTransformList* aVal,
                               dom::SVGElement* aSVGElement)
         : mVal(aVal), mElement(aSVGElement) {}
 
-    // nsISMILAttr methods
+    // SMILAttr methods
     virtual nsresult ValueFromString(
         const nsAString& aStr, const dom::SVGAnimationElement* aSrcElement,
         SMILValue& aValue, bool& aPreventCachingOfSandwich) const override;
     virtual SMILValue GetBaseValue() const override;
     virtual void ClearAnimValue() override;
     virtual nsresult SetAnimValue(const SMILValue& aValue) override;
 
    protected:
     static void ParseValue(const nsAString& aSpec, const nsAtom* aTransformType,
                            SMILValue& aResult);
     static int32_t ParseParameterList(const nsAString& aSpec, float* aVars,
                                       int32_t aNVars);
 
-    // These will stay alive because a nsISMILAttr only lives as long
+    // These will stay alive because a SMILAttr only lives as long
     // as the Compositing step, and DOM elements don't get a chance to
     // die during that.
     SVGAnimatedTransformList* mVal;
     dom::SVGElement* mElement;
   };
 };
 
 }  // namespace mozilla
--- a/dom/svg/SVGAnimationElement.h
+++ b/dom/svg/SVGAnimationElement.h
@@ -13,22 +13,16 @@
 #include "mozilla/dom/SVGElement.h"
 #include "mozilla/dom/SVGTests.h"
 
 namespace mozilla {
 namespace dom {
 
 typedef SVGElement SVGAnimationElementBase;
 
-enum nsSMILTargetAttrType {
-  eSMILTargetAttrType_auto,
-  eSMILTargetAttrType_CSS,
-  eSMILTargetAttrType_XML
-};
-
 class SVGAnimationElement : public SVGAnimationElementBase, public SVGTests {
  protected:
   explicit SVGAnimationElement(
       already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
   nsresult Init();
   virtual ~SVGAnimationElement();
 
  public:
--- a/dom/svg/SVGBoolean.cpp
+++ b/dom/svg/SVGBoolean.cpp
@@ -109,17 +109,17 @@ already_AddRefed<SVGAnimatedBoolean> SVG
 
   return domAnimatedBoolean.forget();
 }
 
 SVGAnimatedBoolean::~SVGAnimatedBoolean() {
   SVGAnimatedBooleanTearoffTable().RemoveTearoff(mVal);
 }
 
-UniquePtr<nsISMILAttr> SVGBoolean::ToSMILAttr(SVGElement* aSVGElement) {
+UniquePtr<SMILAttr> SVGBoolean::ToSMILAttr(SVGElement* aSVGElement) {
   return MakeUnique<SMILBool>(this, aSVGElement);
 }
 
 nsresult SVGBoolean::SMILBool::ValueFromString(
     const nsAString& aStr, const SVGAnimationElement* /*aSrcElement*/,
     SMILValue& aValue, bool& aPreventCachingOfSandwich) const {
   bool value;
   if (!GetValueFromString(aStr, value)) {
--- a/dom/svg/SVGBoolean.h
+++ b/dom/svg/SVGBoolean.h
@@ -3,17 +3,17 @@
 /* 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 __NS_SVGBOOLEAN_H__
 #define __NS_SVGBOOLEAN_H__
 
 #include "nsError.h"
-#include "nsISMILAttr.h"
+#include "mozilla/SMILAttr.h"
 #include "mozilla/AlreadyAddRefed.h"
 #include "mozilla/Attributes.h"
 #include "mozilla/UniquePtr.h"
 
 class nsAtom;
 
 namespace mozilla {
 
@@ -41,37 +41,37 @@ class SVGBoolean {
   void SetBaseValue(bool aValue, SVGElement* aSVGElement);
   bool GetBaseValue() const { return mBaseVal; }
 
   void SetAnimValue(bool aValue, SVGElement* aSVGElement);
   bool GetAnimValue() const { return mAnimVal; }
 
   already_AddRefed<mozilla::dom::SVGAnimatedBoolean> ToDOMAnimatedBoolean(
       SVGElement* aSVGElement);
-  mozilla::UniquePtr<nsISMILAttr> ToSMILAttr(SVGElement* aSVGElement);
+  mozilla::UniquePtr<SMILAttr> ToSMILAttr(SVGElement* aSVGElement);
 
  private:
   bool mAnimVal;
   bool mBaseVal;
   bool mIsAnimated;
   uint8_t mAttrEnum;  // element specified tracking for attribute
 
  public:
-  struct SMILBool : public nsISMILAttr {
+  struct SMILBool : public SMILAttr {
    public:
     SMILBool(SVGBoolean* aVal, SVGElement* aSVGElement)
         : mVal(aVal), mSVGElement(aSVGElement) {}
 
-    // These will stay alive because a nsISMILAttr only lives as long
+    // These will stay alive because a SMILAttr only lives as long
     // as the Compositing step, and DOM elements don't get a chance to
     // die during that.
     SVGBoolean* mVal;
     SVGElement* mSVGElement;
 
-    // nsISMILAttr methods
+    // SMILAttr methods
     virtual nsresult ValueFromString(
         const nsAString& aStr,
         const mozilla::dom::SVGAnimationElement* aSrcElement, SMILValue& aValue,
         bool& aPreventCachingOfSandwich) const override;
     virtual SMILValue GetBaseValue() const override;
     virtual void ClearAnimValue() override;
     virtual nsresult SetAnimValue(const SMILValue& aValue) override;
   };
--- a/dom/svg/SVGClass.cpp
+++ b/dom/svg/SVGClass.cpp
@@ -96,17 +96,17 @@ void SVGClass::SetAnimValue(const nsAStr
   aSVGElement->DidAnimateClass();
 }
 
 void DOMAnimatedString::GetAnimVal(nsAString& aResult) {
   mSVGElement->FlushAnimations();
   mVal->GetAnimValue(aResult, mSVGElement);
 }
 
-UniquePtr<nsISMILAttr> SVGClass::ToSMILAttr(SVGElement* aSVGElement) {
+UniquePtr<SMILAttr> SVGClass::ToSMILAttr(SVGElement* aSVGElement) {
   return MakeUnique<SMILString>(this, aSVGElement);
 }
 
 nsresult SVGClass::SMILString::ValueFromString(
     const nsAString& aStr, const dom::SVGAnimationElement* /*aSrcElement*/,
     SMILValue& aValue, bool& aPreventCachingOfSandwich) const {
   SMILValue val(SMILStringType::Singleton());
 
--- a/dom/svg/SVGClass.h
+++ b/dom/svg/SVGClass.h
@@ -5,19 +5,19 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef __NS_SVGCLASS_H__
 #define __NS_SVGCLASS_H__
 
 #include "nsAutoPtr.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsError.h"
-#include "nsISMILAttr.h"
 #include "nsString.h"
 #include "mozilla/Attributes.h"
+#include "mozilla/SMILAttr.h"
 #include "mozilla/UniquePtr.h"
 
 namespace mozilla {
 
 class SMILValue;
 
 namespace dom {
 class SVGAnimatedString;
@@ -35,34 +35,34 @@ class SVGClass {
 
   void SetAnimValue(const nsAString& aValue, SVGElement* aSVGElement);
   void GetAnimValue(nsAString& aValue, const SVGElement* aSVGElement) const;
   bool IsAnimated() const { return !!mAnimVal; }
 
   already_AddRefed<mozilla::dom::SVGAnimatedString> ToDOMAnimatedString(
       SVGElement* aSVGElement);
 
-  mozilla::UniquePtr<nsISMILAttr> ToSMILAttr(SVGElement* aSVGElement);
+  mozilla::UniquePtr<SMILAttr> ToSMILAttr(SVGElement* aSVGElement);
 
  private:
   nsAutoPtr<nsString> mAnimVal;
 
  public:
-  struct SMILString : public nsISMILAttr {
+  struct SMILString : public SMILAttr {
    public:
     SMILString(SVGClass* aVal, SVGElement* aSVGElement)
         : mVal(aVal), mSVGElement(aSVGElement) {}
 
-    // These will stay alive because a nsISMILAttr only lives as long
+    // These will stay alive because a SMILAttr only lives as long
     // as the Compositing step, and DOM elements don't get a chance to
     // die during that.
     SVGClass* mVal;
     SVGElement* mSVGElement;
 
-    // nsISMILAttr methods
+    // SMILAttr methods
     virtual nsresult ValueFromString(
         const nsAString& aStr,
         const mozilla::dom::SVGAnimationElement* aSrcElement, SMILValue& aValue,
         bool& aPreventCachingOfSandwich) const override;
     virtual SMILValue GetBaseValue() const override;
     virtual void ClearAnimValue() override;
     virtual nsresult SetAnimValue(const SMILValue& aValue) override;
   };
--- a/dom/svg/SVGElement.cpp
+++ b/dom/svg/SVGElement.cpp
@@ -2140,18 +2140,18 @@ void SVGElement::RecompileScriptEventLis
     }
 
     nsAutoString value;
     GetAttr(attr, value);
     SetEventHandler(GetEventNameForAttr(attr), value, true);
   }
 }
 
-UniquePtr<nsISMILAttr> SVGElement::GetAnimatedAttr(int32_t aNamespaceID,
-                                                   nsAtom* aName) {
+UniquePtr<SMILAttr> SVGElement::GetAnimatedAttr(int32_t aNamespaceID,
+                                                nsAtom* aName) {
   if (aNamespaceID == kNameSpaceID_None) {
     // Transforms:
     if (GetTransformListAttrName() == aName) {
       // The transform attribute is being animated, so we must ensure that the
       // SVGAnimatedTransformList is/has been allocated:
       return GetAnimatedTransformList(DO_ALLOCATE)->ToSMILAttr(this);
     }
 
--- a/dom/svg/SVGElement.h
+++ b/dom/svg/SVGElement.h
@@ -272,18 +272,18 @@ class SVGElement : public SVGElementBase
    * that require the SVGAnimatedTransformList to be allocated and for this
    * method to return non-null must pass the DO_ALLOCATE flag.
    */
   virtual SVGAnimatedTransformList* GetAnimatedTransformList(
       uint32_t aFlags = 0) {
     return nullptr;
   }
 
-  mozilla::UniquePtr<nsISMILAttr> GetAnimatedAttr(int32_t aNamespaceID,
-                                                  nsAtom* aName) override;
+  mozilla::UniquePtr<SMILAttr> GetAnimatedAttr(int32_t aNamespaceID,
+                                               nsAtom* aName) override;
   void AnimationNeedsResample();
   void FlushAnimations();
 
   virtual void RecompileScriptEventListeners() override;
 
   void GetStringBaseValue(uint8_t aAttrEnum, nsAString& aResult) const;
   void SetStringBaseValue(uint8_t aAttrEnum, const nsAString& aValue);
 
--- a/dom/svg/SVGEnum.cpp
+++ b/dom/svg/SVGEnum.cpp
@@ -110,17 +110,17 @@ already_AddRefed<SVGAnimatedEnumeration>
 
   return domAnimatedEnum.forget();
 }
 
 SVGEnum::DOMAnimatedEnum::~DOMAnimatedEnum() {
   sSVGAnimatedEnumTearoffTable.RemoveTearoff(mVal);
 }
 
-UniquePtr<nsISMILAttr> SVGEnum::ToSMILAttr(SVGElement* aSVGElement) {
+UniquePtr<SMILAttr> SVGEnum::ToSMILAttr(SVGElement* aSVGElement) {
   return MakeUnique<SMILEnum>(this, aSVGElement);
 }
 
 nsresult SVGEnum::SMILEnum::ValueFromString(
     const nsAString& aStr, const SVGAnimationElement* /*aSrcElement*/,
     SMILValue& aValue, bool& aPreventCachingOfSandwich) const {
   nsAtom* valAtom = NS_GetStaticAtom(aStr);
   if (valAtom) {
--- a/dom/svg/SVGEnum.h
+++ b/dom/svg/SVGEnum.h
@@ -4,18 +4,18 @@
  * 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 __NS_SVGENUM_H__
 #define __NS_SVGENUM_H__
 
 #include "nsCycleCollectionParticipant.h"
 #include "nsError.h"
-#include "nsISMILAttr.h"
 #include "mozilla/Attributes.h"
+#include "mozilla/SMILAttr.h"
 #include "mozilla/UniquePtr.h"
 #include "mozilla/dom/SVGAnimatedEnumeration.h"
 #include "mozilla/dom/SVGElement.h"
 
 class nsAtom;
 
 namespace mozilla {
 
@@ -50,17 +50,17 @@ class SVGEnum {
 
   void SetAnimValue(uint16_t aValue, SVGElement* aSVGElement);
   uint16_t GetAnimValue() const { return mAnimVal; }
   bool IsExplicitlySet() const { return mIsAnimated || mIsBaseSet; }
 
   already_AddRefed<mozilla::dom::SVGAnimatedEnumeration> ToDOMAnimatedEnum(
       SVGElement* aSVGElement);
 
-  mozilla::UniquePtr<nsISMILAttr> ToSMILAttr(SVGElement* aSVGElement);
+  mozilla::UniquePtr<SMILAttr> ToSMILAttr(SVGElement* aSVGElement);
 
  private:
   SVGEnumValue mAnimVal;
   SVGEnumValue mBaseVal;
   uint8_t mAttrEnum;  // element specified tracking for attribute
   bool mIsAnimated;
   bool mIsBaseSet;
 
@@ -84,28 +84,28 @@ class SVGEnum {
       // Script may have modified animation parameters or timeline -- DOM
       // getters need to flush any resample requests to reflect these
       // modifications.
       mSVGElement->FlushAnimations();
       return mVal->GetAnimValue();
     }
   };
 
-  struct SMILEnum : public nsISMILAttr {
+  struct SMILEnum : public SMILAttr {
    public:
     SMILEnum(SVGEnum* aVal, SVGElement* aSVGElement)
         : mVal(aVal), mSVGElement(aSVGElement) {}
 
-    // These will stay alive because a nsISMILAttr only lives as long
+    // These will stay alive because a SMILAttr only lives as long
     // as the Compositing step, and DOM elements don't get a chance to
     // die during that.
     SVGEnum* mVal;
     SVGElement* mSVGElement;
 
-    // nsISMILAttr methods
+    // SMILAttr methods
     virtual nsresult ValueFromString(
         const nsAString& aStr,
         const mozilla::dom::SVGAnimationElement* aSrcElement, SMILValue& aValue,
         bool& aPreventCachingOfSandwich) const override;
     virtual SMILValue GetBaseValue() const override;
     virtual void ClearAnimValue() override;
     virtual nsresult SetAnimValue(const SMILValue& aValue) override;
   };
--- a/dom/svg/SVGInteger.cpp
+++ b/dom/svg/SVGInteger.cpp
@@ -83,17 +83,17 @@ already_AddRefed<SVGAnimatedInteger> SVG
 
   return domAnimatedInteger.forget();
 }
 
 SVGInteger::DOMAnimatedInteger::~DOMAnimatedInteger() {
   sSVGAnimatedIntegerTearoffTable.RemoveTearoff(mVal);
 }
 
-UniquePtr<nsISMILAttr> SVGInteger::ToSMILAttr(SVGElement *aSVGElement) {
+UniquePtr<SMILAttr> SVGInteger::ToSMILAttr(SVGElement *aSVGElement) {
   return MakeUnique<SMILInteger>(this, aSVGElement);
 }
 
 nsresult SVGInteger::SMILInteger::ValueFromString(
     const nsAString &aStr, const dom::SVGAnimationElement * /*aSrcElement*/,
     SMILValue &aValue, bool &aPreventCachingOfSandwich) const {
   int32_t val;
 
--- a/dom/svg/SVGInteger.h
+++ b/dom/svg/SVGInteger.h
@@ -5,20 +5,20 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef __NS_SVGINTEGER_H__
 #define __NS_SVGINTEGER_H__
 
 #include "nsCycleCollectionParticipant.h"
 #include "nsError.h"
 #include "SVGAnimatedInteger.h"
-#include "nsISMILAttr.h"
-#include "SVGElement.h"
 #include "mozilla/Attributes.h"
+#include "mozilla/SMILAttr.h"
 #include "mozilla/UniquePtr.h"
+#include "mozilla/dom/SVGElement.h"
 
 namespace mozilla {
 
 class SMILValue;
 
 namespace dom {
 class SVGAnimationElement;
 }  // namespace dom
@@ -47,17 +47,17 @@ class SVGInteger {
   // set (either by animation, or by taking on the base value which has been
   // explicitly set by markup or a DOM call), false otherwise.
   // If this returns false, the animated value is still valid, that is,
   // usable, and represents the default base value of the attribute.
   bool IsExplicitlySet() const { return mIsAnimated || mIsBaseSet; }
 
   already_AddRefed<mozilla::dom::SVGAnimatedInteger> ToDOMAnimatedInteger(
       SVGElement* aSVGElement);
-  mozilla::UniquePtr<nsISMILAttr> ToSMILAttr(SVGElement* aSVGElement);
+  mozilla::UniquePtr<SMILAttr> ToSMILAttr(SVGElement* aSVGElement);
 
  private:
   int32_t mAnimVal;
   int32_t mBaseVal;
   uint8_t mAttrEnum;  // element specified tracking for attribute
   bool mIsAnimated;
   bool mIsBaseSet;
 
@@ -77,28 +77,28 @@ class SVGInteger {
     // Script may have modified animation parameters or timeline -- DOM getters
     // need to flush any resample requests to reflect these modifications.
     virtual int32_t AnimVal() override {
       mSVGElement->FlushAnimations();
       return mVal->GetAnimValue();
     }
   };
 
-  struct SMILInteger : public nsISMILAttr {
+  struct SMILInteger : public SMILAttr {
    public:
     SMILInteger(SVGInteger* aVal, SVGElement* aSVGElement)
         : mVal(aVal), mSVGElement(aSVGElement) {}
 
-    // These will stay alive because a nsISMILAttr only lives as long
+    // These will stay alive because a SMILAttr only lives as long
     // as the Compositing step, and DOM elements don't get a chance to
     // die during that.
     SVGInteger* mVal;
     SVGElement* mSVGElement;
 
-    // nsISMILAttr methods
+    // SMILAttr methods
     virtual nsresult ValueFromString(
         const nsAString& aStr,
         const mozilla::dom::SVGAnimationElement* aSrcElement, SMILValue& aValue,
         bool& aPreventCachingOfSandwich) const override;
     virtual SMILValue GetBaseValue() const override;
     virtual void ClearAnimValue() override;
     virtual nsresult SetAnimValue(const SMILValue& aValue) override;
   };
--- a/dom/svg/SVGIntegerPair.cpp
+++ b/dom/svg/SVGIntegerPair.cpp
@@ -157,17 +157,17 @@ already_AddRefed<SVGAnimatedInteger> SVG
 SVGIntegerPair::DOMAnimatedInteger::~DOMAnimatedInteger() {
   if (mIndex == eFirst) {
     sSVGFirstAnimatedIntegerTearoffTable.RemoveTearoff(mVal);
   } else {
     sSVGSecondAnimatedIntegerTearoffTable.RemoveTearoff(mVal);
   }
 }
 
-UniquePtr<nsISMILAttr> SVGIntegerPair::ToSMILAttr(SVGElement* aSVGElement) {
+UniquePtr<SMILAttr> SVGIntegerPair::ToSMILAttr(SVGElement* aSVGElement) {
   return MakeUnique<SMILIntegerPair>(this, aSVGElement);
 }
 
 nsresult SVGIntegerPair::SMILIntegerPair::ValueFromString(
     const nsAString& aStr, const dom::SVGAnimationElement* /*aSrcElement*/,
     SMILValue& aValue, bool& aPreventCachingOfSandwich) const {
   int32_t values[2];
 
--- a/dom/svg/SVGIntegerPair.h
+++ b/dom/svg/SVGIntegerPair.h
@@ -4,18 +4,18 @@
  * 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 __NS_SVGINTEGERPAIR_H__
 #define __NS_SVGINTEGERPAIR_H__
 
 #include "nsCycleCollectionParticipant.h"
 #include "nsError.h"
-#include "nsISMILAttr.h"
 #include "mozilla/Attributes.h"
+#include "mozilla/SMILAttr.h"
 #include "mozilla/UniquePtr.h"
 #include "mozilla/dom/SVGAnimatedInteger.h"
 
 namespace mozilla {
 
 class SMILValue;
 
 namespace dom {
@@ -55,17 +55,17 @@ class SVGIntegerPair {
   // set (either by animation, or by taking on the base value which has been
   // explicitly set by markup or a DOM call), false otherwise.
   // If this returns false, the animated value is still valid, that is,
   // usable, and represents the default base value of the attribute.
   bool IsExplicitlySet() const { return mIsAnimated || mIsBaseSet; }
 
   already_AddRefed<mozilla::dom::SVGAnimatedInteger> ToDOMAnimatedInteger(
       PairIndex aIndex, SVGElement* aSVGElement);
-  mozilla::UniquePtr<nsISMILAttr> ToSMILAttr(SVGElement* aSVGElement);
+  mozilla::UniquePtr<SMILAttr> ToSMILAttr(SVGElement* aSVGElement);
 
  private:
   int32_t mAnimVal[2];
   int32_t mBaseVal[2];
   uint8_t mAttrEnum;  // element specified tracking for attribute
   bool mIsAnimated;
   bool mIsBaseSet;
 
@@ -89,28 +89,28 @@ class SVGIntegerPair {
     // Script may have modified animation parameters or timeline -- DOM getters
     // need to flush any resample requests to reflect these modifications.
     virtual int32_t AnimVal() override {
       mSVGElement->FlushAnimations();
       return mVal->GetAnimValue(mIndex);
     }
   };
 
-  struct SMILIntegerPair : public nsISMILAttr {
+  struct SMILIntegerPair : public SMILAttr {
    public:
     SMILIntegerPair(SVGIntegerPair* aVal, SVGElement* aSVGElement)
         : mVal(aVal), mSVGElement(aSVGElement) {}
 
-    // These will stay alive because a nsISMILAttr only lives as long
+    // These will stay alive because a SMILAttr only lives as long
     // as the Compositing step, and DOM elements don't get a chance to
     // die during that.
     SVGIntegerPair* mVal;
     SVGElement* mSVGElement;
 
-    // nsISMILAttr methods
+    // SMILAttr methods
     virtual nsresult ValueFromString(
         const nsAString& aStr,
         const mozilla::dom::SVGAnimationElement* aSrcElement, SMILValue& aValue,
         bool& aPreventCachingOfSandwich) const override;
     virtual SMILValue GetBaseValue() const override;
     virtual void ClearAnimValue() override;
     virtual nsresult SetAnimValue(const SMILValue& aValue) override;
   };
--- a/dom/svg/SVGMotionSMILAnimationFunction.cpp
+++ b/dom/svg/SVGMotionSMILAnimationFunction.cpp
@@ -99,24 +99,24 @@ bool SVGMotionSMILAnimationFunction::Uns
   } else {
     // Defer to superclass method
     return SMILAnimationFunction::UnsetAttr(aAttribute);
   }
 
   return true;
 }
 
-SMILAnimationFunction::nsSMILCalcMode
+SMILAnimationFunction::SMILCalcMode
 SVGMotionSMILAnimationFunction::GetCalcMode() const {
   const nsAttrValue* value = GetAttr(nsGkAtoms::calcMode);
   if (!value) {
     return CALC_PACED;  // animateMotion defaults to calcMode="paced"
   }
 
-  return nsSMILCalcMode(value->GetEnumValue());
+  return SMILCalcMode(value->GetEnumValue());
 }
 
 //----------------------------------------------------------------------
 // Helpers for GetValues
 
 /*
  * Returns the first <mpath> child of the given element
  */
@@ -287,17 +287,17 @@ bool SVGMotionSMILAnimationFunction::Gen
                                    aPath, curDist, mRotateType, mRotateAngle),
                                fallible)) {
       return false;
     }
   }
   return true;
 }
 
-nsresult SVGMotionSMILAnimationFunction::GetValues(const nsISMILAttr& aSMILAttr,
+nsresult SVGMotionSMILAnimationFunction::GetValues(const SMILAttr& aSMILAttr,
                                                    SMILValueArray& aResult) {
   if (mIsPathStale) {
     RebuildPathAndVertices(aSMILAttr.GetTargetNode());
   }
   MOZ_ASSERT(!mIsPathStale, "Forgot to clear 'is path stale' state");
 
   if (!mPath) {
     // This could be due to e.g. a parse error.
--- a/dom/svg/SVGMotionSMILAnimationFunction.h
+++ b/dom/svg/SVGMotionSMILAnimationFunction.h
@@ -5,26 +5,26 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef MOZILLA_SVGMOTIONSMILANIMATIONFUNCTION_H_
 #define MOZILLA_SVGMOTIONSMILANIMATIONFUNCTION_H_
 
 #include "mozilla/gfx/2D.h"
 #include "mozilla/RefPtr.h"
 #include "mozilla/SMILAnimationFunction.h"
+#include "SVGMotionSMILType.h"
 #include "nsTArray.h"
-#include "SVGMotionSMILType.h"  // for RotateType
 
 class nsAttrValue;
 class nsAtom;
 class nsIContent;
-class nsISMILAttr;
 
 namespace mozilla {
 
+class SMILAttr;
 class SMILValue;
 
 namespace dom {
 class SVGMPathElement;
 }  // namespace dom
 
 //----------------------------------------------------------------------
 // SVGMotionSMILAnimationFunction
@@ -56,18 +56,18 @@ class SVGMotionSMILAnimationFunction fin
     ePathSourceType_None,    // uninitialized or not applicable
     ePathSourceType_ByAttr,  // by or from-by animation
     ePathSourceType_ToAttr,  // to or from-to animation
     ePathSourceType_ValuesAttr,
     ePathSourceType_PathAttr,
     ePathSourceType_Mpath
   };
 
-  virtual nsSMILCalcMode GetCalcMode() const override;
-  virtual nsresult GetValues(const nsISMILAttr& aSMILAttr,
+  virtual SMILCalcMode GetCalcMode() const override;
+  virtual nsresult GetValues(const SMILAttr& aSMILAttr,
                              SMILValueArray& aResult) override;
   virtual void CheckValueListDependentAttrs(uint32_t aNumValues) override;
 
   virtual bool IsToAnimation() const override;
 
   void CheckKeyPoints();
   nsresult SetKeyPoints(const nsAString& aKeyPoints, nsAttrValue& aResult);
   void UnsetKeyPoints();
--- a/dom/svg/SVGMotionSMILAttr.cpp
+++ b/dom/svg/SVGMotionSMILAttr.cpp
@@ -16,17 +16,17 @@
 #include "gfx2DGlue.h"
 
 namespace mozilla {
 
 nsresult SVGMotionSMILAttr::ValueFromString(
     const nsAString& aStr, const dom::SVGAnimationElement* aSrcElement,
     SMILValue& aValue, bool& aPreventCachingOfSandwich) const {
   MOZ_ASSERT_UNREACHABLE(
-      "Shouldn't using nsISMILAttr::ValueFromString for "
+      "Shouldn't using SMILAttr::ValueFromString for "
       "parsing animateMotion's SMIL values.");
   return NS_ERROR_FAILURE;
 }
 
 SMILValue SVGMotionSMILAttr::GetBaseValue() const {
   return SMILValue(&SVGMotionSMILType::sSingleton);
 }
 
--- a/dom/svg/SVGMotionSMILAttr.h
+++ b/dom/svg/SVGMotionSMILAttr.h
@@ -5,42 +5,42 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /* representation of a dummy attribute targeted by <animateMotion> element */
 
 #ifndef MOZILLA_SVGMOTIONSMILATTR_H_
 #define MOZILLA_SVGMOTIONSMILATTR_H_
 
 #include "mozilla/Attributes.h"
-#include "nsISMILAttr.h"
+#include "mozilla/SMILAttr.h"
 
 class nsIContent;
 
 namespace mozilla {
 
 class SMILValue;
 
 namespace dom {
 class SVGAnimationElement;
 class SVGElement;
 }  // namespace dom
 
 /**
- * SVGMotionSMILAttr: Implements the nsISMILAttr interface for SMIL animations
+ * SVGMotionSMILAttr: Implements the SMILAttr interface for SMIL animations
  * from <animateMotion>.
  *
  * NOTE: Even though there's technically no "motion" attribute, we behave in
  * many ways as if there were, for simplicity.
  */
-class SVGMotionSMILAttr : public nsISMILAttr {
+class SVGMotionSMILAttr : public SMILAttr {
  public:
   explicit SVGMotionSMILAttr(dom::SVGElement* aSVGElement)
       : mSVGElement(aSVGElement) {}
 
-  // nsISMILAttr methods
+  // SMILAttr methods
   virtual nsresult ValueFromString(
       const nsAString& aStr, const dom::SVGAnimationElement* aSrcElement,
       SMILValue& aValue, bool& aPreventCachingOfSandwich) const override;
   virtual SMILValue GetBaseValue() const override;
   virtual nsresult SetAnimValue(const SMILValue& aValue) override;
   virtual void ClearAnimValue() override;
   virtual const nsIContent* GetTargetNode() const override;
 
--- a/dom/svg/SVGNumberPair.cpp
+++ b/dom/svg/SVGNumberPair.cpp
@@ -149,17 +149,17 @@ already_AddRefed<SVGAnimatedNumber> SVGN
 SVGNumberPair::DOMAnimatedNumber::~DOMAnimatedNumber() {
   if (mIndex == eFirst) {
     sSVGFirstAnimatedNumberTearoffTable.RemoveTearoff(mVal);
   } else {
     sSVGSecondAnimatedNumberTearoffTable.RemoveTearoff(mVal);
   }
 }
 
-UniquePtr<nsISMILAttr> SVGNumberPair::ToSMILAttr(SVGElement* aSVGElement) {
+UniquePtr<SMILAttr> SVGNumberPair::ToSMILAttr(SVGElement* aSVGElement) {
   return MakeUnique<SMILNumberPair>(this, aSVGElement);
 }
 
 nsresult SVGNumberPair::SMILNumberPair::ValueFromString(
     const nsAString& aStr, const dom::SVGAnimationElement* /*aSrcElement*/,
     SMILValue& aValue, bool& aPreventCachingOfSandwich) const {
   float values[2];
 
--- a/dom/svg/SVGNumberPair.h
+++ b/dom/svg/SVGNumberPair.h
@@ -4,21 +4,21 @@
  * 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 __NS_SVGNUMBERPAIR_H__
 #define __NS_SVGNUMBERPAIR_H__
 
 #include "nsCycleCollectionParticipant.h"
 #include "nsError.h"
-#include "nsISMILAttr.h"
 #include "nsMathUtils.h"
 #include "mozilla/dom/SVGAnimatedNumber.h"
 #include "mozilla/Attributes.h"
 #include "mozilla/FloatingPoint.h"
+#include "mozilla/SMILAttr.h"
 #include "mozilla/UniquePtr.h"
 
 namespace mozilla {
 
 class SMILValue;
 
 namespace dom {
 class SVGAnimationElement;
@@ -56,17 +56,17 @@ class SVGNumberPair {
   // set (either by animation, or by taking on the base value which has been
   // explicitly set by markup or a DOM call), false otherwise.
   // If this returns false, the animated value is still valid, that is,
   // usable, and represents the default base value of the attribute.
   bool IsExplicitlySet() const { return mIsAnimated || mIsBaseSet; }
 
   already_AddRefed<mozilla::dom::SVGAnimatedNumber> ToDOMAnimatedNumber(
       PairIndex aIndex, SVGElement* aSVGElement);
-  mozilla::UniquePtr<nsISMILAttr> ToSMILAttr(SVGElement* aSVGElement);
+  mozilla::UniquePtr<SMILAttr> ToSMILAttr(SVGElement* aSVGElement);
 
  private:
   float mAnimVal[2];
   float mBaseVal[2];
   uint8_t mAttrEnum;  // element specified tracking for attribute
   bool mIsAnimated;
   bool mIsBaseSet;
 
@@ -91,28 +91,28 @@ class SVGNumberPair {
     // Script may have modified animation parameters or timeline -- DOM getters
     // need to flush any resample requests to reflect these modifications.
     virtual float AnimVal() override {
       mSVGElement->FlushAnimations();
       return mVal->GetAnimValue(mIndex);
     }
   };
 
-  struct SMILNumberPair : public nsISMILAttr {
+  struct SMILNumberPair : public SMILAttr {
    public:
     SMILNumberPair(SVGNumberPair* aVal, SVGElement* aSVGElement)
         : mVal(aVal), mSVGElement(aSVGElement) {}
 
-    // These will stay alive because a nsISMILAttr only lives as long
+    // These will stay alive because a SMILAttr only lives as long
     // as the Compositing step, and DOM elements don't get a chance to
     // die during that.
     SVGNumberPair* mVal;
     SVGElement* mSVGElement;
 
-    // nsISMILAttr methods
+    // SMILAttr methods
     virtual nsresult ValueFromString(
         const nsAString& aStr,
         const mozilla::dom::SVGAnimationElement* aSrcElement, SMILValue& aValue,
         bool& aPreventCachingOfSandwich) const override;
     virtual SMILValue GetBaseValue() const override;
     virtual void ClearAnimValue() override;
     virtual nsresult SetAnimValue(const SMILValue& aValue) override;
   };
--- a/dom/svg/SVGPathData.h
+++ b/dom/svg/SVGPathData.h
@@ -113,17 +113,17 @@ class SVGPathData {
   /**
    * Returns the number of *floats* in the encoding array, and NOT the number
    * of segments encoded in this object. (For that, see CountItems() above.)
    */
   uint32_t Length() const { return mData.Length(); }
 
   const float& operator[](uint32_t aIndex) const { return mData[aIndex]; }
 
-  // Used by nsSMILCompositor to check if the cached base val is out of date
+  // Used by SMILCompositor to check if the cached base val is out of date
   bool operator==(const SVGPathData& rhs) const {
     // We use memcmp so that we don't need to worry that the data encoded in
     // the first float may have the same bit pattern as a NaN.
     return mData.Length() == rhs.mData.Length() &&
            memcmp(mData.Elements(), rhs.mData.Elements(),
                   mData.Length() * sizeof(float)) == 0;
   }
 
--- a/dom/svg/SVGSVGElement.cpp
+++ b/dom/svg/SVGSVGElement.cpp
@@ -225,17 +225,17 @@ float SVGSVGElement::GetCurrentTimeAsFlo
 
 void SVGSVGElement::SetCurrentTime(float seconds) {
   if (mTimedDocumentRoot) {
     // Make sure the timegraph is up-to-date
     FlushAnimations();
     double fMilliseconds = double(seconds) * PR_MSEC_PER_SEC;
     // Round to nearest whole number before converting, to avoid precision
     // errors
-    nsSMILTime lMilliseconds = int64_t(NS_round(fMilliseconds));
+    SMILTime lMilliseconds = int64_t(NS_round(fMilliseconds));
     mTimedDocumentRoot->SetCurrentTime(lMilliseconds);
     AnimationNeedsResample();
     // Trigger synchronous sample now, to:
     //  - Make sure we get an up-to-date paint after this method
     //  - re-enable event firing (it got disabled during seeking, and it
     //  doesn't get re-enabled until the first sample after the seek -- so
     //  let's make that happen now.)
     FlushAnimations();
@@ -521,20 +521,18 @@ void SVGSVGElement::InvalidateTransformN
 }
 
 SVGElement::EnumAttributesInfo SVGSVGElement::GetEnumInfo() {
   return EnumAttributesInfo(mEnumAttributes, sEnumInfo, ArrayLength(sEnumInfo));
 }
 
 void SVGSVGElement::SetImageOverridePreserveAspectRatio(
     const SVGPreserveAspectRatio& aPAR) {
-#ifdef DEBUG
   MOZ_ASSERT(OwnerDoc()->IsBeingUsedAsImage(),
              "should only override preserveAspectRatio in images");
-#endif
 
   bool hasViewBoxRect = HasViewBoxRect();
   if (!hasViewBoxRect && ShouldSynthesizeViewBox()) {
     // My non-<svg:image> clients will have been painting me with a synthesized
     // viewBox, but my <svg:image> client that's about to paint me now does NOT
     // want that.  Need to tell ourselves to flush our transform.
     mImageNeedsTransformInvalidation = true;
   }
@@ -544,20 +542,18 @@ void SVGSVGElement::SetImageOverridePres
   }
 
   if (SetPreserveAspectRatioProperty(aPAR)) {
     mImageNeedsTransformInvalidation = true;
   }
 }
 
 void SVGSVGElement::ClearImageOverridePreserveAspectRatio() {
-#ifdef DEBUG
   MOZ_ASSERT(OwnerDoc()->IsBeingUsedAsImage(),
              "should only override image preserveAspectRatio in images");
-#endif
 
   if (!HasViewBoxRect() && ShouldSynthesizeViewBox()) {
     // My non-<svg:image> clients will want to paint me with a synthesized
     // viewBox, but my <svg:image> client that just painted me did NOT
     // use that.  Need to tell ourselves to flush our transform.
     mImageNeedsTransformInvalidation = true;
   }
 
--- a/dom/svg/SVGString.cpp
+++ b/dom/svg/SVGString.cpp
@@ -84,17 +84,17 @@ already_AddRefed<SVGAnimatedString> SVGS
 
   return domAnimatedString.forget();
 }
 
 SVGString::DOMAnimatedString::~DOMAnimatedString() {
   SVGAnimatedStringTearoffTable().RemoveTearoff(mVal);
 }
 
-UniquePtr<nsISMILAttr> SVGString::ToSMILAttr(SVGElement* aSVGElement) {
+UniquePtr<SMILAttr> SVGString::ToSMILAttr(SVGElement* aSVGElement) {
   return MakeUnique<SMILString>(this, aSVGElement);
 }
 
 nsresult SVGString::SMILString::ValueFromString(
     const nsAString& aStr, const dom::SVGAnimationElement* /*aSrcElement*/,
     SMILValue& aValue, bool& aPreventCachingOfSandwich) const {
   SMILValue val(SMILStringType::Singleton());
 
--- a/dom/svg/SVGString.h
+++ b/dom/svg/SVGString.h
@@ -45,17 +45,17 @@ class SVGString {
   // explicitly set by markup or a DOM call), false otherwise.
   // If this returns false, the animated value is still valid, that is,
   // usable, and represents the default base value of the attribute.
   bool IsExplicitlySet() const { return !!mAnimVal || mIsBaseSet; }
 
   already_AddRefed<mozilla::dom::SVGAnimatedString> ToDOMAnimatedString(
       SVGElement* aSVGElement);
 
-  mozilla::UniquePtr<nsISMILAttr> ToSMILAttr(SVGElement* aSVGElement);
+  mozilla::UniquePtr<SMILAttr> ToSMILAttr(SVGElement* aSVGElement);
 
  private:
   nsAutoPtr<nsString> mAnimVal;
   uint8_t mAttrEnum;  // element specified tracking for attribute
   bool mIsBaseSet;
 
  public:
   struct DOMAnimatedString final : public mozilla::dom::SVGAnimatedString {
@@ -78,28 +78,28 @@ class SVGString {
     void GetAnimVal(nsAString& aResult) override {
       mSVGElement->FlushAnimations();
       mVal->GetAnimValue(aResult, mSVGElement);
     }
 
    private:
     virtual ~DOMAnimatedString();
   };
-  struct SMILString : public nsISMILAttr {
+  struct SMILString : public SMILAttr {
    public:
     SMILString(SVGString* aVal, SVGElement* aSVGElement)
         : mVal(aVal), mSVGElement(aSVGElement) {}
 
-    // These will stay alive because a nsISMILAttr only lives as long
+    // These will stay alive because a SMILAttr only lives as long
     // as the Compositing step, and DOM elements don't get a chance to
     // die during that.
     SVGString* mVal;
     SVGElement* mSVGElement;
 
-    // nsISMILAttr methods
+    // SMILAttr methods
     virtual nsresult ValueFromString(
         const nsAString& aStr,
         const mozilla::dom::SVGAnimationElement* aSrcElement, SMILValue& aValue,
         bool& aPreventCachingOfSandwich) const override;
     virtual SMILValue GetBaseValue() const override;
     virtual void ClearAnimValue() override;
     virtual nsresult SetAnimValue(const SMILValue& aValue) override;
   };
--- a/dom/svg/SVGViewBox.cpp
+++ b/dom/svg/SVGViewBox.cpp
@@ -262,17 +262,17 @@ void SVGViewBox::DOMBaseVal::SetWidth(fl
 }
 
 void SVGViewBox::DOMBaseVal::SetHeight(float aHeight, ErrorResult& aRv) {
   SVGViewBoxRect rect = mVal->GetBaseValue();
   rect.height = aHeight;
   mVal->SetBaseValue(rect, mSVGElement);
 }
 
-UniquePtr<nsISMILAttr> SVGViewBox::ToSMILAttr(SVGElement* aSVGElement) {
+UniquePtr<SMILAttr> SVGViewBox::ToSMILAttr(SVGElement* aSVGElement) {
   return MakeUnique<SMILViewBox>(this, aSVGElement);
 }
 
 nsresult SVGViewBox::SMILViewBox ::ValueFromString(
     const nsAString& aStr, const dom::SVGAnimationElement* /*aSrcElement*/,
     SMILValue& aValue, bool& aPreventCachingOfSandwich) const {
   SVGViewBoxRect viewBox;
   nsresult res = SVGViewBoxRect::FromString(aStr, &viewBox);
--- a/dom/svg/SVGViewBox.h
+++ b/dom/svg/SVGViewBox.h
@@ -7,17 +7,17 @@
 #ifndef __NS_SVGVIEWBOX_H__
 #define __NS_SVGVIEWBOX_H__
 
 #include "nsAutoPtr.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsError.h"
 #include "SVGAttrTearoffTable.h"
 #include "mozilla/Attributes.h"
-#include "nsISMILAttr.h"
+#include "mozilla/SMILAttr.h"
 #include "mozilla/UniquePtr.h"
 #include "mozilla/dom/SVGAnimatedRect.h"
 #include "mozilla/dom/SVGIRect.h"
 
 namespace mozilla {
 
 class SMILValue;
 
@@ -87,17 +87,17 @@ class SVGViewBox {
       SVGElement* aSVGElement);
 
   already_AddRefed<mozilla::dom::SVGIRect> ToDOMBaseVal(
       SVGElement* aSVGElement);
 
   already_AddRefed<mozilla::dom::SVGIRect> ToDOMAnimVal(
       SVGElement* aSVGElement);
 
-  mozilla::UniquePtr<nsISMILAttr> ToSMILAttr(SVGElement* aSVGElement);
+  mozilla::UniquePtr<SMILAttr> ToSMILAttr(SVGElement* aSVGElement);
 
  private:
   SVGViewBoxRect mBaseVal;
   nsAutoPtr<SVGViewBoxRect> mAnimVal;
   bool mHasBaseVal;
 
  public:
   struct DOMBaseVal final : public mozilla::dom::SVGIRect {
@@ -178,28 +178,28 @@ class SVGViewBox {
     }
 
     virtual nsIContent* GetParentObject() const override { return mSVGElement; }
 
    private:
     virtual ~DOMAnimVal();
   };
 
-  struct SMILViewBox : public nsISMILAttr {
+  struct SMILViewBox : public SMILAttr {
    public:
     SMILViewBox(SVGViewBox* aVal, SVGElement* aSVGElement)
         : mVal(aVal), mSVGElement(aSVGElement) {}
 
-    // These will stay alive because a nsISMILAttr only lives as long
+    // These will stay alive because a SMILAttr only lives as long
     // as the Compositing step, and DOM elements don't get a chance to
     // die during that.
     SVGViewBox* mVal;
     SVGElement* mSVGElement;
 
-    // nsISMILAttr methods
+    // SMILAttr methods
     virtual nsresult ValueFromString(
         const nsAString& aStr,
         const mozilla::dom::SVGAnimationElement* aSrcElement, SMILValue& aValue,
         bool& aPreventCachingOfSandwich) const override;
     virtual SMILValue GetBaseValue() const override;
     virtual void ClearAnimValue() override;
     virtual nsresult SetAnimValue(const SMILValue& aValue) override;
   };
--- a/dom/svg/nsSVGLength2.cpp
+++ b/dom/svg/nsSVGLength2.cpp
@@ -409,17 +409,17 @@ already_AddRefed<SVGAnimatedLength> nsSV
 
   return svgAnimatedLength.forget();
 }
 
 SVGAnimatedLength::~SVGAnimatedLength() {
   sSVGAnimatedLengthTearoffTable.RemoveTearoff(mVal);
 }
 
-UniquePtr<nsISMILAttr> nsSVGLength2::ToSMILAttr(SVGElement* aSVGElement) {
+UniquePtr<SMILAttr> nsSVGLength2::ToSMILAttr(SVGElement* aSVGElement) {
   return MakeUnique<SMILLength>(this, aSVGElement);
 }
 
 nsresult nsSVGLength2::SMILLength::ValueFromString(
     const nsAString& aStr, const SVGAnimationElement* /*aSrcElement*/,
     SMILValue& aValue, bool& aPreventCachingOfSandwich) const {
   float value;
   uint16_t unitType;
--- a/dom/svg/nsSVGLength2.h
+++ b/dom/svg/nsSVGLength2.h
@@ -3,25 +3,25 @@
 /* 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 __NS_SVGLENGTH2_H__
 #define __NS_SVGLENGTH2_H__
 
 #include "mozilla/Attributes.h"
+#include "mozilla/SMILAttr.h"
 #include "mozilla/SVGContentUtils.h"
 #include "mozilla/UniquePtr.h"
 #include "mozilla/dom/SVGLengthBinding.h"
 #include "mozilla/dom/SVGElement.h"
 #include "mozilla/gfx/Rect.h"
 #include "nsCoord.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsError.h"
-#include "nsISMILAttr.h"
 #include "nsMathUtils.h"
 
 class nsIFrame;
 
 namespace mozilla {
 
 class SMILValue;
 
@@ -87,16 +87,18 @@ class NonSVGFrameUserSpaceMetrics : publ
 
 class nsSVGLength2 {
   friend class mozilla::dom::SVGAnimatedLength;
   friend class mozilla::dom::DOMSVGLength;
   typedef mozilla::dom::DOMSVGLength DOMSVGLength;
   typedef mozilla::dom::SVGElement SVGElement;
   typedef mozilla::dom::SVGViewportElement SVGViewportElement;
   typedef mozilla::dom::UserSpaceMetrics UserSpaceMetrics;
+  typedef mozilla::SMILAttr SMILAttr;
+  typedef mozilla::SMILValue SMILValue;
   typedef mozilla::SVGContentUtils SVGContentUtils;
 
  public:
   void Init(uint8_t aCtxType = mozilla::SVGContentUtils::XY,
             uint8_t aAttrEnum = 0xff, float aValue = 0,
             uint8_t aUnitType =
                 mozilla::dom::SVGLength_Binding::SVG_LENGTHTYPE_NUMBER) {
     mAnimVal = mBaseVal = aValue;
@@ -157,17 +159,17 @@ class nsSVGLength2 {
   // explicitly set by markup or a DOM call), false otherwise.
   // If this returns false, the animated value is still valid, that is,
   // usable, and represents the default base value of the attribute.
   bool IsExplicitlySet() const { return mIsAnimated || mIsBaseSet; }
 
   already_AddRefed<mozilla::dom::SVGAnimatedLength> ToDOMAnimatedLength(
       SVGElement* aSVGElement);
 
-  mozilla::UniquePtr<nsISMILAttr> ToSMILAttr(SVGElement* aSVGElement);
+  mozilla::UniquePtr<SMILAttr> ToSMILAttr(SVGElement* aSVGElement);
 
  private:
   float mAnimVal;
   float mBaseVal;
   uint8_t mSpecifiedUnitType;
   uint8_t mAttrEnum;  // element specified tracking for attribute
   uint8_t mCtxType;   // X, Y or Unspecified
   bool mIsAnimated : 1;
@@ -193,28 +195,28 @@ class nsSVGLength2 {
   void SetAnimValueInSpecifiedUnits(float aValue, SVGElement* aSVGElement);
   nsresult NewValueSpecifiedUnits(uint16_t aUnitType, float aValue,
                                   SVGElement* aSVGElement);
   nsresult ConvertToSpecifiedUnits(uint16_t aUnitType, SVGElement* aSVGElement);
   already_AddRefed<DOMSVGLength> ToDOMBaseVal(SVGElement* aSVGElement);
   already_AddRefed<DOMSVGLength> ToDOMAnimVal(SVGElement* aSVGElement);
 
  public:
-  struct SMILLength : public nsISMILAttr {
+  struct SMILLength : public SMILAttr {
    public:
     SMILLength(nsSVGLength2* aVal, SVGElement* aSVGElement)
         : mVal(aVal), mSVGElement(aSVGElement) {}
 
-    // These will stay alive because a nsISMILAttr only lives as long
+    // These will stay alive because a SMILAttr only lives as long
     // as the Compositing step, and DOM elements don't get a chance to
     // die during that.
     nsSVGLength2* mVal;
     SVGElement* mSVGElement;
 
-    // nsISMILAttr methods
+    // SMILAttr methods
     virtual nsresult ValueFromString(
         const nsAString& aStr,
         const mozilla::dom::SVGAnimationElement* aSrcElement, SMILValue& aValue,
         bool& aPreventCachingOfSandwich) const override;
     virtual SMILValue GetBaseValue() const override;
     virtual void ClearAnimValue() override;
     virtual nsresult SetAnimValue(const SMILValue& aValue) override;
   };
--- a/dom/svg/nsSVGNumber2.cpp
+++ b/dom/svg/nsSVGNumber2.cpp
@@ -106,17 +106,17 @@ already_AddRefed<SVGAnimatedNumber> nsSV
 
   return domAnimatedNumber.forget();
 }
 
 nsSVGNumber2::DOMAnimatedNumber::~DOMAnimatedNumber() {
   sSVGAnimatedNumberTearoffTable.RemoveTearoff(mVal);
 }
 
-UniquePtr<nsISMILAttr> nsSVGNumber2::ToSMILAttr(SVGElement* aSVGElement) {
+UniquePtr<SMILAttr> nsSVGNumber2::ToSMILAttr(SVGElement* aSVGElement) {
   return MakeUnique<SMILNumber>(this, aSVGElement);
 }
 
 nsresult nsSVGNumber2::SMILNumber::ValueFromString(
     const nsAString& aStr,
     const mozilla::dom::SVGAnimationElement* /*aSrcElement*/, SMILValue& aValue,
     bool& aPreventCachingOfSandwich) const {
   float value;
--- a/dom/svg/nsSVGNumber2.h
+++ b/dom/svg/nsSVGNumber2.h
@@ -4,35 +4,37 @@
  * 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 __NS_SVGNUMBER2_H__
 #define __NS_SVGNUMBER2_H__
 
 #include "nsCycleCollectionParticipant.h"
 #include "nsError.h"
-#include "nsISMILAttr.h"
 #include "nsMathUtils.h"
-#include "SVGElement.h"
 #include "mozilla/Attributes.h"
 #include "mozilla/FloatingPoint.h"
+#include "mozilla/SMILAttr.h"
+#include "mozilla/UniquePtr.h"
 #include "mozilla/dom/SVGAnimatedNumber.h"
-#include "mozilla/UniquePtr.h"
+#include "mozilla/dom/SVGElement.h"
 
 namespace mozilla {
 
 class SMILValue;
 
 namespace dom {
 class SVGAnimationElement;
 }  // namespace dom
 }  // namespace mozilla
 
 class nsSVGNumber2 {
  public:
+  typedef mozilla::SMILAttr SMILAttr;
+  typedef mozilla::SMILValue SMILValue;
   typedef mozilla::dom::SVGElement SVGElement;
 
   void Init(uint8_t aAttrEnum = 0xff, float aValue = 0) {
     mAnimVal = mBaseVal = aValue;
     mAttrEnum = aAttrEnum;
     mIsAnimated = false;
     mIsBaseSet = false;
   }
@@ -49,17 +51,17 @@ class nsSVGNumber2 {
   // set (either by animation, or by taking on the base value which has been
   // explicitly set by markup or a DOM call), false otherwise.
   // If this returns false, the animated value is still valid, that is,
   // usable, and represents the default base value of the attribute.
   bool IsExplicitlySet() const { return mIsAnimated || mIsBaseSet; }
 
   already_AddRefed<mozilla::dom::SVGAnimatedNumber> ToDOMAnimatedNumber(
       SVGElement* aSVGElement);
-  mozilla::UniquePtr<nsISMILAttr> ToSMILAttr(SVGElement* aSVGElement);
+  mozilla::UniquePtr<SMILAttr> ToSMILAttr(SVGElement* aSVGElement);
 
  private:
   float mAnimVal;
   float mBaseVal;
   uint8_t mAttrEnum;  // element specified tracking for attribute
   bool mIsAnimated;
   bool mIsBaseSet;
 
@@ -80,28 +82,28 @@ class nsSVGNumber2 {
     // Script may have modified animation parameters or timeline -- DOM getters
     // need to flush any resample requests to reflect these modifications.
     virtual float AnimVal() override {
       mSVGElement->FlushAnimations();
       return mVal->GetAnimValue();
     }
   };
 
-  struct SMILNumber : public nsISMILAttr {
+  struct SMILNumber : public SMILAttr {
    public:
     SMILNumber(nsSVGNumber2* aVal, SVGElement* aSVGElement)
         : mVal(aVal), mSVGElement(aSVGElement) {}
 
-    // These will stay alive because a nsISMILAttr only lives as long
+    // These will stay alive because a SMILAttr only lives as long
     // as the Compositing step, and DOM elements don't get a chance to
     // die during that.
     nsSVGNumber2* mVal;
     SVGElement* mSVGElement;
 
-    // nsISMILAttr methods
+    // SMILAttr methods
     virtual nsresult ValueFromString(
         const nsAString& aStr,
         const mozilla::dom::SVGAnimationElement* aSrcElement, SMILValue& aValue,
         bool& aPreventCachingOfSandwich) const override;
     virtual SMILValue GetBaseValue() const override;
     virtual void ClearAnimValue() override;
     virtual nsresult SetAnimValue(const SMILValue& aValue) override;
   };
--- a/gfx/2d/DrawTargetD2D1.cpp
+++ b/gfx/2d/DrawTargetD2D1.cpp
@@ -40,17 +40,17 @@ RefPtr<ID2D1Factory1> D2DFactory() { ret
 
 DrawTargetD2D1::DrawTargetD2D1()
     : mPushedLayers(1),
       mSnapshotLock(make_shared<Mutex>("DrawTargetD2D1::mSnapshotLock")),
       mUsedCommandListsSincePurge(0),
       mTransformedGlyphsSinceLastPurge(0),
       mComplexBlendsWithListInList(0),
       mDeviceSeq(0),
-      mIsInitialized(false) {}
+      mInitState(InitState::Uninitialized) {}
 
 DrawTargetD2D1::~DrawTargetD2D1() {
   PopAllClips();
 
   if (mSnapshot) {
     MutexAutoLock lock(*mSnapshotLock);
     // We may hold the only reference. MarkIndependent will clear mSnapshot;
     // keep the snapshot object alive so it doesn't get destroyed while
@@ -85,17 +85,17 @@ DrawTargetD2D1::~DrawTargetD2D1() {
       (*iter)->mDependentTargets.erase(this);
     }
   }
 }
 
 bool DrawTargetD2D1::IsValid() const {
   if (NS_IsMainThread()) {
     // Uninitialized DTs are considered valid.
-    return !mIsInitialized || mDC;
+    return mInitState != InitState::Failure;
   } else {
     return const_cast<DrawTargetD2D1 *>(this)->EnsureInitialized();
   }
 }
 
 already_AddRefed<SourceSurface> DrawTargetD2D1::Snapshot() {
   if (!EnsureInitialized()) {
     return nullptr;
@@ -1310,22 +1310,22 @@ void DrawTargetD2D1::FlushInternal(bool 
   for (TargetSet::iterator iter = mDependingOnTargets.begin();
        iter != mDependingOnTargets.end(); iter++) {
     (*iter)->mDependentTargets.erase(this);
   }
   mDependingOnTargets.clear();
 }
 
 bool DrawTargetD2D1::EnsureInitialized() {
-  if (mIsInitialized) {
-    return !!mDC;
+  if (mInitState != InitState::Uninitialized) {
+    return mInitState == InitState::Success;
   }
 
   // Don't retry.
-  mIsInitialized = true;
+  mInitState = InitState::Failure;
 
   HRESULT hr;
 
   RefPtr<ID2D1Device> device = Factory::GetD2D1Device(&mDeviceSeq);
   if (!device) {
     gfxCriticalNote << "[D2D1.1] Failed to obtain a device for "
                        "DrawTargetD2D1::EnsureInitialized().";
     return false;
@@ -1395,16 +1395,18 @@ bool DrawTargetD2D1::EnsureInitialized()
   mDC->BeginDraw();
 
   CurrentLayer().mIsOpaque = mFormat == SurfaceFormat::B8G8R8X8;
 
   if (!mSurface) {
     mDC->Clear();
   }
 
+  mInitState = InitState::Success;
+
   return true;
 }
 
 void DrawTargetD2D1::MarkChanged() {
   if (mSnapshot) {
     MutexAutoLock lock(*mSnapshotLock);
     if (mSnapshot->hasOneRef()) {
       // Just destroy it, since no-one else knows about it.
--- a/gfx/2d/DrawTargetD2D1.h
+++ b/gfx/2d/DrawTargetD2D1.h
@@ -313,16 +313,21 @@ class DrawTargetD2D1 : public DrawTarget
   // This value is uesed to verify if the DrawTarget is created by a stale
   // device.
   uint32_t mDeviceSeq;
 
   // List of effects we use
   bool EnsureLuminanceEffect();
   RefPtr<ID2D1Effect> mLuminanceEffect;
 
-  bool mIsInitialized;
+  enum class InitState {
+    Uninitialized,
+    Success,
+    Failure
+  };
+  InitState mInitState;
   RefPtr<IDXGISurface> mSurface;
 };
 
 }  // namespace gfx
 }  // namespace mozilla
 
 #endif /* MOZILLA_GFX_DRAWTARGETD2D_H_ */
--- a/gfx/wr/wrench/reftests/border/reftest.list
+++ b/gfx/wr/wrench/reftests/border/reftest.list
@@ -2,17 +2,17 @@ platform(linux,mac) == border-clamp-corn
 == border-gradient-simple.yaml border-gradient-simple-ref.yaml
 platform(linux,mac) == border-gradient-nine-patch.yaml border-gradient-nine-patch.png
 == border-radial-gradient-simple.yaml border-radial-gradient-simple-ref.yaml
 platform(linux,mac) == border-radial-gradient-nine-patch.yaml border-radial-gradient-nine-patch.png
 == border-radii.yaml border-radii.png
 == border-none.yaml border-none-ref.yaml
 == border-invisible.yaml border-invisible-ref.yaml
 platform(linux,mac) == border-suite.yaml border-suite.png
-platform(linux,mac) fuzzy(1,57) == border-suite-2.yaml border-suite-2.png
+platform(linux,mac) fuzzy(8,8) == border-suite-2.yaml border-suite-2.png
 platform(linux,mac) == border-suite-3.yaml border-suite-3.png
 == border-double-simple.yaml border-double-simple-ref.yaml
 == border-double-simple-2.yaml border-double-simple-2-ref.yaml
 fuzzy(64,24) == border-groove-simple.yaml border-groove-simple-ref.yaml
 fuzzy(64,24) == border-ridge-simple.yaml border-ridge-simple-ref.yaml
 platform(linux,mac) fuzzy(1,2) == degenerate-curve.yaml degenerate-curve.png
 platform(linux,mac) == border-image.yaml border-image-ref.png
 == border-image-crash.yaml border-image-crash-ref.yaml
--- a/js/src/gc/Marking.cpp
+++ b/js/src/gc/Marking.cpp
@@ -2770,36 +2770,35 @@ struct TenuringTraversalFunctor : public
 
 template <typename T>
 void TenuringTracer::traverse(T* thingp) {
   *thingp = DispatchTyped(TenuringTraversalFunctor<T>(), *thingp, this);
 }
 }  // namespace js
 
 template <typename T>
-void js::gc::StoreBuffer::MonoTypeBuffer<T>::trace(StoreBuffer* owner,
-                                                   TenuringTracer& mover) {
-  mozilla::ReentrancyGuard g(*owner);
-  MOZ_ASSERT(owner->isEnabled());
+void js::gc::StoreBuffer::MonoTypeBuffer<T>::trace(TenuringTracer& mover) {
+  mozilla::ReentrancyGuard g(*owner_);
+  MOZ_ASSERT(owner_->isEnabled());
   if (last_) {
     last_.trace(mover);
   }
   for (typename StoreSet::Range r = stores_.all(); !r.empty(); r.popFront()) {
     r.front().trace(mover);
   }
 }
 
 namespace js {
 namespace gc {
 template void StoreBuffer::MonoTypeBuffer<StoreBuffer::ValueEdge>::trace(
-    StoreBuffer*, TenuringTracer&);
+    TenuringTracer&);
 template void StoreBuffer::MonoTypeBuffer<StoreBuffer::SlotsEdge>::trace(
-    StoreBuffer*, TenuringTracer&);
+    TenuringTracer&);
 template void StoreBuffer::MonoTypeBuffer<StoreBuffer::CellPtrEdge>::trace(
-    StoreBuffer*, TenuringTracer&);
+    TenuringTracer&);
 }  // namespace gc
 }  // namespace js
 
 void js::gc::StoreBuffer::SlotsEdge::trace(TenuringTracer& mover) const {
   NativeObject* obj = object();
   MOZ_ASSERT(IsCellPointerValid(obj));
 
   // Beware JSObject::swap exchanging a native object for a non-native one.
@@ -2869,19 +2868,18 @@ static void TraceBufferedCells(TenuringT
     if (cells->hasCell(i)) {
       auto cell =
           reinterpret_cast<T*>(uintptr_t(arena) + ArenaCellIndexBytes * i);
       TraceWholeCell(mover, cell);
     }
   }
 }
 
-void js::gc::StoreBuffer::WholeCellBuffer::trace(StoreBuffer* owner,
-                                                 TenuringTracer& mover) {
-  MOZ_ASSERT(owner->isEnabled());
+void js::gc::StoreBuffer::WholeCellBuffer::trace(TenuringTracer& mover) {
+  MOZ_ASSERT(owner_->isEnabled());
 
   for (ArenaCellSet* cells = head_; cells; cells = cells->next) {
     cells->check();
 
     Arena* arena = cells->arena;
     arena->bufferedCells() = &ArenaCellSet::Empty;
 
     JS::TraceKind kind = MapAllocToTraceKind(arena->getAllocKind());
--- a/js/src/gc/StoreBuffer.cpp
+++ b/js/src/gc/StoreBuffer.cpp
@@ -12,30 +12,72 @@
 #include "vm/ArgumentsObject.h"
 #include "vm/Runtime.h"
 
 #include "gc/GC-inl.h"
 
 using namespace js;
 using namespace js::gc;
 
-void StoreBuffer::GenericBuffer::trace(StoreBuffer* owner, JSTracer* trc) {
-  mozilla::ReentrancyGuard g(*owner);
-  MOZ_ASSERT(owner->isEnabled());
+bool StoreBuffer::WholeCellBuffer::init() {
+  MOZ_ASSERT(!head_);
+  if (!storage_) {
+    storage_ = MakeUnique<LifoAlloc>(LifoAllocBlockSize);
+    // This prevents LifoAlloc::Enum from crashing with a release
+    // assertion if we ever allocate one entry larger than
+    // LifoAllocBlockSize.
+    if (storage_) {
+      storage_->disableOversize();
+    }
+  }
+  clear();
+  return bool(storage_);
+}
+
+bool StoreBuffer::GenericBuffer::init() {
+  if (!storage_) {
+    storage_ = MakeUnique<LifoAlloc>(LifoAllocBlockSize);
+  }
+  clear();
+  return bool(storage_);
+}
+
+void StoreBuffer::GenericBuffer::trace(JSTracer* trc) {
+  mozilla::ReentrancyGuard g(*owner_);
+  MOZ_ASSERT(owner_->isEnabled());
   if (!storage_) {
     return;
   }
 
   for (LifoAlloc::Enum e(*storage_); !e.empty();) {
     unsigned size = *e.read<unsigned>();
     BufferableRef* edge = e.read<BufferableRef>(size);
     edge->trace(trc);
   }
 }
 
+StoreBuffer::StoreBuffer(JSRuntime* rt, const Nursery& nursery)
+ : bufferVal(this),
+   bufferCell(this),
+   bufferSlot(this),
+   bufferWholeCell(this),
+   bufferGeneric(this),
+   cancelIonCompilations_(false),
+   runtime_(rt),
+   nursery_(nursery),
+   aboutToOverflow_(false),
+   enabled_(false)
+#ifdef DEBUG
+ ,
+   mEntered(false)
+#endif
+{
+}
+
+
 void StoreBuffer::checkEmpty() const {
   MOZ_ASSERT(bufferVal.isEmpty());
   MOZ_ASSERT(bufferCell.isEmpty());
   MOZ_ASSERT(bufferSlot.isEmpty());
   MOZ_ASSERT(bufferWholeCell.isEmpty());
   MOZ_ASSERT(bufferGeneric.isEmpty());
 }
 
--- a/js/src/gc/StoreBuffer.h
+++ b/js/src/gc/StoreBuffer.h
@@ -13,16 +13,17 @@
 
 #include <algorithm>
 
 #include "ds/BitArray.h"
 #include "ds/LifoAlloc.h"
 #include "gc/Nursery.h"
 #include "js/AllocPolicy.h"
 #include "js/MemoryMetrics.h"
+#include "js/UniquePtr.h"
 
 namespace js {
 namespace gc {
 
 class Arena;
 class ArenaCellSet;
 
 /*
@@ -72,106 +73,94 @@ class StoreBuffer {
     StoreSet stores_;
 
     /*
      * A one element cache in front of the canonical set to speed up
      * temporary instances of HeapPtr.
      */
     T last_;
 
+    StoreBuffer* owner_;
+
     /* Maximum number of entries before we request a minor GC. */
     const static size_t MaxEntries = 48 * 1024 / sizeof(T);
 
-    explicit MonoTypeBuffer() : last_(T()) {}
+    explicit MonoTypeBuffer(StoreBuffer* owner)
+     : last_(T()), owner_(owner)
+    {}
 
     void clear() {
       last_ = T();
       stores_.clear();
     }
 
     /* Add one item to the buffer. */
-    void put(StoreBuffer* owner, const T& t) {
-      sinkStore(owner);
+    void put(const T& t) {
+      sinkStore();
       last_ = t;
     }
 
     /* Remove an item from the store buffer. */
-    void unput(StoreBuffer* owner, const T& v) {
+    void unput(const T& v) {
       // Fast, hashless remove of last put.
       if (last_ == v) {
         last_ = T();
         return;
       }
       stores_.remove(v);
     }
 
     /* Move any buffered stores to the canonical store set. */
-    void sinkStore(StoreBuffer* owner) {
+    void sinkStore() {
       if (last_) {
         AutoEnterOOMUnsafeRegion oomUnsafe;
         if (!stores_.put(last_)) {
           oomUnsafe.crash("Failed to allocate for MonoTypeBuffer::put.");
         }
       }
       last_ = T();
 
       if (MOZ_UNLIKELY(stores_.count() > MaxEntries)) {
-        owner->setAboutToOverflow(T::FullBufferReason);
+        owner_->setAboutToOverflow(T::FullBufferReason);
       }
     }
 
-    bool has(StoreBuffer* owner, const T& v) {
-      sinkStore(owner);
-      return stores_.has(v);
-    }
-
     /* Trace the source of all edges in the store buffer. */
-    void trace(StoreBuffer* owner, TenuringTracer& mover);
+    void trace(TenuringTracer& mover);
 
     size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) {
       return stores_.shallowSizeOfExcludingThis(mallocSizeOf);
     }
 
     bool isEmpty() const { return last_ == T() && stores_.empty(); }
 
    private:
     MonoTypeBuffer(const MonoTypeBuffer& other) = delete;
     MonoTypeBuffer& operator=(const MonoTypeBuffer& other) = delete;
   };
 
   struct WholeCellBuffer {
-    LifoAlloc* storage_;
+    UniquePtr<LifoAlloc> storage_;
     ArenaCellSet* head_;
-
-    WholeCellBuffer() : storage_(nullptr), head_(nullptr) {}
-    ~WholeCellBuffer() { js_delete(storage_); }
+    StoreBuffer* owner_;
 
-    MOZ_MUST_USE bool init() {
-      MOZ_ASSERT(!head_);
-      if (!storage_) {
-        storage_ = js_new<LifoAlloc>(LifoAllocBlockSize);
-        // This prevents LifoAlloc::Enum from crashing with a release
-        // assertion if we ever allocate one entry larger than
-        // LifoAllocBlockSize.
-        if (storage_) {
-          storage_->disableOversize();
-        }
-      }
-      clear();
-      return bool(storage_);
-    }
+    explicit WholeCellBuffer(StoreBuffer* owner)
+     : storage_(nullptr), head_(nullptr), owner_(owner)
+    {}
+
+    MOZ_MUST_USE bool init();
 
     void clear();
 
     bool isAboutToOverflow() const {
       return !storage_->isEmpty() &&
              storage_->used() > WholeCellBufferOverflowThresholdBytes;
     }
 
-    void trace(StoreBuffer* owner, TenuringTracer& mover);
+    void trace(TenuringTracer& mover);
 
     inline void put(const Cell* cell);
 
     size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) {
       return storage_ ? storage_->sizeOfIncludingThis(mallocSizeOf) : 0;
     }
 
     bool isEmpty() const {
@@ -182,47 +171,39 @@ class StoreBuffer {
    private:
     ArenaCellSet* allocateCellSet(Arena* arena);
 
     WholeCellBuffer(const WholeCellBuffer& other) = delete;
     WholeCellBuffer& operator=(const WholeCellBuffer& other) = delete;
   };
 
   struct GenericBuffer {
-    LifoAlloc* storage_;
-
-    explicit GenericBuffer() : storage_(nullptr) {}
-    ~GenericBuffer() { js_delete(storage_); }
+    UniquePtr<LifoAlloc> storage_;
+    StoreBuffer* owner_;
 
-    MOZ_MUST_USE bool init() {
-      if (!storage_) {
-        storage_ = js_new<LifoAlloc>(LifoAllocBlockSize);
-      }
-      clear();
-      return bool(storage_);
-    }
+    explicit GenericBuffer(StoreBuffer* owner) : storage_(nullptr), owner_(owner) {}
+
+    MOZ_MUST_USE bool init();
 
     void clear() {
-      if (!storage_) {
-        return;
+      if (storage_) {
+        storage_->used() ? storage_->releaseAll() : storage_->freeAll();
       }
-
-      storage_->used() ? storage_->releaseAll() : storage_->freeAll();
     }
 
     bool isAboutToOverflow() const {
       return !storage_->isEmpty() && storage_->availableInCurrentChunk() <
                                          GenericBufferLowAvailableThreshold;
     }
 
     /* Trace all generic edges. */
-    void trace(StoreBuffer* owner, JSTracer* trc);
+    void trace(JSTracer* trc);
 
     template <typename T>
-    void put(StoreBuffer* owner, const T& t) {
+    void put(const T& t) {
       MOZ_ASSERT(storage_);
 
       /* Ensure T is derived from BufferableRef. */
       (void)static_cast<const BufferableRef*>(&t);
 
       AutoEnterOOMUnsafeRegion oomUnsafe;
       unsigned size = sizeof(T);
       unsigned* sizep = storage_->pod_malloc<unsigned>();
@@ -232,17 +213,17 @@ class StoreBuffer {
       *sizep = size;
 
       T* tp = storage_->new_<T>(t);
       if (!tp) {
         oomUnsafe.crash("Failed to allocate for GenericBuffer::put.");
       }
 
       if (isAboutToOverflow()) {
-        owner->setAboutToOverflow(JS::GCReason::FULL_GENERIC_BUFFER);
+        owner_->setAboutToOverflow(JS::GCReason::FULL_GENERIC_BUFFER);
       }
     }
 
     size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) {
       return storage_ ? storage_->sizeOfIncludingThis(mallocSizeOf) : 0;
     }
 
     bool isEmpty() const { return !storage_ || storage_->isEmpty(); }
@@ -416,29 +397,29 @@ class StoreBuffer {
   template <typename Buffer, typename Edge>
   void unput(Buffer& buffer, const Edge& edge) {
     MOZ_ASSERT(!JS::RuntimeHeapIsBusy());
     MOZ_ASSERT(CurrentThreadCanAccessRuntime(runtime_));
     if (!isEnabled()) {
       return;
     }
     mozilla::ReentrancyGuard g(*this);
-    buffer.unput(this, edge);
+    buffer.unput(edge);
   }
 
   template <typename Buffer, typename Edge>
   void put(Buffer& buffer, const Edge& edge) {
     MOZ_ASSERT(!JS::RuntimeHeapIsBusy());
     MOZ_ASSERT(CurrentThreadCanAccessRuntime(runtime_));
     if (!isEnabled()) {
       return;
     }
     mozilla::ReentrancyGuard g(*this);
     if (edge.maybeInRememberedSet(nursery_)) {
-      buffer.put(this, edge);
+      buffer.put(edge);
     }
   }
 
   MonoTypeBuffer<ValueEdge> bufferVal;
   MonoTypeBuffer<CellPtrEdge> bufferCell;
   MonoTypeBuffer<SlotsEdge> bufferSlot;
   WholeCellBuffer bufferWholeCell;
   GenericBuffer bufferGeneric;
@@ -449,34 +430,17 @@ class StoreBuffer {
 
   bool aboutToOverflow_;
   bool enabled_;
 #ifdef DEBUG
   bool mEntered; /* For ReentrancyGuard. */
 #endif
 
  public:
-  explicit StoreBuffer(JSRuntime* rt, const Nursery& nursery)
-      : bufferVal(),
-        bufferCell(),
-        bufferSlot(),
-        bufferWholeCell(),
-        bufferGeneric(),
-        cancelIonCompilations_(false),
-        runtime_(rt),
-        nursery_(nursery),
-        aboutToOverflow_(false),
-        enabled_(false)
-#ifdef DEBUG
-        ,
-        mEntered(false)
-#endif
-  {
-  }
-
+  explicit StoreBuffer(JSRuntime* rt, const Nursery& nursery);
   MOZ_MUST_USE bool enable();
 
   void disable();
   bool isEnabled() const { return enabled_; }
 
   void clear();
 
   const Nursery& nursery() const { return nursery_; }
@@ -506,23 +470,21 @@ class StoreBuffer {
   template <typename T>
   void putGeneric(const T& t) {
     put(bufferGeneric, t);
   }
 
   void setShouldCancelIonCompilations() { cancelIonCompilations_ = true; }
 
   /* Methods to trace the source of all edges in the store buffer. */
-  void traceValues(TenuringTracer& mover) { bufferVal.trace(this, mover); }
-  void traceCells(TenuringTracer& mover) { bufferCell.trace(this, mover); }
-  void traceSlots(TenuringTracer& mover) { bufferSlot.trace(this, mover); }
-  void traceWholeCells(TenuringTracer& mover) {
-    bufferWholeCell.trace(this, mover);
-  }
-  void traceGenericEntries(JSTracer* trc) { bufferGeneric.trace(this, trc); }
+  void traceValues(TenuringTracer& mover) { bufferVal.trace(mover); }
+  void traceCells(TenuringTracer& mover) { bufferCell.trace(mover); }
+  void traceSlots(TenuringTracer& mover) { bufferSlot.trace(mover); }
+  void traceWholeCells(TenuringTracer& mover) { bufferWholeCell.trace(mover); }
+  void traceGenericEntries(JSTracer* trc) { bufferGeneric.trace(trc); }
 
   /* For use by our owned buffers and for testing. */
   void setAboutToOverflow(JS::GCReason);
 
   void addSizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf,
                               JS::GCSizes* sizes);
 
   void checkEmpty() const;
--- a/js/src/gc/Verifier.cpp
+++ b/js/src/gc/Verifier.cpp
@@ -756,16 +756,18 @@ static JSObject* MaybeGetDelegate(Cell* 
   }
 
   JSObject* object = cell->as<JSObject>();
   return js::UncheckedUnwrapWithoutExpose(object);
 }
 
 bool js::gc::CheckWeakMapEntryMarking(const WeakMapBase* map, Cell* key,
                                       Cell* value) {
+  bool ok = true;
+
   DebugOnly<Zone*> zone = map->zone();
   MOZ_ASSERT(CurrentThreadCanAccessZone(zone));
   MOZ_ASSERT(zone->isGCMarking());
 
   JSObject* object = map->memberOf;
   MOZ_ASSERT_IF(object, object->zone() == zone);
 
   // Debugger weak maps can have keys in different zones.
@@ -773,55 +775,61 @@ bool js::gc::CheckWeakMapEntryMarking(co
   MOZ_ASSERT_IF(!map->allowKeysInOtherZones(),
                 keyZone == zone || keyZone->isAtomsZone());
 
   Zone* valueZone = GetCellZoneFromAnyThread(value);
   MOZ_ASSERT(valueZone == zone || valueZone->isAtomsZone());
 
   CellColor mapColor =
       map->markColor == MarkColor::Black ? CellColor::Black : CellColor::Gray;
-  MOZ_ASSERT_IF(object, GetCellColor(object) == mapColor);
+  if (object && GetCellColor(object) != mapColor) {
+    fprintf(stderr, "WeakMap object is marked differently to the map\n");
+    fprintf(stderr, "(map %p is %s, object %p is %s)\n",
+            map, CellColorName(mapColor),
+            object, CellColorName(GetCellColor(object)));
+    ok = false;
+  }
 
   CellColor keyColor = GetCellColor(key);
   CellColor valueColor =
       valueZone->isGCMarking() ? GetCellColor(value) : CellColor::Black;
 
   if (valueColor < Min(mapColor, keyColor)) {
     fprintf(stderr, "WeakMap value is less marked than map and key\n");
     fprintf(stderr, "(map %p is %s, key %p is %s, value %p is %s)\n", map,
             CellColorName(mapColor), key, CellColorName(keyColor), value,
             CellColorName(valueColor));
-    return false;
+    ok = false;
   }
 
   // Debugger weak maps map have keys in zones that are not or are
   // no longer collecting. We can't make guarantees about the mark
   // state of these keys.
   if (map->allowKeysInOtherZones() &&
       !(keyZone->isGCMarking() || keyZone->isGCSweeping())) {
-    return true;
+    return ok;
   }
 
   JSObject* delegate = MaybeGetDelegate(key);
   if (!delegate) {
-    return true;
+    return ok;
   }
 
   CellColor delegateColor;
   if (delegate->zone()->isGCMarking() || delegate->zone()->isGCSweeping()) {
     delegateColor = GetCellColor(delegate);
   } else {
     // IsMarked() assumes cells in uncollected zones are marked.
     delegateColor = CellColor::Black;
   }
 
   if (keyColor < Min(mapColor, delegateColor)) {
     fprintf(stderr, "WeakMap key is less marked than map and delegate\n");
     fprintf(stderr, "(map %p is %s, delegate %p is %s, key %p is %s)\n", map,
             CellColorName(mapColor), delegate, CellColorName(delegateColor),
             key, CellColorName(keyColor));
-    return false;
+    ok = false;
   }
 
-  return true;
+  return ok;
 }
 
 #endif  // defined(JS_GC_ZEAL) || defined(DEBUG)
--- a/js/src/jit-test/lib/wasm-binary.js
+++ b/js/src/jit-test/lib/wasm-binary.js
@@ -103,16 +103,24 @@ const RefNull          = 0xd0;
 const FirstInvalidOpcode = 0xc5;
 const LastInvalidOpcode = 0xfb;
 const MiscPrefix = 0xfc;
 const SimdPrefix = 0xfd;
 const ThreadPrefix = 0xfe;
 const MozPrefix = 0xff;
 
 // Secondary opcode bytes for misc prefix
+const MemoryInitCode = 0x08;    // Pending
+const DataDropCode = 0x09;      // Pending
+const MemoryCopyCode = 0x0a;    // Pending
+const MemoryFillCode = 0x0b;    // Pending
+const TableInitCode = 0x0c;     // Pending
+const ElemDropCode = 0x0d;      // Pending
+const TableCopyCode = 0x0e;     // Pending
+
 const StructNew = 0x50;         // UNOFFICIAL
 const StructGet = 0x51;         // UNOFFICIAL
 const StructSet = 0x52;         // UNOFFICIAL
 const StructNarrow = 0x53;      // UNOFFICIAL
 
 // DefinitionKind
 const FunctionCode     = 0x00;
 const TableCode        = 0x01;
--- a/js/src/jit-test/tests/wasm/passive-segs-boundary.js
+++ b/js/src/jit-test/tests/wasm/passive-segs-boundary.js
@@ -98,55 +98,55 @@ function tab_test_nofail(insn1, insn2) {
     do_test(insn1, insn2, undefined, undefined,
             /*isMem=*/false, /*haveMemOrTable=*/true);
 }
 
 
 //---- memory.{drop,init} -------------------------------------------------
 
 // drop with no memory
-mem_test("memory.drop 3", "",
+mem_test("data.drop 3", "",
          WebAssembly.CompileError, /can't touch memory without memory/,
          false);
 
 // init with no memory
 mem_test("(memory.init 1 (i32.const 1234) (i32.const 1) (i32.const 1))", "",
          WebAssembly.CompileError, /can't touch memory without memory/,
          false);
 
 // drop with data seg ix out of range
-mem_test("memory.drop 4", "",
-         WebAssembly.CompileError, /memory.{drop,init} index out of range/);
+mem_test("data.drop 4", "",
+         WebAssembly.CompileError, /data.drop segment index out of range/);
 
 // init with data seg ix out of range
 mem_test("(memory.init 4 (i32.const 1234) (i32.const 1) (i32.const 1))", "",
-         WebAssembly.CompileError, /memory.{drop,init} index out of range/);
+         WebAssembly.CompileError, /memory.init segment index out of range/);
 
 // drop with data seg ix indicating an active segment
-mem_test("memory.drop 2", "",
-         WebAssembly.RuntimeError, /use of invalid passive data segment/);
+mem_test("data.drop 2", "",
+         WebAssembly.RuntimeError, /use of dropped data segment/);
 
 // init with data seg ix indicating an active segment
 mem_test("(memory.init 2 (i32.const 1234) (i32.const 1) (i32.const 1))", "",
-         WebAssembly.RuntimeError, /use of invalid passive data segment/);
+         WebAssembly.RuntimeError, /use of dropped data segment/);
 
 // init, using a data seg ix more than once is OK
 mem_test_nofail(
     "(memory.init 1 (i32.const 1234) (i32.const 1) (i32.const 1))",
     "(memory.init 1 (i32.const 4321) (i32.const 1) (i32.const 1))");
 
 // drop, then drop
-mem_test("memory.drop 1",
-         "memory.drop 1",
-         WebAssembly.RuntimeError, /use of invalid passive data segment/);
+mem_test("data.drop 1",
+         "data.drop 1",
+         WebAssembly.RuntimeError, /use of dropped data segment/);
 
 // drop, then init
-mem_test("memory.drop 1",
+mem_test("data.drop 1",
          "(memory.init 1 (i32.const 1234) (i32.const 1) (i32.const 1))",
-         WebAssembly.RuntimeError, /use of invalid passive data segment/);
+         WebAssembly.RuntimeError, /use of dropped data segment/);
 
 // init: seg ix is valid passive, but length to copy > len of seg
 mem_test("",
          "(memory.init 1 (i32.const 1234) (i32.const 0) (i32.const 5))",
          WebAssembly.RuntimeError, /index out of bounds/);
 
 // init: seg ix is valid passive, but implies copying beyond end of seg
 mem_test("",
@@ -164,17 +164,17 @@ mem_test("",
          WebAssembly.RuntimeError, /index out of bounds/);
 
 // init: seg ix is valid passive, zero len, but dst offset out of bounds
 mem_test("",
          "(memory.init 1 (i32.const 0x10000) (i32.const 2) (i32.const 0))",
          WebAssembly.RuntimeError, /index out of bounds/);
 
 // drop: too many args
-mem_test("memory.drop 1 (i32.const 42)", "",
+mem_test("data.drop 1 (i32.const 42)", "",
          WebAssembly.CompileError,
          /unused values not explicitly dropped by end of block/);
 
 // init: too many args
 mem_test("(memory.init 1 (i32.const 1) (i32.const 1) (i32.const 1) (i32.const 1))",
          "",
          SyntaxError, /parsing wasm text at/);
 
@@ -196,55 +196,55 @@ mem_test("(memory.init 1 (i32.const 1) (
         mem_test(i1, "", WebAssembly.CompileError, /type mismatch/);
     }}}
 }
 
 
 //---- table.{drop,init} --------------------------------------------------
 
 // drop with no table
-tab_test("table.drop 3", "",
-         WebAssembly.CompileError, /can't table.drop without a table/,
+tab_test("elem.drop 3", "",
+         WebAssembly.CompileError, /can't elem.drop without a table/,
          false);
 
 // init with no table
 tab_test("(table.init 1 (i32.const 12) (i32.const 1) (i32.const 1))", "",
          WebAssembly.CompileError, /table index out of range/,
          false);
 
 // drop with elem seg ix out of range
-tab_test("table.drop 4", "",
-         WebAssembly.CompileError, /element segment index out of range for table.drop/);
+tab_test("elem.drop 4", "",
+         WebAssembly.CompileError, /element segment index out of range for elem.drop/);
 
 // init with elem seg ix out of range
 tab_test("(table.init 4 (i32.const 12) (i32.const 1) (i32.const 1))", "",
          WebAssembly.CompileError, /table.init segment index out of range/);
 
 // drop with elem seg ix indicating an active segment
-tab_test("table.drop 2", "",
-         WebAssembly.RuntimeError, /use of invalid passive element segment/);
+tab_test("elem.drop 2", "",
+         WebAssembly.RuntimeError, /use of dropped element segment/);
 
 // init with elem seg ix indicating an active segment
 tab_test("(table.init 2 (i32.const 12) (i32.const 1) (i32.const 1))", "",
-         WebAssembly.RuntimeError, /use of invalid passive element segment/);
+         WebAssembly.RuntimeError, /use of dropped element segment/);
 
 // init, using an elem seg ix more than once is OK
 tab_test_nofail(
     "(table.init 1 (i32.const 12) (i32.const 1) (i32.const 1))",
     "(table.init 1 (i32.const 21) (i32.const 1) (i32.const 1))");
 
 // drop, then drop
-tab_test("table.drop 1",
-         "table.drop 1",
-         WebAssembly.RuntimeError, /use of invalid passive element segment/);
+tab_test("elem.drop 1",
+         "elem.drop 1",
+         WebAssembly.RuntimeError, /use of dropped element segment/);
 
 // drop, then init
-tab_test("table.drop 1",
+tab_test("elem.drop 1",
          "(table.init 1 (i32.const 12) (i32.const 1) (i32.const 1))",
-         WebAssembly.RuntimeError, /use of invalid passive element segment/);
+         WebAssembly.RuntimeError, /use of dropped element segment/);
 
 // init: seg ix is valid passive, but length to copy > len of seg
 tab_test("",
          "(table.init 1 (i32.const 12) (i32.const 0) (i32.const 5))",
          WebAssembly.RuntimeError, /index out of bounds/);
 
 // init: seg ix is valid passive, but implies copying beyond end of seg
 tab_test("",
@@ -262,17 +262,17 @@ tab_test("",
          WebAssembly.RuntimeError, /index out of bounds/);
 
 // init: seg ix is valid passive, zero len, but dst offset out of bounds
 tab_test("",
          "(table.init 1 (i32.const 30) (i32.const 2) (i32.const 0))",
          WebAssembly.RuntimeError, /index out of bounds/);
 
 // drop: too many args
-tab_test("table.drop 1 (i32.const 42)", "",
+tab_test("elem.drop 1 (i32.const 42)", "",
          WebAssembly.CompileError,
          /unused values not explicitly dropped by end of block/);
 
 // init: too many args
 tab_test("(table.init 1 (i32.const 1) (i32.const 1) (i32.const 1) (i32.const 1))",
          "",
          SyntaxError, /parsing wasm text at/);
 
--- a/js/src/jit-test/tests/wasm/passive-segs-nonboundary.js
+++ b/js/src/jit-test/tests/wasm/passive-segs-nonboundary.js
@@ -1,10 +1,15 @@
 // |jit-test| skip-if: !wasmBulkMemSupported()
 
+load(libdir + "wasm-binary.js");
+
+const v2vSig = {args:[], ret:VoidCode};
+const v2vSigSection = sigSection([v2vSig]);
+
 const Module = WebAssembly.Module;
 const Instance = WebAssembly.Instance;
 
 // Some non-boundary tests for {table,memory}.{init,drop,copy}.  The table
 // case is more complex and appears first.  The memory case is a simplified
 // version of it.
 
 // This module exports 5 functions ..
@@ -141,19 +146,19 @@ tab_test("(table.init 1 (i32.const 7) (i
          [e,e,3,1,4, 1,e,2,7,1, 8,e,7,5,2, 3,6,e,e,e, e,e,e,e,e, e,e,e,e,e]);
 
 // Passive init that overwrites existing active-init-created entries
 tab_test("(table.init 3 (i32.const 15) (i32.const 1) (i32.const 3))",
          [e,e,3,1,4, 1,e,e,e,e, e,e,7,5,2, 9,2,7,e,e, e,e,e,e,e, e,e,e,e,e]);
 
 // Perform active and passive initialisation and then multiple copies
 tab_test("(table.init 1 (i32.const 7) (i32.const 0) (i32.const 4)) \n" +
-         "table.drop 1 \n" +
+         "elem.drop 1 \n" +
          "(table.init 3 (i32.const 15) (i32.const 1) (i32.const 3)) \n" +
-         "table.drop 3 \n" +
+         "elem.drop 3 \n" +
          "(table.copy (i32.const 20) (i32.const 15) (i32.const 5)) \n" +
          "(table.copy (i32.const 21) (i32.const 29) (i32.const 1)) \n" +
          "(table.copy (i32.const 24) (i32.const 10) (i32.const 1)) \n" +
          "(table.copy (i32.const 13) (i32.const 11) (i32.const 4)) \n" +
          "(table.copy (i32.const 19) (i32.const 20) (i32.const 5))",
          [e,e,3,1,4, 1,e,2,7,1, 8,e,7,e,7, 5,2,7,e,9, e,7,e,8,8, e,e,e,e,e]);
 
 
@@ -238,144 +243,97 @@ mem_test("(memory.init 1 (i32.const 7) (
          [e,e,3,1,4, 1,e,2,7,1, 8,e,7,5,2, 3,6,e,e,e, e,e,e,e,e, e,e,e,e,e]);
 
 // Passive init that overwrites existing active-init-created entries
 mem_test("(memory.init 3 (i32.const 15) (i32.const 1) (i32.const 3))",
          [e,e,3,1,4, 1,e,e,e,e, e,e,7,5,2, 9,2,7,e,e, e,e,e,e,e, e,e,e,e,e]);
 
 // Perform active and passive initialisation and then multiple copies
 mem_test("(memory.init 1 (i32.const 7) (i32.const 0) (i32.const 4)) \n" +
-         "memory.drop 1 \n" +
+         "data.drop 1 \n" +
          "(memory.init 3 (i32.const 15) (i32.const 1) (i32.const 3)) \n" +
-         "memory.drop 3 \n" +
+         "data.drop 3 \n" +
          "(memory.copy (i32.const 20) (i32.const 15) (i32.const 5)) \n" +
          "(memory.copy (i32.const 21) (i32.const 29) (i32.const 1)) \n" +
          "(memory.copy (i32.const 24) (i32.const 10) (i32.const 1)) \n" +
          "(memory.copy (i32.const 13) (i32.const 11) (i32.const 4)) \n" +
          "(memory.copy (i32.const 19) (i32.const 20) (i32.const 5))",
          [e,e,3,1,4, 1,e,2,7,1, 8,e,7,e,7, 5,2,7,e,9, e,7,e,8,8, e,e,e,e,e]);
 
+// DataCount section is present but value is too low for the number of data segments
+assertErrorMessage(() => wasmEvalText(
+    `(module
+       (datacount 1)
+       (data passive "")
+       (data passive ""))`),
+                   WebAssembly.CompileError,
+                   /number of data segments does not match declared count/);
+
+// DataCount section is present but value is too high for the number of data segments
+assertErrorMessage(() => wasmEvalText(
+    `(module
+       (datacount 3)
+       (data passive "")
+       (data passive ""))`),
+                   WebAssembly.CompileError,
+                   /number of data segments does not match declared count/);
+
+// DataCount section is not present but memory.init or data.drop uses it
+function checkNoDataCount(body, err) {
+    let binary = moduleWithSections(
+        [v2vSigSection,
+         declSection([0]),
+         memorySection(1),
+         bodySection(
+             [funcBody({locals:[], body})])]);
+    assertErrorMessage(() => new WebAssembly.Module(binary),
+                       WebAssembly.CompileError,
+                       err);
+}
+
+checkNoDataCount([I32ConstCode, 0,
+                  I32ConstCode, 0,
+                  I32ConstCode, 0,
+                  MiscPrefix, MemoryInitCode, 0, 0],
+                /memory.init requires a DataCount section/);
+
+checkNoDataCount([MiscPrefix, DataDropCode, 0],
+                 /data.drop requires a DataCount section/);
 
 //---------------------------------------------------------------------//
 //---------------------------------------------------------------------//
 // Some further tests for memory.copy and memory.fill.  First, validation
 // tests.
 
-//-----------------------------------------------------------
-// Test helpers.  Copied and simplified from binary.js.
-
-load(libdir + "wasm-binary.js");
-
-function toU8(array) {
-    for (let b of array)
-        assertEq(b < 256, true);
-    return Uint8Array.from(array);
-}
-
-function varU32(u32) {
-    assertEq(u32 >= 0, true);
-    assertEq(u32 < Math.pow(2,32), true);
-    var bytes = [];
-    do {
-        var byte = u32 & 0x7f;
-        u32 >>>= 7;
-        if (u32 != 0)
-            byte |= 0x80;
-        bytes.push(byte);
-    } while (u32 != 0);
-    return bytes;
-}
-
-function moduleHeaderThen(...rest) {
-    return [magic0, magic1, magic2, magic3, ver0, ver1, ver2, ver3, ...rest];
-}
-
-function moduleWithSections(sectionArray) {
-    var bytes = moduleHeaderThen();
-    for (let section of sectionArray) {
-        bytes.push(section.name);
-        bytes.push(...varU32(section.body.length));
-        bytes.push(...section.body);
-    }
-    return toU8(bytes);
-}
-
-function sigSection(sigs) {
-    var body = [];
-    body.push(...varU32(sigs.length));
-    for (let sig of sigs) {
-        body.push(...varU32(FuncCode));
-        body.push(...varU32(sig.args.length));
-        for (let arg of sig.args)
-            body.push(...varU32(arg));
-        body.push(...varU32(sig.ret == VoidCode ? 0 : 1));
-        if (sig.ret != VoidCode)
-            body.push(...varU32(sig.ret));
-    }
-    return { name: typeId, body };
-}
-
-function declSection(decls) {
-    var body = [];
-    body.push(...varU32(decls.length));
-    for (let decl of decls)
-        body.push(...varU32(decl));
-    return { name: functionId, body };
-}
-
-function funcBody(func) {
-    var body = varU32(func.locals.length);
-    for (let local of func.locals)
-        body.push(...varU32(local));
-    body = body.concat(...func.body);
-    body.push(EndCode);
-    body.splice(0, 0, ...varU32(body.length));
-    return body;
-}
-
-function bodySection(bodies) {
-    var body = varU32(bodies.length).concat(...bodies);
-    return { name: codeId, body };
-}
-
-function memorySection(initialSize) {
-    var body = [];
-    body.push(...varU32(1));           // number of memories
-    body.push(...varU32(0x0));         // for now, no maximum
-    body.push(...varU32(initialSize));
-    return { name: memoryId, body };
-}
-
-const v2vSig = {args:[], ret:VoidCode};
-const v2vSigSection = sigSection([v2vSig]);
-
 // Prefixed opcodes
 
 function checkMiscPrefixed(opcode, expect_failure) {
     let binary = moduleWithSections(
            [v2vSigSection, declSection([0]), memorySection(1),
             bodySection(
                 [funcBody(
                     {locals:[],
-                     body:[0x41, 0x0, 0x41, 0x0, 0x41, 0x0, // 3 x const.i32 0
+                     body:[I32ConstCode, 0x0,
+                           I32ConstCode, 0x0,
+                           I32ConstCode, 0x0,
                            MiscPrefix, ...opcode]})])]);
     if (expect_failure) {
         assertErrorMessage(() => new WebAssembly.Module(binary),
                            WebAssembly.CompileError, /unrecognized opcode/);
     } else {
         assertEq(WebAssembly.validate(binary), true);
     }
 }
 
 //-----------------------------------------------------------
 // Verification cases for memory.copy/fill opcode encodings
 
-checkMiscPrefixed([0x0a, 0x00], false); // memory.copy, flags=0
-checkMiscPrefixed([0x0b, 0x00], false); // memory.fill, flags=0
-checkMiscPrefixed([0x0b, 0x80, 0x00], false); // memory.fill, flags=0 (long encoding)
+checkMiscPrefixed([MemoryCopyCode, 0x00, 0x00], false); // memory.copy src=0 dest=0
+checkMiscPrefixed([MemoryFillCode, 0x00], false); // memory.fill mem=0
+checkMiscPrefixed([MemoryFillCode, 0x80, 0x00], false); // memory.fill, mem=0 (long encoding)
 checkMiscPrefixed([0x13], true);        // table.size+1, which is currently unassigned
 
 //-----------------------------------------------------------
 // Verification cases for memory.copy/fill arguments
 
 // Invalid argument types
 {
     const tys = ['i32', 'f32', 'i64', 'f64'];
--- a/js/src/jit/BaselineCacheIRCompiler.cpp
+++ b/js/src/jit/BaselineCacheIRCompiler.cpp
@@ -224,16 +224,17 @@ JitCode* BaselineCacheIRCompiler::compil
     cx_->recoverFromOutOfMemory();
     return nullptr;
   }
 
   return newStubCode;
 }
 
 bool BaselineCacheIRCompiler::emitGuardShape() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   ObjOperandId objId = reader.objOperandId();
   Register obj = allocator.useRegister(masm, objId);
   AutoScratchRegister scratch1(allocator, masm);
 
   bool needSpectreMitigations = objectGuardNeedsSpectreMitigations(objId);
 
   Maybe<AutoScratchRegister> maybeScratch2;
   if (needSpectreMitigations) {
@@ -254,16 +255,17 @@ bool BaselineCacheIRCompiler::emitGuardS
     masm.branchTestObjShapeNoSpectreMitigations(Assembler::NotEqual, obj,
                                                 scratch1, failure->label());
   }
 
   return true;
 }
 
 bool BaselineCacheIRCompiler::emitGuardGroup() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   ObjOperandId objId = reader.objOperandId();
   Register obj = allocator.useRegister(masm, objId);
   AutoScratchRegister scratch1(allocator, masm);
 
   bool needSpectreMitigations = objectGuardNeedsSpectreMitigations(objId);
 
   Maybe<AutoScratchRegister> maybeScratch2;
   if (needSpectreMitigations) {
@@ -284,31 +286,33 @@ bool BaselineCacheIRCompiler::emitGuardG
     masm.branchTestObjGroupNoSpectreMitigations(Assembler::NotEqual, obj,
                                                 scratch1, failure->label());
   }
 
   return true;
 }
 
 bool BaselineCacheIRCompiler::emitGuardProto() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   Register obj = allocator.useRegister(masm, reader.objOperandId());
   AutoScratchRegister scratch(allocator, masm);
 
   FailurePath* failure;
   if (!addFailurePath(&failure)) {
     return false;
   }
 
   Address addr(stubAddress(reader.stubOffset()));
   masm.loadObjProto(obj, scratch);
   masm.branchPtr(Assembler::NotEqual, addr, scratch, failure->label());
   return true;
 }
 
 bool BaselineCacheIRCompiler::emitGuardCompartment() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   Register obj = allocator.useRegister(masm, reader.objOperandId());
   AutoScratchRegister scratch(allocator, masm);
 
   FailurePath* failure;
   if (!addFailurePath(&failure)) {
     return false;
   }
 
@@ -322,16 +326,17 @@ bool BaselineCacheIRCompiler::emitGuardC
 
   Address addr(stubAddress(reader.stubOffset()));
   masm.branchTestObjCompartment(Assembler::NotEqual, obj, addr, scratch,
                                 failure->label());
   return true;
 }
 
 bool BaselineCacheIRCompiler::emitGuardAnyClass() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   ObjOperandId objId = reader.objOperandId();
   Register obj = allocator.useRegister(masm, objId);
   AutoScratchRegister scratch(allocator, masm);
 
   FailurePath* failure;
   if (!addFailurePath(&failure)) {
     return false;
   }
@@ -344,16 +349,17 @@ bool BaselineCacheIRCompiler::emitGuardA
     masm.branchTestObjClassNoSpectreMitigations(
         Assembler::NotEqual, obj, testAddr, scratch, failure->label());
   }
 
   return true;
 }
 
 bool BaselineCacheIRCompiler::emitGuardHasProxyHandler() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   Register obj = allocator.useRegister(masm, reader.objOperandId());
   AutoScratchRegister scratch(allocator, masm);
 
   FailurePath* failure;
   if (!addFailurePath(&failure)) {
     return false;
   }
 
@@ -361,29 +367,31 @@ bool BaselineCacheIRCompiler::emitGuardH
   masm.loadPtr(testAddr, scratch);
 
   Address handlerAddr(obj, ProxyObject::offsetOfHandler());
   masm.branchPtr(Assembler::NotEqual, handlerAddr, scratch, failure->label());
   return true;
 }
 
 bool BaselineCacheIRCompiler::emitGuardSpecificObject() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   Register obj = allocator.useRegister(masm, reader.objOperandId());
 
   FailurePath* failure;
   if (!addFailurePath(&failure)) {
     return false;
   }
 
   Address addr(stubAddress(reader.stubOffset()));
   masm.branchPtr(Assembler::NotEqual, addr, obj, failure->label());
   return true;
 }
 
 bool BaselineCacheIRCompiler::emitGuardSpecificAtom() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   Register str = allocator.useRegister(masm, reader.stringOperandId());
   AutoScratchRegister scratch(allocator, masm);
 
   FailurePath* failure;
   if (!addFailurePath(&failure)) {
     return false;
   }
 
@@ -421,57 +429,62 @@ bool BaselineCacheIRCompiler::emitGuardS
   masm.PopRegsInMaskIgnore(volatileRegs, ignore);
   masm.branchIfFalseBool(scratch, failure->label());
 
   masm.bind(&done);
   return true;
 }
 
 bool BaselineCacheIRCompiler::emitGuardSpecificSymbol() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   Register sym = allocator.useRegister(masm, reader.symbolOperandId());
 
   FailurePath* failure;
   if (!addFailurePath(&failure)) {
     return false;
   }
 
   Address addr(stubAddress(reader.stubOffset()));
   masm.branchPtr(Assembler::NotEqual, addr, sym, failure->label());
   return true;
 }
 
 bool BaselineCacheIRCompiler::emitLoadValueResult() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   AutoOutputRegister output(*this);
   masm.loadValue(stubAddress(reader.stubOffset()), output.valueReg());
   return true;
 }
 
 bool BaselineCacheIRCompiler::emitLoadFixedSlotResult() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   AutoOutputRegister output(*this);
   Register obj = allocator.useRegister(masm, reader.objOperandId());
   AutoScratchRegisterMaybeOutput scratch(allocator, masm, output);
 
   masm.load32(stubAddress(reader.stubOffset()), scratch);
   masm.loadValue(BaseIndex(obj, scratch, TimesOne), output.valueReg());
   return true;
 }
 
 bool BaselineCacheIRCompiler::emitLoadDynamicSlotResult() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   AutoOutputRegister output(*this);
   Register obj = allocator.useRegister(masm, reader.objOperandId());
   AutoScratchRegisterMaybeOutput scratch(allocator, masm, output);
   AutoScratchRegister scratch2(allocator, masm);
 
   masm.load32(stubAddress(reader.stubOffset()), scratch);
   masm.loadPtr(Address(obj, NativeObject::offsetOfSlots()), scratch2);
   masm.loadValue(BaseIndex(scratch2, scratch, TimesOne), output.valueReg());
   return true;
 }
 
 bool BaselineCacheIRCompiler::emitGuardHasGetterSetter() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   Register obj = allocator.useRegister(masm, reader.objOperandId());
   Address shapeAddr = stubAddress(reader.stubOffset());
 
   AutoScratchRegister scratch1(allocator, masm);
   AutoScratchRegister scratch2(allocator, masm);
 
   FailurePath* failure;
   if (!addFailurePath(&failure)) {
@@ -494,16 +507,17 @@ bool BaselineCacheIRCompiler::emitGuardH
   masm.mov(ReturnReg, scratch1);
   masm.PopRegsInMask(volatileRegs);
 
   masm.branchIfFalseBool(scratch1, failure->label());
   return true;
 }
 
 bool BaselineCacheIRCompiler::emitCallScriptedGetterResult() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   Register obj = allocator.useRegister(masm, reader.objOperandId());
   Address getterAddr(stubAddress(reader.stubOffset()));
   bool isCrossRealm = reader.readBool();
 
   AutoScratchRegister code(allocator, masm);
   AutoScratchRegister callee(allocator, masm);
   AutoScratchRegister scratch(allocator, masm);
 
@@ -567,16 +581,17 @@ bool BaselineCacheIRCompiler::emitCallSc
 }
 
 typedef bool (*CallNativeGetterFn)(JSContext*, HandleFunction, HandleObject,
                                    MutableHandleValue);
 static const VMFunction CallNativeGetterInfo =
     FunctionInfo<CallNativeGetterFn>(CallNativeGetter, "CallNativeGetter");
 
 bool BaselineCacheIRCompiler::emitCallNativeGetterResult() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   Register obj = allocator.useRegister(masm, reader.objOperandId());
   Address getterAddr(stubAddress(reader.stubOffset()));
 
   AutoScratchRegister scratch(allocator, masm);
 
   allocator.discardStack(masm);
 
   AutoStubFrame stubFrame(*this);
@@ -592,16 +607,17 @@ bool BaselineCacheIRCompiler::emitCallNa
     return false;
   }
 
   stubFrame.leave(masm);
   return true;
 }
 
 bool BaselineCacheIRCompiler::emitCallProxyGetResult() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   Register obj = allocator.useRegister(masm, reader.objOperandId());
   Address idAddr(stubAddress(reader.stubOffset()));
 
   AutoScratchRegister scratch(allocator, masm);
 
   allocator.discardStack(masm);
 
   AutoStubFrame stubFrame(*this);
@@ -617,16 +633,17 @@ bool BaselineCacheIRCompiler::emitCallPr
     return false;
   }
 
   stubFrame.leave(masm);
   return true;
 }
 
 bool BaselineCacheIRCompiler::emitCallProxyGetByValueResult() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   Register obj = allocator.useRegister(masm, reader.objOperandId());
   ValueOperand idVal = allocator.useValueRegister(masm, reader.valOperandId());
 
   AutoScratchRegister scratch(allocator, masm);
 
   allocator.discardStack(masm);
 
   AutoStubFrame stubFrame(*this);
@@ -639,16 +656,17 @@ bool BaselineCacheIRCompiler::emitCallPr
     return false;
   }
 
   stubFrame.leave(masm);
   return true;
 }
 
 bool BaselineCacheIRCompiler::emitCallProxyHasPropResult() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   Register obj = allocator.useRegister(masm, reader.objOperandId());
   ValueOperand idVal = allocator.useValueRegister(masm, reader.valOperandId());
   bool hasOwn = reader.readBool();
 
   AutoScratchRegister scratch(allocator, masm);
 
   allocator.discardStack(masm);
 
@@ -668,16 +686,17 @@ bool BaselineCacheIRCompiler::emitCallPr
     }
   }
 
   stubFrame.leave(masm);
   return true;
 }
 
 bool BaselineCacheIRCompiler::emitCallNativeGetElementResult() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   Register obj = allocator.useRegister(masm, reader.objOperandId());
   Register index = allocator.useRegister(masm, reader.int32OperandId());
 
   AutoScratchRegister scratch(allocator, masm);
 
   allocator.discardStack(masm);
 
   AutoStubFrame stubFrame(*this);
@@ -691,62 +710,67 @@ bool BaselineCacheIRCompiler::emitCallNa
     return false;
   }
 
   stubFrame.leave(masm);
   return true;
 }
 
 bool BaselineCacheIRCompiler::emitLoadUnboxedPropertyResult() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   AutoOutputRegister output(*this);
   Register obj = allocator.useRegister(masm, reader.objOperandId());
   AutoScratchRegisterMaybeOutput scratch(allocator, masm, output);
 
   JSValueType fieldType = reader.valueType();
   Address fieldOffset(stubAddress(reader.stubOffset()));
   masm.load32(fieldOffset, scratch);
   masm.loadUnboxedProperty(BaseIndex(obj, scratch, TimesOne), fieldType,
                            output);
   return true;
 }
 
 bool BaselineCacheIRCompiler::emitGuardFrameHasNoArgumentsObject() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   FailurePath* failure;
   if (!addFailurePath(&failure)) {
     return false;
   }
 
   masm.branchTest32(
       Assembler::NonZero,
       Address(BaselineFrameReg, BaselineFrame::reverseOffsetOfFlags()),
       Imm32(BaselineFrame::HAS_ARGS_OBJ), failure->label());
   return true;
 }
 
 bool BaselineCacheIRCompiler::emitLoadFrameCalleeResult() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   AutoOutputRegister output(*this);
   AutoScratchRegisterMaybeOutput scratch(allocator, masm, output);
 
   Address callee(BaselineFrameReg, BaselineFrame::offsetOfCalleeToken());
   masm.loadFunctionFromCalleeToken(callee, scratch);
   masm.tagValue(JSVAL_TYPE_OBJECT, scratch, output.valueReg());
   return true;
 }
 
 bool BaselineCacheIRCompiler::emitLoadFrameNumActualArgsResult() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   AutoOutputRegister output(*this);
   AutoScratchRegisterMaybeOutput scratch(allocator, masm, output);
 
   Address actualArgs(BaselineFrameReg, BaselineFrame::offsetOfNumActualArgs());
   masm.loadPtr(actualArgs, scratch);
   masm.tagValue(JSVAL_TYPE_INT32, scratch, output.valueReg());
   return true;
 }
 
 bool BaselineCacheIRCompiler::emitLoadTypedObjectResult() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   AutoOutputRegister output(*this);
   Register obj = allocator.useRegister(masm, reader.objOperandId());
   AutoScratchRegister scratch1(allocator, masm);
   AutoScratchRegister scratch2(allocator, masm);
 
   TypedThingLayout layout = reader.typedThingLayout();
   uint32_t typeDescr = reader.typeDescrKey();
   Address fieldOffset(stubAddress(reader.stubOffset()));
@@ -759,16 +783,17 @@ bool BaselineCacheIRCompiler::emitLoadTy
   masm.addPtr(scratch2, scratch1);
 
   Address fieldAddr(scratch1, 0);
   emitLoadTypedObjectResultShared(fieldAddr, scratch2, typeDescr, output);
   return true;
 }
 
 bool BaselineCacheIRCompiler::emitLoadFrameArgumentResult() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   AutoOutputRegister output(*this);
   Register index = allocator.useRegister(masm, reader.int32OperandId());
   AutoScratchRegister scratch1(allocator, masm);
   AutoScratchRegisterMaybeOutput scratch2(allocator, masm, output);
 
   FailurePath* failure;
   if (!addFailurePath(&failure)) {
     return false;
@@ -783,16 +808,17 @@ bool BaselineCacheIRCompiler::emitLoadFr
   // Load the argument.
   masm.loadValue(
       BaseValueIndex(BaselineFrameReg, index, BaselineFrame::offsetOfArg(0)),
       output.valueReg());
   return true;
 }
 
 bool BaselineCacheIRCompiler::emitLoadEnvironmentFixedSlotResult() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   AutoOutputRegister output(*this);
   Register obj = allocator.useRegister(masm, reader.objOperandId());
   AutoScratchRegisterMaybeOutput scratch(allocator, masm, output);
 
   FailurePath* failure;
   if (!addFailurePath(&failure)) {
     return false;
   }
@@ -804,16 +830,17 @@ bool BaselineCacheIRCompiler::emitLoadEn
   masm.branchTestMagic(Assembler::Equal, slot, failure->label());
 
   // Load the value.
   masm.loadValue(slot, output.valueReg());
   return true;
 }
 
 bool BaselineCacheIRCompiler::emitLoadEnvironmentDynamicSlotResult() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   AutoOutputRegister output(*this);
   Register obj = allocator.useRegister(masm, reader.objOperandId());
   AutoScratchRegister scratch(allocator, masm);
   AutoScratchRegisterMaybeOutput scratch2(allocator, masm, output);
 
   FailurePath* failure;
   if (!addFailurePath(&failure)) {
     return false;
@@ -827,25 +854,27 @@ bool BaselineCacheIRCompiler::emitLoadEn
   masm.branchTestMagic(Assembler::Equal, slot, failure->label());
 
   // Load the value.
   masm.loadValue(slot, output.valueReg());
   return true;
 }
 
 bool BaselineCacheIRCompiler::emitLoadStringResult() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   AutoOutputRegister output(*this);
   AutoScratchRegisterMaybeOutput scratch(allocator, masm, output);
 
   masm.loadPtr(stubAddress(reader.stubOffset()), scratch);
   masm.tagValue(JSVAL_TYPE_STRING, scratch, output.valueReg());
   return true;
 }
 
 bool BaselineCacheIRCompiler::emitCallStringSplitResult() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   Register str = allocator.useRegister(masm, reader.stringOperandId());
   Register sep = allocator.useRegister(masm, reader.stringOperandId());
   Address groupAddr(stubAddress(reader.stubOffset()));
 
   AutoScratchRegister scratch(allocator, masm);
   allocator.discardStack(masm);
 
   AutoStubFrame stubFrame(*this);
@@ -863,16 +892,17 @@ bool BaselineCacheIRCompiler::emitCallSt
     return false;
   }
 
   stubFrame.leave(masm);
   return true;
 }
 
 bool BaselineCacheIRCompiler::emitCompareStringResult() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   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);
 
@@ -962,16 +992,17 @@ bool BaselineCacheIRCompiler::callTypeUp
 
   stubFrame.leave(masm);
 
   masm.bind(&done);
   return true;
 }
 
 bool BaselineCacheIRCompiler::emitStoreSlotShared(bool isFixed) {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   ObjOperandId objId = reader.objOperandId();
   Address offsetAddr = stubAddress(reader.stubOffset());
 
   // Allocate the fixed registers first. These need to be fixed for
   // callTypeUpdateIC.
   AutoScratchRegister scratch1(allocator, masm, R1.scratchReg());
   ValueOperand val =
       allocator.useFixedValueRegister(masm, reader.valOperandId(), R0);
@@ -1002,24 +1033,27 @@ bool BaselineCacheIRCompiler::emitStoreS
     masm.storeValue(val, slot);
   }
 
   emitPostBarrierSlot(obj, val, scratch1);
   return true;
 }
 
 bool BaselineCacheIRCompiler::emitStoreFixedSlot() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   return emitStoreSlotShared(true);
 }
 
 bool BaselineCacheIRCompiler::emitStoreDynamicSlot() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   return emitStoreSlotShared(false);
 }
 
 bool BaselineCacheIRCompiler::emitAddAndStoreSlotShared(CacheOp op) {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   ObjOperandId objId = reader.objOperandId();
   Address offsetAddr = stubAddress(reader.stubOffset());
 
   // Allocate the fixed registers first. These need to be fixed for
   // callTypeUpdateIC.
   AutoScratchRegister scratch1(allocator, masm, R1.scratchReg());
   ValueOperand val =
       allocator.useFixedValueRegister(masm, reader.valOperandId(), R0);
@@ -1109,28 +1143,32 @@ bool BaselineCacheIRCompiler::emitAddAnd
     masm.storeValue(val, slot);
   }
 
   emitPostBarrierSlot(obj, val, scratch1);
   return true;
 }
 
 bool BaselineCacheIRCompiler::emitAddAndStoreFixedSlot() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   return emitAddAndStoreSlotShared(CacheOp::AddAndStoreFixedSlot);
 }
 
 bool BaselineCacheIRCompiler::emitAddAndStoreDynamicSlot() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   return emitAddAndStoreSlotShared(CacheOp::AddAndStoreDynamicSlot);
 }
 
 bool BaselineCacheIRCompiler::emitAllocateAndStoreDynamicSlot() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   return emitAddAndStoreSlotShared(CacheOp::AllocateAndStoreDynamicSlot);
 }
 
 bool BaselineCacheIRCompiler::emitStoreUnboxedProperty() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   ObjOperandId objId = reader.objOperandId();
   JSValueType fieldType = reader.valueType();
   Address offsetAddr = stubAddress(reader.stubOffset());
 
   // Allocate the fixed registers first. These need to be fixed for
   // callTypeUpdateIC.
   AutoScratchRegister scratch(allocator, masm, R1.scratchReg());
   ValueOperand val =
@@ -1160,16 +1198,17 @@ bool BaselineCacheIRCompiler::emitStoreU
 
   if (UnboxedTypeNeedsPostBarrier(fieldType)) {
     emitPostBarrierSlot(obj, val, scratch);
   }
   return true;
 }
 
 bool BaselineCacheIRCompiler::emitStoreTypedObjectReferenceProperty() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   ObjOperandId objId = reader.objOperandId();
   Address offsetAddr = stubAddress(reader.stubOffset());
   TypedThingLayout layout = reader.typedThingLayout();
   ReferenceType type = reader.referenceTypeDescrType();
 
   // Allocate the fixed registers first. These need to be fixed for
   // callTypeUpdateIC.
   AutoScratchRegister scratch1(allocator, masm, R1.scratchReg());
@@ -1196,16 +1235,17 @@ bool BaselineCacheIRCompiler::emitStoreT
 
   emitStoreTypedObjectReferenceProp(val, type, dest, scratch2);
   emitPostBarrierSlot(obj, val, scratch1);
 
   return true;
 }
 
 bool BaselineCacheIRCompiler::emitStoreTypedObjectScalarProperty() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   Register obj = allocator.useRegister(masm, reader.objOperandId());
   Address offsetAddr = stubAddress(reader.stubOffset());
   TypedThingLayout layout = reader.typedThingLayout();
   Scalar::Type type = reader.scalarType();
   ValueOperand val = allocator.useValueRegister(masm, reader.valOperandId());
   AutoScratchRegister scratch1(allocator, masm);
   AutoScratchRegister scratch2(allocator, masm);
 
@@ -1219,16 +1259,17 @@ bool BaselineCacheIRCompiler::emitStoreT
   masm.addPtr(offsetAddr, scratch1);
   Address dest(scratch1, 0);
 
   StoreToTypedArray(cx_, masm, type, val, dest, scratch2, failure->label());
   return true;
 }
 
 bool BaselineCacheIRCompiler::emitStoreDenseElement() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   ObjOperandId objId = reader.objOperandId();
   Int32OperandId indexId = reader.int32OperandId();
 
   // Allocate the fixed registers first. These need to be fixed for
   // callTypeUpdateIC.
   AutoScratchRegister scratch(allocator, masm, R1.scratchReg());
   ValueOperand val =
       allocator.useFixedValueRegister(masm, reader.valOperandId(), R0);
@@ -1296,16 +1337,17 @@ bool BaselineCacheIRCompiler::emitStoreD
   EmitPreBarrier(masm, element, MIRType::Value);
   masm.storeValue(val, element);
 
   emitPostBarrierElement(obj, val, scratch, index);
   return true;
 }
 
 bool BaselineCacheIRCompiler::emitStoreDenseElementHole() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   ObjOperandId objId = reader.objOperandId();
   Int32OperandId indexId = reader.int32OperandId();
 
   // Allocate the fixed registers first. These need to be fixed for
   // callTypeUpdateIC.
   AutoScratchRegister scratch(allocator, masm, R1.scratchReg());
   ValueOperand val =
       allocator.useFixedValueRegister(masm, reader.valOperandId(), R0);
@@ -1443,16 +1485,17 @@ bool BaselineCacheIRCompiler::emitStoreD
   masm.bind(&doStore);
   masm.storeValue(val, element);
 
   emitPostBarrierElement(obj, val, scratch, index);
   return true;
 }
 
 bool BaselineCacheIRCompiler::emitArrayPush() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   ObjOperandId objId = reader.objOperandId();
   ValOperandId rhsId = reader.valOperandId();
 
   // Allocate the fixed registers first. These need to be fixed for
   // callTypeUpdateIC.
   AutoScratchRegister scratch(allocator, masm, R1.scratchReg());
   ValueOperand val = allocator.useFixedValueRegister(masm, rhsId, R0);
 
@@ -1556,16 +1599,17 @@ bool BaselineCacheIRCompiler::emitArrayP
   // Return value is new length.
   masm.add32(Imm32(1), scratchLength);
   masm.tagValue(JSVAL_TYPE_INT32, scratchLength, val);
 
   return true;
 }
 
 bool BaselineCacheIRCompiler::emitStoreTypedElement() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   Register obj = allocator.useRegister(masm, reader.objOperandId());
   Register index = allocator.useRegister(masm, reader.int32OperandId());
   ValueOperand val = allocator.useValueRegister(masm, reader.valOperandId());
 
   TypedThingLayout layout = reader.typedThingLayout();
   Scalar::Type type = reader.scalarType();
   bool handleOOB = reader.readBool();
 
@@ -1611,16 +1655,17 @@ bool BaselineCacheIRCompiler::emitStoreT
 }
 
 typedef bool (*CallNativeSetterFn)(JSContext*, HandleFunction, HandleObject,
                                    HandleValue);
 static const VMFunction CallNativeSetterInfo =
     FunctionInfo<CallNativeSetterFn>(CallNativeSetter, "CallNativeSetter");
 
 bool BaselineCacheIRCompiler::emitCallNativeSetter() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   Register obj = allocator.useRegister(masm, reader.objOperandId());
   Address setterAddr(stubAddress(reader.stubOffset()));
   ValueOperand val = allocator.useValueRegister(masm, reader.valOperandId());
 
   AutoScratchRegister scratch(allocator, masm);
 
   allocator.discardStack(masm);
 
@@ -1638,16 +1683,17 @@ bool BaselineCacheIRCompiler::emitCallNa
     return false;
   }
 
   stubFrame.leave(masm);
   return true;
 }
 
 bool BaselineCacheIRCompiler::emitCallScriptedSetter() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   AutoScratchRegister scratch1(allocator, masm);
   AutoScratchRegister scratch2(allocator, masm);
 
   Register obj = allocator.useRegister(masm, reader.objOperandId());
   Address setterAddr(stubAddress(reader.stubOffset()));
   ValueOperand val = allocator.useValueRegister(masm, reader.valOperandId());
   bool isCrossRealm = reader.readBool();
 
@@ -1716,16 +1762,17 @@ bool BaselineCacheIRCompiler::emitCallSc
   if (isCrossRealm) {
     masm.switchToBaselineFrameRealm(R1.scratchReg());
   }
 
   return true;
 }
 
 bool BaselineCacheIRCompiler::emitCallSetArrayLength() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   Register obj = allocator.useRegister(masm, reader.objOperandId());
   bool strict = reader.readBool();
   ValueOperand val = allocator.useValueRegister(masm, reader.valOperandId());
 
   AutoScratchRegister scratch(allocator, masm);
 
   allocator.discardStack(masm);
 
@@ -1740,16 +1787,17 @@ bool BaselineCacheIRCompiler::emitCallSe
     return false;
   }
 
   stubFrame.leave(masm);
   return true;
 }
 
 bool BaselineCacheIRCompiler::emitCallProxySet() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   Register obj = allocator.useRegister(masm, reader.objOperandId());
   ValueOperand val = allocator.useValueRegister(masm, reader.valOperandId());
   Address idAddr(stubAddress(reader.stubOffset()));
   bool strict = reader.readBool();
 
   AutoScratchRegister scratch(allocator, masm);
 
   allocator.discardStack(masm);
@@ -1769,16 +1817,17 @@ bool BaselineCacheIRCompiler::emitCallPr
     return false;
   }
 
   stubFrame.leave(masm);
   return true;
 }
 
 bool BaselineCacheIRCompiler::emitCallProxySetByValue() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   Register obj = allocator.useRegister(masm, reader.objOperandId());
   ValueOperand idVal = allocator.useValueRegister(masm, reader.valOperandId());
   ValueOperand val = allocator.useValueRegister(masm, reader.valOperandId());
   bool strict = reader.readBool();
 
   allocator.discardStack(masm);
 
   // We need a scratch register but we don't have any registers available on
@@ -1803,16 +1852,17 @@ bool BaselineCacheIRCompiler::emitCallPr
     return false;
   }
 
   stubFrame.leave(masm);
   return true;
 }
 
 bool BaselineCacheIRCompiler::emitCallAddOrUpdateSparseElementHelper() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   Register obj = allocator.useRegister(masm, reader.objOperandId());
   Register id = allocator.useRegister(masm, reader.int32OperandId());
   ValueOperand val = allocator.useValueRegister(masm, reader.valOperandId());
   bool strict = reader.readBool();
   AutoScratchRegister scratch(allocator, masm);
 
   allocator.discardStack(masm);
 
@@ -1827,16 +1877,17 @@ bool BaselineCacheIRCompiler::emitCallAd
   if (!callVM(masm, AddOrUpdateSparseElementHelperInfo)) {
     return false;
   }
   stubFrame.leave(masm);
   return true;
 }
 
 bool BaselineCacheIRCompiler::emitCallGetSparseElementResult() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   Register obj = allocator.useRegister(masm, reader.objOperandId());
   Register id = allocator.useRegister(masm, reader.int32OperandId());
   AutoScratchRegister scratch(allocator, masm);
 
   allocator.discardStack(masm);
 
   AutoStubFrame stubFrame(*this);
   stubFrame.enter(masm, scratch);
@@ -1847,16 +1898,17 @@ bool BaselineCacheIRCompiler::emitCallGe
   if (!callVM(masm, GetSparseElementHelperInfo)) {
     return false;
   }
   stubFrame.leave(masm);
   return true;
 }
 
 bool BaselineCacheIRCompiler::emitMegamorphicSetElement() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   Register obj = allocator.useRegister(masm, reader.objOperandId());
   ValueOperand idVal = allocator.useValueRegister(masm, reader.valOperandId());
   ValueOperand val = allocator.useValueRegister(masm, reader.valOperandId());
   bool strict = reader.readBool();
 
   allocator.discardStack(masm);
 
   // We need a scratch register but we don't have any registers available on
@@ -1882,36 +1934,40 @@ bool BaselineCacheIRCompiler::emitMegamo
     return false;
   }
 
   stubFrame.leave(masm);
   return true;
 }
 
 bool BaselineCacheIRCompiler::emitTypeMonitorResult() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   allocator.discardStack(masm);
   EmitEnterTypeMonitorIC(masm);
   return true;
 }
 
 bool BaselineCacheIRCompiler::emitReturnFromIC() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   allocator.discardStack(masm);
   EmitReturnFromIC(masm);
   return true;
 }
 
 bool BaselineCacheIRCompiler::emitLoadStackValue() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   ValueOperand val = allocator.defineValueRegister(masm, reader.valOperandId());
   Address addr =
       allocator.addressOf(masm, BaselineFrameSlot(reader.uint32Immediate()));
   masm.loadValue(addr, val);
   return true;
 }
 
 bool BaselineCacheIRCompiler::emitGuardAndGetIterator() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   Register obj = allocator.useRegister(masm, reader.objOperandId());
 
   AutoScratchRegister scratch1(allocator, masm);
   AutoScratchRegister scratch2(allocator, masm);
   AutoScratchRegister niScratch(allocator, masm);
 
   Address iterAddr(stubAddress(reader.stubOffset()));
   Address enumeratorsAddr(stubAddress(reader.stubOffset()));
@@ -1950,16 +2006,17 @@ bool BaselineCacheIRCompiler::emitGuardA
   masm.loadPtr(enumeratorsAddr, scratch1);
   masm.loadPtr(Address(scratch1, 0), scratch1);
   emitRegisterEnumerator(scratch1, niScratch, scratch2);
 
   return true;
 }
 
 bool BaselineCacheIRCompiler::emitGuardDOMExpandoMissingOrGuardShape() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   ValueOperand val = allocator.useValueRegister(masm, reader.valOperandId());
   AutoScratchRegister shapeScratch(allocator, masm);
   AutoScratchRegister objScratch(allocator, masm);
   Address shapeAddr(stubAddress(reader.stubOffset()));
 
   FailurePath* failure;
   if (!addFailurePath(&failure)) {
     return false;
@@ -1976,16 +2033,17 @@ bool BaselineCacheIRCompiler::emitGuardD
   masm.branchTestObjShapeNoSpectreMitigations(Assembler::NotEqual, objScratch,
                                               shapeScratch, failure->label());
 
   masm.bind(&done);
   return true;
 }
 
 bool BaselineCacheIRCompiler::emitLoadDOMExpandoValueGuardGeneration() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   Register obj = allocator.useRegister(masm, reader.objOperandId());
   Address expandoAndGenerationAddr(stubAddress(reader.stubOffset()));
   Address generationAddr(stubAddress(reader.stubOffset()));
 
   AutoScratchRegister scratch(allocator, masm);
   ValueOperand output =
       allocator.defineValueRegister(masm, reader.valOperandId());
 
@@ -2319,16 +2377,17 @@ uint8_t* ICCacheIR_Monitored::stubDataSt
   return reinterpret_cast<uint8_t*>(this) + stubInfo_->stubDataOffset();
 }
 
 uint8_t* ICCacheIR_Updated::stubDataStart() {
   return reinterpret_cast<uint8_t*>(this) + stubInfo_->stubDataOffset();
 }
 
 bool BaselineCacheIRCompiler::emitCallStringConcatResult() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   AutoOutputRegister output(*this);
   Register lhs = allocator.useRegister(masm, reader.stringOperandId());
   Register rhs = allocator.useRegister(masm, reader.stringOperandId());
   AutoScratchRegisterMaybeOutput scratch(allocator, masm, output);
 
   allocator.discardStack(masm);
 
   AutoStubFrame stubFrame(*this);
@@ -2343,16 +2402,17 @@ bool BaselineCacheIRCompiler::emitCallSt
 
   masm.tagValue(JSVAL_TYPE_STRING, ReturnReg, output.valueReg());
 
   stubFrame.leave(masm);
   return true;
 }
 
 bool BaselineCacheIRCompiler::emitCallStringObjectConcatResult() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   ValueOperand lhs = allocator.useValueRegister(masm, reader.valOperandId());
   ValueOperand rhs = allocator.useValueRegister(masm, reader.valOperandId());
 
   allocator.discardStack(masm);
 
   // For the expression decompiler
   EmitRestoreTailCallReg(masm);
   masm.pushValue(lhs);
--- a/js/src/jit/CacheIRCompiler.cpp
+++ b/js/src/jit/CacheIRCompiler.cpp
@@ -1259,16 +1259,17 @@ bool CacheIRCompiler::addFailurePath(Fai
     return false;
   }
 
   *failure = &failurePaths.back();
   return true;
 }
 
 bool CacheIRCompiler::emitFailurePath(size_t index) {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   FailurePath& failure = failurePaths[index];
 
   allocator.setStackPushed(failure.stackPushed());
 
   for (size_t i = 0; i < writer_.numInputOperands(); i++) {
     allocator.setOperandLocation(i, failure.input(i));
   }
 
@@ -1277,16 +1278,17 @@ bool CacheIRCompiler::emitFailurePath(si
   }
 
   masm.bind(failure.label());
   allocator.restoreInputState(masm);
   return true;
 }
 
 bool CacheIRCompiler::emitGuardIsNumber() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   ValOperandId inputId = reader.valOperandId();
   JSValueType knownType = allocator.knownType(inputId);
 
   // Doubles and ints are numbers!
   if (knownType == JSVAL_TYPE_DOUBLE || knownType == JSVAL_TYPE_INT32) {
     return true;
   }
 
@@ -1296,31 +1298,33 @@ bool CacheIRCompiler::emitGuardIsNumber(
     return false;
   }
 
   masm.branchTestNumber(Assembler::NotEqual, input, failure->label());
   return true;
 }
 
 bool CacheIRCompiler::emitGuardIsObject() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   ValOperandId inputId = reader.valOperandId();
   if (allocator.knownType(inputId) == JSVAL_TYPE_OBJECT) {
     return true;
   }
 
   ValueOperand input = allocator.useValueRegister(masm, inputId);
   FailurePath* failure;
   if (!addFailurePath(&failure)) {
     return false;
   }
   masm.branchTestObject(Assembler::NotEqual, input, failure->label());
   return true;
 }
 
 bool CacheIRCompiler::emitGuardIsNullOrUndefined() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   ValOperandId inputId = reader.valOperandId();
   JSValueType knownType = allocator.knownType(inputId);
   if (knownType == JSVAL_TYPE_UNDEFINED || knownType == JSVAL_TYPE_NULL) {
     return true;
   }
 
   ValueOperand input = allocator.useValueRegister(masm, inputId);
   FailurePath* failure;
@@ -1332,16 +1336,17 @@ bool CacheIRCompiler::emitGuardIsNullOrU
   masm.branchTestNull(Assembler::Equal, input, &success);
   masm.branchTestUndefined(Assembler::NotEqual, input, failure->label());
 
   masm.bind(&success);
   return true;
 }
 
 bool CacheIRCompiler::emitGuardIsNotNullOrUndefined() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   ValOperandId inputId = reader.valOperandId();
   JSValueType knownType = allocator.knownType(inputId);
   if (knownType == JSVAL_TYPE_UNDEFINED || knownType == JSVAL_TYPE_NULL) {
     return false;
   }
 
   ValueOperand input = allocator.useValueRegister(masm, inputId);
   FailurePath* failure;
@@ -1351,16 +1356,17 @@ bool CacheIRCompiler::emitGuardIsNotNull
 
   masm.branchTestNull(Assembler::Equal, input, failure->label());
   masm.branchTestUndefined(Assembler::Equal, input, failure->label());
 
   return true;
 }
 
 bool CacheIRCompiler::emitGuardIsNull() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   ValOperandId inputId = reader.valOperandId();
   JSValueType knownType = allocator.knownType(inputId);
   if (knownType == JSVAL_TYPE_NULL) {
     return true;
   }
 
   ValueOperand input = allocator.useValueRegister(masm, inputId);
   FailurePath* failure;
@@ -1369,16 +1375,17 @@ bool CacheIRCompiler::emitGuardIsNull() 
   }
 
   Label success;
   masm.branchTestNull(Assembler::NotEqual, input, failure->label());
   return true;
 }
 
 bool CacheIRCompiler::emitGuardIsUndefined() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   ValOperandId inputId = reader.valOperandId();
   JSValueType knownType = allocator.knownType(inputId);
   if (knownType == JSVAL_TYPE_UNDEFINED) {
     return true;
   }
 
   ValueOperand input = allocator.useValueRegister(masm, inputId);
   FailurePath* failure;
@@ -1386,16 +1393,17 @@ bool CacheIRCompiler::emitGuardIsUndefin
     return false;
   }
 
   masm.branchTestUndefined(Assembler::NotEqual, input, failure->label());
   return true;
 }
 
 bool CacheIRCompiler::emitGuardIsObjectOrNull() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   ValOperandId inputId = reader.valOperandId();
   JSValueType knownType = allocator.knownType(inputId);
   if (knownType == JSVAL_TYPE_OBJECT || knownType == JSVAL_TYPE_NULL) {
     return true;
   }
 
   ValueOperand input = allocator.useValueRegister(masm, inputId);
   FailurePath* failure;
@@ -1406,16 +1414,17 @@ bool CacheIRCompiler::emitGuardIsObjectO
   Label done;
   masm.branchTestObject(Assembler::Equal, input, &done);
   masm.branchTestNull(Assembler::NotEqual, input, failure->label());
   masm.bind(&done);
   return true;
 }
 
 bool CacheIRCompiler::emitGuardIsBoolean() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   ValOperandId inputId = reader.valOperandId();
   Register output = allocator.defineRegister(masm, reader.int32OperandId());
 
   if (allocator.knownType(inputId) == JSVAL_TYPE_BOOLEAN) {
     Register input = allocator.useRegister(masm, Int32OperandId(inputId.id()));
     masm.move32(input, output);
     return true;
   }
@@ -1427,46 +1436,49 @@ bool CacheIRCompiler::emitGuardIsBoolean
   }
 
   masm.branchTestBoolean(Assembler::NotEqual, input, failure->label());
   masm.unboxBoolean(input, output);
   return true;
 }
 
 bool CacheIRCompiler::emitGuardIsString() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   ValOperandId inputId = reader.valOperandId();
   if (allocator.knownType(inputId) == JSVAL_TYPE_STRING) {
     return true;
   }
 
   ValueOperand input = allocator.useValueRegister(masm, inputId);
   FailurePath* failure;
   if (!addFailurePath(&failure)) {
     return false;
   }
   masm.branchTestString(Assembler::NotEqual, input, failure->label());
   return true;
 }
 
 bool CacheIRCompiler::emitGuardIsSymbol() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   ValOperandId inputId = reader.valOperandId();
   if (allocator.knownType(inputId) == JSVAL_TYPE_SYMBOL) {
     return true;
   }
 
   ValueOperand input = allocator.useValueRegister(masm, inputId);
   FailurePath* failure;
   if (!addFailurePath(&failure)) {
     return false;
   }
   masm.branchTestSymbol(Assembler::NotEqual, input, failure->label());
   return true;
 }
 
 bool CacheIRCompiler::emitGuardIsInt32() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   ValOperandId inputId = reader.valOperandId();
   Register output = allocator.defineRegister(masm, reader.int32OperandId());
 
   if (allocator.knownType(inputId) == JSVAL_TYPE_INT32) {
     Register input = allocator.useRegister(masm, Int32OperandId(inputId.id()));
     masm.move32(input, output);
     return true;
   }
@@ -1478,16 +1490,17 @@ bool CacheIRCompiler::emitGuardIsInt32()
   }
 
   masm.branchTestInt32(Assembler::NotEqual, input, failure->label());
   masm.unboxInt32(input, output);
   return true;
 }
 
 bool CacheIRCompiler::emitGuardIsInt32Index() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   ValOperandId inputId = reader.valOperandId();
   Register output = allocator.defineRegister(masm, reader.int32OperandId());
 
   if (allocator.knownType(inputId) == JSVAL_TYPE_INT32) {
     Register input = allocator.useRegister(masm, Int32OperandId(inputId.id()));
     masm.move32(input, output);
     return true;
   }
@@ -1528,16 +1541,17 @@ bool CacheIRCompiler::emitGuardIsInt32In
     masm.jump(failure->label());
   }
 
   masm.bind(&done);
   return true;
 }
 
 bool CacheIRCompiler::emitGuardType() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   ValOperandId inputId = reader.valOperandId();
   JSValueType type = reader.valueType();
 
   if (allocator.knownType(inputId) == type) {
     return true;
   }
 
   ValueOperand input = allocator.useValueRegister(masm, inputId);
@@ -1572,16 +1586,17 @@ bool CacheIRCompiler::emitGuardType() {
     default:
       MOZ_CRASH("Unexpected type");
   }
 
   return true;
 }
 
 bool CacheIRCompiler::emitGuardClass() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   ObjOperandId objId = reader.objOperandId();
   Register obj = allocator.useRegister(masm, objId);
   AutoScratchRegister scratch(allocator, masm);
 
   FailurePath* failure;
   if (!addFailurePath(&failure)) {
     return false;
   }
@@ -1613,16 +1628,17 @@ bool CacheIRCompiler::emitGuardClass() {
     masm.branchTestObjClassNoSpectreMitigations(Assembler::NotEqual, obj, clasp,
                                                 scratch, failure->label());
   }
 
   return true;
 }
 
 bool CacheIRCompiler::emitGuardIsExtensible() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   Register obj = allocator.useRegister(masm, reader.objOperandId());
   AutoScratchRegister scratch(allocator, masm);
 
   FailurePath* failure;
   if (!addFailurePath(&failure)) {
     return false;
   }
 
@@ -1640,16 +1656,17 @@ bool CacheIRCompiler::emitGuardIsExtensi
   // Spectre-style checks are not needed here because we do not
   // interpret data based on this check.
   masm.branch32(Assembler::Equal, scratch, Imm32(js::BaseShape::NOT_EXTENSIBLE),
                 failure->label());
   return true;
 }
 
 bool CacheIRCompiler::emitGuardIsNativeFunction() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   Register obj = allocator.useRegister(masm, reader.objOperandId());
   JSNative nativeFunc = reinterpret_cast<JSNative>(reader.pointer());
   AutoScratchRegister scratch(allocator, masm);
 
   FailurePath* failure;
   if (!addFailurePath(&failure)) {
     return false;
   }
@@ -1662,16 +1679,17 @@ bool CacheIRCompiler::emitGuardIsNativeF
   // Ensure function native matches.
   masm.branchPtr(Assembler::NotEqual,
                  Address(obj, JSFunction::offsetOfNativeOrEnv()),
                  ImmPtr(nativeFunc), failure->label());
   return true;
 }
 
 bool CacheIRCompiler::emitGuardFunctionPrototype() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   Register obj = allocator.useRegister(masm, reader.objOperandId());
   Register prototypeObject = allocator.useRegister(masm, reader.objOperandId());
 
   // Allocate registers before the failure path to make sure they're registered
   // by addFailurePath.
   AutoScratchRegister scratch1(allocator, masm);
   AutoScratchRegister scratch2(allocator, masm);
 
@@ -1689,129 +1707,138 @@ bool CacheIRCompiler::emitGuardFunctionP
   masm.unboxObject(prototypeSlot, scratch1);
   masm.branchPtr(Assembler::NotEqual, prototypeObject, scratch1,
                  failure->label());
 
   return true;
 }
 
 bool CacheIRCompiler::emitGuardIsNativeObject() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   Register obj = allocator.useRegister(masm, reader.objOperandId());
   AutoScratchRegister scratch(allocator, masm);
 
   FailurePath* failure;
   if (!addFailurePath(&failure)) {
     return false;
   }
 
   masm.branchIfNonNativeObj(obj, scratch, failure->label());
   return true;
 }
 
 bool CacheIRCompiler::emitGuardIsProxy() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   Register obj = allocator.useRegister(masm, reader.objOperandId());
   AutoScratchRegister scratch(allocator, masm);
 
   FailurePath* failure;
   if (!addFailurePath(&failure)) {
     return false;
   }
 
   masm.branchTestObjectIsProxy(false, obj, scratch, failure->label());
   return true;
 }
 
 bool CacheIRCompiler::emitGuardNotDOMProxy() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   Register obj = allocator.useRegister(masm, reader.objOperandId());
   AutoScratchRegister scratch(allocator, masm);
 
   FailurePath* failure;
   if (!addFailurePath(&failure)) {
     return false;
   }
 
   masm.branchTestProxyHandlerFamily(Assembler::Equal, obj, scratch,
                                     GetDOMProxyHandlerFamily(),
                                     failure->label());
   return true;
 }
 
 bool CacheIRCompiler::emitGuardSpecificInt32Immediate() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   Register reg = allocator.useRegister(masm, reader.int32OperandId());
   int32_t ival = reader.int32Immediate();
   Assembler::Condition cond = (Assembler::Condition)reader.readByte();
 
   FailurePath* failure;
   if (!addFailurePath(&failure)) {
     return false;
   }
 
   masm.branch32(Assembler::InvertCondition(cond), reg, Imm32(ival),
                 failure->label());
   return true;
 }
 
 bool CacheIRCompiler::emitGuardMagicValue() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   ValueOperand val = allocator.useValueRegister(masm, reader.valOperandId());
   JSWhyMagic magic = reader.whyMagic();
 
   FailurePath* failure;
   if (!addFailurePath(&failure)) {
     return false;
   }
 
   masm.branchTestMagicValue(Assembler::NotEqual, val, magic, failure->label());
   return true;
 }
 
 bool CacheIRCompiler::emitGuardNoUnboxedExpando() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   Register obj = allocator.useRegister(masm, reader.objOperandId());
 
   FailurePath* failure;
   if (!addFailurePath(&failure)) {
     return false;
   }
 
   Address expandoAddr(obj, UnboxedPlainObject::offsetOfExpando());
   masm.branchPtr(Assembler::NotEqual, expandoAddr, ImmWord(0),
                  failure->label());
   return true;
 }
 
 bool CacheIRCompiler::emitGuardAndLoadUnboxedExpando() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   Register obj = allocator.useRegister(masm, reader.objOperandId());
   Register output = allocator.defineRegister(masm, reader.objOperandId());
 
   FailurePath* failure;
   if (!addFailurePath(&failure)) {
     return false;
   }
 
   Address expandoAddr(obj, UnboxedPlainObject::offsetOfExpando());
   masm.loadPtr(expandoAddr, output);
   masm.branchTestPtr(Assembler::Zero, output, output, failure->label());
   return true;
 }
 
 bool CacheIRCompiler::emitGuardNoDetachedTypedObjects() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   FailurePath* failure;
   if (!addFailurePath(&failure)) {
     return false;
   }
 
   // All stubs manipulating typed objects must check the zone-wide flag
   // indicating whether their underlying storage might be detached, to bail
   // out if needed.
   uint32_t* address = &cx_->zone()->detachedTypedObjects;
   masm.branch32(Assembler::NotEqual, AbsoluteAddress(address), Imm32(0),
                 failure->label());
   return true;
 }
 
 bool CacheIRCompiler::emitGuardNoDenseElements() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   Register obj = allocator.useRegister(masm, reader.objOperandId());
   AutoScratchRegister scratch(allocator, masm);
 
   FailurePath* failure;
   if (!addFailurePath(&failure)) {
     return false;
   }
 
@@ -1820,16 +1847,17 @@ bool CacheIRCompiler::emitGuardNoDenseEl
 
   // Make sure there are no dense elements.
   Address initLength(scratch, ObjectElements::offsetOfInitializedLength());
   masm.branch32(Assembler::NotEqual, initLength, Imm32(0), failure->label());
   return true;
 }
 
 bool CacheIRCompiler::emitGuardAndGetNumberFromString() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   Register str = allocator.useRegister(masm, reader.stringOperandId());
   ValueOperand output =
       allocator.defineValueRegister(masm, reader.valOperandId());
   AutoScratchRegister scratch(allocator, masm);
 
   FailurePath* failure;
   if (!addFailurePath(&failure)) {
     return false;
@@ -1882,16 +1910,17 @@ bool CacheIRCompiler::emitGuardAndGetNum
     masm.boxDouble(FloatReg0, output, FloatReg0);
     masm.freeStack(sizeof(double));
   }
   masm.bind(&done);
   return true;
 }
 
 bool CacheIRCompiler::emitGuardAndGetIndexFromString() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   Register str = allocator.useRegister(masm, reader.stringOperandId());
   Register output = allocator.defineRegister(masm, reader.int32OperandId());
 
   FailurePath* failure;
   if (!addFailurePath(&failure)) {
     return false;
   }
 
@@ -1918,64 +1947,70 @@ bool CacheIRCompiler::emitGuardAndGetInd
     masm.branchTest32(Assembler::Signed, output, output, failure->label());
   }
 
   masm.bind(&done);
   return true;
 }
 
 bool CacheIRCompiler::emitLoadProto() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   Register obj = allocator.useRegister(masm, reader.objOperandId());
   Register reg = allocator.defineRegister(masm, reader.objOperandId());
   masm.loadObjProto(obj, reg);
   return true;
 }
 
 bool CacheIRCompiler::emitLoadEnclosingEnvironment() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   Register obj = allocator.useRegister(masm, reader.objOperandId());
   Register reg = allocator.defineRegister(masm, reader.objOperandId());
   masm.unboxObject(
       Address(obj, EnvironmentObject::offsetOfEnclosingEnvironment()), reg);
   return true;
 }
 
 bool CacheIRCompiler::emitLoadWrapperTarget() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   Register obj = allocator.useRegister(masm, reader.objOperandId());
   Register reg = allocator.defineRegister(masm, reader.objOperandId());
 
   masm.loadPtr(Address(obj, ProxyObject::offsetOfReservedSlots()), reg);
   masm.unboxObject(
       Address(reg, detail::ProxyReservedSlots::offsetOfPrivateSlot()), reg);
   return true;
 }
 
 bool CacheIRCompiler::emitLoadValueTag() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   ValueOperand val = allocator.useValueRegister(masm, reader.valOperandId());
   Register res = allocator.defineRegister(masm, reader.valueTagOperandId());
 
   Register tag = masm.extractTag(val, res);
   if (tag != res) {
     masm.mov(tag, res);
   }
   return true;
 }
 
 bool CacheIRCompiler::emitLoadDOMExpandoValue() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   Register obj = allocator.useRegister(masm, reader.objOperandId());
   ValueOperand val = allocator.defineValueRegister(masm, reader.valOperandId());
 
   masm.loadPtr(Address(obj, ProxyObject::offsetOfReservedSlots()),
                val.scratchReg());
   masm.loadValue(Address(val.scratchReg(),
                          detail::ProxyReservedSlots::offsetOfPrivateSlot()),
                  val);
   return true;
 }
 
 bool CacheIRCompiler::emitLoadDOMExpandoValueIgnoreGeneration() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   Register obj = allocator.useRegister(masm, reader.objOperandId());
   ValueOperand output =
       allocator.defineValueRegister(masm, reader.valOperandId());
 
   // Determine the expando's Address.
   Register scratch = output.scratchReg();
   masm.loadPtr(Address(obj, ProxyObject::offsetOfReservedSlots()), scratch);
   Address expandoAddr(scratch,
@@ -1994,16 +2029,17 @@ bool CacheIRCompiler::emitLoadDOMExpando
 
   // Load expandoAndGeneration->expando into the output Value register.
   masm.loadValue(Address(scratch, ExpandoAndGeneration::offsetOfExpando()),
                  output);
   return true;
 }
 
 bool CacheIRCompiler::emitLoadUndefinedResult() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   AutoOutputRegister output(*this);
   if (output.hasValue()) {
     masm.moveValue(UndefinedValue(), output.valueReg());
   } else {
     masm.assumeUnreachable("Should have monitored undefined result");
   }
   return true;
 }
@@ -2015,16 +2051,17 @@ static void EmitStoreBoolean(MacroAssemb
     masm.moveValue(val, output.valueReg());
   } else {
     MOZ_ASSERT(output.type() == JSVAL_TYPE_BOOLEAN);
     masm.movePtr(ImmWord(b), output.typedReg().gpr());
   }
 }
 
 bool CacheIRCompiler::emitLoadBooleanResult() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   AutoOutputRegister output(*this);
   bool b = reader.readBool();
   EmitStoreBoolean(masm, b, output);
 
   return true;
 }
 
 static void EmitStoreResult(MacroAssembler& masm, Register reg,
@@ -2041,16 +2078,17 @@ static void EmitStoreResult(MacroAssembl
   if (type == output.type()) {
     masm.mov(reg, output.typedReg().gpr());
     return;
   }
   masm.assumeUnreachable("Should have monitored result");
 }
 
 bool CacheIRCompiler::emitLoadInt32ArrayLengthResult() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   AutoOutputRegister output(*this);
   Register obj = allocator.useRegister(masm, reader.objOperandId());
   AutoScratchRegisterMaybeOutput scratch(allocator, masm, output);
 
   FailurePath* failure;
   if (!addFailurePath(&failure)) {
     return false;
   }
@@ -2060,63 +2098,68 @@ bool CacheIRCompiler::emitLoadInt32Array
 
   // Guard length fits in an int32.
   masm.branchTest32(Assembler::Signed, scratch, scratch, failure->label());
   EmitStoreResult(masm, scratch, JSVAL_TYPE_INT32, output);
   return true;
 }
 
 bool CacheIRCompiler::emitDoubleAddResult() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   AutoOutputRegister output(*this);
 
   // Float register must be preserved. The BinaryArith ICs use
   // the fact that baseline has them available, as well as fixed temps on
   // LBinaryCache.
   allocator.ensureDoubleRegister(masm, reader.valOperandId(), FloatReg0);
   allocator.ensureDoubleRegister(masm, reader.valOperandId(), FloatReg1);
 
   masm.addDouble(FloatReg1, FloatReg0);
   masm.boxDouble(FloatReg0, output.valueReg(), FloatReg0);
 
   return true;
 }
 bool CacheIRCompiler::emitDoubleSubResult() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   AutoOutputRegister output(*this);
 
   allocator.ensureDoubleRegister(masm, reader.valOperandId(), FloatReg0);
   allocator.ensureDoubleRegister(masm, reader.valOperandId(), FloatReg1);
 
   masm.subDouble(FloatReg1, FloatReg0);
   masm.boxDouble(FloatReg0, output.valueReg(), FloatReg0);
 
   return true;
 }
 bool CacheIRCompiler::emitDoubleMulResult() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   AutoOutputRegister output(*this);
 
   allocator.ensureDoubleRegister(masm, reader.valOperandId(), FloatReg0);
   allocator.ensureDoubleRegister(masm, reader.valOperandId(), FloatReg1);
 
   masm.mulDouble(FloatReg1, FloatReg0);
   masm.boxDouble(FloatReg0, output.valueReg(), FloatReg0);
 
   return true;
 }
 bool CacheIRCompiler::emitDoubleDivResult() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   AutoOutputRegister output(*this);
 
   allocator.ensureDoubleRegister(masm, reader.valOperandId(), FloatReg0);
   allocator.ensureDoubleRegister(masm, reader.valOperandId(), FloatReg1);
 
   masm.divDouble(FloatReg1, FloatReg0);
   masm.boxDouble(FloatReg0, output.valueReg(), FloatReg0);
 
   return true;
 }
 bool CacheIRCompiler::emitDoubleModResult() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   AutoOutputRegister output(*this);
   AutoScratchRegisterMaybeOutput scratch(allocator, masm, output);
 
   allocator.ensureDoubleRegister(masm, reader.valOperandId(), FloatReg0);
   allocator.ensureDoubleRegister(masm, reader.valOperandId(), FloatReg1);
 
   LiveRegisterSet save(GeneralRegisterSet::Volatile(), liveVolatileFloatRegs());
   masm.PushRegsInMask(save);
@@ -2132,47 +2175,50 @@ bool CacheIRCompiler::emitDoubleModResul
   masm.PopRegsInMaskIgnore(save, ignore);
 
   masm.boxDouble(FloatReg0, output.valueReg(), FloatReg0);
 
   return true;
 }
 
 bool CacheIRCompiler::emitInt32AddResult() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   AutoOutputRegister output(*this);
   Register lhs = allocator.useRegister(masm, reader.int32OperandId());
   Register rhs = allocator.useRegister(masm, reader.int32OperandId());
 
   FailurePath* failure;
   if (!addFailurePath(&failure)) {
     return false;
   }
 
   masm.branchAdd32(Assembler::Overflow, lhs, rhs, failure->label());
   EmitStoreResult(masm, rhs, JSVAL_TYPE_INT32, output);
 
   return true;
 }
 bool CacheIRCompiler::emitInt32SubResult() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   AutoOutputRegister output(*this);
   Register lhs = allocator.useRegister(masm, reader.int32OperandId());
   Register rhs = allocator.useRegister(masm, reader.int32OperandId());
 
   FailurePath* failure;
   if (!addFailurePath(&failure)) {
     return false;
   }
 
   masm.branchSub32(Assembler::Overflow, rhs, lhs, failure->label());
   EmitStoreResult(masm, lhs, JSVAL_TYPE_INT32, output);
 
   return true;
 }
 
 bool CacheIRCompiler::emitInt32MulResult() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   AutoOutputRegister output(*this);
   Register lhs = allocator.useRegister(masm, reader.int32OperandId());
   Register rhs = allocator.useRegister(masm, reader.int32OperandId());
   AutoScratchRegisterMaybeOutput scratch(allocator, masm, output);
 
   FailurePath* failure;
   if (!addFailurePath(&failure)) {
     return false;
@@ -2190,16 +2236,17 @@ bool CacheIRCompiler::emitInt32MulResult
   masm.branchTest32(Assembler::Signed, scratch, scratch, failure->label());
 
   masm.bind(&done);
   EmitStoreResult(masm, lhs, JSVAL_TYPE_INT32, output);
   return true;
 }
 
 bool CacheIRCompiler::emitInt32DivResult() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   AutoOutputRegister output(*this);
   Register lhs = allocator.useRegister(masm, reader.int32OperandId());
   Register rhs = allocator.useRegister(masm, reader.int32OperandId());
   AutoScratchRegister rem(allocator, masm);
 
   FailurePath* failure;
   if (!addFailurePath(&failure)) {
     return false;
@@ -2222,16 +2269,17 @@ bool CacheIRCompiler::emitInt32DivResult
 
   // A remainder implies a double result.
   masm.branchTest32(Assembler::NonZero, rem, rem, failure->label());
   EmitStoreResult(masm, lhs, JSVAL_TYPE_INT32, output);
   return true;
 }
 
 bool CacheIRCompiler::emitInt32ModResult() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   AutoOutputRegister output(*this);
   Register lhs = allocator.useRegister(masm, reader.int32OperandId());
   Register rhs = allocator.useRegister(masm, reader.int32OperandId());
 
   FailurePath* failure;
   if (!addFailurePath(&failure)) {
     return false;
   }
@@ -2253,75 +2301,81 @@ bool CacheIRCompiler::emitInt32ModResult
   masm.flexibleRemainder32(rhs, lhs, false, volatileRegs);
 
   EmitStoreResult(masm, lhs, JSVAL_TYPE_INT32, output);
 
   return true;
 }
 
 bool CacheIRCompiler::emitInt32BitOrResult() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   AutoOutputRegister output(*this);
 
   Register lhs = allocator.useRegister(masm, reader.int32OperandId());
   Register rhs = allocator.useRegister(masm, reader.int32OperandId());
 
   masm.or32(lhs, rhs);
   EmitStoreResult(masm, rhs, JSVAL_TYPE_INT32, output);
 
   return true;
 }
 bool CacheIRCompiler::emitInt32BitXorResult() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   AutoOutputRegister output(*this);
 
   Register lhs = allocator.useRegister(masm, reader.int32OperandId());
   Register rhs = allocator.useRegister(masm, reader.int32OperandId());
 
   masm.xor32(lhs, rhs);
   EmitStoreResult(masm, rhs, JSVAL_TYPE_INT32, output);
 
   return true;
 }
 bool CacheIRCompiler::emitInt32BitAndResult() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   AutoOutputRegister output(*this);
 
   Register lhs = allocator.useRegister(masm, reader.int32OperandId());
   Register rhs = allocator.useRegister(masm, reader.int32OperandId());
 
   masm.and32(lhs, rhs);
   EmitStoreResult(masm, rhs, JSVAL_TYPE_INT32, output);
 
   return true;
 }
 bool CacheIRCompiler::emitInt32LeftShiftResult() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   AutoOutputRegister output(*this);
   Register lhs = allocator.useRegister(masm, reader.int32OperandId());
   Register rhs = allocator.useRegister(masm, reader.int32OperandId());
 
   // Mask shift amount as specified by 12.9.3.1 Step 7
   masm.and32(Imm32(0x1F), rhs);
   masm.flexibleLshift32(rhs, lhs);
   EmitStoreResult(masm, lhs, JSVAL_TYPE_INT32, output);
 
   return true;
 }
 
 bool CacheIRCompiler::emitInt32RightShiftResult() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   AutoOutputRegister output(*this);
   Register lhs = allocator.useRegister(masm, reader.int32OperandId());
   Register rhs = allocator.useRegister(masm, reader.int32OperandId());
 
   // Mask shift amount as specified by 12.9.4.1 Step 7
   masm.and32(Imm32(0x1F), rhs);
   masm.flexibleRshift32Arithmetic(rhs, lhs);
   EmitStoreResult(masm, lhs, JSVAL_TYPE_INT32, output);
 
   return true;
 }
 
 bool CacheIRCompiler::emitInt32URightShiftResult() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   AutoOutputRegister output(*this);
 
   Register lhs = allocator.useRegister(masm, reader.int32OperandId());
   Register rhs = allocator.useRegister(masm, reader.int32OperandId());
   bool allowDouble = reader.readBool();
 
   FailurePath* failure;
   if (!addFailurePath(&failure)) {
@@ -2346,16 +2400,17 @@ bool CacheIRCompiler::emitInt32URightShi
   }
   masm.bind(&intDone);
   EmitStoreResult(masm, lhs, JSVAL_TYPE_INT32, output);
   masm.bind(&floatDone);
   return true;
 }
 
 bool CacheIRCompiler::emitInt32NegationResult() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   AutoOutputRegister output(*this);
   Register val = allocator.useRegister(masm, reader.int32OperandId());
 
   FailurePath* failure;
   if (!addFailurePath(&failure)) {
     return false;
   }
 
@@ -2397,24 +2452,26 @@ bool CacheIRCompiler::emitInt32DecResult
   masm.mov(input, scratch);
   masm.branchSub32(Assembler::Overflow, Imm32(1), scratch, failure->label());
   EmitStoreResult(masm, scratch, JSVAL_TYPE_INT32, output);
 
   return true;
 }
 
 bool CacheIRCompiler::emitInt32NotResult() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   AutoOutputRegister output(*this);
   Register val = allocator.useRegister(masm, reader.int32OperandId());
   masm.not32(val);
   masm.tagValue(JSVAL_TYPE_INT32, val, output.valueReg());
   return true;
 }
 
 bool CacheIRCompiler::emitDoubleNegationResult() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   AutoOutputRegister output(*this);
   ValueOperand val = allocator.useValueRegister(masm, reader.valOperandId());
 
   FailurePath* failure;
   if (!addFailurePath(&failure)) {
     return false;
   }
 
@@ -2486,16 +2543,17 @@ bool CacheIRCompiler::emitDoubleIncResul
   return emitDoubleIncDecResult(true);
 }
 
 bool CacheIRCompiler::emitDoubleDecResult() {
   return emitDoubleIncDecResult(false);
 }
 
 bool CacheIRCompiler::emitTruncateDoubleToUInt32() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   ValueOperand val = allocator.useValueRegister(masm, reader.valOperandId());
   Register res = allocator.defineRegister(masm, reader.int32OperandId());
 
   Label int32, done;
   masm.branchTestInt32(Assembler::Equal, val, &int32);
 
   Label doneTruncate, truncateABICall;
   if (mode_ != Mode::Baseline) {
@@ -2533,16 +2591,17 @@ bool CacheIRCompiler::emitTruncateDouble
 
   masm.unboxInt32(val, res);
 
   masm.bind(&done);
   return true;
 }
 
 bool CacheIRCompiler::emitLoadArgumentsObjectLengthResult() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   AutoOutputRegister output(*this);
   Register obj = allocator.useRegister(masm, reader.objOperandId());
   AutoScratchRegisterMaybeOutput scratch(allocator, masm, output);
 
   FailurePath* failure;
   if (!addFailurePath(&failure)) {
     return false;
   }
@@ -2559,16 +2618,17 @@ bool CacheIRCompiler::emitLoadArgumentsO
   // Shift out arguments length and return it. No need to type monitor
   // because this stub always returns int32.
   masm.rshiftPtr(Imm32(ArgumentsObject::PACKED_BITS_COUNT), scratch);
   EmitStoreResult(masm, scratch, JSVAL_TYPE_INT32, output);
   return true;
 }
 
 bool CacheIRCompiler::emitLoadFunctionLengthResult() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   AutoOutputRegister output(*this);
   Register obj = allocator.useRegister(masm, reader.objOperandId());
   AutoScratchRegisterMaybeOutput scratch(allocator, masm, output);
 
   FailurePath* failure;
   if (!addFailurePath(&failure)) {
     return false;
   }
@@ -2610,26 +2670,28 @@ bool CacheIRCompiler::emitLoadFunctionLe
                         scratch);
 
   masm.bind(&done);
   EmitStoreResult(masm, scratch, JSVAL_TYPE_INT32, output);
   return true;
 }
 
 bool CacheIRCompiler::emitLoadStringLengthResult() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   AutoOutputRegister output(*this);
   Register str = allocator.useRegister(masm, reader.stringOperandId());
   AutoScratchRegisterMaybeOutput scratch(allocator, masm, output);
 
   masm.loadStringLength(str, scratch);
   EmitStoreResult(masm, scratch, JSVAL_TYPE_INT32, output);
   return true;
 }
 
 bool CacheIRCompiler::emitLoadStringCharResult() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   AutoOutputRegister output(*this);
   Register str = allocator.useRegister(masm, reader.stringOperandId());
   Register index = allocator.useRegister(masm, reader.int32OperandId());
   AutoScratchRegisterMaybeOutput scratch1(allocator, masm, output);
   AutoScratchRegister scratch2(allocator, masm);
 
   FailurePath* failure;
   if (!addFailurePath(&failure)) {
@@ -2647,16 +2709,17 @@ bool CacheIRCompiler::emitLoadStringChar
   masm.movePtr(ImmPtr(&cx_->staticStrings().unitStaticTable), scratch2);
   masm.loadPtr(BaseIndex(scratch2, scratch1, ScalePointer), scratch2);
 
   EmitStoreResult(masm, scratch2, JSVAL_TYPE_STRING, output);
   return true;
 }
 
 bool CacheIRCompiler::emitLoadArgumentsObjectArgResult() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   AutoOutputRegister output(*this);
   Register obj = allocator.useRegister(masm, reader.objOperandId());
   Register index = allocator.useRegister(masm, reader.int32OperandId());
   AutoScratchRegister scratch1(allocator, masm);
   AutoScratchRegisterMaybeOutput scratch2(allocator, masm, output);
 
   FailurePath* failure;
   if (!addFailurePath(&failure)) {
@@ -2689,16 +2752,17 @@ bool CacheIRCompiler::emitLoadArgumentsO
   // Guard the argument is not a FORWARD_TO_CALL_SLOT MagicValue.
   BaseValueIndex argValue(scratch1, index, ArgumentsData::offsetOfArgs());
   masm.branchTestMagic(Assembler::Equal, argValue, failure->label());
   masm.loadValue(argValue, output.valueReg());
   return true;
 }
 
 bool CacheIRCompiler::emitLoadDenseElementResult() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   AutoOutputRegister output(*this);
   Register obj = allocator.useRegister(masm, reader.objOperandId());
   Register index = allocator.useRegister(masm, reader.int32OperandId());
   AutoScratchRegister scratch1(allocator, masm);
   AutoScratchRegisterMaybeOutput scratch2(allocator, masm, output);
 
   FailurePath* failure;
   if (!addFailurePath(&failure)) {
@@ -2715,28 +2779,30 @@ bool CacheIRCompiler::emitLoadDenseEleme
   // Hole check.
   BaseObjectElementIndex element(scratch1, index);
   masm.branchTestMagic(Assembler::Equal, element, failure->label());
   masm.loadTypedOrValue(element, output);
   return true;
 }
 
 bool CacheIRCompiler::emitGuardIndexIsNonNegative() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   Register index = allocator.useRegister(masm, reader.int32OperandId());
 
   FailurePath* failure;
   if (!addFailurePath(&failure)) {
     return false;
   }
 
   masm.branch32(Assembler::LessThan, index, Imm32(0), failure->label());
   return true;
 }
 
 bool CacheIRCompiler::emitGuardIndexGreaterThanDenseInitLength() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   Register obj = allocator.useRegister(masm, reader.objOperandId());
   Register index = allocator.useRegister(masm, reader.int32OperandId());
   AutoScratchRegister scratch(allocator, masm);
   AutoScratchRegister scratch2(allocator, masm);
 
   FailurePath* failure;
   if (!addFailurePath(&failure)) {
     return false;
@@ -2751,16 +2817,17 @@ bool CacheIRCompiler::emitGuardIndexGrea
   masm.spectreBoundsCheck32(index, capacity, scratch2, &outOfBounds);
   masm.jump(failure->label());
   masm.bind(&outOfBounds);
 
   return true;
 }
 
 bool CacheIRCompiler::emitGuardIndexGreaterThanDenseCapacity() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   Register obj = allocator.useRegister(masm, reader.objOperandId());
   Register index = allocator.useRegister(masm, reader.int32OperandId());
   AutoScratchRegister scratch(allocator, masm);
   AutoScratchRegister scratch2(allocator, masm);
 
   FailurePath* failure;
   if (!addFailurePath(&failure)) {
     return false;
@@ -2775,16 +2842,17 @@ bool CacheIRCompiler::emitGuardIndexGrea
   masm.spectreBoundsCheck32(index, capacity, scratch2, &outOfBounds);
   masm.jump(failure->label());
   masm.bind(&outOfBounds);
 
   return true;
 }
 
 bool CacheIRCompiler::emitGuardIndexGreaterThanArrayLength() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   Register obj = allocator.useRegister(masm, reader.objOperandId());
   Register index = allocator.useRegister(masm, reader.int32OperandId());
   AutoScratchRegister scratch(allocator, masm);
   AutoScratchRegister scratch2(allocator, masm);
 
   FailurePath* failure;
   if (!addFailurePath(&failure)) {
     return false;
@@ -2798,16 +2866,17 @@ bool CacheIRCompiler::emitGuardIndexGrea
   Address length(scratch, ObjectElements::offsetOfLength());
   masm.spectreBoundsCheck32(index, length, scratch2, &outOfBounds);
   masm.jump(failure->label());
   masm.bind(&outOfBounds);
   return true;
 }
 
 bool CacheIRCompiler::emitGuardIndexIsValidUpdateOrAdd() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   Register obj = allocator.useRegister(masm, reader.objOperandId());
   Register index = allocator.useRegister(masm, reader.int32OperandId());
   AutoScratchRegister scratch(allocator, masm);
   AutoScratchRegister scratch2(allocator, masm);
 
   FailurePath* failure;
   if (!addFailurePath(&failure)) {
     return false;
@@ -2828,16 +2897,17 @@ bool CacheIRCompiler::emitGuardIndexIsVa
   Address length(scratch, ObjectElements::offsetOfLength());
   masm.spectreBoundsCheck32(index, length, scratch2,
                             /* failure = */ failure->label());
   masm.bind(&success);
   return true;
 }
 
 bool CacheIRCompiler::emitGuardTagNotEqual() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   Register lhs = allocator.useRegister(masm, reader.valueTagOperandId());
   Register rhs = allocator.useRegister(masm, reader.valueTagOperandId());
 
   FailurePath* failure;
   if (!addFailurePath(&failure)) {
     return false;
   }
 
@@ -2850,16 +2920,17 @@ bool CacheIRCompiler::emitGuardTagNotEqu
   masm.branchTestNumber(Assembler::NotEqual, rhs, &done);
   masm.jump(failure->label());
 
   masm.bind(&done);
   return true;
 }
 
 bool CacheIRCompiler::emitGuardXrayExpandoShapeAndDefaultProto() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   Register obj = allocator.useRegister(masm, reader.objOperandId());
   bool hasExpando = reader.readBool();
   StubFieldOffset shapeWrapper(reader.stubOffset(), StubField::Type::JSObject);
 
   AutoScratchRegister scratch(allocator, masm);
   Maybe<AutoScratchRegister> scratch2, scratch3;
   if (hasExpando) {
     scratch2.emplace(allocator, masm);
@@ -2909,44 +2980,47 @@ bool CacheIRCompiler::emitGuardXrayExpan
     masm.branchTestObject(Assembler::Equal, expandoAddress, failure->label());
     masm.bind(&done);
   }
 
   return true;
 }
 
 bool CacheIRCompiler::emitGuardNoAllocationMetadataBuilder() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   FailurePath* failure;
   if (!addFailurePath(&failure)) {
     return false;
   }
 
   masm.branchPtr(Assembler::NotEqual,
                  AbsoluteAddress(cx_->realm()->addressOfMetadataBuilder()),
                  ImmWord(0), failure->label());
 
   return true;
 }
 
 bool CacheIRCompiler::emitGuardObjectGroupNotPretenured() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   AutoScratchRegister scratch(allocator, masm);
 
   FailurePath* failure;
   if (!addFailurePath(&failure)) {
     return false;
   }
 
   StubFieldOffset group(reader.stubOffset(), StubField::Type::ObjectGroup);
   emitLoadStubField(group, scratch);
 
   masm.branchIfPretenuredGroup(scratch, failure->label());
   return true;
 }
 
 bool CacheIRCompiler::emitLoadDenseElementHoleResult() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   AutoOutputRegister output(*this);
   Register obj = allocator.useRegister(masm, reader.objOperandId());
   Register index = allocator.useRegister(masm, reader.int32OperandId());
   AutoScratchRegister scratch1(allocator, masm);
   AutoScratchRegisterMaybeOutput scratch2(allocator, masm, output);
 
   if (!output.hasValue()) {
     masm.assumeUnreachable(
@@ -2979,16 +3053,17 @@ bool CacheIRCompiler::emitLoadDenseEleme
   masm.bind(&hole);
   masm.moveValue(UndefinedValue(), output.valueReg());
 
   masm.bind(&done);
   return true;
 }
 
 bool CacheIRCompiler::emitLoadTypedElementExistsResult() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   AutoOutputRegister output(*this);
   Register obj = allocator.useRegister(masm, reader.objOperandId());
   Register index = allocator.useRegister(masm, reader.int32OperandId());
   TypedThingLayout layout = reader.typedThingLayout();
   AutoScratchRegisterMaybeOutput scratch(allocator, masm, output);
 
   Label outOfBounds, done;
 
@@ -3001,16 +3076,17 @@ bool CacheIRCompiler::emitLoadTypedEleme
   masm.bind(&outOfBounds);
   EmitStoreBoolean(masm, false, output);
 
   masm.bind(&done);
   return true;
 }
 
 bool CacheIRCompiler::emitLoadDenseElementExistsResult() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   AutoOutputRegister output(*this);
   Register obj = allocator.useRegister(masm, reader.objOperandId());
   Register index = allocator.useRegister(masm, reader.int32OperandId());
   AutoScratchRegisterMaybeOutput scratch(allocator, masm, output);
 
   FailurePath* failure;
   if (!addFailurePath(&failure)) {
     return false;
@@ -3027,16 +3103,17 @@ bool CacheIRCompiler::emitLoadDenseEleme
   BaseObjectElementIndex element(scratch, index);
   masm.branchTestMagic(Assembler::Equal, element, failure->label());
 
   EmitStoreBoolean(masm, true, output);
   return true;
 }
 
 bool CacheIRCompiler::emitLoadDenseElementHoleExistsResult() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   AutoOutputRegister output(*this);
   Register obj = allocator.useRegister(masm, reader.objOperandId());
   Register index = allocator.useRegister(masm, reader.int32OperandId());
   AutoScratchRegisterMaybeOutput scratch(allocator, masm, output);
 
   FailurePath* failure;
   if (!addFailurePath(&failure)) {
     return false;
@@ -3064,16 +3141,17 @@ bool CacheIRCompiler::emitLoadDenseEleme
   masm.bind(&hole);
   EmitStoreBoolean(masm, false, output);
 
   masm.bind(&done);
   return true;
 }
 
 bool CacheIRCompiler::emitArrayJoinResult() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   ObjOperandId objId = reader.objOperandId();
 
   AutoOutputRegister output(*this);
   Register obj = allocator.useRegister(masm, objId);
   AutoScratchRegister scratch(allocator, masm);
 
   FailurePath* failure;
   if (!addFailurePath(&failure)) {
@@ -3111,16 +3189,17 @@ bool CacheIRCompiler::emitArrayJoinResul
   masm.loadValue(elementAddr, output.valueReg());
 
   masm.bind(&finished);
 
   return true;
 }
 
 bool CacheIRCompiler::emitLoadTypedElementResult() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   AutoOutputRegister output(*this);
   Register obj = allocator.useRegister(masm, reader.objOperandId());
   Register index = allocator.useRegister(masm, reader.int32OperandId());
   TypedThingLayout layout = reader.typedThingLayout();
   Scalar::Type type = reader.scalarType();
 
   AutoScratchRegister scratch1(allocator, masm);
   AutoScratchRegisterMaybeOutput scratch2(allocator, masm, output);
@@ -3174,16 +3253,17 @@ bool CacheIRCompiler::emitLoadTypedEleme
     }
   }
   return true;
 }
 
 void CacheIRCompiler::emitLoadTypedObjectResultShared(
     const Address& fieldAddr, Register scratch, uint32_t typeDescr,
     const AutoOutputRegister& output) {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   MOZ_ASSERT(output.hasValue());
 
   if (SimpleTypeDescrKeyIsScalar(typeDescr)) {
     Scalar::Type type = ScalarTypeFromSimpleTypeDescrKey(typeDescr);
     masm.loadFromTypedArray(type, fieldAddr, output.valueReg(),
                             /* allowDouble = */ true, scratch, nullptr);
   } else {
     ReferenceType type = ReferenceTypeFromSimpleTypeDescrKey(typeDescr);
@@ -3214,29 +3294,31 @@ void CacheIRCompiler::emitLoadTypedObjec
 
       default:
         MOZ_CRASH("Invalid ReferenceTypeDescr");
     }
   }
 }
 
 bool CacheIRCompiler::emitLoadObjectResult() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   AutoOutputRegister output(*this);
   Register obj = allocator.useRegister(masm, reader.objOperandId());
 
   if (output.hasValue()) {
     masm.tagValue(JSVAL_TYPE_OBJECT, obj, output.valueReg());
   } else {
     masm.mov(obj, output.typedReg().gpr());
   }
 
   return true;
 }
 
 bool CacheIRCompiler::emitLoadTypeOfObjectResult() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   AutoOutputRegister output(*this);
   Register obj = allocator.useRegister(masm, reader.objOperandId());
   AutoScratchRegisterMaybeOutput scratch(allocator, masm, output);
 
   Label slowCheck, isObject, isCallable, isUndefined, done;
   masm.typeOfObject(obj, scratch, &slowCheck, &isObject, &isCallable,
                     &isUndefined);
 
@@ -3272,32 +3354,34 @@ bool CacheIRCompiler::emitLoadTypeOfObje
     masm.tagValue(JSVAL_TYPE_STRING, scratch, output.valueReg());
   }
 
   masm.bind(&done);
   return true;
 }
 
 bool CacheIRCompiler::emitLoadInt32TruthyResult() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   AutoOutputRegister output(*this);
   ValueOperand val = allocator.useValueRegister(masm, reader.valOperandId());
 
   Label ifFalse, done;
   masm.branchTestInt32Truthy(false, val, &ifFalse);
   masm.moveValue(BooleanValue(true), output.valueReg());
   masm.jump(&done);
 
   masm.bind(&ifFalse);
   masm.moveValue(BooleanValue(false), output.valueReg());
 
   masm.bind(&done);
   return true;
 }
 
 bool CacheIRCompiler::emitLoadStringTruthyResult() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   AutoOutputRegister output(*this);
   Register str = allocator.useRegister(masm, reader.stringOperandId());
 
   Label ifFalse, done;
   masm.branch32(Assembler::Equal, Address(str, JSString::offsetOfLength()),
                 Imm32(0), &ifFalse);
   masm.moveValue(BooleanValue(true), output.valueReg());
   masm.jump(&done);
@@ -3305,16 +3389,17 @@ bool CacheIRCompiler::emitLoadStringTrut
   masm.bind(&ifFalse);
   masm.moveValue(BooleanValue(false), output.valueReg());
 
   masm.bind(&done);
   return true;
 }
 
 bool CacheIRCompiler::emitLoadDoubleTruthyResult() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   AutoOutputRegister output(*this);
   ValueOperand val = allocator.useValueRegister(masm, reader.valOperandId());
 
   Label ifFalse, done, failurePopReg;
 
   // If we're compiling a Baseline IC, FloatReg0 is always available.
   if (mode_ != Mode::Baseline) {
     masm.push(FloatReg0);
@@ -3332,16 +3417,17 @@ bool CacheIRCompiler::emitLoadDoubleTrut
   if (mode_ != Mode::Baseline) {
     masm.pop(FloatReg0);
   }
   masm.bind(&done);
   return true;
 }
 
 bool CacheIRCompiler::emitLoadObjectTruthyResult() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   AutoOutputRegister output(*this);
   Register obj = allocator.useRegister(masm, reader.objOperandId());
   AutoScratchRegisterMaybeOutput scratch(allocator, masm, output);
 
   Label emulatesUndefined, slowPath, done;
   masm.branchIfObjectEmulatesUndefined(obj, scratch, &slowPath,
                                        &emulatesUndefined);
   masm.moveValue(BooleanValue(true), output.valueReg());
@@ -3359,16 +3445,17 @@ bool CacheIRCompiler::emitLoadObjectTrut
   masm.xor32(Imm32(1), ReturnReg);
   masm.tagValue(JSVAL_TYPE_BOOLEAN, ReturnReg, output.valueReg());
 
   masm.bind(&done);
   return true;
 }
 
 bool CacheIRCompiler::emitLoadNewObjectFromTemplateResult() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   AutoOutputRegister output(*this);
   AutoScratchRegister obj(allocator, masm);
   AutoScratchRegisterMaybeOutput scratch(allocator, masm, output);
 
   TemplateObject templateObj(objectStubFieldUnchecked(reader.stubOffset()));
 
   // Consume the disambiguation id (2 halves)
   mozilla::Unused << reader.uint32Immediate();
@@ -3381,16 +3468,17 @@ bool CacheIRCompiler::emitLoadNewObjectF
 
   masm.createGCObject(obj, scratch, templateObj, gc::DefaultHeap,
                       failure->label());
   masm.tagValue(JSVAL_TYPE_OBJECT, obj, output.valueReg());
   return true;
 }
 
 bool CacheIRCompiler::emitComparePointerResultShared(bool symbol) {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   AutoOutputRegister output(*this);
 
   Register left = symbol ? allocator.useRegister(masm, reader.symbolOperandId())
                          : allocator.useRegister(masm, reader.objOperandId());
   Register right = symbol
                        ? allocator.useRegister(masm, reader.symbolOperandId())
                        : allocator.useRegister(masm, reader.objOperandId());
   JSOp op = reader.jsop();
@@ -3406,24 +3494,27 @@ bool CacheIRCompiler::emitComparePointer
 
   masm.bind(&ifTrue);
   EmitStoreBoolean(masm, true, output);
   masm.bind(&done);
   return true;
 }
 
 bool CacheIRCompiler::emitCompareObjectResult() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   return emitComparePointerResultShared(false);
 }
 
 bool CacheIRCompiler::emitCompareSymbolResult() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   return emitComparePointerResultShared(true);
 }
 
 bool CacheIRCompiler::emitCompareInt32Result() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   AutoOutputRegister output(*this);
   Register left = allocator.useRegister(masm, reader.int32OperandId());
   Register right = allocator.useRegister(masm, reader.int32OperandId());
   JSOp op = reader.jsop();
 
   Label ifTrue, done;
   masm.branch32(JSOpToCondition(op, /* signed = */ true), left, right, &ifTrue);
 
@@ -3432,16 +3523,17 @@ bool CacheIRCompiler::emitCompareInt32Re
 
   masm.bind(&ifTrue);
   EmitStoreBoolean(masm, true, output);
   masm.bind(&done);
   return true;
 }
 
 bool CacheIRCompiler::emitCompareDoubleResult() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   AutoOutputRegister output(*this);
 
   FailurePath* failure;
   if (!addFailurePath(&failure)) {
     return false;
   }
 
   allocator.ensureDoubleRegister(masm, reader.valOperandId(), FloatReg0);
@@ -3455,16 +3547,17 @@ bool CacheIRCompiler::emitCompareDoubleR
 
   masm.bind(&ifTrue);
   EmitStoreBoolean(masm, true, output);
   masm.bind(&done);
   return true;
 }
 
 bool CacheIRCompiler::emitCompareObjectUndefinedNullResult() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   AutoOutputRegister output(*this);
 
   Register obj = allocator.useRegister(masm, reader.objOperandId());
   JSOp op = reader.jsop();
 
   FailurePath* failure;
   if (!addFailurePath(&failure)) {
     return false;
@@ -3484,30 +3577,33 @@ bool CacheIRCompiler::emitCompareObjectU
     masm.bind(&emulatesUndefined);
     EmitStoreBoolean(masm, op == JSOP_EQ, output);
     masm.bind(&done);
   }
   return true;
 }
 
 bool CacheIRCompiler::emitCallPrintString() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   const char* str = reinterpret_cast<char*>(reader.pointer());
   masm.printf(str);
   return true;
 }
 
 bool CacheIRCompiler::emitBreakpoint() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   masm.breakpoint();
   return true;
 }
 
 void CacheIRCompiler::emitStoreTypedObjectReferenceProp(ValueOperand val,
                                                         ReferenceType type,
                                                         const Address& dest,
                                                         Register scratch) {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   // Callers will post-barrier this store.
 
   switch (type) {
     case ReferenceType::TYPE_ANY:
       EmitPreBarrier(masm, dest, MIRType::Value);
       masm.storeValue(val, dest);
       break;
 
@@ -3532,16 +3628,17 @@ void CacheIRCompiler::emitStoreTypedObje
       masm.unboxString(val, scratch);
       masm.storePtr(scratch, dest);
       break;
   }
 }
 
 void CacheIRCompiler::emitRegisterEnumerator(Register enumeratorsList,
                                              Register iter, Register scratch) {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   // iter->next = list
   masm.storePtr(enumeratorsList, Address(iter, NativeIterator::offsetOfNext()));
 
   // iter->prev = list->prev
   masm.loadPtr(Address(enumeratorsList, NativeIterator::offsetOfPrev()),
                scratch);
   masm.storePtr(scratch, Address(iter, NativeIterator::offsetOfPrev()));
 
@@ -3551,16 +3648,17 @@ void CacheIRCompiler::emitRegisterEnumer
   // list->prev = ni
   masm.storePtr(iter, Address(enumeratorsList, NativeIterator::offsetOfPrev()));
 }
 
 void CacheIRCompiler::emitPostBarrierShared(Register obj,
                                             const ConstantOrRegister& val,
                                             Register scratch,
                                             Register maybeIndex) {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   if (!cx_->nursery().exists()) {
     return;
   }
 
   if (val.constant()) {
     MOZ_ASSERT_IF(val.value().isGCThing(),
                   !IsInsideNursery(val.value().toGCThing()));
     return;
@@ -3602,16 +3700,17 @@ void CacheIRCompiler::emitPostBarrierSha
     masm.callWithABI(JS_FUNC_TO_DATA_PTR(void*, PostWriteBarrier));
   }
   masm.PopRegsInMask(save);
 
   masm.bind(&skipBarrier);
 }
 
 bool CacheIRCompiler::emitWrapResult() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   AutoOutputRegister output(*this);
   AutoScratchRegister scratch(allocator, masm);
 
   FailurePath* failure;
   if (!addFailurePath(&failure)) {
     return false;
   }
 
@@ -3642,16 +3741,17 @@ bool CacheIRCompiler::emitWrapResult() {
   // We clobbered the output register, so we have to retag.
   masm.tagValue(JSVAL_TYPE_OBJECT, obj, output.valueReg());
 
   masm.bind(&done);
   return true;
 }
 
 bool CacheIRCompiler::emitMegamorphicLoadSlotByValueResult() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   AutoOutputRegister output(*this);
 
   Register obj = allocator.useRegister(masm, reader.objOperandId());
   ValueOperand idVal = allocator.useValueRegister(masm, reader.valOperandId());
   bool handleMissing = reader.readBool();
 
   AutoScratchRegisterMaybeOutput scratch(allocator, masm, output);
 
@@ -3703,16 +3803,17 @@ bool CacheIRCompiler::emitMegamorphicLoa
   }
   masm.setFramePushed(framePushed);
   masm.loadTypedOrValue(Address(masm.getStackPointer(), 0), output);
   masm.adjustStack(sizeof(Value));
   return true;
 }
 
 bool CacheIRCompiler::emitMegamorphicHasPropResult() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   AutoOutputRegister output(*this);
 
   Register obj = allocator.useRegister(masm, reader.objOperandId());
   ValueOperand idVal = allocator.useValueRegister(masm, reader.valOperandId());
   bool hasOwn = reader.readBool();
 
   AutoScratchRegisterMaybeOutput scratch(allocator, masm, output);
 
@@ -3758,16 +3859,17 @@ bool CacheIRCompiler::emitMegamorphicHas
   masm.bind(&ok);
   masm.setFramePushed(framePushed);
   masm.loadTypedOrValue(Address(masm.getStackPointer(), 0), output);
   masm.adjustStack(sizeof(Value));
   return true;
 }
 
 bool CacheIRCompiler::emitCallObjectHasSparseElementResult() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   AutoOutputRegister output(*this);
 
   Register obj = allocator.useRegister(masm, reader.objOperandId());
   Register index = allocator.useRegister(masm, reader.int32OperandId());
 
   AutoScratchRegisterMaybeOutput scratch1(allocator, masm, output);
   AutoScratchRegister scratch2(allocator, masm);
 
@@ -3808,16 +3910,17 @@ bool CacheIRCompiler::emitCallObjectHasS
   return true;
 }
 
 /*
  * Move a constant value into register dest.
  */
 void CacheIRCompiler::emitLoadStubFieldConstant(StubFieldOffset val,
                                                 Register dest) {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   MOZ_ASSERT(mode_ == Mode::Ion);
   switch (val.getStubFieldType()) {
     case StubField::Type::Shape:
       masm.movePtr(ImmGCPtr(shapeStubField(val.getOffset())), dest);
       break;
     case StubField::Type::String:
       masm.movePtr(ImmGCPtr(stringStubField(val.getOffset())), dest);
       break;
@@ -3840,25 +3943,27 @@ void CacheIRCompiler::emitLoadStubFieldC
  * After this is done executing, dest contains the value; either through a
  * constant load or through the load from the stub data.
  *
  * The current policy is that Baseline will use loads from the stub data (to
  * allow IC sharing), where as Ion doesn't share ICs, and so we can safely use
  * constants in the IC.
  */
 void CacheIRCompiler::emitLoadStubField(StubFieldOffset val, Register dest) {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   if (stubFieldPolicy_ == StubFieldPolicy::Constant) {
     emitLoadStubFieldConstant(val, dest);
   } else {
     Address load(ICStubReg, stubDataOffset_ + val.getOffset());
     masm.loadPtr(load, dest);
   }
 }
 
 bool CacheIRCompiler::emitLoadInstanceOfObjectResult() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   AutoOutputRegister output(*this);
   ValueOperand lhs = allocator.useValueRegister(masm, reader.valOperandId());
   Register proto = allocator.useRegister(masm, reader.objOperandId());
 
   AutoScratchRegisterMaybeOutput scratch(allocator, masm, output);
 
   FailurePath* failure;
   if (!addFailurePath(&failure)) {
@@ -3894,16 +3999,17 @@ bool CacheIRCompiler::emitLoadInstanceOf
   masm.bind(&returnTrue);
   EmitStoreBoolean(masm, true, output);
   // fallthrough
   masm.bind(&done);
   return true;
 }
 
 bool CacheIRCompiler::emitMegamorphicLoadSlotResult() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   AutoOutputRegister output(*this);
 
   Register obj = allocator.useRegister(masm, reader.objOperandId());
   StubFieldOffset name(reader.stubOffset(), StubField::Type::String);
   bool handleMissing = reader.readBool();
 
   AutoScratchRegisterMaybeOutput scratch1(allocator, masm, output);
   AutoScratchRegister scratch2(allocator, masm);
@@ -3951,16 +4057,17 @@ bool CacheIRCompiler::emitMegamorphicLoa
   if (JitOptions.spectreJitToCxxCalls) {
     masm.speculationBarrier();
   }
 
   return true;
 }
 
 bool CacheIRCompiler::emitMegamorphicStoreSlot() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   Register obj = allocator.useRegister(masm, reader.objOperandId());
   StubFieldOffset name(reader.stubOffset(), StubField::Type::String);
   ValueOperand val = allocator.useValueRegister(masm, reader.valOperandId());
   bool needsTypeBarrier = reader.readBool();
 
   AutoScratchRegister scratch1(allocator, masm);
   AutoScratchRegister scratch2(allocator, masm);
 
@@ -3999,38 +4106,41 @@ bool CacheIRCompiler::emitMegamorphicSto
   masm.loadValue(Address(masm.getStackPointer(), 0), val);
   masm.adjustStack(sizeof(Value));
 
   masm.branchIfFalseBool(scratch1, failure->label());
   return true;
 }
 
 bool CacheIRCompiler::emitGuardGroupHasUnanalyzedNewScript() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   StubFieldOffset group(reader.stubOffset(), StubField::Type::ObjectGroup);
   AutoScratchRegister scratch1(allocator, masm);
   AutoScratchRegister scratch2(allocator, masm);
 
   FailurePath* failure;
   if (!addFailurePath(&failure)) {
     return false;
   }
 
   emitLoadStubField(group, scratch1);
   masm.guardGroupHasUnanalyzedNewScript(scratch1, scratch2, failure->label());
   return true;
 }
 
 bool CacheIRCompiler::emitLoadObject() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   Register reg = allocator.defineRegister(masm, reader.objOperandId());
   StubFieldOffset obj(reader.stubOffset(), StubField::Type::JSObject);
   emitLoadStubField(obj, reg);
   return true;
 }
 
 bool CacheIRCompiler::emitCallInt32ToString() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   Register input = allocator.useRegister(masm, reader.int32OperandId());
   Register result = allocator.defineRegister(masm, reader.stringOperandId());
 
   FailurePath* failure;
   if (!addFailurePath(&failure)) {
     return false;
   }
 
@@ -4048,16 +4158,17 @@ bool CacheIRCompiler::emitCallInt32ToStr
   masm.mov(ReturnReg, result);
   masm.PopRegsInMask(volatileRegs);
 
   masm.branchPtr(Assembler::Equal, result, ImmPtr(0), failure->label());
   return true;
 }
 
 bool CacheIRCompiler::emitCallNumberToString() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   // Float register must be preserved. The BinaryArith ICs use
   // the fact that baseline has them available, as well as fixed temps on
   // LBinaryCache.
   allocator.ensureDoubleRegister(masm, reader.valOperandId(), FloatReg0);
   Register result = allocator.defineRegister(masm, reader.stringOperandId());
 
   FailurePath* failure;
   if (!addFailurePath(&failure)) {
@@ -4113,16 +4224,17 @@ void js::jit::LoadTypedThingLength(Macro
       masm.loadTypedObjectLength(obj, result);
       break;
     default:
       MOZ_CRASH();
   }
 }
 
 bool CacheIRCompiler::emitCallIsSuspendedGeneratorResult() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   AutoOutputRegister output(*this);
   AutoScratchRegisterMaybeOutput scratch(allocator, masm, output);
   AutoScratchRegister scratch2(allocator, masm);
   ValueOperand input = allocator.useValueRegister(masm, reader.valOperandId());
 
   // Test if it's an object.
   Label returnFalse, done;
   masm.branchTestObject(Assembler::NotEqual, input, &returnFalse);
--- a/js/src/jit/CodeGenerator.cpp
+++ b/js/src/jit/CodeGenerator.cpp
@@ -11655,30 +11655,35 @@ class OutOfLineSwitch : public OutOfLine
 
   void setOutOfLine() { isOutOfLine_ = true; }
 };
 
 template <SwitchTableType tableType>
 void CodeGenerator::visitOutOfLineSwitch(
     OutOfLineSwitch<tableType>* jumpTable) {
   jumpTable->setOutOfLine();
+  auto& labels = jumpTable->labels();
+#if defined(JS_CODEGEN_ARM64)
+  AutoForbidPools afp(&masm, (labels.length() + 1) * (sizeof(void*) / vixl::kInstructionSize));
+#endif
+
+
   if (tableType == SwitchTableType::OutOfLine) {
 #if defined(JS_CODEGEN_ARM)
     MOZ_CRASH("NYI: SwitchTableType::OutOfLine");
 #elif defined(JS_CODEGEN_NONE)
     MOZ_CRASH();
 #else
     masm.haltingAlign(sizeof(void*));
     masm.bind(jumpTable->start());
     masm.addCodeLabel(*jumpTable->start());
 #endif
   }
 
   // Add table entries if the table is inlined.
-  auto& labels = jumpTable->labels();
   for (size_t i = 0, e = labels.length(); i < e; i++) {
     jumpTable->addTableEntry(masm);
   }
 
   auto& codeLabels = jumpTable->codeLabels();
   for (size_t i = 0, e = codeLabels.length(); i < e; i++) {
     // The entries of the jump table need to be absolute addresses and thus
     // must be patched after codegen is finished.
--- a/js/src/jit/IonCacheIRCompiler.cpp
+++ b/js/src/jit/IonCacheIRCompiler.cpp
@@ -639,16 +639,17 @@ JitCode* IonCacheIRCompiler::compile() {
         CodeLocationLabel(newStubCode, *stubJitCodeOffset_),
         ImmPtr(newStubCode.get()), ImmPtr((void*)-1));
   }
 
   return newStubCode;
 }
 
 bool IonCacheIRCompiler::emitGuardShape() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   ObjOperandId objId = reader.objOperandId();
   Register obj = allocator.useRegister(masm, objId);
   Shape* shape = shapeStubField(reader.stubOffset());
 
   bool needSpectreMitigations = objectGuardNeedsSpectreMitigations(objId);
 
   Maybe<AutoScratchRegister> maybeScratch;
   if (needSpectreMitigations) {
@@ -667,16 +668,17 @@ bool IonCacheIRCompiler::emitGuardShape(
     masm.branchTestObjShapeNoSpectreMitigations(Assembler::NotEqual, obj, shape,
                                                 failure->label());
   }
 
   return true;
 }
 
 bool IonCacheIRCompiler::emitGuardGroup() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   ObjOperandId objId = reader.objOperandId();
   Register obj = allocator.useRegister(masm, objId);
   ObjectGroup* group = groupStubField(reader.stubOffset());
 
   bool needSpectreMitigations = objectGuardNeedsSpectreMitigations(objId);
 
   Maybe<AutoScratchRegister> maybeScratch;
   if (needSpectreMitigations) {
@@ -695,16 +697,17 @@ bool IonCacheIRCompiler::emitGuardGroup(
     masm.branchTestObjGroupNoSpectreMitigations(Assembler::NotEqual, obj, group,
                                                 failure->label());
   }
 
   return true;
 }
 
 bool IonCacheIRCompiler::emitGuardProto() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   Register obj = allocator.useRegister(masm, reader.objOperandId());
   JSObject* proto = objectStubField(reader.stubOffset());
 
   AutoScratchRegister scratch(allocator, masm);
 
   FailurePath* failure;
   if (!addFailurePath(&failure)) {
     return false;
@@ -712,16 +715,17 @@ bool IonCacheIRCompiler::emitGuardProto(
 
   masm.loadObjProto(obj, scratch);
   masm.branchPtr(Assembler::NotEqual, scratch, ImmGCPtr(proto),
                  failure->label());
   return true;
 }
 
 bool IonCacheIRCompiler::emitGuardCompartment() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   Register obj = allocator.useRegister(masm, reader.objOperandId());
   JSObject* globalWrapper = objectStubField(reader.stubOffset());
   JS::Compartment* compartment = compartmentStubField(reader.stubOffset());
   AutoScratchRegister scratch(allocator, masm);
 
   FailurePath* failure;
   if (!addFailurePath(&failure)) {
     return false;
@@ -735,16 +739,17 @@ bool IonCacheIRCompiler::emitGuardCompar
                  ImmPtr(&DeadObjectProxy::singleton), failure->label());
 
   masm.branchTestObjCompartment(Assembler::NotEqual, obj, compartment, scratch,
                                 failure->label());
   return true;
 }
 
 bool IonCacheIRCompiler::emitGuardAnyClass() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   ObjOperandId objId = reader.objOperandId();
   Register obj = allocator.useRegister(masm, objId);
   AutoScratchRegister scratch(allocator, masm);
 
   const Class* clasp = classStubField(reader.stubOffset());
 
   FailurePath* failure;
   if (!addFailurePath(&failure)) {
@@ -758,45 +763,48 @@ bool IonCacheIRCompiler::emitGuardAnyCla
     masm.branchTestObjClassNoSpectreMitigations(Assembler::NotEqual, obj, clasp,
                                                 scratch, failure->label());
   }
 
   return true;
 }
 
 bool IonCacheIRCompiler::emitGuardHasProxyHandler() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   Register obj = allocator.useRegister(masm, reader.objOperandId());
   const void* handler = proxyHandlerStubField(reader.stubOffset());
 
   FailurePath* failure;
   if (!addFailurePath(&failure)) {
     return false;
   }
 
   Address handlerAddr(obj, ProxyObject::offsetOfHandler());
   masm.branchPtr(Assembler::NotEqual, handlerAddr, ImmPtr(handler),
                  failure->label());
   return true;
 }
 
 bool IonCacheIRCompiler::emitGuardSpecificObject() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   Register obj = allocator.useRegister(masm, reader.objOperandId());
   JSObject* expected = objectStubField(reader.stubOffset());
 
   FailurePath* failure;
   if (!addFailurePath(&failure)) {
     return false;
   }
 
   masm.branchPtr(Assembler::NotEqual, obj, ImmGCPtr(expected),
                  failure->label());
   return true;
 }
 
 bool IonCacheIRCompiler::emitGuardSpecificAtom() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   Register str = allocator.useRegister(masm, reader.stringOperandId());
   AutoScratchRegister scratch(allocator, masm);
 
   JSAtom* atom = &stringStubField(reader.stubOffset())->asAtom();
 
   FailurePath* failure;
   if (!addFailurePath(&failure)) {
     return false;
@@ -832,16 +840,17 @@ bool IonCacheIRCompiler::emitGuardSpecif
   masm.PopRegsInMaskIgnore(volatileRegs, ignore);
   masm.branchIfFalseBool(scratch, failure->label());
 
   masm.bind(&done);
   return true;
 }
 
 bool IonCacheIRCompiler::emitGuardSpecificSymbol() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   Register sym = allocator.useRegister(masm, reader.symbolOperandId());
   JS::Symbol* expected = symbolStubField(reader.stubOffset());
 
   FailurePath* failure;
   if (!addFailurePath(&failure)) {
     return false;
   }
 
@@ -850,35 +859,38 @@ bool IonCacheIRCompiler::emitGuardSpecif
   return true;
 }
 
 bool IonCacheIRCompiler::emitLoadValueResult() {
   MOZ_CRASH("Baseline-specific op");
 }
 
 bool IonCacheIRCompiler::emitLoadFixedSlotResult() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   AutoOutputRegister output(*this);
   Register obj = allocator.useRegister(masm, reader.objOperandId());
   int32_t offset = int32StubField(reader.stubOffset());
   masm.loadTypedOrValue(Address(obj, offset), output);
   return true;
 }
 
 bool IonCacheIRCompiler::emitLoadDynamicSlotResult() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   AutoOutputRegister output(*this);
   Register obj = allocator.useRegister(masm, reader.objOperandId());
   int32_t offset = int32StubField(reader.stubOffset());
 
   AutoScratchRegisterMaybeOutput scratch(allocator, masm, output);
   masm.loadPtr(Address(obj, NativeObject::offsetOfSlots()), scratch);
   masm.loadTypedOrValue(Address(scratch, offset), output);
   return true;
 }
 
 bool IonCacheIRCompiler::emitGuardHasGetterSetter() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   Register obj = allocator.useRegister(masm, reader.objOperandId());
   Shape* shape = shapeStubField(reader.stubOffset());
 
   AutoScratchRegister scratch1(allocator, masm);
   AutoScratchRegister scratch2(allocator, masm);
 
   FailurePath* failure;
   if (!addFailurePath(&failure)) {
@@ -901,16 +913,17 @@ bool IonCacheIRCompiler::emitGuardHasGet
   masm.mov(ReturnReg, scratch1);
   masm.PopRegsInMask(volatileRegs);
 
   masm.branchIfFalseBool(scratch1, failure->label());
   return true;
 }
 
 bool IonCacheIRCompiler::emitCallScriptedGetterResult() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   AutoSaveLiveRegisters save(*this);
   AutoOutputRegister output(*this);
 
   Register obj = allocator.useRegister(masm, reader.objOperandId());
   JSFunction* target = &objectStubField(reader.stubOffset())->as<JSFunction>();
   AutoScratchRegister scratch(allocator, masm);
 
   bool isCrossRealm = reader.readBool();
@@ -972,16 +985,17 @@ bool IonCacheIRCompiler::emitCallScripte
   }
 
   masm.storeCallResultValue(output);
   masm.freeStack(masm.framePushed() - framePushedBefore);
   return true;
 }
 
 bool IonCacheIRCompiler::emitCallNativeGetterResult() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   AutoSaveLiveRegisters save(*this);
   AutoOutputRegister output(*this);
 
   Register obj = allocator.useRegister(masm, reader.objOperandId());
   JSFunction* target = &objectStubField(reader.stubOffset())->as<JSFunction>();
   MOZ_ASSERT(target->isNative());
 
   AutoScratchRegister argJSContext(allocator, masm);
@@ -1045,16 +1059,17 @@ bool IonCacheIRCompiler::emitCallNativeG
     masm.speculationBarrier();
   }
 
   masm.adjustStack(IonOOLNativeExitFrameLayout::Size(0));
   return true;
 }
 
 bool IonCacheIRCompiler::emitCallProxyGetResult() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   AutoSaveLiveRegisters save(*this);
   AutoOutputRegister output(*this);
 
   Register obj = allocator.useRegister(masm, reader.objOperandId());
   jsid id = idStubField(reader.stubOffset());
 
   // ProxyGetProperty(JSContext* cx, HandleObject proxy, HandleId id,
   //                  MutableHandleValue vp)
@@ -1111,16 +1126,17 @@ bool IonCacheIRCompiler::emitCallProxyGe
   }
 
   // masm.leaveExitFrame & pop locals
   masm.adjustStack(IonOOLProxyExitFrameLayout::Size());
   return true;
 }
 
 bool IonCacheIRCompiler::emitCallProxyGetByValueResult() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   AutoSaveLiveRegisters save(*this);
   AutoOutputRegister output(*this);
 
   Register obj = allocator.useRegister(masm, reader.objOperandId());
   ValueOperand idVal = allocator.useValueRegister(masm, reader.valOperandId());
 
   allocator.discardStack(masm);
 
@@ -1133,16 +1149,17 @@ bool IonCacheIRCompiler::emitCallProxyGe
     return false;
   }
 
   masm.storeCallResultValue(output);
   return true;
 }
 
 bool IonCacheIRCompiler::emitCallProxyHasPropResult() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   AutoSaveLiveRegisters save(*this);
   AutoOutputRegister output(*this);
 
   Register obj = allocator.useRegister(masm, reader.objOperandId());
   ValueOperand idVal = allocator.useValueRegister(masm, reader.valOperandId());
   bool hasOwn = reader.readBool();
 
   allocator.discardStack(masm);
@@ -1162,16 +1179,17 @@ bool IonCacheIRCompiler::emitCallProxyHa
     }
   }
 
   masm.storeCallResultValue(output);
   return true;
 }
 
 bool IonCacheIRCompiler::emitCallNativeGetElementResult() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   AutoSaveLiveRegisters save(*this);
   AutoOutputRegister output(*this);
 
   Register obj = allocator.useRegister(masm, reader.objOperandId());
   Register index = allocator.useRegister(masm, reader.int32OperandId());
 
   allocator.discardStack(masm);
 
@@ -1185,16 +1203,17 @@ bool IonCacheIRCompiler::emitCallNativeG
     return false;
   }
 
   masm.storeCallResultValue(output);
   return true;
 }
 
 bool IonCacheIRCompiler::emitLoadUnboxedPropertyResult() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   AutoOutputRegister output(*this);
   Register obj = allocator.useRegister(masm, reader.objOperandId());
 
   JSValueType fieldType = reader.valueType();
   int32_t fieldOffset = int32StubField(reader.stubOffset());
   masm.loadUnboxedProperty(Address(obj, fieldOffset), fieldType, output);
   return true;
 }
@@ -1211,16 +1230,17 @@ bool IonCacheIRCompiler::emitLoadFrameNu
   MOZ_CRASH("Baseline-specific op");
 }
 
 bool IonCacheIRCompiler::emitLoadFrameArgumentResult() {
   MOZ_CRASH("Baseline-specific op");
 }
 
 bool IonCacheIRCompiler::emitLoadEnvironmentFixedSlotResult() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   AutoOutputRegister output(*this);
   Register obj = allocator.useRegister(masm, reader.objOperandId());
   int32_t offset = int32StubField(reader.stubOffset());
 
   FailurePath* failure;
   if (!addFailurePath(&failure)) {
     return false;
   }
@@ -1230,16 +1250,17 @@ bool IonCacheIRCompiler::emitLoadEnviron
   masm.branchTestMagic(Assembler::Equal, slot, failure->label());
 
   // Load the value.
   masm.loadTypedOrValue(slot, output);
   return true;
 }
 
 bool IonCacheIRCompiler::emitLoadEnvironmentDynamicSlotResult() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   AutoOutputRegister output(*this);
   Register obj = allocator.useRegister(masm, reader.objOperandId());
   int32_t offset = int32StubField(reader.stubOffset());
   AutoScratchRegisterMaybeOutput scratch(allocator, masm, output);
 
   FailurePath* failure;
   if (!addFailurePath(&failure)) {
     return false;
@@ -1252,20 +1273,22 @@ bool IonCacheIRCompiler::emitLoadEnviron
   masm.branchTestMagic(Assembler::Equal, slot, failure->label());
 
   // Load the value.
   masm.loadTypedOrValue(slot, output);
   return true;
 }
 
 bool IonCacheIRCompiler::emitLoadStringResult() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   MOZ_CRASH("not used in ion");
 }
 
 bool IonCacheIRCompiler::emitCallStringSplitResult() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   AutoSaveLiveRegisters save(*this);
   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);
@@ -1281,16 +1304,17 @@ bool IonCacheIRCompiler::emitCallStringS
     return false;
   }
 
   masm.storeCallResultValue(output);
   return true;
 }
 
 bool IonCacheIRCompiler::emitCompareStringResult() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   AutoSaveLiveRegisters save(*this);
   AutoOutputRegister output(*this);
 
   Register left = allocator.useRegister(masm, reader.stringOperandId());
   Register right = allocator.useRegister(masm, reader.stringOperandId());
   JSOp op = reader.jsop();
 
   allocator.discardStack(masm);
@@ -1470,16 +1494,17 @@ static void EmitCheckPropertyTypes(Macro
   masm.bind(&done);
   if (objScratch != InvalidReg) {
     masm.Pop(objScratch);
   }
   masm.Pop(obj);
 }
 
 bool IonCacheIRCompiler::emitStoreFixedSlot() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   Register obj = allocator.useRegister(masm, reader.objOperandId());
   int32_t offset = int32StubField(reader.stubOffset());
   ConstantOrRegister val =
       allocator.useConstantOrRegister(masm, reader.valOperandId());
 
   Maybe<AutoScratchRegister> scratch;
   if (needsPostBarrier()) {
     scratch.emplace(allocator, masm);
@@ -1500,16 +1525,17 @@ bool IonCacheIRCompiler::emitStoreFixedS
   masm.storeConstantOrRegister(val, slot);
   if (needsPostBarrier()) {
     emitPostBarrierSlot(obj, val, scratch.ref());
   }
   return true;
 }
 
 bool IonCacheIRCompiler::emitStoreDynamicSlot() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   Register obj = allocator.useRegister(masm, reader.objOperandId());
   int32_t offset = int32StubField(reader.stubOffset());
   ConstantOrRegister val =
       allocator.useConstantOrRegister(masm, reader.valOperandId());
   AutoScratchRegister scratch(allocator, masm);
 
   if (typeCheckInfo_->isSet()) {
     FailurePath* failure;
@@ -1527,16 +1553,17 @@ bool IonCacheIRCompiler::emitStoreDynami
   masm.storeConstantOrRegister(val, slot);
   if (needsPostBarrier()) {
     emitPostBarrierSlot(obj, val, scratch);
   }
   return true;
 }
 
 bool IonCacheIRCompiler::emitAddAndStoreSlotShared(CacheOp op) {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   Register obj = allocator.useRegister(masm, reader.objOperandId());
   int32_t offset = int32StubField(reader.stubOffset());
   ConstantOrRegister val =
       allocator.useConstantOrRegister(masm, reader.valOperandId());
 
   AutoScratchRegister scratch1(allocator, masm);
 
   Maybe<AutoScratchRegister> scratch2;
@@ -1621,28 +1648,32 @@ bool IonCacheIRCompiler::emitAddAndStore
   if (needsPostBarrier()) {
     emitPostBarrierSlot(obj, val, scratch1);
   }
 
   return true;
 }
 
 bool IonCacheIRCompiler::emitAddAndStoreFixedSlot() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   return emitAddAndStoreSlotShared(CacheOp::AddAndStoreFixedSlot);
 }
 
 bool IonCacheIRCompiler::emitAddAndStoreDynamicSlot() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   return emitAddAndStoreSlotShared(CacheOp::AddAndStoreDynamicSlot);
 }
 
 bool IonCacheIRCompiler::emitAllocateAndStoreDynamicSlot() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   return emitAddAndStoreSlotShared(CacheOp::AllocateAndStoreDynamicSlot);
 }
 
 bool IonCacheIRCompiler::emitStoreUnboxedProperty() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   Register obj = allocator.useRegister(masm, reader.objOperandId());
   JSValueType fieldType = reader.valueType();
   int32_t offset = int32StubField(reader.stubOffset());
   ConstantOrRegister val =
       allocator.useConstantOrRegister(masm, reader.valOperandId());
 
   Maybe<AutoScratchRegister> scratch;
   if (needsPostBarrier() && UnboxedTypeNeedsPostBarrier(fieldType)) {
@@ -1665,16 +1696,17 @@ bool IonCacheIRCompiler::emitStoreUnboxe
   masm.storeUnboxedProperty(fieldAddr, fieldType, val, /* failure = */ nullptr);
   if (needsPostBarrier() && UnboxedTypeNeedsPostBarrier(fieldType)) {
     emitPostBarrierSlot(obj, val, scratch.ref());
   }
   return true;
 }
 
 bool IonCacheIRCompiler::emitStoreTypedObjectReferenceProperty() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   Register obj = allocator.useRegister(masm, reader.objOperandId());
   int32_t offset = int32StubField(reader.stubOffset());
   TypedThingLayout layout = reader.typedThingLayout();
   ReferenceType type = reader.referenceTypeDescrType();
 
   ValueOperand val = allocator.useValueRegister(masm, reader.valOperandId());
 
   AutoScratchRegister scratch1(allocator, masm);
@@ -1699,16 +1731,17 @@ bool IonCacheIRCompiler::emitStoreTypedO
 
   if (needsPostBarrier() && type != ReferenceType::TYPE_STRING) {
     emitPostBarrierSlot(obj, val, scratch1);
   }
   return true;
 }
 
 bool IonCacheIRCompiler::emitStoreTypedObjectScalarProperty() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   Register obj = allocator.useRegister(masm, reader.objOperandId());
   int32_t offset = int32StubField(reader.stubOffset());
   TypedThingLayout layout = reader.typedThingLayout();
   Scalar::Type type = reader.scalarType();
   ValueOperand val = allocator.useValueRegister(masm, reader.valOperandId());
   AutoScratchRegister scratch1(allocator, masm);
   AutoScratchRegister scratch2(allocator, masm);
 
@@ -1788,16 +1821,17 @@ static void EmitAssertNoCopyOnWriteEleme
   masm.branchTest32(Assembler::Zero, elementsFlags,
                     Imm32(ObjectElements::COPY_ON_WRITE), &ok);
   masm.assumeUnreachable("Unexpected copy-on-write elements in Ion IC!");
   masm.bind(&ok);
 #endif
 }
 
 bool IonCacheIRCompiler::emitStoreDenseElement() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   Register obj = allocator.useRegister(masm, reader.objOperandId());
   Register index = allocator.useRegister(masm, reader.int32OperandId());
   ConstantOrRegister val =
       allocator.useConstantOrRegister(masm, reader.valOperandId());
 
   AutoScratchRegister scratch1(allocator, masm);
   AutoScratchRegister scratch2(allocator, masm);
 
@@ -1833,16 +1867,17 @@ bool IonCacheIRCompiler::emitStoreDenseE
   EmitStoreDenseElement(masm, val, scratch1, element);
   if (needsPostBarrier()) {
     emitPostBarrierElement(obj, val, scratch1, index);
   }
   return true;
 }
 
 bool IonCacheIRCompiler::emitStoreDenseElementHole() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   Register obj = allocator.useRegister(masm, reader.objOperandId());
   Register index = allocator.useRegister(masm, reader.int32OperandId());
   ConstantOrRegister val =
       allocator.useConstantOrRegister(masm, reader.valOperandId());
 
   // handleAdd boolean is only relevant for Baseline. Ion ICs can always
   // handle adds as we don't have to set any flags on the fallback stub to
   // track this.
@@ -1937,16 +1972,17 @@ bool IonCacheIRCompiler::emitStoreDenseE
 }
 
 bool IonCacheIRCompiler::emitArrayPush() {
   MOZ_ASSERT_UNREACHABLE("emitArrayPush not supported for IonCaches.");
   return false;
 }
 
 bool IonCacheIRCompiler::emitStoreTypedElement() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   Register obj = allocator.useRegister(masm, reader.objOperandId());
   Register index = allocator.useRegister(masm, reader.int32OperandId());
   ConstantOrRegister val =
       allocator.useConstantOrRegister(masm, reader.valOperandId());
 
   TypedThingLayout layout = reader.typedThingLayout();
   Scalar::Type arrayType = reader.scalarType();
   bool handleOOB = reader.readBool();
@@ -2006,16 +2042,17 @@ bool IonCacheIRCompiler::emitStoreTypedE
     masm.storeToTypedIntArray(arrayType, valueToStore, dest);
   }
 
   masm.bind(&done);
   return true;
 }
 
 bool IonCacheIRCompiler::emitCallNativeSetter() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   AutoSaveLiveRegisters save(*this);
 
   Register obj = allocator.useRegister(masm, reader.objOperandId());
   JSFunction* target = &objectStubField(reader.stubOffset())->as<JSFunction>();
   MOZ_ASSERT(target->isNative());
   ConstantOrRegister val =
       allocator.useConstantOrRegister(masm, reader.valOperandId());
 
@@ -2071,16 +2108,17 @@ bool IonCacheIRCompiler::emitCallNativeS
     masm.switchToRealm(cx_->realm(), ReturnReg);
   }
 
   masm.adjustStack(IonOOLNativeExitFrameLayout::Size(1));
   return true;
 }
 
 bool IonCacheIRCompiler::emitCallScriptedSetter() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   AutoSaveLiveRegisters save(*this);
 
   Register obj = allocator.useRegister(masm, reader.objOperandId());
   JSFunction* target = &objectStubField(reader.stubOffset())->as<JSFunction>();
   ConstantOrRegister val =
       allocator.useConstantOrRegister(masm, reader.valOperandId());
 
   bool isCrossRealm = reader.readBool();
@@ -2143,16 +2181,17 @@ bool IonCacheIRCompiler::emitCallScripte
     masm.switchToRealm(cx_->realm(), ReturnReg);
   }
 
   masm.freeStack(masm.framePushed() - framePushedBefore);
   return true;
 }
 
 bool IonCacheIRCompiler::emitCallSetArrayLength() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   AutoSaveLiveRegisters save(*this);
 
   Register obj = allocator.useRegister(masm, reader.objOperandId());
   bool strict = reader.readBool();
   ConstantOrRegister val =
       allocator.useConstantOrRegister(masm, reader.valOperandId());
 
   allocator.discardStack(masm);
@@ -2161,16 +2200,17 @@ bool IonCacheIRCompiler::emitCallSetArra
   masm.Push(Imm32(strict));
   masm.Push(val);
   masm.Push(obj);
 
   return callVM(masm, SetArrayLengthInfo);
 }
 
 bool IonCacheIRCompiler::emitCallProxySet() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   AutoSaveLiveRegisters save(*this);
 
   Register obj = allocator.useRegister(masm, reader.objOperandId());
   ConstantOrRegister val =
       allocator.useConstantOrRegister(masm, reader.valOperandId());
   jsid id = idStubField(reader.stubOffset());
   bool strict = reader.readBool();
 
@@ -2183,16 +2223,17 @@ bool IonCacheIRCompiler::emitCallProxySe
   masm.Push(val);
   masm.Push(id, scratch);
   masm.Push(obj);
 
   return callVM(masm, ProxySetPropertyInfo);
 }
 
 bool IonCacheIRCompiler::emitCallProxySetByValue() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   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();
@@ -2204,16 +2245,17 @@ bool IonCacheIRCompiler::emitCallProxySe
   masm.Push(val);
   masm.Push(idVal);
   masm.Push(obj);
 
   return callVM(masm, ProxySetPropertyByValueInfo);
 }
 
 bool IonCacheIRCompiler::emitCallAddOrUpdateSparseElementHelper() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   AutoSaveLiveRegisters save(*this);
 
   Register obj = allocator.useRegister(masm, reader.objOperandId());
   Register id = allocator.useRegister(masm, reader.int32OperandId());
   ValueOperand val = allocator.useValueRegister(masm, reader.valOperandId());
   bool strict = reader.readBool();
 
   allocator.discardStack(masm);
@@ -2223,16 +2265,17 @@ bool IonCacheIRCompiler::emitCallAddOrUp
   masm.Push(val);
   masm.Push(id);
   masm.Push(obj);
 
   return callVM(masm, AddOrUpdateSparseElementHelperInfo);
 }
 
 bool IonCacheIRCompiler::emitCallGetSparseElementResult() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   AutoSaveLiveRegisters save(*this);
   AutoOutputRegister output(*this);
 
   Register obj = allocator.useRegister(masm, reader.objOperandId());
   Register id = allocator.useRegister(masm, reader.int32OperandId());
 
   allocator.discardStack(masm);
   prepareVMCall(masm, save);
@@ -2243,16 +2286,17 @@ bool IonCacheIRCompiler::emitCallGetSpar
     return false;
   }
 
   masm.storeCallResultValue(output);
   return true;
 }
 
 bool IonCacheIRCompiler::emitMegamorphicSetElement() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   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();
@@ -2265,16 +2309,17 @@ bool IonCacheIRCompiler::emitMegamorphic
   masm.Push(val);
   masm.Push(idVal);
   masm.Push(obj);
 
   return callVM(masm, SetObjectElementInfo);
 }
 
 bool IonCacheIRCompiler::emitLoadTypedObjectResult() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   AutoOutputRegister output(*this);
   Register obj = allocator.useRegister(masm, reader.objOperandId());
   AutoScratchRegister scratch1(allocator, masm);
   AutoScratchRegister scratch2(allocator, masm);
 
   TypedThingLayout layout = reader.typedThingLayout();
   uint32_t typeDescr = reader.typeDescrKey();
   uint32_t fieldOffset = int32StubField(reader.stubOffset());
@@ -2282,35 +2327,40 @@ bool IonCacheIRCompiler::emitLoadTypedOb
   // Get the object's data pointer.
   LoadTypedThingData(masm, layout, obj, scratch1);
 
   Address fieldAddr(scratch1, fieldOffset);
   emitLoadTypedObjectResultShared(fieldAddr, scratch2, typeDescr, output);
   return true;
 }
 
-bool IonCacheIRCompiler::emitTypeMonitorResult() { return emitReturnFromIC(); }
+bool IonCacheIRCompiler::emitTypeMonitorResult() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
+  return emitReturnFromIC();
+}
 
 bool IonCacheIRCompiler::emitReturnFromIC() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   if (!savedLiveRegs_) {
     allocator.restoreInputState(masm);
   }
 
   RepatchLabel rejoin;
   rejoinOffset_ = masm.jumpWithPatch(&rejoin);
   masm.bind(&rejoin);
   return true;
 }
 
 bool IonCacheIRCompiler::emitLoadStackValue() {
   MOZ_ASSERT_UNREACHABLE("emitLoadStackValue not supported for IonCaches.");
   return false;
 }
 
 bool IonCacheIRCompiler::emitGuardAndGetIterator() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   Register obj = allocator.useRegister(masm, reader.objOperandId());
 
   AutoScratchRegister scratch1(allocator, masm);
   AutoScratchRegister scratch2(allocator, masm);
   AutoScratchRegister niScratch(allocator, masm);
 
   PropertyIteratorObject* iterobj =
       &objectStubField(reader.stubOffset())->as<PropertyIteratorObject>();
@@ -2348,16 +2398,17 @@ bool IonCacheIRCompiler::emitGuardAndGet
   // Chain onto the active iterator stack.
   masm.loadPtr(AbsoluteAddress(enumerators), scratch1);
   emitRegisterEnumerator(scratch1, niScratch, scratch2);
 
   return true;
 }
 
 bool IonCacheIRCompiler::emitGuardDOMExpandoMissingOrGuardShape() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   ValueOperand val = allocator.useValueRegister(masm, reader.valOperandId());
   Shape* shape = shapeStubField(reader.stubOffset());
 
   AutoScratchRegister objScratch(allocator, masm);
 
   FailurePath* failure;
   if (!addFailurePath(&failure)) {
     return false;
@@ -2373,16 +2424,17 @@ bool IonCacheIRCompiler::emitGuardDOMExp
   masm.branchTestObjShapeNoSpectreMitigations(Assembler::NotEqual, objScratch,
                                               shape, failure->label());
 
   masm.bind(&done);
   return true;
 }
 
 bool IonCacheIRCompiler::emitLoadDOMExpandoValueGuardGeneration() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   Register obj = allocator.useRegister(masm, reader.objOperandId());
   ExpandoAndGeneration* expandoAndGeneration =
       rawWordStubField<ExpandoAndGeneration*>(reader.stubOffset());
   uint64_t* generationFieldPtr =
       expandoGenerationStubFieldPtr(reader.stubOffset());
 
   AutoScratchRegister scratch1(allocator, masm);
   AutoScratchRegister scratch2(allocator, masm);
@@ -2516,16 +2568,17 @@ void IonIC::attachCacheIRStub(JSContext*
     return;
   }
 
   attachStub(newStub, code);
   *attached = true;
 }
 
 bool IonCacheIRCompiler::emitCallStringConcatResult() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   AutoSaveLiveRegisters save(*this);
   AutoOutputRegister output(*this);
 
   Register lhs = allocator.useRegister(masm, reader.stringOperandId());
   Register rhs = allocator.useRegister(masm, reader.stringOperandId());
 
   allocator.discardStack(masm);
 
@@ -2544,16 +2597,17 @@ bool IonCacheIRCompiler::emitCallStringC
 
 typedef bool (*DoConcatStringObjectFn)(JSContext*, HandleValue, HandleValue,
                                        MutableHandleValue);
 const VMFunction DoIonConcatStringObjectInfo =
     FunctionInfo<DoConcatStringObjectFn>(DoConcatStringObject,
                                          "DoIonConcatStringObject");
 
 bool IonCacheIRCompiler::emitCallStringObjectConcatResult() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
   AutoSaveLiveRegisters save(*this);
   AutoOutputRegister output(*this);
 
   ValueOperand lhs = allocator.useValueRegister(masm, reader.valOperandId());
   ValueOperand rhs = allocator.useValueRegister(masm, reader.valOperandId());
 
   allocator.discardStack(masm);
 
--- a/js/src/jit/arm64/CodeGenerator-arm64.cpp
+++ b/js/src/jit/arm64/CodeGenerator-arm64.cpp
@@ -807,16 +807,17 @@ class js::jit::OutOfLineTableSwitch
   MTableSwitch* mir() const { return mir_; }
 
   CodeLabel* jumpLabel() { return &jumpLabel_; }
 };
 
 void CodeGeneratorARM64::visitOutOfLineTableSwitch(OutOfLineTableSwitch* ool) {
   MTableSwitch* mir = ool->mir();
 
+  AutoForbidPools afp(&masm, (mir->numCases() + 1) * (sizeof(void*) / vixl::kInstructionSize));
   masm.haltingAlign(sizeof(void*));
   masm.bind(ool->jumpLabel());
   masm.addCodeLabel(*ool->jumpLabel());
 
   for (size_t i = 0; i < mir->numCases(); i++) {
     LBlock* caseblock = skipTrivialBlocks(mir->getCase(i))->lir();
     Label* caseheader = caseblock->label();
     uint32_t caseoffset = caseheader->offset();
--- a/js/src/jit/arm64/MacroAssembler-arm64.h
+++ b/js/src/jit/arm64/MacroAssembler-arm64.h
@@ -214,17 +214,17 @@ class MacroAssemblerCompat : public vixl
   }
   void pop(ARMFPRegister r0, ARMFPRegister r1, ARMFPRegister r2,
            ARMFPRegister r3) {
     vixl::MacroAssembler::Pop(r0, r1, r2, r3);
   }
 
   void pop(const ValueOperand& v) { pop(v.valueReg()); }
   void pop(const FloatRegister& f) {
-    vixl::MacroAssembler::Pop(ARMRegister(f.code(), 64));
+    vixl::MacroAssembler::Pop(ARMFPRegister(f, 64));
   }
 
   void implicitPop(uint32_t args) {
     MOZ_ASSERT(args % sizeof(intptr_t) == 0);
     adjustFrame(0 - args);
   }
   void Pop(ARMRegister r) {
     vixl::MacroAssembler::Pop(r);
--- a/js/src/js.msg
+++ b/js/src/js.msg
@@ -391,18 +391,18 @@ MSG_DEF(JSMSG_WASM_IND_CALL_TO_NULL,   0
 MSG_DEF(JSMSG_WASM_IND_CALL_BAD_SIG,   0, JSEXN_WASMRUNTIMEERROR, "indirect call signature mismatch")
 MSG_DEF(JSMSG_WASM_UNREACHABLE,        0, JSEXN_WASMRUNTIMEERROR, "unreachable executed")
 MSG_DEF(JSMSG_WASM_INTEGER_OVERFLOW,   0, JSEXN_WASMRUNTIMEERROR, "integer overflow")
 MSG_DEF(JSMSG_WASM_INVALID_CONVERSION, 0, JSEXN_WASMRUNTIMEERROR, "invalid conversion to integer")
 MSG_DEF(JSMSG_WASM_INT_DIVIDE_BY_ZERO, 0, JSEXN_WASMRUNTIMEERROR, "integer divide by zero")
 MSG_DEF(JSMSG_WASM_OUT_OF_BOUNDS,      0, JSEXN_WASMRUNTIMEERROR, "index out of bounds")
 MSG_DEF(JSMSG_WASM_UNALIGNED_ACCESS,   0, JSEXN_WASMRUNTIMEERROR, "unaligned memory access")
 MSG_DEF(JSMSG_WASM_WAKE_OVERFLOW,      0, JSEXN_WASMRUNTIMEERROR, "too many woken agents")
-MSG_DEF(JSMSG_WASM_INVALID_PASSIVE_DATA_SEG, 0, JSEXN_WASMRUNTIMEERROR, "use of invalid passive data segment")
-MSG_DEF(JSMSG_WASM_INVALID_PASSIVE_ELEM_SEG, 0, JSEXN_WASMRUNTIMEERROR, "use of invalid passive element segment")
+MSG_DEF(JSMSG_WASM_DROPPED_DATA_SEG,   0, JSEXN_WASMRUNTIMEERROR, "use of dropped data segment")
+MSG_DEF(JSMSG_WASM_DROPPED_ELEM_SEG,   0, JSEXN_WASMRUNTIMEERROR, "use of dropped element segment")
 MSG_DEF(JSMSG_WASM_DEREF_NULL,         0, JSEXN_WASMRUNTIMEERROR, "dereferencing null pointer")
 MSG_DEF(JSMSG_WASM_BAD_RANGE ,         2, JSEXN_RANGEERR,    "bad {0} {1}")
 MSG_DEF(JSMSG_WASM_BAD_GROW,           1, JSEXN_RANGEERR,    "failed to grow {0}")
 MSG_DEF(JSMSG_WASM_TABLE_OUT_OF_BOUNDS, 0, JSEXN_RANGEERR,   "table index out of bounds")
 MSG_DEF(JSMSG_WASM_BAD_UINT32,         2, JSEXN_TYPEERR,     "bad {0} {1}")
 MSG_DEF(JSMSG_WASM_BAD_BUF_ARG,        0, JSEXN_TYPEERR,     "first argument must be an ArrayBuffer or typed array object")
 MSG_DEF(JSMSG_WASM_BAD_MOD_ARG,        0, JSEXN_TYPEERR,     "first argument must be a WebAssembly.Module")
 MSG_DEF(JSMSG_WASM_BAD_BUF_MOD_ARG,    0, JSEXN_TYPEERR,     "first argument must be a WebAssembly.Module, ArrayBuffer or typed array object")
--- a/js/src/vm/MutexIDs.h
+++ b/js/src/vm/MutexIDs.h
@@ -55,17 +55,16 @@
   _(WasmStreamEnd, 500)               \
   _(WasmStreamStatus, 500)            \
   _(WasmRuntimeInstances, 500)        \
   _(WasmSignalInstallState, 500)      \
                                       \
   _(IcuTimeZoneStateMutex, 600)       \
   _(ThreadId, 600)                    \
   _(WasmCodeSegmentMap, 600)          \
-  _(WasmDeferredValidation, 600)      \
   _(TraceLoggerGraphState, 600)       \
   _(VTuneLock, 600)
 
 namespace js {
 namespace mutexid {
 
 #define DEFINE_MUTEX_ID(name, order) static const MutexId name{#name, order};
 FOR_EACH_MUTEX(DEFINE_MUTEX_ID)
--- a/js/src/wasm/WasmAST.h
+++ b/js/src/wasm/WasmAST.h
@@ -402,17 +402,17 @@ enum class AstExprKind {
   First,
   GetGlobal,
   GetLocal,
   GrowMemory,
   If,
   Load,
 #ifdef ENABLE_WASM_BULKMEM_OPS
   MemOrTableCopy,
-  MemOrTableDrop,
+  DataOrElemDrop,
   MemFill,
   MemOrTableInit,
 #endif
 #ifdef ENABLE_WASM_GENERALIZED_TABLES
   TableGet,
   TableGrow,
   TableSet,
   TableSize,
@@ -829,33 +829,33 @@ class AstMemOrTableCopy : public AstExpr
         isMem_(isMem),
         destTable_(destTable),
         dest_(dest),
         srcTable_(srcTable),
         src_(src),
         len_(len) {}
 
   bool isMem() const { return isMem_; }
-  AstRef& destTable() { return destTable_; }
+  AstRef& destTable() { MOZ_ASSERT(!isMem()); return destTable_; }
   AstExpr& dest() const { return *dest_; }
-  AstRef& srcTable() { return srcTable_; }
+  AstRef& srcTable() { MOZ_ASSERT(!isMem()); return srcTable_; }
   AstExpr& src() const { return *src_; }
   AstExpr& len() const { return *len_; }
 };
 
-class AstMemOrTableDrop : public AstExpr {
-  bool isMem_;
+class AstDataOrElemDrop : public AstExpr {
+  bool isData_;
   uint32_t segIndex_;
 
  public:
-  static const AstExprKind Kind = AstExprKind::MemOrTableDrop;
-  explicit AstMemOrTableDrop(bool isMem, uint32_t segIndex)
-      : AstExpr(Kind, ExprType::Void), isMem_(isMem), segIndex_(segIndex) {}
+  static const AstExprKind Kind = AstExprKind::DataOrElemDrop;
+  explicit AstDataOrElemDrop(bool isData, uint32_t segIndex)
+      : AstExpr(Kind, ExprType::Void), isData_(isData), segIndex_(segIndex) {}
 
-  bool isMem() const { return isMem_; }
+  bool isData() const { return isData_; }
   uint32_t segIndex() const { return segIndex_; }
 };
 
 class AstMemFill : public AstExpr {
   AstExpr* start_;
   AstExpr* val_;
   AstExpr* len_;
 
@@ -867,36 +867,38 @@ class AstMemFill : public AstExpr {
   AstExpr& start() const { return *start_; }
   AstExpr& val() const { return *val_; }
   AstExpr& len() const { return *len_; }
 };
 
 class AstMemOrTableInit : public AstExpr {
   bool isMem_;
   uint32_t segIndex_;
-  AstRef targetTable_;
+  AstRef target_;
   AstExpr* dst_;
   AstExpr* src_;
   AstExpr* len_;
 
  public:
   static const AstExprKind Kind = AstExprKind::MemOrTableInit;
-  explicit AstMemOrTableInit(bool isMem, uint32_t segIndex, AstRef targetTable,
+  explicit AstMemOrTableInit(bool isMem, uint32_t segIndex, AstRef target,
                              AstExpr* dst, AstExpr* src, AstExpr* len)
       : AstExpr(Kind, ExprType::Void),
         isMem_(isMem),
         segIndex_(segIndex),
-        targetTable_(targetTable),
+        target_(target),
         dst_(dst),
         src_(src),
         len_(len) {}
 
   bool isMem() const { return isMem_; }
   uint32_t segIndex() const { return segIndex_; }
-  AstRef& targetTable() { return targetTable_; }
+  AstRef& target() { return target_; }
+  AstRef& targetTable() { MOZ_ASSERT(!isMem()); return target_; }
+  AstRef& targetMemory() { MOZ_ASSERT(isMem()); return target_; }
   AstExpr& dst() const { return *dst_; }
   AstExpr& src() const { return *src_; }
   AstExpr& len() const { return *len_; }
 };
 #endif
 
 #ifdef ENABLE_WASM_GENERALIZED_TABLES
 class AstTableGet : public AstExpr {
@@ -1290,16 +1292,17 @@ class AstModule : public AstNode {
   FuncTypeMap funcTypeMap_;
   ImportVector imports_;
   NameVector funcImportNames_;
   AstTableVector tables_;
   AstMemoryVector memories_;
 #ifdef ENABLE_WASM_REFTYPES
   uint32_t gcFeatureOptIn_;
 #endif
+  Maybe<uint32_t> dataCount_;
   ExportVector exports_;
   Maybe<AstStartFunc> startFunc_;
   FuncVector funcs_;
   AstDataSegmentVector dataSegments_;
   AstElemSegmentVector elemSegments_;
   AstGlobalVector globals_;
 
   size_t numGlobalImports_;
@@ -1330,16 +1333,22 @@ class AstModule : public AstNode {
   const AstMemoryVector& memories() const { return memories_; }
 #ifdef ENABLE_WASM_REFTYPES
   bool addGcFeatureOptIn(uint32_t version) {
     gcFeatureOptIn_ = version;
     return true;
   }
   uint32_t gcFeatureOptIn() const { return gcFeatureOptIn_; }
 #endif
+  bool initDataCount(uint32_t dataCount) {
+    MOZ_ASSERT(dataCount_.isNothing());
+    dataCount_.emplace(dataCount);
+    return true;
+  }
+  Maybe<uint32_t> dataCount() const { return dataCount_; }
   bool addTable(AstName name, const Limits& table, TableKind tableKind) {
     return tables_.append(AstTable(table, tableKind, false, name));
   }
   bool hasTable() const { return !!tables_.length(); }
   const AstTableVector& tables() const { return tables_; }
   bool append(AstDataSegment* seg) { return dataSegments_.append(seg); }
   const AstDataSegmentVector& dataSegments() const { return dataSegments_; }
   bool append(AstElemSegment* seg) { return elemSegments_.append(seg); }
--- a/js/src/wasm/WasmBaselineCompile.cpp
+++ b/js/src/wasm/WasmBaselineCompile.cpp
@@ -2562,18 +2562,18 @@ class BaseCompiler final : public BaseCo
   RegF64 joinRegF64_;
 
   // There are more members scattered throughout.
 
  public:
   BaseCompiler(const ModuleEnvironment& env, const FuncCompileInput& input,
                const ValTypeVector& locals, const MachineState& trapExitLayout,
                size_t trapExitLayoutNumWords, Decoder& decoder,
-               ExclusiveDeferredValidationState& dvs, TempAllocator* alloc,
-               MacroAssembler* masm, StackMaps* stackMaps);
+               TempAllocator* alloc, MacroAssembler* masm,
+               StackMaps* stackMaps);
 
   MOZ_MUST_USE bool init();
 
   FuncOffsets finish();
 
   MOZ_MUST_USE bool emitFunction();
   void emitInitStackLocals();
 
@@ -6861,17 +6861,17 @@ class BaseCompiler final : public BaseCo
   MOZ_MUST_USE bool emitAtomicStore(ValType type, Scalar::Type viewType);
   MOZ_MUST_USE bool emitWait(ValType type, uint32_t byteSize);
   MOZ_MUST_USE bool emitWake();
   MOZ_MUST_USE bool emitAtomicXchg(ValType type, Scalar::Type viewType);
   void emitAtomicXchg64(MemoryAccessDesc* access, ValType type,
                         WantResult wantResult);
 #ifdef ENABLE_WASM_BULKMEM_OPS
   MOZ_MUST_USE bool emitMemOrTableCopy(bool isMem);
-  MOZ_MUST_USE bool emitMemOrTableDrop(bool isMem);
+  MOZ_MUST_USE bool emitDataOrElemDrop(bool isData);
   MOZ_MUST_USE bool emitMemFill();
   MOZ_MUST_USE bool emitMemOrTableInit(bool isMem);
 #endif
   MOZ_MUST_USE bool emitTableGet();
   MOZ_MUST_USE bool emitTableGrow();
   MOZ_MUST_USE bool emitTableSet();
   MOZ_MUST_USE bool emitTableSize();
   MOZ_MUST_USE bool emitStructNew();
@@ -10222,34 +10222,34 @@ bool BaseCompiler::emitMemOrTableCopy(bo
   Label ok;
   masm.branchTest32(Assembler::NotSigned, ReturnReg, ReturnReg, &ok);
   trap(Trap::ThrowReported);
   masm.bind(&ok);
 
   return true;
 }
 
-bool BaseCompiler::emitMemOrTableDrop(bool isMem) {
+bool BaseCompiler::emitDataOrElemDrop(bool isData) {
   uint32_t lineOrBytecode = readCallSiteLineOrBytecode();
 
   uint32_t segIndex = 0;
-  if (!iter_.readMemOrTableDrop(isMem, &segIndex)) {
+  if (!iter_.readDataOrElemDrop(isData, &segIndex)) {
     return false;
   }
 
   if (deadCode_) {
     return true;
   }
 
   // Despite the cast to int32_t, the callee regards the value as unsigned.
   //
   // Returns -1 on trap, otherwise 0.
   pushI32(int32_t(segIndex));
   SymbolicAddress callee =
-      isMem ? SymbolicAddress::MemDrop : SymbolicAddress::TableDrop;
+      isData ? SymbolicAddress::DataDrop : SymbolicAddress::ElemDrop;
   if (!emitInstanceCall(lineOrBytecode, SigPI_, ExprType::Void, callee)) {
     return false;
   }
 
   Label ok;
   masm.branchTest32(Assembler::NotSigned, ReturnReg, ReturnReg, &ok);
   trap(Trap::ThrowReported);
   masm.bind(&ok);
@@ -11528,26 +11528,26 @@ bool BaseCompiler::emitBody() {
 #else
             CHECK_NEXT(emitConversionOOM(
                 emitTruncateF64ToI64<TRUNC_UNSIGNED | TRUNC_SATURATING>,
                 ValType::F64, ValType::I64));
 #endif
 #ifdef ENABLE_WASM_BULKMEM_OPS
           case uint16_t(MiscOp::MemCopy):
             CHECK_NEXT(emitMemOrTableCopy(/*isMem=*/true));
-          case uint16_t(MiscOp::MemDrop):
-            CHECK_NEXT(emitMemOrTableDrop(/*isMem=*/true));
+          case uint16_t(MiscOp::DataDrop):
+            CHECK_NEXT(emitDataOrElemDrop(/*isData=*/true));
           case uint16_t(MiscOp::MemFill):
             CHECK_NEXT(emitMemFill());
           case uint16_t(MiscOp::MemInit):
             CHECK_NEXT(emitMemOrTableInit(/*isMem=*/true));
           case uint16_t(MiscOp::TableCopy):
             CHECK_NEXT(emitMemOrTableCopy(/*isMem=*/false));
-          case uint16_t(MiscOp::TableDrop):
-            CHECK_NEXT(emitMemOrTableDrop(/*isMem=*/false));
+          case uint16_t(MiscOp::ElemDrop):
+            CHECK_NEXT(emitDataOrElemDrop(/*isData=*/false));
           case uint16_t(MiscOp::TableInit):
             CHECK_NEXT(emitMemOrTableInit(/*isMem=*/false));
 #endif  // ENABLE_WASM_BULKMEM_OPS
 #ifdef ENABLE_WASM_GENERALIZED_TABLES
           case uint16_t(MiscOp::TableGet):
             CHECK_NEXT(emitTableGet());
           case uint16_t(MiscOp::TableGrow):
             CHECK_NEXT(emitTableGrow());
@@ -11812,21 +11812,20 @@ bool BaseCompiler::emitFunction() {
   return true;
 }
 
 BaseCompiler::BaseCompiler(const ModuleEnvironment& env,
                            const FuncCompileInput& func,
                            const ValTypeVector& locals,
                            const MachineState& trapExitLayout,
                            size_t trapExitLayoutNumWords, Decoder& decoder,
-                           ExclusiveDeferredValidationState& dvs,
                            TempAllocator* alloc, MacroAssembler* masm,
                            StackMaps* stackMaps)
     : env_(env),
-      iter_(env, decoder, dvs),
+      iter_(env, decoder),
       func_(func),
       lastReadCallSite_(0),
       alloc_(*alloc),
       locals_(locals),
       deadCode_(false),
       bceSafe_(0),
       latentOp_(LatentOp::None),
       latentType_(ValType::I32),
@@ -11940,17 +11939,16 @@ bool js::wasm::BaselineCanCompile() {
   return false;
 #endif
 }
 
 bool js::wasm::BaselineCompileFunctions(const ModuleEnvironment& env,
                                         LifoAlloc& lifo,
                                         const FuncCompileInputVector& inputs,
                                         CompiledCode* code,
-                                        ExclusiveDeferredValidationState& dvs,
                                         UniqueChars* error) {
   MOZ_ASSERT(env.tier() == Tier::Baseline);
   MOZ_ASSERT(env.kind == ModuleKind::Wasm);
 
   // The MacroAssembler will sometimes access the jitContext.
 
   TempAllocator alloc(&lifo);
   JitContext jitContext(&alloc);
@@ -11980,17 +11978,17 @@ bool js::wasm::BaselineCompileFunctions(
     if (!DecodeLocalEntries(d, env.kind, env.types, env.gcTypesEnabled(),
                             &locals)) {
       return false;
     }
 
     // One-pass baseline compilation.
 
     BaseCompiler f(env, func, locals, trapExitLayout, trapExitLayoutNumWords, d,
-                   dvs, &alloc, &masm, &code->stackMaps);
+                   &alloc, &masm, &code->stackMaps);
     if (!f.init()) {
       return false;
     }
     if (!f.emitFunction()) {
       return false;
     }
     if (!code->codeRanges.emplaceBack(func.index, func.lineOrBytecode,
                                       f.finish())) {
--- a/js/src/wasm/WasmBaselineCompile.h
+++ b/js/src/wasm/WasmBaselineCompile.h
@@ -27,17 +27,17 @@ namespace wasm {
 // Return whether BaselineCompileFunction can generate code on the current
 // device.
 bool BaselineCanCompile();
 
 // Generate adequate code quickly.
 MOZ_MUST_USE bool BaselineCompileFunctions(
     const ModuleEnvironment& env, LifoAlloc& lifo,
     const FuncCompileInputVector& inputs, CompiledCode* code,
-    ExclusiveDeferredValidationState& dvs, UniqueChars* error);
+    UniqueChars* error);
 
 class BaseLocalIter {
  private:
   using ConstValTypeRange = mozilla::Range<const ValType>;
 
   const ValTypeVector& locals_;
   size_t argsLength_;
   ConstValTypeRange argsRange_;  // range struct cache for ABIArgIter
--- a/js/src/wasm/WasmBuiltins.cpp
+++ b/js/src/wasm/WasmBuiltins.cpp
@@ -622,31 +622,31 @@ static void* AddressOf(SymbolicAddress i
       *abiType = Args_Int_GeneralGeneralInt64Int64;
       return FuncCast(Instance::wait_i64, *abiType);
     case SymbolicAddress::Wake:
       *abiType = Args_General3;
       return FuncCast(Instance::wake, *abiType);
     case SymbolicAddress::MemCopy:
       *abiType = Args_General4;
       return FuncCast(Instance::memCopy, *abiType);
-    case SymbolicAddress::MemDrop:
+    case SymbolicAddress::DataDrop:
       *abiType = Args_General2;
-      return FuncCast(Instance::memDrop, *abiType);
+      return FuncCast(Instance::dataDrop, *abiType);
     case SymbolicAddress::MemFill:
       *abiType = Args_General4;
       return FuncCast(Instance::memFill, *abiType);
     case SymbolicAddress::MemInit:
       *abiType = Args_General5;
       return FuncCast(Instance::memInit, *abiType);
     case SymbolicAddress::TableCopy:
       *abiType = Args_General6;
       return FuncCast(Instance::tableCopy, *abiType);
-    case SymbolicAddress::TableDrop:
+    case SymbolicAddress::ElemDrop:
       *abiType = Args_General2;
-      return FuncCast(Instance::tableDrop, *abiType);
+      return FuncCast(Instance::elemDrop, *abiType);
     case SymbolicAddress::TableInit:
       *abiType = Args_General6;
       return FuncCast(Instance::tableInit, *abiType);
     case SymbolicAddress::TableGet:
       *abiType = Args_General3;
       return FuncCast(Instance::tableGet, *abiType);
     case SymbolicAddress::TableGrow:
       *abiType = Args_General4;
@@ -734,21 +734,21 @@ bool wasm::NeedsBuiltinThunk(SymbolicAdd
     case SymbolicAddress::GrowMemory:
     case SymbolicAddress::CurrentMemory:
     case SymbolicAddress::WaitI32:
     case SymbolicAddress::WaitI64:
     case SymbolicAddress::Wake:
     case SymbolicAddress::CoerceInPlace_JitEntry:
     case SymbolicAddress::ReportInt64JSCall:
     case SymbolicAddress::MemCopy:
-    case SymbolicAddress::MemDrop:
+    case SymbolicAddress::DataDrop:
     case SymbolicAddress::MemFill:
     case SymbolicAddress::MemInit:
     case SymbolicAddress::TableCopy:
-    case SymbolicAddress::TableDrop:
+    case SymbolicAddress::ElemDrop:
     case SymbolicAddress::TableGet:
     case SymbolicAddress::TableGrow:
     case SymbolicAddress::TableInit:
     case SymbolicAddress::TableSet:
     case SymbolicAddress::TableSize:
     case SymbolicAddress::PostBarrier:
     case SymbolicAddress::StructNew:
     case SymbolicAddress::StructNarrow:
--- a/js/src/wasm/WasmCompile.cpp
+++ b/js/src/wasm/WasmCompile.cpp
@@ -79,22 +79,27 @@ CompileArgs::build(JSContext* cx, Script
   bool baseline = BaselineCanCompile() && cx->options().wasmBaseline();
   bool ion = IonCanCompile() && cx->options().wasmIon();
 #ifdef ENABLE_WASM_CRANELIFT
   bool cranelift = CraneliftCanCompile() && cx->options().wasmCranelift();
 #else
   bool cranelift = false;
 #endif
 
+#ifdef ENABLE_WASM_REFTYPES
+  bool gc = cx->options().wasmGc();
+#else
+  bool gc = false;
+#endif
+
   // Debug information such as source view or debug traps will require
   // additional memory and permanently stay in baseline code, so we try to
   // only enable it when a developer actually cares: when the debugger tab
   // is open.
   bool debug = cx->realm()->debuggerObservesAsmJS();
-  bool gc = cx->options().wasmGc();
 
   bool sharedMemory = cx->realm()->creationOptions().getSharedMemoryAndAtomicsEnabled();
   bool forceTiering = cx->options().testWasmAwaitTier2() || JitOptions.wasmDelayTier2;
 
   if (debug || gc) {
     if (!baseline) {
       JS_ReportErrorASCII(cx, "can't use wasm debug/gc without baseline");
       return nullptr;
@@ -559,17 +564,17 @@ SharedModule wasm::CompileBuffer(const C
   if (!mg.init()) {
     return nullptr;
   }
 
   if (!DecodeCodeSection(env, d, mg)) {
     return nullptr;
   }
 
-  if (!DecodeModuleTail(d, &env, mg.deferredValidationState())) {
+  if (!DecodeModuleTail(d, &env)) {
     return nullptr;
   }
 
   return mg.finishModule(bytecode, nullptr, maybeLinkData);
 }
 
 void wasm::CompileTier2(const CompileArgs& args, const Bytes& bytecode,
                         const Module& module, Atomic<bool>* cancelled) {
@@ -597,17 +602,17 @@ void wasm::CompileTier2(const CompileArg
   if (!mg.init()) {
     return;
   }
 
   if (!DecodeCodeSection(env, d, mg)) {
     return;
   }
 
-  if (!DecodeModuleTail(d, &env, mg.deferredValidationState())) {
+  if (!DecodeModuleTail(d, &env)) {
     return;
   }
 
   if (!mg.finishTier2(module)) {
     return;
   }
 
   // The caller doesn't care about success or failure; only that compilation
@@ -738,17 +743,17 @@ SharedModule wasm::CompileStreaming(
   }
 
   const StreamEndData& streamEnd = exclusiveStreamEnd.lock();
   const Bytes& tailBytes = *streamEnd.tailBytes;
 
   {
     Decoder d(tailBytes, env->codeSection->end(), error, warnings);
 
-    if (!DecodeModuleTail(d, env.ptr(), mg.deferredValidationState())) {
+    if (!DecodeModuleTail(d, env.ptr())) {
       return nullptr;
     }
 
     MOZ_ASSERT(d.done());
   }
 
   SharedBytes bytecode = CreateBytecode(envBytes, codeBytes, tailBytes, error);
   if (!bytecode) {
--- a/js/src/wasm/WasmConstants.h
+++ b/js/src/wasm/WasmConstants.h
@@ -33,16 +33,17 @@ enum class SectionId {
   Table = 4,
   Memory = 5,
   Global = 6,
   Export = 7,
   Start = 8,
   Elem = 9,
   Code = 10,
   Data = 11,
+  DataCount = 12,
   GcFeatureOptIn = 42  // Arbitrary, but fits in 7 bits
 };
 
 enum class TypeCode {
   I32 = 0x7f,  // SLEB128(-0x01)
   I64 = 0x7e,  // SLEB128(-0x02)
   F32 = 0x7d,  // SLEB128(-0x03)
   F64 = 0x7c,  // SLEB128(-0x04)
@@ -368,21 +369,21 @@ enum class MiscOp {
   I64TruncSSatF32 = 0x04,
   I64TruncUSatF32 = 0x05,
   I64TruncSSatF64 = 0x06,
   I64TruncUSatF64 = 0x07,
 
   // Bulk memory operations.  Note, these are unofficial, but in accordance
   // with the proposal as of June 2018.
   MemInit = 0x08,
-  MemDrop = 0x09,
+  DataDrop = 0x09,
   MemCopy = 0x0a,
   MemFill = 0x0b,
   TableInit = 0x0c,
-  TableDrop = 0x0d,
+  ElemDrop = 0x0d,
   TableCopy = 0x0e,
 
   // Generalized tables (reftypes proposal).  Note, these are unofficial.
   TableGrow = 0x0f,
   TableGet = 0x10,
   TableSet = 0x11,
   TableSize = 0x12,
 
--- a/js/src/wasm/WasmCraneliftCompile.cpp
+++ b/js/src/wasm/WasmCraneliftCompile.cpp
@@ -275,17 +275,16 @@ const GlobalDesc* env_global(const Crane
                              size_t globalIndex) {
   return &env->env.globals[globalIndex];
 }
 
 bool wasm::CraneliftCompileFunctions(const ModuleEnvironment& env,
                                      LifoAlloc& lifo,
                                      const FuncCompileInputVector& inputs,
                                      CompiledCode* code,
-                                     ExclusiveDeferredValidationState& dvs,
                                      UniqueChars* error) {
 
   MOZ_RELEASE_ASSERT(CraneliftCanCompile());
 
   MOZ_ASSERT(env.tier() == Tier::Optimized);
   MOZ_ASSERT(env.optimizedBackend() == OptimizedBackend::Cranelift);
   MOZ_ASSERT(!env.isAsmJS());
 
@@ -302,17 +301,17 @@ bool wasm::CraneliftCompileFunctions(con
   // Swap in already-allocated empty vectors to avoid malloc/free.
   MOZ_ASSERT(code->empty());
   if (!code->swap(masm)) {
     return false;
   }
 
   for (const FuncCompileInput& func : inputs) {
     Decoder d(func.begin, func.end, func.lineOrBytecode, error);
-    if (!ValidateFunctionBody(env, func.index, func.end - func.begin, d, dvs)) {
+    if (!ValidateFunctionBody(env, func.index, func.end - func.begin, d)) {
       return false;
     }
 
     CraneliftFuncCompileInput clifInput(func);
 
     CraneliftCompiledFunc clifFunc;
     if (!cranelift_compile_function(compiler, &clifInput, &clifFunc)) {
       *error = JS_smprintf("Cranelift error in clifFunc #%u", clifInput.index);
--- a/js/src/wasm/WasmCraneliftCompile.h
+++ b/js/src/wasm/WasmCraneliftCompile.h
@@ -31,14 +31,14 @@ MOZ_MUST_USE bool CraneliftCanCompile();
 #else
 MOZ_MUST_USE inline bool CraneliftCanCompile() { return false; }
 #endif
 
 // Generates code with Cranelift.
 MOZ_MUST_USE bool CraneliftCompileFunctions(
     const ModuleEnvironment& env, LifoAlloc& lifo,
     const FuncCompileInputVector& inputs, CompiledCode* code,
-    ExclusiveDeferredValidationState& dvs, UniqueChars* error);
+    UniqueChars* error);
 
 }  // namespace wasm
 }  // namespace js
 
 #endif  // wasm_cranelift_compile_h
--- a/js/src/wasm/WasmFrameIter.cpp
+++ b/js/src/wasm/WasmFrameIter.cpp
@@ -1342,26 +1342,26 @@ static const char* ThunkedNativeToDescri
     case SymbolicAddress::Wake:
       return "call to native wake (in wasm)";
     case SymbolicAddress::CoerceInPlace_JitEntry:
       return "out-of-line coercion for jit entry arguments (in wasm)";
     case SymbolicAddress::ReportInt64JSCall:
       return "jit call to int64 wasm function";
     case SymbolicAddress::MemCopy:
       return "call to native memory.copy function";
-    case SymbolicAddress::MemDrop:
-      return "call to native memory.drop function";
+    case SymbolicAddress::DataDrop:
+      return "call to native data.drop function";
     case SymbolicAddress::MemFill:
       return "call to native memory.fill function";
     case SymbolicAddress::MemInit:
       return "call to native memory.init function";
     case SymbolicAddress::TableCopy:
       return "call to native table.copy function";
-    case SymbolicAddress::TableDrop:
-      return "call to native table.drop function";
+    case SymbolicAddress::ElemDrop:
+      return "call to native elem.drop function";
     case SymbolicAddress::TableGet:
       return "call to native table.get function";
     case SymbolicAddress::TableGrow:
       return "call to native table.grow function";
     case SymbolicAddress::TableInit:
       return "call to native table.init function";
     case SymbolicAddress::TableSet:
       return "call to native table.set function";
--- a/js/src/wasm/WasmGenerator.cpp
+++ b/js/src/wasm/WasmGenerator.cpp
@@ -77,17 +77,16 @@ ModuleGenerator::ModuleGenerator(const C
       metadataTier_(nullptr),
       taskState_(mutexid::WasmCompileTaskState),
       lifo_(GENERATOR_LIFO_DEFAULT_CHUNK_SIZE),
       masmAlloc_(&lifo_),
       masm_(masmAlloc_),
       debugTrapCodeOffset_(),
       lastPatchedCallSite_(0),
       startOfUnpatchedCallsites_(0),
-      deferredValidationState_(mutexid::WasmDeferredValidation),
       parallel_(false),
       outstanding_(0),
       currentTask_(nullptr),
       batchedBytecode_(0),
       finishedFuncDefs_(false) {
   MOZ_ASSERT(IsCompilingWasm());
 }
 
@@ -381,20 +380,16 @@ bool ModuleGenerator::init(Metadata* may
     FuncType funcType;
     if (!funcType.clone(*env_->funcTypes[funcIndex.index()])) {
       return false;
     }
     metadataTier_->funcExports.infallibleEmplaceBack(
         std::move(funcType), funcIndex.index(), funcIndex.isExplicit());
   }
 
-  // Ensure that mutable shared state for deferred validation is correctly
-  // set up.
-  deferredValidationState_.lock()->init();
-
   // Determine whether parallel or sequential compilation is to be used and
   // initialize the CompileTasks that will be used in either mode.
 
   GlobalHelperThreadState& threads = HelperThreadState();
   MOZ_ASSERT(threads.threadCount > 1);
 
   uint32_t numTasks;
   if (CanUseExtraThreads() && threads.cpuCount > 1) {
@@ -403,17 +398,17 @@ bool ModuleGenerator::init(Metadata* may
   } else {
     numTasks = 1;
   }
 
   if (!tasks_.initCapacity(numTasks)) {
     return false;
   }
   for (size_t i = 0; i < numTasks; i++) {
-    tasks_.infallibleEmplaceBack(*env_, taskState_, deferredValidationState_,
+    tasks_.infallibleEmplaceBack(*env_, taskState_,
                                  COMPILATION_LIFO_DEFAULT_CHUNK_SIZE);
   }
 
   if (!freeTasks_.reserve(numTasks)) {
     return false;
   }
   for (size_t i = 0; i < numTasks; i++) {
     freeTasks_.infallibleAppend(&tasks_[i]);
@@ -703,31 +698,31 @@ static bool ExecuteCompileTask(CompileTa
   MOZ_ASSERT(task->lifo.isEmpty());
   MOZ_ASSERT(task->output.empty());
 
   switch (task->env.tier()) {
     case Tier::Optimized:
 #ifdef ENABLE_WASM_CRANELIFT
       if (task->env.optimizedBackend() == OptimizedBackend::Cranelift) {
         if (!CraneliftCompileFunctions(task->env, task->lifo, task->inputs,
-                                       &task->output, task->dvs, error)) {
+                                       &task->output, error)) {
           return false;
         }
         break;
       }
 #endif
       MOZ_ASSERT(task->env.optimizedBackend() == OptimizedBackend::Ion);
       if (!IonCompileFunctions(task->env, task->lifo, task->inputs,
-                               &task->output, task->dvs, error)) {
+                               &task->output, error)) {
         return false;
       }
       break;
     case Tier::Baseline:
       if (!BaselineCompileFunctions(task->env, task->lifo, task->inputs,
-                                    &task->output, task->dvs, error)) {
+                                    &task->output, error)) {
         return false;
       }
       break;
   }
 
   MOZ_ASSERT(task->lifo.isEmpty());
   MOZ_ASSERT(task->inputs.length() == task->output.codeRanges.length());
   task->inputs.clear();
@@ -1005,24 +1000,16 @@ UniqueCodeTier ModuleGenerator::finishCo
                      metadataTier_->funcExports, &stubCode)) {
     return nullptr;
   }
 
   if (!linkCompiledCode(stubCode)) {
     return nullptr;
   }
 
-  // All functions and stubs have been compiled.  Perform module-end
-  // validation.
-
-  if (!deferredValidationState_.lock()->performDeferredValidation(*env_,
-                                                                  error_)) {
-    return nullptr;
-  }
-
   // Finish linking and metadata.
 
   if (!finishCodegen()) {
     return nullptr;
   }
 
   if (!finishMetadataTier()) {
     return nullptr;
--- a/js/src/wasm/WasmGenerator.h
+++ b/js/src/wasm/WasmGenerator.h
@@ -112,24 +112,23 @@ struct CompileTaskState {
 typedef ExclusiveWaitableData<CompileTaskState> ExclusiveCompileTaskState;
 
 // A CompileTask holds a batch of input functions that are to be compiled on a
 // helper thread as well as, eventually, the results of compilation.
 
 struct CompileTask {
   const ModuleEnvironment& env;
   ExclusiveCompileTaskState& state;
-  ExclusiveDeferredValidationState& dvs;
   LifoAlloc lifo;
   FuncCompileInputVector inputs;
   CompiledCode output;
 
   CompileTask(const ModuleEnvironment& env, ExclusiveCompileTaskState& state,
-              ExclusiveDeferredValidationState& dvs, size_t defaultChunkSize)
-      : env(env), state(state), dvs(dvs), lifo(defaultChunkSize) {}
+              size_t defaultChunkSize)
+      : env(env), state(state), lifo(defaultChunkSize) {}
 
   size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const;
 };
 
 // A ModuleGenerator encapsulates the creation of a wasm module. During the
 // lifetime of a ModuleGenerator, a sequence of FunctionGenerators are created
 // and destroyed to compile the individual function bodies. After generating all
 // functions, ModuleGenerator::finish() must be called to complete the
@@ -159,19 +158,16 @@ class MOZ_STACK_CLASS ModuleGenerator {
   Uint32Vector funcToCodeRange_;
   uint32_t debugTrapCodeOffset_;
   CallFarJumpVector callFarJumps_;
   CallSiteTargetVector callSiteTargets_;
   uint32_t lastPatchedCallSite_;
   uint32_t startOfUnpatchedCallsites_;
   CodeOffsetVector debugTrapFarJumps_;
 
-  // Data accumulated for deferred validation.  Is shared and mutable.
-  ExclusiveDeferredValidationState deferredValidationState_;
-
   // Parallel compilation
   bool parallel_;
   uint32_t outstanding_;
   CompileTaskVector tasks_;
   CompileTaskPtrVector freeTasks_;
   CompileTask* currentTask_;
   uint32_t batchedBytecode_;
 
@@ -222,18 +218,14 @@ class MOZ_STACK_CLASS ModuleGenerator {
   // a new Module. Otherwise, if env->mode is Tier2, finishTier2() must be
   // called to augment the given Module with tier 2 code.
 
   SharedModule finishModule(
       const ShareableBytes& bytecode,
       JS::OptimizedEncodingListener* maybeTier2Listener = nullptr,
       UniqueLinkData* maybeLinkData = nullptr);
   MOZ_MUST_USE bool finishTier2(const Module& module);
-
-  ExclusiveDeferredValidationState& deferredValidationState() {
-    return deferredValidationState_;
-  }
 };
 
 }  // namespace wasm
 }  // namespace js
 
 #endif  // wasm_generator_h
--- a/js/src/wasm/WasmInstance.cpp
+++ b/js/src/wasm/WasmInstance.cpp
@@ -442,23 +442,23 @@ Instance::memCopy(Instance* instance, ui
 
   JSContext* cx = TlsContext.get();
   JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
                             JSMSG_WASM_OUT_OF_BOUNDS);
   return -1;
 }
 
 /* static */ int32_t /* -1 to signal trap; 0 for ok */
-Instance::memDrop(Instance* instance, uint32_t segIndex) {
+Instance::dataDrop(Instance* instance, uint32_t segIndex) {
   MOZ_RELEASE_ASSERT(size_t(segIndex) < instance->passiveDataSegments_.length(),
                      "ensured by validation");
 
   if (!instance->passiveDataSegments_[segIndex]) {
     JS_ReportErrorNumberASCII(TlsContext.get(), GetErrorMessage, nullptr,
-                              JSMSG_WASM_INVALID_PASSIVE_DATA_SEG);
+                              JSMSG_WASM_DROPPED_DATA_SEG);
     return -1;
   }
 
   SharedDataSegment& segRefPtr = instance->passiveDataSegments_[segIndex];
   MOZ_RELEASE_ASSERT(!segRefPtr->active());
 
   // Drop this instance's reference to the DataSegment so it can be released.
   segRefPtr = nullptr;
@@ -496,17 +496,17 @@ Instance::memFill(Instance* instance, ui
 /* static */ int32_t /* -1 to signal trap; 0 for ok */
 Instance::memInit(Instance* instance, uint32_t dstOffset, uint32_t srcOffset,
                   uint32_t len, uint32_t segIndex) {
   MOZ_RELEASE_ASSERT(size_t(segIndex) < instance->passiveDataSegments_.length(),
                      "ensured by validation");
 
   if (!instance->passiveDataSegments_[segIndex]) {
     JS_ReportErrorNumberASCII(TlsContext.get(), GetErrorMessage, nullptr,
-                              JSMSG_WASM_INVALID_PASSIVE_DATA_SEG);
+                              JSMSG_WASM_DROPPED_DATA_SEG);
     return -1;
   }
 
   const DataSegment& seg = *instance->passiveDataSegments_[segIndex];
   MOZ_RELEASE_ASSERT(!seg.active());
 
   const uint32_t segLen = seg.bytes.length();
 
@@ -588,23 +588,23 @@ Instance::tableCopy(Instance* instance, 
   }
 
   JS_ReportErrorNumberASCII(TlsContext.get(), GetErrorMessage, nullptr,
                             JSMSG_WASM_OUT_OF_BOUNDS);
   return -1;
 }
 
 /* static */ int32_t /* -1 to signal trap; 0 for ok */
-Instance::tableDrop(Instance* instance, uint32_t segIndex) {
+Instance::elemDrop(Instance* instance, uint32_t segIndex) {
   MOZ_RELEASE_ASSERT(size_t(segIndex) < instance->passiveElemSegments_.length(),
                      "ensured by validation");
 
   if (!instance->passiveElemSegments_[segIndex]) {
     JS_ReportErrorNumberASCII(TlsContext.get(), GetErrorMessage, nullptr,
-                              JSMSG_WASM_INVALID_PASSIVE_ELEM_SEG);
+                              JSMSG_WASM_DROPPED_ELEM_SEG);
     return -1;
   }
 
   SharedElemSegment& segRefPtr = instance->passiveElemSegments_[segIndex];
   MOZ_RELEASE_ASSERT(!segRefPtr->active());
 
   // Drop this instance's reference to the ElemSegment so it can be released.
   segRefPtr = nullptr;
@@ -660,17 +660,17 @@ void Instance::initElems(uint32_t tableI
 /* static */ int32_t /* -1 to signal trap; 0 for ok */
 Instance::tableInit(Instance* instance, uint32_t dstOffset, uint32_t srcOffset,
                     uint32_t len, uint32_t segIndex, uint32_t tableIndex) {
   MOZ_RELEASE_ASSERT(size_t(segIndex) < instance->passiveElemSegments_.length(),
                      "ensured by validation");
 
   if (!instance->passiveElemSegments_[segIndex]) {
     JS_ReportErrorNumberASCII(TlsContext.get(), GetErrorMessage, nullptr,
-                              JSMSG_WASM_INVALID_PASSIVE_ELEM_SEG);
+                              JSMSG_WASM_DROPPED_ELEM_SEG);
     return -1;
   }
 
   const ElemSegment& seg = *instance->passiveElemSegments_[segIndex];
   MOZ_RELEASE_ASSERT(!seg.active());
   const Table& table = *instance->tables()[tableIndex];
 
   // Element segments cannot currently contain arbitrary values, and anyref
--- a/js/src/wasm/WasmInstance.h
+++ b/js/src/wasm/WasmInstance.h
@@ -187,25 +187,25 @@ class Instance {
   static uint32_t currentMemory_i32(Instance* instance);
   static int32_t wait_i32(Instance* instance, uint32_t byteOffset,
                           int32_t value, int64_t timeout);
   static int32_t wait_i64(Instance* instance, uint32_t byteOffset,
                           int64_t value, int64_t timeout);
   static int32_t wake(Instance* instance, uint32_t byteOffset, int32_t count);
   static int32_t memCopy(Instance* instance, uint32_t destByteOffset,
                          uint32_t srcByteOffset, uint32_t len);
-  static int32_t memDrop(Instance* instance, uint32_t segIndex);
+  static int32_t dataDrop(Instance* instance, uint32_t segIndex);
   static int32_t memFill(Instance* instance, uint32_t byteOffset,
                          uint32_t value, uint32_t len);
   static int32_t memInit(Instance* instance, uint32_t dstOffset,
                          uint32_t srcOffset, uint32_t len, uint32_t segIndex);
   static int32_t tableCopy(Instance* instance, uint32_t dstOffset,
                            uint32_t srcOffset, uint32_t len,
                            uint32_t dstTableIndex, uint32_t srcTableIndex);
-  static int32_t tableDrop(Instance* instance, uint32_t segIndex);
+  static int32_t elemDrop(Instance* instance, uint32_t segIndex);
   static void* tableGet(Instance* instance, uint32_t index,
                         uint32_t tableIndex);
   static uint32_t tableGrow(Instance* instance, uint32_t delta, void* initValue,
                             uint32_t tableIndex);
   static int32_t tableSet(Instance* instance, uint32_t index, void* value,
                           uint32_t tableIndex);
   static uint32_t tableSize(Instance* instance, uint32_t tableIndex);
   static int32_t tableInit(Instance* instance, uint32_t dstOffset,
--- a/js/src/wasm/WasmIonCompile.cpp
+++ b/js/src/wasm/WasmIonCompile.cpp
@@ -138,21 +138,20 @@ class FunctionCompiler {
   uint32_t blockDepth_;
   ControlFlowPatchsVector blockPatches_;
 
   // TLS pointer argument to the current function.
   MWasmParameter* tlsPointer_;
 
  public:
   FunctionCompiler(const ModuleEnvironment& env, Decoder& decoder,
-                   ExclusiveDeferredValidationState& dvs,
                    const FuncCompileInput& func, const ValTypeVector& locals,
                    MIRGenerator& mirGen)
       : env_(env),
-        iter_(env, decoder, dvs),
+        iter_(env, decoder),
         func_(func),
         locals_(locals),
         lastReadCallSite_(0),
         alloc_(mirGen.alloc()),
         graph_(mirGen.graph()),
         info_(mirGen.info()),
         mirGen_(mirGen),
         curBlock_(nullptr),
@@ -2961,19 +2960,19 @@ static bool EmitMemOrTableCopy(FunctionC
 
   if (!f.checkI32NegativeMeansFailedResult(ret)) {
     return false;
   }
 
   return true;
 }
 
-static bool EmitMemOrTableDrop(FunctionCompiler& f, bool isMem) {
+static bool EmitDataOrElemDrop(FunctionCompiler& f, bool isData) {
   uint32_t segIndexVal = 0;
-  if (!f.iter().readMemOrTableDrop(isMem, &segIndexVal)) {
+  if (!f.iter().readDataOrElemDrop(isData, &segIndexVal)) {
     return false;
   }
 
   if (f.inDeadCode()) {
     return false;
   }
 
   uint32_t lineOrBytecode = f.readCallSiteLineOrBytecode();
@@ -2993,17 +2992,17 @@ static bool EmitMemOrTableDrop(FunctionC
     return false;
   }
 
   if (!f.finishCall(&args)) {
     return false;
   }
 
   SymbolicAddress callee =
-      isMem ? SymbolicAddress::MemDrop : SymbolicAddress::TableDrop;
+      isData ? SymbolicAddress::DataDrop : SymbolicAddress::ElemDrop;
   MDefinition* ret;
   if (!f.builtinInstanceMethodCall(callee, args, ValType::I32, &ret)) {
     return false;
   }
 
   if (!f.checkI32NegativeMeansFailedResult(ret)) {
     return false;
   }
@@ -3687,26 +3686,26 @@ static bool EmitBodyExprs(FunctionCompil
                                MiscOp(op.b1) == MiscOp::I64TruncUSatF32, true));
           case uint16_t(MiscOp::I64TruncSSatF64):
           case uint16_t(MiscOp::I64TruncUSatF64):
             CHECK(EmitTruncate(f, ValType::F64, ValType::I64,
                                MiscOp(op.b1) == MiscOp::I64TruncUSatF64, true));
 #ifdef ENABLE_WASM_BULKMEM_OPS
           case uint16_t(MiscOp::MemCopy):
             CHECK(EmitMemOrTableCopy(f, /*isMem=*/true));
-          case uint16_t(MiscOp::MemDrop):
-            CHECK(EmitMemOrTableDrop(f, /*isMem=*/true));
+          case uint16_t(MiscOp::DataDrop):
+            CHECK(EmitDataOrElemDrop(f, /*isData=*/true));
           case uint16_t(MiscOp::MemFill):
             CHECK(EmitMemFill(f));
           case uint16_t(MiscOp::MemInit):
             CHECK(EmitMemOrTableInit(f, /*isMem=*/true));
           case uint16_t(MiscOp::TableCopy):
             CHECK(EmitMemOrTableCopy(f, /*isMem=*/false));
-          case uint16_t(MiscOp::TableDrop):
-            CHECK(EmitMemOrTableDrop(f, /*isMem=*/false));
+          case uint16_t(MiscOp::ElemDrop):
+            CHECK(EmitDataOrElemDrop(f, /*isData=*/false));
           case uint16_t(MiscOp::TableInit):
             CHECK(EmitMemOrTableInit(f, /*isMem=*/false));
 #endif
 #ifdef ENABLE_WASM_GENERALIZED_TABLES
           case uint16_t(MiscOp::TableGet):
             CHECK(EmitTableGet(f));
           case uint16_t(MiscOp::TableGrow):
             CHECK(EmitTableGrow(f));
@@ -4008,17 +4007,16 @@ static bool EmitBodyExprs(FunctionCompil
   MOZ_CRASH("unreachable");
 
 #undef CHECK
 }
 
 bool wasm::IonCompileFunctions(const ModuleEnvironment& env, LifoAlloc& lifo,
                                const FuncCompileInputVector& inputs,
                                CompiledCode* code,
-                               ExclusiveDeferredValidationState& dvs,
                                UniqueChars* error) {
   MOZ_ASSERT(env.tier() == Tier::Optimized);
   MOZ_ASSERT(env.optimizedBackend() == OptimizedBackend::Ion);
 
   TempAllocator alloc(&lifo);
   JitContext jitContext(&alloc);
   MOZ_ASSERT(IsCompilingWasm());
   WasmMacroAssembler masm(alloc);
@@ -4049,17 +4047,17 @@ bool wasm::IonCompileFunctions(const Mod
     MIRGraph graph(&alloc);
     CompileInfo compileInfo(locals.length());
     MIRGenerator mir(nullptr, options, &alloc, &graph, &compileInfo,
                      IonOptimizations.get(OptimizationLevel::Wasm));
     mir.initMinWasmHeapLength(env.minMemoryLength);
 
     // Build MIR graph
     {
-      FunctionCompiler f(env, d, dvs, func, locals, mir);
+      FunctionCompiler f(env, d, func, locals, mir);
       if (!f.init()) {
         return false;
       }
 
       if (!f.startBlock()) {
         return false;
       }
 
--- a/js/src/wasm/WasmIonCompile.h
+++ b/js/src/wasm/WasmIonCompile.h
@@ -29,15 +29,14 @@ namespace wasm {
 // Return whether IonCompileFunction() can generate code on the current device.
 bool IonCanCompile();
 
 // Generates very fast code at the expense of compilation time.
 MOZ_MUST_USE bool IonCompileFunctions(const ModuleEnvironment& env,
                                       LifoAlloc& lifo,
                                       const FuncCompileInputVector& inputs,
                                       CompiledCode* code,
-                                      ExclusiveDeferredValidationState& dvs,
                                       UniqueChars* error);
 
 }  // namespace wasm
 }  // namespace js
 
 #endif  // wasm_ion_compile_h
--- a/js/src/wasm/WasmOpIter.cpp
+++ b/js/src/wasm/WasmOpIter.cpp
@@ -288,19 +288,19 @@ OpKind wasm::Classify(OpBytes op) {
         case MiscOp::I64TruncSSatF32:
         case MiscOp::I64TruncUSatF32:
         case MiscOp::I64TruncSSatF64:
         case MiscOp::I64TruncUSatF64:
           return OpKind::Conversion;
         case MiscOp::MemCopy:
         case MiscOp::TableCopy:
           WASM_BULK_OP(OpKind::MemOrTableCopy);
-        case MiscOp::MemDrop:
-        case MiscOp::TableDrop:
-          WASM_BULK_OP(OpKind::MemOrTableDrop);
+        case MiscOp::DataDrop:
+        case MiscOp::ElemDrop:
+          WASM_BULK_OP(OpKind::DataOrElemDrop);
         case MiscOp::MemFill:
           WASM_BULK_OP(OpKind::MemFill);
         case MiscOp::MemInit:
         case MiscOp::TableInit:
           WASM_BULK_OP(OpKind::MemOrTableInit);
         case MiscOp::TableGet:
           WASM_TABLE_OP(OpKind::TableGet);
         case MiscOp::TableGrow:
--- a/js/src/wasm/WasmOpIter.h
+++ b/js/src/wasm/WasmOpIter.h
@@ -159,17 +159,17 @@ enum class OpKind {
   OldAtomicCompareExchange,
   OldAtomicExchange,
   ExtractLane,
   ReplaceLane,
   Swizzle,
   Shuffle,
   Splat,
   MemOrTableCopy,
-  MemOrTableDrop,
+  DataOrElemDrop,
   MemFill,
   MemOrTableInit,
   TableGet,
   TableGrow,
   TableSet,
   TableSize,
   RefNull,
   StructNew,
@@ -308,17 +308,16 @@ class TypeAndValue<Nothing> {
 // it to be used on the stack.
 template <typename Policy>
 class MOZ_STACK_CLASS OpIter : private Policy {
   typedef typename Policy::Value Value;
   typedef typename Policy::ControlItem ControlItem;
 
   Decoder& d_;
   const ModuleEnvironment& env_;
-  ExclusiveDeferredValidationState& dvs_;
 
   Vector<TypeAndValue<Value>, 8, SystemAllocPolicy> valueStack_;
   Vector<ControlStackEntry<ControlItem>, 8, SystemAllocPolicy> controlStack_;
 
 #ifdef DEBUG
   OpBytes op_;
 #endif
   size_t offsetOfLastReadOp_;
@@ -386,27 +385,24 @@ class MOZ_STACK_CLASS OpIter : private P
   }
 
   inline bool Join(StackType one, StackType two, StackType* result);
 
  public:
   typedef Vector<Value, 8, SystemAllocPolicy> ValueVector;
 
 #ifdef DEBUG
-  explicit OpIter(const ModuleEnvironment& env, Decoder& decoder,
-                  ExclusiveDeferredValidationState& dvs)
+  explicit OpIter(const ModuleEnvironment& env, Decoder& decoder)
       : d_(decoder),
         env_(env),
-        dvs_(dvs),
         op_(OpBytes(Op::Limit)),
         offsetOfLastReadOp_(0) {}
 #else
-  explicit OpIter(const ModuleEnvironment& env, Decoder& decoder,
-                  ExclusiveDeferredValidationState& dvs)
-      : d_(decoder), env_(env), dvs_(dvs), offsetOfLastReadOp_(0) {}
+  explicit OpIter(const ModuleEnvironment& env, Decoder& decoder)
+      : d_(decoder), env_(env), offsetOfLastReadOp_(0) {}
 #endif
 
   // Return the decoding byte offset.
   uint32_t currentOffset() const { return d_.currentOffset(); }
 
   // Return the offset within the entire module of the last-read op.
   size_t lastOpcodeOffset() const {
     return offsetOfLastReadOp_ ? offsetOfLastReadOp_ : d_.currentOffset();
@@ -513,17 +509,17 @@ class MOZ_STACK_CLASS OpIter : private P
                                   ValType resultType, uint32_t byteSize,
                                   Value* value);
   MOZ_MUST_USE bool readAtomicCmpXchg(LinearMemoryAddress<Value>* addr,
                                       ValType resultType, uint32_t byteSize,
                                       Value* oldValue, Value* newValue);
   MOZ_MUST_USE bool readMemOrTableCopy(bool isMem, uint32_t* dstMemOrTableIndex,
                                        Value* dst, uint32_t* srcMemOrTableIndex,
                                        Value* src, Value* len);
-  MOZ_MUST_USE bool readMemOrTableDrop(bool isMem, uint32_t* segIndex);
+  MOZ_MUST_USE bool readDataOrElemDrop(bool isData, uint32_t* segIndex);
   MOZ_MUST_USE bool readMemFill(Value* start, Value* val, Value* len);
   MOZ_MUST_USE bool readMemOrTableInit(bool isMem, uint32_t* segIndex,
                                        uint32_t* dstTableIndex, Value* dst,
                                        Value* src, Value* len);
   MOZ_MUST_USE bool readTableGet(uint32_t* tableIndex, Value* index);
   MOZ_MUST_USE bool readTableGrow(uint32_t* tableIndex, Value* delta,
                                   Value* initValue);
   MOZ_MUST_USE bool readTableSet(uint32_t* tableIndex, Value* index,
@@ -1873,42 +1869,32 @@ template <typename Policy>
 inline bool OpIter<Policy>::readMemOrTableCopy(bool isMem,
                                                uint32_t* dstMemOrTableIndex,
                                                Value* dst,
                                                uint32_t* srcMemOrTableIndex,
                                                Value* src, Value* len) {
   MOZ_ASSERT(Classify(op_) == OpKind::MemOrTableCopy);
   MOZ_ASSERT(dstMemOrTableIndex != srcMemOrTableIndex);
 
-  *dstMemOrTableIndex = 0;
-  *srcMemOrTableIndex = 0;
-
-  uint32_t memOrTableFlags;
-  if (!readVarU32(&memOrTableFlags)) {
-    return fail(isMem ? "unable to read memory flags"
-                      : "unable to read table flags");
+  // We use (dest, src) everywhere in code but the spec requires (src, dest)
+  // encoding order for the immediates.
+  if (!readVarU32(srcMemOrTableIndex)) {
+    return false;
   }
-  if (!isMem && (memOrTableFlags & uint32_t(MemoryTableFlags::HasTableIndex))) {
-    if (!readVarU32(dstMemOrTableIndex)) {
-      return false;
-    }
-    if (!readVarU32(srcMemOrTableIndex)) {
-      return false;
-    }
-    memOrTableFlags ^= uint32_t(MemoryTableFlags::HasTableIndex);
-  }
-  if (memOrTableFlags != uint32_t(MemoryTableFlags::Default)) {
-    return fail(isMem ? "unrecognized memory flags"
-                      : "unrecognized table flags");
+  if (!readVarU32(dstMemOrTableIndex)) {
+    return false;
   }
 
   if (isMem) {
     if (!env_.usesMemory()) {
       return fail("can't touch memory without memory");
     }
+    if (*srcMemOrTableIndex != 0 || *dstMemOrTableIndex != 0) {
+      return fail("memory index out of range for memory.copy");
+    }
   } else {
     if (*dstMemOrTableIndex >= env_.tables.length() ||
         *srcMemOrTableIndex >= env_.tables.length()) {
       return fail("table index out of range for table.copy");
     }
   }
 
   if (!popWithType(ValType::I32, len)) {
@@ -1922,61 +1908,66 @@ inline bool OpIter<Policy>::readMemOrTab
   if (!popWithType(ValType::I32, dst)) {
     return false;
   }
 
   return true;
 }
 
 template <typename Policy>
-inline bool OpIter<Policy>::readMemOrTableDrop(bool isMem, uint32_t* segIndex) {
-  MOZ_ASSERT(Classify(op_) == OpKind::MemOrTableDrop);
-
-  if (isMem) {
+inline bool OpIter<Policy>::readDataOrElemDrop(bool isData, uint32_t* segIndex) {
+  MOZ_ASSERT(Classify(op_) == OpKind::DataOrElemDrop);
+
+  if (isData) {
     if (!env_.usesMemory()) {
       return fail("can't touch memory without memory");
     }
   } else {
     if (env_.tables.length() == 0) {
-      return fail("can't table.drop without a table");
+      return fail("can't elem.drop without a table");
     }
   }
 
   if (!readVarU32(segIndex)) {
     return false;
   }
 
-  if (isMem) {
-    // We can't range-check *segIndex at this point since we don't yet
-    // know how many data segments the module has.  So note the index, but
-    // defer the actual check for now.
-    dvs_.lock()->notifyDataSegmentIndex(*segIndex, d_.currentOffset());
+  if (isData) {
+    if (env_.dataCount.isNothing()) {
+      return fail("data.drop requires a DataCount section");
+    }
+    if (*segIndex >= *env_.dataCount) {
+      return fail("data.drop segment index out of range");
+    }
   } else {
     if (*segIndex >= env_.elemSegments.length()) {
-      return fail("element segment index out of range for table.drop");
+      return fail("element segment index out of range for elem.drop");
     }
   }
 
   return true;
 }
 
 template <typename Policy>
 inline bool OpIter<Policy>::readMemFill(Value* start, Value* val, Value* len) {
   MOZ_ASSERT(Classify(op_) == OpKind::MemFill);
 
   if (!env_.usesMemory()) {
     return fail("can't touch memory without memory");
   }
 
-  uint32_t memoryFlags;
-  if (!readVarU32(&memoryFlags)) {
-    return fail("unable to read memory flags");
+  uint32_t memoryIndex;
+  if (!readVarU32(&memoryIndex)) {
+    return false;
   }
-  if (memoryFlags != uint32_t(MemoryTableFlags::Default)) {
-    return fail("unrecognized memory flags");
+  if (!env_.usesMemory()) {
+    return fail("can't touch memory without memory");
+  }
+  if (memoryIndex != 0) {
+    return fail("memory index must be zero");
   }
 
   if (!popWithType(ValType::I32, len)) {
     return false;
   }
 
   if (!popWithType(ValType::I32, val)) {
     return false;
@@ -2004,52 +1995,43 @@ inline bool OpIter<Policy>::readMemOrTab
   if (!popWithType(ValType::I32, src)) {
     return false;
   }
 
   if (!popWithType(ValType::I32, dst)) {
     return false;
   }
 
-  *dstTableIndex = 0;
-
-  uint32_t memOrTableFlags;
-  if (!readVarU32(&memOrTableFlags)) {
-    return fail(isMem ? "unable to read memory flags"
-                      : "unable to read table flags");
+  if (!readVarU32(segIndex)) {
+    return false;
   }
-  if (!isMem && (memOrTableFlags & uint32_t(MemoryTableFlags::HasTableIndex))) {
-    if (!readVarU32(dstTableIndex)) {
-      return false;
-    }
-    memOrTableFlags ^= uint32_t(MemoryTableFlags::HasTableIndex);
+
+  uint32_t memOrTableIndex = 0;
+  if (!readVarU32(&memOrTableIndex)) {
+    return false;
   }
-  if (memOrTableFlags != uint32_t(MemoryTableFlags::Default)) {
-    return fail(isMem ? "unrecognized memory flags"
-                      : "unrecognized table flags");
-  }
-
   if (isMem) {
     if (!env_.usesMemory()) {
       return fail("can't touch memory without memory");
     }
+    if (memOrTableIndex != 0) {
+      return fail("memory index must be zero");
+    }
+    if (env_.dataCount.isNothing()) {
+      return fail("memory.init requires a DataCount section");
+    }
+    if (*segIndex >= *env_.dataCount) {
+      return fail("memory.init segment index out of range");
+    }
   } else {
-    if (*dstTableIndex >= env_.tables.length()) {
+    if (memOrTableIndex >= env_.tables.length()) {
       return fail("table index out of range for table.init");
     }
-  }
-
-  if (!readVarU32(segIndex)) {
-    return false;
-  }
-
-  if (isMem) {
-    // Same comment as for readMemOrTableDrop.
-    dvs_.lock()->notifyDataSegmentIndex(*segIndex, d_.currentOffset());
-  } else {
+    *dstTableIndex = memOrTableIndex;
+
     // Element segments must carry functions exclusively and anyfunc is not
     // yet a subtype of anyref.
     if (env_.tables[*dstTableIndex].kind != TableKind::AnyFunction) {
       return fail("only tables of 'anyfunc' may have element segments");
     }
     if (*segIndex >= env_.elemSegments.length()) {
       return fail("table.init segment index out of range");
     }
--- a/js/src/wasm/WasmTextToBinary.cpp
+++ b/js/src/wasm/WasmTextToBinary.cpp
@@ -71,16 +71,19 @@ class WasmToken {
     Call,
     CallIndirect,
     CloseParen,
     ComparisonOpcode,
     Const,
     ConversionOpcode,
     CurrentMemory,
     Data,
+#ifdef ENABLE_WASM_BULKMEM_OPS
+    DataCount,
+#endif
     Drop,
     Elem,
     Else,
     End,
     EndOfFile,
     Equal,
     Error,
     Export,
@@ -100,17 +103,17 @@ class WasmToken {
     Index,
     Memory,
     NegativeZero,
     Load,
     Local,
     Loop,
 #ifdef ENABLE_WASM_BULKMEM_OPS
     MemCopy,
-    MemDrop,
+    DataDrop,
     MemFill,
     MemInit,
 #endif
     Module,
     Mutable,
     Name,
 #ifdef ENABLE_WASM_GC
     StructNew,
@@ -134,17 +137,17 @@ class WasmToken {
     Shared,
     SignedInteger,
     Start,
     Struct,
     Store,
     Table,
 #ifdef ENABLE_WASM_BULKMEM_OPS
     TableCopy,
-    TableDrop,
+    ElemDrop,
     TableInit,
 #endif
 #ifdef ENABLE_WASM_GENERALIZED_TABLES
     TableGet,
     TableGrow,
     TableSet,
     TableSize,
 #endif
@@ -312,17 +315,17 @@ class WasmToken {
       case GetGlobal:
       case GetLocal:
       case GrowMemory:
       case If:
       case Load:
       case Loop:
 #ifdef ENABLE_WASM_BULKMEM_OPS
       case MemCopy:
-      case MemDrop:
+      case DataDrop:
       case MemFill:
       case MemInit:
 #endif
 #ifdef ENABLE_WASM_GC
       case StructNew:
       case StructGet:
       case StructSet:
       case StructNarrow:
@@ -330,17 +333,17 @@ class WasmToken {
       case Nop:
       case RefNull:
       case Return:
       case SetGlobal:
       case SetLocal:
       case Store:
 #ifdef ENABLE_WASM_BULKMEM_OPS
       case TableCopy:
-      case TableDrop:
+      case ElemDrop:
       case TableInit:
 #endif
 #ifdef ENABLE_WASM_GENERALIZED_TABLES
       case TableGet:
       case TableGrow:
       case TableSet:
       case TableSize:
 #endif
@@ -350,16 +353,19 @@ class WasmToken {
       case Unreachable:
       case Wait:
       case Wake:
         return true;
       case Align:
       case AnyFunc:
       case CloseParen:
       case Data:
+#ifdef ENABLE_WASM_BULKMEM_OPS
+      case DataCount:
+#endif
       case Elem:
       case Else:
       case EndOfFile:
       case Equal:
       case End:
       case Error:
       case Export:
       case Field:
@@ -979,25 +985,34 @@ WasmToken WasmTokenStream::next() {
       }
       if (consume(u"current_memory")) {
         return WasmToken(WasmToken::CurrentMemory, begin, cur_);
       }
       break;
 
     case 'd':
       if (consume(u"data")) {
+        if (consume(u"count")) {
+          return WasmToken(WasmToken::DataCount, begin, cur_);
+        }
+        if (consume(u".drop")) {
+          return WasmToken(WasmToken::DataDrop, begin, cur_);
+        }
         return WasmToken(WasmToken::Data, begin, cur_);
       }
       if (consume(u"drop")) {
         return WasmToken(WasmToken::Drop, begin, cur_);
       }
       break;
 
     case 'e':
       if (consume(u"elem")) {
+        if (consume(u".drop")) {
+          return WasmToken(WasmToken::ElemDrop, begin, cur_);
+        }