Bug 1364805 part 2 - Add a nsIFrame::mClass field and propagate the concrete class' value up the ctor chain. r=jfkthame
authorMats Palmgren <mats@mozilla.com>
Fri, 26 May 2017 12:11:11 +0200
changeset 411319 47ed59045f9bff59434723249b995515116d4ed0
parent 411318 45bf72e9b3b3b5d45457598865c72536b3027264
child 411320 9164c8933697fc198209d2f5455c7f0e059b670e
push id1490
push usermtabara@mozilla.com
push dateMon, 31 Jul 2017 14:08:16 +0000
treeherdermozilla-release@70e32e6bf15e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjfkthame
bugs1364805
milestone55.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
Bug 1364805 part 2 - Add a nsIFrame::mClass field and propagate the concrete class' value up the ctor chain. r=jfkthame nsIFrame::mClass is of type enum class nsQueryFrame::ClassID which is a strict subset of the nsQueryFrame::FrameIID values. For a concrete frame class, its FrameIID is the same numeric value as its ClassID. MozReview-Commit-ID: 1N0AkCGo1ol
layout/forms/nsColorControlFrame.cpp
layout/forms/nsComboboxControlFrame.cpp
layout/forms/nsDateTimeControlFrame.cpp
layout/forms/nsFieldSetFrame.cpp
layout/forms/nsFileControlFrame.cpp
layout/forms/nsFormControlFrame.cpp
layout/forms/nsFormControlFrame.h
layout/forms/nsGfxButtonControlFrame.cpp
layout/forms/nsGfxCheckboxControlFrame.cpp
layout/forms/nsGfxRadioControlFrame.cpp
layout/forms/nsHTMLButtonControlFrame.cpp
layout/forms/nsHTMLButtonControlFrame.h
layout/forms/nsImageControlFrame.cpp
layout/forms/nsLegendFrame.h
layout/forms/nsListControlFrame.cpp
layout/forms/nsMeterFrame.cpp
layout/forms/nsNumberControlFrame.cpp
layout/forms/nsProgressFrame.cpp
layout/forms/nsRangeFrame.cpp
layout/forms/nsSelectsAreaFrame.h
layout/forms/nsTextControlFrame.cpp
layout/generic/BRFrame.cpp
layout/generic/DetailsFrame.cpp
layout/generic/ViewportFrame.h
layout/generic/nsAtomicContainerFrame.h
layout/generic/nsBackdropFrame.h
layout/generic/nsBlockFrame.h
layout/generic/nsBulletFrame.h
layout/generic/nsCanvasFrame.h
layout/generic/nsColumnSetFrame.cpp
layout/generic/nsContainerFrame.h
layout/generic/nsFirstLetterFrame.h
layout/generic/nsFlexContainerFrame.h
layout/generic/nsFrame.cpp
layout/generic/nsFrame.h
layout/generic/nsFrameSetFrame.cpp
layout/generic/nsGfxScrollFrame.cpp
layout/generic/nsGfxScrollFrame.h
layout/generic/nsGridContainerFrame.h
layout/generic/nsHTMLCanvasFrame.h
layout/generic/nsIFrame.h
layout/generic/nsImageFrame.cpp
layout/generic/nsImageFrame.h
layout/generic/nsInlineFrame.h
layout/generic/nsLeafFrame.h
layout/generic/nsPageContentFrame.h
layout/generic/nsPageFrame.cpp
layout/generic/nsPlaceholderFrame.h
layout/generic/nsPluginFrame.cpp
layout/generic/nsQueryFrame.h
layout/generic/nsRubyBaseContainerFrame.h
layout/generic/nsRubyBaseFrame.h
layout/generic/nsRubyContentFrame.h
layout/generic/nsRubyFrame.h
layout/generic/nsRubyTextContainerFrame.h
layout/generic/nsRubyTextFrame.h
layout/generic/nsSimplePageSequenceFrame.cpp
layout/generic/nsSplittableFrame.h
layout/generic/nsSubDocumentFrame.cpp
layout/generic/nsTextFrame.cpp
layout/generic/nsTextFrame.h
layout/generic/nsVideoFrame.cpp
layout/mathml/nsMathMLContainerFrame.h
layout/mathml/nsMathMLSelectedFrame.h
layout/mathml/nsMathMLTokenFrame.h
layout/mathml/nsMathMLmactionFrame.h
layout/mathml/nsMathMLmencloseFrame.cpp
layout/mathml/nsMathMLmencloseFrame.h
layout/mathml/nsMathMLmfencedFrame.h
layout/mathml/nsMathMLmfracFrame.h
layout/mathml/nsMathMLmmultiscriptsFrame.h
layout/mathml/nsMathMLmoFrame.h
layout/mathml/nsMathMLmpaddedFrame.h
layout/mathml/nsMathMLmrootFrame.cpp
layout/mathml/nsMathMLmrowFrame.h
layout/mathml/nsMathMLmspaceFrame.h
layout/mathml/nsMathMLmsqrtFrame.cpp
layout/mathml/nsMathMLmtableFrame.cpp
layout/mathml/nsMathMLmtableFrame.h
layout/mathml/nsMathMLmunderoverFrame.h
layout/mathml/nsMathMLsemanticsFrame.h
layout/svg/SVGFEContainerFrame.cpp
layout/svg/SVGFEImageFrame.cpp
layout/svg/SVGFELeafFrame.cpp
layout/svg/SVGFEUnstyledLeafFrame.cpp
layout/svg/SVGGeometryFrame.h
layout/svg/SVGTextFrame.h
layout/svg/SVGViewFrame.cpp
layout/svg/nsSVGAFrame.cpp
layout/svg/nsSVGClipPathFrame.h
layout/svg/nsSVGContainerFrame.cpp
layout/svg/nsSVGContainerFrame.h
layout/svg/nsSVGFilterFrame.h
layout/svg/nsSVGForeignObjectFrame.cpp
layout/svg/nsSVGGFrame.h
layout/svg/nsSVGGenericContainerFrame.h
layout/svg/nsSVGGradientFrame.cpp
layout/svg/nsSVGGradientFrame.h
layout/svg/nsSVGImageFrame.h
layout/svg/nsSVGInnerSVGFrame.h
layout/svg/nsSVGMarkerFrame.h
layout/svg/nsSVGMaskFrame.h
layout/svg/nsSVGOuterSVGFrame.cpp
layout/svg/nsSVGOuterSVGFrame.h
layout/svg/nsSVGPaintServerFrame.h
layout/svg/nsSVGPatternFrame.cpp
layout/svg/nsSVGStopFrame.cpp
layout/svg/nsSVGSwitchFrame.cpp
layout/svg/nsSVGUseFrame.cpp
layout/tables/nsTableCellFrame.cpp
layout/tables/nsTableCellFrame.h
layout/tables/nsTableColFrame.cpp
layout/tables/nsTableColGroupFrame.h
layout/tables/nsTableFrame.cpp
layout/tables/nsTableFrame.h
layout/tables/nsTableRowFrame.cpp
layout/tables/nsTableRowFrame.h
layout/tables/nsTableRowGroupFrame.cpp
layout/tables/nsTableWrapperFrame.cpp
layout/tables/nsTableWrapperFrame.h
layout/xul/grid/nsGridRowGroupFrame.h
layout/xul/grid/nsGridRowLeafFrame.h
layout/xul/nsBox.cpp
layout/xul/nsBox.h
layout/xul/nsBoxFrame.cpp
layout/xul/nsBoxFrame.h
layout/xul/nsButtonBoxFrame.cpp
layout/xul/nsButtonBoxFrame.h
layout/xul/nsDeckFrame.cpp
layout/xul/nsDocElementBoxFrame.cpp
layout/xul/nsGroupBoxFrame.cpp
layout/xul/nsImageBoxFrame.cpp
layout/xul/nsLeafBoxFrame.cpp
layout/xul/nsLeafBoxFrame.h
layout/xul/nsListBoxBodyFrame.cpp
layout/xul/nsListItemFrame.cpp
layout/xul/nsMenuBarFrame.cpp
layout/xul/nsMenuFrame.cpp
layout/xul/nsMenuPopupFrame.cpp
layout/xul/nsPopupSetFrame.h
layout/xul/nsProgressMeterFrame.h
layout/xul/nsResizerFrame.cpp
layout/xul/nsRootBoxFrame.cpp
layout/xul/nsScrollBoxFrame.cpp
layout/xul/nsScrollbarButtonFrame.h
layout/xul/nsScrollbarFrame.h
layout/xul/nsSliderFrame.cpp
layout/xul/nsSplitterFrame.cpp
layout/xul/nsStackFrame.cpp
layout/xul/nsTextBoxFrame.cpp
layout/xul/nsTitleBarFrame.cpp
layout/xul/nsTitleBarFrame.h
layout/xul/nsXULLabelFrame.h
layout/xul/tree/nsTreeBodyFrame.cpp
layout/xul/tree/nsTreeColFrame.h
--- a/layout/forms/nsColorControlFrame.cpp
+++ b/layout/forms/nsColorControlFrame.cpp
@@ -18,17 +18,17 @@
 #include "mozilla/dom/HTMLInputElement.h"
 #include "nsIDocument.h"
 
 using mozilla::dom::Element;
 using mozilla::dom::HTMLInputElement;
 using mozilla::dom::CallerType;
 
 nsColorControlFrame::nsColorControlFrame(nsStyleContext* aContext)
-  : nsHTMLButtonControlFrame(aContext, LayoutFrameType::ColorControl)
+  : nsHTMLButtonControlFrame(aContext, kClassID, LayoutFrameType::ColorControl)
 {
 }
 
 nsIFrame*
 NS_NewColorControlFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
 {
   return new (aPresShell) nsColorControlFrame(aContext);
 }
--- a/layout/forms/nsComboboxControlFrame.cpp
+++ b/layout/forms/nsComboboxControlFrame.cpp
@@ -218,17 +218,17 @@ static int32_t gReflowInx = -1;
 #define PX(__v) __v
 #endif
 
 //------------------------------------------------------
 //-- Done with macros
 //------------------------------------------------------
 
 nsComboboxControlFrame::nsComboboxControlFrame(nsStyleContext* aContext)
-  : nsBlockFrame(aContext, LayoutFrameType::ComboboxControl)
+  : nsBlockFrame(aContext, kClassID, LayoutFrameType::ComboboxControl)
   , mDisplayFrame(nullptr)
   , mButtonFrame(nullptr)
   , mDropdownFrame(nullptr)
   , mListControlFrame(nullptr)
   , mDisplayISize(0)
   , mRecentSelectedIndex(NS_SKIP_NOTIFY_INDEX)
   , mDisplayedIndex(-1)
   , mLastDropDownBeforeScreenBCoord(nscoord_MIN)
