Bug 1392185 - Remove dynamic HTML5 atoms. r=njn,hsivonen
authorEmilio Cobos Álvarez <emilio@crisal.io>
Fri, 09 Nov 2018 14:27:10 +0100
changeset 445520 e9267d39ec81476831da99bd3b98557877962ca3
parent 445519 48b23717fe953e2970292d90c8979947749fae7f
child 445521 b1d6491fc47e69c118a630a1367bca40af30632f
push id35020
push usershindli@mozilla.com
push dateSat, 10 Nov 2018 21:37:25 +0000
treeherdermozilla-central@39dba5141dd9 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnjn, hsivonen
bugs1392185
milestone65.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 1392185 - Remove dynamic HTML5 atoms. r=njn,hsivonen This is a rebase + manual refcounting on some places, + cleanup of the original patch in the bug. Co-authored-by: Nicholas Nethercote <nnethercote@mozilla.com> Differential Revision: https://phabricator.services.mozilla.com/D11035
parser/html/nsHtml5AtomTable.cpp
parser/html/nsHtml5AtomTable.h
parser/html/nsHtml5AttributeEntry.h
parser/html/nsHtml5AttributeName.cpp
parser/html/nsHtml5AttributeName.h
parser/html/nsHtml5ElementName.h
parser/html/nsHtml5Portability.cpp
parser/html/nsHtml5StackNode.h
parser/html/nsHtml5Tokenizer.h
parser/html/nsHtml5TreeBuilder.h
parser/html/nsHtml5TreeBuilderCppSupplement.h
parser/html/nsHtml5TreeOperation.cpp
parser/html/nsHtml5TreeOperation.h
servo/components/style/gecko_string_cache/mod.rs
xpcom/ds/nsAtom.h
xpcom/ds/nsAtomTable.cpp
--- a/parser/html/nsHtml5AtomTable.cpp
+++ b/parser/html/nsHtml5AtomTable.cpp
@@ -1,63 +1,36 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsHtml5AtomTable.h"
 #include "nsThreadUtils.h"
 
-nsHtml5AtomEntry::nsHtml5AtomEntry(KeyTypePointer aStr)
-  : nsStringHashKey(aStr)
-  , mAtom(nsDynamicAtom::Create(*aStr))
-{
-}
-
-nsHtml5AtomEntry::nsHtml5AtomEntry(nsHtml5AtomEntry&& aOther)
-  : nsStringHashKey(std::move(aOther))
-  , mAtom(nullptr)
-{
-  MOZ_ASSERT_UNREACHABLE("nsHtml5AtomTable is broken; tried to copy an entry");
-}
-
-nsHtml5AtomEntry::~nsHtml5AtomEntry()
-{
-  nsDynamicAtom::Destroy(mAtom);
-}
-
 nsHtml5AtomTable::nsHtml5AtomTable()
   : mRecentlyUsedParserAtoms{}
 {
 #ifdef DEBUG
   mPermittedLookupEventTarget = mozilla::GetCurrentThreadSerialEventTarget();
 #endif
 }
 
 nsHtml5AtomTable::~nsHtml5AtomTable() {}
 
 nsAtom*
 nsHtml5AtomTable::GetAtom(const nsAString& aKey)
 {
 #ifdef DEBUG
-  {
-    MOZ_ASSERT(mPermittedLookupEventTarget->IsOnCurrentThread());
-  }
+  MOZ_ASSERT(mPermittedLookupEventTarget->IsOnCurrentThread());
 #endif
 
   uint32_t index = mozilla::HashString(aKey) % RECENTLY_USED_PARSER_ATOMS_SIZE;
-  nsAtom* cachedAtom = mRecentlyUsedParserAtoms[index];
-  if (cachedAtom && cachedAtom->Equals(aKey)) {
-    return cachedAtom;
+  if (nsAtom* atom = mRecentlyUsedParserAtoms[index]) {
+    if (atom->Equals(aKey)) {
+      return atom;
+    }
   }
 
-  nsStaticAtom* atom = NS_GetStaticAtom(aKey);
-  if (atom) {
-    mRecentlyUsedParserAtoms[index] = atom;
-    return atom;
-  }
-  nsHtml5AtomEntry* entry = mTable.PutEntry(aKey);
-  if (!entry) {
-    return nullptr;
-  }
-
-  mRecentlyUsedParserAtoms[index] = entry->GetAtom();
-  return entry->GetAtom();
+  RefPtr<nsAtom> atom = NS_Atomize(aKey);
+  nsAtom* ret = atom.get();
+  mRecentlyUsedParserAtoms[index] = atom.forget();
+  return ret;
 }
--- a/parser/html/nsHtml5AtomTable.h
+++ b/parser/html/nsHtml5AtomTable.h
@@ -7,28 +7,16 @@
 
 #include "nsHashKeys.h"
 #include "nsTHashtable.h"
 #include "nsAtom.h"
 #include "nsISerialEventTarget.h"
 
 #define RECENTLY_USED_PARSER_ATOMS_SIZE 31
 
-class nsHtml5AtomEntry : public nsStringHashKey
-{
-public:
-  explicit nsHtml5AtomEntry(KeyTypePointer aStr);
-  nsHtml5AtomEntry(nsHtml5AtomEntry&& aOther);
-  ~nsHtml5AtomEntry();
-  inline nsAtom* GetAtom() { return mAtom; }
-
-private:
-  nsDynamicAtom* mAtom;
-};
-
 /**
  * nsHtml5AtomTable provides non-locking lookup and creation of atoms for
  * nsHtml5Parser or nsHtml5StreamParser.
  *
  * The hashtable holds dynamically allocated atoms that are private to an
  * instance of nsHtml5Parser or nsHtml5StreamParser. (Static atoms are used on
  * interned nsHtml5ElementNames and interned nsHtml5AttributeNames. Also, when
  * the doctype name is 'html', that identifier needs to be represented as a
@@ -69,40 +57,38 @@ private:
  * nsHtml5Parser or nsHtml5StreamParser is destructed.
  */
 class nsHtml5AtomTable
 {
 public:
   nsHtml5AtomTable();
   ~nsHtml5AtomTable();
 
-  /**
-   * Obtains the atom for the given string in the scope of this atom table.
-   */
+  // NOTE: We rely on mRecentlyUsedParserAtoms keeping alive the returned atom,
+  // but the caller is responsible to take a reference before calling GetAtom
+  // again.
   nsAtom* GetAtom(const nsAString& aKey);
 
   /**
    * Empties the table.
    */
   void Clear()
   {
     for (uint32_t i = 0; i < RECENTLY_USED_PARSER_ATOMS_SIZE; ++i) {
       mRecentlyUsedParserAtoms[i] = nullptr;
     }
-    mTable.Clear();
   }
 
 #ifdef DEBUG
   void SetPermittedLookupEventTarget(nsISerialEventTarget* aEventTarget)
   {
     mPermittedLookupEventTarget = aEventTarget;
   }
 #endif
 
 private:
-  nsTHashtable<nsHtml5AtomEntry> mTable;
-  nsAtom* mRecentlyUsedParserAtoms[RECENTLY_USED_PARSER_ATOMS_SIZE];
+  RefPtr<nsAtom> mRecentlyUsedParserAtoms[RECENTLY_USED_PARSER_ATOMS_SIZE];
 #ifdef DEBUG
   nsCOMPtr<nsISerialEventTarget> mPermittedLookupEventTarget;
 #endif
 };
 
 #endif // nsHtml5AtomTable_h
--- a/parser/html/nsHtml5AttributeEntry.h
+++ b/parser/html/nsHtml5AttributeEntry.h
@@ -66,26 +66,26 @@ public:
     if (aInterner) {
       // Now if we have an interner, we'll need to rewrite non-static atoms.
       // Only the local names may be non-static, in which case all three
       // are the same.
       nsAtom* local = GetLocal(0);
       if (!local->IsStatic()) {
         nsAutoString str;
         local->ToString(str);
-        local = aInterner->GetAtom(str);
+        nsAtom* local = aInterner->GetAtom(str);
         clone.mLocals[0] = local;
         clone.mLocals[1] = local;
         clone.mLocals[2] = local;
       }
     }
     return clone;
   }
 
 private:
