Bug 851892 part 4. Make css::Rule wrappercached. r=heycam,peterv
authorBoris Zbarsky <bzbarsky@mit.edu>
Fri, 13 Jan 2017 10:41:02 -0500
changeset 374330 efbe11a48de704ef8f9fa6daa1f45a172b74cec1
parent 374329 681ca39f54118cc4038febe5ac6caabeadc84d9e
child 374331 1a603d30e5e12f9b5f779878ee3ad50fb8d8a57e
push id6996
push userjlorenzo@mozilla.com
push dateMon, 06 Mar 2017 20:48:21 +0000
treeherdermozilla-beta@d89512dab048 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersheycam, peterv
bugs851892
milestone53.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 851892 part 4. Make css::Rule wrappercached. r=heycam,peterv Note that this increases the size of css::Rule by three words, unfortunately.
dom/base/nsWrapperCache.h
layout/style/ImportRule.h
layout/style/NameSpaceRule.h
layout/style/Rule.h
layout/style/ServoStyleRule.cpp
layout/style/ServoStyleRule.h
layout/style/StyleRule.cpp
layout/style/StyleRule.h
layout/style/nsCSSRules.cpp
layout/style/nsCSSRules.h
--- a/dom/base/nsWrapperCache.h
+++ b/dom/base/nsWrapperCache.h
@@ -14,20 +14,35 @@
 #include "js/RootingAPI.h"
 #include "js/TracingAPI.h"
 
 namespace mozilla {
 namespace dom {
 class TabChildGlobal;
 class ProcessGlobal;
 } // namespace dom
+namespace css {
+class ImportRule;
+class NameSpaceRule;
+class StyleRule;
+class MediaRule;
+class DocumentRule;
+} // namespace css
+class ServoStyleRule;
+class CSSSupportsRule;
 } // namespace mozilla
 class SandboxPrivate;
 class nsInProcessTabChildGlobal;
 class nsWindowRoot;
+class nsCSSFontFaceRule;
+class nsCSSFontFeatureValuesRule;
+class nsCSSKeyframeRule;
+class nsCSSKeyframesRule;
+class nsCSSPageRule;
+class nsCSSCounterStyleRule;
 
 #define NS_WRAPPERCACHE_IID \
 { 0x6f3179a1, 0x36f7, 0x4a5c, \
   { 0x8c, 0xf1, 0xad, 0xc8, 0x7c, 0xde, 0x3e, 0x87 } }
 
 /**
  * Class to store the wrapper for an object. This can only be used with objects
  * that only have one non-security wrapper at a time (for an XPCWrappedNative
@@ -267,21 +282,37 @@ protected:
     if (mWrapper) {
       // Set the pointer to a value that will cause a crash if it is
       // dereferenced.
       mWrapper = reinterpret_cast<JSObject*>(1);
     }
   }
 
 private:
+  // Friend declarations for things that need to be able to call
+  // SetIsNotDOMBinding().  The goal is to get rid of all of these, and
+  // SetIsNotDOMBinding() too.
   friend class mozilla::dom::TabChildGlobal;
   friend class mozilla::dom::ProcessGlobal;
   friend class SandboxPrivate;
   friend class nsInProcessTabChildGlobal;
   friend class nsWindowRoot;
+  friend class mozilla::css::ImportRule;
+  friend class mozilla::css::NameSpaceRule;
+  friend class mozilla::css::StyleRule;
+  friend class mozilla::css::MediaRule;
+  friend class mozilla::css::DocumentRule;
+  friend class mozilla::ServoStyleRule;
+  friend class mozilla::CSSSupportsRule;
+  friend class nsCSSFontFaceRule;
+  friend class nsCSSFontFeatureValuesRule;
+  friend class nsCSSKeyframeRule;
+  friend class nsCSSKeyframesRule;
+  friend class nsCSSPageRule;
+  friend class nsCSSCounterStyleRule;
   void SetIsNotDOMBinding()
   {
     MOZ_ASSERT(!mWrapper && !(GetWrapperFlags() & ~WRAPPER_IS_NOT_DOM_BINDING),
                "This flag should be set before creating any wrappers.");
     SetWrapperFlags(WRAPPER_IS_NOT_DOM_BINDING);
   }
 
   JSObject *GetWrapperJSObject() const
--- a/layout/style/ImportRule.h
+++ b/layout/style/ImportRule.h
@@ -47,16 +47,19 @@ public:
 #endif
   virtual int32_t GetType() const override;
   virtual already_AddRefed<Rule> Clone() const override;
 
   void SetSheet(CSSStyleSheet*);
 
   virtual size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const override;
 
+  virtual JSObject* WrapObject(JSContext* aCx,
+                               JS::Handle<JSObject*> aGivenProto) override;
+
   // nsIDOMCSSRule interface
   NS_DECL_NSIDOMCSSRULE
 
   // nsIDOMCSSImportRule interface
   NS_DECL_NSIDOMCSSIMPORTRULE
 
 private:
   nsString  mURLSpec;
--- a/layout/style/NameSpaceRule.h
+++ b/layout/style/NameSpaceRule.h
@@ -49,16 +49,19 @@ public:
 
   nsIAtom* GetPrefix() const { return mPrefix; }
 
   void GetURLSpec(nsString& aURLSpec) const { aURLSpec = mURLSpec; }
 
   virtual size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
     override MOZ_MUST_OVERRIDE;
 
+  virtual JSObject* WrapObject(JSContext* aCx,
+                               JS::Handle<JSObject*> aGivenProto) override;
+
   // nsIDOMCSSRule interface
   NS_DECL_NSIDOMCSSRULE
 
 private:
   nsCOMPtr<nsIAtom> mPrefix;
   nsString          mURLSpec;
 };
 
--- a/layout/style/Rule.h
+++ b/layout/style/Rule.h
@@ -7,16 +7,17 @@
 
 #ifndef mozilla_css_Rule_h___
 #define mozilla_css_Rule_h___
 
 #include "mozilla/StyleSheetInlines.h"
 #include "mozilla/MemoryReporting.h"
 #include "nsISupports.h"
 #include "nsIDOMCSSRule.h"
+#include "nsWrapperCache.h"
 
 class nsIDocument;
 struct nsRuleData;
 template<class T> struct already_AddRefed;
 class nsHTMLCSSStyleSheet;
 
 namespace mozilla {
 namespace css {
@@ -24,17 +25,19 @@ class GroupRule;
 
 #define DECL_STYLE_RULE_INHERIT_NO_DOMRULE  \
  /* nothing */
 
 #define DECL_STYLE_RULE_INHERIT                            \
   DECL_STYLE_RULE_INHERIT_NO_DOMRULE                       \
   virtual nsIDOMCSSRule* GetDOMRule() override;
 