@@ -1281,17 +1281,17 @@ nsComboboxControlFrame::AppendAnonymousC
 // XXXbz this is a for-now hack.  Now that display:inline-block works,
 // need to revisit this.
 class nsComboboxDisplayFrame : public nsBlockFrame {
 public:
   NS_DECL_FRAMEARENA_HELPERS(nsComboboxDisplayFrame)
 
   nsComboboxDisplayFrame(nsStyleContext* aContext,
                          nsComboboxControlFrame* aComboBox)
-    : nsBlockFrame(aContext, LayoutFrameType::ComboboxDisplay)
+    : nsBlockFrame(aContext, kClassID, LayoutFrameType::ComboboxDisplay)
     , mComboBox(aComboBox)
   {}
 
 #ifdef DEBUG_FRAME_DUMP
   nsresult GetFrameName(nsAString& aResult) const override
   {
     return MakeFrameName(NS_LITERAL_STRING("ComboboxDisplay"), aResult);
   }
--- a/layout/forms/nsDateTimeControlFrame.cpp
+++ b/layout/forms/nsDateTimeControlFrame.cpp
@@ -38,17 +38,17 @@ NS_NewDateTimeControlFrame(nsIPresShell*
 NS_IMPL_FRAMEARENA_HELPERS(nsDateTimeControlFrame)
 
 NS_QUERYFRAME_HEAD(nsDateTimeControlFrame)
   NS_QUERYFRAME_ENTRY(nsDateTimeControlFrame)
   NS_QUERYFRAME_ENTRY(nsIAnonymousContentCreator)
 NS_QUERYFRAME_TAIL_INHERITING(nsContainerFrame)
 
 nsDateTimeControlFrame::nsDateTimeControlFrame(nsStyleContext* aContext)
-  : nsContainerFrame(aContext, LayoutFrameType::DateTimeControl)
+  : nsContainerFrame(aContext, kClassID, LayoutFrameType::DateTimeControl)
 {
 }
 
 void
 nsDateTimeControlFrame::DestroyFrom(nsIFrame* aDestructRoot)
 {
   nsContentUtils::DestroyAnonymousContent(&mInputAreaContent);
   nsContainerFrame::DestroyFrom(aDestructRoot);
--- a/layout/forms/nsFieldSetFrame.cpp
+++ b/layout/forms/nsFieldSetFrame.cpp
@@ -27,17 +27,17 @@ nsContainerFrame*
 NS_NewFieldSetFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
 {
   return new (aPresShell) nsFieldSetFrame(aContext);
 }
 
 NS_IMPL_FRAMEARENA_HELPERS(nsFieldSetFrame)
 
 nsFieldSetFrame::nsFieldSetFrame(nsStyleContext* aContext)
-  : nsContainerFrame(aContext, LayoutFrameType::FieldSet)
+  : nsContainerFrame(aContext, kClassID, LayoutFrameType::FieldSet)
   , mLegendRect(GetWritingMode())
 {
   mLegendSpace  = 0;
 }
 
 nsRect
 nsFieldSetFrame::VisualBorderRectRelativeToSelf() const
 {
--- a/layout/forms/nsFileControlFrame.cpp
+++ b/layout/forms/nsFileControlFrame.cpp
@@ -34,17 +34,17 @@ nsIFrame*
 NS_NewFileControlFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
 {
   return new (aPresShell) nsFileControlFrame(aContext);
 }
 
 NS_IMPL_FRAMEARENA_HELPERS(nsFileControlFrame)
 
 nsFileControlFrame::nsFileControlFrame(nsStyleContext* aContext)
-  : nsBlockFrame(aContext)
+  : nsBlockFrame(aContext, kClassID)
 {
   AddStateBits(NS_BLOCK_FLOAT_MGR);
 }
 
 
 void
 nsFileControlFrame::Init(nsIContent*       aContent,
                          nsContainerFrame* aParent,
--- a/layout/forms/nsFormControlFrame.cpp
+++ b/layout/forms/nsFormControlFrame.cpp
@@ -12,18 +12,19 @@
 #include "mozilla/LookAndFeel.h"
 #include "nsDeviceContext.h"
 #include "nsIContent.h"
 
 using namespace mozilla;
 
 //#define FCF_NOISY
 
-nsFormControlFrame::nsFormControlFrame(nsStyleContext* aContext)
-  : nsAtomicContainerFrame(aContext, LayoutFrameType::FormControl)
+nsFormControlFrame::nsFormControlFrame(nsStyleContext* aContext,
+                                       nsIFrame::ClassID aID)
+  : nsAtomicContainerFrame(aContext, aID, LayoutFrameType::FormControl)
 {
 }
 
 nsFormControlFrame::~nsFormControlFrame()
 {
 }
 
 void
--- a/layout/forms/nsFormControlFrame.h
+++ b/layout/forms/nsFormControlFrame.h
@@ -20,17 +20,17 @@ class nsFormControlFrame : public nsAtom
                            public nsIFormControlFrame
 {
 public:
   /**
     * Main constructor
     * @param aContent the content representing this frame
     * @param aParentFrame the parent frame
     */
-  explicit nsFormControlFrame(nsStyleContext*);
+  explicit nsFormControlFrame(nsStyleContext*, nsIFrame::ClassID);
 
   virtual bool IsFrameOfType(uint32_t aFlags) const override
   {
     return nsAtomicContainerFrame::IsFrameOfType(aFlags &
       ~(nsIFrame::eReplaced | nsIFrame::eReplacedContainsBlock));
   }
 
   NS_DECL_QUERYFRAME
--- a/layout/forms/nsGfxButtonControlFrame.cpp
+++ b/layout/forms/nsGfxButtonControlFrame.cpp
@@ -14,17 +14,17 @@
 #include "nsContentList.h"
 
 #include "nsIDOMHTMLInputElement.h"
 #include "nsTextNode.h"
 
 using namespace mozilla;
 
 nsGfxButtonControlFrame::nsGfxButtonControlFrame(nsStyleContext* aContext)
-  : nsHTMLButtonControlFrame(aContext, LayoutFrameType::GfxButtonControl)
+  : nsHTMLButtonControlFrame(aContext, kClassID, LayoutFrameType::GfxButtonControl)
 {
 }
 
 nsContainerFrame*
 NS_NewGfxButtonControlFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
 {
   return new (aPresShell) nsGfxButtonControlFrame(aContext);
 }
--- a/layout/forms/nsGfxCheckboxControlFrame.cpp
+++ b/layout/forms/nsGfxCheckboxControlFrame.cpp
@@ -87,17 +87,17 @@ NS_NewGfxCheckboxControlFrame(nsIPresShe
 }
 
 NS_IMPL_FRAMEARENA_HELPERS(nsGfxCheckboxControlFrame)
 
 
 //------------------------------------------------------------
 // Initialize GFX-rendered state
 nsGfxCheckboxControlFrame::nsGfxCheckboxControlFrame(nsStyleContext* aContext)
-: nsFormControlFrame(aContext)
+: nsFormControlFrame(aContext, kClassID)
 {
 }
 
 nsGfxCheckboxControlFrame::~nsGfxCheckboxControlFrame()
 {
 }
 
 #ifdef ACCESSIBILITY
--- a/layout/forms/nsGfxRadioControlFrame.cpp
+++ b/layout/forms/nsGfxRadioControlFrame.cpp
@@ -20,17 +20,17 @@ nsIFrame*
 NS_NewGfxRadioControlFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
 {
   return new (aPresShell) nsGfxRadioControlFrame(aContext);
 }
 
 NS_IMPL_FRAMEARENA_HELPERS(nsGfxRadioControlFrame)
 
 nsGfxRadioControlFrame::nsGfxRadioControlFrame(nsStyleContext* aContext):
-  nsFormControlFrame(aContext)
+  nsFormControlFrame(aContext, kClassID)
 {
 }
 
 nsGfxRadioControlFrame::~nsGfxRadioControlFrame()
 {
 }
 
 #ifdef ACCESSIBILITY
--- a/layout/forms/nsHTMLButtonControlFrame.cpp
+++ b/layout/forms/nsHTMLButtonControlFrame.cpp
@@ -22,18 +22,19 @@ nsContainerFrame*
 NS_NewHTMLButtonControlFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
 {
   return new (aPresShell) nsHTMLButtonControlFrame(aContext);
 }
 
 NS_IMPL_FRAMEARENA_HELPERS(nsHTMLButtonControlFrame)
 
 nsHTMLButtonControlFrame::nsHTMLButtonControlFrame(nsStyleContext* aContext,
+                                                   nsIFrame::ClassID aID,
                                                    LayoutFrameType aType)
-  : nsContainerFrame(aContext, aType)
+  : nsContainerFrame(aContext, aID, aType)
 {
 }
 
 nsHTMLButtonControlFrame::~nsHTMLButtonControlFrame()
 {
 }
 
 void
--- a/layout/forms/nsHTMLButtonControlFrame.h
+++ b/layout/forms/nsHTMLButtonControlFrame.h
@@ -14,17 +14,17 @@
 class nsRenderingContext;
 class nsPresContext;
 
 class nsHTMLButtonControlFrame : public nsContainerFrame,
                                  public nsIFormControlFrame
 {
 public:
   explicit nsHTMLButtonControlFrame(nsStyleContext* aContext)
-    : nsHTMLButtonControlFrame(aContext,
+    : nsHTMLButtonControlFrame(aContext, kClassID,
                                mozilla::LayoutFrameType::HTMLButtonControl)
   {}
 
   ~nsHTMLButtonControlFrame();
 
   virtual void DestroyFrom(nsIFrame* aDestructRoot) override;
 
   NS_DECL_QUERYFRAME
@@ -101,17 +101,17 @@ public:
 
   /**
    * Update the style of our ::-moz-button-content anonymous box.
    */
   void DoUpdateStyleOfOwnedAnonBoxes(mozilla::ServoStyleSet& aStyleSet,
                                      nsStyleChangeList& aChangeList,
                                      nsChangeHint aHintForThisFrame) override;
 protected:
-  nsHTMLButtonControlFrame(nsStyleContext* aContext,
+  nsHTMLButtonControlFrame(nsStyleContext* aContext, nsIFrame::ClassID aID,
                            mozilla::LayoutFrameType aType);
 
   virtual bool IsInput() { return false; }
 
   // Indicates whether we should clip our children's painting to our
   // border-box (either because of "overflow" or because of legacy reasons
   // about how <input>-flavored buttons work).
   bool ShouldClipPaintingToBorderBox();
--- a/layout/forms/nsImageControlFrame.cpp
+++ b/layout/forms/nsImageControlFrame.cpp
@@ -53,17 +53,17 @@ public:
                              nsIFrame::Cursor& aCursor) override;
   // nsIFormContromFrame
   virtual void SetFocus(bool aOn, bool aRepaint) override;
   virtual nsresult SetFormProperty(nsIAtom* aName,
                                    const nsAString& aValue) override;
 };
 
 nsImageControlFrame::nsImageControlFrame(nsStyleContext* aContext)
-  : nsImageFrame(aContext, LayoutFrameType::ImageControl)
+  : nsImageFrame(aContext, kClassID, LayoutFrameType::ImageControl)
 {
 }
 
 nsImageControlFrame::~nsImageControlFrame()
 {
 }
 
 void
--- a/layout/forms/nsLegendFrame.h
+++ b/layout/forms/nsLegendFrame.h
@@ -11,17 +11,17 @@
 
 class nsLegendFrame final : public nsBlockFrame
 {
 public:
   NS_DECL_QUERYFRAME
   NS_DECL_FRAMEARENA_HELPERS(nsLegendFrame)
 
   explicit nsLegendFrame(nsStyleContext* aContext)
-    : nsBlockFrame(aContext, mozilla::LayoutFrameType::Legend)
+    : nsBlockFrame(aContext, kClassID, mozilla::LayoutFrameType::Legend)
   {}
 
   virtual void Reflow(nsPresContext* aPresContext,
                       ReflowOutput& aDesiredSize,
                       const ReflowInput& aReflowInput,
                       nsReflowStatus& aStatus) override;
 
   virtual void DestroyFrom(nsIFrame* aDestructRoot) override;
--- a/layout/forms/nsListControlFrame.cpp
+++ b/layout/forms/nsListControlFrame.cpp
@@ -87,17 +87,17 @@ NS_NewListControlFrame(nsIPresShell* aPr
 
   return it;
 }
 
 NS_IMPL_FRAMEARENA_HELPERS(nsListControlFrame)
 
 //---------------------------------------------------------
 nsListControlFrame::nsListControlFrame(nsStyleContext* aContext)
-  : nsHTMLScrollFrame(aContext, LayoutFrameType::ListControl, false)
+  : nsHTMLScrollFrame(aContext, kClassID, LayoutFrameType::ListControl, false)
   , mView(nullptr)
   , mMightNeedSecondPass(false)
   , mHasPendingInterruptAtStartOfReflow(false)
   , mDropdownCanGrow(false)
   , mForceSelection(false)
   , mLastDropdownComputedBSize(NS_UNCONSTRAINEDSIZE)
 {
   mComboboxFrame      = nullptr;
--- a/layout/forms/nsMeterFrame.cpp
+++ b/layout/forms/nsMeterFrame.cpp
@@ -34,17 +34,17 @@ nsIFrame*
 NS_NewMeterFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
 {
   return new (aPresShell) nsMeterFrame(aContext);
 }
 
 NS_IMPL_FRAMEARENA_HELPERS(nsMeterFrame)
 
 nsMeterFrame::nsMeterFrame(nsStyleContext* aContext)
-  : nsContainerFrame(aContext, LayoutFrameType::Meter)
+  : nsContainerFrame(aContext, kClassID, LayoutFrameType::Meter)
   , mBarDiv(nullptr)
 {
 }
 
 nsMeterFrame::~nsMeterFrame()
 {
 }
 
--- a/layout/forms/nsNumberControlFrame.cpp
+++ b/layout/forms/nsNumberControlFrame.cpp
@@ -45,17 +45,17 @@ NS_IMPL_FRAMEARENA_HELPERS(nsNumberContr
 
 NS_QUERYFRAME_HEAD(nsNumberControlFrame)
   NS_QUERYFRAME_ENTRY(nsNumberControlFrame)
   NS_QUERYFRAME_ENTRY(nsIAnonymousContentCreator)
   NS_QUERYFRAME_ENTRY(nsIFormControlFrame)
 NS_QUERYFRAME_TAIL_INHERITING(nsContainerFrame)
 
 nsNumberControlFrame::nsNumberControlFrame(nsStyleContext* aContext)
-  : nsContainerFrame(aContext, LayoutFrameType::NumberControl)
+  : nsContainerFrame(aContext, kClassID, LayoutFrameType::NumberControl)
   , mHandlingInputEvent(false)
 {
 }
 
 void
 nsNumberControlFrame::DestroyFrom(nsIFrame* aDestructRoot)
 {
   NS_ASSERTION(!GetPrevContinuation() && !GetNextContinuation(),
--- a/layout/forms/nsProgressFrame.cpp
+++ b/layout/forms/nsProgressFrame.cpp
@@ -33,17 +33,17 @@ nsIFrame*
 NS_NewProgressFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
 {
   return new (aPresShell) nsProgressFrame(aContext);
 }
 
 NS_IMPL_FRAMEARENA_HELPERS(nsProgressFrame)
 
 nsProgressFrame::nsProgressFrame(nsStyleContext* aContext)
-  : nsContainerFrame(aContext, LayoutFrameType::Progress)
+  : nsContainerFrame(aContext, kClassID, LayoutFrameType::Progress)
   , mBarDiv(nullptr)
 {
 }
 
 nsProgressFrame::~nsProgressFrame()
 {
 }
 
--- a/layout/forms/nsRangeFrame.cpp
+++ b/layout/forms/nsRangeFrame.cpp
@@ -42,17 +42,17 @@ NS_IMPL_ISUPPORTS(nsRangeFrame::DummyTou
 
 nsIFrame*
 NS_NewRangeFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
 {
   return new (aPresShell) nsRangeFrame(aContext);
 }
 
 nsRangeFrame::nsRangeFrame(nsStyleContext* aContext)
-  : nsContainerFrame(aContext, LayoutFrameType::Range)
+  : nsContainerFrame(aContext, kClassID, LayoutFrameType::Range)
 {
 }
 
 nsRangeFrame::~nsRangeFrame()
 {
 #ifdef DEBUG
   if (mOuterFocusStyle) {
     mOuterFocusStyle->FrameRelease();
--- a/layout/forms/nsSelectsAreaFrame.h
+++ b/layout/forms/nsSelectsAreaFrame.h
@@ -29,17 +29,17 @@ public:
                       ReflowOutput&     aDesiredSize,
                       const ReflowInput& aReflowInput,
                       nsReflowStatus&          aStatus) override;
 
   nscoord BSizeOfARow() const { return mBSizeOfARow; }
   
 protected:
   explicit nsSelectsAreaFrame(nsStyleContext* aContext) :
-    nsBlockFrame(aContext),
+    nsBlockFrame(aContext, kClassID),
     mBSizeOfARow(0)
   {}
 
   // We cache the block size of a single row so that changes to the
   // "size" attribute, padding, etc. can all be handled with only one
   // reflow.  We'll have to reflow twice if someone changes our font
   // size or something like that, so that the block size of our options
   // will change.
--- a/layout/forms/nsTextControlFrame.cpp
+++ b/layout/forms/nsTextControlFrame.cpp
@@ -98,17 +98,17 @@ public:
   bool EnteredMoreThanOnce() const { return !mFirstEntry; }
 private:
   nsTextControlFrame &mFrame;
   bool mFirstEntry;
 };
 #endif
 
 nsTextControlFrame::nsTextControlFrame(nsStyleContext* aContext)
-  : nsContainerFrame(aContext, LayoutFrameType::TextInput)
+  : nsContainerFrame(aContext, kClassID, LayoutFrameType::TextInput)
   , mFirstBaseline(NS_INTRINSIC_WIDTH_UNKNOWN)
   , mEditorHasBeenInitialized(false)
   , mIsProcessing(false)
   , mUsePlaceholder(false)
   , mUsePreview(false)
 #ifdef DEBUG
   , mInEditorInitialization(false)
 #endif
--- a/layout/generic/BRFrame.cpp
+++ b/layout/generic/BRFrame.cpp
@@ -59,17 +59,17 @@ public:
   }
 
 #ifdef ACCESSIBILITY
   virtual mozilla::a11y::AccType AccessibleType() override;
 #endif
 
 protected:
   explicit BRFrame(nsStyleContext* aContext)
-    : nsFrame(aContext, LayoutFrameType::Br)
+    : nsFrame(aContext, kClassID, LayoutFrameType::Br)
     , mAscent(NS_INTRINSIC_WIDTH_UNKNOWN)
   {}
 
   virtual ~BRFrame();
 
   nscoord mAscent;
 };
 
--- a/layout/generic/DetailsFrame.cpp
+++ b/layout/generic/DetailsFrame.cpp
@@ -26,17 +26,17 @@ nsBlockFrame*
 NS_NewDetailsFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
 {
   return new (aPresShell) DetailsFrame(aContext);
 }
 
 namespace mozilla {
 
 DetailsFrame::DetailsFrame(nsStyleContext* aContext)
-  : nsBlockFrame(aContext, LayoutFrameType::Details)
+  : nsBlockFrame(aContext, kClassID, LayoutFrameType::Details)
 {
 }
 
 DetailsFrame::~DetailsFrame()
 {
 }
 
 void
--- a/layout/generic/ViewportFrame.h
+++ b/layout/generic/ViewportFrame.h
@@ -24,17 +24,17 @@ namespace mozilla {
   * list.
   */
 class ViewportFrame : public nsContainerFrame {
 public:
   NS_DECL_QUERYFRAME
   NS_DECL_FRAMEARENA_HELPERS(ViewportFrame)
 
   explicit ViewportFrame(nsStyleContext* aContext)
-    : ViewportFrame(aContext, mozilla::LayoutFrameType::Viewport)
+    : ViewportFrame(aContext, kClassID, mozilla::LayoutFrameType::Viewport)
   {}
 
   virtual ~ViewportFrame() { } // useful for debugging
 
   virtual void Init(nsIContent*       aContent,
                     nsContainerFrame* aParent,
                     nsIFrame*         aPrevInFlow) override;
 
@@ -72,18 +72,18 @@ public:
    */
   nsRect AdjustReflowInputAsContainingBlock(ReflowInput* aReflowInput) const;
 
 #ifdef DEBUG_FRAME_DUMP
   virtual nsresult GetFrameName(nsAString& aResult) const override;
 #endif
 
 protected:
-  ViewportFrame(nsStyleContext* aContext, mozilla::LayoutFrameType aType)
-    : nsContainerFrame(aContext, aType)
+  ViewportFrame(nsStyleContext* aContext, ClassID aID, mozilla::LayoutFrameType aType)
+    : nsContainerFrame(aContext, aID, aType)
     , mView(nullptr)
   {}
 
   /**
    * Calculate how much room is available for fixed frames. That means
    * determining if the viewport is scrollable and whether the vertical and/or
    * horizontal scrollbars are visible.  Adjust the computed width/height and
    * available width for aReflowInput accordingly.
--- a/layout/generic/nsAtomicContainerFrame.h
+++ b/layout/generic/nsAtomicContainerFrame.h
@@ -35,15 +35,15 @@ public:
     return nsFrame::PeekOffsetCharacter(aForward, aOffset, aRespectClusters);
   }
   nsSplittableType GetSplittableType() const override
   {
     return nsFrame::GetSplittableType();
   }
 
 protected:
-  nsAtomicContainerFrame(nsStyleContext* aContext,
+  nsAtomicContainerFrame(nsStyleContext* aContext, ClassID aID,
                          mozilla::LayoutFrameType aType)
-    : nsContainerFrame(aContext, aType)
+    : nsContainerFrame(aContext, aID, aType)
   {}
 };
 
 #endif // nsAtomicContainerFrame_h___
--- a/layout/generic/nsBackdropFrame.h
+++ b/layout/generic/nsBackdropFrame.h
@@ -12,17 +12,17 @@
 #include "nsFrame.h"
 
 class nsBackdropFrame final : public nsFrame
 {
 public:
   NS_DECL_FRAMEARENA_HELPERS(nsBackdropFrame)
 
   explicit nsBackdropFrame(nsStyleContext* aContext)
-    : nsFrame(aContext, mozilla::LayoutFrameType::Backdrop)
+    : nsFrame(aContext, kClassID, mozilla::LayoutFrameType::Backdrop)
   {}
 
 #ifdef DEBUG_FRAME_DUMP
   virtual nsresult GetFrameName(nsAString& aResult) const override;
 #endif
   virtual nsStyleContext*
     GetParentStyleContext(nsIFrame** aProviderFrame) const override;
   virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder,
--- a/layout/generic/nsBlockFrame.h
+++ b/layout/generic/nsBlockFrame.h
@@ -391,28 +391,28 @@ public:
   static nsBlockFrame* GetNearestAncestorBlock(nsIFrame* aCandidate);
 
   struct FrameLines {
     nsLineList mLines;
     nsFrameList mFrames;
   };
 
 protected:
-  nsBlockFrame(nsStyleContext* aContext, mozilla::LayoutFrameType aType)
-    : nsContainerFrame(aContext, aType)
+  nsBlockFrame(nsStyleContext* aContext, ClassID aID, mozilla::LayoutFrameType aType)
+    : nsContainerFrame(aContext, aID, aType)
     , mMinWidth(NS_INTRINSIC_WIDTH_UNKNOWN)
     , mPrefWidth(NS_INTRINSIC_WIDTH_UNKNOWN)
   {
 #ifdef DEBUG
   InitDebugFlags();
 #endif
   }
 
-  explicit nsBlockFrame(nsStyleContext* aContext)
-    : nsBlockFrame(aContext, mozilla::LayoutFrameType::Block)
+  explicit nsBlockFrame(nsStyleContext* aContext, ClassID aID = kClassID)
+    : nsBlockFrame(aContext, aID, mozilla::LayoutFrameType::Block)
   {}
 
   virtual ~nsBlockFrame();
 
 #ifdef DEBUG
   already_AddRefed<nsStyleContext> GetFirstLetterStyle(nsPresContext* aPresContext);
 #endif
 
--- a/layout/generic/nsBulletFrame.h
+++ b/layout/generic/nsBulletFrame.h
@@ -48,17 +48,17 @@ class nsBulletFrame final : public nsFra
 
 public:
   NS_DECL_FRAMEARENA_HELPERS(nsBulletFrame)
 #ifdef DEBUG
   NS_DECL_QUERYFRAME
 #endif
 
   explicit nsBulletFrame(nsStyleContext* aContext)
-    : nsFrame(aContext, mozilla::LayoutFrameType::Bullet)
+    : nsFrame(aContext, kClassID, mozilla::LayoutFrameType::Bullet)
     , mPadding(GetWritingMode())
     , mIntrinsicSize(GetWritingMode())
     , mOrdinal(0)
     , mRequestRegistered(false)
     , mBlockingOnload(false)
   {}
 
   virtual ~nsBulletFrame();
--- a/layout/generic/nsCanvasFrame.h
+++ b/layout/generic/nsCanvasFrame.h
@@ -29,17 +29,17 @@ class nsRenderingContext;
  * frame in the main child list.
  */
 class nsCanvasFrame final : public nsContainerFrame,
                             public nsIScrollPositionListener,
                             public nsIAnonymousContentCreator
 {
 public:
   explicit nsCanvasFrame(nsStyleContext* aContext)
-    : nsContainerFrame(aContext, mozilla::LayoutFrameType::Canvas)
+    : nsContainerFrame(aContext, kClassID, mozilla::LayoutFrameType::Canvas)
     , mDoPaintFocus(false)
     , mAddedScrollPositionListener(false)
   {}
 
   NS_DECL_QUERYFRAME
   NS_DECL_FRAMEARENA_HELPERS(nsCanvasFrame)
 
 
--- a/layout/generic/nsColumnSetFrame.cpp
+++ b/layout/generic/nsColumnSetFrame.cpp
@@ -124,17 +124,17 @@ NS_NewColumnSetFrame(nsIPresShell* aPres
   nsColumnSetFrame* it = new (aPresShell) nsColumnSetFrame(aContext);
   it->AddStateBits(aStateFlags | NS_BLOCK_MARGIN_ROOT);
   return it;
 }
 
 NS_IMPL_FRAMEARENA_HELPERS(nsColumnSetFrame)
 
 nsColumnSetFrame::nsColumnSetFrame(nsStyleContext* aContext)
-  : nsContainerFrame(aContext, LayoutFrameType::ColumnSet)
+  : nsContainerFrame(aContext, kClassID, LayoutFrameType::ColumnSet)
   , mLastBalanceBSize(NS_INTRINSICSIZE)
 {
 }
 
 void
 nsColumnSetFrame::ForEachColumn(const std::function<void(const nsRect& lineRect)>& aSetLineRect,
                                 const nsPoint& aPt)
 {
--- a/layout/generic/nsContainerFrame.h
+++ b/layout/generic/nsContainerFrame.h
@@ -529,18 +529,18 @@ public:
   // Use this to suppress the CRAZY_SIZE assertions.
   NS_DECLARE_FRAME_PROPERTY_SMALL_VALUE(DebugReflowingWithInfiniteISize, bool)
   bool IsCrazySizeAssertSuppressed() const {
     return Properties().Get(DebugReflowingWithInfiniteISize());
   }
 #endif
 
 protected:
-  nsContainerFrame(nsStyleContext* aContext, mozilla::LayoutFrameType aType)
-    : nsSplittableFrame(aContext, aType)
+  nsContainerFrame(nsStyleContext* aContext, ClassID aID, mozilla::LayoutFrameType aType)
+    : nsSplittableFrame(aContext, aID, aType)
   {}
 
   ~nsContainerFrame();
 
   /**
    * Helper for DestroyFrom. DestroyAbsoluteFrames is called before
    * destroying frames on lists that can contain placeholders.
    * Derived classes must do that too, if they destroy such frame lists.
--- a/layout/generic/nsFirstLetterFrame.h
+++ b/layout/generic/nsFirstLetterFrame.h
@@ -12,17 +12,17 @@
 #include "nsContainerFrame.h"
 
 class nsFirstLetterFrame final : public nsContainerFrame {
 public:
   NS_DECL_QUERYFRAME
   NS_DECL_FRAMEARENA_HELPERS(nsFirstLetterFrame)
 
   explicit nsFirstLetterFrame(nsStyleContext* aContext)
-    : nsContainerFrame(aContext, mozilla::LayoutFrameType::Letter)
+    : nsContainerFrame(aContext, kClassID, mozilla::LayoutFrameType::Letter)
   {}
 
   virtual void BuildDisplayList(nsDisplayListBuilder*   aBuilder,
                                 const nsRect&           aDirtyRect,
                                 const nsDisplayListSet& aLists) override;
 
   virtual void Init(nsIContent*       aContent,
                     nsContainerFrame* aParent,
--- a/layout/generic/nsFlexContainerFrame.h
+++ b/layout/generic/nsFlexContainerFrame.h
@@ -127,17 +127,17 @@ public:
                                     uint8_t aAlignVal,
                                     nscoord* aFirstSubjectOffset,
                                     uint32_t* aNumPackingSpacesRemaining,
                                     nscoord* aPackingSpaceRemaining);
 
 protected:
   // Protected constructor & destructor
   explicit nsFlexContainerFrame(nsStyleContext* aContext)
-    : nsContainerFrame(aContext, mozilla::LayoutFrameType::FlexContainer)
+    : nsContainerFrame(aContext, kClassID, mozilla::LayoutFrameType::FlexContainer)
     , mBaselineFromLastReflow(NS_INTRINSIC_WIDTH_UNKNOWN)
     , mLastBaselineFromLastReflow(NS_INTRINSIC_WIDTH_UNKNOWN)
   {}
 
   virtual ~nsFlexContainerFrame();
 
   /*
    * This method does the bulk of the flex layout, implementing the algorithm
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -443,21 +443,21 @@ WeakFrame::Init(nsIFrame* aFrame)
       mFrame = nullptr;
     }
   }
 }
 
 nsIFrame*
 NS_NewEmptyFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
 {
-  return new (aPresShell) nsFrame(aContext, LayoutFrameType::None);
-}
-
-nsFrame::nsFrame(nsStyleContext* aContext, LayoutFrameType aType)
-  : nsBox(aType)
+  return new (aPresShell) nsFrame(aContext);
+}
+
+nsFrame::nsFrame(nsStyleContext* aContext, ClassID aID, LayoutFrameType aType)
+  : nsBox(aID, aType)
 {
   MOZ_COUNT_CTOR(nsFrame);
 
   mStyleContext = aContext;
   mWritingMode = WritingMode(mStyleContext);
   mStyleContext->AddRef();
 #ifdef DEBUG
   mStyleContext->FrameAddRef();
@@ -565,16 +565,17 @@ IsFontSizeInflationContainer(nsIFrame* a
   return !isInline;
 }
 
 void
 nsFrame::Init(nsIContent*       aContent,
               nsContainerFrame* aParent,
               nsIFrame*         aPrevInFlow)
 {
+  MOZ_ASSERT(nsQueryFrame::FrameIID(mClass) == GetFrameId());
   NS_PRECONDITION(!mContent, "Double-initing a frame?");
   NS_ASSERTION(IsFrameOfType(eDEBUGAllFrames) &&
                !IsFrameOfType(eDEBUGNoFrames),
                "IsFrameOfType implementation that doesn't call base class");
 
   mContent = aContent;
   mParent = aParent;
 
--- a/layout/generic/nsFrame.h
+++ b/layout/generic/nsFrame.h
@@ -87,16 +87,17 @@
 // class abstract and stop it from being instantiated. If a frame class
 // without its own operator new and GetFrameId gets instantiated, the
 // per-frame recycler lists in nsPresArena will not work correctly,
 // with potentially catastrophic consequences (not enough memory is
 // allocated for a frame object).
 
 #define NS_DECL_FRAMEARENA_HELPERS(class)                           \
   NS_DECL_QUERYFRAME_TARGET(class)                                  \
+  static constexpr nsIFrame::ClassID kClassID = nsIFrame::ClassID::class##_id;  \
   void* operator new(size_t, nsIPresShell*) MOZ_MUST_OVERRIDE;      \
   nsQueryFrame::FrameIID GetFrameId() override MOZ_MUST_OVERRIDE {  \
     return nsQueryFrame::class##_id;                                \
   }
 
 #define NS_IMPL_FRAMEARENA_HELPERS(class)                         \
   void* class::operator new(size_t sz, nsIPresShell* aShell)      \
   { return aShell->AllocateFrame(nsQueryFrame::class##_id, sz); } \
@@ -578,17 +579,19 @@ public:
    *                           Must not be null.
    * @param aChildPseudo the child's pseudo type, if any.
    */
   static nsIFrame*
   CorrectStyleParentFrame(nsIFrame* aProspectiveParent, nsIAtom* aChildPseudo);
 
 protected:
   // Protected constructor and destructor
-  explicit nsFrame(nsStyleContext* aContext, mozilla::LayoutFrameType aType);
+  nsFrame(nsStyleContext* aContext, ClassID aID, mozilla::LayoutFrameType aType);
+  explicit nsFrame(nsStyleContext* aContext)
+    : nsFrame(aContext, ClassID::nsFrame_id, mozilla::LayoutFrameType::None) {}
   virtual ~nsFrame();
 
   /**
    * To be called by |BuildDisplayLists| of this class or derived classes to add
    * a translucent overlay if this frame's content is selected.
    * @param aContentType an nsISelectionDisplay DISPLAY_ constant identifying
    * which kind of content this is for
    */
--- a/layout/generic/nsFrameSetFrame.cpp
+++ b/layout/generic/nsFrameSetFrame.cpp
@@ -153,17 +153,17 @@ public:
 
   virtual void Reflow(nsPresContext*           aPresContext,
                           ReflowOutput&     aDesiredSize,
                           const ReflowInput& aReflowInput,
                           nsReflowStatus&          aStatus) override;
 
 protected:
   explicit nsHTMLFramesetBlankFrame(nsStyleContext* aContext)
-    : nsLeafFrame(aContext, LayoutFrameType::None)
+    : nsLeafFrame(aContext, kClassID, LayoutFrameType::None)
   {}
 
   virtual ~nsHTMLFramesetBlankFrame();
   virtual nscoord GetIntrinsicISize() override;
   virtual nscoord GetIntrinsicBSize() override;
 
   friend class nsHTMLFramesetFrame;
   friend class nsHTMLFrameset;
@@ -171,17 +171,17 @@ protected:
 
 /*******************************************************************************
  * nsHTMLFramesetFrame
  ******************************************************************************/
 bool    nsHTMLFramesetFrame::gDragInProgress = false;
 #define DEFAULT_BORDER_WIDTH_PX 6
 
 nsHTMLFramesetFrame::nsHTMLFramesetFrame(nsStyleContext* aContext)
-  : nsContainerFrame(aContext, LayoutFrameType::FrameSet)
+  : nsContainerFrame(aContext, kClassID, LayoutFrameType::FrameSet)
 {
   mNumRows             = 0;
   mNumCols             = 0;
   mEdgeVisibility      = 0;
   mParentFrameborder   = eFrameborder_Yes; // default
   mParentBorderWidth   = -1; // default not set
   mParentBorderColor   = NO_COLOR; // default not set
   mFirstDragPoint.x     = mFirstDragPoint.y = 0;
@@ -1331,17 +1331,17 @@ NS_IMPL_FRAMEARENA_HELPERS(nsHTMLFramese
 
 /*******************************************************************************
  * nsHTMLFramesetBorderFrame
  ******************************************************************************/
 nsHTMLFramesetBorderFrame::nsHTMLFramesetBorderFrame(nsStyleContext* aContext,
                                                      int32_t aWidth,
                                                      bool aVertical,
                                                      bool aVisibility)
-  : nsLeafFrame(aContext, LayoutFrameType::None)
+  : nsLeafFrame(aContext, kClassID, LayoutFrameType::None)
   , mWidth(aWidth)
   , mVertical(aVertical)
   , mVisibility(aVisibility)
 {
    mCanResize    = true;
    mColor        = NO_COLOR;
    mPrevNeighbor = 0;
    mNextNeighbor = 0;
--- a/layout/generic/nsGfxScrollFrame.cpp
+++ b/layout/generic/nsGfxScrollFrame.cpp
@@ -105,19 +105,20 @@ nsHTMLScrollFrame*
 NS_NewHTMLScrollFrame(nsIPresShell* aPresShell, nsStyleContext* aContext, bool aIsRoot)
 {
   return new (aPresShell) nsHTMLScrollFrame(aContext, aIsRoot);
 }
 
 NS_IMPL_FRAMEARENA_HELPERS(nsHTMLScrollFrame)
 
 nsHTMLScrollFrame::nsHTMLScrollFrame(nsStyleContext* aContext,
+                                     nsIFrame::ClassID aID,
                                      LayoutFrameType aType,
                                      bool aIsRoot)
-  : nsContainerFrame(aContext, aType)
+  : nsContainerFrame(aContext, aID, aType)
   , mHelper(ALLOW_THIS_IN_INITIALIZER_LIST(this), aIsRoot)
 {
 }
 
 void
 nsHTMLScrollFrame::ScrollbarActivityStarted() const
 {
   if (mHelper.mScrollbarActivity) {
@@ -1156,17 +1157,17 @@ NS_NewXULScrollFrame(nsIPresShell* aPres
                                            aClipAllDescendants);
 }
 
 NS_IMPL_FRAMEARENA_HELPERS(nsXULScrollFrame)
 
 nsXULScrollFrame::nsXULScrollFrame(nsStyleContext* aContext,
                                    bool aIsRoot,
                                    bool aClipAllDescendants)
-  : nsBoxFrame(aContext, LayoutFrameType::Scroll, aIsRoot)
+  : nsBoxFrame(aContext, kClassID, LayoutFrameType::Scroll, aIsRoot)
   , mHelper(ALLOW_THIS_IN_INITIALIZER_LIST(this), aIsRoot)
 {
   SetXULLayoutManager(nullptr);
   mHelper.mClipAllDescendants = aClipAllDescendants;
 }
 
 void
 nsXULScrollFrame::ScrollbarActivityStarted() const
--- a/layout/generic/nsGfxScrollFrame.h
+++ b/layout/generic/nsGfxScrollFrame.h
@@ -1055,20 +1055,21 @@ public:
 #endif
 
 #ifdef ACCESSIBILITY
   virtual mozilla::a11y::AccType AccessibleType() override;
 #endif
 
 protected:
   nsHTMLScrollFrame(nsStyleContext* aContext, bool aIsRoot)
-    : nsHTMLScrollFrame(aContext, mozilla::LayoutFrameType::Scroll, aIsRoot)
+    : nsHTMLScrollFrame(aContext, kClassID, mozilla::LayoutFrameType::Scroll, aIsRoot)
   {}
 
   nsHTMLScrollFrame(nsStyleContext* aContext,
+                    nsIFrame::ClassID aID,
                     mozilla::LayoutFrameType aType,
                     bool aIsRoot);
   void SetSuppressScrollbarUpdate(bool aSuppress) {
     mHelper.mSupppressScrollbarUpdate = aSuppress;
   }
   bool GuessHScrollbarNeeded(const ScrollReflowInput& aState);
   bool GuessVScrollbarNeeded(const ScrollReflowInput& aState);
 
--- a/layout/generic/nsGridContainerFrame.h
+++ b/layout/generic/nsGridContainerFrame.h
@@ -252,17 +252,17 @@ protected:
   struct LineRange;
   struct SharedGridData;
   struct TrackSizingFunctions;
   struct Tracks;
   struct TranslatedLineRange;
   friend nsContainerFrame* NS_NewGridContainerFrame(nsIPresShell* aPresShell,
                                                     nsStyleContext* aContext);
   explicit nsGridContainerFrame(nsStyleContext* aContext)
-    : nsContainerFrame(aContext, mozilla::LayoutFrameType::GridContainer)
+    : nsContainerFrame(aContext, kClassID, mozilla::LayoutFrameType::GridContainer)
     , mCachedMinISize(NS_INTRINSIC_WIDTH_UNKNOWN)
     , mCachedPrefISize(NS_INTRINSIC_WIDTH_UNKNOWN)
   {
     mBaseline[0][0] = NS_INTRINSIC_WIDTH_UNKNOWN;
     mBaseline[0][1] = NS_INTRINSIC_WIDTH_UNKNOWN;
     mBaseline[1][0] = NS_INTRINSIC_WIDTH_UNKNOWN;
     mBaseline[1][1] = NS_INTRINSIC_WIDTH_UNKNOWN;
   }
--- a/layout/generic/nsHTMLCanvasFrame.h
+++ b/layout/generic/nsHTMLCanvasFrame.h
@@ -31,17 +31,17 @@ public:
   typedef mozilla::layers::Layer Layer;
   typedef mozilla::layers::LayerManager LayerManager;
   typedef mozilla::ContainerLayerParameters ContainerLayerParameters;
 
   NS_DECL_QUERYFRAME
   NS_DECL_FRAMEARENA_HELPERS(nsHTMLCanvasFrame)
 
   explicit nsHTMLCanvasFrame(nsStyleContext* aContext)
-    : nsContainerFrame(aContext, mozilla::LayoutFrameType::HTMLCanvas)
+    : nsContainerFrame(aContext, kClassID, mozilla::LayoutFrameType::HTMLCanvas)
     , mBorderPadding(GetWritingMode())
   {}
 
   virtual void Init(nsIContent*       aContent,
                     nsContainerFrame* aParent,
                     nsIFrame*         aPrevInFlow) override;
 
   virtual void BuildDisplayList(nsDisplayListBuilder*   aBuilder,
--- a/layout/generic/nsIFrame.h
+++ b/layout/generic/nsIFrame.h
@@ -598,28 +598,30 @@ public:
   typedef mozilla::layout::FrameChildListIterator ChildListIterator;
   typedef mozilla::layout::FrameChildListArrayIterator ChildListArrayIterator;
   typedef mozilla::gfx::DrawTarget DrawTarget;
   typedef mozilla::gfx::Matrix Matrix;
   typedef mozilla::gfx::Matrix4x4 Matrix4x4;
   typedef mozilla::Sides Sides;
   typedef mozilla::LogicalSides LogicalSides;
   typedef mozilla::SmallPointerArray<mozilla::DisplayItemData> DisplayItemArray;
+  typedef nsQueryFrame::ClassID ClassID;
 
   NS_DECL_QUERYFRAME_TARGET(nsIFrame)
 
-  explicit nsIFrame(mozilla::LayoutFrameType aType)
+  explicit nsIFrame(ClassID aID, mozilla::LayoutFrameType aType)
     : mRect()
     , mContent(nullptr)
     , mStyleContext(nullptr)
     , mParent(nullptr)
     , mNextSibling(nullptr)
     , mPrevSibling(nullptr)
     , mState(NS_FRAME_FIRST_REFLOW | NS_FRAME_IS_DIRTY)
     , mType(aType)
+    , mClass(aID)
   {
     mozilla::PodZero(&mOverflow);
   }
 
   nsPresContext* PresContext() const {
     return StyleContext()->PresContext();
   }
 
@@ -3897,16 +3899,19 @@ protected:
   } mOverflow;
 
   /** @see GetWritingMode() */
   mozilla::WritingMode mWritingMode;
 
   /** The type of the frame. */
   mozilla::LayoutFrameType mType;
 
+  /** The ClassID of the concrete class of this instance. */
+  ClassID mClass; // 1 byte
+
   // Helpers
   /**
    * Can we stop inside this frame when we're skipping non-rendered whitespace?
    * @param  aForward [in] Are we moving forward (or backward) in content order.
    * @param  aOffset [in/out] At what offset into the frame to start looking.
    *         on output - what offset was reached (whether or not we found a place to stop).
    * @return STOP: An appropriate offset was found within this frame,
    *         and is given by aOffset.
--- a/layout/generic/nsImageFrame.cpp
+++ b/layout/generic/nsImageFrame.cpp
@@ -130,18 +130,18 @@ inline bool HaveFixedSize(const ReflowIn
 nsIFrame*
 NS_NewImageFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
 {
   return new (aPresShell) nsImageFrame(aContext);
 }
 
 NS_IMPL_FRAMEARENA_HELPERS(nsImageFrame)
 
-nsImageFrame::nsImageFrame(nsStyleContext* aContext, LayoutFrameType aType)
-  : nsAtomicContainerFrame(aContext, aType)
+nsImageFrame::nsImageFrame(nsStyleContext* aContext, ClassID aID, LayoutFrameType aType)
+  : nsAtomicContainerFrame(aContext, aID, aType)
   , mComputedSize(0, 0)
   , mIntrinsicRatio(0, 0)
   , mDisplayingIcon(false)
   , mFirstFrameComplete(false)
   , mReflowCallbackPosted(false)
   , mForceSyncDecoding(false)
 {
   EnableVisibilityTracking();
--- a/layout/generic/nsImageFrame.h
+++ b/layout/generic/nsImageFrame.h
@@ -67,18 +67,18 @@ public:
   typedef mozilla::image::DrawResult DrawResult;
   typedef mozilla::layers::ImageContainer ImageContainer;
   typedef mozilla::layers::ImageLayer ImageLayer;
   typedef mozilla::layers::LayerManager LayerManager;
 
   NS_DECL_FRAMEARENA_HELPERS(nsImageFrame)
   NS_DECL_QUERYFRAME
 
-  explicit nsImageFrame(nsStyleContext* aContext)
-    : nsImageFrame(aContext, mozilla::LayoutFrameType::Image)
+  explicit nsImageFrame(nsStyleContext* aContext, ClassID aID = kClassID)
+    : nsImageFrame(aContext, aID, mozilla::LayoutFrameType::Image)
   {}
 
 
   virtual void DestroyFrom(nsIFrame* aDestructRoot) override;
   virtual void DidSetStyleContext(nsStyleContext* aOldStyleContext) override;
 
   virtual void Init(nsIContent*       aContent,
                     nsContainerFrame* aParent,
@@ -177,17 +177,17 @@ public:
 
   void DisconnectMap();
 
   // nsIReflowCallback
   virtual bool ReflowFinished() override;
   virtual void ReflowCallbackCanceled() override;
 
 protected:
-  nsImageFrame(nsStyleContext* aContext, mozilla::LayoutFrameType aType);
+  nsImageFrame(nsStyleContext* aContext, ClassID, mozilla::LayoutFrameType aType);
 
   virtual ~nsImageFrame();
 
   void EnsureIntrinsicSizeAndRatio();
 
   virtual mozilla::LogicalSize
   ComputeSize(nsRenderingContext *aRenderingContext,
               mozilla::WritingMode aWritingMode,
--- a/layout/generic/nsInlineFrame.h
+++ b/layout/generic/nsInlineFrame.h
@@ -135,23 +135,23 @@ protected:
       mPrevFrame = nullptr;
       mNextInFlow = nullptr;
       mLineContainer = nullptr;
       mLineLayout = nullptr;
       mSetParentPointer = false;
     }
   };
 
-  nsInlineFrame(nsStyleContext* aContext, mozilla::LayoutFrameType aType)
-    : nsContainerFrame(aContext, aType)
+  nsInlineFrame(nsStyleContext* aContext, ClassID aID, mozilla::LayoutFrameType aType)
+    : nsContainerFrame(aContext, aID, aType)
     , mBaseline(NS_INTRINSIC_WIDTH_UNKNOWN)
   {}
 
-  explicit nsInlineFrame(nsStyleContext* aContext)
-    : nsInlineFrame(aContext, mozilla::LayoutFrameType::Inline)
+  explicit nsInlineFrame(nsStyleContext* aContext, ClassID aID = kClassID)
+    : nsInlineFrame(aContext, aID, mozilla::LayoutFrameType::Inline)
   {}
 
   virtual LogicalSides GetLogicalSkipSides(const ReflowInput* aReflowInput = nullptr) const override;
 
   void ReflowFrames(nsPresContext* aPresContext,
                     const ReflowInput& aReflowInput,
                     InlineReflowInput& rs,
                     ReflowOutput& aMetrics,
@@ -227,17 +227,17 @@ public:
   virtual void Init(nsIContent*       aContent,
                     nsContainerFrame* aParent,
                     nsIFrame*         aPrevInFlow) override;
   virtual void PullOverflowsFromPrevInFlow() override;
   virtual bool DrainSelfOverflowList() override;
 
 protected:
   explicit nsFirstLineFrame(nsStyleContext* aContext)
-    : nsInlineFrame(aContext, mozilla::LayoutFrameType::Line)
+    : nsInlineFrame(aContext, kClassID, mozilla::LayoutFrameType::Line)
   {}
 
   virtual nsIFrame* PullOneFrame(nsPresContext* aPresContext,
                                  InlineReflowInput& rs,
                                  bool* aIsComplete) override;
 };
 
 #endif /* nsInlineFrame_h___ */
--- a/layout/generic/nsLeafFrame.h
+++ b/layout/generic/nsLeafFrame.h
@@ -72,18 +72,18 @@ public:
   virtual bool IsFrameOfType(uint32_t aFlags) const override
   {
     // We don't actually contain a block, but we do always want a
     // computed width, so tell a little white lie here.
     return nsFrame::IsFrameOfType(aFlags & ~(nsIFrame::eReplacedContainsBlock));
   }
 
 protected:
-  nsLeafFrame(nsStyleContext* aContext, mozilla::LayoutFrameType aType)
-    : nsFrame(aContext, aType)
+  nsLeafFrame(nsStyleContext* aContext, ClassID aID, mozilla::LayoutFrameType aType)
+    : nsFrame(aContext, aID, aType)
   {}
 
   virtual ~nsLeafFrame();
 
   /**
    * Return the intrinsic isize of the frame's content area. Note that this
    * should not include borders or padding and should not depend on the applied
    * styles.
--- a/layout/generic/nsPageContentFrame.h
+++ b/layout/generic/nsPageContentFrame.h
@@ -39,16 +39,16 @@ public:
 
 #ifdef DEBUG_FRAME_DUMP
   // Debugging
   virtual nsresult  GetFrameName(nsAString& aResult) const override;
 #endif
 
 protected:
   explicit nsPageContentFrame(nsStyleContext* aContext)
-    : ViewportFrame(aContext, mozilla::LayoutFrameType::PageContent)
+    : ViewportFrame(aContext, kClassID, mozilla::LayoutFrameType::PageContent)
   {}
 
   nsSharedPageData*         mPD;
 };
 
 #endif /* nsPageContentFrame_h___ */
 
--- a/layout/generic/nsPageFrame.cpp
+++ b/layout/generic/nsPageFrame.cpp
@@ -36,17 +36,17 @@ NS_NewPageFrame(nsIPresShell* aPresShell
 
 NS_IMPL_FRAMEARENA_HELPERS(nsPageFrame)
 
 NS_QUERYFRAME_HEAD(nsPageFrame)
   NS_QUERYFRAME_ENTRY(nsPageFrame)
 NS_QUERYFRAME_TAIL_INHERITING(nsContainerFrame)
 
 nsPageFrame::nsPageFrame(nsStyleContext* aContext)
-  : nsContainerFrame(aContext, LayoutFrameType::Page)
+  : nsContainerFrame(aContext, kClassID, LayoutFrameType::Page)
 {
 }
 
 nsPageFrame::~nsPageFrame()
 {
 }
 
 void
@@ -677,17 +677,17 @@ NS_NewPageBreakFrame(nsIPresShell* aPres
   NS_ASSERTION(aPresShell->GetPresContext()->IsPaginated(), "created a page break frame while not printing");
 
   return new (aPresShell) nsPageBreakFrame(aContext);
 }
 
 NS_IMPL_FRAMEARENA_HELPERS(nsPageBreakFrame)
 
 nsPageBreakFrame::nsPageBreakFrame(nsStyleContext* aContext)
-  : nsLeafFrame(aContext, LayoutFrameType::PageBreak)
+  : nsLeafFrame(aContext, kClassID, LayoutFrameType::PageBreak)
   , mHaveReflowed(false)
 {
 }
 
 nsPageBreakFrame::~nsPageBreakFrame()
 {
 }
 
--- a/layout/generic/nsPlaceholderFrame.h
+++ b/layout/generic/nsPlaceholderFrame.h
@@ -62,17 +62,17 @@ public:
   /**
    * Create a new placeholder frame.  aTypeBit must be one of the
    * PLACEHOLDER_FOR_* constants above.
    */
   friend nsIFrame* NS_NewPlaceholderFrame(nsIPresShell* aPresShell,
                                           nsStyleContext* aContext,
                                           nsFrameState aTypeBit);
   nsPlaceholderFrame(nsStyleContext* aContext, nsFrameState aTypeBit)
-    : nsFrame(aContext, mozilla::LayoutFrameType::Placeholder)
+    : nsFrame(aContext, kClassID, mozilla::LayoutFrameType::Placeholder)
     , mOutOfFlowFrame(nullptr)
   {
     NS_PRECONDITION(aTypeBit == PLACEHOLDER_FOR_FLOAT ||
                     aTypeBit == PLACEHOLDER_FOR_ABSPOS ||
                     aTypeBit == PLACEHOLDER_FOR_FIXEDPOS ||
                     aTypeBit == PLACEHOLDER_FOR_POPUP ||
                     aTypeBit == PLACEHOLDER_FOR_TOPLAYER,
                     "Unexpected type bit");
--- a/layout/generic/nsPluginFrame.cpp
+++ b/layout/generic/nsPluginFrame.cpp
@@ -140,17 +140,17 @@ protected:
     return false;
   }
 
   uint64_t mLastSequenceNumber;
   nsPluginFrame* mFrame;
 };
 
 nsPluginFrame::nsPluginFrame(nsStyleContext* aContext)
-  : nsFrame(aContext, LayoutFrameType::Object)
+  : nsFrame(aContext, kClassID, LayoutFrameType::Object)
   , mInstanceOwner(nullptr)
   , mOuterView(nullptr)
   , mInnerView(nullptr)
   , mBackgroundSink(nullptr)
   , mReflowCallbackPosted(false)
 {
   MOZ_LOG(sPluginFrameLog, LogLevel::Debug,
          ("Created new nsPluginFrame %p\n", this));
--- a/layout/generic/nsQueryFrame.h
+++ b/layout/generic/nsQueryFrame.h
@@ -63,16 +63,25 @@ public:
 #undef FRAME_ID
 
     // This marker allows mozilla::ArenaObjectID to "extend" this enum
     // with additional sequential values for use in nsPresArena and
     // nsIPresShell::{Allocate,Free}ByObjectId
     NON_FRAME_MARKER
   };
 
+  // A strict subset of FrameIID above for frame classes that we instantiate.
+  enum class ClassID : uint8_t {
+#define FRAME_ID(classname, ...) classname##_id,
+#define ABSTRACT_FRAME_ID(classname)
+#include "nsFrameIdList.h"
+#undef FRAME_ID
+#undef ABSTRACT_FRAME_ID
+  };
+
   virtual void* QueryFrame(FrameIID id) = 0;
 };
 
 class do_QueryFrame
 {
 public:
   explicit do_QueryFrame(nsQueryFrame *s) : mRawPtr(s) { }
 
--- a/layout/generic/nsRubyBaseContainerFrame.h
+++ b/layout/generic/nsRubyBaseContainerFrame.h
@@ -61,17 +61,17 @@ public:
   }
 
 protected:
   friend nsContainerFrame*
     NS_NewRubyBaseContainerFrame(nsIPresShell* aPresShell,
                                  nsStyleContext* aContext);
 
   explicit nsRubyBaseContainerFrame(nsStyleContext* aContext)
-    : nsContainerFrame(aContext, mozilla::LayoutFrameType::RubyBaseContainer)
+    : nsContainerFrame(aContext, kClassID, mozilla::LayoutFrameType::RubyBaseContainer)
   {}
 
   struct RubyReflowInput;
   nscoord ReflowColumns(const RubyReflowInput& aReflowInput,
                         nsReflowStatus& aStatus);
   nscoord ReflowOneColumn(const RubyReflowInput& aReflowInput,
                           uint32_t aColumnIndex,
                           const mozilla::RubyColumn& aColumn,
--- a/layout/generic/nsRubyBaseFrame.h
+++ b/layout/generic/nsRubyBaseFrame.h
@@ -27,13 +27,13 @@ public:
 #ifdef DEBUG_FRAME_DUMP
   virtual nsresult GetFrameName(nsAString& aResult) const override;
 #endif
 
 protected:
   friend nsContainerFrame* NS_NewRubyBaseFrame(nsIPresShell* aPresShell,
                                                nsStyleContext* aContext);
   explicit nsRubyBaseFrame(nsStyleContext* aContext)
-    : nsRubyContentFrame(aContext, mozilla::LayoutFrameType::RubyBase)
+    : nsRubyContentFrame(aContext, kClassID, mozilla::LayoutFrameType::RubyBase)
   {}
 };
 
 #endif /* nsRubyBaseFrame_h___ */
--- a/layout/generic/nsRubyContentFrame.h
+++ b/layout/generic/nsRubyContentFrame.h
@@ -23,14 +23,15 @@ public:
   // an anonymous frame that was created to contain non-droppable
   // whitespaces directly inside a ruby level container. This impacts
   // ruby pairing behavior.
   // See http://dev.w3.org/csswg/css-ruby/#anon-gen-interpret-space
   bool IsIntraLevelWhitespace() const;
 
 protected:
   explicit nsRubyContentFrame(nsStyleContext* aContext,
+                              ClassID aID,
                               mozilla::LayoutFrameType aType)
-    : nsInlineFrame(aContext, aType)
+    : nsInlineFrame(aContext, aID, aType)
   {}
 };
 
 #endif /* nsRubyContentFrame_h___ */
--- a/layout/generic/nsRubyFrame.h
+++ b/layout/generic/nsRubyFrame.h
@@ -43,17 +43,17 @@ public:
   mozilla::RubyBlockLeadings GetBlockLeadings() const {
     return mLeadings;
   }
 
 protected:
   friend nsContainerFrame* NS_NewRubyFrame(nsIPresShell* aPresShell,
                                            nsStyleContext* aContext);
   explicit nsRubyFrame(nsStyleContext* aContext)
-    : nsInlineFrame(aContext, mozilla::LayoutFrameType::Ruby)
+    : nsInlineFrame(aContext, kClassID, mozilla::LayoutFrameType::Ruby)
   {}
 
   void ReflowSegment(nsPresContext* aPresContext,
                      const ReflowInput& aReflowInput,
                      nsRubyBaseContainerFrame* aBaseContainer,
                      nsReflowStatus& aStatus);
 
   nsRubyBaseContainerFrame* PullOneSegment(const nsLineLayout* aLineLayout,
--- a/layout/generic/nsRubyTextContainerFrame.h
+++ b/layout/generic/nsRubyTextContainerFrame.h
@@ -51,17 +51,17 @@ public:
   }
 
 protected:
   friend nsContainerFrame*
     NS_NewRubyTextContainerFrame(nsIPresShell* aPresShell,
                                  nsStyleContext* aContext);
 
   explicit nsRubyTextContainerFrame(nsStyleContext* aContext)
-    : nsContainerFrame(aContext, mozilla::LayoutFrameType::RubyTextContainer)
+    : nsContainerFrame(aContext, kClassID, mozilla::LayoutFrameType::RubyTextContainer)
     , mISize(0)
   {}
 
   void UpdateSpanFlag();
 
   friend class nsRubyBaseContainerFrame;
   void SetISize(nscoord aISize) { mISize = aISize; }
 
--- a/layout/generic/nsRubyTextFrame.h
+++ b/layout/generic/nsRubyTextFrame.h
@@ -44,13 +44,13 @@ public:
   {
     return GetStateBits() & NS_RUBY_TEXT_FRAME_AUTOHIDE;
   }
 
 protected:
   friend nsContainerFrame* NS_NewRubyTextFrame(nsIPresShell* aPresShell,
                                                nsStyleContext* aContext);
   explicit nsRubyTextFrame(nsStyleContext* aContext)
-    : nsRubyContentFrame(aContext, mozilla::LayoutFrameType::RubyText)
+    : nsRubyContentFrame(aContext, kClassID, mozilla::LayoutFrameType::RubyText)
   {}
 };
 
 #endif /* nsRubyTextFrame_h___ */
--- a/layout/generic/nsSimplePageSequenceFrame.cpp
+++ b/layout/generic/nsSimplePageSequenceFrame.cpp
@@ -40,17 +40,17 @@ nsSimplePageSequenceFrame*
 NS_NewSimplePageSequenceFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
 {
   return new (aPresShell) nsSimplePageSequenceFrame(aContext);
 }
 
 NS_IMPL_FRAMEARENA_HELPERS(nsSimplePageSequenceFrame)
 
 nsSimplePageSequenceFrame::nsSimplePageSequenceFrame(nsStyleContext* aContext)
-  : nsContainerFrame(aContext, LayoutFrameType::Sequence)
+  : nsContainerFrame(aContext, kClassID, LayoutFrameType::Sequence)
   , mTotalPages(-1)
   , mSelectionHeight(-1)
   , mYSelOffset(0)
   , mCalledBeginPage(false)
   , mCurrentCanvasListSetup(false)
 {
   nscoord halfInch = PresContext()->CSSTwipsToAppUnits(NS_INCHES_TO_TWIPS(0.5));
   mMargin.SizeTo(halfInch, halfInch, halfInch, halfInch);
--- a/layout/generic/nsSplittableFrame.h
+++ b/layout/generic/nsSplittableFrame.h
@@ -69,19 +69,19 @@ public:
   virtual nsIFrame* FirstInFlow() const override;
   virtual nsIFrame* LastInFlow() const override;
 
   // Remove the frame from the flow. Connects the frame's prev-in-flow
   // and its next-in-flow. This should only be called in frame Destroy() methods.
   static void RemoveFromFlow(nsIFrame* aFrame);
 
 protected:
-  explicit nsSplittableFrame(nsStyleContext* aContext,
+  explicit nsSplittableFrame(nsStyleContext* aContext, ClassID aID,
                              mozilla::LayoutFrameType aType)
-    : nsFrame(aContext, aType)
+    : nsFrame(aContext, aID, aType)
     , mPrevContinuation(nullptr)
     , mNextContinuation(nullptr)
   {}
 
   /**
    * Return the sum of the block-axis content size of our prev-in-flows.
    * @param aWM a writing-mode to determine the block-axis
    *
--- a/layout/generic/nsSubDocumentFrame.cpp
+++ b/layout/generic/nsSubDocumentFrame.cpp
@@ -54,17 +54,17 @@ GetDocumentFromView(nsView* aView)
   NS_PRECONDITION(aView, "");
 
   nsViewManager* vm = aView->GetViewManager();
   nsIPresShell* ps =  vm ? vm->GetPresShell() : nullptr;
   return ps ? ps->GetDocument() : nullptr;
 }
 
 nsSubDocumentFrame::nsSubDocumentFrame(nsStyleContext* aContext)
-  : nsAtomicContainerFrame(aContext, LayoutFrameType::SubDocument)
+  : nsAtomicContainerFrame(aContext, kClassID, LayoutFrameType::SubDocument)
   , mOuterView(nullptr)
   , mInnerView(nullptr)
   , mIsInline(false)
   , mPostedReflowCallback(false)
   , mDidCreateDoc(false)
   , mCallingShow(false)
 {
 }
--- a/layout/generic/nsTextFrame.cpp
+++ b/layout/generic/nsTextFrame.cpp
@@ -4432,17 +4432,17 @@ public:
 
   void AddInlineMinISize(nsRenderingContext* aRenderingContext,
                          InlineMinISizeData* aData) override;
   void AddInlinePrefISize(nsRenderingContext* aRenderingContext,
                           InlinePrefISizeData* aData) override;
 
 protected:
   explicit nsContinuingTextFrame(nsStyleContext* aContext)
-    : nsTextFrame(aContext)
+    : nsTextFrame(aContext, kClassID)
   {}
 
   nsTextFrame* mPrevContinuation;
 };
 
 void
 nsContinuingTextFrame::Init(nsIContent*       aContent,
                             nsContainerFrame* aParent,
--- a/layout/generic/nsTextFrame.h
+++ b/layout/generic/nsTextFrame.h
@@ -45,18 +45,18 @@ class nsTextFrame : public nsFrame
   typedef mozilla::TextRangeStyle TextRangeStyle;
   typedef mozilla::gfx::DrawTarget DrawTarget;
   typedef mozilla::gfx::Point Point;
   typedef mozilla::gfx::Rect Rect;
   typedef mozilla::gfx::Size Size;
   typedef gfxTextRun::Range Range;
 
 public:
-  explicit nsTextFrame(nsStyleContext* aContext)
-    : nsTextFrame(aContext, mozilla::LayoutFrameType::Text)
+  explicit nsTextFrame(nsStyleContext* aContext, ClassID aID = kClassID)
+    : nsTextFrame(aContext, aID, mozilla::LayoutFrameType::Text)
   {}
 
   NS_DECL_FRAMEARENA_HELPERS(nsTextFrame)
 
   friend class nsContinuingTextFrame;
   friend class nsDisplayTextGeometry;
   friend class nsDisplayText;
 
@@ -643,18 +643,18 @@ public:
   bool ComputeCustomOverflow(nsOverflowAreas& aOverflowAreas) override;
 
   void AssignJustificationGaps(const mozilla::JustificationAssignment& aAssign);
   mozilla::JustificationAssignment GetJustificationAssignment() const;
 
   uint32_t CountGraphemeClusters() const;
 
 protected:
-  nsTextFrame(nsStyleContext* aContext, mozilla::LayoutFrameType aType)
-    : nsFrame(aContext, aType)
+  nsTextFrame(nsStyleContext* aContext, ClassID aID, mozilla::LayoutFrameType aType)
+    : nsFrame(aContext, aID, aType)
     , mNextContinuation(nullptr)
     , mContentOffset(0)
     , mContentLengthHint(0)
     , mAscent(0)
   {
     NS_ASSERTION(mContentOffset == 0, "Bogus content offset");
   }
 
--- a/layout/generic/nsVideoFrame.cpp
+++ b/layout/generic/nsVideoFrame.cpp
@@ -70,17 +70,17 @@ SwapScaleWidthHeightForRotation(IntSize&
       aDegrees == VideoInfo::Rotation::kDegree_270) {
     int32_t tmpWidth = aSize.width;
     aSize.width = aSize.height;
     aSize.height = tmpWidth;
   }
 }
 
 nsVideoFrame::nsVideoFrame(nsStyleContext* aContext)
-  : nsContainerFrame(aContext, LayoutFrameType::HTMLVideo)
+  : nsContainerFrame(aContext, kClassID, LayoutFrameType::HTMLVideo)
 {
   EnableVisibilityTracking();
 }
 
 nsVideoFrame::~nsVideoFrame()
 {
 }
 
--- a/layout/mathml/nsMathMLContainerFrame.h
+++ b/layout/mathml/nsMathMLContainerFrame.h
@@ -27,18 +27,18 @@
 #define STRETCH_CONSIDER_ACTUAL_SIZE    0x00000001 // just use our current size
 #define STRETCH_CONSIDER_EMBELLISHMENTS 0x00000002 // size calculations include embellishments
 
 class nsMathMLContainerFrame : public nsContainerFrame,
                                public nsMathMLFrame
 {
   friend class nsMathMLmfencedFrame;
 public:
-  nsMathMLContainerFrame(nsStyleContext* aContext)
-    : nsContainerFrame(aContext, mozilla::LayoutFrameType::None)
+  nsMathMLContainerFrame(nsStyleContext* aContext, ClassID aID)
+    : nsContainerFrame(aContext, aID, mozilla::LayoutFrameType::None)
     , mIntrinsicWidth(NS_INTRINSIC_WIDTH_UNKNOWN)
     , mBlockStartAscent(0)
   {}
 
   NS_DECL_QUERYFRAME_TARGET(nsMathMLContainerFrame)
   NS_DECL_QUERYFRAME
   NS_DECL_ABSTRACT_FRAME(nsMathMLContainerFrame)
 
@@ -464,17 +464,19 @@ public:
 
   // See nsIMathMLFrame.h
   bool IsMrowLike() {
     return mFrames.FirstChild() != mFrames.LastChild() ||
            !mFrames.FirstChild();
   }
 
 protected:
-  explicit nsMathMLmathBlockFrame(nsStyleContext* aContext) : nsBlockFrame(aContext) {
+  explicit nsMathMLmathBlockFrame(nsStyleContext* aContext)
+    : nsBlockFrame(aContext, kClassID)
+  {
     // We should always have a float manager.  Not that things can really try
     // to float out of us anyway, but we need one for line layout.
     // Bug 1301881: Do we still need to set NS_BLOCK_FLOAT_MGR?
     // AddStateBits(NS_BLOCK_FLOAT_MGR);
   }
   virtual ~nsMathMLmathBlockFrame() {}
 };
 
@@ -541,15 +543,15 @@ public:
   bool
   IsMrowLike() override {
     return mFrames.FirstChild() != mFrames.LastChild() ||
            !mFrames.FirstChild();
   }
 
 protected:
   explicit nsMathMLmathInlineFrame(nsStyleContext* aContext)
-    : nsInlineFrame(aContext)
+    : nsInlineFrame(aContext, kClassID)
   {}
 
   virtual ~nsMathMLmathInlineFrame() {}
 };
 
 #endif /* nsMathMLContainerFrame_h___ */
--- a/layout/mathml/nsMathMLSelectedFrame.h
+++ b/layout/mathml/nsMathMLSelectedFrame.h
@@ -43,18 +43,18 @@ public:
   Reflow(nsPresContext*          aPresContext,
          ReflowOutput&     aDesiredSize,
          const ReflowInput& aReflowInput,
          nsReflowStatus&          aStatus) override;
 
   virtual nsQueryFrame::FrameIID GetFrameId() override = 0;
 
 protected:
-  explicit nsMathMLSelectedFrame(nsStyleContext* aContext) :
-    nsMathMLContainerFrame(aContext),
+  nsMathMLSelectedFrame(nsStyleContext* aContext, ClassID aID) :
+    nsMathMLContainerFrame(aContext, aID),
     mSelectedFrame(nullptr),
     mInvalidMarkup(false) {}
   virtual ~nsMathMLSelectedFrame();
   
   virtual nsIFrame* GetSelectedFrame() = 0;
   nsIFrame*       mSelectedFrame;
 
   bool            mInvalidMarkup;
--- a/layout/mathml/nsMathMLTokenFrame.h
+++ b/layout/mathml/nsMathMLTokenFrame.h
@@ -54,15 +54,16 @@ public:
          nsReflowStatus&          aStatus) override;
 
   virtual nsresult
   Place(DrawTarget*          aDrawTarget,
         bool                 aPlaceOrigin,
         ReflowOutput& aDesiredSize) override;
 
 protected:
-  explicit nsMathMLTokenFrame(nsStyleContext* aContext) : nsMathMLContainerFrame(aContext) {}
+  explicit nsMathMLTokenFrame(nsStyleContext* aContext, ClassID aID = kClassID)
+    : nsMathMLContainerFrame(aContext, aID) {}
   virtual ~nsMathMLTokenFrame();
 
   void MarkTextFramesAsTokenMathML();
 };
 
 #endif /* nsMathMLTokentFrame_h___ */
--- a/layout/mathml/nsMathMLmactionFrame.h
+++ b/layout/mathml/nsMathMLmactionFrame.h
@@ -54,17 +54,17 @@ private:
 
     explicit MouseListener(nsMathMLmactionFrame* aOwner) : mOwner(aOwner) { }
 
     nsMathMLmactionFrame* mOwner;
   };
 
 protected:
   explicit nsMathMLmactionFrame(nsStyleContext* aContext) :
-    nsMathMLSelectedFrame(aContext) {}
+    nsMathMLSelectedFrame(aContext, kClassID) {}
   virtual ~nsMathMLmactionFrame();
   
 private:
   int32_t         mActionType;
   int32_t         mChildCount;
   int32_t         mSelection;
   RefPtr<MouseListener> mListener;
 
--- a/layout/mathml/nsMathMLmencloseFrame.cpp
+++ b/layout/mathml/nsMathMLmencloseFrame.cpp
@@ -42,18 +42,18 @@ static const uint8_t kPhasorangleWidth =
 nsIFrame*
 NS_NewMathMLmencloseFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
 {
   return new (aPresShell) nsMathMLmencloseFrame(aContext);
 }
 
 NS_IMPL_FRAMEARENA_HELPERS(nsMathMLmencloseFrame)
 
-nsMathMLmencloseFrame::nsMathMLmencloseFrame(nsStyleContext* aContext) :
-  nsMathMLContainerFrame(aContext), mNotationsToDraw(0),
+nsMathMLmencloseFrame::nsMathMLmencloseFrame(nsStyleContext* aContext, ClassID aID) :
+  nsMathMLContainerFrame(aContext, aID), mNotationsToDraw(0),
   mRuleThickness(0), mRadicalRuleThickness(0),
   mLongDivCharIndex(-1), mRadicalCharIndex(-1), mContentWidth(0)
 {
 }
 
 nsMathMLmencloseFrame::~nsMathMLmencloseFrame()
 {
 }
--- a/layout/mathml/nsMathMLmencloseFrame.h
+++ b/layout/mathml/nsMathMLmencloseFrame.h
@@ -84,17 +84,17 @@ public:
 
   bool
   IsMrowLike() override {
     return mFrames.FirstChild() != mFrames.LastChild() ||
            !mFrames.FirstChild();
   }
 
 protected:
-  explicit nsMathMLmencloseFrame(nsStyleContext* aContext);
+  explicit nsMathMLmencloseFrame(nsStyleContext* aContext, ClassID aID = kClassID);
   virtual ~nsMathMLmencloseFrame();
 
   nsresult PlaceInternal(DrawTarget*          aDrawTarget,
                          bool                 aPlaceOrigin,
                          ReflowOutput& aDesiredSize,
                          bool                 aWidthOnly);
 
   // functions to parse the "notation" attribute.
--- a/layout/mathml/nsMathMLmfencedFrame.h
+++ b/layout/mathml/nsMathMLmfencedFrame.h
@@ -92,17 +92,17 @@ public:
     // renders equivalently to
     // <mrow> <mo> ( </mo> <mo>%</mo> <mo> ) </mo> </mrow>
     // This also holds with multiple children.  (MathML3 3.3.8.1)
     return true;
   }
 
 protected:
   explicit nsMathMLmfencedFrame(nsStyleContext* aContext)
-    : nsMathMLContainerFrame(aContext)
+    : nsMathMLContainerFrame(aContext, kClassID)
     , mOpenChar(nullptr)
     , mCloseChar(nullptr)
     , mSeparatorsChar(nullptr)
     , mSeparatorsCount(0)
   {}
 
   virtual ~nsMathMLmfencedFrame();
   
--- a/layout/mathml/nsMathMLmfracFrame.h
+++ b/layout/mathml/nsMathMLmfracFrame.h
@@ -91,17 +91,17 @@ public:
                     nscoord          aDefaultRuleThickness,
                     float            aFontSizeInflation);
 
   uint8_t
   ScriptIncrement(nsIFrame* aFrame) override;
 
 protected:
   explicit nsMathMLmfracFrame(nsStyleContext* aContext)
-    : nsMathMLContainerFrame(aContext)
+    : nsMathMLContainerFrame(aContext, kClassID)
     , mLineRect()
     , mSlashChar(nullptr)
     , mLineThickness(0)
     , mIsBevelled(false)
   {}
   virtual ~nsMathMLmfracFrame();
 
   nsresult PlaceInternal(DrawTarget*          aDrawTarget,
--- a/layout/mathml/nsMathMLmmultiscriptsFrame.h
+++ b/layout/mathml/nsMathMLmmultiscriptsFrame.h
@@ -39,15 +39,16 @@ public:
                    nscoord                 aUserSubScriptShift,
                    nscoord                 aUserSupScriptShift,
                    float                   aFontSizeInflation);
 
   uint8_t
   ScriptIncrement(nsIFrame* aFrame) override;
 
 protected:
-  explicit nsMathMLmmultiscriptsFrame(nsStyleContext* aContext) : nsMathMLContainerFrame(aContext) {}
+  explicit nsMathMLmmultiscriptsFrame(nsStyleContext* aContext)
+    : nsMathMLContainerFrame(aContext, kClassID) {}
   virtual ~nsMathMLmmultiscriptsFrame();
   
 
 };
 
 #endif /* nsMathMLmmultiscriptsFrame_h___ */
--- a/layout/mathml/nsMathMLmoFrame.h
+++ b/layout/mathml/nsMathMLmoFrame.h
@@ -76,17 +76,17 @@ public:
   ChildListChanged(int32_t aModType) override
   {
     ProcessTextData();
     return nsMathMLContainerFrame::ChildListChanged(aModType);
   }
 
 protected:
   explicit nsMathMLmoFrame(nsStyleContext* aContext) :
-    nsMathMLTokenFrame(aContext), mFlags(0), mMinSize(0), mMaxSize(0) {}
+    nsMathMLTokenFrame(aContext, kClassID), mFlags(0), mMinSize(0), mMaxSize(0) {}
   virtual ~nsMathMLmoFrame();
   
   nsMathMLChar     mMathMLChar; // Here is the MathMLChar that will deal with the operator.
   nsOperatorFlags  mFlags;
   float            mMinSize;
   float            mMaxSize;
 
   bool UseMathMLChar();
--- a/layout/mathml/nsMathMLmpaddedFrame.h
+++ b/layout/mathml/nsMathMLmpaddedFrame.h
@@ -41,17 +41,17 @@ public:
   bool
   IsMrowLike() override {
     return mFrames.FirstChild() != mFrames.LastChild() ||
            !mFrames.FirstChild();
   }
 
 protected:
   explicit nsMathMLmpaddedFrame(nsStyleContext* aContext)
-    : nsMathMLContainerFrame(aContext)
+    : nsMathMLContainerFrame(aContext, kClassID)
     , mWidthSign(0)
     , mHeightSign(0)
     , mDepthSign(0)
     , mLeadingSpaceSign(0)
     , mVerticalOffsetSign(0)
     , mWidthPseudoUnit(0)
     , mHeightPseudoUnit(0)
     , mDepthPseudoUnit(0)
--- a/layout/mathml/nsMathMLmrootFrame.cpp
+++ b/layout/mathml/nsMathMLmrootFrame.cpp
@@ -24,17 +24,17 @@ nsIFrame*
 NS_NewMathMLmrootFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
 {
   return new (aPresShell) nsMathMLmrootFrame(aContext);
 }
 
 NS_IMPL_FRAMEARENA_HELPERS(nsMathMLmrootFrame)
 
 nsMathMLmrootFrame::nsMathMLmrootFrame(nsStyleContext* aContext) :
-  nsMathMLContainerFrame(aContext),
+  nsMathMLContainerFrame(aContext, kClassID),
   mSqrChar(),
   mBarRect()
 {
 }
 
 nsMathMLmrootFrame::~nsMathMLmrootFrame()
 {
 }
--- a/layout/mathml/nsMathMLmrowFrame.h
+++ b/layout/mathml/nsMathMLmrowFrame.h
@@ -42,13 +42,14 @@ public:
     // <mrow> elements with a single child are treated identically to the case
     // where the child wasn't within an mrow, so we pretend the mrow isn't an
     // mrow in that situation.
     return mFrames.FirstChild() != mFrames.LastChild() ||
            !mFrames.FirstChild();
   }
 
 protected:
-  explicit nsMathMLmrowFrame(nsStyleContext* aContext) : nsMathMLContainerFrame(aContext) {}
+  explicit nsMathMLmrowFrame(nsStyleContext* aContext)
+    : nsMathMLContainerFrame(aContext, kClassID) {}
   virtual ~nsMathMLmrowFrame();
 };
 
 #endif /* nsMathMLmrowFrame_h___ */
--- a/layout/mathml/nsMathMLmspaceFrame.h
+++ b/layout/mathml/nsMathMLmspaceFrame.h
@@ -32,17 +32,17 @@ public:
   virtual void
   Reflow(nsPresContext*          aPresContext,
          ReflowOutput&     aDesiredSize,
          const ReflowInput& aReflowInput,
          nsReflowStatus&          aStatus) override;
   
 protected:
   explicit nsMathMLmspaceFrame(nsStyleContext* aContext) :
-    nsMathMLContainerFrame(aContext), mWidth(0), mHeight(0), mDepth(0) {}
+    nsMathMLContainerFrame(aContext, kClassID), mWidth(0), mHeight(0), mDepth(0) {}
   virtual ~nsMathMLmspaceFrame();
 
   virtual nsresult
   MeasureForWidth(DrawTarget* aDrawTarget,
                   ReflowOutput& aDesiredSize) override;
 
 private:
   nscoord mWidth;
--- a/layout/mathml/nsMathMLmsqrtFrame.cpp
+++ b/layout/mathml/nsMathMLmsqrtFrame.cpp
@@ -14,17 +14,17 @@ nsIFrame*
 NS_NewMathMLmsqrtFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
 {
   return new (aPresShell) nsMathMLmsqrtFrame(aContext);
 }
 
 NS_IMPL_FRAMEARENA_HELPERS(nsMathMLmsqrtFrame)
 
 nsMathMLmsqrtFrame::nsMathMLmsqrtFrame(nsStyleContext* aContext) :
-  nsMathMLmencloseFrame(aContext)
+  nsMathMLmencloseFrame(aContext, kClassID)
 {
 }
 
 nsMathMLmsqrtFrame::~nsMathMLmsqrtFrame()
 {
 }
 
 void
--- a/layout/mathml/nsMathMLmtableFrame.cpp
+++ b/layout/mathml/nsMathMLmtableFrame.cpp
@@ -1300,17 +1300,17 @@ nsContainerFrame*
 NS_NewMathMLmtdInnerFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
 {
   return new (aPresShell) nsMathMLmtdInnerFrame(aContext);
 }
 
 NS_IMPL_FRAMEARENA_HELPERS(nsMathMLmtdInnerFrame)
 
 nsMathMLmtdInnerFrame::nsMathMLmtdInnerFrame(nsStyleContext* aContext)
-  : nsBlockFrame(aContext)
+  : nsBlockFrame(aContext, kClassID)
 {
   // Make a copy of the parent nsStyleText for later modification.
   mUniqueStyleText = new (PresContext()) nsStyleText(*StyleText());
 }
 
 nsMathMLmtdInnerFrame::~nsMathMLmtdInnerFrame()
 {
   mUniqueStyleText->Destroy(PresContext());
--- a/layout/mathml/nsMathMLmtableFrame.h
+++ b/layout/mathml/nsMathMLmtableFrame.h
@@ -44,17 +44,17 @@ public:
 
   virtual bool IsFrameOfType(uint32_t aFlags) const override
   {
     return nsTableWrapperFrame::IsFrameOfType(aFlags & ~(nsIFrame::eMathML));
   }
 
 protected:
   explicit nsMathMLmtableWrapperFrame(nsStyleContext* aContext)
-    : nsTableWrapperFrame(aContext)
+    : nsTableWrapperFrame(aContext, kClassID)
   {}
 
   virtual ~nsMathMLmtableWrapperFrame();
 
   // helper to find the row frame at a given index, positive or negative, e.g.,
   // 1..n means the first row down to the last row, -1..-n means the last row
   // up to the first row. Used for alignments that are relative to a given row
   nsIFrame*
@@ -152,17 +152,17 @@ public:
    * rowspacing, columnspacing and framespacing attributes.  The second
    * approach is used if the user specifies at least one of those attributes.
    */
   void SetUseCSSSpacing();
   bool GetUseCSSSpacing() { return mUseCSSSpacing; }
 
 protected:
   explicit nsMathMLmtableFrame(nsStyleContext* aContext)
-    : nsTableFrame(aContext)
+    : nsTableFrame(aContext, kClassID)
     , mFrameSpacingX(0)
     , mFrameSpacingY(0)
     , mUseCSSSpacing(false)
   {}
 
   virtual ~nsMathMLmtableFrame();
 
 private:
@@ -227,17 +227,17 @@ public:
     if (tableFrame && tableFrame->IsFrameOfType(nsIFrame::eMathML)) {
       // relayout the table
       ((nsMathMLmtableFrame*)tableFrame)->RestyleTable();
     }
   }
 
 protected:
   explicit nsMathMLmtrFrame(nsStyleContext* aContext)
-    : nsTableRowFrame(aContext)
+    : nsTableRowFrame(aContext, kClassID)
   {}
 
   virtual ~nsMathMLmtrFrame();
 }; // class nsMathMLmtrFrame
 
 // --------------
 
 class nsMathMLmtdFrame : public nsTableCellFrame
@@ -274,17 +274,17 @@ public:
   }
 
   virtual LogicalMargin GetBorderWidth(WritingMode aWM) const override;
 
   virtual nsMargin GetBorderOverflow() override;
 
 protected:
   nsMathMLmtdFrame(nsStyleContext* aContext, nsTableFrame* aTableFrame)
-    : nsTableCellFrame(aContext, aTableFrame)
+    : nsTableCellFrame(aContext, aTableFrame, kClassID)
   {
   }
 
   virtual ~nsMathMLmtdFrame();
 }; // class nsMathMLmtdFrame
 
 // --------------
 
--- a/layout/mathml/nsMathMLmunderoverFrame.h
+++ b/layout/mathml/nsMathMLmunderoverFrame.h
@@ -44,17 +44,17 @@ public:
   uint8_t ScriptIncrement(nsIFrame* aFrame) override;
 
   // nsIReflowCallback.
   bool ReflowFinished() override;
   void ReflowCallbackCanceled() override;
 
 protected:
   explicit nsMathMLmunderoverFrame(nsStyleContext* aContext)
-    : nsMathMLContainerFrame(aContext)
+    : nsMathMLContainerFrame(aContext, kClassID)
     , mIncrementUnder(false)
     , mIncrementOver(false)
   {}
 
   virtual ~nsMathMLmunderoverFrame();
 
 private:
   // Helper to set the "increment script level" flag on the element belonging
--- a/layout/mathml/nsMathMLsemanticsFrame.h
+++ b/layout/mathml/nsMathMLsemanticsFrame.h
@@ -17,15 +17,15 @@ class nsMathMLsemanticsFrame : public ns
 public:
   NS_DECL_FRAMEARENA_HELPERS(nsMathMLsemanticsFrame)
 
   friend nsIFrame* NS_NewMathMLsemanticsFrame(nsIPresShell* aPresShell,
                                               nsStyleContext* aContext);
 
 protected:
   explicit nsMathMLsemanticsFrame(nsStyleContext* aContext) :
-    nsMathMLSelectedFrame(aContext) {}
+    nsMathMLSelectedFrame(aContext, kClassID) {}
   virtual ~nsMathMLsemanticsFrame();
 
   nsIFrame* GetSelectedFrame() override;
 };
 
 #endif /* nsMathMLsemanticsFrame_h___ */
--- a/layout/svg/SVGFEContainerFrame.cpp
+++ b/layout/svg/SVGFEContainerFrame.cpp
@@ -16,17 +16,17 @@
  * have special child elements that provide parameters.
  */
 class SVGFEContainerFrame : public nsContainerFrame
 {
   friend nsIFrame*
   NS_NewSVGFEContainerFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 protected:
   explicit SVGFEContainerFrame(nsStyleContext* aContext)
-    : nsContainerFrame(aContext, mozilla::LayoutFrameType::SVGFEContainer)
+    : nsContainerFrame(aContext, kClassID, mozilla::LayoutFrameType::SVGFEContainer)
   {
     AddStateBits(NS_FRAME_SVG_LAYOUT | NS_FRAME_IS_NONDISPLAY);
   }
 
 public:
   NS_DECL_FRAMEARENA_HELPERS(SVGFEContainerFrame)
 
   virtual bool IsFrameOfType(uint32_t aFlags) const override
--- a/layout/svg/SVGFEImageFrame.cpp
+++ b/layout/svg/SVGFEImageFrame.cpp
@@ -18,17 +18,17 @@ using namespace mozilla;
 using namespace mozilla::dom;
 
 class SVGFEImageFrame final : public nsFrame
 {
   friend nsIFrame*
   NS_NewSVGFEImageFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 protected:
   explicit SVGFEImageFrame(nsStyleContext* aContext)
-    : nsFrame(aContext, LayoutFrameType::SVGFEImage)
+    : nsFrame(aContext, kClassID, LayoutFrameType::SVGFEImage)
   {
     AddStateBits(NS_FRAME_SVG_LAYOUT | NS_FRAME_IS_NONDISPLAY);
 
     // This frame isn't actually displayed, but it contains an image and we want
     // to use the nsImageLoadingContent machinery for managing images, which
     // requires visibility tracking, so we enable visibility tracking and
     // forcibly mark it visible below.
     EnableVisibilityTracking();
--- a/layout/svg/SVGFELeafFrame.cpp
+++ b/layout/svg/SVGFELeafFrame.cpp
@@ -15,17 +15,17 @@
  * have special child elements that provide parameters.
  */
 class SVGFELeafFrame final : public nsFrame
 {
   friend nsIFrame*
   NS_NewSVGFELeafFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 protected:
   explicit SVGFELeafFrame(nsStyleContext* aContext)
-    : nsFrame(aContext, LayoutFrameType::SVGFELeaf)
+    : nsFrame(aContext, kClassID, LayoutFrameType::SVGFELeaf)
   {
     AddStateBits(NS_FRAME_SVG_LAYOUT | NS_FRAME_IS_NONDISPLAY);
   }
 
 public:
   NS_DECL_FRAMEARENA_HELPERS(SVGFELeafFrame)
 
 #ifdef DEBUG
--- a/layout/svg/SVGFEUnstyledLeafFrame.cpp
+++ b/layout/svg/SVGFEUnstyledLeafFrame.cpp
@@ -11,17 +11,17 @@
 #include "nsSVGFilters.h"
 
 class SVGFEUnstyledLeafFrame : public nsFrame
 {
   friend nsIFrame*
   NS_NewSVGFEUnstyledLeafFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 protected:
   explicit SVGFEUnstyledLeafFrame(nsStyleContext* aContext)
-    : nsFrame(aContext, LayoutFrameType::SVGFEUnstyledLeaf)
+    : nsFrame(aContext, kClassID, LayoutFrameType::SVGFEUnstyledLeaf)
   {
     AddStateBits(NS_FRAME_SVG_LAYOUT | NS_FRAME_IS_NONDISPLAY);
   }
 
 public:
   NS_DECL_FRAMEARENA_HELPERS(SVGFEUnstyledLeafFrame)
 
   virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder,
--- a/layout/svg/SVGGeometryFrame.h
+++ b/layout/svg/SVGGeometryFrame.h
@@ -44,24 +44,24 @@ class SVGGeometryFrame : public nsFrame
   typedef mozilla::gfx::DrawTarget DrawTarget;
 
   friend nsIFrame*
   ::NS_NewSVGGeometryFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 
   friend class ::nsDisplaySVGGeometry;
 
 protected:
-  SVGGeometryFrame(nsStyleContext* aContext, mozilla::LayoutFrameType aType)
-    : nsFrame(aContext, aType)
+  SVGGeometryFrame(nsStyleContext* aContext, nsIFrame::ClassID aID, mozilla::LayoutFrameType aType)
+    : nsFrame(aContext, aID, aType)
   {
      AddStateBits(NS_FRAME_SVG_LAYOUT | NS_FRAME_MAY_BE_TRANSFORMED);
   }
 
   explicit SVGGeometryFrame(nsStyleContext* aContext)
-    : SVGGeometryFrame(aContext, mozilla::LayoutFrameType::SVGGeometry)
+    : SVGGeometryFrame(aContext, kClassID, mozilla::LayoutFrameType::SVGGeometry)
   {}
 
 public:
   NS_DECL_QUERYFRAME
   NS_DECL_FRAMEARENA_HELPERS(SVGGeometryFrame)
 
   // nsIFrame interface:
   virtual void Init(nsIContent*       aContent,
--- a/layout/svg/SVGTextFrame.h
+++ b/layout/svg/SVGTextFrame.h
@@ -188,17 +188,17 @@ class SVGTextFrame final : public nsSVGD
 
   typedef gfxTextRun::Range Range;
   typedef mozilla::gfx::DrawTarget DrawTarget;
   typedef mozilla::gfx::Path Path;
   typedef mozilla::gfx::Point Point;
 
 protected:
   explicit SVGTextFrame(nsStyleContext* aContext)
-    : nsSVGDisplayContainerFrame(aContext, mozilla::LayoutFrameType::SVGText)
+    : nsSVGDisplayContainerFrame(aContext, kClassID, mozilla::LayoutFrameType::SVGText)
     , mTrailingUndisplayedCharacters(0)
     , mFontSizeScaleFactor(1.0f)
     , mLastContextScale(1.0f)
     , mLengthAdjustScaleFactor(1.0f)
   {
     AddStateBits(NS_STATE_SVG_POSITIONING_DIRTY);
   }
 
--- a/layout/svg/SVGViewFrame.cpp
+++ b/layout/svg/SVGViewFrame.cpp
@@ -19,17 +19,17 @@ using namespace mozilla::dom;
  * the view receives to the overridden <svg> element (if there is one).
  **/
 class SVGViewFrame : public nsFrame
 {
   friend nsIFrame*
   NS_NewSVGViewFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 protected:
   explicit SVGViewFrame(nsStyleContext* aContext)
-    : nsFrame(aContext, LayoutFrameType::SVGView)
+    : nsFrame(aContext, kClassID, LayoutFrameType::SVGView)
   {
     AddStateBits(NS_FRAME_IS_NONDISPLAY);
   }
 
 public:
   NS_DECL_FRAMEARENA_HELPERS(SVGViewFrame)
 
 #ifdef DEBUG
--- a/layout/svg/nsSVGAFrame.cpp
+++ b/layout/svg/nsSVGAFrame.cpp
@@ -16,17 +16,17 @@
 using namespace mozilla;
 
 class nsSVGAFrame : public nsSVGDisplayContainerFrame
 {
   friend nsIFrame*
   NS_NewSVGAFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 protected:
   explicit nsSVGAFrame(nsStyleContext* aContext)
-    : nsSVGDisplayContainerFrame(aContext, LayoutFrameType::SVGA)
+    : nsSVGDisplayContainerFrame(aContext, kClassID, LayoutFrameType::SVGA)
   {}
 
 public:
   NS_DECL_FRAMEARENA_HELPERS(nsSVGAFrame)
 
 #ifdef DEBUG
   virtual void Init(nsIContent*       aContent,
                     nsContainerFrame* aParent,
--- a/layout/svg/nsSVGClipPathFrame.h
+++ b/layout/svg/nsSVGClipPathFrame.h
@@ -20,17 +20,17 @@ class nsSVGClipPathFrame final : public 
   NS_NewSVGClipPathFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 
   typedef mozilla::gfx::Matrix Matrix;
   typedef mozilla::gfx::SourceSurface SourceSurface;
   typedef mozilla::image::imgDrawingParams imgDrawingParams;
 
 protected:
   explicit nsSVGClipPathFrame(nsStyleContext* aContext)
-    : nsSVGContainerFrame(aContext, mozilla::LayoutFrameType::SVGClipPath)
+    : nsSVGContainerFrame(aContext, kClassID, mozilla::LayoutFrameType::SVGClipPath)
     , mIsBeingProcessed(false)
   {
     AddStateBits(NS_FRAME_IS_NONDISPLAY);
   }
 
 public:
   NS_DECL_FRAMEARENA_HELPERS(nsSVGClipPathFrame)
 
--- a/layout/svg/nsSVGContainerFrame.cpp
+++ b/layout/svg/nsSVGContainerFrame.cpp
@@ -29,26 +29,25 @@ NS_QUERYFRAME_HEAD(nsSVGDisplayContainer
   NS_QUERYFRAME_ENTRY(nsSVGDisplayableFrame)
 NS_QUERYFRAME_TAIL_INHERITING(nsSVGContainerFrame)
 
 nsIFrame*
 NS_NewSVGContainerFrame(nsIPresShell* aPresShell,
                         nsStyleContext* aContext)
 {
   nsIFrame* frame =
-    new (aPresShell) nsSVGContainerFrame(aContext, LayoutFrameType::None);
+    new (aPresShell) nsSVGContainerFrame(aContext, nsSVGContainerFrame::kClassID, LayoutFrameType::None);
   // If we were called directly, then the frame is for a <defs> or
   // an unknown element type. In both cases we prevent the content
   // from displaying directly.
   frame->AddStateBits(NS_FRAME_IS_NONDISPLAY);
   return frame;
 }
 
 NS_IMPL_FRAMEARENA_HELPERS(nsSVGContainerFrame)
-NS_IMPL_FRAMEARENA_HELPERS(nsSVGDisplayContainerFrame)
 
 void
 nsSVGContainerFrame::AppendFrames(ChildListID  aListID,
                                   nsFrameList& aFrameList)
 {
   InsertFrames(aListID, mFrames.LastChild(), aFrameList);  
 }
 
--- a/layout/svg/nsSVGContainerFrame.h
+++ b/layout/svg/nsSVGContainerFrame.h
@@ -35,18 +35,18 @@ struct nsRect;
  * Do *not* blindly cast to SVG element types in this class's methods (see the
  * warning comment for nsSVGDisplayContainerFrame below). 
  */
 class nsSVGContainerFrame : public nsContainerFrame
 {
   friend nsIFrame* NS_NewSVGContainerFrame(nsIPresShell* aPresShell,
                                            nsStyleContext* aContext);
 protected:
-  nsSVGContainerFrame(nsStyleContext* aContext, mozilla::LayoutFrameType aType)
-    : nsContainerFrame(aContext, aType)
+  nsSVGContainerFrame(nsStyleContext* aContext, ClassID aID, mozilla::LayoutFrameType aType)
+    : nsContainerFrame(aContext, aID, aType)
   {
     AddStateBits(NS_FRAME_SVG_LAYOUT);
   }
 
 public:
   NS_DECL_QUERYFRAME
   NS_DECL_FRAMEARENA_HELPERS(nsSVGContainerFrame)
 
@@ -105,26 +105,27 @@ protected:
  * an SVG element class since this class is inherited by
  * nsSVGGenericContainerFrame which is used for unrecognized elements in the
  * SVG namespace. Do *not* blindly cast to SVG element types.
  */
 class nsSVGDisplayContainerFrame : public nsSVGContainerFrame,
                                    public nsSVGDisplayableFrame
 {
 protected:
-  nsSVGDisplayContainerFrame(nsStyleContext* aContext,
+  nsSVGDisplayContainerFrame(nsStyleContext* aContext, nsIFrame::ClassID aID,
                              mozilla::LayoutFrameType aType)
-    : nsSVGContainerFrame(aContext, aType)
+    : nsSVGContainerFrame(aContext, aID, aType)
   {
      AddStateBits(NS_FRAME_MAY_BE_TRANSFORMED);
   }
 
 public:
   NS_DECL_QUERYFRAME
-  NS_DECL_FRAMEARENA_HELPERS(nsSVGDisplayContainerFrame)
+  NS_DECL_QUERYFRAME_TARGET(nsSVGDisplayContainerFrame)
+  NS_DECL_ABSTRACT_FRAME(nsSVGDisplayContainerFrame)
 
   // nsIFrame:
   virtual void InsertFrames(ChildListID     aListID,
                                 nsIFrame*       aPrevFrame,
                                 nsFrameList&    aFrameList) override;
   virtual void RemoveFrame(ChildListID     aListID,
                                nsIFrame*       aOldFrame) override;
  virtual void Init(nsIContent*       aContent,
--- a/layout/svg/nsSVGFilterFrame.h
+++ b/layout/svg/nsSVGFilterFrame.h
@@ -28,17 +28,17 @@ class SVGFilterElement;
 } // namespace mozilla
 
 class nsSVGFilterFrame : public nsSVGContainerFrame
 {
   friend nsIFrame*
   NS_NewSVGFilterFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 protected:
   explicit nsSVGFilterFrame(nsStyleContext* aContext)
-    : nsSVGContainerFrame(aContext, mozilla::LayoutFrameType::SVGFilter)
+    : nsSVGContainerFrame(aContext, kClassID, mozilla::LayoutFrameType::SVGFilter)
     , mLoopFlag(false)
     , mNoHRefURI(false)
   {
     AddStateBits(NS_FRAME_IS_NONDISPLAY);
   }
 
 public:
   NS_DECL_FRAMEARENA_HELPERS(nsSVGFilterFrame)
--- a/layout/svg/nsSVGForeignObjectFrame.cpp
+++ b/layout/svg/nsSVGForeignObjectFrame.cpp
@@ -35,17 +35,17 @@ NS_NewSVGForeignObjectFrame(nsIPresShell
                             nsStyleContext *aContext)
 {
   return new (aPresShell) nsSVGForeignObjectFrame(aContext);
 }
 
 NS_IMPL_FRAMEARENA_HELPERS(nsSVGForeignObjectFrame)
 
 nsSVGForeignObjectFrame::nsSVGForeignObjectFrame(nsStyleContext* aContext)
-  : nsContainerFrame(aContext, LayoutFrameType::SVGForeignObject)
+  : nsContainerFrame(aContext, kClassID, LayoutFrameType::SVGForeignObject)
   , mInReflow(false)
 {
   AddStateBits(NS_FRAME_REFLOW_ROOT | NS_FRAME_MAY_BE_TRANSFORMED |
                NS_FRAME_SVG_LAYOUT);
 }
 
 //----------------------------------------------------------------------
 // nsIFrame methods
--- a/layout/svg/nsSVGGFrame.h
+++ b/layout/svg/nsSVGGFrame.h
@@ -11,22 +11,22 @@
 #include "nsAutoPtr.h"
 #include "nsSVGContainerFrame.h"
 
 class nsSVGGFrame : public nsSVGDisplayContainerFrame
 {
   friend nsIFrame*
   NS_NewSVGGFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 protected:
-  nsSVGGFrame(nsStyleContext* aContext, mozilla::LayoutFrameType aType)
-    : nsSVGDisplayContainerFrame(aContext, aType)
+  nsSVGGFrame(nsStyleContext* aContext, nsIFrame::ClassID aID, mozilla::LayoutFrameType aType)
+    : nsSVGDisplayContainerFrame(aContext, aID, aType)
   {}
 
-  explicit nsSVGGFrame(nsStyleContext* aContext)
-    : nsSVGGFrame(aContext, mozilla::LayoutFrameType::SVGG)
+  explicit nsSVGGFrame(nsStyleContext* aContext, nsIFrame::ClassID aID = kClassID)
+    : nsSVGGFrame(aContext, aID, mozilla::LayoutFrameType::SVGG)
   {}
 
 public:
   NS_DECL_FRAMEARENA_HELPERS(nsSVGGFrame)
 
 #ifdef DEBUG
   virtual void Init(nsIContent*       aContent,
                     nsContainerFrame* aParent,
--- a/layout/svg/nsSVGGenericContainerFrame.h
+++ b/layout/svg/nsSVGGenericContainerFrame.h
@@ -20,17 +20,17 @@ class nsStyleContext;
 
 class nsSVGGenericContainerFrame final : public nsSVGDisplayContainerFrame
 {
   friend nsIFrame*
   NS_NewSVGGenericContainerFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 
 protected:
   explicit nsSVGGenericContainerFrame(nsStyleContext* aContext)
-    : nsSVGDisplayContainerFrame(aContext,
+    : nsSVGDisplayContainerFrame(aContext, kClassID,
                                  mozilla::LayoutFrameType::SVGGenericContainer)
   {}
 
 public:
   NS_DECL_FRAMEARENA_HELPERS(nsSVGGenericContainerFrame)
 
   // nsIFrame:
   virtual nsresult  AttributeChanged(int32_t         aNameSpaceID,
--- a/layout/svg/nsSVGGradientFrame.cpp
+++ b/layout/svg/nsSVGGradientFrame.cpp
@@ -21,18 +21,19 @@
 using namespace mozilla;
 using namespace mozilla::dom;
 using namespace mozilla::gfx;
 
 //----------------------------------------------------------------------
 // Implementation
 
 nsSVGGradientFrame::nsSVGGradientFrame(nsStyleContext* aContext,
+                                       ClassID aID,
                                        LayoutFrameType aType)
-  : nsSVGPaintServerFrame(aContext, aType)
+  : nsSVGPaintServerFrame(aContext, aID, aType)
   , mSource(nullptr)
   , mLoopFlag(false)
   , mNoHRefURI(false)
 {
 }
 
 //----------------------------------------------------------------------
 // nsIFrame methods:
--- a/layout/svg/nsSVGGradientFrame.h
+++ b/layout/svg/nsSVGGradientFrame.h
@@ -35,17 +35,17 @@ class SVGRadialGradientElement;
  * Gradients can refer to other gradients. We create an nsSVGPaintingProperty
  * with property type nsGkAtoms::href to track the referenced gradient.
  */
 class nsSVGGradientFrame : public nsSVGPaintServerFrame
 {
   typedef mozilla::gfx::ExtendMode ExtendMode;
 
 protected:
-  nsSVGGradientFrame(nsStyleContext* aContext, mozilla::LayoutFrameType aType);
+  nsSVGGradientFrame(nsStyleContext* aContext, ClassID aID, mozilla::LayoutFrameType aType);
 
 public:
   NS_DECL_ABSTRACT_FRAME(nsSVGGradientFrame)
 
   // nsSVGPaintServerFrame methods:
   virtual already_AddRefed<gfxPattern>
     GetPaintServerPattern(nsIFrame *aSource,
                           const DrawTarget* aDrawTarget,
@@ -122,17 +122,17 @@ private:
 // -------------------------------------------------------------------------
 
 class nsSVGLinearGradientFrame : public nsSVGGradientFrame
 {
   friend nsIFrame* NS_NewSVGLinearGradientFrame(nsIPresShell* aPresShell,
                                                 nsStyleContext* aContext);
 protected:
   explicit nsSVGLinearGradientFrame(nsStyleContext* aContext)
-    : nsSVGGradientFrame(aContext, mozilla::LayoutFrameType::SVGLinearGradient)
+    : nsSVGGradientFrame(aContext, kClassID, mozilla::LayoutFrameType::SVGLinearGradient)
   {}
 
 public:
   NS_DECL_FRAMEARENA_HELPERS(nsSVGLinearGradientFrame)
 
   // nsIFrame interface:
 #ifdef DEBUG
   virtual void Init(nsIContent*       aContent,
@@ -164,17 +164,17 @@ protected:
 // -------------------------------------------------------------------------
 
 class nsSVGRadialGradientFrame : public nsSVGGradientFrame
 {
   friend nsIFrame* NS_NewSVGRadialGradientFrame(nsIPresShell* aPresShell,
                                                 nsStyleContext* aContext);
 protected:
   explicit nsSVGRadialGradientFrame(nsStyleContext* aContext)
-    : nsSVGGradientFrame(aContext, mozilla::LayoutFrameType::SVGRadialGradient)
+    : nsSVGGradientFrame(aContext, kClassID, mozilla::LayoutFrameType::SVGRadialGradient)
   {}
 
 public:
   NS_DECL_FRAMEARENA_HELPERS(nsSVGRadialGradientFrame)
 
   // nsIFrame interface:
 #ifdef DEBUG
   virtual void Init(nsIContent*       aContent,
--- a/layout/svg/nsSVGImageFrame.h
+++ b/layout/svg/nsSVGImageFrame.h
@@ -54,17 +54,17 @@ class nsSVGImageFrame final
   : public SVGGeometryFrame
   , public nsIReflowCallback
 {
   friend nsIFrame*
   NS_NewSVGImageFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 
 protected:
   explicit nsSVGImageFrame(nsStyleContext* aContext)
-    : SVGGeometryFrame(aContext, LayoutFrameType::SVGImage)
+    : SVGGeometryFrame(aContext, kClassID, LayoutFrameType::SVGImage)
     , mReflowCallbackPosted(false)
     , mForceSyncDecoding(false)
   {
     EnableVisibilityTracking();
   }
 
   virtual ~nsSVGImageFrame();
 
--- a/layout/svg/nsSVGInnerSVGFrame.h
+++ b/layout/svg/nsSVGInnerSVGFrame.h
@@ -16,17 +16,17 @@ class gfxContext;
 class nsSVGInnerSVGFrame final
   : public nsSVGDisplayContainerFrame
   , public nsISVGSVGFrame
 {
   friend nsIFrame*
   NS_NewSVGInnerSVGFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 protected:
   explicit nsSVGInnerSVGFrame(nsStyleContext* aContext)
-    : nsSVGDisplayContainerFrame(aContext,
+    : nsSVGDisplayContainerFrame(aContext, kClassID,
                                  mozilla::LayoutFrameType::SVGInnerSVG)
   {
   }
 
 public:
   NS_DECL_QUERYFRAME
   NS_DECL_FRAMEARENA_HELPERS(nsSVGInnerSVGFrame)
 
--- a/layout/svg/nsSVGMarkerFrame.h
+++ b/layout/svg/nsSVGMarkerFrame.h
@@ -30,17 +30,17 @@ class nsSVGMarkerFrame final : public ns
 {
   typedef mozilla::image::imgDrawingParams imgDrawingParams;
 
   friend class nsSVGMarkerAnonChildFrame;
   friend nsContainerFrame*
   NS_NewSVGMarkerFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 protected:
   explicit nsSVGMarkerFrame(nsStyleContext* aContext)
-    : nsSVGContainerFrame(aContext, mozilla::LayoutFrameType::SVGMarker)
+    : nsSVGContainerFrame(aContext, kClassID, mozilla::LayoutFrameType::SVGMarker)
     , mMarkedFrame(nullptr)
     , mInUse(false)
     , mInUse2(false)
   {
     AddStateBits(NS_FRAME_IS_NONDISPLAY);
   }
 
 public:
@@ -136,17 +136,17 @@ private:
 
 class nsSVGMarkerAnonChildFrame final : public nsSVGDisplayContainerFrame
 {
   friend nsContainerFrame*
   NS_NewSVGMarkerAnonChildFrame(nsIPresShell* aPresShell,
                                 nsStyleContext* aContext);
 
   explicit nsSVGMarkerAnonChildFrame(nsStyleContext* aContext)
-    : nsSVGDisplayContainerFrame(aContext,
+    : nsSVGDisplayContainerFrame(aContext, kClassID,
                                  mozilla::LayoutFrameType::SVGMarkerAnonChild)
   {}
 
 public:
   NS_DECL_FRAMEARENA_HELPERS(nsSVGMarkerAnonChildFrame)
 
 #ifdef DEBUG
   virtual void Init(nsIContent*       aContent,
--- a/layout/svg/nsSVGMaskFrame.h
+++ b/layout/svg/nsSVGMaskFrame.h
@@ -37,17 +37,17 @@ class nsSVGMaskFrame final : public nsSV
   NS_NewSVGMaskFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 
   typedef mozilla::gfx::Matrix Matrix;
   typedef mozilla::gfx::SourceSurface SourceSurface;
   typedef mozilla::image::imgDrawingParams imgDrawingParams;
 
 protected:
   explicit nsSVGMaskFrame(nsStyleContext* aContext)
-    : nsSVGContainerFrame(aContext, mozilla::LayoutFrameType::SVGMask)
+    : nsSVGContainerFrame(aContext, kClassID, mozilla::LayoutFrameType::SVGMask)
     , mInUse(false)
   {
     AddStateBits(NS_FRAME_IS_NONDISPLAY);
   }
 
 public:
   NS_DECL_FRAMEARENA_HELPERS(nsSVGMaskFrame)
 
--- a/layout/svg/nsSVGOuterSVGFrame.cpp
+++ b/layout/svg/nsSVGOuterSVGFrame.cpp
@@ -60,17 +60,17 @@ nsContainerFrame*
 NS_NewSVGOuterSVGFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
 {
   return new (aPresShell) nsSVGOuterSVGFrame(aContext);
 }
 
 NS_IMPL_FRAMEARENA_HELPERS(nsSVGOuterSVGFrame)
 
 nsSVGOuterSVGFrame::nsSVGOuterSVGFrame(nsStyleContext* aContext)
-  : nsSVGDisplayContainerFrame(aContext, LayoutFrameType::SVGOuterSVG)
+  : nsSVGDisplayContainerFrame(aContext, kClassID, LayoutFrameType::SVGOuterSVG)
   , mCallingReflowSVG(false)
   , mFullZoom(aContext->PresContext()->GetFullZoom())
   , mViewportInitialized(false)
   , mIsRootContent(false)
 {
   // Outer-<svg> has CSS layout, so remove this bit:
   RemoveStateBits(NS_FRAME_SVG_LAYOUT);
 }
--- a/layout/svg/nsSVGOuterSVGFrame.h
+++ b/layout/svg/nsSVGOuterSVGFrame.h
@@ -228,17 +228,17 @@ protected:
  */
 class nsSVGOuterSVGAnonChildFrame final : public nsSVGDisplayContainerFrame
 {
   friend nsContainerFrame*
   NS_NewSVGOuterSVGAnonChildFrame(nsIPresShell* aPresShell,
                                   nsStyleContext* aContext);
 
   explicit nsSVGOuterSVGAnonChildFrame(nsStyleContext* aContext)
-    : nsSVGDisplayContainerFrame(aContext,
+    : nsSVGDisplayContainerFrame(aContext, kClassID,
                                  mozilla::LayoutFrameType::SVGOuterSVGAnonChild)
   {}
 
 public:
   NS_DECL_FRAMEARENA_HELPERS(nsSVGOuterSVGAnonChildFrame)
 
 #ifdef DEBUG
   virtual void Init(nsIContent*       aContent,
--- a/layout/svg/nsSVGPaintServerFrame.h
+++ b/layout/svg/nsSVGPaintServerFrame.h
@@ -52,19 +52,19 @@ private:
   MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
 };
 
 class nsSVGPaintServerFrame : public nsSVGContainerFrame
 {
 protected:
   typedef mozilla::gfx::DrawTarget DrawTarget;
 
-  explicit nsSVGPaintServerFrame(nsStyleContext* aContext,
+  explicit nsSVGPaintServerFrame(nsStyleContext* aContext, ClassID aID,
                                  mozilla::LayoutFrameType aType)
-    : nsSVGContainerFrame(aContext, aType)
+    : nsSVGContainerFrame(aContext, aID, aType)
   {
     AddStateBits(NS_FRAME_IS_NONDISPLAY);
   }
 
 public:
   typedef mozilla::image::imgDrawingParams imgDrawingParams;
 
   NS_DECL_ABSTRACT_FRAME(nsSVGPaintServerFrame)
--- a/layout/svg/nsSVGPatternFrame.cpp
+++ b/layout/svg/nsSVGPatternFrame.cpp
@@ -29,17 +29,17 @@ using namespace mozilla;
 using namespace mozilla::dom;
 using namespace mozilla::gfx;
 using namespace mozilla::image;
 
 //----------------------------------------------------------------------
 // Implementation
 
 nsSVGPatternFrame::nsSVGPatternFrame(nsStyleContext* aContext)
-  : nsSVGPaintServerFrame(aContext, LayoutFrameType::SVGPattern)
+  : nsSVGPaintServerFrame(aContext, kClassID, LayoutFrameType::SVGPattern)
   , mSource(nullptr)
   , mLoopFlag(false)
   , mNoHRefURI(false)
 {
 }
 
 NS_IMPL_FRAMEARENA_HELPERS(nsSVGPatternFrame)
 
--- a/layout/svg/nsSVGStopFrame.cpp
+++ b/layout/svg/nsSVGStopFrame.cpp
@@ -15,17 +15,17 @@
 // within the nsSVGGradientFrame, which is the parent for this frame
 
 class nsSVGStopFrame : public nsFrame
 {
   friend nsIFrame*
   NS_NewSVGStopFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 protected:
   explicit nsSVGStopFrame(nsStyleContext* aContext)
-    : nsFrame(aContext, LayoutFrameType::SVGStop)
+    : nsFrame(aContext, kClassID, LayoutFrameType::SVGStop)
   {
     AddStateBits(NS_FRAME_IS_NONDISPLAY);
   }
 
 public:
   NS_DECL_FRAMEARENA_HELPERS(nsSVGStopFrame)
 
   // nsIFrame interface:
--- a/layout/svg/nsSVGSwitchFrame.cpp
+++ b/layout/svg/nsSVGSwitchFrame.cpp
@@ -14,17 +14,17 @@ using namespace mozilla::gfx;
 using namespace mozilla::image;
 
 class nsSVGSwitchFrame final : public nsSVGGFrame
 {
   friend nsIFrame*
   NS_NewSVGSwitchFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 protected:
   explicit nsSVGSwitchFrame(nsStyleContext* aContext)
-    : nsSVGGFrame(aContext, LayoutFrameType::SVGSwitch)
+    : nsSVGGFrame(aContext, kClassID, LayoutFrameType::SVGSwitch)
   {}
 
 public:
   NS_DECL_FRAMEARENA_HELPERS(nsSVGSwitchFrame)
 
 #ifdef DEBUG
   virtual void Init(nsIContent*       aContent,
                     nsContainerFrame* aParent,
--- a/layout/svg/nsSVGUseFrame.cpp
+++ b/layout/svg/nsSVGUseFrame.cpp
@@ -16,17 +16,17 @@ class nsSVGUseFrame final
   : public nsSVGGFrame
   , public nsIAnonymousContentCreator
 {
   friend nsIFrame*
   NS_NewSVGUseFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 
 protected:
   explicit nsSVGUseFrame(nsStyleContext* aContext)
-    : nsSVGGFrame(aContext, LayoutFrameType::SVGUse)
+    : nsSVGGFrame(aContext, kClassID, LayoutFrameType::SVGUse)
     , mHasValidDimensions(true)
   {}
 
 public:
   NS_DECL_QUERYFRAME
   NS_DECL_FRAMEARENA_HELPERS(nsSVGUseFrame)
 
   // nsIFrame interface:
--- a/layout/tables/nsTableCellFrame.cpp
+++ b/layout/tables/nsTableCellFrame.cpp
@@ -38,18 +38,19 @@
 #include "mozilla/LookAndFeel.h"
 
 using namespace mozilla;
 using namespace mozilla::gfx;
 using namespace mozilla::image;
 
 nsTableCellFrame::nsTableCellFrame(nsStyleContext* aContext,
                                    nsTableFrame* aTableFrame,
+                                   ClassID aID,
                                    LayoutFrameType aType)
-  : nsContainerFrame(aContext, aType)
+  : nsContainerFrame(aContext, aID, aType)
   , mDesiredSize(aTableFrame->GetWritingMode())
 {
   mColIndex = 0;
   mPriorAvailISize = 0;
 
   SetContentEmpty(false);
   SetHasPctOverBSize(false);
 }
@@ -1081,17 +1082,17 @@ nsTableCellFrame::GetFrameName(nsAString
   return MakeFrameName(NS_LITERAL_STRING("TableCell"), aResult);
 }
 #endif
 
 // nsBCTableCellFrame
 
 nsBCTableCellFrame::nsBCTableCellFrame(nsStyleContext* aContext,
                                        nsTableFrame* aTableFrame)
-  : nsTableCellFrame(aContext, aTableFrame, LayoutFrameType::BCTableCell)
+  : nsTableCellFrame(aContext, aTableFrame, kClassID, LayoutFrameType::BCTableCell)
 {
   mBStartBorder = mIEndBorder = mBEndBorder = mIStartBorder = 0;
 }
 
 nsBCTableCellFrame::~nsBCTableCellFrame()
 {
 }
 
--- a/layout/tables/nsTableCellFrame.h
+++ b/layout/tables/nsTableCellFrame.h
@@ -43,19 +43,19 @@ protected:
   typedef mozilla::LogicalMargin LogicalMargin;
 
 public:
   NS_DECL_QUERYFRAME
   NS_DECL_FRAMEARENA_HELPERS(nsTableCellFrame)
 
   // default constructor supplied by the compiler
 
-  nsTableCellFrame(nsStyleContext* aContext, nsTableFrame* aTableFrame)
-    : nsTableCellFrame(aContext,
-                       aTableFrame,
+  nsTableCellFrame(nsStyleContext* aContext, nsTableFrame* aTableFrame,
+                   ClassID aID = kClassID)
+    : nsTableCellFrame(aContext, aTableFrame, aID,
                        mozilla::LayoutFrameType::TableCell)
   {}
 
   ~nsTableCellFrame();
 
   nsTableRowFrame* GetTableRowFrame() const
   {
     nsIFrame* parent = GetParent();
@@ -229,16 +229,17 @@ public:
   
   virtual void InvalidateFrame(uint32_t aDisplayItemKey = 0) override;
   virtual void InvalidateFrameWithRect(const nsRect& aRect, uint32_t aDisplayItemKey = 0) override;
   virtual void InvalidateFrameForRemoval() override { InvalidateFrameSubtree(); }
 
 protected:
   nsTableCellFrame(nsStyleContext* aContext,
                    nsTableFrame* aTableFrame,
+                   ClassID aID,
                    mozilla::LayoutFrameType aType);
 
   virtual LogicalSides
   GetLogicalSkipSides(const ReflowInput* aReflowInput = nullptr) const override;
 
   /**
    * GetBorderOverflow says how far the cell's own borders extend
    * outside its own bounds.  In the separated borders model this should
--- a/layout/tables/nsTableColFrame.cpp
+++ b/layout/tables/nsTableColFrame.cpp
@@ -19,17 +19,17 @@ using namespace mozilla;
                                        NS_FRAME_STATE_BIT(29) | \
                                        NS_FRAME_STATE_BIT(30) | \
                                        NS_FRAME_STATE_BIT(31))
 #define COL_TYPE_OFFSET               28
 
 using namespace mozilla;
 
 nsTableColFrame::nsTableColFrame(nsStyleContext* aContext)
-  : nsSplittableFrame(aContext, LayoutFrameType::TableCol)
+  : nsSplittableFrame(aContext, kClassID, LayoutFrameType::TableCol)
   , mMinCoord(0)
   , mPrefCoord(0)
   , mSpanMinCoord(0)
   , mSpanPrefCoord(0)
   , mPrefPercent(0.0f)
   , mSpanPrefPercent(0.0f)
   , mFinalISize(0)
   , mColIndex(0)
--- a/layout/tables/nsTableColGroupFrame.h
+++ b/layout/tables/nsTableColGroupFrame.h
@@ -216,17 +216,17 @@ protected:
   int32_t mStartColIndex;
 
   // border width in pixels
   BCPixelSize mBStartContBorderWidth;
   BCPixelSize mBEndContBorderWidth;
 };
 
 inline nsTableColGroupFrame::nsTableColGroupFrame(nsStyleContext* aContext)
-  : nsContainerFrame(aContext, mozilla::LayoutFrameType::TableColGroup)
+  : nsContainerFrame(aContext, kClassID, mozilla::LayoutFrameType::TableColGroup)
   , mColCount(0)
   , mStartColIndex(0)
 {
   SetColType(eColGroupContent);
 }
 
 inline int32_t nsTableColGroupFrame::GetStartColumnIndex()
 {
--- a/layout/tables/nsTableFrame.cpp
+++ b/layout/tables/nsTableFrame.cpp
@@ -141,18 +141,18 @@ nsTableFrame::GetParentStyleContext(nsIF
     // We're the root.  We have no style context parent.
     *aProviderFrame = nullptr;
     return nullptr;
   }
 
   return GetParent()->DoGetParentStyleContext(aProviderFrame);
 }
 
-nsTableFrame::nsTableFrame(nsStyleContext* aContext)
-  : nsContainerFrame(aContext, LayoutFrameType::Table)
+nsTableFrame::nsTableFrame(nsStyleContext* aContext, ClassID aID)
+  : nsContainerFrame(aContext, aID, LayoutFrameType::Table)
   , mCellMap(nullptr)
   , mTableLayoutStrategy(nullptr)
 {
   memset(&mBits, 0, sizeof(mBits));
 }
 
 void
 nsTableFrame::Init(nsIContent*       aContent,
--- a/layout/tables/nsTableFrame.h
+++ b/layout/tables/nsTableFrame.h
@@ -598,17 +598,17 @@ public:
     mozilla::ServoStyleSet& aStyleSet,
     nsStyleChangeList& aChangeList,
     nsChangeHint aHintForThisFrame) override;
 protected:
 
   /** protected constructor.
     * @see NewFrame
     */
-  explicit nsTableFrame(nsStyleContext* aContext);
+  explicit nsTableFrame(nsStyleContext* aContext, ClassID aID = kClassID);
 
   /** destructor, responsible for mColumnLayoutData */
   virtual ~nsTableFrame();
 
   void InitChildReflowInput(ReflowInput& aReflowInput);
 
   virtual LogicalSides GetLogicalSkipSides(const ReflowInput* aReflowInput = nullptr) const override;
 
--- a/layout/tables/nsTableRowFrame.cpp
+++ b/layout/tables/nsTableRowFrame.cpp
@@ -124,18 +124,18 @@ nsTableRowFrame::SetPctBSize(float aPctV
 }
 
 /* ----------- nsTableRowFrame ---------- */
 
 NS_QUERYFRAME_HEAD(nsTableRowFrame)
   NS_QUERYFRAME_ENTRY(nsTableRowFrame)
 NS_QUERYFRAME_TAIL_INHERITING(nsContainerFrame)
 
-nsTableRowFrame::nsTableRowFrame(nsStyleContext* aContext)
-  : nsContainerFrame(aContext, LayoutFrameType::TableRow)
+nsTableRowFrame::nsTableRowFrame(nsStyleContext* aContext, ClassID aID)
+  : nsContainerFrame(aContext, aID, LayoutFrameType::TableRow)
   , mContentBSize(0)
   , mStylePctBSize(0)
   , mStyleFixedBSize(0)
   , mMaxCellAscent(0)
   , mMaxCellDescent(0)
   , mBStartBorderWidth(0)
   , mBEndBorderWidth(0)
   , mIEndContBorderWidth(0)
--- a/layout/tables/nsTableRowFrame.h
+++ b/layout/tables/nsTableRowFrame.h
@@ -249,17 +249,17 @@ public:
   virtual mozilla::a11y::AccType AccessibleType() override;
 #endif
 
 protected:
 
   /** protected constructor.
     * @see NewFrame
     */
-  explicit nsTableRowFrame(nsStyleContext *aContext);
+  explicit nsTableRowFrame(nsStyleContext* aContext, ClassID aID = kClassID);
 
   void InitChildReflowInput(nsPresContext&              aPresContext,
                             const mozilla::LogicalSize& aAvailSize,
                             bool                        aBorderCollapse,
                             TableCellReflowInput&     aReflowInput);
   
   virtual LogicalSides GetLogicalSkipSides(const ReflowInput* aReflowInput = nullptr) const override;
 
--- a/layout/tables/nsTableRowGroupFrame.cpp
+++ b/layout/tables/nsTableRowGroupFrame.cpp
@@ -49,17 +49,17 @@ struct TableRowGroupReflowInput {
   }
 
   ~TableRowGroupReflowInput() {}
 };
 
 } // namespace mozilla
 
 nsTableRowGroupFrame::nsTableRowGroupFrame(nsStyleContext* aContext)
-  : nsContainerFrame(aContext, LayoutFrameType::TableRowGroup)
+  : nsContainerFrame(aContext, kClassID, LayoutFrameType::TableRowGroup)
 {
   SetRepeatable(false);
 }
 
 nsTableRowGroupFrame::~nsTableRowGroupFrame()
 {
 }
 
--- a/layout/tables/nsTableWrapperFrame.cpp
+++ b/layout/tables/nsTableWrapperFrame.cpp
@@ -37,18 +37,18 @@ nsTableWrapperFrame::GetLogicalBaseline(
     NS_NOTREACHED("no inner table");
     return nsContainerFrame::GetLogicalBaseline(aWritingMode);
   }
 
   return kid->GetLogicalBaseline(aWritingMode) +
          kid->BStart(aWritingMode, mRect.Size());
 }
 
-nsTableWrapperFrame::nsTableWrapperFrame(nsStyleContext* aContext)
-  : nsContainerFrame(aContext, LayoutFrameType::TableWrapper)
+nsTableWrapperFrame::nsTableWrapperFrame(nsStyleContext* aContext, ClassID aID)
+  : nsContainerFrame(aContext, aID, LayoutFrameType::TableWrapper)
 {
 }
 
 nsTableWrapperFrame::~nsTableWrapperFrame()
 {
 }
 
 NS_QUERYFRAME_HEAD(nsTableWrapperFrame)
--- a/layout/tables/nsTableWrapperFrame.h
+++ b/layout/tables/nsTableWrapperFrame.h
@@ -191,17 +191,17 @@ public:
 
   /**
    * The CB size to use for the inner table frame if we're a grid item.
    */
   NS_DECLARE_FRAME_PROPERTY_DELETABLE(GridItemCBSizeProperty, mozilla::LogicalSize);
 
 protected:
 
-  explicit nsTableWrapperFrame(nsStyleContext* aContext);
+  explicit nsTableWrapperFrame(nsStyleContext* aContext, ClassID aID = kClassID);
   virtual ~nsTableWrapperFrame();
 
   void InitChildReflowInput(nsPresContext&     aPresContext,
                             ReflowInput& aReflowInput);
 
   // Get a NS_STYLE_CAPTION_SIDE_* value, or NO_SIDE if no caption is present.
   // (Remember that caption-side values are interpreted logically, despite
   // having "physical" names.)
--- a/layout/xul/grid/nsGridRowGroupFrame.h
+++ b/layout/xul/grid/nsGridRowGroupFrame.h
@@ -32,17 +32,17 @@ public:
   virtual nsresult GetFrameName(nsAString& aResult) const override
   {
       return MakeFrameName(NS_LITERAL_STRING("nsGridRowGroup"), aResult);
   }
 #endif
 
   nsGridRowGroupFrame(nsStyleContext* aContext,
                       nsBoxLayout* aLayoutManager):
-    nsBoxFrame(aContext, false, aLayoutManager) {}
+    nsBoxFrame(aContext, kClassID, false, aLayoutManager) {}
 
   virtual nscoord GetXULFlex() override;
 
 }; // class nsGridRowGroupFrame
 
 
 
 #endif
--- a/layout/xul/grid/nsGridRowLeafFrame.h
+++ b/layout/xul/grid/nsGridRowLeafFrame.h
@@ -36,18 +36,19 @@ public:
   virtual nsresult GetFrameName(nsAString& aResult) const override
   {
       return MakeFrameName(NS_LITERAL_STRING("nsGridRowLeaf"), aResult);
   }
 #endif
 
   nsGridRowLeafFrame(nsStyleContext* aContext,
                      bool aIsRoot,
-                     nsBoxLayout* aLayoutManager):
-    nsBoxFrame(aContext, aIsRoot, aLayoutManager) {}
+                     nsBoxLayout* aLayoutManager,
+                     ClassID aID = kClassID) :
+    nsBoxFrame(aContext, aID, aIsRoot, aLayoutManager) {}
 
   virtual nsresult GetXULBorderAndPadding(nsMargin& aBorderAndPadding) override;
 
 }; // class nsGridRowLeafFrame
 
 
 
 #endif
--- a/layout/xul/nsBox.cpp
+++ b/layout/xul/nsBox.cpp
@@ -171,18 +171,18 @@ nsBox::EndXULLayout(nsBoxLayoutState& aS
   #endif
 
   return SyncLayout(aState);
 }
 
 bool nsBox::gGotTheme = false;
 nsITheme* nsBox::gTheme = nullptr;
 
-nsBox::nsBox(LayoutFrameType aType)
-  : nsIFrame(aType)
+nsBox::nsBox(ClassID aID, LayoutFrameType aType)
+  : nsIFrame(aID, aType)
 {
   MOZ_COUNT_CTOR(nsBox);
   //mX = 0;
   //mY = 0;
   if (!gGotTheme) {
     gGotTheme = true;
     CallGetService("@mozilla.org/chrome/chrome-native-theme;1", &gTheme);
   }
--- a/layout/xul/nsBox.h
+++ b/layout/xul/nsBox.h
@@ -45,17 +45,17 @@ public:
   NS_IMETHOD GetDebugBoxAt(const nsPoint& aPoint, nsIFrame** aBox);
   virtual nsresult GetXULDebug(bool& aDebug) override;
   virtual nsresult SetXULDebug(nsBoxLayoutState& aState, bool aDebug) override;
 
   virtual nsresult XULDumpBox(FILE* out) override;
   void PropagateDebug(nsBoxLayoutState& aState);
 #endif
 
-  explicit nsBox(mozilla::LayoutFrameType);
+  nsBox(ClassID aID, mozilla::LayoutFrameType);
   virtual ~nsBox();
 
   /**
    * Returns true if this box clips its children, e.g., if this box is an sc
 rollbox.
   */
   virtual bool DoesClipChildren();
   virtual bool ComputesOwnOverflowArea() = 0;
--- a/layout/xul/nsBoxFrame.cpp
+++ b/layout/xul/nsBoxFrame.cpp
@@ -93,17 +93,18 @@ using namespace mozilla::gfx;
 #ifdef DEBUG_LAYOUT
 bool nsBoxFrame::gDebug = false;
 nsIFrame* nsBoxFrame::mDebugChild = nullptr;
 #endif
 
 nsIFrame*
 NS_NewBoxFrame(nsIPresShell* aPresShell, nsStyleContext* aContext, bool aIsRoot, nsBoxLayout* aLayoutManager)
 {
-  return new (aPresShell) nsBoxFrame(aContext, aIsRoot, aLayoutManager);
+  return new (aPresShell) nsBoxFrame(aContext, nsBoxFrame::kClassID,
+                                     aIsRoot, aLayoutManager);
 }
 
 nsIFrame*
 NS_NewBoxFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
 {
   return new (aPresShell) nsBoxFrame(aContext);
 }
 
@@ -111,20 +112,21 @@ NS_IMPL_FRAMEARENA_HELPERS(nsBoxFrame)
 
 #ifdef DEBUG
 NS_QUERYFRAME_HEAD(nsBoxFrame)
   NS_QUERYFRAME_ENTRY(nsBoxFrame)
 NS_QUERYFRAME_TAIL_INHERITING(nsContainerFrame)
 #endif
 
 nsBoxFrame::nsBoxFrame(nsStyleContext* aContext,
+                       ClassID aID,
                        LayoutFrameType aType,
                        bool aIsRoot,
                        nsBoxLayout* aLayoutManager)
-  : nsContainerFrame(aContext, aType)
+  : nsContainerFrame(aContext, aID, aType)
   , mFlex(0)
   , mAscent(0)
 {
   mState |= NS_STATE_IS_HORIZONTAL;
   mState |= NS_STATE_AUTO_STRETCH;
 
   if (aIsRoot)
      mState |= NS_STATE_IS_ROOT;
--- a/layout/xul/nsBoxFrame.h
+++ b/layout/xul/nsBoxFrame.h
@@ -136,19 +136,20 @@ public:
                          const ReflowInput* aReflowInput,
                          nsDidReflowStatus        aStatus) override;
 
   virtual bool HonorPrintBackgroundSettings() override;
 
   virtual ~nsBoxFrame();
 
   explicit nsBoxFrame(nsStyleContext* aContext,
+                      ClassID aID = kClassID,
                       bool aIsRoot = false,
                       nsBoxLayout* aLayoutManager = nullptr)
-    : nsBoxFrame(aContext,
+    : nsBoxFrame(aContext, aID,
                  mozilla::LayoutFrameType::Box,
                  aIsRoot,
                  aLayoutManager)
   {}
 
   // virtual so nsStackFrame, nsButtonBoxFrame, nsSliderFrame and nsMenuFrame
   // can override it
   virtual void BuildDisplayListForChildren(nsDisplayListBuilder*   aBuilder,
@@ -179,16 +180,17 @@ public:
   /**
    * This defaults to true, but some box frames (nsListBoxBodyFrame for
    * example) don't support ordinals in their children.
    */
   virtual bool SupportsOrdinalsInChildren();
 
 protected:
   nsBoxFrame(nsStyleContext* aContext,
+             ClassID aID,
              mozilla::LayoutFrameType aType,
              bool aIsRoot = false,
              nsBoxLayout* aLayoutManager = nullptr);
 
 #ifdef DEBUG_LAYOUT
     virtual void GetBoxName(nsAutoString& aName) override;
     void PaintXULDebugBackground(nsRenderingContext& aRenderingContext,
                                  nsPoint aPt);
--- a/layout/xul/nsButtonBoxFrame.cpp
+++ b/layout/xul/nsButtonBoxFrame.cpp
@@ -54,18 +54,18 @@ nsButtonBoxFrame::nsButtonBoxListener::H
 nsIFrame*
 NS_NewButtonBoxFrame (nsIPresShell* aPresShell, nsStyleContext* aContext)
 {
   return new (aPresShell) nsButtonBoxFrame(aContext);
 }
 
 NS_IMPL_FRAMEARENA_HELPERS(nsButtonBoxFrame)
 
-nsButtonBoxFrame::nsButtonBoxFrame(nsStyleContext* aContext) :
-  nsBoxFrame(aContext, false),
+nsButtonBoxFrame::nsButtonBoxFrame(nsStyleContext* aContext, ClassID aID) :
+  nsBoxFrame(aContext, aID, false),
   mButtonBoxListener(nullptr),
   mIsHandlingKeyEvent(false)
 {
   UpdateMouseThrough();
 }
 
 void
 nsButtonBoxFrame::Init(nsIContent*       aContent,
--- a/layout/xul/nsButtonBoxFrame.h
+++ b/layout/xul/nsButtonBoxFrame.h
@@ -11,17 +11,17 @@
 
 class nsButtonBoxFrame : public nsBoxFrame
 {
 public:
   NS_DECL_FRAMEARENA_HELPERS(nsButtonBoxFrame)
 
   friend nsIFrame* NS_NewButtonBoxFrame(nsIPresShell* aPresShell);
 
-  explicit nsButtonBoxFrame(nsStyleContext* aContext);
+  explicit nsButtonBoxFrame(nsStyleContext* aContext, ClassID = kClassID);
 
   virtual void Init(nsIContent*       aContent,
                     nsContainerFrame* aParent,
                     nsIFrame*         aPrevInFlow) override;
 
   virtual void BuildDisplayListForChildren(nsDisplayListBuilder*   aBuilder,
                                            const nsRect&           aDirtyRect,
                                            const nsDisplayListSet& aLists) override;
--- a/layout/xul/nsDeckFrame.cpp
+++ b/layout/xul/nsDeckFrame.cpp
@@ -39,17 +39,17 @@ NS_NewDeckFrame(nsIPresShell* aPresShell
 
 NS_IMPL_FRAMEARENA_HELPERS(nsDeckFrame)
 
 NS_QUERYFRAME_HEAD(nsDeckFrame)
   NS_QUERYFRAME_ENTRY(nsDeckFrame)
 NS_QUERYFRAME_TAIL_INHERITING(nsBoxFrame)
 
 nsDeckFrame::nsDeckFrame(nsStyleContext* aContext)
-  : nsBoxFrame(aContext, LayoutFrameType::Deck)
+  : nsBoxFrame(aContext, kClassID, LayoutFrameType::Deck)
   , mIndex(0)
 {
   nsCOMPtr<nsBoxLayout> layout;
   NS_NewStackLayout(layout);
   SetXULLayoutManager(layout);
 }
 
 nsresult
--- a/layout/xul/nsDocElementBoxFrame.cpp
+++ b/layout/xul/nsDocElementBoxFrame.cpp
@@ -31,17 +31,17 @@ class nsDocElementBoxFrame final : publi
 {
 public:
   virtual void DestroyFrom(nsIFrame* aDestructRoot) override;
 
   friend nsIFrame* NS_NewBoxFrame(nsIPresShell* aPresShell,
                                   nsStyleContext* aContext);
 
   explicit nsDocElementBoxFrame(nsStyleContext* aContext)
-    :nsBoxFrame(aContext, true) {}
+    :nsBoxFrame(aContext, kClassID, true) {}
 
   NS_DECL_QUERYFRAME
   NS_DECL_FRAMEARENA_HELPERS(nsDocElementBoxFrame)
 
   // nsIAnonymousContentCreator
   virtual nsresult CreateAnonymousContent(nsTArray<ContentInfo>& aElements) override;
   virtual void AppendAnonymousContentTo(nsTArray<nsIContent*>& aElements,
                                         uint32_t aFilter) override;
--- a/layout/xul/nsGroupBoxFrame.cpp
+++ b/layout/xul/nsGroupBoxFrame.cpp
@@ -19,17 +19,17 @@ using namespace mozilla::gfx;
 using namespace mozilla::image;
 
 class nsGroupBoxFrame final : public nsBoxFrame
 {
 public:
   NS_DECL_FRAMEARENA_HELPERS(nsGroupBoxFrame)
 
   explicit nsGroupBoxFrame(nsStyleContext* aContext):
-    nsBoxFrame(aContext) {}
+    nsBoxFrame(aContext, kClassID) {}
 
   virtual nsresult GetXULBorderAndPadding(nsMargin& aBorderAndPadding) override;
 
   virtual void BuildDisplayList(nsDisplayListBuilder*   aBuilder,
                                 const nsRect&           aDirtyRect,
                                 const nsDisplayListSet& aLists) override;
 
 #ifdef DEBUG_FRAME_DUMP
--- a/layout/xul/nsImageBoxFrame.cpp
+++ b/layout/xul/nsImageBoxFrame.cpp
@@ -146,17 +146,17 @@ nsImageBoxFrame::AttributeChanged(int32_
   }
   else if (aAttribute == nsGkAtoms::validate)
     UpdateLoadFlags();
 
   return rv;
 }
 
 nsImageBoxFrame::nsImageBoxFrame(nsStyleContext* aContext)
-  : nsLeafBoxFrame(aContext, LayoutFrameType::ImageBox)
+  : nsLeafBoxFrame(aContext, kClassID, LayoutFrameType::ImageBox)
   , mIntrinsicSize(0, 0)
   , mLoadFlags(nsIRequest::LOAD_NORMAL)
   , mRequestRegistered(false)
   , mUseSrcAttr(false)
   , mSuppressStyleCheck(false)
 {
   MarkIntrinsicISizesDirty();
 }
--- a/layout/xul/nsLeafBoxFrame.cpp
+++ b/layout/xul/nsLeafBoxFrame.cpp
@@ -35,18 +35,18 @@ using namespace mozilla;
 nsIFrame*
 NS_NewLeafBoxFrame (nsIPresShell* aPresShell, nsStyleContext* aContext)
 {
   return new (aPresShell) nsLeafBoxFrame(aContext);
 }
 
 NS_IMPL_FRAMEARENA_HELPERS(nsLeafBoxFrame)
 
-nsLeafBoxFrame::nsLeafBoxFrame(nsStyleContext* aContext, LayoutFrameType aType)
-  : nsLeafFrame(aContext, aType)
+nsLeafBoxFrame::nsLeafBoxFrame(nsStyleContext* aContext, ClassID aID, LayoutFrameType aType)
+  : nsLeafFrame(aContext, aID, aType)
 {
 }
 
 #ifdef DEBUG_LAYOUT
 void
 nsLeafBoxFrame::GetBoxName(nsAutoString& aName)
 {
    GetFrameName(aName);
--- a/layout/xul/nsLeafBoxFrame.h
+++ b/layout/xul/nsLeafBoxFrame.h
@@ -77,21 +77,21 @@ protected:
   NS_IMETHOD DoXULLayout(nsBoxLayoutState& aState) override;
 
 #ifdef DEBUG_LAYOUT
   virtual void GetBoxName(nsAutoString& aName) override;
 #endif
 
   virtual nscoord GetIntrinsicISize() override;
 
-  explicit nsLeafBoxFrame(nsStyleContext* aContext)
-    : nsLeafBoxFrame(aContext, mozilla::LayoutFrameType::LeafBox)
+  explicit nsLeafBoxFrame(nsStyleContext* aContext, ClassID aID = kClassID)
+    : nsLeafBoxFrame(aContext, aID, mozilla::LayoutFrameType::LeafBox)
   {}
 
-  nsLeafBoxFrame(nsStyleContext* aContext, mozilla::LayoutFrameType aType);
+  nsLeafBoxFrame(nsStyleContext* aContext, ClassID aID, mozilla::LayoutFrameType aType);
 
 private:
 
  void UpdateMouseThrough();
 
 
 }; // class nsLeafBoxFrame
 
--- a/layout/xul/nsListBoxBodyFrame.cpp
+++ b/layout/xul/nsListBoxBodyFrame.cpp
@@ -146,17 +146,17 @@ nsListScrollSmoother::Stop()
     mRepeatTimer = nullptr;
   }
 }
 
 /////////////// nsListBoxBodyFrame //////////////////
 
 nsListBoxBodyFrame::nsListBoxBodyFrame(nsStyleContext* aContext,
                                        nsBoxLayout* aLayoutManager)
-  : nsBoxFrame(aContext, false, aLayoutManager),
+  : nsBoxFrame(aContext, kClassID, false, aLayoutManager),
     mTopFrame(nullptr),
     mBottomFrame(nullptr),
     mLinkupFrame(nullptr),
     mScrollSmoother(nullptr),
     mRowsToPrepend(0),
     mRowCount(-1),
     mRowHeight(0),
     mAvailableHeight(0),
--- a/layout/xul/nsListItemFrame.cpp
+++ b/layout/xul/nsListItemFrame.cpp
@@ -12,17 +12,17 @@
 #include "nsGkAtoms.h"
 #include "nsDisplayList.h"
 #include "nsBoxLayout.h"
 #include "nsIContent.h"
 
 nsListItemFrame::nsListItemFrame(nsStyleContext* aContext,
                                  bool aIsRoot,
                                  nsBoxLayout* aLayoutManager)
-  : nsGridRowLeafFrame(aContext, aIsRoot, aLayoutManager) 
+  : nsGridRowLeafFrame(aContext, aIsRoot, aLayoutManager, kClassID) 
 {
 }
 
 nsListItemFrame::~nsListItemFrame()
 {
 }
 
 nsSize
--- a/layout/xul/nsMenuBarFrame.cpp
+++ b/layout/xul/nsMenuBarFrame.cpp
@@ -46,17 +46,17 @@ NS_IMPL_FRAMEARENA_HELPERS(nsMenuBarFram
 NS_QUERYFRAME_HEAD(nsMenuBarFrame)
   NS_QUERYFRAME_ENTRY(nsMenuBarFrame)
 NS_QUERYFRAME_TAIL_INHERITING(nsBoxFrame)
 
 //
 // nsMenuBarFrame cntr
 //
 nsMenuBarFrame::nsMenuBarFrame(nsStyleContext* aContext)
-  : nsBoxFrame(aContext)
+  : nsBoxFrame(aContext, kClassID)
   , mStayActive(false)
   , mIsActive(false)
   , mActiveByKeyboard(false)
   , mCurrentMenu(nullptr)
 {
 } // cntr
 
 void
--- a/layout/xul/nsMenuFrame.cpp
+++ b/layout/xul/nsMenuFrame.cpp
@@ -165,17 +165,17 @@ NS_NewMenuItemFrame(nsIPresShell* aPresS
 
 NS_IMPL_FRAMEARENA_HELPERS(nsMenuFrame)
 
 NS_QUERYFRAME_HEAD(nsMenuFrame)
   NS_QUERYFRAME_ENTRY(nsMenuFrame)
 NS_QUERYFRAME_TAIL_INHERITING(nsBoxFrame)
 
 nsMenuFrame::nsMenuFrame(nsStyleContext* aContext)
-  : nsBoxFrame(aContext, LayoutFrameType::Menu)
+  : nsBoxFrame(aContext, kClassID, LayoutFrameType::Menu)
   , mIsMenu(false)
   , mChecked(false)
   , mIgnoreAccelTextChange(false)
   , mReflowCallbackPosted(false)
   , mType(eMenuType_Normal)
   , mBlinkState(0)
 {
 }
--- a/layout/xul/nsMenuPopupFrame.cpp
+++ b/layout/xul/nsMenuPopupFrame.cpp
@@ -90,17 +90,17 @@ NS_IMPL_FRAMEARENA_HELPERS(nsMenuPopupFr
 NS_QUERYFRAME_HEAD(nsMenuPopupFrame)
   NS_QUERYFRAME_ENTRY(nsMenuPopupFrame)
 NS_QUERYFRAME_TAIL_INHERITING(nsBoxFrame)
 
 //
 // nsMenuPopupFrame ctor
 //
 nsMenuPopupFrame::nsMenuPopupFrame(nsStyleContext* aContext)
-  : nsBoxFrame(aContext, LayoutFrameType::MenuPopup)
+  : nsBoxFrame(aContext, kClassID, LayoutFrameType::MenuPopup)
   , mCurrentMenu(nullptr)
   , mView(nullptr)
   , mPrefSize(-1, -1)
   , mXPos(0)
   , mYPos(0)
   , mLastClientOffset(0, 0)
   , mPopupType(ePopupTypePanel)
   , mPopupState(ePopupClosed)
--- a/layout/xul/nsPopupSetFrame.h
+++ b/layout/xul/nsPopupSetFrame.h
@@ -14,17 +14,17 @@
 nsIFrame* NS_NewPopupSetFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 
 class nsPopupSetFrame final : public nsBoxFrame
 {
 public:
   NS_DECL_FRAMEARENA_HELPERS(nsPopupSetFrame)
 
   explicit nsPopupSetFrame(nsStyleContext* aContext)
-    : nsBoxFrame(aContext, mozilla::LayoutFrameType::PopupSet)
+    : nsBoxFrame(aContext, kClassID, mozilla::LayoutFrameType::PopupSet)
   {}
 
   ~nsPopupSetFrame() {}
 
   virtual void Init(nsIContent*       aContent,
                     nsContainerFrame* aParent,
                     nsIFrame*         aPrevInFlow) override;
 
--- a/layout/xul/nsProgressMeterFrame.h
+++ b/layout/xul/nsProgressMeterFrame.h
@@ -34,13 +34,13 @@ public:
                                     int32_t aModType) override;
 
 #ifdef DEBUG_FRAME_DUMP
   virtual nsresult GetFrameName(nsAString& aResult) const override;
 #endif
 
 protected:
   explicit nsProgressMeterFrame(nsStyleContext* aContext) :
-    nsBoxFrame(aContext), mNeedsReflowCallback(true) {}
+    nsBoxFrame(aContext, kClassID), mNeedsReflowCallback(true) {}
   virtual ~nsProgressMeterFrame();
 
   bool mNeedsReflowCallback;
 }; // class nsProgressMeterFrame
--- a/layout/xul/nsResizerFrame.cpp
+++ b/layout/xul/nsResizerFrame.cpp
@@ -41,17 +41,17 @@ nsIFrame*
 NS_NewResizerFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
 {
   return new (aPresShell) nsResizerFrame(aContext);
 }
 
 NS_IMPL_FRAMEARENA_HELPERS(nsResizerFrame)
 
 nsResizerFrame::nsResizerFrame(nsStyleContext* aContext)
-:nsTitleBarFrame(aContext)
+  : nsTitleBarFrame(aContext, kClassID)
 {
 }
 
 nsresult
 nsResizerFrame::HandleEvent(nsPresContext* aPresContext,
                             WidgetGUIEvent* aEvent,
                             nsEventStatus* aEventStatus)
 {
--- a/layout/xul/nsRootBoxFrame.cpp
+++ b/layout/xul/nsRootBoxFrame.cpp
@@ -103,17 +103,17 @@ nsContainerFrame*
 NS_NewRootBoxFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
 {
   return new (aPresShell) nsRootBoxFrame(aContext);
 }
 
 NS_IMPL_FRAMEARENA_HELPERS(nsRootBoxFrame)
 
 nsRootBoxFrame::nsRootBoxFrame(nsStyleContext* aContext)
-  : nsBoxFrame(aContext, LayoutFrameType::Root, true)
+  : nsBoxFrame(aContext, kClassID, LayoutFrameType::Root, true)
   , mPopupSetFrame(nullptr)
   , mDefaultTooltip(nullptr)
 {
   nsCOMPtr<nsBoxLayout> layout;
   NS_NewStackLayout(layout);
   SetXULLayoutManager(layout);
 }
 
--- a/layout/xul/nsScrollBoxFrame.cpp
+++ b/layout/xul/nsScrollBoxFrame.cpp
@@ -37,17 +37,17 @@ public:
                          nsEventStatus* aEventStatus) override;
 
   NS_IMETHOD HandleRelease(nsPresContext* aPresContext,
                            WidgetGUIEvent* aEvent,
                            nsEventStatus* aEventStatus) override;
 
 protected:
   explicit nsAutoRepeatBoxFrame(nsStyleContext* aContext):
-    nsButtonBoxFrame(aContext) {}
+    nsButtonBoxFrame(aContext, kClassID) {}
   
   void StartRepeat() {
     if (IsActivatedOnHover()) {
       // No initial delay on hover.
       nsRepeatService::GetInstance()->Start(Notify, this,
                                             mContent->OwnerDoc(),
                                             NS_LITERAL_CSTRING("DoMouseClick"),
                                             0);
--- a/layout/xul/nsScrollbarButtonFrame.h
+++ b/layout/xul/nsScrollbarButtonFrame.h
@@ -19,17 +19,17 @@
 #include "nsRepeatService.h"
 
 class nsScrollbarButtonFrame final : public nsButtonBoxFrame
 {
 public:
   NS_DECL_FRAMEARENA_HELPERS(nsScrollbarButtonFrame)
 
   explicit nsScrollbarButtonFrame(nsStyleContext* aContext):
-    nsButtonBoxFrame(aContext), mCursorOnThis(false) {}
+    nsButtonBoxFrame(aContext, kClassID), mCursorOnThis(false) {}
 
   // Overrides
   virtual void DestroyFrom(nsIFrame* aDestructRoot) override;
 
   friend nsIFrame* NS_NewScrollbarButtonFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 
   virtual nsresult HandleEvent(nsPresContext* aPresContext,
                                mozilla::WidgetGUIEvent* aEvent,
--- a/layout/xul/nsScrollbarFrame.h
+++ b/layout/xul/nsScrollbarFrame.h
@@ -16,17 +16,17 @@
 class nsIScrollbarMediator;
 
 nsIFrame* NS_NewScrollbarFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 
 class nsScrollbarFrame final : public nsBoxFrame
 {
 public:
   explicit nsScrollbarFrame(nsStyleContext* aContext)
-    : nsBoxFrame(aContext, mozilla::LayoutFrameType::Scrollbar)
+    : nsBoxFrame(aContext, kClassID, mozilla::LayoutFrameType::Scrollbar)
     , mIncrement(0)
     , mSmoothScroll(false)
     , mScrollbarMediator(nullptr)
   {}
 
   NS_DECL_QUERYFRAME
   NS_DECL_FRAMEARENA_HELPERS(nsScrollbarFrame)
 
--- a/layout/xul/nsSliderFrame.cpp
+++ b/layout/xul/nsSliderFrame.cpp
@@ -79,17 +79,17 @@ NS_NewSliderFrame (nsIPresShell* aPresSh
 
 NS_IMPL_FRAMEARENA_HELPERS(nsSliderFrame)
 
 NS_QUERYFRAME_HEAD(nsSliderFrame)
   NS_QUERYFRAME_ENTRY(nsSliderFrame)
 NS_QUERYFRAME_TAIL_INHERITING(nsBoxFrame)
 
 nsSliderFrame::nsSliderFrame(nsStyleContext* aContext)
-  : nsBoxFrame(aContext, LayoutFrameType::Slider)
+  : nsBoxFrame(aContext, kClassID, LayoutFrameType::Slider)
   , mRatio(0.0f)
   , mDragStart(0)
   , mThumbStart(0)
   , mCurPos(0)
   , mChange(0)
   , mDragFinished(true)
   , mUserChanged(false)
   , mScrollingWithAPZ(false)
--- a/layout/xul/nsSplitterFrame.cpp
+++ b/layout/xul/nsSplitterFrame.cpp
@@ -198,17 +198,17 @@ nsIFrame*
 NS_NewSplitterFrame (nsIPresShell* aPresShell, nsStyleContext* aContext)
 {
   return new (aPresShell) nsSplitterFrame(aContext);
 }
 
 NS_IMPL_FRAMEARENA_HELPERS(nsSplitterFrame)
 
 nsSplitterFrame::nsSplitterFrame(nsStyleContext* aContext)
-: nsBoxFrame(aContext),
+: nsBoxFrame(aContext, kClassID),
   mInner(0)
 {
 }
 
 void
 nsSplitterFrame::DestroyFrom(nsIFrame* aDestructRoot)
 {
   if (mInner) {
--- a/layout/xul/nsStackFrame.cpp
+++ b/layout/xul/nsStackFrame.cpp
@@ -25,17 +25,17 @@ nsIFrame*
 NS_NewStackFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
 {
   return new (aPresShell) nsStackFrame(aContext);
 }
 
 NS_IMPL_FRAMEARENA_HELPERS(nsStackFrame)
 
 nsStackFrame::nsStackFrame(nsStyleContext* aContext):
-  nsBoxFrame(aContext)
+  nsBoxFrame(aContext, kClassID)
 {
   nsCOMPtr<nsBoxLayout> layout;
   NS_NewStackLayout(layout);
   SetXULLayoutManager(layout);
 }
 
 // REVIEW: The old code put everything in the background layer. To be more
 // consistent with the way other frames work, I'm putting everything in the
--- a/layout/xul/nsTextBoxFrame.cpp
+++ b/layout/xul/nsTextBoxFrame.cpp
@@ -95,17 +95,17 @@ nsTextBoxFrame::AttributeChanged(int32_t
     // The old value has been unregistered in nsXULElement::SetAttr
     if (aAttribute == nsGkAtoms::accesskey || aAttribute == nsGkAtoms::control)
         RegUnregAccessKey(true);
 
     return NS_OK;
 }
 
 nsTextBoxFrame::nsTextBoxFrame(nsStyleContext* aContext)
-  : nsLeafBoxFrame(aContext)
+  : nsLeafBoxFrame(aContext, kClassID)
   , mAccessKeyInfo(nullptr)
   , mCropType(CropRight)
   , mAscent(0)
   , mNeedsReflowCallback(false)
 {
   MarkIntrinsicISizesDirty();
 }
 
--- a/layout/xul/nsTitleBarFrame.cpp
+++ b/layout/xul/nsTitleBarFrame.cpp
@@ -28,18 +28,18 @@ using namespace mozilla;
 nsIFrame*
 NS_NewTitleBarFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
 {
   return new (aPresShell) nsTitleBarFrame(aContext);
 }
 
 NS_IMPL_FRAMEARENA_HELPERS(nsTitleBarFrame)
 
-nsTitleBarFrame::nsTitleBarFrame(nsStyleContext* aContext)
-:nsBoxFrame(aContext, false)
+nsTitleBarFrame::nsTitleBarFrame(nsStyleContext* aContext, ClassID aID)
+  : nsBoxFrame(aContext, aID, false)
 {
   mTrackingMouseMove = false;
   UpdateMouseThrough();
 }
 
 void
 nsTitleBarFrame::BuildDisplayListForChildren(nsDisplayListBuilder*   aBuilder,
                                              const nsRect&           aDirtyRect,
--- a/layout/xul/nsTitleBarFrame.h
+++ b/layout/xul/nsTitleBarFrame.h
@@ -11,17 +11,17 @@
 
 class nsTitleBarFrame : public nsBoxFrame  
 {
 public:
   NS_DECL_FRAMEARENA_HELPERS(nsTitleBarFrame)
 
   friend nsIFrame* NS_NewTitleBarFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);  
 
-  explicit nsTitleBarFrame(nsStyleContext* aContext);
+  explicit nsTitleBarFrame(nsStyleContext* aContext, ClassID = kClassID);
 
   virtual void BuildDisplayListForChildren(nsDisplayListBuilder*   aBuilder,
                                            const nsRect&           aDirtyRect,
                                            const nsDisplayListSet& aLists) override;
 
   virtual nsresult HandleEvent(nsPresContext* aPresContext,
                                mozilla::WidgetGUIEvent* aEvent,
                                nsEventStatus* aEventStatus) override;
--- a/layout/xul/nsXULLabelFrame.h
+++ b/layout/xul/nsXULLabelFrame.h
@@ -35,17 +35,17 @@ public:
                                     int32_t aModType) override;
 
 #ifdef DEBUG_FRAME_DUMP
   virtual nsresult GetFrameName(nsAString& aResult) const override;
 #endif
 
 protected:
   explicit nsXULLabelFrame(nsStyleContext* aContext)
-    : nsBlockFrame(aContext, mozilla::LayoutFrameType::XULLabel)
+    : nsBlockFrame(aContext, kClassID, mozilla::LayoutFrameType::XULLabel)
   {}
 
   nsresult RegUnregAccessKey(bool aDoReg);
 };
 
 nsIFrame*
 NS_NewXULLabelFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 
--- a/layout/xul/tree/nsTreeBodyFrame.cpp
+++ b/layout/xul/tree/nsTreeBodyFrame.cpp
@@ -109,17 +109,17 @@ NS_IMPL_FRAMEARENA_HELPERS(nsTreeBodyFra
 
 NS_QUERYFRAME_HEAD(nsTreeBodyFrame)
   NS_QUERYFRAME_ENTRY(nsIScrollbarMediator)
   NS_QUERYFRAME_ENTRY(nsTreeBodyFrame)
 NS_QUERYFRAME_TAIL_INHERITING(nsLeafBoxFrame)
 
 // Constructor
 nsTreeBodyFrame::nsTreeBodyFrame(nsStyleContext* aContext)
-:nsLeafBoxFrame(aContext),
+:nsLeafBoxFrame(aContext, kClassID),
  mSlots(nullptr),
  mImageCache(),
  mTopRowIndex(0),
  mPageLength(0),
  mHorzPosition(0),
  mOriginalHorzWidth(-1),
  mHorzWidth(0),
  mAdjustWidth(0),
--- a/layout/xul/tree/nsTreeColFrame.h
+++ b/layout/xul/tree/nsTreeColFrame.h
@@ -12,17 +12,17 @@ nsIFrame* NS_NewTreeColFrame(nsIPresShel
                              nsStyleContext* aContext);
 
 class nsTreeColFrame final : public nsBoxFrame
 {
 public:
   NS_DECL_FRAMEARENA_HELPERS(nsTreeColFrame)
 
   explicit nsTreeColFrame(nsStyleContext* aContext):
-    nsBoxFrame(aContext) {}
+    nsBoxFrame(aContext, kClassID) {}
 
   virtual void Init(nsIContent*       aContent,
                     nsContainerFrame* aParent,
                     nsIFrame*         aPrevInFlow) override;
 
   virtual void DestroyFrom(nsIFrame* aDestructRoot) override;
 
   virtual void BuildDisplayListForChildren(nsDisplayListBuilder*   aBuilder,