-  nsAtom* mLocals[3];
-  nsAtom* mPrefixes[3];
+  RefPtr<nsAtom> mLocals[3];
+  RefPtr<nsAtom> mPrefixes[3];
   int32_t mUris[3];
   int32_t mLine;
   nsHtml5String mValue;
 };
 
 #endif // nsHtml5AttributeEntry_h
--- a/parser/html/nsHtml5AttributeName.cpp
+++ b/parser/html/nsHtml5AttributeName.cpp
@@ -53,63 +53,63 @@
 #include "nsHtml5Portability.h"
 
 #include "nsHtml5AttributeName.h"
 
 int32_t* nsHtml5AttributeName::ALL_NO_NS = 0;
 int32_t* nsHtml5AttributeName::XMLNS_NS = 0;
 int32_t* nsHtml5AttributeName::XML_NS = 0;
 int32_t* nsHtml5AttributeName::XLINK_NS = 0;
-nsAtom** nsHtml5AttributeName::ALL_NO_PREFIX = 0;
-nsAtom** nsHtml5AttributeName::XMLNS_PREFIX = 0;
-nsAtom** nsHtml5AttributeName::XLINK_PREFIX = 0;
-nsAtom** nsHtml5AttributeName::XML_PREFIX = 0;
-nsAtom**
+nsStaticAtom** nsHtml5AttributeName::ALL_NO_PREFIX = 0;
+nsStaticAtom** nsHtml5AttributeName::XMLNS_PREFIX = 0;
+nsStaticAtom** nsHtml5AttributeName::XLINK_PREFIX = 0;
+nsStaticAtom** nsHtml5AttributeName::XML_PREFIX = 0;
+RefPtr<nsAtom>*
 nsHtml5AttributeName::SVG_DIFFERENT(nsAtom* name, nsAtom* camel)
 {
-  nsAtom** arr = new nsAtom*[4];
+  RefPtr<nsAtom>* arr = new RefPtr<nsAtom>[4];
   arr[0] = name;
   arr[1] = name;
   arr[2] = camel;
   return arr;
 }
 
-nsAtom**
+RefPtr<nsAtom>*
 nsHtml5AttributeName::MATH_DIFFERENT(nsAtom* name, nsAtom* camel)
 {
-  nsAtom** arr = new nsAtom*[4];
+  RefPtr<nsAtom>* arr = new RefPtr<nsAtom>[4];
   arr[0] = name;
   arr[1] = camel;
   arr[2] = name;
   return arr;
 }
 
-nsAtom**
+RefPtr<nsAtom>*
 nsHtml5AttributeName::COLONIFIED_LOCAL(nsAtom* name, nsAtom* suffix)
 {
-  nsAtom** arr = new nsAtom*[4];
+  RefPtr<nsAtom>* arr = new RefPtr<nsAtom>[4];
   arr[0] = name;
   arr[1] = suffix;
   arr[2] = suffix;
   return arr;
 }
 
-nsAtom**
+RefPtr<nsAtom>*
 nsHtml5AttributeName::SAME_LOCAL(nsAtom* name)
 {
-  nsAtom** arr = new nsAtom*[4];
+  RefPtr<nsAtom>* arr = new RefPtr<nsAtom>[4];
   arr[0] = name;
   arr[1] = name;
   arr[2] = name;
   return arr;
 }
 
 nsHtml5AttributeName::nsHtml5AttributeName(int32_t* uri,
-                                           nsAtom** local,
-                                           nsAtom** prefix)
+                                           RefPtr<nsAtom>* local,
+                                           nsStaticAtom** prefix)
   : uri(uri)
   , local(local)
   , prefix(prefix)
   , custom(false)
 {
   MOZ_COUNT_CTOR(nsHtml5AttributeName);
 }
 
@@ -143,17 +143,17 @@ nsHtml5AttributeName::getUri(int32_t mod
 }
 
 nsAtom*
 nsHtml5AttributeName::getLocal(int32_t mode)
 {
   return local[mode];
 }
 