-class Rule : public nsISupports {
+class Rule : public nsISupports
+           , public nsWrapperCache
+{
 protected:
   Rule(uint32_t aLineNumber, uint32_t aColumnNumber)
     : mSheet(nullptr),
       mParentRule(nullptr),
       mLineNumber(aLineNumber),
       mColumnNumber(aColumnNumber)
   {
   }
@@ -47,17 +50,17 @@ protected:
   {
   }
 
   virtual ~Rule() {}
 
 public:
 
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
-  NS_DECL_CYCLE_COLLECTION_CLASS(Rule)
+  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(Rule)
 
 #ifdef DEBUG
   virtual void List(FILE* out = stdout, int32_t aIndent = 0) const = 0;
 #endif
 
   // The constants in this list must maintain the following invariants:
   //   If a rule of type N must appear before a rule of type M in stylesheets
   //   then N < M
--- a/layout/style/ServoStyleRule.cpp
+++ b/layout/style/ServoStyleRule.cpp
@@ -99,16 +99,17 @@ ServoStyleRuleDeclaration::GetCSSParsing
 
 // -- ServoStyleRule --------------------------------------------------
 
 ServoStyleRule::ServoStyleRule(already_AddRefed<RawServoStyleRule> aRawRule)
   : css::Rule(0, 0)
   , mRawRule(aRawRule)
   , mDecls(Servo_StyleRule_GetStyle(mRawRule).Consume())
 {
+  SetIsNotDOMBinding();
 }
 
 // QueryInterface implementation for ServoStyleRule
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(ServoStyleRule)
   NS_INTERFACE_MAP_ENTRY(nsIDOMCSSStyleRule)
   NS_INTERFACE_MAP_ENTRY(nsIDOMCSSRule)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(CSSStyleRule)
 NS_INTERFACE_MAP_END_INHERITING(css::Rule)
@@ -147,16 +148,24 @@ ServoStyleRule::Clone() const
 
 size_t
 ServoStyleRule::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
 {
   // TODO Implement this!
   return aMallocSizeOf(this);
 }
 
+/* virtual */ JSObject*
+ServoStyleRule::WrapObject(JSContext* aCx,
+                           JS::Handle<JSObject*> aGivenProto)
+{
+  NS_NOTREACHED("We called SetIsNotDOMBinding() in our constructor");
+  return nullptr;
+}
+
 #ifdef DEBUG
 void
 ServoStyleRule::List(FILE* out, int32_t aIndent) const
 {
   nsAutoCString str;
   for (int32_t i = 0; i < aIndent; i++) {
     str.AppendLiteral("  ");
   }
--- a/layout/style/ServoStyleRule.h
+++ b/layout/style/ServoStyleRule.h
@@ -61,16 +61,18 @@ public:
 
   RawServoStyleRule* Raw() const { return mRawRule; }
 
   // Methods of mozilla::css::Rule
   int32_t GetType() const final { return css::Rule::STYLE_RULE; }
   already_AddRefed<Rule> Clone() const final;
   nsIDOMCSSRule* GetDOMRule() final { return this; }
   size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const final;
+  virtual JSObject* WrapObject(JSContext* aCx,
+                               JS::Handle<JSObject*> aGivenProto) override;
 #ifdef DEBUG
   void List(FILE* out = stdout, int32_t aIndent = 0) const final;
 #endif
 
 private:
   ~ServoStyleRule() {}
 
   // For computing the offset of mDecls.
--- a/layout/style/StyleRule.cpp
+++ b/layout/style/StyleRule.cpp
@@ -1375,27 +1375,29 @@ namespace css {
 StyleRule::StyleRule(nsCSSSelectorList* aSelector,
                      Declaration* aDeclaration,
                      uint32_t aLineNumber,
                      uint32_t aColumnNumber)
   : Rule(aLineNumber, aColumnNumber),
     mSelector(aSelector),
     mDeclaration(aDeclaration)
 {
+  SetIsNotDOMBinding();
   NS_PRECONDITION(aDeclaration, "must have a declaration");
 
   mDeclaration->SetOwningRule(this);
 }
 
 // for |Clone|
 StyleRule::StyleRule(const StyleRule& aCopy)
   : Rule(aCopy),
     mSelector(aCopy.mSelector ? aCopy.mSelector->Clone() : nullptr),
     mDeclaration(new Declaration(*aCopy.mDeclaration))
 {
+  SetIsNotDOMBinding();
   mDeclaration->SetOwningRule(this);
   // rest is constructed lazily on existing data
 }
 
 StyleRule::~StyleRule()
 {
   delete mSelector;
   DropReferences();
@@ -1569,11 +1571,19 @@ StyleRule::SizeOfIncludingThis(mozilla::
 
   // Measurement of the following members may be added later if DMD finds it is
   // worthwhile:
   // - mDOMRule;
 
   return n;
 }
 
+/* virtual */ JSObject*
+StyleRule::WrapObject(JSContext* aCx,
+                      JS::Handle<JSObject*> aGivenProto)
+{
+  NS_NOTREACHED("We called SetIsNotDOMBinding() in our constructor");
+  return nullptr;
+}
+
 
 } // namespace css
 } // namespace mozilla
--- a/layout/style/StyleRule.h
+++ b/layout/style/StyleRule.h
@@ -349,16 +349,19 @@ public:
   virtual nsIDOMCSSRule* GetDOMRule() override;
 
 #ifdef DEBUG
   virtual void List(FILE* out = stdout, int32_t aIndent = 0) const override;
 #endif
 
   virtual size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const override;
 
+  virtual JSObject* WrapObject(JSContext* aCx,
+                               JS::Handle<JSObject*> aGivenProto) override;
+
 private:
   ~StyleRule();
 
   // Drop our references to mDeclaration and mRule, and let them know we're
   // doing that.
   void DropReferences();
 
 private:
--- a/layout/style/nsCSSRules.cpp
+++ b/layout/style/nsCSSRules.cpp
@@ -52,20 +52,21 @@ IMPL_STYLE_RULE_INHERIT_GET_DOM_RULE_WEA
 
 namespace mozilla {
 namespace css {
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(Rule)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(Rule)
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(Rule)
+  NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
   NS_INTERFACE_MAP_ENTRY(nsISupports)
 NS_INTERFACE_MAP_END
 
-NS_IMPL_CYCLE_COLLECTION_0(Rule)
+NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(Rule)
 
 /* virtual */ void
 Rule::SetStyleSheet(StyleSheet* aSheet)
 {
   // We don't reference count this up reference. The style sheet
   // will tell us when it's going away or when we're detached from
   // it.
   mSheet = aSheet;
@@ -174,25 +175,27 @@ GroupRuleRuleList::IndexedGetter(uint32_
 //
 
 ImportRule::ImportRule(nsMediaList* aMedia, const nsString& aURLSpec,
                        uint32_t aLineNumber, uint32_t aColumnNumber)
   : Rule(aLineNumber, aColumnNumber)
   , mURLSpec(aURLSpec)
   , mMedia(aMedia)
 {
+  SetIsNotDOMBinding();
   // XXXbz This is really silly.... the mMedia here will be replaced
   // with itself if we manage to load a sheet.  Which should really
   // never fail nowadays, in sane cases.
 }
 
 ImportRule::ImportRule(const ImportRule& aCopy)
   : Rule(aCopy),
     mURLSpec(aCopy.mURLSpec)
 {
+  SetIsNotDOMBinding();
   // Whether or not an @import rule has a null sheet is a permanent
   // property of that @import rule, since it is null only if the target
   // sheet failed security checks.
   if (aCopy.mChildSheet) {
     RefPtr<CSSStyleSheet> sheet =
       aCopy.mChildSheet->Clone(nullptr, this, nullptr, nullptr);
     SetSheet(sheet);
     // SetSheet sets mMedia appropriately
@@ -352,16 +355,24 @@ ImportRule::SizeOfIncludingThis(MallocSi
   // worthwhile:
   // - mURLSpec
   //
   // The following members are not measured:
   // - mMedia, because it is measured via CSSStyleSheet::mMedia
   // - mChildSheet, because it is measured via CSSStyleSheetInner::mSheets
 }
 
+/* virtual */ JSObject*
+ImportRule::WrapObject(JSContext* aCx,
+                       JS::Handle<JSObject*> aGivenProto)
+{
+  NS_NOTREACHED("We called SetIsNotDOMBinding() in our constructor");
+  return nullptr;
+}
+
 GroupRule::GroupRule(uint32_t aLineNumber, uint32_t aColumnNumber)
   : Rule(aLineNumber, aColumnNumber)
 {
 }
 
 static bool
 SetParentRuleReference(Rule* aRule, void* aParentRule)
 {
@@ -583,21 +594,23 @@ GroupRule::SizeOfExcludingThis(MallocSiz
 
 
 // -------------------------------------------
 // nsICSSMediaRule
 //
 MediaRule::MediaRule(uint32_t aLineNumber, uint32_t aColumnNumber)
   : GroupRule(aLineNumber, aColumnNumber)
 {
+  SetIsNotDOMBinding();
 }
 
 MediaRule::MediaRule(const MediaRule& aCopy)
   : GroupRule(aCopy)
 {
+  SetIsNotDOMBinding();
   if (aCopy.mMedia) {
     mMedia = aCopy.mMedia->Clone();
     // XXXldb This doesn't really make sense.
     mMedia->SetStyleSheet(aCopy.GetStyleSheet());
   }
 }
 
 MediaRule::~MediaRule()
@@ -798,35 +811,45 @@ MediaRule::SizeOfIncludingThis(MallocSiz
 
   // Measurement of the following members may be added later if DMD finds it is
   // worthwhile:
   // - mMedia
 
   return n;
 }
 
+/* virtual */ JSObject*
+MediaRule::WrapObject(JSContext* aCx,
+                      JS::Handle<JSObject*> aGivenProto)
+{
+  NS_NOTREACHED("We called SetIsNotDOMBinding() in our constructor");
+  return nullptr;
+}
+
 void
 MediaRule::AppendConditionText(nsAString& aOutput)
 {
   if (mMedia) {
     nsAutoString mediaText;
     mMedia->GetText(mediaText);
     aOutput.Append(mediaText);
   }
 }
 
 DocumentRule::DocumentRule(uint32_t aLineNumber, uint32_t aColumnNumber)
   : GroupRule(aLineNumber, aColumnNumber)
 {
+  SetIsNotDOMBinding();
 }
 
 DocumentRule::DocumentRule(const DocumentRule& aCopy)
   : GroupRule(aCopy)
   , mURLs(new URL(*aCopy.mURLs))
 {
+  SetIsNotDOMBinding();
 }
 
 DocumentRule::~DocumentRule()
 {
 }
 
 NS_IMPL_ADDREF_INHERITED(DocumentRule, GroupRule)
 NS_IMPL_RELEASE_INHERITED(DocumentRule, GroupRule)
@@ -1039,16 +1062,24 @@ DocumentRule::SizeOfIncludingThis(Malloc
 
   // Measurement of the following members may be added later if DMD finds it is
   // worthwhile:
   // - mURLs
 
   return n;
 }
 
+/* virtual */ JSObject*
+DocumentRule::WrapObject(JSContext* aCx,
+                         JS::Handle<JSObject*> aGivenProto)
+{
+  NS_NOTREACHED("We called SetIsNotDOMBinding() in our constructor");
+  return nullptr;
+}
+
 void
 DocumentRule::AppendConditionText(nsAString& aCssText)
 {
   for (URL *url = mURLs; url; url = url->next) {
     switch (url->func) {
       case eURL:
         aCssText.AppendLiteral("url(");
         break;
@@ -1074,23 +1105,25 @@ DocumentRule::AppendConditionText(nsAStr
 //
 
 NameSpaceRule::NameSpaceRule(nsIAtom* aPrefix, const nsString& aURLSpec,
                              uint32_t aLineNumber, uint32_t aColumnNumber)
   : Rule(aLineNumber, aColumnNumber),
     mPrefix(aPrefix),
     mURLSpec(aURLSpec)
 {
+  SetIsNotDOMBinding();
 }
 
 NameSpaceRule::NameSpaceRule(const NameSpaceRule& aCopy)
   : Rule(aCopy),
     mPrefix(aCopy.mPrefix),
     mURLSpec(aCopy.mURLSpec)
 {
+  SetIsNotDOMBinding();
 }
 
 NameSpaceRule::~NameSpaceRule()
 {
 }
 
 NS_IMPL_ADDREF_INHERITED(NameSpaceRule, Rule)
 NS_IMPL_RELEASE_INHERITED(NameSpaceRule, Rule)
@@ -1198,16 +1231,23 @@ NameSpaceRule::SizeOfIncludingThis(Mallo
   return aMallocSizeOf(this);
 
   // Measurement of the following members may be added later if DMD finds it is
   // worthwhile:
   // - mPrefix
   // - mURLSpec
 }
 
+/* virtual */ JSObject*
+NameSpaceRule::WrapObject(JSContext* aCx,
+                          JS::Handle<JSObject*> aGivenProto)
+{
+  NS_NOTREACHED("We called SetIsNotDOMBinding() in our constructor");
+  return nullptr;
+}
 
 } // namespace css
 } // namespace mozilla
 
 // -------------------------------------------
 // nsCSSFontFaceStyleDecl and related routines
 //
 
@@ -1661,16 +1701,23 @@ nsCSSFontFaceRule::SizeOfIncludingThis(M
 {
   return aMallocSizeOf(this);
 
   // Measurement of the following members may be added later if DMD finds it is
   // worthwhile:
   // - mDecl
 }
 
+/* virtual */ JSObject*
+nsCSSFontFaceRule::WrapObject(JSContext* aCx,
+                              JS::Handle<JSObject*> aGivenProto)
+{
+  NS_NOTREACHED("We called SetIsNotDOMBinding() in our constructor");
+  return nullptr;
+}
 
 // -----------------------------------
 // nsCSSFontFeatureValuesRule
 //
 
 /* virtual */ already_AddRefed<css::Rule>
 nsCSSFontFeatureValuesRule::Clone() const
 {
@@ -1900,16 +1947,24 @@ nsCSSFontFeatureValuesRule::AddValueList
 
 size_t
 nsCSSFontFeatureValuesRule::SizeOfIncludingThis(
   MallocSizeOf aMallocSizeOf) const
 {
   return aMallocSizeOf(this);
 }
 
+/* virtual */ JSObject*
+nsCSSFontFeatureValuesRule::WrapObject(JSContext* aCx,
+                                       JS::Handle<JSObject*> aGivenProto)
+{
+  NS_NOTREACHED("We called SetIsNotDOMBinding() in our constructor");
+  return nullptr;
+}
+
 // -------------------------------------------
 // nsCSSKeyframeStyleDeclaration
 //
 
 nsCSSKeyframeStyleDeclaration::nsCSSKeyframeStyleDeclaration(nsCSSKeyframeRule *aRule)
   : mRule(aRule)
 {
 }
@@ -1978,16 +2033,17 @@ nsCSSKeyframeStyleDeclaration::GetParent
 //
 
 nsCSSKeyframeRule::nsCSSKeyframeRule(const nsCSSKeyframeRule& aCopy)
   // copy everything except our reference count and mDOMDeclaration
   : Rule(aCopy)
   , mKeys(aCopy.mKeys)
   , mDeclaration(new css::Declaration(*aCopy.mDeclaration))
 {
+  SetIsNotDOMBinding();
   mDeclaration->SetOwningRule(this);
 }
 
 nsCSSKeyframeRule::~nsCSSKeyframeRule()
 {
   mDeclaration->SetOwningRule(nullptr);
   if (mDOMDeclaration) {
     mDOMDeclaration->DropReference();
@@ -2187,28 +2243,36 @@ nsCSSKeyframeRule::SizeOfIncludingThis(M
 
   // Measurement of the following members may be added later if DMD finds it is
   // worthwhile:
   // - mKeys
   // - mDeclaration
   // - mDOMDeclaration
 }
 
+/* virtual */ JSObject*
+nsCSSKeyframeRule::WrapObject(JSContext* aCx,
+                              JS::Handle<JSObject*> aGivenProto)
+{
+  NS_NOTREACHED("We called SetIsNotDOMBinding() in our constructor");
+  return nullptr;
+}
 
 // -------------------------------------------
 // nsCSSKeyframesRule
 //
 
 nsCSSKeyframesRule::nsCSSKeyframesRule(const nsCSSKeyframesRule& aCopy)
   // copy everything except our reference count.  GroupRule's copy
   // constructor also doesn't copy the lazily-constructed
   // mRuleCollection.
   : GroupRule(aCopy),
     mName(aCopy.mName)
 {
+  SetIsNotDOMBinding();
 }
 
 nsCSSKeyframesRule::~nsCSSKeyframesRule()
 {
 }
 
 /* virtual */ already_AddRefed<css::Rule>
 nsCSSKeyframesRule::Clone() const
@@ -2438,16 +2502,24 @@ nsCSSKeyframesRule::SizeOfIncludingThis(
 
   // Measurement of the following members may be added later if DMD finds it is
   // worthwhile:
   // - mName
 
   return n;
 }
 
+/* virtual */ JSObject*
+nsCSSKeyframesRule::WrapObject(JSContext* aCx,
+                               JS::Handle<JSObject*> aGivenProto)
+{
+  NS_NOTREACHED("We called SetIsNotDOMBinding() in our constructor");
+  return nullptr;
+}
+
 // -------------------------------------------
 // nsCSSPageStyleDeclaration
 //
 
 nsCSSPageStyleDeclaration::nsCSSPageStyleDeclaration(nsCSSPageRule* aRule)
   : mRule(aRule)
 {
 }
@@ -2515,16 +2587,17 @@ nsCSSPageStyleDeclaration::GetParentObje
 // nsCSSPageRule
 //
 
 nsCSSPageRule::nsCSSPageRule(const nsCSSPageRule& aCopy)
   // copy everything except our reference count and mDOMDeclaration
   : Rule(aCopy)
   , mDeclaration(new css::Declaration(*aCopy.mDeclaration))
 {
+  SetIsNotDOMBinding();
   mDeclaration->SetOwningRule(this);
 }
 
 nsCSSPageRule::~nsCSSPageRule()
 {
   mDeclaration->SetOwningRule(nullptr);
   if (mDOMDeclaration) {
     mDOMDeclaration->DropReference();
@@ -2656,36 +2729,46 @@ nsCSSPageRule::ChangeDeclaration(css::De
 }
 
 /* virtual */ size_t
 nsCSSPageRule::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
 {
   return aMallocSizeOf(this);
 }
 
+/* virtual */ JSObject*
+nsCSSPageRule::WrapObject(JSContext* aCx,
+                          JS::Handle<JSObject*> aGivenProto)
+{
+  NS_NOTREACHED("We called SetIsNotDOMBinding() in our constructor");
+  return nullptr;
+}
+
 namespace mozilla {
 
 CSSSupportsRule::CSSSupportsRule(bool aConditionMet,
                                  const nsString& aCondition,
                                  uint32_t aLineNumber, uint32_t aColumnNumber)
   : css::GroupRule(aLineNumber, aColumnNumber)
   , mUseGroup(aConditionMet)
   , mCondition(aCondition)
 {
+  SetIsNotDOMBinding();
 }
 
 CSSSupportsRule::~CSSSupportsRule()
 {
 }
 
 CSSSupportsRule::CSSSupportsRule(const CSSSupportsRule& aCopy)
   : css::GroupRule(aCopy),
     mUseGroup(aCopy.mUseGroup),
     mCondition(aCopy.mCondition)
 {
+  SetIsNotDOMBinding();
 }
 
 #ifdef DEBUG
 /* virtual */ void
 CSSSupportsRule::List(FILE* out, int32_t aIndent) const
 {
   nsAutoCString indentStr;
   for (int32_t indent = aIndent; --indent >= 0; ) {
@@ -2811,27 +2894,36 @@ CSSSupportsRule::SetConditionText(const 
 CSSSupportsRule::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
 {
   size_t n = aMallocSizeOf(this);
   n += css::GroupRule::SizeOfExcludingThis(aMallocSizeOf);
   n += mCondition.SizeOfExcludingThisIfUnshared(aMallocSizeOf);
   return n;
 }
 
+/* virtual */ JSObject*
+CSSSupportsRule::WrapObject(JSContext* aCx,
+                            JS::Handle<JSObject*> aGivenProto)
+{
+  NS_NOTREACHED("We called SetIsNotDOMBinding() in our constructor");
+  return nullptr;
+}
+
 } // namespace mozilla
 
 // -------------------------------------------
 // nsCSSCounterStyleRule
 //
 
 nsCSSCounterStyleRule::nsCSSCounterStyleRule(const nsCSSCounterStyleRule& aCopy)
   : Rule(aCopy)
   , mName(aCopy.mName)
   , mGeneration(aCopy.mGeneration)
 {
+  SetIsNotDOMBinding();
   for (size_t i = 0; i < ArrayLength(mValues); ++i) {
     mValues[i] = aCopy.mValues[i];
   }
 }
 
 nsCSSCounterStyleRule::~nsCSSCounterStyleRule()
 {
 }
@@ -3270,8 +3362,16 @@ CSS_COUNTER_DESC_SETTER(Fallback)
 CSS_COUNTER_DESC_SETTER(SpeakAs)
 #undef CSS_COUNTER_DESC_SETTER
 
 /* virtual */ size_t
 nsCSSCounterStyleRule::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
 {
   return aMallocSizeOf(this);
 }
+
+/* virtual */ JSObject*
+nsCSSCounterStyleRule::WrapObject(JSContext* aCx,
+                                  JS::Handle<JSObject*> aGivenProto)
+{
+  NS_NOTREACHED("We called SetIsNotDOMBinding() in our constructor");
+  return nullptr;
+}
--- a/layout/style/nsCSSRules.h
+++ b/layout/style/nsCSSRules.h
@@ -90,16 +90,19 @@ public:
                                     nsMediaQueryResultCacheKey& aKey) override;
 
   // @media rule methods
   nsresult SetMedia(nsMediaList* aMedia);
   
   virtual size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf)
     const override MOZ_MUST_OVERRIDE;
 
+  virtual JSObject* WrapObject(JSContext* aCx,
+                               JS::Handle<JSObject*> aGivenProto) override;
+
 protected:
   void AppendConditionText(nsAString& aOutput);
 
   RefPtr<nsMediaList> mMedia;
 };
 
 class DocumentRule final : public GroupRule,
                            public nsIDOMCSSMozDocumentRule
@@ -164,16 +167,19 @@ public:
     ~URL();
   };
 
   void SetURLs(URL *aURLs) { mURLs = aURLs; }
 
   virtual size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf)
     const override MOZ_MUST_OVERRIDE;
 
+  virtual JSObject* WrapObject(JSContext* aCx,
+                               JS::Handle<JSObject*> aGivenProto) override;
+
 protected:
   void AppendConditionText(nsAString& aOutput);
 
   nsAutoPtr<URL> mURLs; // linked list of |struct URL| above.
 };
 
 } // namespace css
 
@@ -230,21 +236,27 @@ private:
   void* operator new(size_t size) CPP_THROW_NEW;
 };
 
 class nsCSSFontFaceRule final : public mozilla::css::Rule,
                                 public nsIDOMCSSFontFaceRule
 {
 public:
   nsCSSFontFaceRule(uint32_t aLineNumber, uint32_t aColumnNumber)
-    : mozilla::css::Rule(aLineNumber, aColumnNumber) {}
+    : mozilla::css::Rule(aLineNumber, aColumnNumber)
+  {
+    SetIsNotDOMBinding();
+  }
 
   nsCSSFontFaceRule(const nsCSSFontFaceRule& aCopy)
     // copy everything except our reference count
-    : mozilla::css::Rule(aCopy), mDecl(aCopy.mDecl) {}
+    : mozilla::css::Rule(aCopy), mDecl(aCopy.mDecl)
+  {
+    SetIsNotDOMBinding();
+  }
 
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(nsCSSFontFaceRule,
                                                          mozilla::css::Rule)
 
   // Rule methods
   DECL_STYLE_RULE_INHERIT
 #ifdef DEBUG
@@ -259,16 +271,19 @@ public:
   // nsIDOMCSSFontFaceRule interface
   NS_DECL_NSIDOMCSSFONTFACERULE
 
   void SetDesc(nsCSSFontDesc aDescID, nsCSSValue const & aValue);
   void GetDesc(nsCSSFontDesc aDescID, nsCSSValue & aValue);
 
   virtual size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const override;
 
+  virtual JSObject* WrapObject(JSContext* aCx,
+                               JS::Handle<JSObject*> aGivenProto) override;
+
   void GetDescriptors(mozilla::CSSFontFaceDescriptors& aDescriptors) const
     { aDescriptors = mDecl.mDescriptors; }
 
 protected:
   ~nsCSSFontFaceRule() {}
 
   friend class nsCSSFontFaceStyleDecl;
   nsCSSFontFaceStyleDecl mDecl;
@@ -295,23 +310,29 @@ nsCSSFontFaceStyleDecl::ContainingRule()
     (reinterpret_cast<const char*>(this) - offsetof(nsCSSFontFaceRule, mDecl));
 }
 
 class nsCSSFontFeatureValuesRule final : public mozilla::css::Rule,
                                          public nsIDOMCSSFontFeatureValuesRule
 {
 public:
   nsCSSFontFeatureValuesRule(uint32_t aLineNumber, uint32_t aColumnNumber)
-    : mozilla::css::Rule(aLineNumber, aColumnNumber) {}
+    : mozilla::css::Rule(aLineNumber, aColumnNumber)
+  {
+    SetIsNotDOMBinding();
+  }
 
   nsCSSFontFeatureValuesRule(const nsCSSFontFeatureValuesRule& aCopy)
     // copy everything except our reference count
     : mozilla::css::Rule(aCopy),
       mFamilyList(aCopy.mFamilyList),
-      mFeatureValues(aCopy.mFeatureValues) {}
+      mFeatureValues(aCopy.mFeatureValues)
+  {
+    SetIsNotDOMBinding();
+  }
 
   NS_DECL_ISUPPORTS_INHERITED
 
   // Rule methods
   DECL_STYLE_RULE_INHERIT
 #ifdef DEBUG
   virtual void List(FILE* out = stdout, int32_t aIndent = 0) const override;
 #endif
@@ -332,16 +353,19 @@ public:
 
   const nsTArray<gfxFontFeatureValueSet::FeatureValues>& GetFeatureValues()
   {
     return mFeatureValues;
   }
 
   virtual size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const override;
 
+  virtual JSObject* WrapObject(JSContext* aCx,
+                               JS::Handle<JSObject*> aGivenProto) override;
+
 protected:
   ~nsCSSFontFeatureValuesRule() {}
 
   mozilla::FontFamilyList mFamilyList;
   nsTArray<gfxFontFeatureValueSet::FeatureValues> mFeatureValues;
 };
 
 class nsCSSKeyframeRule;
@@ -379,16 +403,17 @@ public:
   // Steals the contents of aKeys, and takes the reference in Declaration
   nsCSSKeyframeRule(InfallibleTArray<float>&& aKeys,
                     already_AddRefed<mozilla::css::Declaration>&& aDeclaration,
                     uint32_t aLineNumber, uint32_t aColumnNumber)
     : mozilla::css::Rule(aLineNumber, aColumnNumber)
     , mKeys(mozilla::Move(aKeys))
     , mDeclaration(mozilla::Move(aDeclaration))
   {
+    SetIsNotDOMBinding();
     mDeclaration->SetOwningRule(this);
   }
 private:
   nsCSSKeyframeRule(const nsCSSKeyframeRule& aCopy);
   ~nsCSSKeyframeRule();
 public:
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsCSSKeyframeRule, mozilla::css::Rule)
@@ -409,16 +434,19 @@ public:
 
   const nsTArray<float>& GetKeys() const     { return mKeys; }
   mozilla::css::Declaration* Declaration()   { return mDeclaration; }
 
   void ChangeDeclaration(mozilla::css::Declaration* aDeclaration);
 
   virtual size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const override;
 
+  virtual JSObject* WrapObject(JSContext* aCx,
+                               JS::Handle<JSObject*> aGivenProto) override;
+
   void DoGetKeyText(nsAString &aKeyText) const;
 
 private:
   nsTArray<float>                            mKeys;
   RefPtr<mozilla::css::Declaration>          mDeclaration;
   // lazily created when needed:
   RefPtr<nsCSSKeyframeStyleDeclaration>    mDOMDeclaration;
 };
@@ -427,16 +455,17 @@ class nsCSSKeyframesRule final : public 
                                  public nsIDOMCSSKeyframesRule
 {
 public:
   nsCSSKeyframesRule(const nsSubstring& aName,
                      uint32_t aLineNumber, uint32_t aColumnNumber)
     : mozilla::css::GroupRule(aLineNumber, aColumnNumber)
     , mName(aName)
   {
+    SetIsNotDOMBinding();
   }
 private:
   nsCSSKeyframesRule(const nsCSSKeyframesRule& aCopy);
   ~nsCSSKeyframesRule();
 public:
   NS_DECL_ISUPPORTS_INHERITED
 
   // Rule methods
@@ -459,16 +488,19 @@ public:
   // rest of GroupRule
   virtual bool UseForPresentation(nsPresContext* aPresContext,
                                     nsMediaQueryResultCacheKey& aKey) override;
 
   const nsString& GetName() { return mName; }
 
   virtual size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const override;
 
+  virtual JSObject* WrapObject(JSContext* aCx,
+                               JS::Handle<JSObject*> aGivenProto) override;
+
 private:
   uint32_t FindRuleIndexForKey(const nsAString& aKey);
 
   nsString                                   mName;
 };
 
 class nsCSSPageRule;
 
@@ -502,16 +534,17 @@ class nsCSSPageRule final : public mozil
                             public nsIDOMCSSPageRule
 {
 public:
   nsCSSPageRule(mozilla::css::Declaration* aDeclaration,
                 uint32_t aLineNumber, uint32_t aColumnNumber)
     : mozilla::css::Rule(aLineNumber, aColumnNumber)
     , mDeclaration(aDeclaration)
   {
+    SetIsNotDOMBinding();
     mDeclaration->SetOwningRule(this);
   }
 private:
   nsCSSPageRule(const nsCSSPageRule& aCopy);
   ~nsCSSPageRule();
 public:
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsCSSPageRule, mozilla::css::Rule)
@@ -530,26 +563,30 @@ public:
   // nsIDOMCSSPageRule interface
   NS_DECL_NSIDOMCSSPAGERULE
 
   mozilla::css::Declaration* Declaration()   { return mDeclaration; }
 
   void ChangeDeclaration(mozilla::css::Declaration* aDeclaration);
 
   virtual size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const override;
+
+  virtual JSObject* WrapObject(JSContext* aCx,
+                               JS::Handle<JSObject*> aGivenProto) override;
+
 private:
   RefPtr<mozilla::css::Declaration>     mDeclaration;
   // lazily created when needed:
   RefPtr<nsCSSPageStyleDeclaration>     mDOMDeclaration;
 };
 
 namespace mozilla {
 
-class CSSSupportsRule : public css::GroupRule,
-                        public nsIDOMCSSSupportsRule
+class CSSSupportsRule final : public css::GroupRule,
+                              public nsIDOMCSSSupportsRule
 {
 public:
   CSSSupportsRule(bool aConditionMet, const nsString& aCondition,
                   uint32_t aLineNumber, uint32_t aColumnNumber);
   CSSSupportsRule(const CSSSupportsRule& aCopy);
 
   // Rule methods
 #ifdef DEBUG
@@ -575,16 +612,19 @@ public:
   // nsIDOMCSSConditionRule interface
   NS_DECL_NSIDOMCSSCONDITIONRULE
 
   // nsIDOMCSSSupportsRule interface
   NS_DECL_NSIDOMCSSSUPPORTSRULE
 
   virtual size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const override;
 
+  virtual JSObject* WrapObject(JSContext* aCx,
+                               JS::Handle<JSObject*> aGivenProto) override;
+
 protected:
   virtual ~CSSSupportsRule();
 
   bool mUseGroup;
   nsString mCondition;
 };
 
 } // namespace mozilla
@@ -594,16 +634,17 @@ class nsCSSCounterStyleRule final : publ
 {
 public:
   explicit nsCSSCounterStyleRule(const nsAString& aName,
                                  uint32_t aLineNumber, uint32_t aColumnNumber)
     : mozilla::css::Rule(aLineNumber, aColumnNumber)
     , mName(aName)
     , mGeneration(0)
   {
+    SetIsNotDOMBinding();
   }
 
 private:
   nsCSSCounterStyleRule(const nsCSSCounterStyleRule& aCopy);
   ~nsCSSCounterStyleRule();
 
 public:
   NS_DECL_ISUPPORTS_INHERITED
@@ -641,16 +682,19 @@ public:
                "descriptor ID out of range");
     return mValues[aDescID];
   }
 
   void SetDesc(nsCSSCounterDesc aDescID, const nsCSSValue& aValue);
 
   virtual size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const override;
 
+  virtual JSObject* WrapObject(JSContext* aCx,
+                               JS::Handle<JSObject*> aGivenProto) override;
+
 private:
   typedef NS_STDCALL_FUNCPROTO(nsresult, Getter, nsCSSCounterStyleRule,
                                GetSymbols, (nsAString&));
   static const Getter kGetters[];
 
   nsresult GetDescriptor(nsCSSCounterDesc aDescID, nsAString& aValue);
   nsresult SetDescriptor(nsCSSCounterDesc aDescID, const nsAString& aValue);