-nsAtom*
+nsStaticAtom*
 nsHtml5AttributeName::getPrefix(int32_t mode)
 {
   return prefix[mode];
 }
 
 bool
 nsHtml5AttributeName::equalsAnother(nsHtml5AttributeName* another)
 {
@@ -762,29 +762,29 @@ nsHtml5AttributeName::initializeStatics(
   XML_NS = new int32_t[3];
   XML_NS[0] = kNameSpaceID_None;
   XML_NS[1] = kNameSpaceID_XML;
   XML_NS[2] = kNameSpaceID_XML;
   XLINK_NS = new int32_t[3];
   XLINK_NS[0] = kNameSpaceID_None;
   XLINK_NS[1] = kNameSpaceID_XLink;
   XLINK_NS[2] = kNameSpaceID_XLink;
-  ALL_NO_PREFIX = new nsAtom*[3];
+  ALL_NO_PREFIX = new nsStaticAtom*[3];
   ALL_NO_PREFIX[0] = nullptr;
   ALL_NO_PREFIX[1] = nullptr;
   ALL_NO_PREFIX[2] = nullptr;
-  XMLNS_PREFIX = new nsAtom*[3];
+  XMLNS_PREFIX = new nsStaticAtom*[3];
   XMLNS_PREFIX[0] = nullptr;
   XMLNS_PREFIX[1] = nsGkAtoms::xmlns;
   XMLNS_PREFIX[2] = nsGkAtoms::xmlns;
-  XLINK_PREFIX = new nsAtom*[3];
+  XLINK_PREFIX = new nsStaticAtom*[3];
   XLINK_PREFIX[0] = nullptr;
   XLINK_PREFIX[1] = nsGkAtoms::xlink;
   XLINK_PREFIX[2] = nsGkAtoms::xlink;
-  XML_PREFIX = new nsAtom*[3];
+  XML_PREFIX = new nsStaticAtom*[3];
   XML_PREFIX[0] = nullptr;
   XML_PREFIX[1] = nsGkAtoms::xml;
   XML_PREFIX[2] = nsGkAtoms::xml;
   ATTR_ALT = new nsHtml5AttributeName(
     ALL_NO_NS, SAME_LOCAL(nsGkAtoms::alt), ALL_NO_PREFIX);
   ATTR_DIR = new nsHtml5AttributeName(
     ALL_NO_NS, SAME_LOCAL(nsGkAtoms::dir), ALL_NO_PREFIX);
   ATTR_DUR = new nsHtml5AttributeName(
--- a/parser/html/nsHtml5AttributeName.h
+++ b/parser/html/nsHtml5AttributeName.h
@@ -58,26 +58,28 @@ class nsHtml5AttributeName
 {
 public:
   static int32_t* ALL_NO_NS;
 private:
   static int32_t* XMLNS_NS;
   static int32_t* XML_NS;
   static int32_t* XLINK_NS;
 public:
-  static nsAtom** ALL_NO_PREFIX;
+  static nsStaticAtom** ALL_NO_PREFIX;
+
 private:
-  static nsAtom** XMLNS_PREFIX;
-  static nsAtom** XLINK_PREFIX;
-  static nsAtom** XML_PREFIX;
-  static nsAtom** SVG_DIFFERENT(nsAtom* name, nsAtom* camel);
-  static nsAtom** MATH_DIFFERENT(nsAtom* name, nsAtom* camel);
-  static nsAtom** COLONIFIED_LOCAL(nsAtom* name, nsAtom* suffix);
+  static nsStaticAtom** XMLNS_PREFIX;
+  static nsStaticAtom** XLINK_PREFIX;
+  static nsStaticAtom** XML_PREFIX;
+  static RefPtr<nsAtom>* SVG_DIFFERENT(nsAtom* name, nsAtom* camel);
+  static RefPtr<nsAtom>* MATH_DIFFERENT(nsAtom* name, nsAtom* camel);
+  static RefPtr<nsAtom>* COLONIFIED_LOCAL(nsAtom* name, nsAtom* suffix);
+
 public:
-  static nsAtom** SAME_LOCAL(nsAtom* name);
+  static RefPtr<nsAtom>* SAME_LOCAL(nsAtom* name);
   inline static int32_t levelOrderBinarySearch(jArray<int32_t, int32_t> data,
                                                int32_t key)
   {
     int32_t n = data.length;
     int32_t i = 0;
     while (i < n) {
       int32_t val = data[i];
       if (val < key) {
@@ -149,37 +151,40 @@ public:
   static const int32_t HTML = 0;
 
   static const int32_t MATHML = 1;
 
   static const int32_t SVG = 2;
 
 private:
   int32_t* uri;
-  nsAtom** local;
-  nsAtom** prefix;
+  RefPtr<nsAtom>* local;
+  nsStaticAtom** prefix;
   bool custom;
-  nsHtml5AttributeName(int32_t* uri, nsAtom** local, nsAtom** prefix);
+  nsHtml5AttributeName(int32_t* uri,
+                       RefPtr<nsAtom>* local,
+                       nsStaticAtom** prefix);
+
 public:
   nsHtml5AttributeName();
   inline bool isInterned() { return !custom; }
 
   inline void setNameForNonInterned(nsAtom* name)
   {
     MOZ_ASSERT(custom);
     local[0] = name;
     local[1] = name;
     local[2] = name;
   }
 
   static nsHtml5AttributeName* createAttributeName(nsAtom* name);
   ~nsHtml5AttributeName();
   int32_t getUri(int32_t mode);
   nsAtom* getLocal(int32_t mode);
-  nsAtom* getPrefix(int32_t mode);
+  nsStaticAtom* getPrefix(int32_t mode);
   bool equalsAnother(nsHtml5AttributeName* another);
   static nsHtml5AttributeName* ATTR_ALT;
   static nsHtml5AttributeName* ATTR_DIR;
   static nsHtml5AttributeName* ATTR_DUR;
   static nsHtml5AttributeName* ATTR_END;
   static nsHtml5AttributeName* ATTR_FOR;
   static nsHtml5AttributeName* ATTR_IN2;
   static nsHtml5AttributeName* ATTR_LOW;
--- a/parser/html/nsHtml5ElementName.h
+++ b/parser/html/nsHtml5ElementName.h
@@ -71,18 +71,18 @@ public:
 
   static const int32_t SCOPING_AS_MATHML = (1 << 25);
 
   static const int32_t HTML_INTEGRATION_POINT = (1 << 24);
 
   static const int32_t OPTIONAL_END_TAG = (1 << 23);
 
 private:
-  nsAtom* name;
-  nsAtom* camelCaseName;
+  RefPtr<nsAtom> name;
+  RefPtr<nsAtom> camelCaseName;
   mozilla::dom::HTMLContentCreatorFunction htmlCreator;
   mozilla::dom::SVGContentCreatorFunction svgCreator;
 public:
   int32_t flags;
   inline nsAtom* getName() { return name; }
 
   inline nsAtom* getCamelCaseName() { return camelCaseName; }
 
--- a/parser/html/nsHtml5Portability.cpp
+++ b/parser/html/nsHtml5Portability.cpp
@@ -12,16 +12,24 @@ nsAtom*
 nsHtml5Portability::newLocalNameFromBuffer(char16_t* buf,
                                            int32_t length,
                                            nsHtml5AtomTable* interner)
 {
   NS_ASSERTION(interner, "Didn't get an atom service.");
   return interner->GetAtom(nsDependentSubstring(buf, buf + length));
 }
 
+nsAtom*
+nsHtml5Portability::newLocalFromLocal(nsAtom* local,
+                                      nsHtml5AtomTable* interner)
+{
+  // FIXME(emilio): This function should be removed.
+  return local;
+}
+
 static bool
 ContainsWhiteSpace(mozilla::Span<char16_t> aSpan)
 {
   for (char16_t c : aSpan) {
     if (nsContentUtils::IsHTMLWhitespace(c)) {
       return true;
     }
   }
@@ -81,29 +89,16 @@ nsHtml5Portability::newCharArrayFromStri
   MOZ_RELEASE_ASSERT(string);
   uint32_t len = string.Length();
   MOZ_RELEASE_ASSERT(len < INT32_MAX);
   jArray<char16_t, int32_t> arr = jArray<char16_t, int32_t>::newJArray(len);
   string.CopyToBuffer(arr);
   return arr;
 }
 
-nsAtom*
-nsHtml5Portability::newLocalFromLocal(nsAtom* local, nsHtml5AtomTable* interner)
-{
-  MOZ_ASSERT(local, "Atom was null.");
-  MOZ_ASSERT(interner, "Atom table was null");
-  if (!local->IsStatic()) {
-    nsAutoString str;
-    local->ToString(str);
-    local = interner->GetAtom(str);
-  }
-  return local;
-}
-
 bool
 nsHtml5Portability::localEqualsBuffer(nsAtom* local,
                                       char16_t* buf,
                                       int32_t length)
 {
   return local->Equals(buf, length);
 }
 
--- a/parser/html/nsHtml5StackNode.h
+++ b/parser/html/nsHtml5StackNode.h
@@ -56,18 +56,18 @@ class nsHtml5UTF16Buffer;
 class nsHtml5StateSnapshot;
 class nsHtml5Portability;
 
 class nsHtml5StackNode
 {
 public:
   int32_t idxInTreeBuilder;
   int32_t flags;
-  nsAtom* name;
-  nsAtom* popName;
+  RefPtr<nsAtom> name;
+  RefPtr<nsAtom> popName;
   int32_t ns;
   nsIContentHandle* node;
   nsHtml5HtmlAttributes* attributes;
 private:
   int32_t refcount;
   mozilla::dom::HTMLContentCreatorFunction htmlCreator;
 public:
   inline int32_t getFlags() { return flags; }
--- a/parser/html/nsHtml5Tokenizer.h
+++ b/parser/html/nsHtml5Tokenizer.h
@@ -277,17 +277,17 @@ protected:
 private:
   bool containsHyphen;
   nsHtml5ElementName* tagName;
   nsHtml5ElementName* nonInternedTagName;
 protected:
   nsHtml5AttributeName* attributeName;
 private:
   nsHtml5AttributeName* nonInternedAttributeName;
-  nsAtom* doctypeName;
+  RefPtr<nsAtom> doctypeName;
   nsHtml5String publicIdentifier;
   nsHtml5String systemIdentifier;
   nsHtml5HtmlAttributes* attributes;
   bool newAttributesEachTime;
   bool shouldSuspend;
 protected:
   bool confident;
 private:
--- a/parser/html/nsHtml5TreeBuilder.h
+++ b/parser/html/nsHtml5TreeBuilder.h
@@ -288,17 +288,17 @@ private:
   int32_t originalMode;
   bool framesetOk;
 protected:
   nsHtml5Tokenizer* tokenizer;
 private:
   bool scriptingEnabled;
   bool needToDropLF;
   bool fragment;
-  nsAtom* contextName;
+  RefPtr<nsAtom> contextName;
   int32_t contextNamespace;
   nsIContentHandle* contextNode;
   autoJArray<int32_t, int32_t> templateModeStack;
   int32_t templateModePtr;
   autoJArray<nsHtml5StackNode*, int32_t> stackNodes;
   int32_t stackNodesIdx;
   int32_t numStackNodes;
   autoJArray<nsHtml5StackNode*, int32_t> stack;
--- a/parser/html/nsHtml5TreeBuilderCppSupplement.h
+++ b/parser/html/nsHtml5TreeBuilderCppSupplement.h
@@ -107,48 +107,46 @@ nsHtml5TreeBuilder::createElement(int32_
   MOZ_ASSERT(aAttributes, "Got null attributes.");
   MOZ_ASSERT(aName, "Got null name.");
   MOZ_ASSERT(aNamespace == kNameSpaceID_XHTML ||
                aNamespace == kNameSpaceID_SVG ||
                aNamespace == kNameSpaceID_MathML,
              "Bogus namespace.");
 
   if (mBuilder) {
-    RefPtr<nsAtom> name = nsHtml5TreeOperation::Reget(aName);
-
     nsIContent* intendedParent =
       aIntendedParent ? static_cast<nsIContent*>(aIntendedParent) : nullptr;
 
     // intendedParent == nullptr is a special case where the
     // intended parent is the document.
     nsNodeInfoManager* nodeInfoManager =
       intendedParent ? intendedParent->OwnerDoc()->NodeInfoManager()
                      : mBuilder->GetNodeInfoManager();
 
     nsIContent* elem;
     if (aNamespace == kNameSpaceID_XHTML) {
       elem = nsHtml5TreeOperation::CreateHTMLElement(
-        name,
+        aName,
         aAttributes,
         mozilla::dom::FROM_PARSER_FRAGMENT,
         nodeInfoManager,
         mBuilder,
         aCreator.html);
     } else if (aNamespace == kNameSpaceID_SVG) {
       elem = nsHtml5TreeOperation::CreateSVGElement(
-        name,
+        aName,
         aAttributes,
         mozilla::dom::FROM_PARSER_FRAGMENT,
         nodeInfoManager,
         mBuilder,
         aCreator.svg);
     } else {
       MOZ_ASSERT(aNamespace == kNameSpaceID_MathML);
       elem = nsHtml5TreeOperation::CreateMathMLElement(
-        name, aAttributes, nodeInfoManager, mBuilder);
+        aName, aAttributes, nodeInfoManager, mBuilder);
     }
     if (MOZ_UNLIKELY(aAttributes != tokenizer->GetAttributes() &&
                      aAttributes != nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES)) {
       delete aAttributes;
     }
     return elem;
   }
 
@@ -902,19 +900,18 @@ nsHtml5TreeBuilder::appendDoctypeToDocum
                                             nsHtml5String aSystemId)
 {
   MOZ_ASSERT(aName, "Null name");
   nsString publicId; // Not Auto, because using it to hold nsStringBuffer*
   nsString systemId; // Not Auto, because using it to hold nsStringBuffer*
   aPublicId.ToString(publicId);
   aSystemId.ToString(systemId);
   if (mBuilder) {
-    RefPtr<nsAtom> name = nsHtml5TreeOperation::Reget(aName);
     nsresult rv = nsHtml5TreeOperation::AppendDoctypeToDocument(
-      name, publicId, systemId, mBuilder);
+      aName, publicId, systemId, mBuilder);
     if (NS_FAILED(rv)) {
       MarkAsBrokenAndRequestSuspensionWithBuilder(rv);
     }
     return;
   }
 
   nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement(mozilla::fallible);
   if (MOZ_UNLIKELY(!treeOp)) {
--- a/parser/html/nsHtml5TreeOperation.cpp
+++ b/parser/html/nsHtml5TreeOperation.cpp
@@ -97,19 +97,29 @@ nsHtml5TreeOperation::~nsHtml5TreeOperat
     case eTreeOpAddAttributes:
       delete mTwo.attributes;
       break;
     case eTreeOpCreateHTMLElementNetwork:
     case eTreeOpCreateHTMLElementNotNetwork:
     case eTreeOpCreateSVGElementNetwork:
     case eTreeOpCreateSVGElementNotNetwork:
     case eTreeOpCreateMathMLElement:
+      mTwo.atom->Release();
       delete mThree.attributes;
       break;
+    case eTreeOpAddError:
+      if (mThree.atom) {
+        mThree.atom->Release();
+      }
+      if (mFour.atom) {
+        mFour.atom->Release();
+      }
+      break;
     case eTreeOpAppendDoctypeToDocument:
+      mOne.atom->Release();
       delete mTwo.stringPair;
       break;
     case eTreeOpFosterParentText:
     case eTreeOpAppendText:
     case eTreeOpAppendComment:
     case eTreeOpAppendCommentToDocument:
     case eTreeOpAddViewSourceHref:
     case eTreeOpAddViewSourceBase:
@@ -298,23 +308,19 @@ nsHtml5TreeOperation::AddAttributes(nsIC
                                     nsHtml5DocumentBuilder* aBuilder)
 {
   dom::Element* node = aNode->AsElement();
   nsHtml5OtherDocUpdate update(node->OwnerDoc(), aBuilder->GetDocument());
 
   int32_t len = aAttributes->getLength();
   for (int32_t i = len; i > 0;) {
     --i;
-    // prefix doesn't need regetting. it is always null or a static atom
-    // local name is never null
-    RefPtr<nsAtom> localName = Reget(aAttributes->getLocalNameNoBoundsCheck(i));
+    nsAtom* localName = aAttributes->getLocalNameNoBoundsCheck(i);
     int32_t nsuri = aAttributes->getURINoBoundsCheck(i);
     if (!node->HasAttr(nsuri, localName)) {
-      // prefix doesn't need regetting. it is always null or a static atom
-      // local name is never null
       nsString value; // Not Auto, because using it to hold nsStringBuffer*
       aAttributes->getValueNoBoundsCheck(i).ToString(value);
       node->SetAttr(
         nsuri, localName, aAttributes->getPrefixNoBoundsCheck(i), value, true);
       // XXX what to do with nsresult?
     }
   }
   return NS_OK;
@@ -328,21 +334,18 @@ nsHtml5TreeOperation::SetHTMLElementAttr
 {
   int32_t len = aAttributes->getLength();
   for (int32_t i = 0; i < len; i++) {
     nsHtml5String val = aAttributes->getValueNoBoundsCheck(i);
     nsAtom* klass = val.MaybeAsAtom();
     if (klass) {
       aElement->SetSingleClassFromParser(klass);
     } else {
-      // prefix doesn't need regetting. it is always null or a static atom
-      // local name is never null
-      RefPtr<nsAtom> localName =
-        Reget(aAttributes->getLocalNameNoBoundsCheck(i));
-      RefPtr<nsAtom> prefix = aAttributes->getPrefixNoBoundsCheck(i);
+      nsAtom* localName = aAttributes->getLocalNameNoBoundsCheck(i);
+      nsAtom* prefix = aAttributes->getPrefixNoBoundsCheck(i);
       int32_t nsuri = aAttributes->getURINoBoundsCheck(i);
 
       nsString value; // Not Auto, because using it to hold nsStringBuffer*
       val.ToString(value);
       if (nsGkAtoms::a == aName && nsGkAtoms::name == localName) {
         // This is an HTML5-incompliant Geckoism.
         // Remove when fixing bug 582361
         NS_ConvertUTF16toUTF8 cname(value);
@@ -558,21 +561,18 @@ nsHtml5TreeOperation::CreateSVGElement(
 
   int32_t len = aAttributes->getLength();
   for (int32_t i = 0; i < len; i++) {
     nsHtml5String val = aAttributes->getValueNoBoundsCheck(i);
     nsAtom* klass = val.MaybeAsAtom();
     if (klass) {
       newContent->SetSingleClassFromParser(klass);
     } else {
-      // prefix doesn't need regetting. it is always null or a static atom
-      // local name is never null
-      RefPtr<nsAtom> localName =
-        Reget(aAttributes->getLocalNameNoBoundsCheck(i));
-      RefPtr<nsAtom> prefix = aAttributes->getPrefixNoBoundsCheck(i);
+      nsAtom* localName = aAttributes->getLocalNameNoBoundsCheck(i);
+      nsAtom* prefix = aAttributes->getPrefixNoBoundsCheck(i);
       int32_t nsuri = aAttributes->getURINoBoundsCheck(i);
 
       nsString value; // Not Auto, because using it to hold nsStringBuffer*
       val.ToString(value);
       newContent->SetAttr(nsuri, localName, prefix, value, false);
     }
   }
   return newContent;
@@ -612,21 +612,18 @@ nsHtml5TreeOperation::CreateMathMLElemen
 
   int32_t len = aAttributes->getLength();
   for (int32_t i = 0; i < len; i++) {
     nsHtml5String val = aAttributes->getValueNoBoundsCheck(i);
     nsAtom* klass = val.MaybeAsAtom();
     if (klass) {
       newContent->SetSingleClassFromParser(klass);
     } else {
-      // prefix doesn't need regetting. it is always null or a static atom
-      // local name is never null
-      RefPtr<nsAtom> localName =
-        Reget(aAttributes->getLocalNameNoBoundsCheck(i));
-      RefPtr<nsAtom> prefix = aAttributes->getPrefixNoBoundsCheck(i);
+      nsAtom* localName = aAttributes->getLocalNameNoBoundsCheck(i);
+      nsAtom* prefix = aAttributes->getPrefixNoBoundsCheck(i);
       int32_t nsuri = aAttributes->getURINoBoundsCheck(i);
 
       nsString value; // Not Auto, because using it to hold nsStringBuffer*
       val.ToString(value);
       newContent->SetAttr(nsuri, localName, prefix, value, false);
     }
   }
   return newContent;
@@ -841,17 +838,17 @@ nsHtml5TreeOperation::Perform(nsHtml5Tre
     case eTreeOpDocumentMode: {
       aBuilder->SetDocumentMode(mOne.mode);
       return NS_OK;
     }
     case eTreeOpCreateHTMLElementNetwork:
     case eTreeOpCreateHTMLElementNotNetwork: {
       nsIContent** target = mOne.node;
       mozilla::dom::HTMLContentCreatorFunction creator = mFour.htmlCreator;
-      RefPtr<nsAtom> name = Reget(mTwo.atom);
+      nsAtom* name = mTwo.atom;
       nsHtml5HtmlAttributes* attributes = mThree.attributes;
       nsIContent* intendedParent = mFive.node ? *(mFive.node) : nullptr;
 
       // intendedParent == nullptr is a special case where the
       // intended parent is the document.
       nsNodeInfoManager* nodeInfoManager =
         intendedParent ? intendedParent->OwnerDoc()->NodeInfoManager()
                        : aBuilder->GetNodeInfoManager();
@@ -865,17 +862,17 @@ nsHtml5TreeOperation::Perform(nsHtml5Tre
                                   aBuilder,
                                   creator);
       return NS_OK;
     }
     case eTreeOpCreateSVGElementNetwork:
     case eTreeOpCreateSVGElementNotNetwork: {
       nsIContent** target = mOne.node;
       mozilla::dom::SVGContentCreatorFunction creator = mFour.svgCreator;
-      RefPtr<nsAtom> name = Reget(mTwo.atom);
+      nsAtom* name = mTwo.atom;
       nsHtml5HtmlAttributes* attributes = mThree.attributes;
       nsIContent* intendedParent = mFive.node ? *(mFive.node) : nullptr;
 
       // intendedParent == nullptr is a special case where the
       // intended parent is the document.
       nsNodeInfoManager* nodeInfoManager =
         intendedParent ? intendedParent->OwnerDoc()->NodeInfoManager()
                        : aBuilder->GetNodeInfoManager();
@@ -887,17 +884,17 @@ nsHtml5TreeOperation::Perform(nsHtml5Tre
                                    : dom::FROM_PARSER_DOCUMENT_WRITE,
                                  nodeInfoManager,
                                  aBuilder,
                                  creator);
       return NS_OK;
     }
     case eTreeOpCreateMathMLElement: {
       nsIContent** target = mOne.node;
-      RefPtr<nsAtom> name = Reget(mTwo.atom);
+      nsAtom* name = mTwo.atom;
       nsHtml5HtmlAttributes* attributes = mThree.attributes;
       nsIContent* intendedParent = mFive.node ? *(mFive.node) : nullptr;
 
       // intendedParent == nullptr is a special case where the
       // intended parent is the document.
       nsNodeInfoManager* nodeInfoManager =
         intendedParent ? intendedParent->OwnerDoc()->NodeInfoManager()
                        : aBuilder->GetNodeInfoManager();
@@ -932,17 +929,17 @@ nsHtml5TreeOperation::Perform(nsHtml5Tre
       return AppendComment(parent, buffer, length, aBuilder);
     }
     case eTreeOpAppendCommentToDocument: {
       char16_t* buffer = mTwo.unicharPtr;
       int32_t length = mFour.integer;
       return AppendCommentToDocument(buffer, length, aBuilder);
     }
     case eTreeOpAppendDoctypeToDocument: {
-      RefPtr<nsAtom> name = Reget(mOne.atom);
+      nsAtom* name = mOne.atom;
       nsHtml5TreeOperationStringPair* pair = mTwo.stringPair;
       nsString publicId;
       nsString systemId;
       pair->Get(publicId, systemId);
       return AppendDoctypeToDocument(name, publicId, systemId, aBuilder);
     }
     case eTreeOpGetDocumentFragmentForTemplate: {
       nsIContent* node = *(mOne.node);
@@ -1142,18 +1139,18 @@ nsHtml5TreeOperation::Perform(nsHtml5Tre
       int32_t length = mFour.integer;
       nsDependentString baseUrl(buffer, length);
       aBuilder->AddBase(baseUrl);
       return NS_OK;
     }
     case eTreeOpAddError: {
       Element* element = (*(mOne.node))->AsElement();
       char* msgId = mTwo.charPtr;
-      RefPtr<nsAtom> atom = Reget(mThree.atom);
-      RefPtr<nsAtom> otherAtom = Reget(mFour.atom);
+      nsAtom* atom = mThree.atom;
+      nsAtom* otherAtom = mFour.atom;
       // See viewsource.css for the possible classes in addition to "error".
       nsAutoString klass;
       element->GetAttr(kNameSpaceID_None, nsGkAtoms::_class, klass);
       if (!klass.IsEmpty()) {
         klass.AppendLiteral(" error");
         element->SetAttr(kNameSpaceID_None, nsGkAtoms::_class, klass, true);
       } else {
         element->SetAttr(kNameSpaceID_None,
--- a/parser/html/nsHtml5TreeOperation.h
+++ b/parser/html/nsHtml5TreeOperation.h
@@ -101,38 +101,16 @@ public:
 
 class nsHtml5TreeOperation final
 {
   template<typename T>
   using NotNull = mozilla::NotNull<T>;
   using Encoding = mozilla::Encoding;
 
 public:
-  /**
-   * Atom is used inside the parser core are either static atoms that are
-   * the same as Gecko-wide static atoms or they are dynamic atoms scoped by
-   * both thread and parser to a particular nsHtml5AtomTable. In order to
-   * such scoped atoms coming into contact with the rest of Gecko, atoms
-   * that are about to exit the parser must go through this method which
-   * reobtains dynamic atoms from the Gecko-global atom table.
-   *
-   * @param aAtom a potentially parser-scoped atom
-   * @return an nsAtom that's pointer comparable on the main thread with
-   *         other not-parser atoms.
-   */
-  static inline already_AddRefed<nsAtom> Reget(nsAtom* aAtom)
-  {
-    if (!aAtom || aAtom->IsStatic()) {
-      return dont_AddRef(aAtom);
-    }
-    nsAutoString str;
-    aAtom->ToString(str);
-    return NS_AtomizeMainThread(str);
-  }
-
   static nsresult AppendTextToTextNode(const char16_t* aBuffer,
                                        uint32_t aLength,
                                        mozilla::dom::Text* aTextNode,
                                        nsHtml5DocumentBuilder* aBuilder);
 
   static nsresult AppendText(const char16_t* aBuffer,
                              uint32_t aLength,
                              nsIContent* aParent,
@@ -365,16 +343,17 @@ public:
       mFour.svgCreator = aCreator.svg;
     } else {
       MOZ_ASSERT(aNamespace == kNameSpaceID_MathML);
       mOpCode = eTreeOpCreateMathMLElement;
     }
     mFive.node = static_cast<nsIContent**>(aIntendedParent);
     mOne.node = static_cast<nsIContent**>(aTarget);
     mTwo.atom = aName;
+    aName->AddRef();
     if (aAttributes == nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES) {
       mThree.attributes = nullptr;
     } else {
       mThree.attributes = aAttributes;
     }
   }
 
   inline void Init(eHtml5TreeOperation aOpCode,
@@ -429,35 +408,43 @@ public:
     mOne.node = static_cast<nsIContent**>(aElement);
     mTwo.attributes = aAttributes;
   }
 
   inline void Init(nsAtom* aName,
                    const nsAString& aPublicId,
                    const nsAString& aSystemId)
   {
+    MOZ_ASSERT(aName);
     MOZ_ASSERT(mOpCode == eTreeOpUninitialized,
                "Op code must be uninitialized when initializing.");
     mOpCode = eTreeOpAppendDoctypeToDocument;
     mOne.atom = aName;
+    aName->AddRef();
     mTwo.stringPair = new nsHtml5TreeOperationStringPair(aPublicId, aSystemId);
   }
 
   inline void Init(nsIContentHandle* aElement,
                    const char* aMsgId,
                    nsAtom* aAtom,
                    nsAtom* aOtherAtom)
   {
     MOZ_ASSERT(mOpCode == eTreeOpUninitialized,
                "Op code must be uninitialized when initializing.");
     mOpCode = eTreeOpAddError;
     mOne.node = static_cast<nsIContent**>(aElement);
     mTwo.charPtr = (char*)aMsgId;
     mThree.atom = aAtom;
     mFour.atom = aOtherAtom;
+    if (aAtom) {
+      aAtom->AddRef();
+    }
+    if (aOtherAtom) {
+      aOtherAtom->AddRef();
+    }
   }
 
   inline void Init(nsIContentHandle* aElement,
                    const char* aMsgId,
                    nsAtom* aAtom)
   {
     Init(aElement, aMsgId, aAtom, nullptr);
   }
--- a/servo/components/style/gecko_string_cache/mod.rs
+++ b/servo/components/style/gecko_string_cache/mod.rs
@@ -9,17 +9,17 @@
 #![allow(non_upper_case_globals)]
 
 //! A drop-in replacement for string_cache, but backed by Gecko `nsAtom`s.
 
 use gecko_bindings::bindings::Gecko_AddRefAtom;
 use gecko_bindings::bindings::Gecko_Atomize;
 use gecko_bindings::bindings::Gecko_Atomize16;
 use gecko_bindings::bindings::Gecko_ReleaseAtom;
-use gecko_bindings::structs::{nsAtom, nsAtom_AtomKind, nsDynamicAtom, nsStaticAtom};
+use gecko_bindings::structs::{nsAtom, nsDynamicAtom, nsStaticAtom};
 use nsstring::{nsAString, nsStr};
 use precomputed_hash::PrecomputedHash;
 use std::borrow::{Borrow, Cow};
 use std::char::{self, DecodeUtf16};
 use std::fmt::{self, Write};
 use std::hash::{Hash, Hasher};
 use std::iter::Cloned;
 use std::ops::Deref;
@@ -170,17 +170,17 @@ impl WeakAtom {
         };
 
         cb(utf8_slice)
     }
 
     /// Returns whether this atom is static.
     #[inline]
     pub fn is_static(&self) -> bool {
-        unsafe { (*self.as_ptr()).mKind() == nsAtom_AtomKind::Static as u32 }
+        unsafe { (*self.as_ptr()).mIsStatic() != 0 }
     }
 
     /// Returns the length of the atom string.
     #[inline]
     pub fn len(&self) -> u32 {
         unsafe { (*self.as_ptr()).mLength() }
     }
 
--- a/xpcom/ds/nsAtom.h
+++ b/xpcom/ds/nsAtom.h
@@ -33,49 +33,29 @@ class nsDynamicAtom;
 //   extremely rare case.
 //
 class nsAtom
 {
 public:
   void AddSizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf,
                               mozilla::AtomsSizes& aSizes) const;
 
-  // Dynamic HTML5 atoms are just like vanilla dynamic atoms, but we disallow
-  // various operations, the most important of which is AddRef/Release.
-  // XXX: we'd like to get rid of dynamic HTML5 atoms. See bug 1392185 for
-  // details.
-  enum class AtomKind : uint8_t {
-    Static = 0,
-    DynamicNormal = 1,
-    DynamicHTML5 = 2,
-  };
-
   bool Equals(char16ptr_t aString, uint32_t aLength) const
   {
     return mLength == aLength &&
            memcmp(GetUTF16String(), aString, mLength * sizeof(char16_t)) == 0;
   }
 
   bool Equals(const nsAString& aString) const
   {
     return Equals(aString.BeginReading(), aString.Length());
   }
 
-  AtomKind Kind() const { return static_cast<AtomKind>(mKind); }
-
-  bool IsStatic() const { return Kind() == AtomKind::Static; }
-  bool IsDynamic() const
-  {
-    return Kind() == AtomKind::DynamicNormal ||
-           Kind() == AtomKind::DynamicHTML5;
-  }
-  bool IsDynamicHTML5() const
-  {
-    return Kind() == AtomKind::DynamicHTML5;
-  }
+  bool IsStatic() const { return mIsStatic; }
+  bool IsDynamic() const { return !IsStatic(); }
 
   const nsStaticAtom* AsStatic() const;
   const nsDynamicAtom* AsDynamic() const;
   nsDynamicAtom* AsDynamic();
 
   char16ptr_t GetUTF16String() const;
 
   uint32_t GetLength() const { return mLength; }
@@ -88,51 +68,46 @@ public:
   void ToString(nsAString& aString) const;
   void ToUTF8String(nsACString& aString) const;
 
   // A hashcode that is better distributed than the actual atom pointer, for
   // use in situations that need a well-distributed hashcode. It's called hash()
   // rather than Hash() so we can use mozilla::BloomFilter<N, nsAtom>, because
   // BloomFilter requires elements to implement a function called hash().
   //
-  uint32_t hash() const
-  {
-    MOZ_ASSERT(!IsDynamicHTML5());
-    return mHash;
-  }
+  uint32_t hash() const { return mHash; }
 
   // We can't use NS_INLINE_DECL_THREADSAFE_REFCOUNTING because the refcounting
   // of this type is special.
   MozExternalRefCountType AddRef();
   MozExternalRefCountType Release();
 
   typedef mozilla::TrueType HasThreadSafeRefCnt;
 
 protected:
   // Used by nsStaticAtom.
   constexpr nsAtom(uint32_t aLength, uint32_t aHash)
     : mLength(aLength)
-    , mKind(static_cast<uint32_t>(nsAtom::AtomKind::Static))
+    , mIsStatic(true)
     , mHash(aHash)
   {}
 
   // Used by nsDynamicAtom.
-  nsAtom(AtomKind aKind, const nsAString& aString, uint32_t aHash)
+  nsAtom(const nsAString& aString, uint32_t aHash)
     : mLength(aString.Length())
-    , mKind(static_cast<uint32_t>(aKind))
+    , mIsStatic(false)
     , mHash(aHash)
   {
-    MOZ_ASSERT(aKind == AtomKind::DynamicNormal ||
-               aKind == AtomKind::DynamicHTML5);
   }
 
   ~nsAtom() = default;
 
   const uint32_t mLength:30;
-  const uint32_t mKind:2; // nsAtom::AtomKind
+  // NOTE: There's one free bit here.
+  const uint32_t mIsStatic:1;
   const uint32_t mHash;
 };
 
 // This class would be |final| if it wasn't for nsCSSAnonBoxPseudoStaticAtom
 // and nsCSSPseudoElementStaticAtom, which are trivial subclasses used to
 // ensure only certain static atoms are passed to certain functions.
 class nsStaticAtom : public nsAtom
 {
@@ -184,18 +159,16 @@ public:
   static nsDynamicAtom* FromChars(char16_t* chars)
   {
     return reinterpret_cast<nsDynamicAtom*>(chars) - 1;
   }
 
 private:
   friend class nsAtomTable;
   friend class nsAtomSubTable;
-  // XXX: we'd like to remove nsHtml5AtomEntry. See bug 1392185.
-  friend class nsHtml5AtomEntry;
 
   // These shouldn't be used directly, even by friend classes. The
   // Create()/Destroy() methods use them.
   static nsDynamicAtom* CreateInner(const nsAString& aString, uint32_t aHash);
   nsDynamicAtom(const nsAString& aString, uint32_t aHash);
   ~nsDynamicAtom() {}
 
   // Creation/destruction is done by friend classes. The first Create() is for
--- a/xpcom/ds/nsAtomTable.cpp
+++ b/xpcom/ds/nsAtomTable.cpp
@@ -62,17 +62,17 @@ enum class GCKind {
 // we wouldn't use overflow value for comparison.
 // See nsAtom::AddRef() and nsAtom::Release().
 // This atomic can be accessed during the GC and other places where recorded
 // events are not allowed, so its value is not preserved when recording or
 // replaying.
 static Atomic<int32_t, ReleaseAcquire, recordreplay::Behavior::DontPreserve> gUnusedAtomCount(0);
 
 nsDynamicAtom::nsDynamicAtom(const nsAString& aString, uint32_t aHash)
-  : nsAtom(AtomKind::DynamicNormal, aString, aHash)
+  : nsAtom(aString, aHash)
   , mRefCnt(1)
 {
 }
 
 nsDynamicAtom*
 nsDynamicAtom::CreateInner(const nsAString& aString, uint32_t aHash)
 {
   // We tack the chars onto the end of the nsDynamicAtom object.
@@ -144,28 +144,23 @@ nsAtom::ToString(nsAString& aString) con
   } else {
     aString.Assign(AsDynamic()->String(), mLength);
   }
 }
 
 void
 nsAtom::ToUTF8String(nsACString& aBuf) const
 {
-  MOZ_ASSERT(!IsDynamicHTML5(),
-             "Called ToUTF8String() on a dynamic HTML5 atom");
   CopyUTF16toUTF8(nsDependentString(GetUTF16String(), mLength), aBuf);
 }
 
 void
 nsAtom::AddSizeOfIncludingThis(MallocSizeOf aMallocSizeOf, AtomsSizes& aSizes)
   const
 {
-  MOZ_ASSERT(!IsDynamicHTML5(),
-             "Called AddSizeOfIncludingThis() on a dynamic HTML5 atom");
-
   // Static atoms are in static memory, and so are not measured here.
   if (IsDynamic()) {
     aSizes.mDynamicAtoms += aMallocSizeOf(this);
   }
 }
 
 char16ptr_t
 nsAtom::GetUTF16String() const
@@ -490,17 +485,16 @@ nsAtomSubTable::GCLocked(GCKind aKind)
   uint32_t nonZeroRefcountAtomsCount = 0;
   for (auto i = mTable.Iter(); !i.Done(); i.Next()) {
     auto entry = static_cast<AtomTableEntry*>(i.Get());
     if (entry->mAtom->IsStatic()) {
       continue;
     }
 
     nsAtom* atom = entry->mAtom;
-    MOZ_ASSERT(!atom->IsDynamicHTML5());
     if (atom->IsDynamic() && atom->AsDynamic()->mRefCnt == 0) {
       i.Remove();
       nsDynamicAtom::Destroy(atom->AsDynamic());
       ++removedCount;
     }
 #ifdef NS_FREE_PERMANENT_DATA
     else if (aKind == GCKind::Shutdown && PR_GetEnv("XPCOM_MEM_BLOAT_LOG")) {
       // Only report leaking atoms in leak-checking builds in a run where we
@@ -569,26 +563,22 @@ nsDynamicAtom::Release()
   }
 
   return count;
 }
 
 MozExternalRefCountType
 nsAtom::AddRef()
 {
-  MOZ_ASSERT(!IsDynamicHTML5(), "Attempt to AddRef a dynamic HTML5 atom");
-
   return IsStatic() ? 2 : AsDynamic()->AddRef();
 }
 
 MozExternalRefCountType
 nsAtom::Release()
 {
-  MOZ_ASSERT(!IsDynamicHTML5(), "Attempt to Release a dynamic HTML5 atom");
-
   return IsStatic() ? 1 : AsDynamic()->Release();
 }
 
 //----------------------------------------------------------------------
 
 // Have the static atoms been inserted into the table?
 static bool gStaticAtomsDone = false;