Bug 1400459 (part 2) - Devirtualize nsIAtom. r=froydnj. draft
authorNicholas Nethercote <nnethercote@mozilla.com>
Tue, 26 Sep 2017 08:33:21 +1000
changeset 670903 d95ad1fea6c89fff59b23d52550b584d5ea66312
parent 670875 70158e4e215d784d1391db5e517b18727f4b3683
child 733358 8c3437e39a2b66ac15301db0fc8b63538fb4722f
push id81762
push usernnethercote@mozilla.com
push dateWed, 27 Sep 2017 04:55:21 +0000
reviewersfroydnj
bugs1400459
milestone58.0a1
Bug 1400459 (part 2) - Devirtualize nsIAtom. r=froydnj. This patch merges nsAtom into nsIAtom. For the moment, both names can be used interchangeably due to a typedef. The patch also devirtualizes nsIAtom, by making it not inherit from nsISupports, removing NS_DECL_NSIATOM, and dropping the use of NS_IMETHOD_. It also removes nsIAtom's IIDs. These changes trigger knock-on changes throughout the codebase, changing the types of lots of things as follows. - nsCOMPtr<nsIAtom> --> RefPtr<nsIAtom> - nsCOMArray<nsIAtom> --> nsTArray<RefPtr<nsIAtom>> - Count() --> Length() - ObjectAt() --> ElementAt() - AppendObject() --> AppendElement() - RemoveObjectAt() --> RemoveElementAt() - ns*Hashtable<nsISupportsHashKey, ...> --> ns*Hashtable<nsRefPtrHashKey<nsIAtom>, ...> - nsInterfaceHashtable<T, nsIAtom> --> nsRefPtrHashtable<T, nsIAtom> - This requires adding a Get() method to nsRefPtrHashtable that it lacks but nsInterfaceHashtable has. - nsCOMPtr<nsIMutableArray> --> nsTArray<RefPtr<nsIAtom>> - nsArrayBase::Create() --> nsTArray() - GetLength() --> Length() - do_QueryElementAt() --> operator[] The patch also has some changes to Rust code that manipulates nsIAtom. MozReview-Commit-ID: DykOl8aEnUJ
accessible/base/AccEvent.h
caps/BasePrincipal.h
docshell/base/nsDocShell.cpp
dom/base/AnonymousContent.cpp
dom/base/Attr.cpp
dom/base/CustomElementRegistry.cpp
dom/base/CustomElementRegistry.h
dom/base/DOMImplementation.cpp
dom/base/Element.cpp
dom/base/FragmentOrElement.cpp
dom/base/nsAttrValue.cpp
dom/base/nsAttrValue.h
dom/base/nsContentList.cpp
dom/base/nsContentList.h
dom/base/nsContentSink.cpp
dom/base/nsContentUtils.cpp
dom/base/nsContentUtils.h
dom/base/nsDOMMutationObserver.cpp
dom/base/nsDOMMutationObserver.h
dom/base/nsDOMTokenList.h
dom/base/nsDOMWindowUtils.cpp
dom/base/nsDocument.cpp
dom/base/nsDocument.h
dom/base/nsGenericDOMDataNode.cpp
dom/base/nsINode.cpp
dom/base/nsIdentifierMapEntry.h
dom/base/nsNameSpaceManager.cpp
dom/base/nsNameSpaceManager.h
dom/base/nsNodeInfoManager.cpp
dom/base/nsPropertyTable.cpp
dom/base/nsReferencedElement.cpp
dom/base/nsReferencedElement.h
dom/base/nsTextNode.cpp
dom/base/nsTreeSanitizer.cpp
dom/base/nsTreeSanitizer.h
dom/base/nsXMLNameSpaceMap.h
dom/canvas/CanvasRenderingContext2D.h
dom/events/DOMEventTargetHelper.h
dom/events/DataTransfer.cpp
dom/events/EventListenerManager.cpp
dom/events/EventListenerManager.h
dom/events/EventListenerService.cpp
dom/events/EventListenerService.h
dom/events/EventTarget.cpp
dom/events/EventTarget.h
dom/events/InternalMutationEvent.h
dom/events/JSEventHandler.h
dom/html/HTMLAllCollection.cpp
dom/html/HTMLTableElement.cpp
dom/html/nsDOMStringMap.cpp
dom/html/nsGenericHTMLElement.cpp
dom/html/nsHTMLContentSink.cpp
dom/smil/nsSMILAnimationController.cpp
dom/svg/nsSVGElement.cpp
dom/xbl/XBLChildrenElement.h
dom/xbl/nsXBLBinding.cpp
dom/xbl/nsXBLContentSink.cpp
dom/xbl/nsXBLEventHandler.h
dom/xbl/nsXBLPrototypeBinding.cpp
dom/xbl/nsXBLPrototypeBinding.h
dom/xbl/nsXBLPrototypeHandler.cpp
dom/xbl/nsXBLPrototypeHandler.h
dom/xbl/nsXBLWindowKeyHandler.cpp
dom/xml/ProcessingInstruction.cpp
dom/xml/nsXMLContentSink.cpp
dom/xslt/base/txExpandedName.cpp
dom/xslt/base/txExpandedName.h
dom/xslt/base/txExpandedNameMap.h
dom/xslt/base/txNamespaceMap.cpp
dom/xslt/base/txNamespaceMap.h
dom/xslt/xpath/txExpr.h
dom/xslt/xpath/txExprParser.cpp
dom/xslt/xpath/txFunctionCall.cpp
dom/xslt/xpath/txMozillaXPathTreeWalker.cpp
dom/xslt/xpath/txXPCOMExtensionFunction.cpp
dom/xslt/xpath/txXPathTreeWalker.h
dom/xslt/xslt/txBufferingHandler.cpp
dom/xslt/xslt/txExecutionState.h
dom/xslt/xslt/txInstructions.cpp
dom/xslt/xslt/txInstructions.h
dom/xslt/xslt/txMozillaXMLOutput.cpp
dom/xslt/xslt/txMozillaXSLTProcessor.cpp
dom/xslt/xslt/txPatternParser.cpp
dom/xslt/xslt/txStylesheetCompileHandlers.cpp
dom/xslt/xslt/txStylesheetCompiler.cpp
dom/xslt/xslt/txStylesheetCompiler.h
dom/xslt/xslt/txUnknownHandler.cpp
dom/xslt/xslt/txXSLTNumber.cpp
dom/xslt/xslt/txXSLTPatterns.cpp
dom/xslt/xslt/txXSLTPatterns.h
dom/xul/XULDocument.cpp
dom/xul/XULDocument.h
dom/xul/nsXULContentSink.cpp
dom/xul/nsXULElement.cpp
dom/xul/nsXULPrototypeDocument.cpp
dom/xul/templates/nsContentTestNode.h
dom/xul/templates/nsRDFBinding.h
dom/xul/templates/nsRDFConInstanceTestNode.h
dom/xul/templates/nsRDFConMemberTestNode.h
dom/xul/templates/nsRDFPropertyTestNode.h
dom/xul/templates/nsRDFQuery.h
dom/xul/templates/nsRuleNetwork.h
dom/xul/templates/nsTemplateRule.h
dom/xul/templates/nsXMLBinding.h
dom/xul/templates/nsXULContentBuilder.cpp
dom/xul/templates/nsXULSortService.cpp
dom/xul/templates/nsXULSortService.h
dom/xul/templates/nsXULTemplateBuilder.cpp
dom/xul/templates/nsXULTemplateBuilder.h
dom/xul/templates/nsXULTemplateQueryProcessorRDF.cpp
dom/xul/templates/nsXULTemplateQueryProcessorRDF.h
dom/xul/templates/nsXULTemplateQueryProcessorStorage.cpp
dom/xul/templates/nsXULTemplateQueryProcessorStorage.h
dom/xul/templates/nsXULTemplateQueryProcessorXML.cpp
dom/xul/templates/nsXULTemplateQueryProcessorXML.h
dom/xul/templates/nsXULTemplateResultXML.cpp
dom/xul/templates/nsXULTreeBuilder.cpp
dom/xul/templates/nsXULTreeBuilder.h
editor/composer/nsComposerCommands.cpp
editor/libeditor/CSSEditUtils.cpp
editor/libeditor/ChangeAttributeTransaction.h
editor/libeditor/ChangeStyleTransaction.h
editor/libeditor/CreateElementTransaction.h
editor/libeditor/EditAggregateTransaction.h
editor/libeditor/EditorBase.cpp
editor/libeditor/HTMLAnonymousNodeEditor.cpp
editor/libeditor/HTMLEditRules.cpp
editor/libeditor/HTMLEditUtils.cpp
editor/libeditor/HTMLEditor.cpp
editor/libeditor/HTMLEditorObjectResizer.cpp
editor/libeditor/HTMLStyleEditor.cpp
editor/libeditor/HTMLTableEditor.cpp
editor/libeditor/PlaceholderTransaction.cpp
editor/txtsvc/nsFilteredContentIterator.h
gfx/src/nsDeviceContext.cpp
gfx/src/nsFontMetrics.h
gfx/src/nsThebesFontEnumerator.cpp
gfx/thebes/gfxFont.h
intl/hyphenation/glue/nsHyphenationManager.cpp
intl/hyphenation/glue/nsHyphenationManager.h
intl/locale/nsLanguageAtomService.cpp
intl/locale/nsLanguageAtomService.h
layout/base/StaticPresData.cpp
layout/base/StaticPresData.h
layout/base/nsCSSFrameConstructor.cpp
layout/base/nsLayoutUtils.h
layout/base/nsPresContext.cpp
layout/base/nsPresContext.h
layout/generic/nsGfxScrollFrame.cpp
layout/generic/nsTextRunTransformations.cpp
layout/generic/nsTextRunTransformations.h
layout/inspector/inDOMUtils.cpp
layout/style/CounterStyleManager.cpp
layout/style/NameSpaceRule.h
layout/style/ServoBindings.cpp
layout/style/ServoKeyframesRule.cpp
layout/style/ServoSpecifiedValues.cpp
layout/style/ServoStyleRule.cpp
layout/style/StyleRule.cpp
layout/style/StyleRule.h
layout/style/nsCSSCounterStyleRule.h
layout/style/nsCSSParser.cpp
layout/style/nsCSSPseudoElements.cpp
layout/style/nsCSSRuleProcessor.cpp
layout/style/nsCSSRules.cpp
layout/style/nsCSSValue.cpp
layout/style/nsComputedDOMStyle.cpp
layout/style/nsComputedDOMStyle.h
layout/style/nsHTMLStyleSheet.cpp
layout/style/nsHTMLStyleSheet.h
layout/style/nsMediaList.h
layout/style/nsRuleData.h
layout/style/nsRuleNode.cpp
layout/style/nsStyleContext.h
layout/style/nsStyleStruct.cpp
layout/style/nsStyleStruct.h
layout/xul/nsMenuFrame.cpp
layout/xul/nsMenuPopupFrame.cpp
layout/xul/nsSliderFrame.cpp
layout/xul/nsSplitterFrame.cpp
layout/xul/tree/nsTreeColumns.h
layout/xul/tree/nsTreeContentView.cpp
layout/xul/tree/nsTreeStyleCache.h
layout/xul/tree/nsTreeUtils.cpp
netwerk/streamconv/nsStreamConverterService.cpp
netwerk/streamconv/nsStreamConverterService.h
parser/html/nsHtml5TreeBuilderCppSupplement.h
parser/html/nsHtml5TreeOperation.cpp
parser/htmlparser/nsHTMLTags.cpp
rdf/base/nsNameSpaceMap.h
rdf/base/nsRDFContentSink.cpp
rdf/base/nsRDFXMLSerializer.cpp
toolkit/components/extensions/ExtensionPolicyService.h
toolkit/components/extensions/MatchPattern.cpp
toolkit/components/extensions/MatchPattern.h
toolkit/components/extensions/WebExtensionPolicy.h
toolkit/components/extensions/webrequest/StreamFilter.h
toolkit/components/extensions/webrequest/StreamFilterParent.cpp
toolkit/components/extensions/webrequest/WebRequestService.cpp
toolkit/components/extensions/webrequest/WebRequestService.h
toolkit/components/typeaheadfind/nsTypeAheadFind.cpp
widget/BasicEvents.h
widget/MiscEvents.h
widget/cocoa/nsMenuX.mm
widget/windows/KeyboardLayout.cpp
xpcom/ds/nsAtomTable.cpp
xpcom/ds/nsIAtom.h
xpcom/ds/nsRefPtrHashtable.h
xpcom/io/nsDirectoryService.cpp
xpcom/tests/gtest/TestAtoms.cpp
--- a/accessible/base/AccEvent.h
+++ b/accessible/base/AccEvent.h
@@ -526,17 +526,17 @@ public:
   {
     return AccEvent::GetEventGroups() | (1U << eObjectAttrChangedEvent);
   }
 
   // AccObjectAttrChangedEvent
   nsIAtom* GetAttribute() const { return mAttribute; }
 
 private:
-  nsCOMPtr<nsIAtom> mAttribute;
+  RefPtr<nsIAtom> mAttribute;
 
   virtual ~AccObjectAttrChangedEvent() { }
 };
 
 /**
  * Downcast the generic accessible event object to derived type.
  */
 class downcast_accEvent
--- a/caps/BasePrincipal.h
+++ b/caps/BasePrincipal.h
@@ -153,18 +153,18 @@ protected:
   nsCOMPtr<nsIContentSecurityPolicy> mCSP;
   nsCOMPtr<nsIContentSecurityPolicy> mPreloadCSP;
 
 private:
   static already_AddRefed<BasePrincipal>
   CreateCodebasePrincipal(nsIURI* aURI, const OriginAttributes& aAttrs,
                           const nsACString& aOriginNoSuffix);
 
-  nsCOMPtr<nsIAtom> mOriginNoSuffix;
-  nsCOMPtr<nsIAtom> mOriginSuffix;
+  RefPtr<nsIAtom> mOriginNoSuffix;
+  RefPtr<nsIAtom> mOriginSuffix;
 
   OriginAttributes mOriginAttributes;
   PrincipalKind mKind;
   bool mHasExplicitDomain;
   bool mInitialized;
 };
 
 inline bool
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -358,17 +358,17 @@ ForEachPing(nsIContent* aContent, ForEac
   //       implemented an interface that exposed an enumeration of nsIURIs.
 
   // Make sure we are dealing with either an <A> or <AREA> element in the HTML
   // or XHTML namespace.
   if (!IsElementAnchor(aContent)) {
     return;
   }
 
-  nsCOMPtr<nsIAtom> pingAtom = NS_Atomize("ping");
+  RefPtr<nsIAtom> pingAtom = NS_Atomize("ping");
   if (!pingAtom) {
     return;
   }
 
   nsAutoString value;
   aContent->GetAttr(kNameSpaceID_None, pingAtom, value);
   if (value.IsEmpty()) {
     return;
--- a/dom/base/AnonymousContent.cpp
+++ b/dom/base/AnonymousContent.cpp
@@ -182,17 +182,17 @@ AnonymousContent::SetCutoutRectsForEleme
     frame->SchedulePaint();
   }
 }
 
 Element*
 AnonymousContent::GetElementById(const nsAString& aElementId)
 {
   // This can be made faster in the future if needed.
-  nsCOMPtr<nsIAtom> elementId = NS_Atomize(aElementId);
+  RefPtr<nsIAtom> elementId = NS_Atomize(aElementId);
   for (nsIContent* node = mContentNode; node;
        node = node->GetNextNode(mContentNode)) {
     if (!node->IsElement()) {
       continue;
     }
     nsIAtom* id = node->AsElement()->GetID();
     if (id && id == elementId) {
       return node->AsElement();
--- a/dom/base/Attr.cpp
+++ b/dom/base/Attr.cpp
@@ -159,17 +159,17 @@ Attr::GetName(nsAString& aName)
   return NS_OK;
 }
 
 NS_IMETHODIMP
 Attr::GetValue(nsAString& aValue)
 {
   Element* element = GetElement();
   if (element) {
-    nsCOMPtr<nsIAtom> nameAtom = mNodeInfo->NameAtom();
+    RefPtr<nsIAtom> nameAtom = mNodeInfo->NameAtom();
     element->GetAttr(mNodeInfo->NamespaceID(), nameAtom, aValue);
   }
   else {
     aValue = mValue;
   }
 
   return NS_OK;
 }
@@ -178,17 +178,17 @@ void
 Attr::SetValue(const nsAString& aValue, ErrorResult& aRv)
 {
   Element* element = GetElement();
   if (!element) {
     mValue = aValue;
     return;
   }
 
-  nsCOMPtr<nsIAtom> nameAtom = mNodeInfo->NameAtom();
+  RefPtr<nsIAtom> nameAtom = mNodeInfo->NameAtom();
   aRv = element->SetAttr(mNodeInfo->NamespaceID(),
                          nameAtom,
                          mNodeInfo->GetPrefixAtom(),
                          aValue,
                          true);
 }
 
 NS_IMETHODIMP
--- a/dom/base/CustomElementRegistry.cpp
+++ b/dom/base/CustomElementRegistry.cpp
@@ -220,18 +220,18 @@ CustomElementRegistry::~CustomElementReg
 {
   mozilla::DropJSObjects(this);
 }
 
 CustomElementDefinition*
 CustomElementRegistry::LookupCustomElementDefinition(const nsAString& aLocalName,
                                                      const nsAString* aIs) const
 {
-  nsCOMPtr<nsIAtom> localNameAtom = NS_Atomize(aLocalName);
-  nsCOMPtr<nsIAtom> typeAtom = aIs ? NS_Atomize(*aIs) : localNameAtom;
+  RefPtr<nsIAtom> localNameAtom = NS_Atomize(aLocalName);
+  RefPtr<nsIAtom> typeAtom = aIs ? NS_Atomize(*aIs) : localNameAtom;
 
   CustomElementDefinition* data = mCustomDefinitions.GetWeak(typeAtom);
   if (data && data->mLocalName == localNameAtom) {
     return data;
   }
 
   return nullptr;
 }
@@ -256,17 +256,17 @@ CustomElementRegistry::LookupCustomEleme
 void
 CustomElementRegistry::RegisterUnresolvedElement(Element* aElement, nsIAtom* aTypeName)
 {
   mozilla::dom::NodeInfo* info = aElement->NodeInfo();
 
   // Candidate may be a custom element through extension,
   // in which case the custom element type name will not
   // match the element tag name. e.g. <button is="x-button">.
-  nsCOMPtr<nsIAtom> typeName = aTypeName;
+  RefPtr<nsIAtom> typeName = aTypeName;
   if (!typeName) {
     typeName = info->NameAtom();
   }
 
   if (mCustomDefinitions.GetWeak(typeName)) {
     return;
   }
 
@@ -275,18 +275,18 @@ CustomElementRegistry::RegisterUnresolve
   *elem = do_GetWeakReference(aElement);
   aElement->AddStates(NS_EVENT_STATE_UNRESOLVED);
 }
 
 void
 CustomElementRegistry::SetupCustomElement(Element* aElement,
                                           const nsAString* aTypeExtension)
 {
-  nsCOMPtr<nsIAtom> tagAtom = aElement->NodeInfo()->NameAtom();
-  nsCOMPtr<nsIAtom> typeAtom = aTypeExtension ?
+  RefPtr<nsIAtom> tagAtom = aElement->NodeInfo()->NameAtom();
+  RefPtr<nsIAtom> typeAtom = aTypeExtension ?
     NS_Atomize(*aTypeExtension) : tagAtom;
 
   if (aTypeExtension && !aElement->HasAttr(kNameSpaceID_None, nsGkAtoms::is)) {
     // Custom element setup in the parser happens after the "is"
     // attribute is added.
     aElement->SetAttr(kNameSpaceID_None, nsGkAtoms::is, *aTypeExtension, true);
   }
 
@@ -425,17 +425,17 @@ CustomElementRegistry::EnqueueLifecycleC
   }
 
   DocGroup* docGroup = aCustomElement->OwnerDoc()->GetDocGroup();
   if (!docGroup) {
     return;
   }
 
   if (aType == nsIDocument::eAttributeChanged) {
-    nsCOMPtr<nsIAtom> attrName = NS_Atomize(aArgs->name);
+    RefPtr<nsIAtom> attrName = NS_Atomize(aArgs->name);
     if (definition->mObservedAttributes.IsEmpty() ||
         !definition->mObservedAttributes.Contains(attrName)) {
       return;
     }
   }
 
   CustomElementReactionsStack* reactionsStack =
     docGroup->CustomElementReactionsStack();
@@ -571,17 +571,17 @@ CustomElementRegistry::Define(const nsAS
     aRv.ThrowTypeError<MSG_NOT_CONSTRUCTOR>(NS_LITERAL_STRING("Argument 2 of CustomElementRegistry.define"));
     return;
   }
 
   /**
    * 2. If name is not a valid custom element name, then throw a "SyntaxError"
    *    DOMException and abort these steps.
    */
-  nsCOMPtr<nsIAtom> nameAtom(NS_Atomize(aName));
+  RefPtr<nsIAtom> nameAtom(NS_Atomize(aName));
   if (!nsContentUtils::IsCustomElementName(nameAtom)) {
     aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR);
     return;
   }
 
   /**
    * 3. If this CustomElementRegistry contains an entry with name name, then
    *    throw a "NotSupportedError" DOMException and abort these steps.
@@ -613,17 +613,17 @@ CustomElementRegistry::Define(const nsAS
    *    2. If the element interface for extends and the HTML namespace is
    *       HTMLUnknownElement (e.g., if extends does not indicate an element
    *       definition in this specification), then throw a "NotSupportedError"
    *       DOMException.
    *    3. Set localName to extends.
    */
   nsAutoString localName(aName);
   if (aOptions.mExtends.WasPassed()) {
-    nsCOMPtr<nsIAtom> extendsAtom(NS_Atomize(aOptions.mExtends.Value()));
+    RefPtr<nsIAtom> extendsAtom(NS_Atomize(aOptions.mExtends.Value()));
     if (nsContentUtils::IsCustomElementName(extendsAtom)) {
       aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
       return;
     }
 
     // bgsound and multicol are unknown html element.
     int32_t tag = nsHTMLTags::CaseSensitiveAtomTagToId(extendsAtom);
     if (tag == eHTMLTag_userdefined ||
@@ -642,17 +642,17 @@ CustomElementRegistry::Define(const nsAS
    */
   if (mIsCustomDefinitionRunning) {
     aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
     return;
   }
 
   JS::Rooted<JSObject*> constructorPrototype(cx);
   nsAutoPtr<LifecycleCallbacks> callbacksHolder(new LifecycleCallbacks());
-  nsCOMArray<nsIAtom> observedAttributes;
+  nsTArray<RefPtr<nsIAtom>> observedAttributes;
   { // Set mIsCustomDefinitionRunning.
     /**
      * 9. Set this CustomElementRegistry's element definition is running flag.
      */
     AutoSetRunningFlag as(this);
 
     { // Enter constructor's compartment.
       /**
@@ -773,17 +773,17 @@ CustomElementRegistry::Define(const nsAS
 
   /**
    * 11. Let definition be a new custom element definition with name name,
    *     local name localName, constructor constructor, prototype prototype,
    *     observed attributes observedAttributes, and lifecycle callbacks
    *     lifecycleCallbacks.
    */
   // Associate the definition with the custom element.
-  nsCOMPtr<nsIAtom> localNameAtom(NS_Atomize(localName));
+  RefPtr<nsIAtom> localNameAtom(NS_Atomize(localName));
   LifecycleCallbacks* callbacks = callbacksHolder.forget();
 
   /**
    * 12. Add definition to this CustomElementRegistry.
    */
   if (!mConstructors.put(constructorUnwrapped, nameAtom)) {
     aRv.Throw(NS_ERROR_FAILURE);
     return;
@@ -824,17 +824,17 @@ CustomElementRegistry::Define(const nsAS
   }
 
 }
 
 void
 CustomElementRegistry::Get(JSContext* aCx, const nsAString& aName,
                            JS::MutableHandle<JS::Value> aRetVal)
 {
-  nsCOMPtr<nsIAtom> nameAtom(NS_Atomize(aName));
+  RefPtr<nsIAtom> nameAtom(NS_Atomize(aName));
   CustomElementDefinition* data = mCustomDefinitions.GetWeak(nameAtom);
 
   if (!data) {
     aRetVal.setUndefined();
     return;
   }
 
   aRetVal.setObject(*data->mConstructor->Callback(aCx));
@@ -845,17 +845,17 @@ CustomElementRegistry::WhenDefined(const
 {
   nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(mWindow);
   RefPtr<Promise> promise = Promise::Create(global, aRv);
 
   if (aRv.Failed()) {
     return nullptr;
   }
 
-  nsCOMPtr<nsIAtom> nameAtom(NS_Atomize(aName));
+  RefPtr<nsIAtom> nameAtom(NS_Atomize(aName));
   if (!nsContentUtils::IsCustomElementName(nameAtom)) {
     promise->MaybeReject(NS_ERROR_DOM_SYNTAX_ERR);
     return promise.forget();
   }
 
   if (mCustomDefinitions.GetWeak(nameAtom)) {
     promise->MaybeResolve(JS::UndefinedHandleValue);
     return promise.forget();
@@ -1160,17 +1160,17 @@ NS_IMPL_CYCLE_COLLECTION_TRACE_END
 
 NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(CustomElementDefinition, AddRef)
 NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(CustomElementDefinition, Release)
 
 
 CustomElementDefinition::CustomElementDefinition(nsIAtom* aType,
                                                  nsIAtom* aLocalName,
                                                  Function* aConstructor,
-                                                 nsCOMArray<nsIAtom>&& aObservedAttributes,
+                                                 nsTArray<RefPtr<nsIAtom>>&& aObservedAttributes,
                                                  JSObject* aPrototype,
                                                  LifecycleCallbacks* aCallbacks,
                                                  uint32_t aDocOrder)
   : mType(aType),
     mLocalName(aLocalName),
     mConstructor(new CustomElementConstructor(aConstructor)),
     mObservedAttributes(Move(aObservedAttributes)),
     mPrototype(aPrototype),
--- a/dom/base/CustomElementRegistry.h
+++ b/dom/base/CustomElementRegistry.h
@@ -97,17 +97,17 @@ struct CustomElementData
     eFailed,
     eCustom
   };
 
   explicit CustomElementData(nsIAtom* aType);
   CustomElementData(nsIAtom* aType, State aState);
   // Custom element type, for <button is="x-button"> or <x-button>
   // this would be x-button.
-  nsCOMPtr<nsIAtom> mType;
+  RefPtr<nsIAtom> mType;
   // Element is being created flag as described in the custom elements spec.
   bool mElementIsBeingCreated;
   // Flag to determine if the created callback has been invoked, thus it
   // determines if other callbacks can be enqueued.
   bool mCreatedCallbackInvoked;
   // Custom element state as described in the custom element spec.
   State mState;
   // custom element reaction queue as described in the custom element spec.
@@ -145,32 +145,32 @@ private:
 struct CustomElementDefinition
 {
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(CustomElementDefinition)
   NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(CustomElementDefinition)
 
   CustomElementDefinition(nsIAtom* aType,
                           nsIAtom* aLocalName,
                           Function* aConstructor,
-                          nsCOMArray<nsIAtom>&& aObservedAttributes,
+                          nsTArray<RefPtr<nsIAtom>>&& aObservedAttributes,
                           JSObject* aPrototype,
                           mozilla::dom::LifecycleCallbacks* aCallbacks,
                           uint32_t aDocOrder);
 
   // The type (name) for this custom element.
-  nsCOMPtr<nsIAtom> mType;
+  RefPtr<nsIAtom> mType;
 
   // The localname to (e.g. <button is=type> -- this would be button).
-  nsCOMPtr<nsIAtom> mLocalName;
+  RefPtr<nsIAtom> mLocalName;
 
   // The custom element constructor.
   RefPtr<CustomElementConstructor> mConstructor;
 
   // The list of attributes that this custom element observes.
-  nsCOMArray<nsIAtom> mObservedAttributes;
+  nsTArray<RefPtr<nsIAtom>> mObservedAttributes;
 
   // The prototype to use for new custom elements of this type.
   JS::Heap<JSObject *> mPrototype;
 
   // The lifecycle callbacks to call for this custom element.
   UniquePtr<mozilla::dom::LifecycleCallbacks> mCallbacks;
 
   // A construction stack. Use nullptr to represent an "already constructed marker".
@@ -406,36 +406,36 @@ private:
    */
   void RegisterUnresolvedElement(Element* aElement,
                                  nsIAtom* aTypeName = nullptr);
 
   void UpgradeCandidates(nsIAtom* aKey,
                          CustomElementDefinition* aDefinition,
                          ErrorResult& aRv);
 
-  typedef nsRefPtrHashtable<nsISupportsHashKey, CustomElementDefinition>
+  typedef nsRefPtrHashtable<nsRefPtrHashKey<nsIAtom>, CustomElementDefinition>
     DefinitionMap;
-  typedef nsClassHashtable<nsISupportsHashKey, nsTArray<nsWeakPtr>>
+  typedef nsClassHashtable<nsRefPtrHashKey<nsIAtom>, nsTArray<nsWeakPtr>>
     CandidateMap;
   typedef JS::GCHashMap<JS::Heap<JSObject*>,
-                        nsCOMPtr<nsIAtom>,
+                        RefPtr<nsIAtom>,
                         js::MovableCellHasher<JS::Heap<JSObject*>>,
                         js::SystemAllocPolicy> ConstructorMap;
 
   // Hashtable for custom element definitions in web components.
   // Custom prototypes are stored in the compartment where
   // registerElement was called.
   DefinitionMap mCustomDefinitions;
 
   // Hashtable for looking up definitions by using constructor as key.
   // Custom elements' name are stored here and we need to lookup
   // mCustomDefinitions again to get definitions.
   ConstructorMap mConstructors;
 
-  typedef nsRefPtrHashtable<nsISupportsHashKey, Promise>
+  typedef nsRefPtrHashtable<nsRefPtrHashKey<nsIAtom>, Promise>
     WhenDefinedPromiseMap;
   WhenDefinedPromiseMap mWhenDefinedPromiseMap;
 
   // The "upgrade candidates map" from the web components spec. Maps from a
   // namespace id and local name to a list of elements to upgrade if that
   // element is registered as a custom element.
   CandidateMap mCandidatesMap;
 
--- a/dom/base/DOMImplementation.cpp
+++ b/dom/base/DOMImplementation.cpp
@@ -56,17 +56,17 @@ DOMImplementation::CreateDocumentType(co
     return nullptr;
   }
 
   aRv = nsContentUtils::CheckQName(aQualifiedName);
   if (aRv.Failed()) {
     return nullptr;
   }
 
-  nsCOMPtr<nsIAtom> name = NS_Atomize(aQualifiedName);
+  RefPtr<nsIAtom> name = NS_Atomize(aQualifiedName);
   if (!name) {
     aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
     return nullptr;
   }
 
   // Indicate that there is no internal subset (not just an empty one)
   RefPtr<DocumentType> docType =
     NS_NewDOMDocumentType(mOwner->NodeInfoManager(), name, aPublicId,
--- a/dom/base/Element.cpp
+++ b/dom/base/Element.cpp
@@ -1263,17 +1263,17 @@ Element::SetAttribute(const nsAString& a
   aError = nsContentUtils::CheckQName(aName, false);
   if (aError.Failed()) {
     return;
   }
 
   nsAutoString nameToUse;
   const nsAttrName* name = InternalGetAttrNameFromQName(aName, &nameToUse);
   if (!name) {
-    nsCOMPtr<nsIAtom> nameAtom = NS_AtomizeMainThread(nameToUse);
+    RefPtr<nsIAtom> nameAtom = NS_AtomizeMainThread(nameToUse);
     if (!nameAtom) {
       aError.Throw(NS_ERROR_OUT_OF_MEMORY);
       return;
     }
     aError = SetAttr(kNameSpaceID_None, nameAtom, aValue, true);
     return;
   }
 
@@ -1344,17 +1344,17 @@ Element::GetAttributeNS(const nsAString&
                                                        nsContentUtils::IsChromeDoc(OwnerDoc()));
 
   if (nsid == kNameSpaceID_Unknown) {
     // Unknown namespace means no attribute.
     SetDOMStringToNull(aReturn);
     return;
   }
 
-  nsCOMPtr<nsIAtom> name = NS_AtomizeMainThread(aLocalName);
+  RefPtr<nsIAtom> name = NS_AtomizeMainThread(aLocalName);
   bool hasAttr = GetAttr(nsid, name, aReturn);
   if (!hasAttr) {
     SetDOMStringToNull(aReturn);
   }
 }
 
 void
 Element::SetAttributeNS(const nsAString& aNamespaceURI,
@@ -1376,17 +1376,17 @@ Element::SetAttributeNS(const nsAString&
                    aValue, true);
 }
 
 void
 Element::RemoveAttributeNS(const nsAString& aNamespaceURI,
                            const nsAString& aLocalName,
                            ErrorResult& aError)
 {
-  nsCOMPtr<nsIAtom> name = NS_AtomizeMainThread(aLocalName);
+  RefPtr<nsIAtom> name = NS_AtomizeMainThread(aLocalName);
   int32_t nsid =
     nsContentUtils::NameSpaceManager()->GetNameSpaceID(aNamespaceURI,
                                                        nsContentUtils::IsChromeDoc(OwnerDoc()));
 
   if (nsid == kNameSpaceID_Unknown) {
     // If the namespace ID is unknown, it means there can't possibly be an
     // existing attribute. We would need a known namespace ID to pass into
     // UnsetAttr, so we return early if we don't have one.
@@ -1449,17 +1449,17 @@ Element::HasAttributeNS(const nsAString&
     nsContentUtils::NameSpaceManager()->GetNameSpaceID(aNamespaceURI,
                                                        nsContentUtils::IsChromeDoc(OwnerDoc()));
 
   if (nsid == kNameSpaceID_Unknown) {
     // Unknown namespace means no attr...
     return false;
   }
 
-  nsCOMPtr<nsIAtom> name = NS_AtomizeMainThread(aLocalName);
+  RefPtr<nsIAtom> name = NS_AtomizeMainThread(aLocalName);
   return HasAttr(nsid, name);
 }
 
 already_AddRefed<nsIHTMLCollection>
 Element::GetElementsByClassName(const nsAString& aClassNames)
 {
   return nsContentUtils::GetElementsByClassName(this, aClassNames);
 }
@@ -2623,25 +2623,25 @@ Element::SetAttrAndNotify(int32_t aNames
   }
 
   if (CustomElementRegistry::IsCustomElementEnabled()) {
     if (CustomElementData* data = GetCustomElementData()) {
       if (CustomElementDefinition* definition =
             nsContentUtils::GetElementDefinitionIfObservingAttr(this,
                                                                 data->mType,
                                                                 aName)) {
-        nsCOMPtr<nsIAtom> oldValueAtom;
+        RefPtr<nsIAtom> oldValueAtom;
         if (oldValue) {
           oldValueAtom = oldValue->GetAsAtom();
         } else {
           // If there is no old value, get the value of the uninitialized
           // attribute that was swapped with aParsedValue.
           oldValueAtom = aParsedValue.GetAsAtom();
         }
-        nsCOMPtr<nsIAtom> newValueAtom = valueForAfterSetAttr.GetAsAtom();
+        RefPtr<nsIAtom> newValueAtom = valueForAfterSetAttr.GetAsAtom();
         nsAutoString ns;
         nsContentUtils::NameSpaceManager()->GetNameSpaceURI(aNamespaceID, ns);
 
         LifecycleCallbackArgs args = {
           nsDependentAtomString(aName),
           aModType == nsIDOMMutationEvent::ADDITION ?
             VoidString() : nsDependentAtomString(oldValueAtom),
           nsDependentAtomString(newValueAtom),
@@ -2930,17 +2930,17 @@ Element::UnsetAttr(int32_t aNameSpaceID,
     if (CustomElementData* data = GetCustomElementData()) {
       if (CustomElementDefinition* definition =
             nsContentUtils::GetElementDefinitionIfObservingAttr(this,
                                                                 data->mType,
                                                                 aName)) {
         nsAutoString ns;
         nsContentUtils::NameSpaceManager()->GetNameSpaceURI(aNameSpaceID, ns);
 
-        nsCOMPtr<nsIAtom> oldValueAtom = oldValue.GetAsAtom();
+        RefPtr<nsIAtom> oldValueAtom = oldValue.GetAsAtom();
         LifecycleCallbackArgs args = {
           nsDependentAtomString(aName),
           nsDependentAtomString(oldValueAtom),
           VoidString(),
           (ns.IsEmpty() ? VoidString() : ns)
         };
 
         nsContentUtils::EnqueueLifecycleCallback(
--- a/dom/base/FragmentOrElement.cpp
+++ b/dom/base/FragmentOrElement.cpp
@@ -326,17 +326,17 @@ nsIContent::LookupNamespaceURIInternal(c
   }
 
   if (aNamespacePrefix.EqualsLiteral("xmlns")) {
     // Special-case for xmlns prefix
     aNamespaceURI.AssignLiteral("http://www.w3.org/2000/xmlns/");
     return NS_OK;
   }
 
-  nsCOMPtr<nsIAtom> name;
+  RefPtr<nsIAtom> name;
   if (!aNamespacePrefix.IsEmpty()) {
     name = NS_Atomize(aNamespacePrefix);
     NS_ENSURE_TRUE(name, NS_ERROR_OUT_OF_MEMORY);
   }
   else {
     name = nsGkAtoms::xmlns;
   }
   // Trace up the content parent chain looking for the namespace
--- a/dom/base/nsAttrValue.cpp
+++ b/dom/base/nsAttrValue.cpp
@@ -749,17 +749,17 @@ already_AddRefed<nsIAtom>
 nsAttrValue::GetAsAtom() const
 {
   switch (Type()) {
     case eString:
       return NS_AtomizeMainThread(GetStringValue());
 
     case eAtom:
       {
-        nsCOMPtr<nsIAtom> atom = GetAtomValue();
+        RefPtr<nsIAtom> atom = GetAtomValue();
         return atom.forget();
       }
 
     default:
       {
         nsAutoString val;
         ToString(val);
         return NS_AtomizeMainThread(val);
@@ -908,17 +908,17 @@ nsAttrValue::HashValue() const
       nsString str;
       ToString(str);
       return HashString(str);
     }
     case eAtomArray:
     {
       uint32_t hash = 0;
       uint32_t count = cont->mValue.mAtomArray->Length();
-      for (nsCOMPtr<nsIAtom> *cur = cont->mValue.mAtomArray->Elements(),
+      for (RefPtr<nsIAtom> *cur = cont->mValue.mAtomArray->Elements(),
                              *end = cur + count;
            cur != end; ++cur) {
         hash = AddToHash(hash, cur->get());
       }
       return hash;
     }
     case eDoubleValue:
     {
@@ -1188,17 +1188,17 @@ nsAttrValue::Contains(nsIAtom* aValue, n
       if (Type() == eAtomArray) {
         AtomArray* array = GetAtomArrayValue();
         if (aCaseSensitive == eCaseMatters) {
           return array->Contains(aValue);
         }
 
         nsDependentAtomString val1(aValue);
 
-        for (nsCOMPtr<nsIAtom> *cur = array->Elements(),
+        for (RefPtr<nsIAtom> *cur = array->Elements(),
                                *end = cur + array->Length();
              cur != end; ++cur) {
           // For performance reasons, don't do a full on unicode case
           // insensitive string comparison. This is only used for quirks mode
           // anyway.
           if (nsContentUtils::EqualsIgnoreASCIICase(val1,
                 nsDependentAtomString(*cur))) {
             return true;
@@ -1238,17 +1238,17 @@ nsAttrValue::Contains(const nsAString& a
   return false;
 }
 
 void
 nsAttrValue::ParseAtom(const nsAString& aValue)
 {
   ResetIfSet();
 
-  nsCOMPtr<nsIAtom> atom = NS_Atomize(aValue);
+  RefPtr<nsIAtom> atom = NS_Atomize(aValue);
   if (atom) {
     SetPtrValueAndType(atom.forget().take(), eAtomBase);
   }
 }
 
 void
 nsAttrValue::ParseAtomArray(const nsAString& aValue)
 {
@@ -1270,17 +1270,17 @@ nsAttrValue::ParseAtomArray(const nsAStr
 
   nsAString::const_iterator start(iter);
 
   // get first - and often only - atom
   do {
     ++iter;
   } while (iter != end && !nsContentUtils::IsHTMLWhitespace(*iter));
 
-  nsCOMPtr<nsIAtom> classAtom = NS_AtomizeMainThread(Substring(start, iter));
+  RefPtr<nsIAtom> classAtom = NS_AtomizeMainThread(Substring(start, iter));
   if (!classAtom) {
     Reset();
     return;
   }
 
   // skip whitespace
   while (iter != end && nsContentUtils::IsHTMLWhitespace(*iter)) {
     hasSpace = true;
@@ -1791,17 +1791,17 @@ nsAttrValue::SetMiscAtomOrString(const n
     // * We're allowing enumerated values because sometimes the empty
     //   string corresponds to a particular enumerated value, especially
     //   for enumerated values that are not limited enumerated.
     // Add other types as needed.
     NS_ASSERTION(len || Type() == eCSSDeclaration || Type() == eEnum,
                  "Empty string?");
     MiscContainer* cont = GetMiscContainer();
     if (len <= NS_ATTRVALUE_MAX_STRINGLENGTH_ATOM) {
-      nsCOMPtr<nsIAtom> atom = NS_AtomizeMainThread(*aValue);
+      RefPtr<nsIAtom> atom = NS_AtomizeMainThread(*aValue);
       if (atom) {
         cont->mStringBits =
           reinterpret_cast<uintptr_t>(atom.forget().take()) | eAtomBase;
       }
     } else {
       nsStringBuffer* buf = GetStringBuffer(*aValue).take();
       if (buf) {
         cont->mStringBits = reinterpret_cast<uintptr_t>(buf) | eStringBase;
--- a/dom/base/nsAttrValue.h
+++ b/dom/base/nsAttrValue.h
@@ -79,17 +79,17 @@ public:
     if (aBuf)
       aBuf->ToString(aBuf->StorageSize()/sizeof(char16_t) - 1, *this);
   }
 };
 
 class nsAttrValue {
   friend struct MiscContainer;
 public:
-  typedef nsTArray< nsCOMPtr<nsIAtom> > AtomArray;
+  typedef nsTArray< RefPtr<nsIAtom> > AtomArray;
 
   // This has to be the same as in ValueBaseType
   enum ValueType {
     eString =       0x00, //   00
                           //   01  this value indicates a 'misc' struct
     eAtom =         0x02, //   10
     eInteger =      0x03, // 0011
     eColor =        0x07, // 0111
--- a/dom/base/nsContentList.cpp
+++ b/dom/base/nsContentList.cpp
@@ -284,18 +284,18 @@ NS_GetContentList(nsINode* aRootNode,
   auto entry = static_cast<ContentListHashEntry*>
                           (gContentListHashTable->Add(&hashKey, fallible));
   if (entry)
     list = entry->mContentList;
 
   if (!list) {
     // We need to create a ContentList and add it to our new entry, if
     // we have an entry
-    nsCOMPtr<nsIAtom> xmlAtom = NS_Atomize(aTagname);
-    nsCOMPtr<nsIAtom> htmlAtom;
+    RefPtr<nsIAtom> xmlAtom = NS_Atomize(aTagname);
+    RefPtr<nsIAtom> htmlAtom;
     if (aMatchNameSpaceId == kNameSpaceID_Unknown) {
       nsAutoString lowercaseName;
       nsContentUtils::ASCIIToLower(aTagname, lowercaseName);
       htmlAtom = NS_Atomize(lowercaseName);
     } else {
       htmlAtom = xmlAtom;
     }
     list = new nsContentList(aRootNode, aMatchNameSpaceId, htmlAtom, xmlAtom);
@@ -557,17 +557,17 @@ nsContentList::NamedItem(const nsAString
     return nullptr;
   }
 
   BringSelfUpToDate(aDoFlush);
 
   uint32_t i, count = mElements.Length();
 
   // Typically IDs and names are atomized
-  nsCOMPtr<nsIAtom> name = NS_Atomize(aName);
+  RefPtr<nsIAtom> name = NS_Atomize(aName);
   NS_ENSURE_TRUE(name, nullptr);
 
   for (i = 0; i < count; i++) {
     nsIContent *content = mElements[i];
     // XXX Should this pass eIgnoreCase?
     if (content &&
         ((content->IsHTMLElement() &&
           content->AttrValueIs(kNameSpaceID_None, nsGkAtoms::name,
--- a/dom/base/nsContentList.h
+++ b/dom/base/nsContentList.h
@@ -467,18 +467,18 @@ protected:
    */
   virtual void RemoveFromCaches() override
   {
     RemoveFromHashtable();
   }
 
   nsINode* mRootNode; // Weak ref
   int32_t mMatchNameSpaceId;
-  nsCOMPtr<nsIAtom> mHTMLMatchAtom;
-  nsCOMPtr<nsIAtom> mXMLMatchAtom;
+  RefPtr<nsIAtom> mHTMLMatchAtom;
+  RefPtr<nsIAtom> mXMLMatchAtom;
 
   /**
    * Function to use to determine whether a piece of content matches
    * our criterion
    */
   nsContentListMatchFunc mFunc;
   /**
    * Cleanup closure data with this.
--- a/dom/base/nsContentSink.cpp
+++ b/dom/base/nsContentSink.cpp
@@ -847,17 +847,17 @@ nsContentSink::ProcessMETATag(nsIContent
     // documents.
     if (nsGkAtoms::setcookie->Equals(header) && mDocument->IsCookieAverse()) {
       return NS_OK;
     }
 
     nsAutoString result;
     aContent->GetAttr(kNameSpaceID_None, nsGkAtoms::content, result);
     if (!result.IsEmpty()) {
-      nsCOMPtr<nsIAtom> fieldAtom(NS_Atomize(header));
+      RefPtr<nsIAtom> fieldAtom(NS_Atomize(header));
       rv = ProcessHeaderData(fieldAtom, result, aContent);
     }
   }
   NS_ENSURE_SUCCESS(rv, rv);
 
   if (aContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::name,
                             nsGkAtoms::handheldFriendly, eIgnoreCase)) {
     nsAutoString result;
--- a/dom/base/nsContentUtils.cpp
+++ b/dom/base/nsContentUtils.cpp
@@ -250,19 +250,19 @@ const char kLoadAsData[] = "loadAsData";
 nsIXPConnect *nsContentUtils::sXPConnect;
 nsIScriptSecurityManager *nsContentUtils::sSecurityManager;
 nsIPrincipal *nsContentUtils::sSystemPrincipal;
 nsIPrincipal *nsContentUtils::sNullSubjectPrincipal;
 nsNameSpaceManager *nsContentUtils::sNameSpaceManager;
 nsIIOService *nsContentUtils::sIOService;
 nsIUUIDGenerator *nsContentUtils::sUUIDGenerator;
 nsIConsoleService *nsContentUtils::sConsoleService;
-nsDataHashtable<nsISupportsHashKey, EventNameMapping>* nsContentUtils::sAtomEventTable = nullptr;
+nsDataHashtable<nsRefPtrHashKey<nsIAtom>, EventNameMapping>* nsContentUtils::sAtomEventTable = nullptr;
 nsDataHashtable<nsStringHashKey, EventNameMapping>* nsContentUtils::sStringEventTable = nullptr;
-nsCOMArray<nsIAtom>* nsContentUtils::sUserDefinedEvents = nullptr;
+nsTArray<RefPtr<nsIAtom>>* nsContentUtils::sUserDefinedEvents = nullptr;
 nsIStringBundleService *nsContentUtils::sStringBundleService;
 nsIStringBundle *nsContentUtils::sStringBundles[PropertiesFile_COUNT];
 nsIContentPolicy *nsContentUtils::sContentPolicyService;
 bool nsContentUtils::sTriedToGetContentPolicy = false;
 nsILineBreaker *nsContentUtils::sLineBreaker;
 nsIWordBreaker *nsContentUtils::sWordBreaker;
 nsIBidiKeyboard *nsContentUtils::sBidiKeyboard = nullptr;
 uint32_t nsContentUtils::sScriptBlockerCount = 0;
@@ -948,21 +948,21 @@ nsContentUtils::InitializeEventTable() {
 #define NON_IDL_EVENT EVENT
 #include "mozilla/EventNameList.h"
 #undef WINDOW_ONLY_EVENT
 #undef NON_IDL_EVENT
 #undef EVENT
     { nullptr }
   };
 
-  sAtomEventTable = new nsDataHashtable<nsISupportsHashKey, EventNameMapping>(
+  sAtomEventTable = new nsDataHashtable<nsRefPtrHashKey<nsIAtom>, EventNameMapping>(
       ArrayLength(eventArray));
   sStringEventTable = new nsDataHashtable<nsStringHashKey, EventNameMapping>(
       ArrayLength(eventArray));
-  sUserDefinedEvents = new nsCOMArray<nsIAtom>(64);
+  sUserDefinedEvents = new nsTArray<RefPtr<nsIAtom>>(64);
 
   // Subtract one from the length because of the trailing null
   for (uint32_t i = 0; i < ArrayLength(eventArray) - 1; ++i) {
     MOZ_ASSERT(!sAtomEventTable->Lookup(eventArray[i].mAtom),
                "Double-defining event name; fix your EventNameList.h");
     sAtomEventTable->Put(eventArray[i].mAtom, eventArray[i]);
     if (ShouldAddEventToStringEventTable(eventArray[i])) {
       sStringEventTable->Put(
@@ -3411,17 +3411,17 @@ nsContentUtils::GetNodeInfoFromQName(con
   NS_ENSURE_SUCCESS(rv, rv);
 
   int32_t nsID;
   sNameSpaceManager->RegisterNameSpace(aNamespaceURI, nsID);
   if (colon) {
     const char16_t* end;
     qName.EndReading(end);
 
-    nsCOMPtr<nsIAtom> prefix =
+    RefPtr<nsIAtom> prefix =
       NS_AtomizeMainThread(Substring(qName.get(), colon));
 
     rv = aNodeInfoManager->GetNodeInfo(Substring(colon + 1, end), prefix,
                                        nsID, aNodeType, aNodeInfo);
   }
   else {
     rv = aNodeInfoManager->GetNodeInfo(aQualifiedName, nullptr, nsID,
                                        aNodeType, aNodeInfo);
@@ -4381,28 +4381,28 @@ nsContentUtils::GetEventMessageAndAtom(c
   if (sStringEventTable->Get(aName, &mapping)) {
     *aEventMessage =
       mapping.mEventClassID == aEventClassID ? mapping.mMessage :
                                                eUnidentifiedEvent;
     return mapping.mAtom;
   }
 
   // If we have cached lots of user defined event names, clear some of them.
-  if (sUserDefinedEvents->Count() > 127) {
-    while (sUserDefinedEvents->Count() > 64) {
-      nsIAtom* first = sUserDefinedEvents->ObjectAt(0);
+  if (sUserDefinedEvents->Length() > 127) {
+    while (sUserDefinedEvents->Length() > 64) {
+      nsIAtom* first = sUserDefinedEvents->ElementAt(0);
       sStringEventTable->Remove(Substring(nsDependentAtomString(first), 2));
-      sUserDefinedEvents->RemoveObjectAt(0);
+      sUserDefinedEvents->RemoveElementAt(0);
     }
   }
 
   *aEventMessage = eUnidentifiedEvent;
-  nsCOMPtr<nsIAtom> atom =
+  RefPtr<nsIAtom> atom =
     NS_AtomizeMainThread(NS_LITERAL_STRING("on") + aName);
-  sUserDefinedEvents->AppendObject(atom);
+  sUserDefinedEvents->AppendElement(atom);
   mapping.mAtom = atom;
   mapping.mMessage = eUnidentifiedEvent;
   mapping.mType = EventNameType_None;
   mapping.mEventClassID = eBasicEventClass;
   // This is a slow hashtable call, but at least we cache the result for the
   // following calls. Because GetEventMessageAndAtomForListener utilizes
   // sStringEventTable, it needs to know in which cases sStringEventTable
   // doesn't contain the information it needs so that it can use
@@ -4419,17 +4419,17 @@ nsContentUtils::GetEventMessageAndAtomFo
                                                   nsIAtom** aOnName)
 {
   // Because of SVG/SMIL sStringEventTable contains a subset of the event names
   // comparing to the sAtomEventTable. However, usually sStringEventTable
   // contains the information we need, so in order to reduce hashtable
   // lookups, start from it.
   EventNameMapping mapping;
   EventMessage msg = eUnidentifiedEvent;
-  nsCOMPtr<nsIAtom> atom;
+  RefPtr<nsIAtom> atom;
   if (sStringEventTable->Get(aName, &mapping)) {
     if (mapping.mMaybeSpecialSVGorSMILEvent) {
       // Try the atom version so that we should get the right message for
       // SVG/SMIL.
       atom = NS_AtomizeMainThread(NS_LITERAL_STRING("on") + aName);
       msg = GetEventMessage(atom);
     } else {
       atom = mapping.mAtom;
@@ -4625,17 +4625,17 @@ nsContentUtils::MatchElementId(nsIConten
 
 /* static */
 Element *
 nsContentUtils::MatchElementId(nsIContent *aContent, const nsAString& aId)
 {
   NS_PRECONDITION(!aId.IsEmpty(), "Will match random elements");
 
   // ID attrs are generally stored as atoms, so just atomize this up front
-  nsCOMPtr<nsIAtom> id(NS_Atomize(aId));
+  RefPtr<nsIAtom> id(NS_Atomize(aId));
   if (!id) {
     // OOM, so just bail
     return nullptr;
   }
 
   return MatchElementId(aContent, id);
 }
 
@@ -5819,17 +5819,17 @@ static void ProcessViewportToken(nsIDocu
     nsContentUtils::TrimWhitespace<nsCRT::IsAsciiSpace>(Substring(tail, tip),
                                                         true);
   const nsAString &value =
     nsContentUtils::TrimWhitespace<nsCRT::IsAsciiSpace>(Substring(++tip, end),
                                                         true);
 
   /* Check for known keys. If we find a match, insert the appropriate
    * information into the document header. */
-  nsCOMPtr<nsIAtom> key_atom = NS_Atomize(key);
+  RefPtr<nsIAtom> key_atom = NS_Atomize(key);
   if (key_atom == nsGkAtoms::height)
     aDocument->SetHeaderData(nsGkAtoms::viewport_height, value);
   else if (key_atom == nsGkAtoms::width)
     aDocument->SetHeaderData(nsGkAtoms::viewport_width, value);
   else if (key_atom == nsGkAtoms::initial_scale)
     aDocument->SetHeaderData(nsGkAtoms::viewport_initial_scale, value);
   else if (key_atom == nsGkAtoms::minimum_scale)
     aDocument->SetHeaderData(nsGkAtoms::viewport_minimum_scale, value);
--- a/dom/base/nsContentUtils.h
+++ b/dom/base/nsContentUtils.h
@@ -3285,19 +3285,19 @@ private:
 
   static nsNameSpaceManager *sNameSpaceManager;
 
   static nsIIOService *sIOService;
   static nsIUUIDGenerator *sUUIDGenerator;
 
   static nsIConsoleService* sConsoleService;
 
-  static nsDataHashtable<nsISupportsHashKey, EventNameMapping>* sAtomEventTable;
+  static nsDataHashtable<nsRefPtrHashKey<nsIAtom>, EventNameMapping>* sAtomEventTable;
   static nsDataHashtable<nsStringHashKey, EventNameMapping>* sStringEventTable;
-  static nsCOMArray<nsIAtom>* sUserDefinedEvents;
+  static nsTArray<RefPtr<nsIAtom>>* sUserDefinedEvents;
 
   static nsIStringBundleService* sStringBundleService;
   static nsIStringBundle* sStringBundles[PropertiesFile_COUNT];
 
   static nsIContentPolicy* sContentPolicyService;
   static bool sTriedToGetContentPolicy;
 
   static nsILineBreaker* sLineBreaker;
--- a/dom/base/nsDOMMutationObserver.cpp
+++ b/dom/base/nsDOMMutationObserver.cpp
@@ -678,17 +678,17 @@ nsDOMMutationObserver::Observe(nsINode& 
   if (aOptions.mCharacterDataOldValue.WasPassed() &&
       aOptions.mCharacterDataOldValue.Value() &&
       aOptions.mCharacterData.WasPassed() &&
       !aOptions.mCharacterData.Value()) {
     aRv.Throw(NS_ERROR_DOM_TYPE_ERR);
     return;
   }
 
-  nsCOMArray<nsIAtom> filters;
+  nsTArray<RefPtr<nsIAtom>> filters;
   bool allAttrs = true;
   if (aOptions.mAttributeFilter.WasPassed()) {
     allAttrs = false;
     const mozilla::dom::Sequence<nsString>& filtersAsString =
       aOptions.mAttributeFilter.Value();
     uint32_t len = filtersAsString.Length();
     filters.SetCapacity(len);
 
@@ -762,28 +762,28 @@ nsDOMMutationObserver::GetObservingInfo(
     info.mChildList = mr->ChildList();
     info.mAttributes.Construct(mr->Attributes());
     info.mCharacterData.Construct(mr->CharacterData());
     info.mSubtree = mr->Subtree();
     info.mAttributeOldValue.Construct(mr->AttributeOldValue());
     info.mCharacterDataOldValue.Construct(mr->CharacterDataOldValue());
     info.mNativeAnonymousChildList = mr->NativeAnonymousChildList();
     info.mAnimations = mr->Animations();
-    nsCOMArray<nsIAtom>& filters = mr->AttributeFilter();
-    if (filters.Count()) {
+    nsTArray<RefPtr<nsIAtom>>& filters = mr->AttributeFilter();
+    if (filters.Length()) {
       info.mAttributeFilter.Construct();
       mozilla::dom::Sequence<nsString>& filtersAsStrings =
         info.mAttributeFilter.Value();
-      nsString* strings = filtersAsStrings.AppendElements(filters.Count(),
+      nsString* strings = filtersAsStrings.AppendElements(filters.Length(),
                                                           mozilla::fallible);
       if (!strings) {
         aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
         return;
       }
-      for (int32_t j = 0; j < filters.Count(); ++j) {
+      for (size_t j = 0; j < filters.Length(); ++j) {
         filters[j]->ToString(strings[j]);
       }
     }
     info.mObservedNode = mr->Target();
   }
 }
 
 // static
--- a/dom/base/nsDOMMutationObserver.h
+++ b/dom/base/nsDOMMutationObserver.h
@@ -106,18 +106,18 @@ public:
   }
 
   void GetChangedAnimations(AnimationArray& aRetVal) const
   {
     aRetVal = mChangedAnimations;
   }
 
   nsCOMPtr<nsINode>             mTarget;
-  nsCOMPtr<nsIAtom>             mType;
-  nsCOMPtr<nsIAtom>             mAttrName;
+  RefPtr<nsIAtom>             mType;
+  RefPtr<nsIAtom>             mAttrName;
   nsString                      mAttrNamespace;
   nsString                      mPrevValue;
   RefPtr<nsSimpleContentList> mAddedNodes;
   RefPtr<nsSimpleContentList> mRemovedNodes;
   nsCOMPtr<nsINode>             mPreviousSibling;
   nsCOMPtr<nsINode>             mNextSibling;
   AnimationArray                mAddedAnimations;
   AnimationArray                mRemovedAnimations;
@@ -212,18 +212,18 @@ public:
                    : mAttributeOldValue;
   }
   void SetAttributeOldValue(bool aOldValue)
   {
     NS_ASSERTION(!mParent, "Shouldn't have parent");
     mAttributeOldValue = aOldValue;
   }
 
-  nsCOMArray<nsIAtom>& AttributeFilter() { return mAttributeFilter; }
-  void SetAttributeFilter(nsCOMArray<nsIAtom>&& aFilter)
+  nsTArray<RefPtr<nsIAtom>>& AttributeFilter() { return mAttributeFilter; }
+  void SetAttributeFilter(nsTArray<RefPtr<nsIAtom>>&& aFilter)
   {
     NS_ASSERTION(!mParent, "Shouldn't have parent");
     mAttributeFilter.Clear();
     mAttributeFilter = mozilla::Move(aFilter);
   }
 
   void AddClone(nsMutationReceiverBase* aClone)
   {
@@ -300,18 +300,18 @@ protected:
     if (AllAttributes()) {
       return true;
     }
 
     if (aNameSpaceID != kNameSpaceID_None) {
       return false;
     }
 
-    nsCOMArray<nsIAtom>& filters = AttributeFilter();
-    for (int32_t i = 0; i < filters.Count(); ++i) {
+    nsTArray<RefPtr<nsIAtom>>& filters = AttributeFilter();
+    for (size_t i = 0; i < filters.Length(); ++i) {
       if (filters[i] == aAttr) {
         return true;
       }
     }
     return false;
   }
 
   // The target for the MutationObserver.observe() method.
@@ -331,17 +331,17 @@ private:
   bool                               mChildList;
   bool                               mCharacterData;
   bool                               mCharacterDataOldValue;
   bool                               mNativeAnonymousChildList;
   bool                               mAttributes;
   bool                               mAllAttributes;
   bool                               mAttributeOldValue;
   bool                               mAnimations;
-  nsCOMArray<nsIAtom>                mAttributeFilter;
+  nsTArray<RefPtr<nsIAtom>>          mAttributeFilter;
 };
 
 
 class nsMutationReceiver : public nsMutationReceiverBase
 {
 protected:
   virtual ~nsMutationReceiver() { Disconnect(false); }
 
--- a/dom/base/nsDOMTokenList.h
+++ b/dom/base/nsDOMTokenList.h
@@ -83,25 +83,25 @@ public:
   void SetValue(const nsAString& aValue, mozilla::ErrorResult& rv);
   void Stringify(nsAString& aResult);
 
 protected:
   virtual ~nsDOMTokenList();
 
   nsresult CheckToken(const nsAString& aStr);
   nsresult CheckTokens(const nsTArray<nsString>& aStr);
-  void RemoveDuplicatesInternal(nsTArray<nsCOMPtr<nsIAtom>>* aArray,
+  void RemoveDuplicatesInternal(nsTArray<RefPtr<nsIAtom>>* aArray,
                                 uint32_t aStart);
   void AddInternal(const nsAttrValue* aAttr,
                    const nsTArray<nsString>& aTokens);
   void RemoveInternal(const nsAttrValue* aAttr,
                       const nsTArray<nsString>& aTokens);
   void ReplaceInternal(const nsAttrValue* aAttr,
                        const nsAString& aToken,
                        const nsAString& aNewToken);
   inline const nsAttrValue* GetParsedAttr();
 
   nsCOMPtr<Element> mElement;
-  nsCOMPtr<nsIAtom> mAttrAtom;
+  RefPtr<nsIAtom> mAttrAtom;
   const mozilla::dom::DOMTokenListSupportedTokenArray mSupportedTokens;
 };
 
 #endif // nsDOMTokenList_h___
--- a/dom/base/nsDOMWindowUtils.cpp
+++ b/dom/base/nsDOMWindowUtils.cpp
@@ -324,17 +324,17 @@ nsDOMWindowUtils::GetDocCharsetIsForced(
 }
 
 NS_IMETHODIMP
 nsDOMWindowUtils::GetDocumentMetadata(const nsAString& aName,
                                       nsAString& aValue)
 {
   nsIDocument* doc = GetDocument();
   if (doc) {
-    nsCOMPtr<nsIAtom> name = NS_Atomize(aName);
+    RefPtr<nsIAtom> name = NS_Atomize(aName);
     doc->GetHeaderData(name, aValue);
     return NS_OK;
   }
 
   aValue.Truncate();
   return NS_OK;
 }
 
@@ -2966,17 +2966,17 @@ nsDOMWindowUtils::GetUnanimatedComputedS
     return NS_ERROR_INVALID_ARG;
   }
 
   nsIPresShell* shell = GetPresShell();
   if (!shell) {
     return NS_ERROR_FAILURE;
   }
 
-  nsCOMPtr<nsIAtom> pseudo = nsCSSPseudoElements::GetPseudoAtom(aPseudoElement);
+  RefPtr<nsIAtom> pseudo = nsCSSPseudoElements::GetPseudoAtom(aPseudoElement);
   RefPtr<nsStyleContext> styleContext =
     nsComputedDOMStyle::GetUnanimatedStyleContextNoFlush(element,
                                                          pseudo, shell);
 
   if (styleContext->IsServo()) {
     RefPtr<RawServoAnimationValue> value =
       Servo_ComputedValues_ExtractAnimationValue(styleContext->AsServo(),
                                                  propertyID).Consume();
--- a/dom/base/nsDocument.cpp
+++ b/dom/base/nsDocument.cpp
@@ -595,17 +595,17 @@ public:
   {
     return mElements.SafeElementAt(aIndex)->AsElement();
   }
 
   virtual Element* GetFirstNamedElement(const nsAString& aName,
                                         bool& aFound) override
   {
     aFound = false;
-    nsCOMPtr<nsIAtom> name = NS_Atomize(aName);
+    RefPtr<nsIAtom> name = NS_Atomize(aName);
     for (uint32_t i = 0; i < mElements.Length(); i++) {
       MOZ_DIAGNOSTIC_ASSERT(mElements[i]);
       Element* element = mElements[i]->AsElement();
       if (element->GetID() == name ||
           (element->HasName() &&
            element->GetParsedAttr(nsGkAtoms::name)->GetAtomValue() == name)) {
         aFound = true;
         return element;
@@ -5968,17 +5968,17 @@ nsDocument::GetCustomElementRegistry()
 static CSSPseudoElementType
 GetPseudoElementType(const nsString& aString, ErrorResult& aRv)
 {
   MOZ_ASSERT(!aString.IsEmpty(), "GetPseudoElementType aString should be non-null");
   if (aString.Length() <= 2 || aString[0] != ':' || aString[1] != ':') {
     aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR);
     return CSSPseudoElementType::NotPseudo;
   }
-  nsCOMPtr<nsIAtom> pseudo = NS_Atomize(Substring(aString, 1));
+  RefPtr<nsIAtom> pseudo = NS_Atomize(Substring(aString, 1));
   return nsCSSPseudoElements::GetPseudoType(pseudo,
       nsCSSProps::EnabledState::eInUASheets);
 }
 
 already_AddRefed<Element>
 nsDocument::CreateElement(const nsAString& aTagName,
                           const ElementCreationOptionsOrString& aOptions,
                           ErrorResult& rv)
@@ -6307,17 +6307,17 @@ nsDocument::CustomElementConstructor(JSC
     return true;
   }
 
   RefPtr<mozilla::dom::CustomElementRegistry> registry = window->CustomElements();
   if (!registry) {
     return true;
   }
 
-  nsCOMPtr<nsIAtom> typeAtom(NS_Atomize(elemName));
+  RefPtr<nsIAtom> typeAtom(NS_Atomize(elemName));
   CustomElementDefinition* definition =
     registry->mCustomDefinitions.GetWeak(typeAtom);
   if (!definition) {
     return true;
   }
 
   RefPtr<Element> element;
 
@@ -7002,17 +7002,17 @@ nsDocument::GetAnonymousElementByAttribu
   return NS_OK;
 }
 
 Element*
 nsIDocument::GetAnonymousElementByAttribute(Element& aElement,
                                             const nsAString& aAttrName,
                                             const nsAString& aAttrValue)
 {
-  nsCOMPtr<nsIAtom> attribute = NS_Atomize(aAttrName);
+  RefPtr<nsIAtom> attribute = NS_Atomize(aAttrName);
 
   return GetAnonymousElementByAttribute(&aElement, attribute, aAttrValue);
 }
 
 
 NS_IMETHODIMP
 nsDocument::GetAnonymousNodes(nsIDOMElement* aElement,
                               nsIDOMNodeList** aResult)
@@ -7408,17 +7408,17 @@ nsDocument::GetBoxObjectFor(Element* aEl
   RefPtr<BoxObject> boxObject;
   auto entry = mBoxObjectTable->LookupForAdd(aElement);
   if (entry) {
     boxObject = entry.Data();
     return boxObject.forget();
   }
 
   int32_t namespaceID;
-  nsCOMPtr<nsIAtom> tag = BindingManager()->ResolveTag(aElement, &namespaceID);
+  RefPtr<nsIAtom> tag = BindingManager()->ResolveTag(aElement, &namespaceID);
 #ifdef MOZ_XUL
   if (namespaceID == kNameSpaceID_XUL) {
     if (tag == nsGkAtoms::browser ||
         tag == nsGkAtoms::editor ||
         tag == nsGkAtoms::iframe) {
       boxObject = new ContainerBoxObject();
     } else if (tag == nsGkAtoms::menu) {
       boxObject = new MenuBoxObject();
@@ -8706,17 +8706,17 @@ nsDocument::RetrieveRelevantHeaders(nsIC
     };
 
     nsAutoCString headerVal;
     const char *const *name = headers;
     while (*name) {
       rv =
         httpChannel->GetResponseHeader(nsDependentCString(*name), headerVal);
       if (NS_SUCCEEDED(rv) && !headerVal.IsEmpty()) {
-        nsCOMPtr<nsIAtom> key = NS_Atomize(*name);
+        RefPtr<nsIAtom> key = NS_Atomize(*name);
         SetHeaderData(key, NS_ConvertASCIItoUTF16(headerVal));
       }
       ++name;
     }
   } else {
     nsCOMPtr<nsIFileChannel> fileChannel = do_QueryInterface(aChannel);
     if (fileChannel) {
       nsCOMPtr<nsIFile> file;
--- a/dom/base/nsDocument.h
+++ b/dom/base/nsDocument.h
@@ -139,17 +139,17 @@ public:
   {
   }
 
   ~nsDocHeaderData(void)
   {
     delete mNext;
   }
 
-  nsCOMPtr<nsIAtom> mField;
+  RefPtr<nsIAtom> mField;
   nsString          mData;
   nsDocHeaderData*  mNext;
 };
 
 class nsDOMStyleSheetList : public mozilla::dom::StyleSheetList,
                             public nsStubDocumentObserver
 {
 public:
--- a/dom/base/nsGenericDOMDataNode.cpp
+++ b/dom/base/nsGenericDOMDataNode.cpp
@@ -292,17 +292,17 @@ nsGenericDOMDataNode::SetTextInternal(ui
   nsIDocument *document = GetComposedDoc();
   mozAutoDocUpdate updateBatch(document, UPDATE_CONTENT_MODEL, aNotify);
 
   bool haveMutationListeners = aNotify &&
     nsContentUtils::HasMutationListeners(this,
       NS_EVENT_BITS_MUTATION_CHARACTERDATAMODIFIED,
       this);
 
-  nsCOMPtr<nsIAtom> oldValue;
+  RefPtr<nsIAtom> oldValue;
   if (haveMutationListeners) {
     oldValue = GetCurrentValueAtom();
   }
 
   if (aNotify) {
     CharacterDataChangeInfo info = {
       aOffset == textLength,
       aOffset,
--- a/dom/base/nsINode.cpp
+++ b/dom/base/nsINode.cpp
@@ -806,17 +806,17 @@ SetUserDataProperty(uint16_t aCategory, 
 }
 
 nsresult
 nsINode::SetUserData(const nsAString &aKey, nsIVariant *aData, nsIVariant **aResult)
 {
   OwnerDoc()->WarnOnceAbout(nsIDocument::eGetSetUserData);
   *aResult = nullptr;
 
-  nsCOMPtr<nsIAtom> key = NS_Atomize(aKey);
+  RefPtr<nsIAtom> key = NS_Atomize(aKey);
   if (!key) {
     return NS_ERROR_OUT_OF_MEMORY;
   }
 
   nsresult rv;
   void *data;
   if (aData) {
     rv = SetUserDataProperty(DOM_USER_DATA, this, key, aData, &data);
@@ -859,17 +859,17 @@ nsINode::SetUserData(JSContext* aCx, con
   aError = nsContentUtils::XPConnect()->VariantToJS(aCx, GetWrapper(), oldData,
                                                     aRetval);
 }
 
 nsIVariant*
 nsINode::GetUserData(const nsAString& aKey)
 {
   OwnerDoc()->WarnOnceAbout(nsIDocument::eGetSetUserData);
-  nsCOMPtr<nsIAtom> key = NS_Atomize(aKey);
+  RefPtr<nsIAtom> key = NS_Atomize(aKey);
   if (!key) {
     return nullptr;
   }
 
   return static_cast<nsIVariant*>(GetProperty(DOM_USER_DATA, key));
 }
 
 void
--- a/dom/base/nsIdentifierMapEntry.h
+++ b/dom/base/nsIdentifierMapEntry.h
@@ -54,17 +54,17 @@ public:
     }
 
     AtomOrString(AtomOrString&& aOther)
       : mAtom(aOther.mAtom.forget())
       , mString(aOther.mString)
     {
     }
 
-    nsCOMPtr<nsIAtom> mAtom;
+    RefPtr<nsIAtom> mAtom;
     const nsString mString;
   };
 
   typedef const AtomOrString& KeyType;
   typedef const AtomOrString* KeyTypePointer;
 
   typedef mozilla::dom::Element Element;
   typedef mozilla::net::ReferrerPolicy ReferrerPolicy;
--- a/dom/base/nsNameSpaceManager.cpp
+++ b/dom/base/nsNameSpaceManager.cpp
@@ -94,17 +94,17 @@ nsNameSpaceManager::RegisterNameSpace(co
                                       int32_t& aNameSpaceID)
 {
   if (aURI.IsEmpty()) {
     aNameSpaceID = kNameSpaceID_None; // xmlns="", see bug 75700 for details
 
     return NS_OK;
   }
 
-  nsCOMPtr<nsIAtom> atom = NS_Atomize(aURI);
+  RefPtr<nsIAtom> atom = NS_Atomize(aURI);
   nsresult rv = NS_OK;
   if (!mURIToIDTable.Get(atom, &aNameSpaceID)) {
     aNameSpaceID = mURIArray.Length();
 
     rv = AddNameSpace(atom.forget(), aNameSpaceID);
     if (NS_FAILED(rv)) {
       aNameSpaceID = kNameSpaceID_Unknown;
     }
@@ -136,17 +136,17 @@ nsNameSpaceManager::GetNameSpaceURI(int3
 int32_t
 nsNameSpaceManager::GetNameSpaceID(const nsAString& aURI,
                                    bool aInChromeDoc)
 {
   if (aURI.IsEmpty()) {
     return kNameSpaceID_None; // xmlns="", see bug 75700 for details
   }
 
-  nsCOMPtr<nsIAtom> atom = NS_Atomize(aURI);
+  RefPtr<nsIAtom> atom = NS_Atomize(aURI);
   return GetNameSpaceID(atom, aInChromeDoc);
 }
 
 int32_t
 nsNameSpaceManager::GetNameSpaceID(nsIAtom* aURI,
                                    bool aInChromeDoc)
 {
   if (aURI == nsGkAtoms::_empty) {
@@ -229,34 +229,34 @@ nsNameSpaceManager::HasElementCreator(in
          aNameSpaceID == kNameSpaceID_MathML ||
          aNameSpaceID == kNameSpaceID_SVG ||
          false;
 }
 
 nsresult nsNameSpaceManager::AddNameSpace(already_AddRefed<nsIAtom> aURI,
                                           const int32_t aNameSpaceID)
 {
-  nsCOMPtr<nsIAtom> uri = aURI;
+  RefPtr<nsIAtom> uri = aURI;
   if (aNameSpaceID < 0) {
     // We've wrapped...  Can't do anything else here; just bail.
     return NS_ERROR_OUT_OF_MEMORY;
   }
 
   MOZ_ASSERT(aNameSpaceID == (int32_t) mURIArray.Length());
   mURIArray.AppendElement(uri.forget());
   mURIToIDTable.Put(mURIArray.LastElement(), aNameSpaceID);
 
   return NS_OK;
 }
 
 nsresult
 nsNameSpaceManager::AddDisabledNameSpace(already_AddRefed<nsIAtom> aURI,
                                          const int32_t aNameSpaceID)
 {
-  nsCOMPtr<nsIAtom> uri = aURI;
+  RefPtr<nsIAtom> uri = aURI;
   if (aNameSpaceID < 0) {
     // We've wrapped...  Can't do anything else here; just bail.
     return NS_ERROR_OUT_OF_MEMORY;
   }
 
   MOZ_ASSERT(aNameSpaceID == (int32_t) mURIArray.Length());
   mURIArray.AppendElement(uri.forget());
   mDisabledURIToIDTable.Put(mURIArray.LastElement(), aNameSpaceID);
--- a/dom/base/nsNameSpaceManager.h
+++ b/dom/base/nsNameSpaceManager.h
@@ -68,16 +68,16 @@ public:
   bool mSVGDisabled;
 
 private:
   bool Init();
   nsresult AddNameSpace(already_AddRefed<nsIAtom> aURI, const int32_t aNameSpaceID);
   nsresult AddDisabledNameSpace(already_AddRefed<nsIAtom> aURI, const int32_t aNameSpaceID);
   ~nsNameSpaceManager() {};
 
-  nsDataHashtable<nsISupportsHashKey, int32_t> mURIToIDTable;
-  nsDataHashtable<nsISupportsHashKey, int32_t> mDisabledURIToIDTable;
-  nsTArray<nsCOMPtr<nsIAtom>> mURIArray;
+  nsDataHashtable<nsRefPtrHashKey<nsIAtom>, int32_t> mURIToIDTable;
+  nsDataHashtable<nsRefPtrHashKey<nsIAtom>, int32_t> mDisabledURIToIDTable;
+  nsTArray<RefPtr<nsIAtom>> mURIArray;
 
   static mozilla::StaticRefPtr<nsNameSpaceManager> sInstance;
 };
 
 #endif // nsNameSpaceManager_h___
--- a/dom/base/nsNodeInfoManager.cpp
+++ b/dom/base/nsNodeInfoManager.cpp
@@ -276,17 +276,17 @@ nsNodeInfoManager::GetNodeInfo(nsIAtom *
 
 nsresult
 nsNodeInfoManager::GetNodeInfo(const nsAString& aName, nsIAtom *aPrefix,
                                int32_t aNamespaceID, uint16_t aNodeType,
                                NodeInfo** aNodeInfo)
 {
 #ifdef DEBUG
   {
-    nsCOMPtr<nsIAtom> nameAtom = NS_Atomize(aName);
+    RefPtr<nsIAtom> nameAtom = NS_Atomize(aName);
     CheckValidNodeInfo(aNodeType, nameAtom, aNamespaceID, nullptr);
   }
 #endif
 
   NodeInfo::NodeInfoInner tmpKey(aName, aPrefix, aNamespaceID, aNodeType);
 
   uint32_t index =
     GetNodeInfoInnerHashValue(&tmpKey) % RECENTLY_USED_NODEINFOS_SIZE;
@@ -302,17 +302,17 @@ nsNodeInfoManager::GetNodeInfo(const nsA
   if (node) {
     RefPtr<NodeInfo> nodeInfo = static_cast<NodeInfo*>(node);
     mRecentlyUsedNodeInfos[index] = nodeInfo;
     nodeInfo.forget(aNodeInfo);
 
     return NS_OK;
   }
 
-  nsCOMPtr<nsIAtom> nameAtom = NS_Atomize(aName);
+  RefPtr<nsIAtom> nameAtom = NS_Atomize(aName);
   NS_ENSURE_TRUE(nameAtom, NS_ERROR_OUT_OF_MEMORY);
 
   RefPtr<NodeInfo> newNodeInfo =
     new NodeInfo(nameAtom, aPrefix, aNamespaceID, aNodeType, nullptr, this);
   NS_ENSURE_TRUE(newNodeInfo, NS_ERROR_OUT_OF_MEMORY);
 
   PLHashEntry *he;
   he = PL_HashTableAdd(mNodeInfoHash, &newNodeInfo->mInner, newNodeInfo);
--- a/dom/base/nsPropertyTable.cpp
+++ b/dom/base/nsPropertyTable.cpp
@@ -43,17 +43,17 @@ public:
 
   bool Equals(nsIAtom *aPropertyName)
   {
     return mName == aPropertyName;
   }
 
   size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf);
 
-  nsCOMPtr<nsIAtom>  mName;           // property name
+  RefPtr<nsIAtom>  mName;           // property name
   PLDHashTable       mObjectValueMap; // map of object/value pairs
   NSPropertyDtorFunc mDtorFunc;       // property specific value dtor function
   void*              mDtorData;       // pointer to pass to dtor
   bool               mTransfer;       // whether to transfer in
                                       // TransferOrDeleteAllPropertiesFor
 
   PropertyList*      mNext;
 };
--- a/dom/base/nsReferencedElement.cpp
+++ b/dom/base/nsReferencedElement.cpp
@@ -110,17 +110,17 @@ nsReferencedElement::Reset(nsIContent* a
       if (observer) {
         load->AddObserver(observer);
       }
       // Keep going so we set up our watching stuff a bit
     }
   }
 
   if (aWatch) {
-    nsCOMPtr<nsIAtom> atom = NS_Atomize(ref);
+    RefPtr<nsIAtom> atom = NS_Atomize(ref);
     if (!atom)
       return;
     atom.swap(mWatchID);
   }
 
   mReferencingImage = aReferenceImage;
 
   HaveNewDocument(doc, aWatch, ref);
@@ -132,17 +132,17 @@ nsReferencedElement::ResetWithID(nsICont
 {
   nsIDocument *doc = aFromContent->OwnerDoc();
   if (!doc)
     return;
 
   // XXX Need to take care of XBL/XBL2
 
   if (aWatch) {
-    nsCOMPtr<nsIAtom> atom = NS_Atomize(aID);
+    RefPtr<nsIAtom> atom = NS_Atomize(aID);
     if (!atom)
       return;
     atom.swap(mWatchID);
   }
 
   mReferencingImage = false;
 
   HaveNewDocument(doc, aWatch, aID);
--- a/dom/base/nsReferencedElement.h
+++ b/dom/base/nsReferencedElement.h
@@ -177,17 +177,17 @@ private:
     virtual ~DocumentLoadNotification() {}
 
     virtual void SetTo(Element* aTo) override { }
 
     nsString mRef;
   };
   friend class DocumentLoadNotification;
 
-  nsCOMPtr<nsIAtom>      mWatchID;
+  RefPtr<nsIAtom>      mWatchID;
   nsCOMPtr<nsIDocument>  mWatchDocument;
   RefPtr<Element> mElement;
   RefPtr<Notification> mPendingNotification;
   bool                   mReferencingImage;
 };
 
 inline void
 ImplCycleCollectionUnlink(nsReferencedElement& aField)
--- a/dom/base/nsTextNode.cpp
+++ b/dom/base/nsTextNode.cpp
@@ -85,17 +85,17 @@ private:
 
   // This doesn't need to be a strong pointer because it's only non-null
   // while we're bound to the document tree, and it points to an ancestor
   // so the ancestor must be bound to the document tree the whole time
   // and can't be deleted.
   nsIContent* mGrandparent;
   // What attribute we're showing
   int32_t mNameSpaceID;
-  nsCOMPtr<nsIAtom> mAttrName;
+  RefPtr<nsIAtom> mAttrName;
 };
 
 nsTextNode::~nsTextNode()
 {
 }
 
 // Use the CC variant of this, even though this class does not define
 // a new CC participant, to make QIing to the CC interfaces faster.
--- a/dom/base/nsTreeSanitizer.cpp
+++ b/dom/base/nsTreeSanitizer.cpp
@@ -919,23 +919,23 @@ nsIAtom** const kURLAttributesMathML[] =
   &nsGkAtoms::href,
   &nsGkAtoms::src,
   &nsGkAtoms::cdgroup_,
   &nsGkAtoms::altimg_,
   &nsGkAtoms::definitionURL_,
   nullptr
 };
 
-nsTHashtable<nsISupportsHashKey>* nsTreeSanitizer::sElementsHTML = nullptr;
-nsTHashtable<nsISupportsHashKey>* nsTreeSanitizer::sAttributesHTML = nullptr;
-nsTHashtable<nsISupportsHashKey>* nsTreeSanitizer::sPresAttributesHTML = nullptr;
-nsTHashtable<nsISupportsHashKey>* nsTreeSanitizer::sElementsSVG = nullptr;
-nsTHashtable<nsISupportsHashKey>* nsTreeSanitizer::sAttributesSVG = nullptr;
-nsTHashtable<nsISupportsHashKey>* nsTreeSanitizer::sElementsMathML = nullptr;
-nsTHashtable<nsISupportsHashKey>* nsTreeSanitizer::sAttributesMathML = nullptr;
+nsTHashtable<nsRefPtrHashKey<nsIAtom>>* nsTreeSanitizer::sElementsHTML = nullptr;
+nsTHashtable<nsRefPtrHashKey<nsIAtom>>* nsTreeSanitizer::sAttributesHTML = nullptr;
+nsTHashtable<nsRefPtrHashKey<nsIAtom>>* nsTreeSanitizer::sPresAttributesHTML = nullptr;
+nsTHashtable<nsRefPtrHashKey<nsIAtom>>* nsTreeSanitizer::sElementsSVG = nullptr;
+nsTHashtable<nsRefPtrHashKey<nsIAtom>>* nsTreeSanitizer::sAttributesSVG = nullptr;
+nsTHashtable<nsRefPtrHashKey<nsIAtom>>* nsTreeSanitizer::sElementsMathML = nullptr;
+nsTHashtable<nsRefPtrHashKey<nsIAtom>>* nsTreeSanitizer::sAttributesMathML = nullptr;
 nsIPrincipal* nsTreeSanitizer::sNullPrincipal = nullptr;
 
 nsTreeSanitizer::nsTreeSanitizer(uint32_t aFlags)
  : mAllowStyles(aFlags & nsIParserUtils::SanitizerAllowStyle)
  , mAllowComments(aFlags & nsIParserUtils::SanitizerAllowComments)
  , mDropNonCSSPresentation(aFlags &
      nsIParserUtils::SanitizerDropNonCSSPresentation)
  , mDropForms(aFlags & nsIParserUtils::SanitizerDropForms)
@@ -1140,28 +1140,28 @@ nsTreeSanitizer::SanitizeStyleSheet(cons
       }
     }
   }
   return didSanitize;
 }
 
 void
 nsTreeSanitizer::SanitizeAttributes(mozilla::dom::Element* aElement,
-                                    nsTHashtable<nsISupportsHashKey>* aAllowed,
+                                    nsTHashtable<nsRefPtrHashKey<nsIAtom>>* aAllowed,
                                     nsIAtom*** aURLs,
                                     bool aAllowXLink,
                                     bool aAllowStyle,
                                     bool aAllowDangerousSrc)
 {
   uint32_t ac = aElement->GetAttrCount();
 
   for (int32_t i = ac - 1; i >= 0; --i) {
     const nsAttrName* attrName = aElement->GetAttrNameAt(i);
     int32_t attrNs = attrName->NamespaceID();
-    nsCOMPtr<nsIAtom> attrLocal = attrName->LocalName();
+    RefPtr<nsIAtom> attrLocal = attrName->LocalName();
 
     if (kNameSpaceID_None == attrNs) {
       if (aAllowStyle && nsGkAtoms::style == attrLocal) {
         nsCOMPtr<nsIURI> baseURI = aElement->GetBaseURI();
         nsIDocument* document = aElement->OwnerDoc();
         // Pass the CSS Loader object to the parser, to allow parser error
         // reports to include the outer window ID.
         nsCSSParser parser(document->CSSLoader());
@@ -1473,57 +1473,64 @@ nsTreeSanitizer::SanitizeChildren(nsINod
 }
 
 void
 nsTreeSanitizer::RemoveAllAttributes(nsIContent* aElement)
 {
   const nsAttrName* attrName;
   while ((attrName = aElement->GetAttrNameAt(0))) {
     int32_t attrNs = attrName->NamespaceID();
-    nsCOMPtr<nsIAtom> attrLocal = attrName->LocalName();
+    RefPtr<nsIAtom> attrLocal = attrName->LocalName();
     aElement->UnsetAttr(attrNs, attrLocal, false);
   }
 }
 
 void
 nsTreeSanitizer::InitializeStatics()
 {
   NS_PRECONDITION(!sElementsHTML, "Initializing a second time.");
 
-  sElementsHTML = new nsTHashtable<nsISupportsHashKey>(ArrayLength(kElementsHTML));
+  sElementsHTML =
+    new nsTHashtable<nsRefPtrHashKey<nsIAtom>>(ArrayLength(kElementsHTML));
   for (uint32_t i = 0; kElementsHTML[i]; i++) {
     sElementsHTML->PutEntry(*kElementsHTML[i]);
   }
 
-  sAttributesHTML = new nsTHashtable<nsISupportsHashKey>(ArrayLength(kAttributesHTML));
+  sAttributesHTML =
+    new nsTHashtable<nsRefPtrHashKey<nsIAtom>>(ArrayLength(kAttributesHTML));
   for (uint32_t i = 0; kAttributesHTML[i]; i++) {
     sAttributesHTML->PutEntry(*kAttributesHTML[i]);
   }
 
-  sPresAttributesHTML = new nsTHashtable<nsISupportsHashKey>(ArrayLength(kPresAttributesHTML));
+  sPresAttributesHTML =
+    new nsTHashtable<nsRefPtrHashKey<nsIAtom>>(ArrayLength(kPresAttributesHTML));
   for (uint32_t i = 0; kPresAttributesHTML[i]; i++) {
     sPresAttributesHTML->PutEntry(*kPresAttributesHTML[i]);
   }
 
-  sElementsSVG = new nsTHashtable<nsISupportsHashKey>(ArrayLength(kElementsSVG));
+  sElementsSVG =
+    new nsTHashtable<nsRefPtrHashKey<nsIAtom>>(ArrayLength(kElementsSVG));
   for (uint32_t i = 0; kElementsSVG[i]; i++) {
     sElementsSVG->PutEntry(*kElementsSVG[i]);
   }
 
-  sAttributesSVG = new nsTHashtable<nsISupportsHashKey>(ArrayLength(kAttributesSVG));
+  sAttributesSVG =
+    new nsTHashtable<nsRefPtrHashKey<nsIAtom>>(ArrayLength(kAttributesSVG));
   for (uint32_t i = 0; kAttributesSVG[i]; i++) {
     sAttributesSVG->PutEntry(*kAttributesSVG[i]);
   }
 
-  sElementsMathML = new nsTHashtable<nsISupportsHashKey>(ArrayLength(kElementsMathML));
+  sElementsMathML =
+    new nsTHashtable<nsRefPtrHashKey<nsIAtom>>(ArrayLength(kElementsMathML));
   for (uint32_t i = 0; kElementsMathML[i]; i++) {
     sElementsMathML->PutEntry(*kElementsMathML[i]);
   }
 
-  sAttributesMathML = new nsTHashtable<nsISupportsHashKey>(ArrayLength(kAttributesMathML));
+  sAttributesMathML =
+    new nsTHashtable<nsRefPtrHashKey<nsIAtom>>(ArrayLength(kAttributesMathML));
   for (uint32_t i = 0; kAttributesMathML[i]; i++) {
     sAttributesMathML->PutEntry(*kAttributesMathML[i]);
   }
 
   nsCOMPtr<nsIPrincipal> principal = NullPrincipal::Create();
   principal.forget(&sNullPrincipal);
 }
 
--- a/dom/base/nsTreeSanitizer.h
+++ b/dom/base/nsTreeSanitizer.h
@@ -125,17 +125,17 @@ class MOZ_STACK_CLASS nsTreeSanitizer {
      * @param aAllowed the whitelist of permitted local names to use
      * @param aURLs the local names of URL-valued attributes
      * @param aAllowXLink whether XLink attributes are allowed
      * @param aAllowStyle whether the style attribute is allowed
      * @param aAllowDangerousSrc whether to leave the value of the src
      *                           attribute unsanitized
      */
     void SanitizeAttributes(mozilla::dom::Element* aElement,
-                            nsTHashtable<nsISupportsHashKey>* aAllowed,
+                            nsTHashtable<nsRefPtrHashKey<nsIAtom>>* aAllowed,
                             nsIAtom*** aURLs,
                             bool aAllowXLink,
                             bool aAllowStyle,
                             bool aAllowDangerousSrc);
 
     /**
      * Remove the named URL attribute from the element if the URL fails a
      * security check.
@@ -181,47 +181,47 @@ class MOZ_STACK_CLASS nsTreeSanitizer {
     /**
      * Removes all attributes from an element node.
      */
     void RemoveAllAttributes(nsIContent* aElement);
 
     /**
      * The whitelist of HTML elements.
      */
-    static nsTHashtable<nsISupportsHashKey>* sElementsHTML;
+    static nsTHashtable<nsRefPtrHashKey<nsIAtom>>* sElementsHTML;
 
     /**
      * The whitelist of non-presentational HTML attributes.
      */
-    static nsTHashtable<nsISupportsHashKey>* sAttributesHTML;
+    static nsTHashtable<nsRefPtrHashKey<nsIAtom>>* sAttributesHTML;
 
     /**
      * The whitelist of presentational HTML attributes.
      */
-    static nsTHashtable<nsISupportsHashKey>* sPresAttributesHTML;
+    static nsTHashtable<nsRefPtrHashKey<nsIAtom>>* sPresAttributesHTML;
 
     /**
      * The whitelist of SVG elements.
      */
-    static nsTHashtable<nsISupportsHashKey>* sElementsSVG;
+    static nsTHashtable<nsRefPtrHashKey<nsIAtom>>* sElementsSVG;
 
     /**
      * The whitelist of SVG attributes.
      */
-    static nsTHashtable<nsISupportsHashKey>* sAttributesSVG;
+    static nsTHashtable<nsRefPtrHashKey<nsIAtom>>* sAttributesSVG;
 
     /**
      * The whitelist of SVG elements.
      */
-    static nsTHashtable<nsISupportsHashKey>* sElementsMathML;
+    static nsTHashtable<nsRefPtrHashKey<nsIAtom>>* sElementsMathML;
 
     /**
      * The whitelist of MathML attributes.
      */
-    static nsTHashtable<nsISupportsHashKey>* sAttributesMathML;
+    static nsTHashtable<nsRefPtrHashKey<nsIAtom>>* sAttributesMathML;
 
     /**
      * Reusable null principal for URL checks.
      */
     static nsIPrincipal* sNullPrincipal;
 };
 
 #endif // nsTreeSanitizer_h_
--- a/dom/base/nsXMLNameSpaceMap.h
+++ b/dom/base/nsXMLNameSpaceMap.h
@@ -12,17 +12,17 @@
 #include "nsCOMPtr.h"
 #include "nsIAtom.h"
 
 struct nsNameSpaceEntry
 {
   explicit nsNameSpaceEntry(nsIAtom* aPrefix)
     : prefix(aPrefix) {}
 
-  nsCOMPtr<nsIAtom> prefix;
+  RefPtr<nsIAtom> prefix;
   MOZ_INIT_OUTSIDE_CTOR int32_t nameSpaceID;
 };
 
 /**
  * nsXMLNameSpaceMap contains a set of prefixes which are mapped onto
  * namespaces.  It allows the set to be searched by prefix or by namespace ID.
  */
 class nsXMLNameSpaceMap
--- a/dom/canvas/CanvasRenderingContext2D.h
+++ b/dom/canvas/CanvasRenderingContext2D.h
@@ -1071,17 +1071,17 @@ protected:
     mozilla::gfx::Float ShadowBlurSigma() const
     {
       return std::min(SIGMA_MAX, shadowBlur / 2.0f);
     }
 
     nsTArray<ClipState> clipsAndTransforms;
 
     RefPtr<gfxFontGroup> fontGroup;
-    nsCOMPtr<nsIAtom> fontLanguage;
+    RefPtr<nsIAtom> fontLanguage;
     nsFont fontFont;
 
     EnumeratedArray<Style, Style::MAX, RefPtr<CanvasGradient>> gradientStyles;
     EnumeratedArray<Style, Style::MAX, RefPtr<CanvasPattern>> patternStyles;
     EnumeratedArray<Style, Style::MAX, nscolor> colorStyles;
 
     nsString font;
     TextAlign textAlign;
--- a/dom/events/DOMEventTargetHelper.h
+++ b/dom/events/DOMEventTargetHelper.h
@@ -203,17 +203,17 @@ private:
   // mParentObject pre QI-ed and cached (inner window)
   // (it is needed for off main thread access)
   // It is obtained in BindToOwner and reset in DisconnectFromOwner.
   nsPIDOMWindowInner* MOZ_NON_OWNING_REF mOwnerWindow;
   bool                       mHasOrHasHadOwnerWindow;
 
   struct {
     nsTArray<nsString> mStrings;
-    nsTArray<nsCOMPtr<nsIAtom>> mAtoms;
+    nsTArray<RefPtr<nsIAtom>> mAtoms;
   } mKeepingAliveTypes;
 
   bool mIsKeptAlive;
 };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(DOMEventTargetHelper,
                               NS_DOMEVENTTARGETHELPER_IID)
 
--- a/dom/events/DataTransfer.cpp
+++ b/dom/events/DataTransfer.cpp
@@ -199,17 +199,17 @@ DataTransfer::~DataTransfer()
 // static
 already_AddRefed<DataTransfer>
 DataTransfer::Constructor(const GlobalObject& aGlobal,
                           const nsAString& aEventType, bool aIsExternal,
                           ErrorResult& aRv)
 {
   nsAutoCString onEventType("on");
   AppendUTF16toUTF8(aEventType, onEventType);
-  nsCOMPtr<nsIAtom> eventTypeAtom = NS_Atomize(onEventType);
+  RefPtr<nsIAtom> eventTypeAtom = NS_Atomize(onEventType);
   if (!eventTypeAtom) {
     aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
     return nullptr;
   }
 
   EventMessage eventMessage = nsContentUtils::GetEventMessage(eventTypeAtom);
   RefPtr<DataTransfer> transfer = new DataTransfer(aGlobal.GetAsSupports(),
                                                      eventMessage, aIsExternal,
@@ -692,17 +692,17 @@ void
 DataTransfer::TypesListMayHaveChanged()
 {
   DataTransferBinding::ClearCachedTypesValue(this);
 }
 
 already_AddRefed<DataTransfer>
 DataTransfer::MozCloneForEvent(const nsAString& aEvent, ErrorResult& aRv)
 {
-  nsCOMPtr<nsIAtom> atomEvt = NS_Atomize(aEvent);
+  RefPtr<nsIAtom> atomEvt = NS_Atomize(aEvent);
   if (!atomEvt) {
     aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
     return nullptr;
   }
   EventMessage eventMessage = nsContentUtils::GetEventMessage(atomEvt);
 
   RefPtr<DataTransfer> dt;
   nsresult rv = Clone(mParent, eventMessage, false, false, getter_AddRefs(dt));
--- a/dom/events/EventListenerManager.cpp
+++ b/dom/events/EventListenerManager.cpp
@@ -685,32 +685,32 @@ EventListenerManager::ListenerCanHandle(
 }
 
 void
 EventListenerManager::AddEventListenerByType(
                         EventListenerHolder aListenerHolder,
                         const nsAString& aType,
                         const EventListenerFlags& aFlags)
 {
-  nsCOMPtr<nsIAtom> atom;
+  RefPtr<nsIAtom> atom;
   EventMessage message = mIsMainThreadELM ?
     nsContentUtils::GetEventMessageAndAtomForListener(aType,
                                                       getter_AddRefs(atom)) :
     eUnidentifiedEvent;
   AddEventListenerInternal(Move(aListenerHolder),
                            message, atom, aType, aFlags);
 }
 
 void
 EventListenerManager::RemoveEventListenerByType(
                         EventListenerHolder aListenerHolder,
                         const nsAString& aType,
                         const EventListenerFlags& aFlags)
 {
-  nsCOMPtr<nsIAtom> atom;
+  RefPtr<nsIAtom> atom;
   EventMessage message = mIsMainThreadELM ?
     nsContentUtils::GetEventMessageAndAtomForListener(aType,
                                                       getter_AddRefs(atom)) :
     eUnidentifiedEvent;
   RemoveEventListenerInternal(Move(aListenerHolder),
                               message, atom, aType, aFlags);
 }
 
@@ -927,17 +927,17 @@ EventListenerManager::CompileEventHandle
   // Activate JSAPI, and make sure that exceptions are reported on the right
   // Window.
   AutoJSAPI jsapi;
   if (NS_WARN_IF(!jsapi.Init(global))) {
     return NS_ERROR_UNEXPECTED;
   }
   JSContext* cx = jsapi.cx();
 
-  nsCOMPtr<nsIAtom> typeAtom = aListener->mTypeAtom;
+  RefPtr<nsIAtom> typeAtom = aListener->mTypeAtom;
   nsIAtom* attrName = typeAtom;
 
   // Flag us as not a string so we don't keep trying to compile strings which
   // can't be compiled.
   aListener->mHandlerIsString = false;
 
   // mTarget may not be an Element if it's a window and we're
   // getting an inline event listener forwarded from <html:body> or
@@ -1493,17 +1493,17 @@ EventListenerManager::MutationListenerBi
   }
   return bits;
 }
 
 bool
 EventListenerManager::HasListenersFor(const nsAString& aEventName)
 {
   if (mIsMainThreadELM) {
-    nsCOMPtr<nsIAtom> atom = NS_Atomize(NS_LITERAL_STRING("on") + aEventName);
+    RefPtr<nsIAtom> atom = NS_Atomize(NS_LITERAL_STRING("on") + aEventName);
     return HasListenersFor(atom);
   }
 
   uint32_t count = mListeners.Length();
   for (uint32_t i = 0; i < count; ++i) {
     Listener* listener = &mListeners.ElementAt(i);
     if (listener->mTypeString == aEventName) {
       return true;
--- a/dom/events/EventListenerManager.h
+++ b/dom/events/EventListenerManager.h
@@ -178,17 +178,17 @@ protected:
 class EventListenerManager final : public EventListenerManagerBase
 {
   ~EventListenerManager();
 
 public:
   struct Listener
   {
     EventListenerHolder mListener;
-    nsCOMPtr<nsIAtom> mTypeAtom; // for the main thread
+    RefPtr<nsIAtom> mTypeAtom; // for the main thread
     nsString mTypeString; // for non-main-threads
     EventMessage mEventMessage;
 
     enum ListenerType : uint8_t
     {
       eNoListener,
       eNativeListener,
       eJSEventListener,
@@ -626,17 +626,17 @@ protected:
   // members, please add them to EventListemerManagerBase and check the size
   // at build time.
 
   already_AddRefed<nsIScriptGlobalObject>
   GetScriptGlobalAndDocument(nsIDocument** aDoc);
 
   nsAutoTObserverArray<Listener, 2> mListeners;
   dom::EventTarget* MOZ_NON_OWNING_REF mTarget;
-  nsCOMPtr<nsIAtom> mNoListenerForEventAtom;
+  RefPtr<nsIAtom> mNoListenerForEventAtom;
 
   friend class ELMCreationDetector;
   static uint32_t sMainThreadCreatedCount;
 };
 
 } // namespace mozilla
 
 /**
--- a/dom/events/EventListenerService.cpp
+++ b/dom/events/EventListenerService.cpp
@@ -32,46 +32,41 @@ NS_IMPL_ISUPPORTS(EventListenerChange, n
 
 EventListenerChange::~EventListenerChange()
 {
 }
 
 EventListenerChange::EventListenerChange(dom::EventTarget* aTarget) :
   mTarget(aTarget)
 {
-  mChangedListenerNames = nsArrayBase::Create();
 }
 
 void
 EventListenerChange::AddChangedListenerName(nsIAtom* aEventName)
 {
-  mChangedListenerNames->AppendElement(aEventName, false);
+  mChangedListenerNames.AppendElement(aEventName);
 }
 
 NS_IMETHODIMP
 EventListenerChange::GetTarget(nsIDOMEventTarget** aTarget)
 {
   NS_ENSURE_ARG_POINTER(aTarget);
   NS_ADDREF(*aTarget = mTarget);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 EventListenerChange::GetCountOfEventListenerChangesAffectingAccessibility(
   uint32_t* aCount)
 {
   *aCount = 0;
 
-  uint32_t length;
-  nsresult rv = mChangedListenerNames->GetLength(&length);
-  NS_ENSURE_SUCCESS(rv, rv);
-
+  size_t length = mChangedListenerNames.Length();
   for (size_t i = 0; i < length; i++) {
-    nsCOMPtr<nsIAtom> listenerName =
-      do_QueryElementAt(mChangedListenerNames, i);
+    RefPtr<nsIAtom> listenerName = mChangedListenerNames[i];
 
     // These are the event listener changes which may make an element
     // accessible or inaccessible.
     if (listenerName == nsGkAtoms::onclick ||
         listenerName == nsGkAtoms::onmousedown ||
         listenerName == nsGkAtoms::onmouseup) {
       *aCount += 1;
     }
--- a/dom/events/EventListenerService.h
+++ b/dom/events/EventListenerService.h
@@ -36,18 +36,17 @@ public:
   void AddChangedListenerName(nsIAtom* aEventName);
 
   NS_DECL_ISUPPORTS
   NS_DECL_NSIEVENTLISTENERCHANGE
 
 protected:
   virtual ~EventListenerChange();
   nsCOMPtr<dom::EventTarget> mTarget;
-  nsCOMPtr<nsIMutableArray> mChangedListenerNames;
-
+  nsTArray<RefPtr<nsIAtom>> mChangedListenerNames;
 };
 
 class EventListenerInfo final : public nsIEventListenerInfo
 {
 public:
   EventListenerInfo(const nsAString& aType,
                     already_AddRefed<nsIDOMEventListener> aListener,
                     bool aCapturing,
--- a/dom/events/EventTarget.cpp
+++ b/dom/events/EventTarget.cpp
@@ -36,17 +36,17 @@ EventTarget::SetEventHandler(const nsASt
                              EventHandlerNonNull* aHandler,
                              ErrorResult& aRv)
 {
   if (!StringBeginsWith(aType, NS_LITERAL_STRING("on"))) {
     aRv.Throw(NS_ERROR_INVALID_ARG);
     return;
   }
   if (NS_IsMainThread()) {
-    nsCOMPtr<nsIAtom> type = NS_Atomize(aType);
+    RefPtr<nsIAtom> type = NS_Atomize(aType);
     SetEventHandler(type, EmptyString(), aHandler);
     return;
   }
   SetEventHandler(nullptr,
                   Substring(aType, 2), // Remove "on"
                   aHandler);
 }
 
--- a/dom/events/EventTarget.h
+++ b/dom/events/EventTarget.h
@@ -55,17 +55,17 @@ public:
                                    EventListener* aCallback,
                                    const EventListenerOptionsOrBoolean& aOptions,
                                    ErrorResult& aRv);
   bool DispatchEvent(Event& aEvent, CallerType aCallerType, ErrorResult& aRv);
 
   // Note, this takes the type in onfoo form!
   EventHandlerNonNull* GetEventHandler(const nsAString& aType)
   {
-    nsCOMPtr<nsIAtom> type = NS_Atomize(aType);
+    RefPtr<nsIAtom> type = NS_Atomize(aType);
     return GetEventHandler(type, EmptyString());
   }
 
   // Note, this takes the type in onfoo form!
   void SetEventHandler(const nsAString& aType, EventHandlerNonNull* aHandler,
                        ErrorResult& rv);
 
   // Note, for an event 'foo' aType will be 'onfoo'.
--- a/dom/events/InternalMutationEvent.h
+++ b/dom/events/InternalMutationEvent.h
@@ -32,19 +32,19 @@ public:
                "Duplicate() must be overridden by sub class");
     InternalMutationEvent* result = new InternalMutationEvent(false, mMessage);
     result->AssignMutationEventData(*this, true);
     result->mFlags = mFlags;
     return result;
   }
 
   nsCOMPtr<nsIDOMNode> mRelatedNode;
-  nsCOMPtr<nsIAtom>    mAttrName;
-  nsCOMPtr<nsIAtom>    mPrevAttrValue;
-  nsCOMPtr<nsIAtom>    mNewAttrValue;
+  RefPtr<nsIAtom>    mAttrName;
+  RefPtr<nsIAtom>    mPrevAttrValue;
+  RefPtr<nsIAtom>    mNewAttrValue;
   unsigned short       mAttrChange;
 
   void AssignMutationEventData(const InternalMutationEvent& aEvent,
                                bool aCopyTargets)
   {
     AssignEventData(aEvent, aCopyTargets);
 
     mRelatedNode = aEvent.mRelatedNode;
--- a/dom/events/JSEventHandler.h
+++ b/dom/events/JSEventHandler.h
@@ -255,17 +255,17 @@ public:
   NS_DECL_CYCLE_COLLECTION_SKIPPABLE_CLASS(JSEventHandler)
 
   bool IsBlackForCC();
 
 protected:
   virtual ~JSEventHandler();
 
   nsISupports* mTarget;
-  nsCOMPtr<nsIAtom> mEventName;
+  RefPtr<nsIAtom> mEventName;
   TypedEventHandler mTypedHandler;
 };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(JSEventHandler, NS_JSEVENTHANDLER_IID)
 
 } // namespace mozilla
 
 /**
--- a/dom/html/HTMLAllCollection.cpp
+++ b/dom/html/HTMLAllCollection.cpp
@@ -107,17 +107,17 @@ DocAllResultMatch(Element* aElement, int
          val->GetAtomValue() == aAtom;
 }
 
 nsContentList*
 HTMLAllCollection::GetDocumentAllList(const nsAString& aID)
 {
   return mNamedMap.LookupForAdd(aID).OrInsert(
     [this, &aID] () {
-      nsCOMPtr<nsIAtom> id = NS_Atomize(aID);
+      RefPtr<nsIAtom> id = NS_Atomize(aID);
       return new nsContentList(mDocument, DocAllResultMatch, nullptr,
                                nullptr, true, id);
     });
 }
 
 void
 HTMLAllCollection::NamedGetter(const nsAString& aID,
                                bool& aFound,
--- a/dom/html/HTMLTableElement.cpp
+++ b/dom/html/HTMLTableElement.cpp
@@ -253,17 +253,17 @@ TableRowsCollection::Item(uint32_t aInde
   return CallQueryInterface(node, aReturn);
 }
 
 Element*
 TableRowsCollection::GetFirstNamedElement(const nsAString& aName, bool& aFound)
 {
   EnsureInitialized();
   aFound = false;
-  nsCOMPtr<nsIAtom> nameAtom = NS_Atomize(aName);
+  RefPtr<nsIAtom> nameAtom = NS_Atomize(aName);
   NS_ENSURE_TRUE(nameAtom, nullptr);
 
   for (auto& node : mRows) {
     if (node->AttrValueIs(kNameSpaceID_None, nsGkAtoms::name,
                           nameAtom, eCaseMatters) ||
         node->AttrValueIs(kNameSpaceID_None, nsGkAtoms::id,
                           nameAtom, eCaseMatters)) {
       aFound = true;
--- a/dom/html/nsDOMStringMap.cpp
+++ b/dom/html/nsDOMStringMap.cpp
@@ -95,17 +95,17 @@ nsDOMStringMap::NamedSetter(const nsAStr
   }
 
   nsresult res = nsContentUtils::CheckQName(attr, false);
   if (NS_FAILED(res)) {
     rv.Throw(res);
     return;
   }
 
-  nsCOMPtr<nsIAtom> attrAtom = NS_Atomize(attr);
+  RefPtr<nsIAtom> attrAtom = NS_Atomize(attr);
   MOZ_ASSERT(attrAtom, "Should be infallible");
 
   res = mElement->SetAttr(kNameSpaceID_None, attrAtom, aValue, true);
   if (NS_FAILED(res)) {
     rv.Throw(res);
   }
 }
 
@@ -119,17 +119,17 @@ nsDOMStringMap::NamedDeleter(const nsASt
   }
 
   nsAutoString attr;
   if (!DataPropToAttr(aProp, attr)) {
     found = false;
     return;
   }
 
-  nsCOMPtr<nsIAtom> attrAtom = NS_Atomize(attr);
+  RefPtr<nsIAtom> attrAtom = NS_Atomize(attr);
   MOZ_ASSERT(attrAtom, "Should be infallible");
 
   found = mElement->HasAttr(kNameSpaceID_None, attrAtom);
 
   if (found) {
     mRemovingProp = true;
     mElement->UnsetAttr(kNameSpaceID_None, attrAtom, true);
     mRemovingProp = false;
--- a/dom/html/nsGenericHTMLElement.cpp
+++ b/dom/html/nsGenericHTMLElement.cpp
@@ -2195,17 +2195,17 @@ nsGenericHTMLFormElement::AddFormIdObser
   NS_ASSERTION(GetUncomposedDoc(), "When adding a form id observer, "
                                    "we should be in a document!");
 
   nsAutoString formId;
   nsIDocument* doc = OwnerDoc();
   GetAttr(kNameSpaceID_None, nsGkAtoms::form, formId);
   NS_ASSERTION(!formId.IsEmpty(),
                "@form value should not be the empty string!");
-  nsCOMPtr<nsIAtom> atom = NS_Atomize(formId);
+  RefPtr<nsIAtom> atom = NS_Atomize(formId);
 
   return doc->AddIDTargetObserver(atom, FormIdUpdated, this, false);
 }
 
 void
 nsGenericHTMLFormElement::RemoveFormIdObserver()
 {
   /**
@@ -2224,17 +2224,17 @@ nsGenericHTMLFormElement::RemoveFormIdOb
   if (!doc) {
     return;
   }
 
   nsAutoString formId;
   GetAttr(kNameSpaceID_None, nsGkAtoms::form, formId);
   NS_ASSERTION(!formId.IsEmpty(),
                "@form value should not be the empty string!");
-  nsCOMPtr<nsIAtom> atom = NS_Atomize(formId);
+  RefPtr<nsIAtom> atom = NS_Atomize(formId);
 
   doc->RemoveIDTargetObserver(atom, FormIdUpdated, this, false);
 }
 
 
 /* static */
 bool
 nsGenericHTMLFormElement::FormIdUpdated(Element* aOldElement,
--- a/dom/html/nsHTMLContentSink.cpp
+++ b/dom/html/nsHTMLContentSink.cpp
@@ -296,18 +296,18 @@ NS_NewHTMLElement(Element** aResult, alr
     JSContext* cx = aes.cx();
     ErrorResult rv;
 
     // Step 5.
     if (definition->IsCustomBuiltIn()) {
       // SetupCustomElement() should be called with an element that don't have
       // CustomElementData setup, if not we will hit the assertion in
       // SetCustomElementData().
-      nsCOMPtr<nsIAtom> tagAtom = nodeInfo->NameAtom();
-      nsCOMPtr<nsIAtom> typeAtom = aIs ? NS_Atomize(*aIs) : tagAtom;
+      RefPtr<nsIAtom> tagAtom = nodeInfo->NameAtom();
+      RefPtr<nsIAtom> typeAtom = aIs ? NS_Atomize(*aIs) : tagAtom;
       // Built-in element
       *aResult = CreateHTMLElement(tag, nodeInfo.forget(), aFromParser).take();
       (*aResult)->SetCustomElementData(new CustomElementData(typeAtom));
       if (synchronousCustomElements) {
         CustomElementRegistry::Upgrade(*aResult, definition, rv);
       } else {
         nsContentUtils::EnqueueUpgradeReaction(*aResult, definition);
       }
--- a/dom/smil/nsSMILAnimationController.cpp
+++ b/dom/smil/nsSMILAnimationController.cpp
@@ -671,17 +671,17 @@ nsSMILAnimationController::GetTargetIden
   Element* targetElem = aAnimElem->GetTargetElementContent();
   if (!targetElem)
     // Animation has no target elem -- skip it.
     return false;
 
   // Look up target (animated) attribute
   // SMILANIM section 3.1, attributeName may
   // have an XMLNS prefix to indicate the XML namespace.
-  nsCOMPtr<nsIAtom> attributeName;
+  RefPtr<nsIAtom> attributeName;
   int32_t attributeNamespaceID;
   if (!aAnimElem->GetTargetAttributeName(&attributeNamespaceID,
                                          getter_AddRefs(attributeName)))
     // Animation has no target attr -- skip it.
     return false;
 
   // animateTransform can only animate transforms, conversely transforms
   // can only be animated by animateTransform
--- a/dom/svg/nsSVGElement.cpp
+++ b/dom/svg/nsSVGElement.cpp
@@ -545,17 +545,17 @@ nsSVGElement::ParseAttribute(int32_t aNa
       }
     }
 
     if (!foundMatch) {
       // Check for nsSVGEnum attribute
       EnumAttributesInfo enumInfo = GetEnumInfo();
       for (i = 0; i < enumInfo.mEnumCount; i++) {
         if (aAttribute == *enumInfo.mEnumInfo[i].mName) {
-          nsCOMPtr<nsIAtom> valAtom = NS_Atomize(aValue);
+          RefPtr<nsIAtom> valAtom = NS_Atomize(aValue);
           rv = enumInfo.mEnums[i].SetBaseValueAtom(valAtom, this);
           if (NS_FAILED(rv)) {
             enumInfo.Reset(i);
           } else {
             aResult.SetTo(valAtom);
             didSetResult = true;
           }
           foundMatch = true;
@@ -1285,17 +1285,17 @@ MappedAttrParser::ParseMappedAttrValue(n
     if (mBackend == StyleBackendType::Gecko) {
       nsCSSExpandedDataBlock block;
       mDecl->AsGecko()->ExpandTo(&block);
       nsCSSValue cssValue(PromiseFlatString(aMappedAttrValue), eCSSUnit_Ident);
       block.AddLonghandProperty(propertyID, cssValue);
       mDecl->AsGecko()->ValueAppended(propertyID);
       mDecl->AsGecko()->CompressFrom(&block);
     } else {
-      nsCOMPtr<nsIAtom> atom = NS_Atomize(aMappedAttrValue);
+      RefPtr<nsIAtom> atom = NS_Atomize(aMappedAttrValue);
       Servo_DeclarationBlock_SetIdentStringValue(mDecl->AsServo()->Raw(), propertyID, atom);
     }
   }
 }
 
 already_AddRefed<DeclarationBlock>
 MappedAttrParser::GetDeclarationBlock()
 {
--- a/dom/xbl/XBLChildrenElement.h
+++ b/dom/xbl/XBLChildrenElement.h
@@ -140,17 +140,17 @@ public:
 protected:
   ~XBLChildrenElement();
   virtual nsresult BeforeSetAttr(int32_t aNamespaceID, nsIAtom* aName,
                                  const nsAttrValueOrString* aValue,
                                  bool aNotify) override;
 
 private:
   nsTArray<nsIContent*> mInsertedChildren; // WEAK
-  nsTArray<nsCOMPtr<nsIAtom> > mIncludes;
+  nsTArray<RefPtr<nsIAtom> > mIncludes;
 };
 
 } // namespace dom
 } // namespace mozilla
 
 class nsAnonymousContentList : public nsINodeList
 {
 public:
--- a/dom/xbl/nsXBLBinding.cpp
+++ b/dom/xbl/nsXBLBinding.cpp
@@ -400,17 +400,17 @@ nsXBLBinding::GenerateAnonymousContent()
   // Always check the content element for potential attributes.
   // This shorthand hack always happens, even when we didn't
   // build anonymous content.
   BorrowedAttrInfo attrInfo;
   for (uint32_t i = 0; (attrInfo = content->GetAttrInfoAt(i)); ++i) {
     int32_t namespaceID = attrInfo.mName->NamespaceID();
     // Hold a strong reference here so that the atom doesn't go away during
     // UnsetAttr.
-    nsCOMPtr<nsIAtom> name = attrInfo.mName->LocalName();
+    RefPtr<nsIAtom> name = attrInfo.mName->LocalName();
 
     if (name != nsGkAtoms::includes) {
       if (!nsContentUtils::HasNonEmptyAttr(mBoundElement, namespaceID, name)) {
         nsAutoString value2;
         attrInfo.mValue->ToString(value2);
         mBoundElement->SetAttr(namespaceID, name, attrInfo.mName->GetPrefix(),
                                value2, false);
       }
@@ -500,17 +500,17 @@ nsXBLBinding::InstallEventHandlers()
         return;
 
       bool isChromeDoc =
         nsContentUtils::IsChromeDoc(mBoundElement->OwnerDoc());
       bool isChromeBinding = mPrototypeBinding->IsChrome();
       nsXBLPrototypeHandler* curr;
       for (curr = handlerChain; curr; curr = curr->GetNextHandler()) {
         // Fetch the event type.
-        nsCOMPtr<nsIAtom> eventAtom = curr->GetEventName();
+        RefPtr<nsIAtom> eventAtom = curr->GetEventName();
         if (!eventAtom ||
             eventAtom == nsGkAtoms::keyup ||
             eventAtom == nsGkAtoms::keydown ||
             eventAtom == nsGkAtoms::keypress)
           continue;
 
         nsXBLEventHandler* handler = curr->GetEventHandler();
         if (handler) {
@@ -652,17 +652,17 @@ nsXBLBinding::UnhookEventHandlers()
     bool isChromeBinding = mPrototypeBinding->IsChrome();
     nsXBLPrototypeHandler* curr;
     for (curr = handlerChain; curr; curr = curr->GetNextHandler()) {
       nsXBLEventHandler* handler = curr->GetCachedEventHandler();
       if (!handler) {
         continue;
       }
 
-      nsCOMPtr<nsIAtom> eventAtom = curr->GetEventName();
+      RefPtr<nsIAtom> eventAtom = curr->GetEventName();
       if (!eventAtom ||
           eventAtom == nsGkAtoms::keyup ||
           eventAtom == nsGkAtoms::keydown ||
           eventAtom == nsGkAtoms::keypress)
         continue;
 
       // Figure out if we're using capturing or not.
       EventListenerFlags flags;
--- a/dom/xbl/nsXBLContentSink.cpp
+++ b/dom/xbl/nsXBLContentSink.cpp
@@ -269,17 +269,17 @@ nsXBLContentSink::HandleStartElement(con
 
 NS_IMETHODIMP
 nsXBLContentSink::HandleEndElement(const char16_t *aName)
 {
   FlushText();
 
   if (mState != eXBL_InDocument) {
     int32_t nameSpaceID;
-    nsCOMPtr<nsIAtom> prefix, localName;
+    RefPtr<nsIAtom> prefix, localName;
     nsContentUtils::SplitExpatName(aName, getter_AddRefs(prefix),
                                    getter_AddRefs(localName), &nameSpaceID);
 
     if (nameSpaceID == kNameSpaceID_XBL) {
       if (mState == eXBL_Error) {
         // Check whether we've opened this tag before; we may not have if
         // it was a real XBL tag before the error occurred.
         if (!GetCurrentContent()->NodeInfo()->Equals(localName,
@@ -569,17 +569,17 @@ nsXBLContentSink::ConstructBinding(uint3
   }
 
   return rv;
 }
 
 static bool
 FindValue(const char16_t **aAtts, nsIAtom *aAtom, const char16_t **aResult)
 {
-  nsCOMPtr<nsIAtom> prefix, localName;
+  RefPtr<nsIAtom> prefix, localName;
   for (; *aAtts; aAtts += 2) {
     int32_t nameSpaceID;
     nsContentUtils::SplitExpatName(aAtts[0], getter_AddRefs(prefix),
                                    getter_AddRefs(localName), &nameSpaceID);
 
     // Is this attribute one of the ones we care about?
     if (nameSpaceID == kNameSpaceID_None && localName == aAtom) {
       *aResult = aAtts[1];
@@ -602,17 +602,17 @@ nsXBLContentSink::ConstructHandler(const
   const char16_t* charcode       = nullptr;
   const char16_t* phase          = nullptr;
   const char16_t* command        = nullptr;
   const char16_t* action         = nullptr;
   const char16_t* group          = nullptr;
   const char16_t* preventdefault = nullptr;
   const char16_t* allowuntrusted = nullptr;
 
-  nsCOMPtr<nsIAtom> prefix, localName;
+  RefPtr<nsIAtom> prefix, localName;
   for (; *aAtts; aAtts += 2) {
     int32_t nameSpaceID;
     nsContentUtils::SplitExpatName(aAtts[0], getter_AddRefs(prefix),
                                    getter_AddRefs(localName), &nameSpaceID);
 
     if (nameSpaceID != kNameSpaceID_None) {
       continue;
     }
@@ -700,17 +700,17 @@ nsXBLContentSink::ConstructImplementatio
   mImplMember = nullptr;
   mImplField = nullptr;
 
   if (!mBinding)
     return;
 
   const char16_t* name = nullptr;
 
-  nsCOMPtr<nsIAtom> prefix, localName;
+  RefPtr<nsIAtom> prefix, localName;
   for (; *aAtts; aAtts += 2) {
     int32_t nameSpaceID;
     nsContentUtils::SplitExpatName(aAtts[0], getter_AddRefs(prefix),
                                    getter_AddRefs(localName), &nameSpaceID);
 
     if (nameSpaceID != kNameSpaceID_None) {
       continue;
     }
@@ -732,17 +732,17 @@ nsXBLContentSink::ConstructImplementatio
 }
 
 void
 nsXBLContentSink::ConstructField(const char16_t **aAtts, uint32_t aLineNumber)
 {
   const char16_t* name     = nullptr;
   const char16_t* readonly = nullptr;
 
-  nsCOMPtr<nsIAtom> prefix, localName;
+  RefPtr<nsIAtom> prefix, localName;
   for (; *aAtts; aAtts += 2) {
     int32_t nameSpaceID;
     nsContentUtils::SplitExpatName(aAtts[0], getter_AddRefs(prefix),
                                    getter_AddRefs(localName), &nameSpaceID);
 
     if (nameSpaceID != kNameSpaceID_None) {
       continue;
     }
@@ -769,17 +769,17 @@ void
 nsXBLContentSink::ConstructProperty(const char16_t **aAtts, uint32_t aLineNumber)
 {
   const char16_t* name     = nullptr;
   const char16_t* readonly = nullptr;
   const char16_t* onget    = nullptr;
   const char16_t* onset    = nullptr;
   bool exposeToUntrustedContent = false;
 
-  nsCOMPtr<nsIAtom> prefix, localName;
+  RefPtr<nsIAtom> prefix, localName;
   for (; *aAtts; aAtts += 2) {
     int32_t nameSpaceID;
     nsContentUtils::SplitExpatName(aAtts[0], getter_AddRefs(prefix),
                                    getter_AddRefs(localName), &nameSpaceID);
 
     if (nameSpaceID != kNameSpaceID_None) {
       continue;
     }
@@ -903,17 +903,17 @@ nsXBLContentSink::AddAttributesToXULProt
   if (aAttsCount > 0) {
     attrs = new nsXULPrototypeAttribute[aAttsCount];
   }
 
   aElement->mAttributes    = attrs;
   aElement->mNumAttributes = aAttsCount;
 
   // Copy the attributes into the prototype
-  nsCOMPtr<nsIAtom> prefix, localName;
+  RefPtr<nsIAtom> prefix, localName;
 
   uint32_t i;
   for (i = 0; i < aAttsCount; ++i) {
     int32_t nameSpaceID;
     nsContentUtils::SplitExpatName(aAtts[i * 2], getter_AddRefs(prefix),
                                    getter_AddRefs(localName), &nameSpaceID);
 
     if (nameSpaceID == kNameSpaceID_None) {
--- a/dom/xbl/nsXBLEventHandler.h
+++ b/dom/xbl/nsXBLEventHandler.h
@@ -100,17 +100,17 @@ public:
 private:
   nsXBLKeyEventHandler();
   virtual ~nsXBLKeyEventHandler();
 
   bool ExecuteMatchedHandlers(nsIDOMKeyEvent* aEvent, uint32_t aCharCode,
                               const IgnoreModifierState& aIgnoreModifierState);
 
   nsTArray<nsXBLPrototypeHandler*> mProtoHandlers;
-  nsCOMPtr<nsIAtom> mEventType;
+  RefPtr<nsIAtom> mEventType;
   uint8_t mPhase;
   uint8_t mType;
   bool mIsBoundToChrome;
   bool mUsingContentXBLScope;
 };
 
 already_AddRefed<nsXBLEventHandler>
 NS_NewXBLEventHandler(nsXBLPrototypeHandler* aHandler,
--- a/dom/xbl/nsXBLPrototypeBinding.cpp
+++ b/dom/xbl/nsXBLPrototypeBinding.cpp
@@ -80,18 +80,18 @@ public:
   nsIContent* GetElement() { return mElement; }
 
   nsXBLAttributeEntry* GetNext() { return mNext; }
   void SetNext(nsXBLAttributeEntry* aEntry) { mNext = aEntry; }
 
 protected:
   nsIContent* mElement;
 
-  nsCOMPtr<nsIAtom> mSrcAttribute;
-  nsCOMPtr<nsIAtom> mDstAttribute;
+  RefPtr<nsIAtom> mSrcAttribute;
+  RefPtr<nsIAtom> mDstAttribute;
   int32_t mDstNameSpace;
   nsXBLAttributeEntry* mNext;
 };
 
 // =============================================================================
 
 // Implementation /////////////////////////////////////////////////////////////////
 
@@ -345,17 +345,17 @@ nsXBLPrototypeBinding::AttributeChanged(
 
     nsCOMPtr<nsIContent> realElement = LocateInstance(aChangedElement, content,
                                                       aAnonymousContent,
                                                       element);
 
     if (realElement) {
       // Hold a strong reference here so that the atom doesn't go away during
       // UnsetAttr.
-      nsCOMPtr<nsIAtom> dstAttr = xblAttr->GetDstAttribute();
+      RefPtr<nsIAtom> dstAttr = xblAttr->GetDstAttribute();
       int32_t dstNs = xblAttr->GetDstNameSpace();
 
       if (aRemoveFlag)
         realElement->UnsetAttr(dstNs, dstAttr, aNotify);
       else {
         bool attrPresent = true;
         nsAutoString value;
         // Check to see if the src attribute is xbl:text.  If so, then we need to obtain the
@@ -632,19 +632,19 @@ nsXBLPrototypeBinding::ConstructAttribut
       char* str = ToNewCString(inherits);
       char* newStr;
       // XXX We should use a strtok function that tokenizes PRUnichars
       // so that we don't have to convert from Unicode to ASCII and then back
 
       char* token = nsCRT::strtok( str, ", ", &newStr );
       while( token != nullptr ) {
         // Build an atom out of this attribute.
-        nsCOMPtr<nsIAtom> atom;
+        RefPtr<nsIAtom> atom;
         int32_t atomNsID = kNameSpaceID_None;
-        nsCOMPtr<nsIAtom> attribute;
+        RefPtr<nsIAtom> attribute;
         int32_t attributeNsID = kNameSpaceID_None;
 
         // Figure out if this token contains a :.
         NS_ConvertASCIItoUTF16 attrTok(token);
         int32_t index = attrTok.Find("=", true);
         nsresult rv;
         if (index != -1) {
           // This attribute maps to something different.
@@ -768,17 +768,17 @@ nsXBLPrototypeBinding::AddResourceListen
   return NS_OK;
 }
 
 void
 nsXBLPrototypeBinding::CreateKeyHandlers()
 {
   nsXBLPrototypeHandler* curr = mPrototypeHandler;
   while (curr) {
-    nsCOMPtr<nsIAtom> eventAtom = curr->GetEventName();
+    RefPtr<nsIAtom> eventAtom = curr->GetEventName();
     if (eventAtom == nsGkAtoms::keyup ||
         eventAtom == nsGkAtoms::keydown ||
         eventAtom == nsGkAtoms::keypress) {
       uint8_t phase = curr->GetPhase();
       uint8_t type = curr->GetType();
 
       int32_t count = mKeyHandlers.Count();
       int32_t i;
@@ -975,18 +975,18 @@ nsXBLPrototypeBinding::Read(nsIObjectInp
       NS_ENSURE_SUCCESS(rv, rv);
 
       rv = aStream->ReadString(attrName);
       NS_ENSURE_SUCCESS(rv, rv);
 
       rv = aStream->ReadString(attrValue);
       NS_ENSURE_SUCCESS(rv, rv);
 
-      nsCOMPtr<nsIAtom> atomPrefix = NS_Atomize(attrPrefix);
-      nsCOMPtr<nsIAtom> atomName = NS_Atomize(attrName);
+      RefPtr<nsIAtom> atomPrefix = NS_Atomize(attrPrefix);
+      RefPtr<nsIAtom> atomName = NS_Atomize(attrName);
       mBinding->SetAttr(attrNamespace, atomName, atomPrefix, attrValue, false);
     }
   }
 
   // Finally, read in the resources.
   while (true) {
     XBLBindingSerializeDetails type;
     rv = aStream->Read8(&type);
@@ -1224,24 +1224,24 @@ nsXBLPrototypeBinding::ReadContentNode(n
     return NS_OK;
   }
 
   // Otherwise, it's an element, so read its tag, attributes and children.
   nsAutoString prefix, tag;
   rv = aStream->ReadString(prefix);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  nsCOMPtr<nsIAtom> prefixAtom;
+  RefPtr<nsIAtom> prefixAtom;
   if (!prefix.IsEmpty())
     prefixAtom = NS_Atomize(prefix);
 
   rv = aStream->ReadString(tag);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  nsCOMPtr<nsIAtom> tagAtom = NS_Atomize(tag);
+  RefPtr<nsIAtom> tagAtom = NS_Atomize(tag);
   RefPtr<NodeInfo> nodeInfo =
     aNim->GetNodeInfo(tagAtom, prefixAtom, namespaceID, nsIDOMNode::ELEMENT_NODE);
 
   uint32_t attrCount;
   rv = aStream->Read32(&attrCount);
   NS_ENSURE_SUCCESS(rv, rv);
 
   // Create XUL prototype elements, or regular elements for other namespaces.
@@ -1269,22 +1269,22 @@ nsXBLPrototypeBinding::ReadContentNode(n
       nsAutoString prefix, name, val;
       rv = aStream->ReadString(prefix);
       NS_ENSURE_SUCCESS(rv, rv);
       rv = aStream->ReadString(name);
       NS_ENSURE_SUCCESS(rv, rv);
       rv = aStream->ReadString(val);
       NS_ENSURE_SUCCESS(rv, rv);
 
-      nsCOMPtr<nsIAtom> nameAtom = NS_Atomize(name);
+      RefPtr<nsIAtom> nameAtom = NS_Atomize(name);
       if (namespaceID == kNameSpaceID_None) {
         attrs[i].mName.SetTo(nameAtom);
       }
       else {
-        nsCOMPtr<nsIAtom> prefixAtom;
+        RefPtr<nsIAtom> prefixAtom;
         if (!prefix.IsEmpty())
           prefixAtom = NS_Atomize(prefix);
 
         RefPtr<NodeInfo> ni =
           aNim->GetNodeInfo(nameAtom, prefixAtom,
                             namespaceID, nsIDOMNode::ATTRIBUTE_NODE);
         attrs[i].mName.SetTo(ni);
       }
@@ -1312,21 +1312,21 @@ nsXBLPrototypeBinding::ReadContentNode(n
       nsAutoString prefix, name, val;
       rv = aStream->ReadString(prefix);
       NS_ENSURE_SUCCESS(rv, rv);
       rv = aStream->ReadString(name);
       NS_ENSURE_SUCCESS(rv, rv);
       rv = aStream->ReadString(val);
       NS_ENSURE_SUCCESS(rv, rv);
 
-      nsCOMPtr<nsIAtom> prefixAtom;
+      RefPtr<nsIAtom> prefixAtom;
       if (!prefix.IsEmpty())
         prefixAtom = NS_Atomize(prefix);
 
-      nsCOMPtr<nsIAtom> nameAtom = NS_Atomize(name);
+      RefPtr<nsIAtom> nameAtom = NS_Atomize(name);
       content->SetAttr(namespaceID, nameAtom, prefixAtom, val, false);
     }
 
 #ifdef MOZ_XUL
   }
 #endif
 
   // Now read the attribute forwarding entries (xbl:inherits)
@@ -1339,18 +1339,18 @@ nsXBLPrototypeBinding::ReadContentNode(n
     nsAutoString srcAttribute, destAttribute;
     rv = aStream->ReadString(srcAttribute);
     NS_ENSURE_SUCCESS(rv, rv);
     rv = ReadNamespace(aStream, destNamespaceID);
     NS_ENSURE_SUCCESS(rv, rv);
     rv = aStream->ReadString(destAttribute);
     NS_ENSURE_SUCCESS(rv, rv);
 
-    nsCOMPtr<nsIAtom> srcAtom = NS_Atomize(srcAttribute);
-    nsCOMPtr<nsIAtom> destAtom = NS_Atomize(destAttribute);
+    RefPtr<nsIAtom> srcAtom = NS_Atomize(srcAttribute);
+    RefPtr<nsIAtom> destAtom = NS_Atomize(destAttribute);
 
     EnsureAttributeTable();
     AddToAttributeTable(srcNamespaceID, srcAtom, destNamespaceID, destAtom, content);
 
     rv = ReadNamespace(aStream, srcNamespaceID);
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
@@ -1610,17 +1610,17 @@ nsXBLPrototypeBinding::ResolveBaseBindin
 
   if (!prefix.IsEmpty()) {
     mBinding->LookupNamespaceURI(prefix, nameSpace);
     if (!nameSpace.IsEmpty()) {
       int32_t nameSpaceID =
         nsContentUtils::NameSpaceManager()->GetNameSpaceID(nameSpace,
                                                            nsContentUtils::IsChromeDoc(doc));
 
-      nsCOMPtr<nsIAtom> tagName = NS_Atomize(display);
+      RefPtr<nsIAtom> tagName = NS_Atomize(display);
       // Check the white list
       if (!CheckTagNameWhiteList(nameSpaceID, tagName)) {
         const char16_t* params[] = { display.get() };
         nsContentUtils::ReportToConsole(nsIScriptError::errorFlag,
                                         NS_LITERAL_CSTRING("XBL"), nullptr,
                                         nsContentUtils::eXBL_PROPERTIES,
                                        "InvalidExtendsBinding",
                                         params, ArrayLength(params),
--- a/dom/xbl/nsXBLPrototypeBinding.h
+++ b/dom/xbl/nsXBLPrototypeBinding.h
@@ -263,17 +263,17 @@ public:
   nsIContent* LocateInstance(nsIContent* aBoundElt,
                              nsIContent* aTemplRoot,
                              nsIContent* aCopyRoot,
                              nsIContent* aTemplChild);
 
   bool ChromeOnlyContent() { return mChromeOnlyContent; }
   bool BindToUntrustedContent() { return mBindToUntrustedContent; }
 
-  typedef nsClassHashtable<nsISupportsHashKey, nsXBLAttributeEntry> InnerAttributeTable;
+  typedef nsClassHashtable<nsRefPtrHashKey<nsIAtom>, nsXBLAttributeEntry> InnerAttributeTable;
 
 protected:
   // Ensure that mAttributeTable has been created.
   void EnsureAttributeTable();
   // Ad an entry to the attribute table
   void AddToAttributeTable(int32_t aSourceNamespaceID, nsIAtom* aSourceTag,
                            int32_t aDestNamespaceID, nsIAtom* aDestTag,
                            nsIContent* aContent);
@@ -350,14 +350,14 @@ protected:
     enum { ALLOW_MEMMOVE = true };
 
   private:
     nsIID mKey;
   };
   nsInterfaceHashtable<IIDHashKey, nsIContent> mInterfaceTable; // A table of cached interfaces that we support.
 
   int32_t mBaseNameSpaceID;    // If we extend a tagname/namespace, then that information will
-  nsCOMPtr<nsIAtom> mBaseTag;  // be stored in here.
+  RefPtr<nsIAtom> mBaseTag;  // be stored in here.
 
   nsCOMArray<nsXBLKeyEventHandler> mKeyHandlers;
 };
 
 #endif
--- a/dom/xbl/nsXBLPrototypeHandler.cpp
+++ b/dom/xbl/nsXBLPrototypeHandler.cpp
@@ -289,17 +289,17 @@ nsXBLPrototypeHandler::ExecuteHandler(Ev
   // event at the element.  It will take care of retargeting it to its
   // command element, if applicable, and executing the event handler.
   if (isXULKey) {
     return DispatchXULKeyCommand(aEvent);
   }
 
   // Look for a compiled handler on the element.
   // Should be compiled and bound with "on" in front of the name.
-  nsCOMPtr<nsIAtom> onEventAtom = NS_Atomize(NS_LITERAL_STRING("onxbl") +
+  RefPtr<nsIAtom> onEventAtom = NS_Atomize(NS_LITERAL_STRING("onxbl") +
                                              nsDependentAtomString(mEventName));
 
   // Compile the handler and bind it to the element.
   nsCOMPtr<nsIScriptGlobalObject> boundGlobal;
   nsCOMPtr<nsPIWindowRoot> winRoot = do_QueryInterface(aTarget);
   if (winRoot) {
     if (nsCOMPtr<nsPIDOMWindowOuter> window = winRoot->GetWindow()) {
       nsPIDOMWindowInner* innerWindow = window->GetCurrentInnerWindow();
@@ -656,17 +656,17 @@ nsXBLPrototypeHandler::GetModifiersMask(
   }
 
   return modifiersMask;
 }
 
 already_AddRefed<nsIAtom>
 nsXBLPrototypeHandler::GetEventName()
 {
-  nsCOMPtr<nsIAtom> eventName = mEventName;
+  RefPtr<nsIAtom> eventName = mEventName;
   return eventName.forget();
 }
 
 already_AddRefed<nsIController>
 nsXBLPrototypeHandler::GetController(EventTarget* aTarget)
 {
   // XXX Fix this so there's a generic interface that describes controllers,
   // This code should have no special knowledge of what objects might have controllers.
--- a/dom/xbl/nsXBLPrototypeHandler.h
+++ b/dom/xbl/nsXBLPrototypeHandler.h
@@ -239,14 +239,14 @@ protected:
                              // in order to be matched.
 
   // The primary filter information for mouse/key events.
   int32_t mDetail;           // For key events, contains a charcode or keycode. For
                              // mouse events, stores the button info.
 
   // Prototype handlers are chained. We own the next handler in the chain.
   nsXBLPrototypeHandler* mNextHandler;
-  nsCOMPtr<nsIAtom> mEventName; // The type of the event, e.g., "keypress"
+  RefPtr<nsIAtom> mEventName; // The type of the event, e.g., "keypress"
   RefPtr<nsXBLEventHandler> mHandler;
   nsXBLPrototypeBinding* mPrototypeBinding; // the binding owns us
 };
 
 #endif
--- a/dom/xbl/nsXBLWindowKeyHandler.cpp
+++ b/dom/xbl/nsXBLWindowKeyHandler.cpp
@@ -505,17 +505,17 @@ nsXBLWindowKeyHandler::HandleEvent(nsIDO
 
   // If this event was handled by APZ then don't do the default action, and
   // preventDefault to prevent any other listeners from handling the event.
   if (widgetKeyboardEvent->mFlags.mHandledByAPZ) {
     aEvent->PreventDefault();
     return NS_OK;
   }
 
-  nsCOMPtr<nsIAtom> eventTypeAtom =
+  RefPtr<nsIAtom> eventTypeAtom =
     ConvertEventToDOMEventType(*widgetKeyboardEvent);
   return WalkHandlers(keyEvent, eventTypeAtom);
 }
 
 void
 nsXBLWindowKeyHandler::HandleEventOnCaptureInDefaultEventGroup(
                          nsIDOMKeyEvent* aEvent)
 {
@@ -805,17 +805,17 @@ nsXBLWindowKeyHandler::HasHandlerForEven
   NS_ENSURE_SUCCESS(rv, false);
 
   bool isDisabled;
   nsCOMPtr<Element> el = GetElement(&isDisabled);
   if (el && isDisabled) {
     return false;
   }
 
-  nsCOMPtr<nsIAtom> eventTypeAtom =
+  RefPtr<nsIAtom> eventTypeAtom =
     ConvertEventToDOMEventType(*widgetKeyboardEvent);
   return WalkHandlersInternal(aEvent, eventTypeAtom, mHandler, false,
                               aOutReservedForChrome);
 }
 
 already_AddRefed<Element>
 nsXBLWindowKeyHandler::GetElement(bool* aIsDisabled)
 {
--- a/dom/xml/ProcessingInstruction.cpp
+++ b/dom/xml/ProcessingInstruction.cpp
@@ -17,17 +17,17 @@ NS_NewXMLProcessingInstruction(nsNodeInf
                                const nsAString& aTarget,
                                const nsAString& aData)
 {
   using mozilla::dom::ProcessingInstruction;
   using mozilla::dom::XMLStylesheetProcessingInstruction;
 
   NS_PRECONDITION(aNodeInfoManager, "Missing nodeinfo manager");
 
-  nsCOMPtr<nsIAtom> target = NS_Atomize(aTarget);
+  RefPtr<nsIAtom> target = NS_Atomize(aTarget);
   MOZ_ASSERT(target);
 
   if (target == nsGkAtoms::xml_stylesheet) {
     RefPtr<XMLStylesheetProcessingInstruction> pi =
       new XMLStylesheetProcessingInstruction(aNodeInfoManager, aData);
     return pi.forget();
   }
 
--- a/dom/xml/nsXMLContentSink.cpp
+++ b/dom/xml/nsXMLContentSink.cpp
@@ -940,17 +940,17 @@ nsXMLContentSink::HandleStartElement(con
   MOZ_ASSERT(eXMLContentSinkState_InEpilog != mState);
 
   FlushText();
   DidAddContent();
 
   mState = eXMLContentSinkState_InDocumentElement;
 
   int32_t nameSpaceID;
-  nsCOMPtr<nsIAtom> prefix, localName;
+  RefPtr<nsIAtom> prefix, localName;
   nsContentUtils::SplitExpatName(aName, getter_AddRefs(prefix),
                                  getter_AddRefs(localName), &nameSpaceID);
 
   if (!OnOpenContainer(aAtts, aAttsCount, nameSpaceID, localName, aLineNumber)) {
     return NS_OK;
   }
 
   RefPtr<mozilla::dom::NodeInfo> nodeInfo;
@@ -1046,17 +1046,17 @@ nsXMLContentSink::HandleEndElement(const
   nsCOMPtr<nsIContent> content;
   sn->mContent.swap(content);
   uint32_t numFlushed = sn->mNumFlushed;
 
   PopContent();
   NS_ASSERTION(content, "failed to pop content");
 #ifdef DEBUG
   // Check that we're closing the right thing
-  nsCOMPtr<nsIAtom> debugNameSpacePrefix, debugTagAtom;
+  RefPtr<nsIAtom> debugNameSpacePrefix, debugTagAtom;
   int32_t debugNameSpaceID;
   nsContentUtils::SplitExpatName(aName, getter_AddRefs(debugNameSpacePrefix),
                                  getter_AddRefs(debugTagAtom),
                                  &debugNameSpaceID);
   // Check if we are closing a template element because template
   // elements do not get pushed on the stack, the template
   // element content is pushed instead.
   bool isTemplateElement = debugTagAtom == nsGkAtoms::_template &&
@@ -1149,17 +1149,17 @@ nsXMLContentSink::HandleDoctypeDecl(cons
                                     nsISupports* aCatalogData)
 {
   FlushText();
 
   nsresult rv = NS_OK;
 
   NS_ASSERTION(mDocument, "Shouldn't get here from a document fragment");
 
-  nsCOMPtr<nsIAtom> name = NS_Atomize(aName);
+  RefPtr<nsIAtom> name = NS_Atomize(aName);
   NS_ENSURE_TRUE(name, NS_ERROR_OUT_OF_MEMORY);
 
   // Create a new doctype node
   nsCOMPtr<nsIDOMDocumentType> docType;
   rv = NS_NewDOMDocumentType(getter_AddRefs(docType), mNodeInfoManager,
                              name, aPublicId, aSystemId, aSubset);
   if (NS_FAILED(rv) || !docType) {
     return rv;
@@ -1398,17 +1398,17 @@ nsXMLContentSink::ReportError(const char
   return NS_OK;
 }
 
 nsresult
 nsXMLContentSink::AddAttributes(const char16_t** aAtts,
                                 nsIContent* aContent)
 {
   // Add tag attributes to the content attributes
-  nsCOMPtr<nsIAtom> prefix, localName;
+  RefPtr<nsIAtom> prefix, localName;
   while (*aAtts) {
     int32_t nameSpaceID;
     nsContentUtils::SplitExpatName(aAtts[0], getter_AddRefs(prefix),
                                    getter_AddRefs(localName), &nameSpaceID);
 
     // Add attribute to content
     aContent->SetAttr(nameSpaceID, localName, prefix,
                       nsDependentString(aAtts[1]), false);
--- a/dom/xslt/base/txExpandedName.cpp
+++ b/dom/xslt/base/txExpandedName.cpp
@@ -17,17 +17,17 @@ txExpandedName::init(const nsAString& aQ
     const nsString& qName = PromiseFlatString(aQName);
     const char16_t* colon;
     bool valid = XMLUtils::isValidQName(qName, &colon);
     if (!valid) {
         return NS_ERROR_FAILURE;
     }
 
     if (colon) {
-        nsCOMPtr<nsIAtom> prefix = NS_Atomize(Substring(qName.get(), colon));
+        RefPtr<nsIAtom> prefix = NS_Atomize(Substring(qName.get(), colon));
         int32_t namespaceID = aResolver->lookupNamespace(prefix);
         if (namespaceID == kNameSpaceID_Unknown)
             return NS_ERROR_FAILURE;
         mNamespaceID = namespaceID;
 
         const char16_t *end;
         qName.EndReading(end);
         mLocalName = NS_Atomize(Substring(colon + 1, end));
--- a/dom/xslt/base/txExpandedName.h
+++ b/dom/xslt/base/txExpandedName.h
@@ -59,12 +59,12 @@ public:
 
     bool operator != (const txExpandedName& rhs) const
     {
         return ((mLocalName != rhs.mLocalName) ||
                 (mNamespaceID != rhs.mNamespaceID));
     }
 
     int32_t mNamespaceID;
-    nsCOMPtr<nsIAtom> mLocalName;
+    RefPtr<nsIAtom> mLocalName;
 };
 
 #endif
--- a/dom/xslt/base/txExpandedNameMap.h
+++ b/dom/xslt/base/txExpandedNameMap.h
@@ -89,17 +89,17 @@ protected:
         uint32_t mCurrentPos;
     };
 
     friend class iterator_base;
 
     friend class txMapItemComparator;
     struct MapItem {
         int32_t mNamespaceID;
-        nsCOMPtr<nsIAtom> mLocalName;
+        RefPtr<nsIAtom> mLocalName;
         void* mValue;
     };
 
     nsTArray<MapItem> mItems;
 };
 
 template<class E>
 class txExpandedNameMap : public txExpandedNameMap_base
--- a/dom/xslt/base/txNamespaceMap.cpp
+++ b/dom/xslt/base/txNamespaceMap.cpp
@@ -22,17 +22,17 @@ txNamespaceMap::mapNamespace(nsIAtom* aP
 {
     nsIAtom* prefix = aPrefix == nsGkAtoms::_empty ? nullptr : aPrefix;
 
     int32_t nsId;
     if (prefix && aNamespaceURI.IsEmpty()) {
         // Remove the mapping
         int32_t index = mPrefixes.IndexOf(prefix);
         if (index >= 0) {
-            mPrefixes.RemoveObjectAt(index);
+            mPrefixes.RemoveElementAt(index);
             mNamespaces.RemoveElementAt(index);
         }
 
         return NS_OK;
     }
 
     if (aNamespaceURI.IsEmpty()) {
         // Set default to empty namespace
@@ -47,22 +47,22 @@ txNamespaceMap::mapNamespace(nsIAtom* aP
     int32_t index = mPrefixes.IndexOf(prefix);
     if (index >= 0) {
         mNamespaces.ElementAt(index) = nsId;
 
         return NS_OK;
     }
 
     // New mapping
-    if (!mPrefixes.AppendObject(prefix)) {
+    if (!mPrefixes.AppendElement(prefix)) {
         return NS_ERROR_OUT_OF_MEMORY;
     }
 
     if (mNamespaces.AppendElement(nsId) == nullptr) {
-        mPrefixes.RemoveObjectAt(mPrefixes.Count() - 1);
+        mPrefixes.RemoveElementAt(mPrefixes.Length() - 1);
 
         return NS_ERROR_OUT_OF_MEMORY;
     }
 
     return NS_OK;
 }
 
 int32_t
@@ -84,15 +84,15 @@ txNamespaceMap::lookupNamespace(nsIAtom*
     }
 
     return kNameSpaceID_Unknown;
 }
 
 int32_t
 txNamespaceMap::lookupNamespaceWithDefault(const nsAString& aPrefix)
 {
-    nsCOMPtr<nsIAtom> prefix = NS_Atomize(aPrefix);
+    RefPtr<nsIAtom> prefix = NS_Atomize(aPrefix);
     if (prefix != nsGkAtoms::_poundDefault) {
         return lookupNamespace(prefix);
     }
 
     return lookupNamespace(nullptr);
 }
--- a/dom/xslt/base/txNamespaceMap.h
+++ b/dom/xslt/base/txNamespaceMap.h
@@ -31,13 +31,13 @@ public:
     }
 
     nsresult mapNamespace(nsIAtom* aPrefix, const nsAString& aNamespaceURI);
     int32_t lookupNamespace(nsIAtom* aPrefix);
     int32_t lookupNamespaceWithDefault(const nsAString& aPrefix);
 
 private:
     nsAutoRefCnt mRefCnt;
-    nsCOMArray<nsIAtom> mPrefixes;
+    nsTArray<RefPtr<nsIAtom>> mPrefixes;
     nsTArray<int32_t> mNamespaces;
 };
 
 #endif //TRANSFRMX_TXNAMESPACEMAP_H
--- a/dom/xslt/xpath/txExpr.h
+++ b/dom/xslt/xpath/txExpr.h
@@ -444,18 +444,18 @@ public:
      */
     txNameTest(nsIAtom* aPrefix, nsIAtom* aLocalName, int32_t aNSID,
                uint16_t aNodeType);
 
     NodeTestType getType() override;
 
     TX_DECL_NODE_TEST
 
-    nsCOMPtr<nsIAtom> mPrefix;
-    nsCOMPtr<nsIAtom> mLocalName;
+    RefPtr<nsIAtom> mPrefix;
+    RefPtr<nsIAtom> mLocalName;
     int32_t mNamespace;
 private:
     uint16_t mNodeType;
 };
 
 /*
  * This class represents a NodeType as defined by the XPath spec
  */
@@ -491,17 +491,17 @@ public:
     }
 
     NodeTestType getType() override;
 
     TX_DECL_NODE_TEST
 
 private:
     NodeType mNodeType;
-    nsCOMPtr<nsIAtom> mNodeName;
+    RefPtr<nsIAtom> mNodeName;
 };
 
 /**
  * Class representing a nodetest combined with a predicate. May only be used
  * if the predicate is not sensitive to the context-nodelist.
  */
 class txPredicatedNodeTest : public txNodeTest
 {
@@ -826,18 +826,18 @@ class VariableRefExpr : public Expr {
 
 public:
 
     VariableRefExpr(nsIAtom* aPrefix, nsIAtom* aLocalName, int32_t aNSID);
 
     TX_DECL_EXPR
 
 private:
-    nsCOMPtr<nsIAtom> mPrefix;
-    nsCOMPtr<nsIAtom> mLocalName;
+    RefPtr<nsIAtom> mPrefix;
+    RefPtr<nsIAtom> mLocalName;
     int32_t mNamespace;
 };
 
 /**
  *  Represents a PathExpr
 **/
 class PathExpr : public Expr {
 
@@ -975,18 +975,18 @@ class txNamedAttributeStep : public Expr
 public:
     txNamedAttributeStep(int32_t aNsID, nsIAtom* aPrefix,
                          nsIAtom* aLocalName);
 
     TX_DECL_EXPR
 
 private:
     int32_t mNamespace;
-    nsCOMPtr<nsIAtom> mPrefix;
-    nsCOMPtr<nsIAtom> mLocalName;
+    RefPtr<nsIAtom> mPrefix;
+    RefPtr<nsIAtom> mLocalName;
 };
 
 /**
  *
  */
 class txUnionNodeTest : public txNodeTest
 {
 public:
--- a/dom/xslt/xpath/txExprParser.cpp
+++ b/dom/xslt/xpath/txExprParser.cpp
@@ -358,17 +358,17 @@ txExprParser::createFilterOrStep(txExprL
     switch (tok->mType) {
         case Token::FUNCTION_NAME_AND_PAREN:
             rv = createFunctionCall(lexer, aContext, getter_Transfers(expr));
             NS_ENSURE_SUCCESS(rv, rv);
             break;
         case Token::VAR_REFERENCE :
             lexer.nextToken();
             {
-                nsCOMPtr<nsIAtom> prefix, lName;
+                RefPtr<nsIAtom> prefix, lName;
                 int32_t nspace;
                 nsresult rv = resolveQName(tok->Value(), getter_AddRefs(prefix),
                                            aContext, getter_AddRefs(lName),
                                            nspace);
                 NS_ENSURE_SUCCESS(rv, rv);
                 expr = new VariableRefExpr(prefix, lName, nspace);
             }
             break;
@@ -419,17 +419,17 @@ txExprParser::createFunctionCall(txExprL
 
     nsAutoPtr<FunctionCall> fnCall;
 
     Token* tok = lexer.nextToken();
     NS_ASSERTION(tok->mType == Token::FUNCTION_NAME_AND_PAREN,
                  "FunctionCall expected");
 
     //-- compare function names
-    nsCOMPtr<nsIAtom> prefix, lName;
+    RefPtr<nsIAtom> prefix, lName;
     int32_t namespaceID;
     nsresult rv = resolveQName(tok->Value(), getter_AddRefs(prefix), aContext,
                                getter_AddRefs(lName), namespaceID);
     NS_ENSURE_SUCCESS(rv, rv);
 
     txCoreFunctionCall::eType type;
     if (namespaceID == kNameSpaceID_None &&
         txCoreFunctionCall::getTypeFromAtom(lName, type)) {
@@ -477,17 +477,17 @@ txExprParser::createLocationStep(txExprL
 
     //-- get Axis Identifier or AbbreviatedStep, if present
     Token* tok = lexer.peek();
     switch (tok->mType) {
         case Token::AXIS_IDENTIFIER:
         {
             //-- eat token
             lexer.nextToken();
-            nsCOMPtr<nsIAtom> axis = NS_Atomize(tok->Value());
+            RefPtr<nsIAtom> axis = NS_Atomize(tok->Value());
             if (axis == nsGkAtoms::ancestor) {
                 axisIdentifier = LocationStep::ANCESTOR_AXIS;
             }
             else if (axis == nsGkAtoms::ancestorOrSelf) {
                 axisIdentifier = LocationStep::ANCESTOR_OR_SELF_AXIS;
             }
             else if (axis == nsGkAtoms::attribute) {
                 axisIdentifier = LocationStep::ATTRIBUTE_AXIS;
@@ -551,17 +551,17 @@ txExprParser::createLocationStep(txExprL
     //-- get NodeTest unless an AbbreviatedStep was found
     nsresult rv = NS_OK;
     if (!nodeTest) {
         tok = lexer.peek();
 
         if (tok->mType == Token::CNAME) {
             lexer.nextToken();
             // resolve QName
-            nsCOMPtr<nsIAtom> prefix, lName;
+            RefPtr<nsIAtom> prefix, lName;
             int32_t nspace;
             rv = resolveQName(tok->Value(), getter_AddRefs(prefix),
                               aContext, getter_AddRefs(lName),
                               nspace, true);
             NS_ENSURE_SUCCESS(rv, rv);
 
             nodeTest =
               new txNameTest(prefix, lName, nspace,
--- a/dom/xslt/xpath/txFunctionCall.cpp
+++ b/dom/xslt/xpath/txFunctionCall.cpp
@@ -107,17 +107,17 @@ FunctionCall::argsSensitiveTo(ContextSen
 
     return false;
 }
 
 #ifdef TX_TO_STRING
 void
 FunctionCall::toString(nsAString& aDest)
 {
-    nsCOMPtr<nsIAtom> functionNameAtom;
+    RefPtr<nsIAtom> functionNameAtom;
     if (NS_FAILED(getNameAtom(getter_AddRefs(functionNameAtom)))) {
         NS_ERROR("Can't get function name.");
         return;
     }
 
 
 
     aDest.Append(nsDependentAtomString(functionNameAtom) +
--- a/dom/xslt/xpath/txMozillaXPathTreeWalker.cpp
+++ b/dom/xslt/xpath/txMozillaXPathTreeWalker.cpp
@@ -289,33 +289,33 @@ already_AddRefed<nsIAtom>
 txXPathNodeUtils::getLocalName(const txXPathNode& aNode)
 {
     if (aNode.isDocument()) {
         return nullptr;
     }
 
     if (aNode.isContent()) {
         if (aNode.mNode->IsElement()) {
-            nsCOMPtr<nsIAtom> localName =
+            RefPtr<nsIAtom> localName =
                 aNode.Content()->NodeInfo()->NameAtom();
             return localName.forget();
         }
 
         if (aNode.mNode->IsNodeOfType(nsINode::ePROCESSING_INSTRUCTION)) {
             nsCOMPtr<nsIDOMNode> node = do_QueryInterface(aNode.mNode);
             nsAutoString target;
             node->GetNodeName(target);
 
             return NS_Atomize(target);
         }
 
         return nullptr;
     }
 
-    nsCOMPtr<nsIAtom> localName = aNode.Content()->
+    RefPtr<nsIAtom> localName = aNode.Content()->
         GetAttrNameAt(aNode.mIndex)->LocalName();
 
     return localName.forget();
 }
 
 nsIAtom*
 txXPathNodeUtils::getPrefix(const txXPathNode& aNode)
 {
--- a/dom/xslt/xpath/txXPCOMExtensionFunction.cpp
+++ b/dom/xslt/xpath/txXPCOMExtensionFunction.cpp
@@ -115,17 +115,17 @@ public:
 private:
     txArgumentType GetParamType(const nsXPTParamInfo &aParam,
                                 nsIInterfaceInfo *aInfo);
 
     nsCOMPtr<nsISupports> mHelper;
     nsIID mIID;
     uint16_t mMethodIndex;
 #ifdef TX_TO_STRING
-    nsCOMPtr<nsIAtom> mName;
+    RefPtr<nsIAtom> mName;
 #endif
     nsCOMPtr<nsISupports> mState;
 };
 
 txXPCOMExtensionFunctionCall::txXPCOMExtensionFunctionCall(nsISupports *aHelper,
                                                            const nsIID &aIID,
                                                            uint16_t aMethodIndex,
 #ifdef TX_TO_STRING
--- a/dom/xslt/xpath/txXPathTreeWalker.h
+++ b/dom/xslt/xpath/txXPathTreeWalker.h
@@ -200,17 +200,17 @@ inline bool
 txXPathNodeUtils::localNameEquals(const txXPathNode& aNode,
                                   nsIAtom* aLocalName)
 {
     if (aNode.isContent() &&
         aNode.Content()->IsElement()) {
         return aNode.Content()->NodeInfo()->Equals(aLocalName);
     }
 
-    nsCOMPtr<nsIAtom> localName = txXPathNodeUtils::getLocalName(aNode);
+    RefPtr<nsIAtom> localName = txXPathNodeUtils::getLocalName(aNode);
 
     return localName == aLocalName;
 }
 
 /* static */
 inline bool
 txXPathNodeUtils::isRoot(const txXPathNode& aNode)
 {
--- a/dom/xslt/xslt/txBufferingHandler.cpp
+++ b/dom/xslt/xslt/txBufferingHandler.cpp
@@ -95,19 +95,19 @@ public:
           mNsID(aNsID)
     {
         MOZ_COUNT_CTOR_INHERITED(txStartElementAtomTransaction, txOutputTransaction);
     }
     virtual ~txStartElementAtomTransaction()
     {
         MOZ_COUNT_DTOR_INHERITED(txStartElementAtomTransaction, txOutputTransaction);
     }
-    nsCOMPtr<nsIAtom> mPrefix;
-    nsCOMPtr<nsIAtom> mLocalName;
-    nsCOMPtr<nsIAtom> mLowercaseLocalName;
+    RefPtr<nsIAtom> mPrefix;
+    RefPtr<nsIAtom> mLocalName;
+    RefPtr<nsIAtom> mLowercaseLocalName;
     int32_t mNsID;
 };
 
 class txStartElementTransaction : public txOutputTransaction
 {
 public:
     txStartElementTransaction(nsIAtom* aPrefix,
                               const nsAString& aLocalName, int32_t aNsID)
@@ -117,17 +117,17 @@ public:
           mNsID(aNsID)
     {
         MOZ_COUNT_CTOR_INHERITED(txStartElementTransaction, txOutputTransaction);
     }
     virtual ~txStartElementTransaction()
     {
         MOZ_COUNT_DTOR_INHERITED(txStartElementTransaction, txOutputTransaction);
     }
-    nsCOMPtr<nsIAtom> mPrefix;
+    RefPtr<nsIAtom> mPrefix;
     nsString mLocalName;
     int32_t mNsID;
 };
 
 class txAttributeTransaction : public txOutputTransaction
 {
 public:
     txAttributeTransaction(nsIAtom* aPrefix,
@@ -140,17 +140,17 @@ public:
           mValue(aValue)
     {
         MOZ_COUNT_CTOR_INHERITED(txAttributeTransaction, txOutputTransaction);
     }
     virtual ~txAttributeTransaction()
     {
         MOZ_COUNT_DTOR_INHERITED(txAttributeTransaction, txOutputTransaction);
     }
-    nsCOMPtr<nsIAtom> mPrefix;
+    RefPtr<nsIAtom> mPrefix;
     nsString mLocalName;
     int32_t mNsID;
     nsString mValue;
 };
 
 class txAttributeAtomTransaction : public txOutputTransaction
 {
 public:
@@ -165,19 +165,19 @@ public:
           mValue(aValue)
     {
         MOZ_COUNT_CTOR_INHERITED(txAttributeAtomTransaction, txOutputTransaction);
     }
     virtual ~txAttributeAtomTransaction()
     {
         MOZ_COUNT_DTOR_INHERITED(txAttributeAtomTransaction, txOutputTransaction);
     }
-    nsCOMPtr<nsIAtom> mPrefix;
-    nsCOMPtr<nsIAtom> mLocalName;
-    nsCOMPtr<nsIAtom> mLowercaseLocalName;
+    RefPtr<nsIAtom> mPrefix;
+    RefPtr<nsIAtom> mLocalName;
+    RefPtr<nsIAtom> mLowercaseLocalName;
     int32_t mNsID;
     nsString mValue;
 };
 
 txBufferingHandler::txBufferingHandler() : mCanAddAttribute(false)
 {
     MOZ_COUNT_CTOR(txBufferingHandler);
     mBuffer = new txResultBuffer();
--- a/dom/xslt/xslt/txExecutionState.h
+++ b/dom/xslt/xslt/txExecutionState.h
@@ -82,17 +82,17 @@ public:
 
     /**
      * Struct holding information about a current template rule
      */
     class TemplateRule {
     public:
         txStylesheet::ImportFrame* mFrame;
         int32_t mModeNsId;
-        nsCOMPtr<nsIAtom> mModeLocalName;
+        RefPtr<nsIAtom> mModeLocalName;
         txVariableMap* mParams;
     };
 
     // Stack functions
     nsresult pushEvalContext(txIEvalContext* aContext);
     txIEvalContext* popEvalContext();
 
     /**
--- a/dom/xslt/xslt/txInstructions.cpp
+++ b/dom/xslt/xslt/txInstructions.cpp
@@ -108,17 +108,17 @@ txAttribute::execute(txExecutionState& a
     NS_ENSURE_SUCCESS(rv, rv);
 
     const char16_t* colon;
     if (!XMLUtils::isValidQName(name, &colon) ||
         TX_StringEqualsAtom(name, nsGkAtoms::xmlns)) {
         return NS_OK;
     }
 
-    nsCOMPtr<nsIAtom> prefix;
+    RefPtr<nsIAtom> prefix;
     uint32_t lnameStart = 0;
     if (colon) {
         prefix = NS_Atomize(Substring(name.get(), colon));
         lnameStart = colon - name.get() + 1;
     }
 
     int32_t nsId = kNameSpaceID_None;
     if (mNamespace) {
@@ -224,17 +224,17 @@ nsresult
 txCopyBase::copyNode(const txXPathNode& aNode, txExecutionState& aEs)
 {
     switch (txXPathNodeUtils::getNodeType(aNode)) {
         case txXPathNodeType::ATTRIBUTE_NODE:
         {
             nsAutoString nodeValue;
             txXPathNodeUtils::appendNodeValue(aNode, nodeValue);
 
-            nsCOMPtr<nsIAtom> localName =
+            RefPtr<nsIAtom> localName =
                 txXPathNodeUtils::getLocalName(aNode);
             return aEs.mResultHandler->
                 attribute(txXPathNodeUtils::getPrefix(aNode),
                           localName, nullptr,
                           txXPathNodeUtils::getNamespaceID(aNode),
                           nodeValue);
         }
         case txXPathNodeType::COMMENT_NODE:
@@ -252,17 +252,17 @@ txCopyBase::copyNode(const txXPathNode& 
             while (hasChild) {
                 copyNode(walker.getCurrentPosition(), aEs);
                 hasChild = walker.moveToNextSibling();
             }
             break;
         }
         case txXPathNodeType::ELEMENT_NODE:
         {
-            nsCOMPtr<nsIAtom> localName =
+            RefPtr<nsIAtom> localName =
                 txXPathNodeUtils::getLocalName(aNode);
             nsresult rv = aEs.mResultHandler->
                 startElement(txXPathNodeUtils::getPrefix(aNode),
                              localName, nullptr,
                              txXPathNodeUtils::getNamespaceID(aNode));
             NS_ENSURE_SUCCESS(rv, rv);
 
             // Copy attributes
@@ -335,17 +335,17 @@ txCopy::execute(txExecutionState& aEs)
 
             rv = aEs.pushBool(false);
             NS_ENSURE_SUCCESS(rv, rv);
 
             break;
         }
         case txXPathNodeType::ELEMENT_NODE:
         {
-            nsCOMPtr<nsIAtom> localName =
+            RefPtr<nsIAtom> localName =
                 txXPathNodeUtils::getLocalName(node);
             rv = aEs.mResultHandler->
                 startElement(txXPathNodeUtils::getPrefix(node),
                              localName, nullptr,
                              txXPathNodeUtils::getNamespaceID(node));
             NS_ENSURE_SUCCESS(rv, rv);
 
             // XXX copy namespace nodes once we have them
@@ -821,17 +821,17 @@ nsresult
 txStartElement::execute(txExecutionState& aEs)
 {
     nsAutoString name;
     nsresult rv = mName->evaluateToString(aEs.getEvalContext(), name);
     NS_ENSURE_SUCCESS(rv, rv);
 
 
     int32_t nsId = kNameSpaceID_None;
-    nsCOMPtr<nsIAtom> prefix;
+    RefPtr<nsIAtom> prefix;
     uint32_t lnameStart = 0;
 
     const char16_t* colon;
     if (XMLUtils::isValidQName(name, &colon)) {
         if (colon) {
             prefix = NS_Atomize(Substring(name.get(), colon));
             lnameStart = colon - name.get() + 1;
         }
--- a/dom/xslt/xslt/txInstructions.h
+++ b/dom/xslt/xslt/txInstructions.h
@@ -186,19 +186,19 @@ class txLREAttribute : public txInstruct
 {
 public:
     txLREAttribute(int32_t aNamespaceID, nsIAtom* aLocalName,
                    nsIAtom* aPrefix, nsAutoPtr<Expr>&& aValue);
 
     TX_DECL_TXINSTRUCTION
 
     int32_t mNamespaceID;
-    nsCOMPtr<nsIAtom> mLocalName;
-    nsCOMPtr<nsIAtom> mLowercaseLocalName;
-    nsCOMPtr<nsIAtom> mPrefix;
+    RefPtr<nsIAtom> mLocalName;
+    RefPtr<nsIAtom> mLowercaseLocalName;
+    RefPtr<nsIAtom> mPrefix;
     nsAutoPtr<Expr> mValue;
 };
 
 class txMessage : public txInstruction
 {
 public:
     explicit txMessage(bool aTerminate);
 
@@ -353,19 +353,19 @@ class txStartLREElement : public txInstr
 {
 public:
     txStartLREElement(int32_t aNamespaceID, nsIAtom* aLocalName,
                       nsIAtom* aPrefix);
 
     TX_DECL_TXINSTRUCTION
 
     int32_t mNamespaceID;
-    nsCOMPtr<nsIAtom> mLocalName;
-    nsCOMPtr<nsIAtom> mLowercaseLocalName;
-    nsCOMPtr<nsIAtom> mPrefix;
+    RefPtr<nsIAtom> mLocalName;
+    RefPtr<nsIAtom> mLowercaseLocalName;
+    RefPtr<nsIAtom> mPrefix;
 };
 
 class txText : public txInstruction
 {
 public:
     txText(const nsAString& aStr, bool aDOE);
 
     TX_DECL_TXINSTRUCTION
--- a/dom/xslt/xslt/txMozillaXMLOutput.cpp
+++ b/dom/xslt/xslt/txMozillaXMLOutput.cpp
@@ -100,17 +100,17 @@ txMozillaXMLOutput::~txMozillaXMLOutput(
 
 nsresult
 txMozillaXMLOutput::attribute(nsIAtom* aPrefix,
                               nsIAtom* aLocalName,
                               nsIAtom* aLowercaseLocalName,
                               const int32_t aNsID,
                               const nsString& aValue)
 {
-    nsCOMPtr<nsIAtom> owner;
+    RefPtr<nsIAtom> owner;
     if (mOpenedElementIsHTML && aNsID == kNameSpaceID_None) {
         if (aLowercaseLocalName) {
             aLocalName = aLowercaseLocalName;
         }
         else {
             owner = TX_ToLowerCaseAtom(aLocalName);
             NS_ENSURE_TRUE(owner, NS_ERROR_OUT_OF_MEMORY);
 
@@ -122,17 +122,17 @@ txMozillaXMLOutput::attribute(nsIAtom* a
 }
 
 nsresult
 txMozillaXMLOutput::attribute(nsIAtom* aPrefix,
                               const nsAString& aLocalName,
                               const int32_t aNsID,
                               const nsString& aValue)
 {
-    nsCOMPtr<nsIAtom> lname;
+    RefPtr<nsIAtom> lname;
 
     if (mOpenedElementIsHTML && aNsID == kNameSpaceID_None) {
         nsAutoString lnameStr;
         nsContentUtils::ASCIIToLower(aLocalName, lnameStr);
         lname = NS_Atomize(lnameStr);
     }
     else {
         lname = NS_Atomize(aLocalName);
@@ -431,17 +431,17 @@ nsresult
 txMozillaXMLOutput::startElement(nsIAtom* aPrefix, nsIAtom* aLocalName,
                                  nsIAtom* aLowercaseLocalName,
                                  const int32_t aNsID)
 {
     NS_PRECONDITION(aNsID != kNameSpaceID_None || !aPrefix,
                     "Can't have prefix without namespace");
 
     if (mOutputFormat.mMethod == eHTMLOutput && aNsID == kNameSpaceID_None) {
-        nsCOMPtr<nsIAtom> owner;
+        RefPtr<nsIAtom> owner;
         if (!aLowercaseLocalName) {
             owner = TX_ToLowerCaseAtom(aLocalName);
             NS_ENSURE_TRUE(owner, NS_ERROR_OUT_OF_MEMORY);
 
             aLowercaseLocalName = owner;
         }
         return startElementInternal(nullptr,
                                     aLowercaseLocalName,
@@ -452,17 +452,17 @@ txMozillaXMLOutput::startElement(nsIAtom
 }
 
 nsresult
 txMozillaXMLOutput::startElement(nsIAtom* aPrefix,
                                  const nsAString& aLocalName,
                                  const int32_t aNsID)
 {
     int32_t nsId = aNsID;
-    nsCOMPtr<nsIAtom> lname;
+    RefPtr<nsIAtom> lname;
 
     if (mOutputFormat.mMethod == eHTMLOutput && aNsID == kNameSpaceID_None) {
         nsId = kNameSpaceID_XHTML;
 
         nsAutoString lnameStr;
         nsContentUtils::ASCIIToLower(aLocalName, lnameStr);
         lname = NS_Atomize(lnameStr);
     }
@@ -753,17 +753,17 @@ txMozillaXMLOutput::endHTMLElement(nsICo
         // handle HTTP-EQUIV data
         nsAutoString httpEquiv;
         aElement->GetAttr(kNameSpaceID_None, nsGkAtoms::httpEquiv, httpEquiv);
         if (!httpEquiv.IsEmpty()) {
             nsAutoString value;
             aElement->GetAttr(kNameSpaceID_None, nsGkAtoms::content, value);
             if (!value.IsEmpty()) {
                 nsContentUtils::ASCIIToLower(httpEquiv);
-                nsCOMPtr<nsIAtom> header = NS_Atomize(httpEquiv);
+                RefPtr<nsIAtom> header = NS_Atomize(httpEquiv);
                 processHTTPEquiv(header, value);
             }
         }
     }
 
     return NS_OK;
 }
 
@@ -888,17 +888,17 @@ txMozillaXMLOutput::createResultDocument
         else {
             qName.Assign(aName);
         }
 
         nsCOMPtr<nsIDOMDocumentType> documentType;
 
         nsresult rv = nsContentUtils::CheckQName(qName);
         if (NS_SUCCEEDED(rv)) {
-            nsCOMPtr<nsIAtom> doctypeName = NS_Atomize(qName);
+            RefPtr<nsIAtom> doctypeName = NS_Atomize(qName);
             if (!doctypeName) {
                 return NS_ERROR_OUT_OF_MEMORY;
             }
 
             // Indicate that there is no internal subset (not just an empty one)
             rv = NS_NewDOMDocumentType(getter_AddRefs(documentType),
                                        mNodeInfoManager,
                                        doctypeName,
--- a/dom/xslt/xslt/txMozillaXSLTProcessor.cpp
+++ b/dom/xslt/xslt/txMozillaXSLTProcessor.cpp
@@ -392,17 +392,17 @@ txMozillaXSLTProcessor::SetSourceContent
 
     return NS_OK;
 }
 
 NS_IMETHODIMP
 txMozillaXSLTProcessor::AddXSLTParamNamespace(const nsString& aPrefix,
                                               const nsString& aNamespace)
 {
-    nsCOMPtr<nsIAtom> pre = NS_Atomize(aPrefix);
+    RefPtr<nsIAtom> pre = NS_Atomize(aPrefix);
     return mParamNamespaceMap.mapNamespace(pre, aNamespace);
 }
 
 
 class txXSLTParamContext : public txIParseContext,
                            public txIEvalContext
 {
 public:
@@ -516,17 +516,17 @@ txMozillaXSLTProcessor::AddXSLTParam(con
         // Evaluate
         rv = expr->evaluate(&paramContext, getter_AddRefs(value));
         NS_ENSURE_SUCCESS(rv, rv);
     }
     else {
         value = new StringResult(aValue, nullptr);
     }
 
-    nsCOMPtr<nsIAtom> name = NS_Atomize(aName);
+    RefPtr<nsIAtom> name = NS_Atomize(aName);
     int32_t nsId = kNameSpaceID_Unknown;
     rv = nsContentUtils::NameSpaceManager()->
         RegisterNameSpace(aNamespace, nsId);
     NS_ENSURE_SUCCESS(rv, rv);
 
     txExpandedName varName(nsId, name);
     txVariable* var = static_cast<txVariable*>(mVariables.get(varName));
     if (var) {
@@ -939,17 +939,17 @@ txMozillaXSLTProcessor::SetParameter(con
             return NS_ERROR_FAILURE;
         }
     }
 
     int32_t nsId = kNameSpaceID_Unknown;
     nsresult rv = nsContentUtils::NameSpaceManager()->
         RegisterNameSpace(aNamespaceURI, nsId);
     NS_ENSURE_SUCCESS(rv, rv);
-    nsCOMPtr<nsIAtom> localName = NS_Atomize(aLocalName);
+    RefPtr<nsIAtom> localName = NS_Atomize(aLocalName);
     txExpandedName varName(nsId, localName);
 
     txVariable* var = static_cast<txVariable*>(mVariables.get(varName));
     if (var) {
         var->setValue(value);
         return NS_OK;
     }
 
@@ -961,17 +961,17 @@ NS_IMETHODIMP
 txMozillaXSLTProcessor::GetParameter(const nsAString& aNamespaceURI,
                                      const nsAString& aLocalName,
                                      nsIVariant **aResult)
 {
     int32_t nsId = kNameSpaceID_Unknown;
     nsresult rv = nsContentUtils::NameSpaceManager()->
         RegisterNameSpace(aNamespaceURI, nsId);
     NS_ENSURE_SUCCESS(rv, rv);
-    nsCOMPtr<nsIAtom> localName = NS_Atomize(aLocalName);
+    RefPtr<nsIAtom> localName = NS_Atomize(aLocalName);
     txExpandedName varName(nsId, localName);
 
     txVariable* var = static_cast<txVariable*>(mVariables.get(varName));
     if (var) {
         return var->getValue(aResult);
     }
     return NS_OK;
 }
@@ -979,17 +979,17 @@ txMozillaXSLTProcessor::GetParameter(con
 NS_IMETHODIMP
 txMozillaXSLTProcessor::RemoveParameter(const nsAString& aNamespaceURI,
                                         const nsAString& aLocalName)
 {
     int32_t nsId = kNameSpaceID_Unknown;
     nsresult rv = nsContentUtils::NameSpaceManager()->
         RegisterNameSpace(aNamespaceURI, nsId);
     NS_ENSURE_SUCCESS(rv, rv);
-    nsCOMPtr<nsIAtom> localName = NS_Atomize(aLocalName);
+    RefPtr<nsIAtom> localName = NS_Atomize(aLocalName);
     txExpandedName varName(nsId, localName);
 
     mVariables.remove(varName);
     return NS_OK;
 }
 
 NS_IMETHODIMP
 txMozillaXSLTProcessor::ClearParameters()
--- a/dom/xslt/xslt/txPatternParser.cpp
+++ b/dom/xslt/xslt/txPatternParser.cpp
@@ -124,17 +124,17 @@ nsresult txPatternParser::createLocPathP
                 aLexer.peek()->mType == Token::UNION_OP) {
                 aPattern = new txRootPattern();
                 return NS_OK;
             }
             break;
         case Token::FUNCTION_NAME_AND_PAREN:
             // id(Literal) or key(Literal, Literal)
             {
-                nsCOMPtr<nsIAtom> nameAtom =
+                RefPtr<nsIAtom> nameAtom =
                     NS_Atomize(aLexer.nextToken()->Value());
                 if (nameAtom == nsGkAtoms::id) {
                     rv = createIdPattern(aLexer, stepPattern);
                 }
                 else if (nameAtom == nsGkAtoms::key) {
                     rv = createKeyPattern(aLexer, aContext, stepPattern);
                 }
                 if (NS_FAILED(rv))
@@ -234,17 +234,17 @@ nsresult txPatternParser::createKeyPatte
         return NS_ERROR_XPATH_PARSE_FAILURE;
 
     if (!aContext->allowed(txIParseContext::KEY_FUNCTION))
         return NS_ERROR_XSLT_CALL_TO_KEY_NOT_ALLOWED;
 
     const char16_t* colon;
     if (!XMLUtils::isValidQName(PromiseFlatString(key), &colon))
         return NS_ERROR_XPATH_PARSE_FAILURE;
-    nsCOMPtr<nsIAtom> prefix, localName;
+    RefPtr<nsIAtom> prefix, localName;
     int32_t namespaceID;
     nsresult rv = resolveQName(key, getter_AddRefs(prefix), aContext,
                                getter_AddRefs(localName), namespaceID);
     if (NS_FAILED(rv))
         return rv;
 
     aPattern  = new txKeyPattern(prefix, localName, namespaceID, value);
     return NS_OK;
@@ -273,17 +273,17 @@ nsresult txPatternParser::createStepPatt
         isAttr = true;
     }
 
     txNodeTest* nodeTest;
     if (aLexer.peek()->mType == Token::CNAME) {
         tok = aLexer.nextToken();
 
         // resolve QName
-        nsCOMPtr<nsIAtom> prefix, lName;
+        RefPtr<nsIAtom> prefix, lName;
         int32_t nspace;
         rv = resolveQName(tok->Value(), getter_AddRefs(prefix), aContext,
                           getter_AddRefs(lName), nspace, true);
         if (NS_FAILED(rv)) {
             // XXX error report namespace resolve failed
             return rv;
         }
 
--- a/dom/xslt/xslt/txStylesheetCompileHandlers.cpp
+++ b/dom/xslt/xslt/txStylesheetCompileHandlers.cpp
@@ -312,17 +312,17 @@ static nsresult
 getYesNoAttr(txStylesheetAttr* aAttributes,
              int32_t aAttrCount,
              nsIAtom* aName,
              bool aRequired,
              txStylesheetCompilerState& aState,
              txThreeState& aRes)
 {
     aRes = eNotSet;
-    nsCOMPtr<nsIAtom> atom;
+    RefPtr<nsIAtom> atom;
     nsresult rv = getAtomAttr(aAttributes, aAttrCount, aName, aRequired,
                               aState, getter_AddRefs(atom));
     if (!atom) {
         return rv;
     }
 
     if (atom == nsGkAtoms::yes) {
         aRes = eTrue;
@@ -1009,17 +1009,17 @@ txFnStartStripSpace(int32_t aNamespaceID
 
     bool strip = aLocalName == nsGkAtoms::stripSpace;
 
     nsAutoPtr<txStripSpaceItem> stripItem(new txStripSpaceItem);
     nsWhitespaceTokenizer tokenizer(attr->mValue);
     while (tokenizer.hasMoreTokens()) {
         const nsAString& name = tokenizer.nextToken();
         int32_t ns = kNameSpaceID_None;
-        nsCOMPtr<nsIAtom> prefix, localName;
+        RefPtr<nsIAtom> prefix, localName;
         rv = XMLUtils::splitQName(name, getter_AddRefs(prefix),
                                   getter_AddRefs(localName));
         if (NS_FAILED(rv)) {
             // check for "*" or "prefix:*"
             uint32_t length = name.Length();
             const char16_t* c;
             name.BeginReading(c);
             if (length == 2 || c[length-1] != '*') {
@@ -1955,17 +1955,17 @@ txFnStartNumber(int32_t aNamespaceID,
                 nsIAtom* aLocalName,
                 nsIAtom* aPrefix,
                 txStylesheetAttr* aAttributes,
                 int32_t aAttrCount,
                 txStylesheetCompilerState& aState)
 {
     nsresult rv = NS_OK;
 
-    nsCOMPtr<nsIAtom> levelAtom;
+    RefPtr<nsIAtom> levelAtom;
     rv = getAtomAttr(aAttributes, aAttrCount, nsGkAtoms::level, false,
                      aState, getter_AddRefs(levelAtom));
     NS_ENSURE_SUCCESS(rv, rv);
 
     txXSLTNumber::LevelType level = txXSLTNumber::eLevelSingle;
     if (levelAtom == nsGkAtoms::multiple) {
         level = txXSLTNumber::eLevelMultiple;
     }
@@ -2849,17 +2849,17 @@ txHandlerTable::txHandlerTable(const Han
 
 nsresult
 txHandlerTable::init(const txElementHandler* aHandlers, uint32_t aCount)
 {
     nsresult rv = NS_OK;
 
     uint32_t i;
     for (i = 0; i < aCount; ++i) {
-        nsCOMPtr<nsIAtom> nameAtom = NS_Atomize(aHandlers->mLocalName);
+        RefPtr<nsIAtom> nameAtom = NS_Atomize(aHandlers->mLocalName);
         txExpandedName name(aHandlers->mNamespaceID, nameAtom);
         rv = mHandlers.add(name, aHandlers);
         NS_ENSURE_SUCCESS(rv, rv);
 
         ++aHandlers;
     }
     return NS_OK;
 }
--- a/dom/xslt/xslt/txStylesheetCompiler.cpp
+++ b/dom/xslt/xslt/txStylesheetCompiler.cpp
@@ -127,17 +127,17 @@ txStylesheetCompiler::startElement(const
     for (i = 0; i < aAttrCount; ++i) {
         rv = XMLUtils::splitExpatName(aAttrs[i * 2],
                                       getter_AddRefs(atts[i].mPrefix),
                                       getter_AddRefs(atts[i].mLocalName),
                                       &atts[i].mNamespaceID);
         NS_ENSURE_SUCCESS(rv, rv);
         atts[i].mValue.Append(aAttrs[i * 2 + 1]);
 
-        nsCOMPtr<nsIAtom> prefixToBind;
+        RefPtr<nsIAtom> prefixToBind;
         if (atts[i].mPrefix == nsGkAtoms::xmlns) {
             prefixToBind = atts[i].mLocalName;
         }
         else if (atts[i].mNamespaceID == kNameSpaceID_XMLNS) {
             prefixToBind = nsGkAtoms::_empty;
         }
 
         if (prefixToBind) {
@@ -151,17 +151,17 @@ txStylesheetCompiler::startElement(const
             }
 
             rv = mElementContext->mMappings->
                 mapNamespace(prefixToBind, atts[i].mValue);
             NS_ENSURE_SUCCESS(rv, rv);
         }
     }
 
-    nsCOMPtr<nsIAtom> prefix, localname;
+    RefPtr<nsIAtom> prefix, localname;
     int32_t namespaceID;
     rv = XMLUtils::splitExpatName(aName, getter_AddRefs(prefix),
                                   getter_AddRefs(localname), &namespaceID);
     NS_ENSURE_SUCCESS(rv, rv);
 
     return startElementInternal(namespaceID, localname, prefix, atts.get(),
                                 aAttrCount);
 }
@@ -857,17 +857,17 @@ public:
     explicit txErrorFunctionCall(nsIAtom* aName)
       : mName(aName)
     {
     }
 
     TX_DECL_FUNCTION
 
 private:
-    nsCOMPtr<nsIAtom> mName;
+    RefPtr<nsIAtom> mName;
 };
 
 nsresult
 txErrorFunctionCall::evaluate(txIEvalContext* aContext,
                               txAExprResult** aResult)
 {
     *aResult = nullptr;
 
--- a/dom/xslt/xslt/txStylesheetCompiler.h
+++ b/dom/xslt/xslt/txStylesheetCompiler.h
@@ -189,18 +189,18 @@ private:
     txListIterator mToplevelIterator;
     nsTArray<txInstruction**> mGotoTargetPointers;
     mozilla::net::ReferrerPolicy mReferrerPolicy;
 };
 
 struct txStylesheetAttr
 {
     int32_t mNamespaceID;
-    nsCOMPtr<nsIAtom> mLocalName;
-    nsCOMPtr<nsIAtom> mPrefix;
+    RefPtr<nsIAtom> mLocalName;
+    RefPtr<nsIAtom> mPrefix;
     nsString mValue;
 };
 
 class txStylesheetCompiler final : private txStylesheetCompilerState,
                                    public txACompileObserver
 {
 public:
     friend class txStylesheetCompilerState;
--- a/dom/xslt/xslt/txUnknownHandler.cpp
+++ b/dom/xslt/xslt/txUnknownHandler.cpp
@@ -117,17 +117,17 @@ txUnknownHandler::startElement(nsIAtom* 
                                nsIAtom* aLowercaseLocalName, int32_t aNsID)
 {
     if (!mFlushed) {
         // Make sure that mEs->mResultHandler == this is true, otherwise we'll
         // leak mEs->mResultHandler in createHandlerAndFlush.
         NS_ASSERTION(mEs->mResultHandler == this,
                      "We're leaking mEs->mResultHandler.");
 
-        nsCOMPtr<nsIAtom> owner;
+        RefPtr<nsIAtom> owner;
         if (!aLowercaseLocalName) {
             owner = TX_ToLowerCaseAtom(aLocalName);
             NS_ENSURE_TRUE(owner, NS_ERROR_OUT_OF_MEMORY);
 
             aLowercaseLocalName = owner;
         }
 
         bool htmlRoot = aNsID == kNameSpaceID_None && !aPrefix &&
--- a/dom/xslt/xslt/txXSLTNumber.cpp
+++ b/dom/xslt/xslt/txXSLTNumber.cpp
@@ -114,17 +114,17 @@ txXSLTNumber::getValueList(Expr* aValueE
     // Parse count- and from-attributes
 
     if (!aCountPattern) {
         txNodeTest* nodeTest;
         uint16_t nodeType = txXPathNodeUtils::getNodeType(currNode);
         switch (nodeType) {
             case txXPathNodeType::ELEMENT_NODE:
             {
-                nsCOMPtr<nsIAtom> localName =
+                RefPtr<nsIAtom> localName =
                     txXPathNodeUtils::getLocalName(currNode);
                 int32_t namespaceID = txXPathNodeUtils::getNamespaceID(currNode);
                 nodeTest = new txNameTest(0, localName, namespaceID,
                                           txXPathNodeType::ELEMENT_NODE);
                 break;
             }
             case txXPathNodeType::TEXT_NODE:
             case txXPathNodeType::CDATA_SECTION_NODE:
--- a/dom/xslt/xslt/txXSLTPatterns.cpp
+++ b/dom/xslt/xslt/txXSLTPatterns.cpp
@@ -300,18 +300,18 @@ txRootPattern::toString(nsAString& aDest
  * This looks like the id() function, but may only have LITERALs as
  * argument.
  */
 txIdPattern::txIdPattern(const nsAString& aString)
 {
     nsWhitespaceTokenizer tokenizer(aString);
     while (tokenizer.hasMoreTokens()) {
         // this can fail, XXX move to a Init(aString) method
-        nsCOMPtr<nsIAtom> atom = NS_Atomize(tokenizer.nextToken());
-        mIds.AppendObject(atom);
+        RefPtr<nsIAtom> atom = NS_Atomize(tokenizer.nextToken());
+        mIds.AppendElement(atom);
     }
 }
 
 nsresult
 txIdPattern::matches(const txXPathNode& aNode, txIMatchContext* aContext,
                      bool& aMatched)
 {
     if (!txXPathNodeUtils::isElement(aNode)) {
@@ -320,17 +320,17 @@ txIdPattern::matches(const txXPathNode& 
         return NS_OK;
     }
 
     // Get a ID attribute, if there is
     nsIContent* content = txXPathNativeNode::getContent(aNode);
     NS_ASSERTION(content, "a Element without nsIContent");
 
     nsIAtom* id = content->GetID();
-    aMatched = id && mIds.IndexOf(id) > -1;
+    aMatched = id && mIds.IndexOf(id) != mIds.NoIndex;
 
     return NS_OK;
 }
 
 double txIdPattern::getDefaultPriority()
 {
     return 0.5;
 }
@@ -341,17 +341,17 @@ TX_IMPL_PATTERN_STUBS_NO_SUB_PATTERN(txI
 #ifdef TX_TO_STRING
 void
 txIdPattern::toString(nsAString& aDest)
 {
 #ifdef DEBUG
     aDest.AppendLiteral("txIdPattern{");
 #endif
     aDest.AppendLiteral("id('");
-    uint32_t k, count = mIds.Count() - 1;
+    uint32_t k, count = mIds.Length() - 1;
     for (k = 0; k < count; ++k) {
         nsAutoString str;
         mIds[k]->ToString(str);
         aDest.Append(str);
         aDest.Append(char16_t(' '));
     }
     nsAutoString str;
     mIds[count]->ToString(str);
--- a/dom/xslt/xslt/txXSLTPatterns.h
+++ b/dom/xslt/xslt/txXSLTPatterns.h
@@ -188,17 +188,17 @@ private:
 class txIdPattern : public txPattern
 {
 public:
     explicit txIdPattern(const nsAString& aString);
 
     TX_DECL_PATTERN;
 
 private:
-    nsCOMArray<nsIAtom> mIds;
+    nsTArray<RefPtr<nsIAtom>> mIds;
 };
 
 class txKeyPattern : public txPattern
 {
 public:
     txKeyPattern(nsIAtom* aPrefix, nsIAtom* aLocalName,
                  int32_t aNSID, const nsAString& aValue)
         : mName(aNSID, aLocalName),
@@ -209,17 +209,17 @@ public:
     {
     }
 
     TX_DECL_PATTERN;
 
 private:
     txExpandedName mName;
 #ifdef TX_TO_STRING
-    nsCOMPtr<nsIAtom> mPrefix;
+    RefPtr<nsIAtom> mPrefix;
 #endif
     nsString mValue;
 };
 
 class txStepPattern : public txPattern,
                       public PredicateList
 {
 public:
--- a/dom/xul/XULDocument.cpp
+++ b/dom/xul/XULDocument.cpp
@@ -137,17 +137,17 @@ const nsForwardReference::Phase nsForwar
 int32_t XULDocument::gRefCnt = 0;
 
 LazyLogModule XULDocument::gXULLog("XULDocument");
 
 //----------------------------------------------------------------------
 
 struct BroadcastListener {
     nsWeakPtr mListener;
-    nsCOMPtr<nsIAtom> mAttribute;
+    RefPtr<nsIAtom> mAttribute;
 };
 
 struct BroadcasterMapEntry : public PLDHashEntryHdr
 {
     Element* mBroadcaster;  // [WEAK]
     nsTArray<BroadcastListener*> mListeners;  // [OWNING] of BroadcastListener objects
 };
 
@@ -649,18 +649,18 @@ CanBroadcast(int32_t aNameSpaceID, nsIAt
 struct nsAttrNameInfo
 {
   nsAttrNameInfo(int32_t aNamespaceID, nsIAtom* aName, nsIAtom* aPrefix) :
     mNamespaceID(aNamespaceID), mName(aName), mPrefix(aPrefix) {}
   nsAttrNameInfo(const nsAttrNameInfo& aOther) :
     mNamespaceID(aOther.mNamespaceID), mName(aOther.mName),
     mPrefix(aOther.mPrefix) {}
   int32_t           mNamespaceID;
-  nsCOMPtr<nsIAtom> mName;
-  nsCOMPtr<nsIAtom> mPrefix;
+  RefPtr<nsIAtom> mName;
+  RefPtr<nsIAtom> mPrefix;
 };
 
 void
 XULDocument::SynchronizeBroadcastListener(Element *aBroadcaster,
                                           Element *aListener,
                                           const nsAString &aAttr)
 {
     if (!nsContentUtils::IsSafeToRunScript()) {
@@ -705,17 +705,17 @@ XULDocument::SynchronizeBroadcastListene
             // which could define JS properties that mask XBL
             // properties, etc.
             ExecuteOnBroadcastHandlerFor(aBroadcaster, aListener, name);
 #endif
         }
     }
     else {
         // Find out if the attribute is even present at all.
-        nsCOMPtr<nsIAtom> name = NS_Atomize(aAttr);
+        RefPtr<nsIAtom> name = NS_Atomize(aAttr);
 
         nsAutoString value;
         if (aBroadcaster->GetAttr(kNameSpaceID_None, name, value)) {
             aListener->SetAttr(kNameSpaceID_None, name, value, notify);
         } else {
             aListener->UnsetAttr(kNameSpaceID_None, name, notify);
         }
 
@@ -786,17 +786,17 @@ XULDocument::AddBroadcastListenerFor(Ele
 
         entry->mBroadcaster = &aBroadcaster;
 
         // N.B. placement new to construct the nsTArray object in-place
         new (&entry->mListeners) nsTArray<BroadcastListener*>();
     }
 
     // Only add the listener if it's not there already!
-    nsCOMPtr<nsIAtom> attr = NS_Atomize(aAttr);
+    RefPtr<nsIAtom> attr = NS_Atomize(aAttr);
 
     for (size_t i = entry->mListeners.Length() - 1; i != (size_t)-1; --i) {
         BroadcastListener* bl = entry->mListeners[i];
         nsCOMPtr<Element> blListener = do_QueryReferent(bl->mListener);
 
         if (blListener == &aListener && bl->mAttribute == attr)
             return;
     }
@@ -830,17 +830,17 @@ XULDocument::RemoveBroadcastListenerFor(
     // If we haven't added any broadcast listeners, then there sure
     // aren't any to remove.
     if (! mBroadcasterMap)
         return;
 
     auto entry = static_cast<BroadcasterMapEntry*>
                             (mBroadcasterMap->Search(&aBroadcaster));
     if (entry) {
-        nsCOMPtr<nsIAtom> attr = NS_Atomize(aAttr);
+        RefPtr<nsIAtom> attr = NS_Atomize(aAttr);
         for (size_t i = entry->mListeners.Length() - 1; i != (size_t)-1; --i) {
             BroadcastListener* bl = entry->mListeners[i];
             nsCOMPtr<Element> blListener = do_QueryReferent(bl->mListener);
 
             if (blListener == &aListener && bl->mAttribute == attr) {
                 entry->mListeners.RemoveElementAt(i);
                 delete bl;
 
@@ -1204,17 +1204,17 @@ XULDocument::GetElementsByAttribute(cons
     *aReturn = GetElementsByAttribute(aAttribute, aValue).take();
     return NS_OK;
 }
 
 already_AddRefed<nsINodeList>
 XULDocument::GetElementsByAttribute(const nsAString& aAttribute,
                                     const nsAString& aValue)
 {
-    nsCOMPtr<nsIAtom> attrAtom(NS_Atomize(aAttribute));
+    RefPtr<nsIAtom> attrAtom(NS_Atomize(aAttribute));
     void* attrValue = new nsString(aValue);
     RefPtr<nsContentList> list = new nsContentList(this,
                                             MatchAttribute,
                                             nsContentUtils::DestroyMatchString,
                                             attrValue,
                                             true,
                                             attrAtom,
                                             kNameSpaceID_Unknown);
@@ -1235,17 +1235,17 @@ XULDocument::GetElementsByAttributeNS(co
 }
 
 already_AddRefed<nsINodeList>
 XULDocument::GetElementsByAttributeNS(const nsAString& aNamespaceURI,
                                       const nsAString& aAttribute,
                                       const nsAString& aValue,
                                       ErrorResult& aRv)
 {
-    nsCOMPtr<nsIAtom> attrAtom(NS_Atomize(aAttribute));
+    RefPtr<nsIAtom> attrAtom(NS_Atomize(aAttribute));
     void* attrValue = new nsString(aValue);
 
     int32_t nameSpaceId = kNameSpaceID_Wildcard;
     if (!aNamespaceURI.EqualsLiteral("*")) {
       nsresult rv =
         nsContentUtils::NameSpaceManager()->RegisterNameSpace(aNamespaceURI,
                                                               nameSpaceId);
       if (NS_FAILED(rv)) {
@@ -1272,17 +1272,17 @@ XULDocument::Persist(const nsAString& aI
     // localstore, _don't_ re-enter and try to set them again!
     if (mApplyingPersistedAttrs)
         return NS_OK;
 
     Element* element = nsDocument::GetElementById(aID);
     if (!element)
         return NS_OK;
 
-    nsCOMPtr<nsIAtom> tag;
+    RefPtr<nsIAtom> tag;
     int32_t nameSpaceID;
 
     RefPtr<mozilla::dom::NodeInfo> ni = element->GetExistingAttrNameFromQName(aAttr);
     nsresult rv;
     if (ni) {
         tag = ni->NameAtom();
         nameSpaceID = ni->NamespaceID();
     }
@@ -2137,17 +2137,17 @@ XULDocument::ApplyPersistentAttributesTo
         attrs->GetNext(attrstr);
 
         nsAutoString value;
         rv = mLocalStore->GetValue(uri, aID, attrstr, value);
         if (NS_WARN_IF(NS_FAILED(rv))) {
             return rv;
         }
 
-        nsCOMPtr<nsIAtom> attr = NS_Atomize(attrstr);
+        RefPtr<nsIAtom> attr = NS_Atomize(attrstr);
         if (NS_WARN_IF(!attr)) {
             return NS_ERROR_OUT_OF_MEMORY;
         }
 
         uint32_t cnt = aElements.Count();
 
         for (int32_t i = int32_t(cnt) - 1; i >= 0; --i) {
             nsCOMPtr<nsIContent> element = aElements.SafeObjectAt(i);
--- a/dom/xul/XULDocument.h
+++ b/dom/xul/XULDocument.h
@@ -758,17 +758,17 @@ protected:
         mAttr(aOther.mAttr), mAttrName(aOther.mAttrName),
         mSetAttr(aOther.mSetAttr), mNeedsAttrChange(aOther.mNeedsAttrChange) {}
 
       nsCOMPtr<Element>       mBroadcaster;
       nsCOMPtr<Element>       mListener;
       // Note if mAttrName isn't used, this is the name of the attr, otherwise
       // this is the value of the attribute.
       nsString                mAttr;
-      nsCOMPtr<nsIAtom>       mAttrName;
+      RefPtr<nsIAtom>       mAttrName;
       bool                    mSetAttr;
       bool                    mNeedsAttrChange;
 
       class Comparator {
         public:
           static bool Equals(const nsDelayedBroadcastUpdate& a, const nsDelayedBroadcastUpdate& b) {
             return a.mBroadcaster == b.mBroadcaster && a.mListener == b.mListener && a.mAttrName == b.mAttrName;
           }
--- a/dom/xul/nsXULContentSink.cpp
+++ b/dom/xul/nsXULContentSink.cpp
@@ -391,17 +391,17 @@ XULContentSinkImpl::FlushText(bool aCrea
 
 //----------------------------------------------------------------------
 
 nsresult
 XULContentSinkImpl::NormalizeAttributeString(const char16_t *aExpatName,
                                              nsAttrName &aName)
 {
     int32_t nameSpaceID;
-    nsCOMPtr<nsIAtom> prefix, localName;
+    RefPtr<nsIAtom> prefix, localName;
     nsContentUtils::SplitExpatName(aExpatName, getter_AddRefs(prefix),
                                    getter_AddRefs(localName), &nameSpaceID);
 
     if (nameSpaceID == kNameSpaceID_None) {
         aName.SetTo(localName);
 
         return NS_OK;
     }
@@ -445,17 +445,17 @@ XULContentSinkImpl::HandleStartElement(c
   if (mState == eInEpilog)
       return NS_ERROR_UNEXPECTED;
 
   if (mState != eInScript) {
       FlushText();
   }
 
   int32_t nameSpaceID;
-  nsCOMPtr<nsIAtom> prefix, localName;
+  RefPtr<nsIAtom> prefix, localName;
   nsContentUtils::SplitExpatName(aName, getter_AddRefs(prefix),
                                  getter_AddRefs(localName), &nameSpaceID);
 
   RefPtr<mozilla::dom::NodeInfo> nodeInfo;
   nodeInfo = mNodeInfoManager->GetNodeInfo(localName, prefix, nameSpaceID,
                                            nsIDOMNode::ELEMENT_NODE);
 
   nsresult rv = NS_OK;
--- a/dom/xul/nsXULElement.cpp
+++ b/dom/xul/nsXULElement.cpp
@@ -379,17 +379,17 @@ nsXULElement::Clone(mozilla::dom::NodeIn
 }
 
 //----------------------------------------------------------------------
 
 already_AddRefed<nsINodeList>
 nsXULElement::GetElementsByAttribute(const nsAString& aAttribute,
                                      const nsAString& aValue)
 {
-    nsCOMPtr<nsIAtom> attrAtom(NS_Atomize(aAttribute));
+    RefPtr<nsIAtom> attrAtom(NS_Atomize(aAttribute));
     void* attrValue = new nsString(aValue);
     RefPtr<nsContentList> list =
         new nsContentList(this,
                           XULDocument::MatchAttribute,
                           nsContentUtils::DestroyMatchString,
                           attrValue,
                           true,
                           attrAtom,
@@ -398,17 +398,17 @@ nsXULElement::GetElementsByAttribute(con
 }
 
 already_AddRefed<nsINodeList>
 nsXULElement::GetElementsByAttributeNS(const nsAString& aNamespaceURI,
                                        const nsAString& aAttribute,
                                        const nsAString& aValue,
                                        ErrorResult& rv)
 {
-    nsCOMPtr<nsIAtom> attrAtom(NS_Atomize(aAttribute));
+    RefPtr<nsIAtom> attrAtom(NS_Atomize(aAttribute));
 
     int32_t nameSpaceId = kNameSpaceID_Wildcard;
     if (!aNamespaceURI.EqualsLiteral("*")) {
       rv =
         nsContentUtils::NameSpaceManager()->RegisterNameSpace(aNamespaceURI,
                                                               nameSpaceId);
       if (rv.Failed()) {
           return nullptr;
--- a/dom/xul/nsXULPrototypeDocument.cpp
+++ b/dom/xul/nsXULPrototypeDocument.cpp
@@ -151,17 +151,17 @@ nsXULPrototypeDocument::Read(nsIObjectIn
     nsTArray<RefPtr<mozilla::dom::NodeInfo>> nodeInfos;
 
     tmp = aStream->Read32(&count);
     if (NS_FAILED(tmp)) {
       rv = tmp;
     }
     nsAutoString namespaceURI, prefixStr, localName;
     bool prefixIsNull;
-    nsCOMPtr<nsIAtom> prefix;
+    RefPtr<nsIAtom> prefix;
     for (i = 0; i < count; ++i) {
         tmp = aStream->ReadString(namespaceURI);
         if (NS_FAILED(tmp)) {
           rv = tmp;
         }
         tmp = aStream->ReadBoolean(&prefixIsNull);
         if (NS_FAILED(tmp)) {
           rv = tmp;
--- a/dom/xul/templates/nsContentTestNode.h
+++ b/dom/xul/templates/nsContentTestNode.h
@@ -35,14 +35,14 @@ public:
     {
         mTag = aTag;
         mDocument = aDocument;
     }
 
 protected:
     nsXULTemplateQueryProcessorRDF *mProcessor;
     nsIDOMDocument* mDocument;
-    nsCOMPtr<nsIAtom> mRefVariable;
-    nsCOMPtr<nsIAtom> mTag;
+    RefPtr<nsIAtom> mRefVariable;
+    RefPtr<nsIAtom> mTag;
 };
 
 #endif // nsContentTestNode_h__
 
--- a/dom/xul/templates/nsRDFBinding.h
+++ b/dom/xul/templates/nsRDFBinding.h
@@ -19,19 +19,19 @@ class nsBindingValues;
 
 /*
  * a  <binding> descriptors
  */
 class RDFBinding {
 
 public:
 
-    nsCOMPtr<nsIAtom>        mSubjectVariable;
+    RefPtr<nsIAtom>        mSubjectVariable;
     nsCOMPtr<nsIRDFResource> mPredicate;
-    nsCOMPtr<nsIAtom>        mTargetVariable;
+    RefPtr<nsIAtom>        mTargetVariable;
 
     // indicates whether a binding is dependant on the result from a
     // previous binding
     bool                     mHasDependency;
 
     RDFBinding*              mNext;
 
 private:
--- a/dom/xul/templates/nsRDFConInstanceTestNode.h
+++ b/dom/xul/templates/nsRDFConInstanceTestNode.h
@@ -74,15 +74,15 @@ public:
     protected:
         nsCOMPtr<nsIRDFResource> mContainer;
         Test mContainerTest;
         Test mEmptyTest;
     };
 
 protected:
     nsXULTemplateQueryProcessorRDF* mProcessor;
-    nsCOMPtr<nsIAtom> mContainerVariable;
+    RefPtr<nsIAtom> mContainerVariable;
     Test mContainer;
     Test mEmpty;
 };
 
 #endif // nsRDFConInstanceTestNode_h__
 
--- a/dom/xul/templates/nsRDFConMemberTestNode.h
+++ b/dom/xul/templates/nsRDFConMemberTestNode.h
@@ -65,13 +65,13 @@ public:
 
     protected:
         nsCOMPtr<nsIRDFResource> mContainer;
         nsCOMPtr<nsIRDFNode> mMember;
     };
 
 protected:
     nsXULTemplateQueryProcessorRDF* mProcessor;
-    nsCOMPtr<nsIAtom> mContainerVariable;
-    nsCOMPtr<nsIAtom> mMemberVariable;
+    RefPtr<nsIAtom> mContainerVariable;
+    RefPtr<nsIAtom> mMemberVariable;
 };
 
 #endif // nsRDFConMemberTestNode_h__
--- a/dom/xul/templates/nsRDFPropertyTestNode.h
+++ b/dom/xul/templates/nsRDFPropertyTestNode.h
@@ -89,16 +89,16 @@ public:
     protected:
         nsCOMPtr<nsIRDFResource> mSource;
         nsCOMPtr<nsIRDFResource> mProperty;
         nsCOMPtr<nsIRDFNode> mTarget;
     };
 
 protected:
     nsXULTemplateQueryProcessorRDF* mProcessor;
-    nsCOMPtr<nsIAtom>        mSourceVariable;
+    RefPtr<nsIAtom>        mSourceVariable;
     nsCOMPtr<nsIRDFResource> mSource;
     nsCOMPtr<nsIRDFResource> mProperty;
-    nsCOMPtr<nsIAtom>        mTargetVariable;
+    RefPtr<nsIAtom>        mTargetVariable;
     nsCOMPtr<nsIRDFNode>     mTarget;
 };
 
 #endif // nsRDFPropertyTestNode_h__
--- a/dom/xul/templates/nsRDFQuery.h
+++ b/dom/xul/templates/nsRDFQuery.h
@@ -96,18 +96,18 @@ public:
 
     nsIAtom* GetMemberVariable() override { return mMemberVariable; }
 
     bool IsSimple() { return mSimple; }
 
     void SetSimple() { mSimple = true; }
 
     // the reference and member variables for the query
-    nsCOMPtr<nsIAtom> mRefVariable;
-    nsCOMPtr<nsIAtom> mMemberVariable;
+    RefPtr<nsIAtom> mRefVariable;
+    RefPtr<nsIAtom> mMemberVariable;
 
 protected:
 
     nsXULTemplateQueryProcessorRDF* mProcessor;
 
     // true if the query is a simple rule (one with a default query)
     bool mSimple;
 
--- a/dom/xul/templates/nsRuleNetwork.h
+++ b/dom/xul/templates/nsRuleNetwork.h
@@ -182,17 +182,17 @@ public:
 
 //----------------------------------------------------------------------
 
 /**
  * An assignment of a value to a variable
  */
 class nsAssignment {
 public:
-    const nsCOMPtr<nsIAtom> mVariable;
+    const RefPtr<nsIAtom> mVariable;
     nsCOMPtr<nsIRDFNode> mValue;
 
     nsAssignment(nsIAtom* aVariable, nsIRDFNode* aValue)
         : mVariable(aVariable),
           mValue(aValue)
         { MOZ_COUNT_CTOR(nsAssignment); }
 
     nsAssignment(const nsAssignment& aAssignment)
--- a/dom/xul/templates/nsTemplateRule.h
+++ b/dom/xul/templates/nsTemplateRule.h
@@ -71,20 +71,20 @@ public:
     bool
     CheckMatch(nsIXULTemplateResult* aResult);
 
     bool
     CheckMatchStrings(const nsAString& aLeftString,
                       const nsAString& aRightString);
 protected:
 
-    nsCOMPtr<nsIAtom>   mSourceVariable;
+    RefPtr<nsIAtom>   mSourceVariable;
     nsString            mSource;
     ConditionRelation   mRelation;
-    nsCOMPtr<nsIAtom>   mTargetVariable;
+    RefPtr<nsIAtom>   mTargetVariable;
     nsTArray<nsString>  mTargetList;
     bool                mIgnoreCase;
     bool                mNegate;
 
    nsTemplateCondition* mNext;
 };
 
 /**
@@ -199,18 +199,18 @@ public:
     {
         cb.NoteXPCOMChild(mRuleNode);
         cb.NoteXPCOMChild(mAction);
     }
 
 protected:
 
     struct Binding {
-        nsCOMPtr<nsIAtom>        mSourceVariable;
-        nsCOMPtr<nsIAtom>        mTargetVariable;
+        RefPtr<nsIAtom>        mSourceVariable;
+        RefPtr<nsIAtom>        mTargetVariable;
         nsString                 mExpr;
         Binding*                 mNext;
         Binding*                 mParent;
     };
 
     // backreference to the query set which owns this rule
     nsTemplateQuerySet* mQuerySet;
 
@@ -221,23 +221,23 @@ protected:
     // which contains the content to generate
     nsCOMPtr<nsIContent> mAction;
 
     // the rule filter set by the builder's SetRuleFilter function
     nsCOMPtr<nsIXULTemplateRuleFilter> mRuleFilter;
 
     // indicates that the rule will only match when generating content
     // to be inserted into a container with this tag
-    nsCOMPtr<nsIAtom> mTag;
+    RefPtr<nsIAtom> mTag;
 
     // linked-list of the bindings for the rule, owned by the rule.
     Binding* mBindings;
 
-    nsCOMPtr<nsIAtom> mRefVariable;
-    nsCOMPtr<nsIAtom> mMemberVariable;
+    RefPtr<nsIAtom> mRefVariable;
+    RefPtr<nsIAtom> mMemberVariable;
 
     nsTemplateCondition* mConditions; // owned by nsTemplateRule
 };
 
 /** nsTemplateQuerySet
  *
  *  A single <queryset> which holds the query node and the rules for it.
  *  All builders have at least one queryset, which may be created with an
@@ -262,17 +262,17 @@ public:
     nsCOMPtr<nsIContent> mQueryNode;
 
     // compiled opaque query object returned by the query processor's
     // CompileQuery call
     nsCOMPtr<nsISupports> mCompiledQuery;
 
     // indicates that the query will only generate content to be inserted into
     // a container with this tag
-    nsCOMPtr<nsIAtom> mTag;
+    RefPtr<nsIAtom> mTag;
 
     explicit nsTemplateQuerySet(int32_t aPriority)
         : mPriority(aPriority)
     {
         MOZ_COUNT_CTOR(nsTemplateQuerySet);
     }
 
     ~nsTemplateQuerySet()
--- a/dom/xul/templates/nsXMLBinding.h
+++ b/dom/xul/templates/nsXMLBinding.h
@@ -23,17 +23,17 @@ class XPathResult;
 /**
  * Classes related to storing bindings for XML handling.
  */
 
 /**
  * a <binding> description
  */
 struct nsXMLBinding {
-  nsCOMPtr<nsIAtom> mVar;
+  RefPtr<nsIAtom> mVar;
   nsAutoPtr<mozilla::dom::XPathExpression> mExpr;
 
   nsAutoPtr<nsXMLBinding> mNext;
 
   nsXMLBinding(nsIAtom* aVar, nsAutoPtr<mozilla::dom::XPathExpression>&& aExpr)
     : mVar(aVar), mExpr(aExpr), mNext(nullptr)
   {
     MOZ_COUNT_CTOR(nsXMLBinding);
--- a/dom/xul/templates/nsXULContentBuilder.cpp
+++ b/dom/xul/templates/nsXULContentBuilder.cpp
@@ -727,17 +727,17 @@ nsXULContentBuilder::CopyAttributesToEle
     // Copy all attributes from the template to the new element
     uint32_t numAttribs = aTemplateNode->GetAttrCount();
 
     for (uint32_t attr = 0; attr < numAttribs; attr++) {
         const nsAttrName* name = aTemplateNode->GetAttrNameAt(attr);
         int32_t attribNameSpaceID = name->NamespaceID();
         // Hold a strong reference here so that the atom doesn't go away
         // during UnsetAttr.
-        nsCOMPtr<nsIAtom> attribName = name->LocalName();
+        RefPtr<nsIAtom> attribName = name->LocalName();
 
         // XXXndeakin ignore namespaces until bug 321182 is fixed
         if (attribName != nsGkAtoms::id && attribName != nsGkAtoms::uri) {
             nsAutoString attribValue;
             aTemplateNode->GetAttr(attribNameSpaceID, attribName, attribValue);
             if (!attribValue.IsEmpty()) {
                 nsAutoString value;
                 rv = SubstituteText(aResult, attribValue, value);
@@ -796,17 +796,17 @@ nsXULContentBuilder::AddPersistentAttrib
             persist.Truncate();
         }
 
         attribute.Trim(" ");
 
         if (attribute.IsEmpty())
             break;
 
-        nsCOMPtr<nsIAtom> tag;
+        RefPtr<nsIAtom> tag;
         int32_t nameSpaceID;
 
         RefPtr<mozilla::dom::NodeInfo> ni =
             aTemplateNode->GetExistingAttrNameFromQName(attribute);
         if (ni) {
             tag = ni->NameAtom();
             nameSpaceID = ni->NamespaceID();
         }
@@ -1769,17 +1769,17 @@ nsXULContentBuilder::CompareResultToNode
         nsresult rv = mQueryProcessor->CompareResults(aResult, match->mResult,
                                                       nullptr, mSortState.sortHints,
                                                       aSortOrder);
         NS_ENSURE_SUCCESS(rv, rv);
     }
     else {
         // iterate over each sort key and compare. If the nodes are equal,
         // continue to compare using the next sort key. If not equal, stop.
-        int32_t length = mSortState.sortKeys.Count();
+        int32_t length = mSortState.sortKeys.Length();
         for (int32_t t = 0; t < length; t++) {
             nsresult rv = mQueryProcessor->CompareResults(aResult, match->mResult,
                                                           mSortState.sortKeys[t],
                                                           mSortState.sortHints, aSortOrder);
             NS_ENSURE_SUCCESS(rv, rv);
 
             if (*aSortOrder)
                 break;
--- a/dom/xul/templates/nsXULSortService.cpp
+++ b/dom/xul/templates/nsXULSortService.cpp
@@ -39,17 +39,17 @@ XULSortServiceImpl::SetSortHints(nsICont
     direction.AssignLiteral("descending");
   else if (aSortState->direction == nsSortState_ascending)
     direction.AssignLiteral("ascending");
   aNode->SetAttr(kNameSpaceID_None, nsGkAtoms::sortDirection,
                  direction, true);
 
   // for trees, also set the sort info on the currently sorted column
   if (aNode->NodeInfo()->Equals(nsGkAtoms::tree, kNameSpaceID_XUL)) {
-    if (aSortState->sortKeys.Count() >= 1) {
+    if (aSortState->sortKeys.Length() >= 1) {
       nsAutoString sortkey;
       aSortState->sortKeys[0]->ToString(sortkey);
       SetSortColumnHints(aNode, sortkey, direction);
     }
   }
 }
 
 void
@@ -179,17 +179,17 @@ testSortCallback(const void *data1, cons
   int32_t sortOrder = 0;
 
   if (sortState->direction == nsSortState_natural && sortState->processor) {
     // sort in natural order
     sortState->processor->CompareResults(left->result, right->result,
                                          nullptr, sortState->sortHints, &sortOrder);
   }
   else {
-    int32_t length = sortState->sortKeys.Count();
+    int32_t length = sortState->sortKeys.Length();
     for (int32_t t = 0; t < length; t++) {
       // for templates, use the query processor to do sorting
       if (sortState->processor) {
         sortState->processor->CompareResults(left->result, right->result,
                                              sortState->sortKeys[t],
                                              sortState->sortHints, &sortOrder);
         if (sortOrder)
           break;
@@ -342,35 +342,35 @@ XULSortServiceImpl::InitializeSortState(
   // The latter is for backwards compatibility, and is equivalent to concatenating
   // both values in the sort attribute
   nsAutoString sort(aSortKey);
   aSortState->sortKeys.Clear();
   if (sort.IsEmpty()) {
     nsAutoString sortResource, sortResource2;
     aRootElement->GetAttr(kNameSpaceID_None, nsGkAtoms::sortResource, sortResource);
     if (!sortResource.IsEmpty()) {
-      nsCOMPtr<nsIAtom> sortkeyatom = NS_Atomize(sortResource);
-      aSortState->sortKeys.AppendObject(sortkeyatom);
+      RefPtr<nsIAtom> sortkeyatom = NS_Atomize(sortResource);
+      aSortState->sortKeys.AppendElement(sortkeyatom);
       sort.Append(sortResource);
 
       aRootElement->GetAttr(kNameSpaceID_None, nsGkAtoms::sortResource2, sortResource2);
       if (!sortResource2.IsEmpty()) {
-        nsCOMPtr<nsIAtom> sortkeyatom2 = NS_Atomize(sortResource2);
-        aSortState->sortKeys.AppendObject(sortkeyatom2);
+        RefPtr<nsIAtom> sortkeyatom2 = NS_Atomize(sortResource2);
+        aSortState->sortKeys.AppendElement(sortkeyatom2);
         sort.Append(' ');
         sort.Append(sortResource2);
       }
     }
   }
   else {
     nsWhitespaceTokenizer tokenizer(sort);
     while (tokenizer.hasMoreTokens()) {
-      nsCOMPtr<nsIAtom> keyatom = NS_Atomize(tokenizer.nextToken());
+      RefPtr<nsIAtom> keyatom = NS_Atomize(tokenizer.nextToken());
       NS_ENSURE_TRUE(keyatom, NS_ERROR_OUT_OF_MEMORY);
-      aSortState->sortKeys.AppendObject(keyatom);
+      aSortState->sortKeys.AppendElement(keyatom);
     }
   }
 
   aSortState->sort.Assign(sort);
   aSortState->direction = nsSortState_natural;
 
   bool noNaturalState = false;
   nsWhitespaceTokenizer tokenizer(aSortHints);
--- a/dom/xul/templates/nsXULSortService.h
+++ b/dom/xul/templates/nsXULSortService.h
@@ -33,17 +33,17 @@ struct nsSortState
   MOZ_INIT_OUTSIDE_CTOR bool inbetweenSeparatorSort;
   MOZ_INIT_OUTSIDE_CTOR bool sortStaticsLast;
   MOZ_INIT_OUTSIDE_CTOR bool isContainerRDFSeq;
 
   uint32_t sortHints;
 
   MOZ_INIT_OUTSIDE_CTOR nsSortState_direction direction;
   nsAutoString sort;
-  nsCOMArray<nsIAtom> sortKeys;
+  nsTArray<RefPtr<nsIAtom>> sortKeys;
 
   nsCOMPtr<nsIXULTemplateQueryProcessor> processor;
   nsCOMPtr<nsIContent> lastContainer;
   MOZ_INIT_OUTSIDE_CTOR bool lastWasFirst, lastWasLast;
 
   nsSortState()
     : initialized(false),
       isContainerRDFSeq(false),
--- a/dom/xul/templates/nsXULTemplateBuilder.cpp
+++ b/dom/xul/templates/nsXULTemplateBuilder.cpp
@@ -1690,17 +1690,17 @@ nsXULTemplateBuilder::SubstituteTextRepl
     nsAutoString replacementText;
 
     // The symbol "rdf:*" is special, and means "this guy's URI"
     if (aVariable.EqualsLiteral("rdf:*")){
         c->result->GetId(replacementText);
     }
     else {
         // Got a variable; get the value it's assigned to
-        nsCOMPtr<nsIAtom> var = NS_Atomize(aVariable);
+        RefPtr<nsIAtom> var = NS_Atomize(aVariable);
         c->result->GetBindingFor(var, replacementText);
     }
 
     c->str += replacementText;
 }
 
 bool
 nsXULTemplateBuilder::IsTemplateElement(nsIContent* aContent)
@@ -1928,27 +1928,27 @@ nsXULTemplateBuilder::CompileTemplate(ns
         if (ni->Equals(nsGkAtoms::rule, kNameSpaceID_XUL)) {
             nsCOMPtr<nsIContent> action;
             nsXULContentUtils::FindChildByTag(rulenode,
                                               kNameSpaceID_XUL,
                                               nsGkAtoms::action,
                                               getter_AddRefs(action));
 
             if (action){
-                nsCOMPtr<nsIAtom> memberVariable = mMemberVariable;
+                RefPtr<nsIAtom> memberVariable = mMemberVariable;
                 if (!memberVariable) {
                     memberVariable = DetermineMemberVariable(action);
                     if (!memberVariable) {
                         nsXULContentUtils::LogTemplateError(ERROR_TEMPLATE_NO_MEMBERVAR);
                         continue;
                     }
                 }
 
                 if (hasQuery) {
-                    nsCOMPtr<nsIAtom> tag;
+                    RefPtr<nsIAtom> tag;
                     DetermineRDFQueryRef(aQuerySet->mQueryNode,
                                          getter_AddRefs(tag));
                     if (tag)
                         aQuerySet->SetTag(tag);
 
                     if (! aQuerySet->mCompiledQuery) {
                         nsCOMPtr<nsIDOMNode> query(do_QueryInterface(aQuerySet->mQueryNode));
 
@@ -1984,17 +1984,17 @@ nsXULTemplateBuilder::CompileTemplate(ns
                         if (hasQuerySet) {
                             aQuerySet = new nsTemplateQuerySet(++*aPriority);
                             if (!mQuerySets.AppendElement(aQuerySet)) {
                                 delete aQuerySet;
                                 return NS_ERROR_OUT_OF_MEMORY;
                             }
                         }
 
-                        nsCOMPtr<nsIAtom> tag;
+                        RefPtr<nsIAtom> tag;
                         DetermineRDFQueryRef(conditions, getter_AddRefs(tag));
                         if (tag)
                             aQuerySet->SetTag(tag);
 
                         hasQuerySet = true;
 
                         nsCOMPtr<nsIDOMNode> conditionsnode(do_QueryInterface(conditions));
 
@@ -2046,22 +2046,22 @@ nsXULTemplateBuilder::CompileTemplate(ns
             aQuerySet->mQueryNode = rulenode;
             hasQuery = true;
         }
         else if (ni->Equals(nsGkAtoms::action, kNameSpaceID_XUL)) {
             // the query must appear before the action
             if (! hasQuery)
                 continue;
 
-            nsCOMPtr<nsIAtom> tag;
+            RefPtr<nsIAtom> tag;
             DetermineRDFQueryRef(aQuerySet->mQueryNode, getter_AddRefs(tag));
             if (tag)
                 aQuerySet->SetTag(tag);
 
-            nsCOMPtr<nsIAtom> memberVariable = mMemberVariable;
+            RefPtr<nsIAtom> memberVariable = mMemberVariable;
             if (!memberVariable) {
                 memberVariable = DetermineMemberVariable(rulenode);
                 if (!memberVariable) {
                     nsXULContentUtils::LogTemplateError(ERROR_TEMPLATE_NO_MEMBERVAR);
                     continue;
                 }
             }
 
@@ -2153,17 +2153,17 @@ nsXULTemplateBuilder::DetermineMemberVar
          child;
          child = child->GetNextSibling()) {
         nsAutoString uri;
         child->GetAttr(kNameSpaceID_None, nsGkAtoms::uri, uri);
         if (!uri.IsEmpty() && uri[0] == char16_t('?')) {
             return NS_Atomize(uri);
         }
 
-        nsCOMPtr<nsIAtom> result = DetermineMemberVariable(child);
+        RefPtr<nsIAtom> result = DetermineMemberVariable(child);
         if (result) {
             return result.forget();
         }
     }
 
     return nullptr;
 }
 
@@ -2204,17 +2204,17 @@ nsresult
 nsXULTemplateBuilder::CompileSimpleQuery(nsIContent* aRuleElement,
                                          nsTemplateQuerySet* aQuerySet,
                                          bool* aCanUseTemplate)
 {
     // compile a simple query, which is a query with no <query> or
     // <conditions>. This means that a default query is used.
     nsCOMPtr<nsIDOMNode> query(do_QueryInterface(aRuleElement));
 
-    nsCOMPtr<nsIAtom> memberVariable;
+    RefPtr<nsIAtom> memberVariable;
     if (mMemberVariable)
         memberVariable = mMemberVariable;
     else
         memberVariable = NS_Atomize("rdf:*");
 
     // since there is no <query> node for a simple query, the query node will
     // be either the <rule> node if multiple rules are used, or the <template> node.
     aQuerySet->mQueryNode = aRuleElement;
@@ -2234,34 +2234,34 @@ nsXULTemplateBuilder::CompileSimpleQuery
         return NS_ERROR_OUT_OF_MEMORY;
 
     rule->SetVars(mRefVariable, memberVariable);
 
     nsAutoString tag;
     aRuleElement->GetAttr(kNameSpaceID_None, nsGkAtoms::parent, tag);
 
     if (!tag.IsEmpty()) {
-        nsCOMPtr<nsIAtom> tagatom = NS_Atomize(tag);
+        RefPtr<nsIAtom> tagatom = NS_Atomize(tag);
         aQuerySet->SetTag(tagatom);
     }
 
     *aCanUseTemplate = true;
 
     return AddSimpleRuleBindings(rule, aRuleElement);
 }
 
 nsresult
 nsXULTemplateBuilder::CompileConditions(nsTemplateRule* aRule,
                                         nsIContent* aCondition)
 {
     nsAutoString tag;
     aCondition->GetAttr(kNameSpaceID_None, nsGkAtoms::parent, tag);
 
     if (!tag.IsEmpty()) {
-        nsCOMPtr<nsIAtom> tagatom = NS_Atomize(tag);
+        RefPtr<nsIAtom> tagatom = NS_Atomize(tag);
         aRule->SetTag(tagatom);
     }
 
     nsTemplateCondition* currentCondition = nullptr;
 
     for (nsIContent* node = aCondition->GetFirstChild();
          node;
          node = node->GetNextSibling()) {
@@ -2298,17 +2298,17 @@ nsXULTemplateBuilder::CompileWhereCondit
     // subject
     nsAutoString subject;
     aCondition->GetAttr(kNameSpaceID_None, nsGkAtoms::subject, subject);
     if (subject.IsEmpty()) {
         nsXULContentUtils::LogTemplateError(ERROR_TEMPLATE_WHERE_NO_SUBJECT);
         return NS_OK;
     }
 
-    nsCOMPtr<nsIAtom> svar;
+    RefPtr<nsIAtom> svar;
     if (subject[0] == char16_t('?'))
         svar = NS_Atomize(subject);
 
     nsAutoString relstring;
     aCondition->GetAttr(kNameSpaceID_None, nsGkAtoms::rel, relstring);
     if (relstring.IsEmpty()) {
         nsXULContentUtils::LogTemplateError(ERROR_TEMPLATE_WHERE_NO_RELATION);
         return NS_OK;
@@ -2322,17 +2322,17 @@ nsXULTemplateBuilder::CompileWhereCondit
         return NS_OK;
     }
 
     // multiple
     bool shouldMultiple =
       aCondition->AttrValueIs(kNameSpaceID_None, nsGkAtoms::multiple,
                               nsGkAtoms::_true, eCaseMatters);
 
-    nsCOMPtr<nsIAtom> vvar;
+    RefPtr<nsIAtom> vvar;
     if (!shouldMultiple && (value[0] == char16_t('?'))) {
         vvar = NS_Atomize(value);
     }
 
     // ignorecase
     bool shouldIgnoreCase =
       aCondition->AttrValueIs(kNameSpaceID_None, nsGkAtoms::ignorecase,
                               nsGkAtoms::_true, eCaseMatters);
@@ -2413,17 +2413,17 @@ nsXULTemplateBuilder::CompileBinding(nsT
     // subject
     nsAutoString subject;
     aBinding->GetAttr(kNameSpaceID_None, nsGkAtoms::subject, subject);
     if (subject.IsEmpty()) {
         nsXULContentUtils::LogTemplateError(ERROR_TEMPLATE_BINDING_BAD_SUBJECT);
         return NS_OK;
     }
 
-    nsCOMPtr<nsIAtom> svar;
+    RefPtr<nsIAtom> svar;
     if (subject[0] == char16_t('?')) {
         svar = NS_Atomize(subject);
     }
     else {
         nsXULContentUtils::LogTemplateError(ERROR_TEMPLATE_BINDING_BAD_SUBJECT);
         return NS_OK;
     }
 
@@ -2439,17 +2439,17 @@ nsXULTemplateBuilder::CompileBinding(nsT
     nsAutoString object;
     aBinding->GetAttr(kNameSpaceID_None, nsGkAtoms::object, object);
 
     if (object.IsEmpty()) {
         nsXULContentUtils::LogTemplateError(ERROR_TEMPLATE_BINDING_BAD_OBJECT);
         return NS_OK;
     }
 
-    nsCOMPtr<nsIAtom> ovar;
+    RefPtr<nsIAtom> ovar;
     if (object[0] == char16_t('?')) {
         ovar = NS_Atomize(object);
     }
     else {
         nsXULContentUtils::LogTemplateError(ERROR_TEMPLATE_BINDING_BAD_OBJECT);
         return NS_OK;
     }
 
@@ -2514,17 +2514,17 @@ nsXULTemplateBuilder::AddBindingsFor(nsX
 {
     // We should *only* be recieving "rdf:"-style variables. Make
     // sure...
     if (!StringBeginsWith(aVariable, NS_LITERAL_STRING("rdf:")))
         return;
 
     nsTemplateRule* rule = static_cast<nsTemplateRule*>(aClosure);
 
-    nsCOMPtr<nsIAtom> var = NS_Atomize(aVariable);
+    RefPtr<nsIAtom> var = NS_Atomize(aVariable);
 
     // Strip it down to the raw RDF property by clobbering the "rdf:"
     // prefix
     nsAutoString property;
     property.Assign(Substring(aVariable, uint32_t(4), aVariable.Length() - 4));
 
     if (! rule->HasBinding(rule->GetMemberVariable(), property, var))
         // In the simple syntax, the binding is always from the
--- a/dom/xul/templates/nsXULTemplateBuilder.h
+++ b/dom/xul/templates/nsXULTemplateBuilder.h
@@ -418,18 +418,18 @@ protected:
     /**
      * Set to true if the rules have already been compiled
      */
     bool          mQueriesCompiled;
 
     /**
      * The default reference and member variables.
      */
-    nsCOMPtr<nsIAtom> mRefVariable;
-    nsCOMPtr<nsIAtom> mMemberVariable;
+    RefPtr<nsIAtom> mRefVariable;
+    RefPtr<nsIAtom> mMemberVariable;
 
     /**
      * The match map contains nsTemplateMatch objects, one for each unique
      * match found, keyed by the resource for that match. A particular match
      * will contain a linked list of all of the matches for that unique result
      * id. Only one is active at a time. When a match is retracted, look in
      * the match map, remove it, and apply the next valid match in sequence to
      * make active.
--- a/dom/xul/templates/nsXULTemplateQueryProcessorRDF.cpp
+++ b/dom/xul/templates/nsXULTemplateQueryProcessorRDF.cpp
@@ -1181,17 +1181,17 @@ nsXULTemplateQueryProcessorRDF::CompileE
                 continue;
             }
 
             // check for <content tag='tag'/> which indicates that matches
             // should only be generated for items inside content with that tag
             nsAutoString tagstr;
             condition->GetAttr(kNameSpaceID_None, nsGkAtoms::tag, tagstr);
 
-            nsCOMPtr<nsIAtom> tag;
+            RefPtr<nsIAtom> tag;
             if (! tagstr.IsEmpty()) {
                 tag = NS_Atomize(tagstr);
             }
 
             nsCOMPtr<nsIDOMDocument> doc = do_QueryInterface(condition->GetComposedDoc());
             if (! doc)
                 return NS_ERROR_FAILURE;
 
@@ -1291,17 +1291,17 @@ nsXULTemplateQueryProcessorRDF::CompileT
     //
     // XXXwaterson Some day it would be cool to allow the 'predicate'
     // to be bound to a variable.
 
     // subject
     nsAutoString subject;
     aCondition->GetAttr(kNameSpaceID_None, nsGkAtoms::subject, subject);
 
-    nsCOMPtr<nsIAtom> svar;
+    RefPtr<nsIAtom> svar;
     nsCOMPtr<nsIRDFResource> sres;
     if (subject.IsEmpty()) {
         nsXULContentUtils::LogTemplateError(ERROR_TEMPLATE_TRIPLE_BAD_SUBJECT);
         return NS_OK;
     }
     if (subject[0] == char16_t('?'))
         svar = NS_Atomize(subject);
     else
@@ -1317,17 +1317,17 @@ nsXULTemplateQueryProcessorRDF::CompileT
         return NS_OK;
     }
     gRDFService->GetUnicodeResource(predicate, getter_AddRefs(pres));
 
     // object
     nsAutoString object;
     aCondition->GetAttr(kNameSpaceID_None, nsGkAtoms::object, object);
 
-    nsCOMPtr<nsIAtom> ovar;
+    RefPtr<nsIAtom> ovar;
     nsCOMPtr<nsIRDFNode> onode;
     if (object.IsEmpty()) {
         nsXULContentUtils::LogTemplateError(ERROR_TEMPLATE_TRIPLE_BAD_OBJECT);
         return NS_OK;
     }
 
     if (object[0] == char16_t('?')) {
         ovar = NS_Atomize(object);
@@ -1394,28 +1394,28 @@ nsXULTemplateQueryProcessorRDF::CompileM
     nsAutoString container;
     aCondition->GetAttr(kNameSpaceID_None, nsGkAtoms::container, container);
 
     if (!container.IsEmpty() && container[0] != char16_t('?')) {
         nsXULContentUtils::LogTemplateError(ERROR_TEMPLATE_MEMBER_NOCONTAINERVAR);
         return NS_OK;
     }
 
-    nsCOMPtr<nsIAtom> containervar = NS_Atomize(container);
+    RefPtr<nsIAtom> containervar = NS_Atomize(container);
 
     // child
     nsAutoString child;
     aCondition->GetAttr(kNameSpaceID_None, nsGkAtoms::child, child);
 
     if (!child.IsEmpty() && child[0] != char16_t('?')) {
         nsXULContentUtils::LogTemplateError(ERROR_TEMPLATE_MEMBER_NOCHILDVAR);
         return NS_OK;
     }
 
-    nsCOMPtr<nsIAtom> childvar = NS_Atomize(child);
+    RefPtr<nsIAtom> childvar = NS_Atomize(child);
 
     TestNode* testnode =
         new nsRDFConMemberTestNode(aParentNode,
                                    this,
                                    containervar,
                                    childvar);
 
     // add testnode to mAllTests first. If adding to mRDFTests fails, just
--- a/dom/xul/templates/nsXULTemplateQueryProcessorRDF.h
+++ b/dom/xul/templates/nsXULTemplateQueryProcessorRDF.h
@@ -287,17 +287,17 @@ protected:
     // containment properties that are checked to determine if a resource is
     // a container
     nsResourceSet mContainmentProperties;
 
     // the end node of the default simple node hierarchy
     TestNode* mSimpleRuleMemberTest;
 
     // the reference variable
-    nsCOMPtr<nsIAtom> mRefVariable;
+    RefPtr<nsIAtom> mRefVariable;
 
     // the last ref that was calculated, used for simple rules
     nsCOMPtr<nsIXULTemplateResult> mLastRef;
 
     /**
      * A map between nsIRDFNodes that form the left-hand side (the subject) of
      * a <binding> and an array of nsIXULTemplateResults. When a new assertion
      * is added to the graph involving a particular rdf node, it is looked up
--- a/dom/xul/templates/nsXULTemplateQueryProcessorStorage.cpp
+++ b/dom/xul/templates/nsXULTemplateQueryProcessorStorage.cpp
@@ -45,18 +45,18 @@ nsXULTemplateResultSetStorage::nsXULTemp
     if (NS_FAILED(rv)) {
         mStatement = nullptr;
         return;
     }
     for (uint32_t c = 0; c < count; c++) {
         nsAutoCString name;
         rv = aStatement->GetColumnName(c, name);
         if (NS_SUCCEEDED(rv)) {
-            nsCOMPtr<nsIAtom> columnName = NS_Atomize(NS_LITERAL_CSTRING("?") + name);
-            mColumnNames.AppendObject(columnName);
+            RefPtr<nsIAtom> columnName = NS_Atomize(NS_LITERAL_CSTRING("?") + name);
+            mColumnNames.AppendElement(columnName);
         }
     }
 }
 
 NS_IMETHODIMP
 nsXULTemplateResultSetStorage::HasMoreElements(bool *aResult)
 {
     if (!mStatement) {
@@ -84,32 +84,32 @@ nsXULTemplateResultSetStorage::GetNext(n
     NS_ADDREF(result);
     return NS_OK;
 }
 
 
 int32_t
 nsXULTemplateResultSetStorage::GetColumnIndex(nsIAtom* aColumnName)
 {
-    int32_t count = mColumnNames.Count();
+    int32_t count = mColumnNames.Length();
     for (int32_t c = 0; c < count; c++) {
         if (mColumnNames[c] == aColumnName)
             return c;
     }
 
     return -1;
 }
 
 void
 nsXULTemplateResultSetStorage::FillColumnValues(nsCOMArray<nsIVariant>& aArray)
 {
     if (!mStatement)
         return;
 
-    int32_t count = mColumnNames.Count();
+    int32_t count = mColumnNames.Length();
 
     for (int32_t c = 0; c < count; c++) {
         RefPtr<nsVariant> value = new nsVariant();
 
         int32_t type;
         mStatement->GetTypeOfIndex(c, &type);
 
         if (type == mStatement->VALUE_TYPE_INTEGER) {
--- a/dom/xul/templates/nsXULTemplateQueryProcessorStorage.h
+++ b/dom/xul/templates/nsXULTemplateQueryProcessorStorage.h
@@ -21,17 +21,17 @@
 class nsXULTemplateQueryProcessorStorage;
 
 class nsXULTemplateResultSetStorage final : public nsISimpleEnumerator
 {
 private:
 
     nsCOMPtr<mozIStorageStatement> mStatement;
 
-    nsCOMArray<nsIAtom> mColumnNames;
+    nsTArray<RefPtr<nsIAtom>> mColumnNames;
 
     ~nsXULTemplateResultSetStorage() {}
 
 public:
 
     // nsISupports interface
     NS_DECL_ISUPPORTS
 
--- a/dom/xul/templates/nsXULTemplateQueryProcessorXML.cpp
+++ b/dom/xul/templates/nsXULTemplateQueryProcessorXML.cpp
@@ -267,17 +267,17 @@ nsXULTemplateQueryProcessorXML::CompileQ
             // ignore assignments without a variable or an expression
             if (!var.IsEmpty() && !expr.IsEmpty()) {
                 compiledexpr = CreateExpression(expr, condition, rv);
                 if (rv.Failed()) {
                     nsXULContentUtils::LogTemplateError(ERROR_TEMPLATE_BAD_ASSIGN_XPATH);
                     return rv.StealNSResult();
                 }
 
-                nsCOMPtr<nsIAtom> varatom = NS_Atomize(var);
+                RefPtr<nsIAtom> varatom = NS_Atomize(var);
 
                 query->AddBinding(varatom, Move(compiledexpr));
             }
         }
     }
 
     query.forget(_retval);
 
--- a/dom/xul/templates/nsXULTemplateQueryProcessorXML.h
+++ b/dom/xul/templates/nsXULTemplateQueryProcessorXML.h
@@ -69,17 +69,17 @@ class nsXMLQuery final : public nsISuppo
           mResultsExpr(aResultsExpr)
     { }
 
   protected:
     ~nsXMLQuery() {}
 
     nsXULTemplateQueryProcessorXML* mProcessor;
 
-    nsCOMPtr<nsIAtom> mMemberVariable;
+    RefPtr<nsIAtom> mMemberVariable;
 
     nsAutoPtr<mozilla::dom::XPathExpression> mResultsExpr;
 
     RefPtr<nsXMLBindingSet> mRequiredBindings;
 };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(nsXMLQuery, NS_IXMLQUERY_IID)
 
--- a/dom/xul/templates/nsXULTemplateResultXML.cpp
+++ b/dom/xul/templates/nsXULTemplateResultXML.cpp
@@ -19,17 +19,17 @@ NS_IMPL_ISUPPORTS(nsXULTemplateResultXML
 
 nsXULTemplateResultXML::nsXULTemplateResultXML(nsXMLQuery* aQuery,
                                                nsIContent* aNode,
                                                nsXMLBindingSet* aBindings)
     : mQuery(aQuery), mNode(aNode)
 {
     // If the node has an id, create the uri from it. Otherwise, there isn't
     // anything to identify the node with so just use a somewhat random number.
-    nsCOMPtr<nsIAtom> id = mNode->GetID();
+    RefPtr<nsIAtom> id = mNode->GetID();
     if (id) {
       nsCOMPtr<nsIURI> uri = mNode->GetBaseURI();
       nsAutoCString spec;
       uri->GetSpec(spec);
 
       mId = NS_ConvertUTF8toUTF16(spec);
 
       nsAutoString idstr;
--- a/dom/xul/templates/nsXULTreeBuilder.cpp
+++ b/dom/xul/templates/nsXULTreeBuilder.cpp
@@ -1384,17 +1384,17 @@ nsIContent*
 nsXULTreeBuilder::GetTemplateActionCellFor(int32_t aRow, nsTreeColumn& aCol)
 {
     nsCOMPtr<nsIContent> row;
     GetTemplateActionRowFor(aRow, getter_AddRefs(row));
     if (!row) {
         return nullptr;
     }
 
-    nsCOMPtr<nsIAtom> colAtom(aCol.GetAtom());
+    RefPtr<nsIAtom> colAtom(aCol.GetAtom());
     int32_t colIndex(aCol.GetIndex());
 
     nsIContent* result = nullptr;
     uint32_t j = 0;
     for (nsIContent* child = row->GetFirstChild();
          child;
          child = child->GetNextSibling()) {
         if (child->NodeInfo()->Equals(nsGkAtoms::treecell, kNameSpaceID_XUL)) {
--- a/dom/xul/templates/nsXULTreeBuilder.h
+++ b/dom/xul/templates/nsXULTreeBuilder.h
@@ -285,17 +285,17 @@ protected:
     /**
      * The rows in the view
      */
     nsTreeRows mRows;
 
     /**
      * The currently active sort variable
      */
-    nsCOMPtr<nsIAtom> mSortVariable;
+    RefPtr<nsIAtom> mSortVariable;
 
     enum Direction {
         eDirection_Descending = -1,
         eDirection_Natural    =  0,
         eDirection_Ascending  = +1
     };
 
     /**
--- a/editor/composer/nsComposerCommands.cpp
+++ b/editor/composer/nsComposerCommands.cpp
@@ -1591,17 +1591,17 @@ GetListState(mozilla::HTMLEditor* aHTMLE
 
 nsresult
 RemoveOneProperty(mozilla::HTMLEditor* aHTMLEditor,
                   const nsAString& aProp)
 {
   MOZ_ASSERT(aHTMLEditor);
 
   /// XXX Hack alert! Look in nsIEditProperty.h for this
-  nsCOMPtr<nsIAtom> styleAtom = NS_Atomize(aProp);
+  RefPtr<nsIAtom> styleAtom = NS_Atomize(aProp);
   NS_ENSURE_TRUE(styleAtom, NS_ERROR_OUT_OF_MEMORY);
 
   return aHTMLEditor->RemoveInlineProperty(styleAtom, EmptyString());
 }
 
 
 // the name of the attribute here should be the contents of the appropriate
 // tag, e.g. 'b' for bold, 'i' for italics.
@@ -1622,14 +1622,14 @@ RemoveTextProperty(mozilla::HTMLEditor* 
 // tag, e.g. 'b' for bold, 'i' for italics.
 nsresult
 SetTextProperty(mozilla::HTMLEditor* aHTMLEditor,
                 const nsAString& aProp)
 {
   MOZ_ASSERT(aHTMLEditor);
 
   /// XXX Hack alert! Look in nsIEditProperty.h for this
-  nsCOMPtr<nsIAtom> styleAtom = NS_Atomize(aProp);
+  RefPtr<nsIAtom> styleAtom = NS_Atomize(aProp);
   NS_ENSURE_TRUE(styleAtom, NS_ERROR_OUT_OF_MEMORY);
 
   return aHTMLEditor->SetInlineProperty(styleAtom,
                                         EmptyString(), EmptyString());
 }
--- a/editor/libeditor/CSSEditUtils.cpp
+++ b/editor/libeditor/CSSEditUtils.cpp
@@ -315,17 +315,17 @@ CSSEditUtils::~CSSEditUtils()
 
 // Answers true if we have some CSS equivalence for the HTML style defined
 // by aProperty and/or aAttribute for the node aNode
 bool
 CSSEditUtils::IsCSSEditableProperty(nsINode* aNode,
                                     nsIAtom* aProperty,
                                     const nsAString* aAttribute)
 {
-  nsCOMPtr<nsIAtom> attribute = aAttribute ? NS_Atomize(*aAttribute) : nullptr;
+  RefPtr<nsIAtom> attribute = aAttribute ? NS_Atomize(*aAttribute) : nullptr;
   return IsCSSEditableProperty(aNode, aProperty, attribute);
 }
 
 bool
 CSSEditUtils::IsCSSEditableProperty(nsINode* aNode,
                                     nsIAtom* aProperty,
                                     nsIAtom* aAttribute)
 {
@@ -907,17 +907,17 @@ CSSEditUtils::SetCSSEquivalentToHTMLStyl
 
 int32_t
 CSSEditUtils::SetCSSEquivalentToHTMLStyle(Element* aElement,
                                           nsIAtom* aHTMLProperty,
                                           const nsAString* aAttribute,
                                           const nsAString* aValue,
                                           bool aSuppressTransaction)
 {
-  nsCOMPtr<nsIAtom> attribute = aAttribute ? NS_Atomize(*aAttribute) : nullptr;
+  RefPtr<nsIAtom> attribute = aAttribute ? NS_Atomize(*aAttribute) : nullptr;
   return SetCSSEquivalentToHTMLStyle(aElement, aHTMLProperty, attribute,
                                      aValue, aSuppressTransaction);
 }
 
 int32_t
 CSSEditUtils::SetCSSEquivalentToHTMLStyle(Element* aElement,
                                           nsIAtom* aHTMLProperty,
                                           nsIAtom* aAttribute,
@@ -956,17 +956,17 @@ CSSEditUtils::SetCSSEquivalentToHTMLStyl
 nsresult
 CSSEditUtils::RemoveCSSEquivalentToHTMLStyle(nsIDOMNode* aNode,
                                              nsIAtom* aHTMLProperty,
                                              const nsAString* aAttribute,
                                              const nsAString* aValue,
                                              bool aSuppressTransaction)
 {
   nsCOMPtr<Element> element = do_QueryInterface(aNode);
-  nsCOMPtr<nsIAtom> attribute = aAttribute ? NS_Atomize(*aAttribute) : nullptr;
+  RefPtr<nsIAtom> attribute = aAttribute ? NS_Atomize(*aAttribute) : nullptr;
 
   return RemoveCSSEquivalentToHTMLStyle(element, aHTMLProperty, attribute,
                                         aValue, aSuppressTransaction);
 }
 
 nsresult
 CSSEditUtils::RemoveCSSEquivalentToHTMLStyle(Element* aElement,
                                              nsIAtom* aHTMLProperty,
@@ -1070,32 +1070,32 @@ CSSEditUtils::IsCSSEquivalentToHTMLInlin
 bool
 CSSEditUtils::IsCSSEquivalentToHTMLInlineStyleSet(nsINode* aNode,
                                                   nsIAtom* aProperty,
                                                   const nsAString* aAttribute,
                                                   nsAString& aValue,
                                                   StyleType aStyleType)
 {
   MOZ_ASSERT(aNode && aProperty);
-  nsCOMPtr<nsIAtom> attribute = aAttribute ? NS_Atomize(*aAttribute) : nullptr;
+  RefPtr<nsIAtom> attribute = aAttribute ? NS_Atomize(*aAttribute) : nullptr;
   return IsCSSEquivalentToHTMLInlineStyleSet(aNode,
                                              aProperty, attribute,
                                              aValue, aStyleType);
 }
 
 bool
 CSSEditUtils::IsCSSEquivalentToHTMLInlineStyleSet(nsIDOMNode* aNode,
                                                   nsIAtom* aProperty,
                                                   const nsAString* aAttribute,
                                                   nsAString& aValue,
                                                   StyleType aStyleType)
 {
   MOZ_ASSERT(aNode && aProperty);
   nsCOMPtr<nsINode> node = do_QueryInterface(aNode);
-  nsCOMPtr<nsIAtom> attribute = aAttribute ? NS_Atomize(*aAttribute) : nullptr;
+  RefPtr<nsIAtom> attribute = aAttribute ? NS_Atomize(*aAttribute) : nullptr;
   return IsCSSEquivalentToHTMLInlineStyleSet(node, aProperty, attribute,
                                              aValue, aStyleType);
 }
 
 bool
 CSSEditUtils::IsCSSEquivalentToHTMLInlineStyleSet(
                 nsINode* aNode,
                 nsIAtom* aHTMLProperty,
--- a/editor/libeditor/ChangeAttributeTransaction.h
+++ b/editor/libeditor/ChangeAttributeTransaction.h
@@ -47,17 +47,17 @@ public:
 
 private:
   virtual ~ChangeAttributeTransaction();
 
   // The element to operate upon
   nsCOMPtr<dom::Element> mElement;
 
   // The attribute to change
-  nsCOMPtr<nsIAtom> mAttribute;
+  RefPtr<nsIAtom> mAttribute;
 
   // The value to set the attribute to (ignored if mRemoveAttribute==true)
   nsString mValue;
 
   // True if the operation is to remove mAttribute from mElement
   bool mRemoveAttribute;
 
   // True if the mAttribute was set on mElement at the time of execution
--- a/editor/libeditor/ChangeStyleTransaction.h
+++ b/editor/libeditor/ChangeStyleTransaction.h
@@ -94,17 +94,17 @@ private:
    * is false, just remove the style attribute.
    */
   nsresult SetStyle(bool aAttributeWasSet, nsAString& aValue);
 
   // The element to operate upon.
   nsCOMPtr<dom::Element> mElement;
 
   // The CSS property to change.
-  nsCOMPtr<nsIAtom> mProperty;
+  RefPtr<nsIAtom> mProperty;
 
   // The value to set the property to (ignored if mRemoveProperty==true).
   nsString mValue;
 
   // true if the operation is to remove mProperty from mElement.
   bool mRemoveProperty;
 
   // The value to set the property to for undo.
--- a/editor/libeditor/CreateElementTransaction.h
+++ b/editor/libeditor/CreateElementTransaction.h
@@ -55,17 +55,17 @@ public:
 
 protected:
   virtual ~CreateElementTransaction();
 
   // The document into which the new node will be inserted.
   RefPtr<EditorBase> mEditorBase;
 
   // The tag (mapping to object type) for the new element.
-  nsCOMPtr<nsIAtom> mTag;
+  RefPtr<nsIAtom> mTag;
 
   // The node into which the new node will be inserted.
   nsCOMPtr<nsINode> mParent;
 
   // The index in mParent for the new node.
   int32_t mOffsetInParent;
 
   // The new node to insert.
--- a/editor/libeditor/EditAggregateTransaction.h
+++ b/editor/libeditor/EditAggregateTransaction.h
@@ -45,14 +45,14 @@ public:
    * Get the name assigned to this transaction.
    */
   NS_IMETHOD GetName(nsIAtom** aName);
 
 protected:
   virtual ~EditAggregateTransaction();
 
   nsTArray<RefPtr<EditTransactionBase>> mChildren;
-  nsCOMPtr<nsIAtom> mName;
+  RefPtr<nsIAtom> mName;
 };
 
 } // namespace mozilla
 
 #endif // #ifndef EditAggregateTransaction_h
--- a/editor/libeditor/EditorBase.cpp
+++ b/editor/libeditor/EditorBase.cpp
@@ -1250,17 +1250,17 @@ EditorBase::SetAttribute(nsIDOMElement* 
                          const nsAString& aAttribute,
                          const nsAString& aValue)
 {
   if (NS_WARN_IF(aAttribute.IsEmpty())) {
     return NS_ERROR_FAILURE;
   }
   nsCOMPtr<Element> element = do_QueryInterface(aElement);
   NS_ENSURE_TRUE(element, NS_ERROR_NULL_POINTER);
-  nsCOMPtr<nsIAtom> attribute = NS_Atomize(aAttribute);
+  RefPtr<nsIAtom> attribute = NS_Atomize(aAttribute);
 
   return SetAttribute(element, attribute, aValue);
 }
 
 nsresult
 EditorBase::SetAttribute(Element* aElement,
                          nsIAtom* aAttribute,
                          const nsAString& aValue)
@@ -1295,17 +1295,17 @@ NS_IMETHODIMP
 EditorBase::RemoveAttribute(nsIDOMElement* aElement,
                             const nsAString& aAttribute)
 {
   if (NS_WARN_IF(aAttribute.IsEmpty())) {
     return NS_ERROR_FAILURE;
   }
   nsCOMPtr<Element> element = do_QueryInterface(aElement);
   NS_ENSURE_TRUE(element, NS_ERROR_NULL_POINTER);
-  nsCOMPtr<nsIAtom> attribute = NS_Atomize(aAttribute);
+  RefPtr<nsIAtom> attribute = NS_Atomize(aAttribute);
 
   return RemoveAttribute(element, attribute);
 }
 
 nsresult
 EditorBase::RemoveAttribute(Element* aElement,
                             nsIAtom* aAttribute)
 {
@@ -1409,17 +1409,17 @@ EditorBase::SetSpellcheckUserOverride(bo
 }
 
 NS_IMETHODIMP
 EditorBase::CreateNode(const nsAString& aTag,
                        nsIDOMNode* aParent,
                        int32_t aPosition,
                        nsIDOMNode** aNewNode)
 {
-  nsCOMPtr<nsIAtom> tag = NS_Atomize(aTag);
+  RefPtr<nsIAtom> tag = NS_Atomize(aTag);
   nsCOMPtr<nsINode> parent = do_QueryInterface(aParent);
   NS_ENSURE_STATE(parent);
   *aNewNode = GetAsDOMNode(CreateNode(tag, parent, aPosition).take());
   NS_ENSURE_STATE(*aNewNode);
   return NS_OK;
 }
 
 already_AddRefed<Element>
@@ -2279,17 +2279,17 @@ EditorBase::CloneAttribute(const nsAStri
   if (NS_WARN_IF(aAttribute.IsEmpty())) {
     return NS_ERROR_FAILURE;
   }
 
   nsCOMPtr<Element> destElement = do_QueryInterface(aDestNode);
   nsCOMPtr<Element> sourceElement = do_QueryInterface(aSourceNode);
   NS_ENSURE_TRUE(destElement && sourceElement, NS_ERROR_NO_INTERFACE);
 
-  nsCOMPtr<nsIAtom> attribute = NS_Atomize(aAttribute);
+  RefPtr<nsIAtom> attribute = NS_Atomize(aAttribute);
   return CloneAttribute(attribute, destElement, sourceElement);
 }
 
 nsresult
 EditorBase::CloneAttribute(nsIAtom* aAttribute,
                            Element* aDestElement,
                            Element* aSourceElement)
 {
@@ -4731,31 +4731,31 @@ EditorBase::SetAttributeOrEquivalent(nsI
                                      const nsAString& aAttribute,
                                      const nsAString& aValue,
                                      bool aSuppressTransaction)
 {
   nsCOMPtr<Element> element = do_QueryInterface(aElement);
   if (NS_WARN_IF(!element)) {
     return NS_ERROR_NULL_POINTER;
   }
-  nsCOMPtr<nsIAtom> attribute = NS_Atomize(aAttribute);
+  RefPtr<nsIAtom> attribute = NS_Atomize(aAttribute);
   return SetAttributeOrEquivalent(element, attribute, aValue,
                                   aSuppressTransaction);
 }
 
 NS_IMETHODIMP
 EditorBase::RemoveAttributeOrEquivalent(nsIDOMElement* aElement,
                                         const nsAString& aAttribute,
                                         bool aSuppressTransaction)
 {
   nsCOMPtr<Element> element = do_QueryInterface(aElement);
   if (NS_WARN_IF(!element)) {
     return NS_ERROR_NULL_POINTER;
   }
-  nsCOMPtr<nsIAtom> attribute = NS_Atomize(aAttribute);
+  RefPtr<nsIAtom> attribute = NS_Atomize(aAttribute);
   return RemoveAttributeOrEquivalent(element, attribute, aSuppressTransaction);
 }
 
 nsresult
 EditorBase::HandleKeyPressEvent(WidgetKeyboardEvent* aKeyboardEvent)
 {
   // NOTE: When you change this method, you should also change:
   //   * editor/libeditor/tests/test_texteditor_keyevent_handling.html
--- a/editor/libeditor/HTMLAnonymousNodeEditor.cpp
+++ b/editor/libeditor/HTMLAnonymousNodeEditor.cpp
@@ -354,17 +354,17 @@ HTMLEditor::CheckSelectionStateForAnonym
     return NS_OK;
   }
 
   // what's its tag?
   nsAutoString focusTagName;
   rv = focusElement->GetTagName(focusTagName);
   NS_ENSURE_SUCCESS(rv, rv);
   ToLowerCase(focusTagName);
-  nsCOMPtr<nsIAtom> focusTagAtom = NS_Atomize(focusTagName);
+  RefPtr<nsIAtom> focusTagAtom = NS_Atomize(focusTagName);
 
   nsCOMPtr<nsIDOMElement> absPosElement;
   if (mIsAbsolutelyPositioningEnabled) {
     // Absolute Positioning support is enabled, is the selection contained
     // in an absolutely positioned element ?
     rv =
       GetAbsolutelyPositionedSelectionContainer(getter_AddRefs(absPosElement));
     NS_ENSURE_SUCCESS(rv, rv);
--- a/editor/libeditor/HTMLEditRules.cpp
+++ b/editor/libeditor/HTMLEditRules.cpp
@@ -991,17 +991,17 @@ HTMLEditRules::GetIndentState(bool* aCan
       nsIAtom& marginProperty =
         MarginPropertyAtomForIndent(*mHTMLEditor->mCSSEditUtils, curNode);
       nsAutoString value;
       // retrieve its specified value
       NS_ENSURE_STATE(mHTMLEditor);
       mHTMLEditor->mCSSEditUtils->GetSpecifiedProperty(*curNode,
                                                        marginProperty, value);
       float f;
-      nsCOMPtr<nsIAtom> unit;
+      RefPtr<nsIAtom> unit;
       // get its number part and its unit
       NS_ENSURE_STATE(mHTMLEditor);
       mHTMLEditor->mCSSEditUtils->ParseLength(value, &f, getter_AddRefs(unit));
       // if the number part is strictly positive, outdent is possible
       if (0 < f) {
         *aCanOutdent = true;
         break;
       }
@@ -1181,17 +1181,17 @@ HTMLEditRules::AppendInnerFormatNodes(ns
 
 nsresult
 HTMLEditRules::GetFormatString(nsIDOMNode* aNode,
                                nsAString& outFormat)
 {
   NS_ENSURE_TRUE(aNode, NS_ERROR_NULL_POINTER);
 
   if (HTMLEditUtils::IsFormatNode(aNode)) {
-    nsCOMPtr<nsIAtom> atom = EditorBase::GetTag(aNode);
+    RefPtr<nsIAtom> atom = EditorBase::GetTag(aNode);
     atom->ToString(outFormat);
   } else {
     outFormat.Truncate();
   }
   return NS_OK;
 }
 
 void
@@ -3178,17 +3178,17 @@ HTMLEditRules::WillMakeList(Selection* a
   WillInsert(*aSelection, aCancel);
 
   // initialize out param
   // we want to ignore result of WillInsert()
   *aCancel = false;
   *aHandled = false;
 
   // deduce what tag to use for list items
-  nsCOMPtr<nsIAtom> itemType;
+  RefPtr<nsIAtom> itemType;
   if (aItemType) {
     itemType = NS_Atomize(*aItemType);
     NS_ENSURE_TRUE(itemType, NS_ERROR_OUT_OF_MEMORY);
   } else if (listType == nsGkAtoms::dl) {
     itemType = nsGkAtoms::dd;
   } else {
     itemType = nsGkAtoms::li;
   }
@@ -4212,17 +4212,17 @@ HTMLEditRules::WillOutdent(Selection& aS
       if (useCSS && IsBlockNode(curNode)) {
         nsIAtom& marginProperty =
           MarginPropertyAtomForIndent(*htmlEditor->mCSSEditUtils, curNode);
         nsAutoString value;
         htmlEditor->mCSSEditUtils->GetSpecifiedProperty(curNode,
                                                          marginProperty,
                                                          value);
         float f;
-        nsCOMPtr<nsIAtom> unit;
+        RefPtr<nsIAtom> unit;
         NS_ENSURE_STATE(htmlEditor);
         htmlEditor->mCSSEditUtils->ParseLength(value, &f,
                                                getter_AddRefs(unit));
         if (f > 0) {
           ChangeIndentation(*curNode->AsElement(), Change::minus);
           continue;
         }
       }
@@ -4290,17 +4290,17 @@ HTMLEditRules::WillOutdent(Selection& aS
           break;
         } else if (useCSS) {
           nsIAtom& marginProperty =
             MarginPropertyAtomForIndent(*htmlEditor->mCSSEditUtils, curNode);
           nsAutoString value;
           htmlEditor->mCSSEditUtils->GetSpecifiedProperty(*n, marginProperty,
                                                            value);
           float f;
-          nsCOMPtr<nsIAtom> unit;
+          RefPtr<nsIAtom> unit;
           htmlEditor->mCSSEditUtils->ParseLength(value, &f, getter_AddRefs(unit));
           if (f > 0 && !(HTMLEditUtils::IsList(curParent) &&
                          HTMLEditUtils::IsList(curNode))) {
             curBlockQuote = n->AsElement();
             firstBQChild = curNode;
             lastBQChild = curNode;
             curBlockQuoteIsIndentedWithCSS = true;
             break;
@@ -6696,17 +6696,17 @@ HTMLEditRules::ReturnInListItem(Selectio
     NS_ENSURE_SUCCESS(rv, rv);
     if (isEmptyNode) {
       rv = CreateMozBR(prevItem->AsDOMNode(), 0);
       NS_ENSURE_SUCCESS(rv, rv);
     } else {
       rv = htmlEditor->IsEmptyNode(&aListItem, &isEmptyNode, true);
       NS_ENSURE_SUCCESS(rv, rv);
       if (isEmptyNode) {
-        nsCOMPtr<nsIAtom> nodeAtom = aListItem.NodeInfo()->NameAtom();
+        RefPtr<nsIAtom> nodeAtom = aListItem.NodeInfo()->NameAtom();
         if (nodeAtom == nsGkAtoms::dd || nodeAtom == nsGkAtoms::dt) {
           nsCOMPtr<nsINode> list = aListItem.GetParentNode();
           int32_t itemOffset = list ? list->IndexOf(&aListItem) : -1;
 
           nsIAtom* listAtom = nodeAtom == nsGkAtoms::dt ? nsGkAtoms::dd
                                                         : nsGkAtoms::dt;
           nsCOMPtr<Element> newListItem =
             htmlEditor->CreateNode(listAtom, list, itemOffset + 1);
@@ -8616,17 +8616,17 @@ HTMLEditRules::ChangeIndentation(Element
   RefPtr<HTMLEditor> htmlEditor(mHTMLEditor);
 
   nsIAtom& marginProperty =
     MarginPropertyAtomForIndent(*htmlEditor->mCSSEditUtils, aElement);
   nsAutoString value;
   htmlEditor->mCSSEditUtils->GetSpecifiedProperty(aElement, marginProperty,
                                                   value);
   float f;
-  nsCOMPtr<nsIAtom> unit;
+  RefPtr<nsIAtom> unit;
   htmlEditor->mCSSEditUtils->ParseLength(value, &f, getter_AddRefs(unit));
   if (!f) {
     nsAutoString defaultLengthUnit;
     htmlEditor->mCSSEditUtils->GetDefaultLengthUnit(defaultLengthUnit);
     unit = NS_Atomize(defaultLengthUnit);
   }
   int8_t multiplier = aChange == Change::plus ? +1 : -1;
   if (nsGkAtoms::in == unit) {
--- a/editor/libeditor/HTMLEditUtils.cpp
+++ b/editor/libeditor/HTMLEditUtils.cpp
@@ -83,17 +83,17 @@ HTMLEditUtils::IsFormatNode(nsINode* aNo
 /**
  * IsNodeThatCanOutdent() returns true if aNode is a list, list item or
  * blockquote.
  */
 bool
 HTMLEditUtils::IsNodeThatCanOutdent(nsIDOMNode* aNode)
 {
   MOZ_ASSERT(aNode);
-  nsCOMPtr<nsIAtom> nodeAtom = EditorBase::GetTag(aNode);
+  RefPtr<nsIAtom> nodeAtom = EditorBase::GetTag(aNode);
   return (nodeAtom == nsGkAtoms::ul)
       || (nodeAtom == nsGkAtoms::ol)
       || (nodeAtom == nsGkAtoms::dl)
       || (nodeAtom == nsGkAtoms::li)
       || (nodeAtom == nsGkAtoms::dd)
       || (nodeAtom == nsGkAtoms::dt)
       || (nodeAtom == nsGkAtoms::blockquote);
 }
--- a/editor/libeditor/HTMLEditor.cpp
+++ b/editor/libeditor/HTMLEditor.cpp
@@ -1951,17 +1951,17 @@ HTMLEditor::MakeOrChangeList(const nsASt
       *selection->GetRangeAt(0)->GetStartContainer()->AsContent();
     int32_t offset = selection->GetRangeAt(0)->StartOffset();
 
     if (isCollapsed) {
       // have to find a place to put the list
       nsCOMPtr<nsIContent> parent = node;
       nsCOMPtr<nsIContent> topChild = node;
 
-      nsCOMPtr<nsIAtom> listAtom = NS_Atomize(aListType);
+      RefPtr<nsIAtom> listAtom = NS_Atomize(aListType);
       while (!CanContainTag(*parent, *listAtom)) {
         topChild = parent;
         parent = parent->GetParent();
       }
 
       if (parent != node) {
         // we need to split up to the child of parent
         offset = SplitNodeDeep(*topChild, *node, offset);
@@ -2088,17 +2088,17 @@ HTMLEditor::InsertBasicBlock(const nsASt
       *selection->GetRangeAt(0)->GetStartContainer()->AsContent();
     int32_t offset = selection->GetRangeAt(0)->StartOffset();
 
     if (isCollapsed) {
       // have to find a place to put the block
       nsCOMPtr<nsIContent> parent = node;
       nsCOMPtr<nsIContent> topChild = node;
 
-      nsCOMPtr<nsIAtom> blockAtom = NS_Atomize(aBlockType);
+      RefPtr<nsIAtom> blockAtom = NS_Atomize(aBlockType);
       while (!CanContainTag(*parent, *blockAtom)) {
         NS_ENSURE_TRUE(parent->GetParent(), NS_ERROR_FAILURE);
         topChild = parent;
         parent = parent->GetParent();
       }
 
       if (parent != node) {
         // we need to split up to the child of parent
@@ -2519,17 +2519,17 @@ HTMLEditor::CreateElementWithDefaults(co
     realTagName.Assign('a');
   } else {
     realTagName = tagName;
   }
   // We don't use editor's CreateElement because we don't want to go through
   // the transaction system
 
   // New call to use instead to get proper HTML element, bug 39919
-  nsCOMPtr<nsIAtom> realTagAtom = NS_Atomize(realTagName);
+  RefPtr<nsIAtom> realTagAtom = NS_Atomize(realTagName);
   RefPtr<Element> newElement = CreateHTMLContent(realTagAtom);
   if (!newElement) {
     return nullptr;
   }
 
   // Mark the new element dirty, so it will be formatted
   ErrorResult rv;
   newElement->SetAttribute(NS_LITERAL_STRING("_moz_dirty"), EmptyString(), rv);
--- a/editor/libeditor/HTMLEditorObjectResizer.cpp
+++ b/editor/libeditor/HTMLEditorObjectResizer.cpp
@@ -185,17 +185,17 @@ HTMLEditor::CreateResizer(int16_t aLocat
   return Move(ret);
 }
 
 ManualNACPtr
 HTMLEditor::CreateShadow(nsIContent& aParentContent,
                          Element& aOriginalObject)
 {
   // let's create an image through the element factory
-  nsCOMPtr<nsIAtom> name;
+  RefPtr<nsIAtom> name;
   if (HTMLEditUtils::IsImage(&aOriginalObject)) {
     name = nsGkAtoms::img;
   } else {
     name = nsGkAtoms::span;
   }
 
   return CreateAnonymousElement(name, aParentContent,
                                 NS_LITERAL_STRING("mozResizingShadow"), true);
@@ -219,17 +219,17 @@ HTMLEditor::SetAllResizersPosition()
   int32_t w = mResizedObjectWidth;
   int32_t h = mResizedObjectHeight;
 
   // now let's place all the resizers around the image
 
   // get the size of resizers
   nsAutoString value;
   float resizerWidth, resizerHeight;
-  nsCOMPtr<nsIAtom> dummyUnit;
+  RefPtr<nsIAtom> dummyUnit;
   mCSSEditUtils->GetComputedProperty(*mTopLeftHandle, *nsGkAtoms::width,
                                      value);
   mCSSEditUtils->ParseLength(value, &resizerWidth, getter_AddRefs(dummyUnit));
   mCSSEditUtils->GetComputedProperty(*mTopLeftHandle, *nsGkAtoms::height,
                                      value);
   mCSSEditUtils->ParseLength(value, &resizerHeight, getter_AddRefs(dummyUnit));
 
   int32_t rw  = (int32_t)((resizerWidth + 1) / 2);
--- a/editor/libeditor/HTMLStyleEditor.cpp
+++ b/editor/libeditor/HTMLStyleEditor.cpp
@@ -54,17 +54,17 @@ IsEmptyTextNode(HTMLEditor* aThis, nsINo
          isEmptyTextNode;
 }
 
 NS_IMETHODIMP
 HTMLEditor::SetInlineProperty(const nsAString& aProperty,
                               const nsAString& aAttribute,
                               const nsAString& aValue)
 {
-  nsCOMPtr<nsIAtom> property = NS_Atomize(aProperty);
+  RefPtr<nsIAtom> property = NS_Atomize(aProperty);
   return SetInlineProperty(property, aAttribute, aValue);
 }
 
 nsresult
 HTMLEditor::SetInlineProperty(nsIAtom* aProperty,
                               const nsAString& aAttribute,
                               const nsAString& aValue)
 {
@@ -210,17 +210,17 @@ HTMLEditor::IsSimpleModifiableNode(nsICo
         element->IsHTMLElement(nsGkAtoms::em)) ||
        (aProperty == nsGkAtoms::strike &&
         element->IsHTMLElement(nsGkAtoms::s)))) {
     return true;
   }
 
   // Now look for things like <font>
   if (aAttribute && !aAttribute->IsEmpty()) {
-    nsCOMPtr<nsIAtom> atom = NS_Atomize(*aAttribute);
+    RefPtr<nsIAtom> atom = NS_Atomize(*aAttribute);
     MOZ_ASSERT(atom);
 
     nsString attrValue;
     if (element->IsHTMLElement(aProperty) &&
         IsOnlyAttribute(element, *aAttribute) &&
         element->GetAttr(kNameSpaceID_None, atom, attrValue) &&
         attrValue.Equals(*aValue, nsCaseInsensitiveStringComparator())) {
       // This is not quite correct, because it excludes cases like
@@ -319,17 +319,17 @@ HTMLEditor::SetInlinePropertyOnTextNode(
 }
 
 nsresult
 HTMLEditor::SetInlinePropertyOnNodeImpl(nsIContent& aNode,
                                         nsIAtom& aProperty,
                                         const nsAString* aAttribute,
                                         const nsAString& aValue)
 {
-  nsCOMPtr<nsIAtom> attrAtom = aAttribute ? NS_Atomize(*aAttribute) : nullptr;
+  RefPtr<nsIAtom> attrAtom = aAttribute ? NS_Atomize(*aAttribute) : nullptr;
 
   // If this is an element that can't be contained in a span, we have to
   // recurse to its children.
   if (!TagCanContain(*nsGkAtoms::span, aNode)) {
     if (aNode.HasChildren()) {
       nsTArray<OwningNonNull<nsIContent>> arrayOfNodes;
 
       // Populate the list.
@@ -701,17 +701,17 @@ HTMLEditor::RemoveStyleInside(nsIContent
         rv =
           CloneAttribute(nsGkAtoms::_class, spanNode, aNode.AsElement());
         NS_ENSURE_SUCCESS(rv, rv);
       }
       nsresult rv = RemoveContainer(&aNode);
       NS_ENSURE_SUCCESS(rv, rv);
     } else {
       // otherwise we just want to eliminate the attribute
-      nsCOMPtr<nsIAtom> attribute = NS_Atomize(*aAttribute);
+      RefPtr<nsIAtom> attribute = NS_Atomize(*aAttribute);
       if (aNode.HasAttr(kNameSpaceID_None, attribute)) {
         // if this matching attribute is the ONLY one on the node,
         // then remove the whole node.  Otherwise just nix the attribute.
         if (IsOnlyAttribute(&aNode, *aAttribute)) {
           nsresult rv = RemoveContainer(&aNode);
           if (NS_WARN_IF(NS_FAILED(rv))) {
             return rv;
           }
@@ -728,17 +728,17 @@ HTMLEditor::RemoveStyleInside(nsIContent
   }
 
   if (!aChildrenOnly &&
       mCSSEditUtils->IsCSSEditableProperty(&aNode, aProperty, aAttribute)) {
     // the HTML style defined by aProperty/aAttribute has a CSS equivalence in
     // this implementation for the node aNode; let's check if it carries those
     // css styles
     if (aNode.IsElement()) {
-      nsCOMPtr<nsIAtom> attribute =
+      RefPtr<nsIAtom> attribute =
         aAttribute ? NS_Atomize(*aAttribute) : nullptr;
       bool hasAttribute =
         mCSSEditUtils->HaveCSSEquivalentStyles(
                          aNode, aProperty, attribute, CSSEditUtils::eSpecified);
       if (hasAttribute) {
         // yes, tmp has the corresponding css declarations in its style
         // attribute
         // let's remove them
@@ -1074,17 +1074,17 @@ HTMLEditor::GetInlinePropertyBase(nsIAto
 NS_IMETHODIMP
 HTMLEditor::GetInlineProperty(const nsAString& aProperty,
                               const nsAString& aAttribute,
                               const nsAString& aValue,
                               bool* aFirst,
                               bool* aAny,
                               bool* aAll)
 {
-  nsCOMPtr<nsIAtom> property = NS_Atomize(aProperty);
+  RefPtr<nsIAtom> property = NS_Atomize(aProperty);
   return GetInlineProperty(property, aAttribute, aValue, aFirst, aAny, aAll);
 }
 
 nsresult
 HTMLEditor::GetInlineProperty(nsIAtom* aProperty,
                               const nsAString& aAttribute,
                               const nsAString& aValue,
                               bool* aFirst,
@@ -1105,17 +1105,17 @@ NS_IMETHODIMP
 HTMLEditor::GetInlinePropertyWithAttrValue(const nsAString& aProperty,
                                            const nsAString& aAttribute,
                                            const nsAString& aValue,
                                            bool* aFirst,
                                            bool* aAny,
                                            bool* aAll,
                                            nsAString& outValue)
 {
-  nsCOMPtr<nsIAtom> property = NS_Atomize(aProperty);
+  RefPtr<nsIAtom> property = NS_Atomize(aProperty);
   return GetInlinePropertyWithAttrValue(property, aAttribute, aValue, aFirst,
                                         aAny, aAll, outValue);
 }
 
 nsresult
 HTMLEditor::GetInlinePropertyWithAttrValue(nsIAtom* aProperty,
                                            const nsAString& aAttribute,
                                            const nsAString& aValue,
@@ -1145,17 +1145,17 @@ HTMLEditor::RemoveAllInlineProperties()
   NS_ENSURE_SUCCESS(rv, rv);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 HTMLEditor::RemoveInlineProperty(const nsAString& aProperty,
                                  const nsAString& aAttribute)
 {
-  nsCOMPtr<nsIAtom> property = NS_Atomize(aProperty);
+  RefPtr<nsIAtom> property = NS_Atomize(aProperty);
   return RemoveInlineProperty(property, aAttribute);
 }
 
 nsresult
 HTMLEditor::RemoveInlineProperty(nsIAtom* aProperty,
                                  const nsAString& aAttribute)
 {
   return RemoveInlinePropertyImpl(aProperty, &aAttribute);
--- a/editor/libeditor/HTMLTableEditor.cpp
+++ b/editor/libeditor/HTMLTableEditor.cpp
@@ -1956,17 +1956,17 @@ HTMLEditor::SwitchTableCellHeaderType(ns
   // Save current selection to restore when done
   // This is needed so ReplaceContainer can monitor selection
   //  when replacing nodes
   RefPtr<Selection> selection = GetSelection();
   NS_ENSURE_TRUE(selection, NS_ERROR_FAILURE);
   AutoSelectionRestorer selectionRestorer(selection, this);
 
   // Set to the opposite of current type
-  nsCOMPtr<nsIAtom> atom = EditorBase::GetTag(aSourceCell);
+  RefPtr<nsIAtom> atom = EditorBase::GetTag(aSourceCell);
   nsIAtom* newCellType = atom == nsGkAtoms::td ? nsGkAtoms::th : nsGkAtoms::td;
 
   // This creates new node, moves children, copies attributes (true)
   //   and manages the selection!
   nsCOMPtr<Element> newNode = ReplaceContainer(sourceCell, newCellType,
       nullptr, nullptr, EditorBase::eCloneAttributes);
   NS_ENSURE_TRUE(newNode, NS_ERROR_FAILURE);
 
--- a/editor/libeditor/PlaceholderTransaction.cpp
+++ b/editor/libeditor/PlaceholderTransaction.cpp
@@ -162,17 +162,17 @@ PlaceholderTransaction::Merge(nsITransac
 //  finished the initial batch and we know we will be told when the batch ends.
 //  we can remeber the selection then.
   } else {
     // merge typing or IME or deletion transactions if the selection matches
     if ((mName.get() == nsGkAtoms::TypingTxnName ||
          mName.get() == nsGkAtoms::IMETxnName    ||
          mName.get() == nsGkAtoms::DeleteTxnName) && !mCommitted) {
       if (absorbingTransaction) {
-        nsCOMPtr<nsIAtom> atom;
+        RefPtr<nsIAtom> atom;
         absorbingTransaction->GetTxnName(getter_AddRefs(atom));
         if (atom && atom == mName) {
           // check if start selection of next placeholder matches
           // end selection of this placeholder
           bool isSame;
           absorbingTransaction->StartSelectionEquals(&mEndSel, &isSame);
           if (isSame) {
             mAbsorb = true;  // we need to start absorbing again
--- a/editor/txtsvc/nsFilteredContentIterator.h
+++ b/editor/txtsvc/nsFilteredContentIterator.h
@@ -61,21 +61,21 @@ protected:
   nsresult AdvanceNode(nsIDOMNode* aNode, nsIDOMNode*& aNewNode, eDirectionType aDir);
   void CheckAdvNode(nsIDOMNode* aNode, bool& aDidSkip, eDirectionType aDir);
   nsresult SwitchDirections(bool aChangeToForward);
 
   nsCOMPtr<nsIContentIterator> mCurrentIterator;
   nsCOMPtr<nsIContentIterator> mIterator;
   nsCOMPtr<nsIContentIterator> mPreIterator;
 
-  nsCOMPtr<nsIAtom> mBlockQuoteAtom;
-  nsCOMPtr<nsIAtom> mScriptAtom;
-  nsCOMPtr<nsIAtom> mTextAreaAtom;
-  nsCOMPtr<nsIAtom> mSelectAreaAtom;
-  nsCOMPtr<nsIAtom> mMapAtom;
+  RefPtr<nsIAtom> mBlockQuoteAtom;
+  RefPtr<nsIAtom> mScriptAtom;
+  RefPtr<nsIAtom> mTextAreaAtom;
+  RefPtr<nsIAtom> mSelectAreaAtom;
+  RefPtr<nsIAtom> mMapAtom;
 
   nsCOMPtr<nsITextServicesFilter> mFilter;
   RefPtr<nsRange>               mRange;
   bool                            mDidSkip;
   bool                            mIsOutOfRange;
   eDirectionType                  mDirection;
 };
 
--- a/gfx/src/nsDeviceContext.cpp
+++ b/gfx/src/nsDeviceContext.cpp
@@ -63,17 +63,17 @@ public:
     void Flush();
 
     void UpdateUserFonts(gfxUserFontSet* aUserFontSet);
 
 protected:
     ~nsFontCache() {}
 
     nsDeviceContext*          mContext; // owner
-    nsCOMPtr<nsIAtom>         mLocaleLanguage;
+    RefPtr<nsIAtom>         mLocaleLanguage;
     nsTArray<nsFontMetrics*>  mFontMetrics;
 };
 
 NS_IMPL_ISUPPORTS(nsFontCache, nsIObserver)
 
 // The Init and Destroy methods are necessary because it's not
 // safe to call AddObserver from a constructor or RemoveObserver
 // from a destructor.  That should be fixed.
--- a/gfx/src/nsFontMetrics.h
+++ b/gfx/src/nsFontMetrics.h
@@ -244,17 +244,17 @@ private:
       return GetMetrics(mOrientation);
     }
 
     const gfxFont::Metrics&
     GetMetrics(const gfxFont::Orientation aFontOrientation) const;
 
     nsFont mFont;
     RefPtr<gfxFontGroup> mFontGroup;
-    nsCOMPtr<nsIAtom> mLanguage;
+    RefPtr<nsIAtom> mLanguage;
     // Pointer to the device context for which this fontMetrics object was
     // created.
     nsDeviceContext* MOZ_NON_OWNING_REF mDeviceContext;
     int32_t mP2A;
 
     // The font orientation (horizontal or vertical) for which these metrics
     // have been initialized. This determines which line metrics (ascent and
     // descent) they will return.
--- a/gfx/src/nsThebesFontEnumerator.cpp
+++ b/gfx/src/nsThebesFontEnumerator.cpp
@@ -43,17 +43,17 @@ nsThebesFontEnumerator::EnumerateFonts(c
     nsTArray<nsString> fontList;
 
     nsAutoCString generic;
     if (aGeneric)
         generic.Assign(aGeneric);
     else
         generic.SetIsVoid(true);
 
-    nsCOMPtr<nsIAtom> langGroupAtom;
+    RefPtr<nsIAtom> langGroupAtom;
     if (aLangGroup) {
         nsAutoCString lowered;
         lowered.Assign(aLangGroup);
         ToLowerCase(lowered);
         langGroupAtom = NS_Atomize(lowered);
     }
 
     nsresult rv = gfxPlatform::GetPlatform()->GetFontList(langGroupAtom, generic, fontList);
@@ -151,17 +151,17 @@ public:
         nsCOMPtr<nsIRunnable> runnable = new EnumerateFontsResult(
             rv, Move(mEnumerateFontsPromise), Move(fontList));
         NS_DispatchToMainThread(runnable.forget());
 
         return NS_OK;
     }
 
 private:
-    nsCOMPtr<nsIAtom> mLangGroupAtom;
+    RefPtr<nsIAtom> mLangGroupAtom;
     nsAutoCStringN<16> mGeneric;
     UniquePtr<EnumerateFontsPromise> mEnumerateFontsPromise;
 };
 
 NS_IMETHODIMP
 nsThebesFontEnumerator::EnumerateAllFontsAsync(JSContext* aCx,
                                                JS::MutableHandleValue aRval)
 {
@@ -187,17 +187,17 @@ nsThebesFontEnumerator::EnumerateFontsAs
     }
 
     auto enumerateFontsPromise = MakeUnique<EnumerateFontsPromise>(promise);
 
     nsCOMPtr<nsIThread> thread;
     nsresult rv = NS_NewNamedThread("FontEnumThread", getter_AddRefs(thread));
     NS_ENSURE_SUCCESS(rv, rv);
 
-    nsCOMPtr<nsIAtom> langGroupAtom;
+    RefPtr<nsIAtom> langGroupAtom;
     if (aLangGroup) {
         nsAutoCStringN<16> lowered;
         lowered.Assign(aLangGroup);
         ToLowerCase(lowered);
         langGroupAtom = NS_Atomize(lowered);
     }
 
     nsAutoCString generic;
--- a/gfx/thebes/gfxFont.h
+++ b/gfx/thebes/gfxFont.h
@@ -180,17 +180,17 @@ struct gfxFontStyle {
         NS_ASSERTION(sizeAdjust >= 0.0, "Not meant to be called when sizeAdjust = -1.0");
         gfxFloat adjustedSize = std::max(NS_round(size*(sizeAdjust/aspect)), 1.0);
         return std::min(adjustedSize, FONT_MAX_SIZE);
     }
 
     PLDHashNumber Hash() const {
         return ((style + (systemFont << 7) +
             (weight << 8)) + uint32_t(size*1000) + uint32_t(sizeAdjust*1000)) ^
-            nsISupportsHashKey::HashKey(language);
+            nsRefPtrHashKey<nsIAtom>::HashKey(language);
     }
 
     int8_t ComputeWeight() const;
 
     // Adjust this style to simulate sub/superscript (as requested in the
     // variantSubSuper field) using size and baselineOffset instead.
     void AdjustForSubSuperscript(int32_t aAppUnitsPerDevPixel);
 
--- a/intl/hyphenation/glue/nsHyphenationManager.cpp
+++ b/intl/hyphenation/glue/nsHyphenationManager.cpp
@@ -87,17 +87,17 @@ nsHyphenationManager::GetHyphenator(nsIA
 {
   RefPtr<nsHyphenator> hyph;
   mHyphenators.Get(aLocale, getter_AddRefs(hyph));
   if (hyph) {
     return hyph.forget();
   }
   nsCOMPtr<nsIURI> uri = mPatternFiles.Get(aLocale);
   if (!uri) {
-    nsCOMPtr<nsIAtom> alias = mHyphAliases.Get(aLocale);
+    RefPtr<nsIAtom> alias = mHyphAliases.Get(aLocale);
     if (alias) {
       mHyphenators.Get(alias, getter_AddRefs(hyph));
       if (hyph) {
         return hyph.forget();
       }
       uri = mPatternFiles.Get(alias);
       if (uri) {
         aLocale = alias;
@@ -109,17 +109,17 @@ nsHyphenationManager::GetHyphenator(nsIA
       // so "de-DE-1996" -> "de-DE-*" (and then recursively -> "de-*")
       nsAtomCString localeStr(aLocale);
       if (StringEndsWith(localeStr, NS_LITERAL_CSTRING("-*"))) {
         localeStr.Truncate(localeStr.Length() - 2);
       }
       int32_t i = localeStr.RFindChar('-');
       if (i > 1) {
         localeStr.Replace(i, localeStr.Length() - i, "-*");
-        nsCOMPtr<nsIAtom> fuzzyLocale = NS_Atomize(localeStr);
+        RefPtr<nsIAtom> fuzzyLocale = NS_Atomize(localeStr);
         return GetHyphenator(fuzzyLocale);
       } else {
         return nullptr;
       }
     }
   }
   hyph = new nsHyphenator(uri);
   if (hyph->IsValid()) {
@@ -220,17 +220,17 @@ nsHyphenationManager::LoadPatternListFro
     if (StringBeginsWith(locale, NS_LITERAL_CSTRING("hyph_"))) {
       locale.Cut(0, 5);
     }
     for (uint32_t i = 0; i < locale.Length(); ++i) {
       if (locale[i] == '_') {
         locale.Replace(i, 1, '-');
       }
     }
-    nsCOMPtr<nsIAtom> localeAtom = NS_Atomize(locale);
+    RefPtr<nsIAtom> localeAtom = NS_Atomize(locale);
     if (NS_SUCCEEDED(rv)) {
       mPatternFiles.Put(localeAtom, uri);
     }
   }
 
   delete find;
 }
 
@@ -278,17 +278,17 @@ nsHyphenationManager::LoadPatternListFro
       if (locale[i] == '_') {
         locale.Replace(i, 1, '-');
       }
     }
 #ifdef DEBUG_hyph
     printf("adding hyphenation patterns for %s: %s\n", locale.get(),
            NS_ConvertUTF16toUTF8(dictName).get());
 #endif
-    nsCOMPtr<nsIAtom> localeAtom = NS_Atomize(locale);
+    RefPtr<nsIAtom> localeAtom = NS_Atomize(locale);
     nsCOMPtr<nsIURI> uri;
     nsresult rv = NS_NewFileURI(getter_AddRefs(uri), file);
     if (NS_SUCCEEDED(rv)) {
       mPatternFiles.Put(localeAtom, uri);
     }
   }
 }
 
@@ -307,16 +307,16 @@ nsHyphenationManager::LoadAliases()
     for (uint32_t i = 0; i < prefCount; ++i) {
       nsAutoCString value;
       rv = Preferences::GetCString(prefNames[i], value);
       if (NS_SUCCEEDED(rv)) {
         nsAutoCString alias(prefNames[i]);
         alias.Cut(0, sizeof(kIntlHyphenationAliasPrefix) - 1);
         ToLowerCase(alias);
         ToLowerCase(value);
-        nsCOMPtr<nsIAtom> aliasAtom = NS_Atomize(alias);
-        nsCOMPtr<nsIAtom> valueAtom = NS_Atomize(value);
+        RefPtr<nsIAtom> aliasAtom = NS_Atomize(alias);
+        RefPtr<nsIAtom> valueAtom = NS_Atomize(value);
         mHyphAliases.Put(aliasAtom, valueAtom);
       }
     }
     NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(prefCount, prefNames);
   }
 }
--- a/intl/hyphenation/glue/nsHyphenationManager.h
+++ b/intl/hyphenation/glue/nsHyphenationManager.h
@@ -40,16 +40,16 @@ protected:
       NS_DECL_NSIOBSERVER
   };
 
   void LoadPatternList();
   void LoadPatternListFromOmnijar(mozilla::Omnijar::Type aType);
   void LoadPatternListFromDir(nsIFile *aDir);
   void LoadAliases();
 
-  nsInterfaceHashtable<nsISupportsHashKey,nsIAtom> mHyphAliases;
-  nsInterfaceHashtable<nsISupportsHashKey,nsIURI> mPatternFiles;
-  nsRefPtrHashtable<nsISupportsHashKey,nsHyphenator> mHyphenators;
+  nsRefPtrHashtable<nsRefPtrHashKey<nsIAtom>, nsIAtom> mHyphAliases;
+  nsInterfaceHashtable<nsRefPtrHashKey<nsIAtom>, nsIURI> mPatternFiles;
+  nsRefPtrHashtable<nsRefPtrHashKey<nsIAtom>, nsHyphenator> mHyphenators;
 
   static nsHyphenationManager *sInstance;
 };
 
 #endif // nsHyphenationManager_h__
--- a/intl/locale/nsLanguageAtomService.cpp
+++ b/intl/locale/nsLanguageAtomService.cpp
@@ -37,17 +37,17 @@ nsLanguageAtomService::GetService()
 }
 
 nsIAtom*
 nsLanguageAtomService::LookupLanguage(const nsACString &aLanguage)
 {
   nsAutoCString lowered(aLanguage);
   ToLowerCase(lowered);
 
-  nsCOMPtr<nsIAtom> lang = NS_Atomize(lowered);
+  RefPtr<nsIAtom> lang = NS_Atomize(lowered);
   return GetLanguageGroup(lang);
 }
 
 already_AddRefed<nsIAtom>
 nsLanguageAtomService::LookupCharSet(NotNull<const Encoding*> aEncoding)
 {
   nsAutoCString charset;
   aEncoding->Name(charset);
@@ -88,17 +88,17 @@ nsLanguageAtomService::GetLanguageGroup(
 {
   nsIAtom *retVal = mLangToGroup.GetWeak(aLanguage);
 
   if (!retVal) {
     if (aNeedsToCache) {
       *aNeedsToCache = true;
       return nullptr;
     }
-    nsCOMPtr<nsIAtom> uncached = GetUncachedLanguageGroup(aLanguage);
+    RefPtr<nsIAtom> uncached = GetUncachedLanguageGroup(aLanguage);
     retVal = uncached.get();
 
     AssertIsMainThreadOrServoLangFontPrefsCacheLocked();
     // The hashtable will keep an owning reference to the atom
     mLangToGroup.Put(aLanguage, uncached);
   }
 
   return retVal;
@@ -123,12 +123,12 @@ nsLanguageAtomService::GetUncachedLangua
       break;
     }
     langStr.Truncate(hyphen);
     res = nsUConvPropertySearch::SearchPropertyValue(kLangGroups,
                                                      ArrayLength(kLangGroups),
                                                      langStr, langGroupStr);
   }
 
-  nsCOMPtr<nsIAtom> langGroup = NS_Atomize(langGroupStr);
+  RefPtr<nsIAtom> langGroup = NS_Atomize(langGroupStr);
 
   return langGroup.forget();
 }
--- a/intl/locale/nsLanguageAtomService.h
+++ b/intl/locale/nsLanguageAtomService.h
@@ -9,17 +9,17 @@
  */
 
 #ifndef nsLanguageAtomService_h_
 #define nsLanguageAtomService_h_
 
 #include "mozilla/NotNull.h"
 #include "nsCOMPtr.h"
 #include "nsIAtom.h"
-#include "nsInterfaceHashtable.h"
+#include "nsRefPtrHashtable.h"
 
 namespace mozilla {
 class Encoding;
 }
 
 class nsLanguageAtomService final
 {
   using Encoding = mozilla::Encoding;
@@ -45,13 +45,13 @@ public:
   // were able to use an existing cached result.  Thus, callers that
   // get a true *aNeedsToCache outparam value should make an effort
   // to re-call GetLanguageGroup when it is safe to cache, to avoid
   // recomputing the language group again later.
   nsIAtom* GetLanguageGroup(nsIAtom* aLanguage, bool* aNeedsToCache = nullptr);
   already_AddRefed<nsIAtom> GetUncachedLanguageGroup(nsIAtom* aLanguage) const;
 
 private:
-  nsInterfaceHashtable<nsISupportsHashKey, nsIAtom> mLangToGroup;
-  nsCOMPtr<nsIAtom> mLocaleLanguage;
+  nsRefPtrHashtable<nsRefPtrHashKey<nsIAtom>, nsIAtom> mLangToGroup;
+  RefPtr<nsIAtom> mLocaleLanguage;
 };
 
 #endif
--- a/layout/base/StaticPresData.cpp
+++ b/layout/base/StaticPresData.cpp
@@ -255,17 +255,17 @@ StaticPresData::GetLangGroup(nsIAtom* aL
     langGroupAtom = nsGkAtoms::x_western; // Assume x-western is safe...
   }
   return langGroupAtom;
 }
 
 already_AddRefed<nsIAtom>
 StaticPresData::GetUncachedLangGroup(nsIAtom* aLanguage) const
 {
-  nsCOMPtr<nsIAtom> langGroupAtom = mLangService->GetUncachedLanguageGroup(aLanguage);
+  RefPtr<nsIAtom> langGroupAtom = mLangService->GetUncachedLanguageGroup(aLanguage);
   if (!langGroupAtom) {
     langGroupAtom = nsGkAtoms::x_western; // Assume x-western is safe...
   }
   return langGroupAtom.forget();
 }
 
 const LangGroupFontPrefs*
 StaticPresData::GetFontPrefsForLangHelper(nsIAtom* aLanguage,
--- a/layout/base/StaticPresData.h
+++ b/layout/base/StaticPresData.h
@@ -58,17 +58,17 @@ struct LangGroupFontPrefs {
       curr = curr->mNext;
     }
     return n;
   }
 
   // Initialize this with the data for a given language
   void Initialize(nsIAtom* aLangGroupAtom);
 
-  nsCOMPtr<nsIAtom> mLangGroup;
+  RefPtr<nsIAtom> mLangGroup;
   nscoord mMinimumFontSize;
   nsFont mDefaultVariableFont;
   nsFont mDefaultFixedFont;
   nsFont mDefaultSerifFont;
   nsFont mDefaultSansSerifFont;
   nsFont mDefaultMonospaceFont;
   nsFont mDefaultCursiveFont;
   nsFont mDefaultFantasyFont;
--- a/layout/base/nsCSSFrameConstructor.cpp
+++ b/layout/base/nsCSSFrameConstructor.cpp
@@ -1760,17 +1760,17 @@ nsCSSFrameConstructor::CreateGeneratedCo
     }
 
     case eStyleContentType_String:
       return CreateGenConTextNode(aState,
                                   nsDependentString(data.GetString()),
                                   nullptr, nullptr);
 
     case eStyleContentType_Attr: {
-      nsCOMPtr<nsIAtom> attrName;
+      RefPtr<nsIAtom> attrName;
       int32_t attrNameSpace = kNameSpaceID_None;
       nsAutoString contentString(data.GetString());
 
       int32_t barIndex = contentString.FindChar('|'); // CSS namespace delimiter
       if (-1 != barIndex) {
         nsAutoString  nameSpaceVal;
         contentString.Left(nameSpaceVal, barIndex);
         nsresult error;
--- a/layout/base/nsLayoutUtils.h
+++ b/layout/base/nsLayoutUtils.h
@@ -3149,29 +3149,29 @@ public:
   nsSetAttrRunnable(nsIContent* aContent, nsIAtom* aAttrName,
                     const nsAString& aValue);
   nsSetAttrRunnable(nsIContent* aContent, nsIAtom* aAttrName,
                     int32_t aValue);
 
   NS_DECL_NSIRUNNABLE
 
   nsCOMPtr<nsIContent> mContent;
-  nsCOMPtr<nsIAtom> mAttrName;
+  RefPtr<nsIAtom> mAttrName;
   nsAutoString mValue;
 };
 
 class nsUnsetAttrRunnable : public mozilla::Runnable
 {
 public:
   nsUnsetAttrRunnable(nsIContent* aContent, nsIAtom* aAttrName);
 
   NS_DECL_NSIRUNNABLE
 
   nsCOMPtr<nsIContent> mContent;
-  nsCOMPtr<nsIAtom> mAttrName;
+  RefPtr<nsIAtom> mAttrName;
 };
 
 // This class allows you to easily set any pointer variable and ensure it's
 // set to nullptr when leaving its scope.
 template<typename T>
 class MOZ_RAII SetAndNullOnExit
 {
 public:
--- a/layout/base/nsPresContext.cpp
+++ b/layout/base/nsPresContext.cpp
@@ -1991,17 +1991,17 @@ nsPresContext::ForceCacheLang(nsIAtom *a
   GetDefaultFont(kPresContext_DefaultVariableFont_ID, aLanguage);
   mLanguagesUsed.PutEntry(aLanguage);
 }
 
 void
 nsPresContext::CacheAllLangs()
 {
   if (mFontGroupCacheDirty) {
-    nsCOMPtr<nsIAtom> thisLang = nsStyleFont::GetLanguage(this);
+    RefPtr<nsIAtom> thisLang = nsStyleFont::GetLanguage(this);
     GetDefaultFont(kPresContext_DefaultVariableFont_ID, thisLang.get());
     GetDefaultFont(kPresContext_DefaultVariableFont_ID, nsGkAtoms::x_math);
     // https://bugzilla.mozilla.org/show_bug.cgi?id=1362599#c12
     GetDefaultFont(kPresContext_DefaultVariableFont_ID, nsGkAtoms::Unicode);
     for (auto iter = mLanguagesUsed.Iter(); !iter.Done(); iter.Next()) {
 
       GetDefaultFont(kPresContext_DefaultVariableFont_ID, iter.Get()->GetKey());
     }
--- a/layout/base/nsPresContext.h
+++ b/layout/base/nsPresContext.h
@@ -1284,29 +1284,29 @@ protected:
   RefPtr<mozilla::EventStateManager> mEventManager;
   RefPtr<nsRefreshDriver> mRefreshDriver;
   RefPtr<mozilla::EffectCompositor> mEffectCompositor;
   RefPtr<nsTransitionManager> mTransitionManager;
   RefPtr<nsAnimationManager> mAnimationManager;
   RefPtr<mozilla::RestyleManager> mRestyleManager;
   RefPtr<mozilla::CounterStyleManager> mCounterStyleManager;
   nsIAtom* MOZ_UNSAFE_REF("always a static atom") mMedium; // initialized by subclass ctors
-  nsCOMPtr<nsIAtom> mMediaEmulated;
+  RefPtr<nsIAtom> mMediaEmulated;
   RefPtr<gfxFontFeatureValueSet> mFontFeatureValuesLookup;
 
   // This pointer is nulled out through SetLinkHandler() in the destructors of
   // the classes which set it. (using SetLinkHandler() again).
   nsILinkHandler* MOZ_NON_OWNING_REF mLinkHandler;
 
   // Formerly mLangGroup; moving from charset-oriented langGroup to
   // maintaining actual language settings everywhere (see bug 524107).
   // This may in fact hold a langGroup such as x-western rather than
   // a specific language, however (e.g, if it is inferred from the
   // charset rather than explicitly specified as a lang attribute).
-  nsCOMPtr<nsIAtom>     mLanguage;
+  RefPtr<nsIAtom>     mLanguage;
 
 public:
   // The following are public member variables so that we can use them
   // with mozilla::AutoToggle or mozilla::AutoRestore.
 
   // Should we disable font size inflation because we're inside of
   // shrink-wrapping calculations on an inflation container?
   bool                  mInflationDisabledForShrinkWrap;
--- a/layout/generic/nsGfxScrollFrame.cpp
+++ b/layout/generic/nsGfxScrollFrame.cpp
@@ -1826,17 +1826,17 @@ public:
   void InitSmoothScroll(TimeStamp aTime, nsPoint aDestination,
                         nsIAtom *aOrigin, const nsRect& aRange,
                         const nsSize& aCurrentVelocity);
   void Init(const nsRect& aRange) {
     mRange = aRange;
   }
 
   // Most recent scroll origin.
-  nsCOMPtr<nsIAtom> mOrigin;
+  RefPtr<nsIAtom> mOrigin;
 
   // Allowed destination positions around mDestination
   nsRect mRange;
   bool mIsSmoothScroll;
 
 private:
   void InitPreferences(TimeStamp aTime, nsIAtom *aOrigin);
 
--- a/layout/generic/nsTextRunTransformations.cpp
+++ b/layout/generic/nsTextRunTransformations.cpp
@@ -267,17 +267,17 @@ GetCasingFor(const nsIAtom* aLang)
     return eLSCB_Irish;
   }
 
   // Is there a region subtag we should ignore?
   nsAtomString langStr(const_cast<nsIAtom*>(aLang));
   int index = langStr.FindChar('-');
   if (index > 0) {
     langStr.Truncate(index);
-    nsCOMPtr<nsIAtom> truncatedLang = NS_Atomize(langStr);
+    RefPtr<nsIAtom> truncatedLang = NS_Atomize(langStr);
     return GetCasingFor(truncatedLang);
   }
 
   return eLSCB_None;
 }
 
 bool
 nsCaseTransformTextRunFactory::TransformString(
--- a/layout/generic/nsTextRunTransformations.h
+++ b/layout/generic/nsTextRunTransformations.h
@@ -22,17 +22,17 @@ struct nsTransformedCharStyle final {
     , mLanguage(aContext->StyleFont()->mLanguage)
     , mPresContext(aContext->PresContext())
     , mScriptSizeMultiplier(aContext->StyleFont()->mScriptSizeMultiplier)
     , mTextTransform(aContext->StyleText()->mTextTransform)
     , mMathVariant(aContext->StyleFont()->mMathVariant)
     , mExplicitLanguage(aContext->StyleFont()->mExplicitLanguage) {}
 
   nsFont                  mFont;
-  nsCOMPtr<nsIAtom>       mLanguage;
+  RefPtr<nsIAtom>       mLanguage;
   RefPtr<nsPresContext> mPresContext;
   float                   mScriptSizeMultiplier;
   uint8_t                 mTextTransform;
   uint8_t                 mMathVariant;
   bool                    mExplicitLanguage;
   bool                    mForceNonFullWidth = false;
 
 private:
--- a/layout/inspector/inDOMUtils.cpp
+++ b/layout/inspector/inDOMUtils.cpp
@@ -219,17 +219,17 @@ NS_IMETHODIMP
 inDOMUtils::GetCSSStyleRules(nsIDOMElement *aElement,
                              const nsAString& aPseudo,
                              nsIArrayExtensions **_retval)
 {
   NS_ENSURE_ARG_POINTER(aElement);
 
   *_retval = nullptr;
 
-  nsCOMPtr<nsIAtom> pseudoElt;
+  RefPtr<nsIAtom> pseudoElt;
   if (!aPseudo.IsEmpty()) {
     pseudoElt = NS_Atomize(aPseudo);
   }
 
   nsCOMPtr<Element> element = do_QueryInterface(aElement);
   NS_ENSURE_STATE(element);
   RefPtr<nsStyleContext> styleContext =
     GetCleanStyleContextForElement(element, pseudoElt);
@@ -1202,17 +1202,17 @@ GetStatesForPseudoClass(const nsAString&
     // index out of bounds into this array no matter what.
     EventStates(),
     EventStates()
   };
   static_assert(MOZ_ARRAY_LENGTH(sPseudoClassStates) ==
                 static_cast<size_t>(CSSPseudoClassType::MAX),
                 "Length of PseudoClassStates array is incorrect");
 
-  nsCOMPtr<nsIAtom> atom = NS_Atomize(aStatePseudo);
+  RefPtr<nsIAtom> atom = NS_Atomize(aStatePseudo);
   CSSPseudoClassType type = nsCSSPseudoClasses::
     GetPseudoType(atom, CSSEnabledState::eIgnoreEnabledState);
 
   // Ignore :any-link so we don't give the element simultaneous
   // visited and unvisited style state
   if (type == CSSPseudoClassType::anyLink ||
       type == CSSPseudoClassType::mozAnyLink) {
     return EventStates();
--- a/layout/style/CounterStyleManager.cpp
+++ b/layout/style/CounterStyleManager.cpp
@@ -1133,17 +1133,17 @@ private:
   void ComputeRawSpeakAs(uint8_t& aSpeakAs,
                          CounterStyle*& aSpeakAsCounter);
   CounterStyle* ComputeSpeakAs();
 
   CounterStyle* ComputeExtends();
   CounterStyle* GetExtends();
   CounterStyle* GetExtendsRoot();
 
-  nsCOMPtr<nsIAtom> mName;
+  RefPtr<nsIAtom> mName;
 
   // CounterStyleManager should always overlive any CounterStyle as it
   // is owned by nsPresContext, and will be released after all nodes and
   // frames are released.
   CounterStyleManager* mManager;
 
   RefPtr<nsCSSCounterStyleRule> mRule;
   uint32_t mRuleGeneration;
--- a/layout/style/NameSpaceRule.h
+++ b/layout/style/NameSpaceRule.h
@@ -47,17 +47,17 @@ public:
   void GetURLSpec(nsString& aURLSpec) const final { aURLSpec = mURLSpec; }
 
   // WebIDL interface
   void GetCssTextImpl(nsAString& aCssText) const override;
 
   size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const final;
 
 private:
-  nsCOMPtr<nsIAtom> mPrefix;
+  RefPtr<nsIAtom> mPrefix;
   nsString          mURLSpec;
 };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(NameSpaceRule, NS_CSS_NAMESPACE_RULE_IMPL_CID)
 
 } // namespace css
 } // namespace mozilla
 
--- a/layout/style/ServoBindings.cpp
+++ b/layout/style/ServoBindings.cpp
@@ -900,17 +900,17 @@ Gecko_GetXMLLangValue(RawGeckoElementBor
     aElement->GetParsedAttr(nsGkAtoms::lang, kNameSpaceID_XML);
 
   if (!attr) {
     return nullptr;
   }
 
   MOZ_ASSERT(attr->Type() == nsAttrValue::eAtom);
 
-  nsCOMPtr<nsIAtom> atom = attr->GetAtomValue();
+  RefPtr<nsIAtom> atom = attr->GetAtomValue();
   return atom.forget().take();
 }
 
 nsIDocument::DocumentTheme
 Gecko_GetDocumentLWTheme(const nsIDocument* aDocument)
 {
   return aDocument->ThreadSafeGetDocumentLWTheme();
 }
@@ -934,17 +934,17 @@ LangValue(Implementor* aElement)
     attr = aElement->GetParsedAttr(nsGkAtoms::lang);
   }
 
   if (!attr) {
     return nullptr;
   }
 
   MOZ_ASSERT(attr->Type() == nsAttrValue::eAtom);
-  nsCOMPtr<nsIAtom> atom = attr->GetAtomValue();
+  RefPtr<nsIAtom> atom = attr->GetAtomValue();
   return atom.forget().take();
 }
 
 template <typename Implementor, typename MatchFn>
 static bool
 DoMatch(Implementor* aElement, nsIAtom* aNS, nsIAtom* aName, MatchFn aMatch)
 {
   if (MOZ_LIKELY(aNS)) {
@@ -1107,17 +1107,17 @@ ClassOrClassList(Implementor* aElement, 
   if (attr->Type() == nsAttrValue::eAtom) {
     *aClass = attr->GetAtomValue();
     return 1;
   }
 
   // At this point we should have an atom array. It is likely, but not
   // guaranteed, that we have two or more elements in the array.
   MOZ_ASSERT(attr->Type() == nsAttrValue::eAtomArray);
-  nsTArray<nsCOMPtr<nsIAtom>>* atomArray = attr->GetAtomArrayValue();
+  nsTArray<RefPtr<nsIAtom>>* atomArray = attr->GetAtomArrayValue();
   uint32_t length = atomArray->Length();
 
   // Special case: zero elements.
   if (length == 0) {
     return 0;
   }
 
   // Special case: one element.
@@ -1126,20 +1126,20 @@ ClassOrClassList(Implementor* aElement, 
     return 1;
   }
 
   // General case: Two or more elements.
   //
   // Note: We could also expose this array as an array of nsCOMPtrs, since
   // bindgen knows what those look like, and eliminate the reinterpret_cast.
   // But it's not obvious that that would be preferable.
-  static_assert(sizeof(nsCOMPtr<nsIAtom>) == sizeof(nsIAtom*), "Bad simplification");
-  static_assert(alignof(nsCOMPtr<nsIAtom>) == alignof(nsIAtom*), "Bad simplification");
-
-  nsCOMPtr<nsIAtom>* elements = atomArray->Elements();
+  static_assert(sizeof(RefPtr<nsIAtom>) == sizeof(nsIAtom*), "Bad simplification");
+  static_assert(alignof(RefPtr<nsIAtom>) == alignof(nsIAtom*), "Bad simplification");
+
+  RefPtr<nsIAtom>* elements = atomArray->Elements();
   nsIAtom** rawElements = reinterpret_cast<nsIAtom**>(elements);
   *aClassList = rawElements;
   return atomArray->Length();
 }
 
 #define SERVO_IMPL_ELEMENT_ATTR_MATCHING_FUNCTIONS(prefix_, implementor_)        \
   nsIAtom* prefix_##AtomAttrValue(implementor_ aElement, nsIAtom* aName)         \
   {                                                                              \
@@ -1394,17 +1394,17 @@ Gecko_CopyImageOrientationFrom(nsStyleVi
 
 void
 Gecko_SetCounterStyleToName(CounterStylePtr* aPtr, nsIAtom* aName,
                             RawGeckoPresContextBorrowed aPresContext)
 {
   // Try resolving the counter style if possible, and keep it unresolved
   // otherwise.
   CounterStyleManager* manager = aPresContext->CounterStyleManager();
-  nsCOMPtr<nsIAtom> name = already_AddRefed<nsIAtom>(aName);
+  RefPtr<nsIAtom> name = already_AddRefed<nsIAtom>(aName);
   if (CounterStyle* style = manager->GetCounterStyle(name)) {
     *aPtr = style;
   } else {
     *aPtr = name.forget();
   }
 }
 
 void
@@ -2374,17 +2374,17 @@ FontSizePrefs::CopyFrom(const LangGroupF
   mDefaultCursiveSize = prefs.mDefaultCursiveFont.size;
   mDefaultFantasySize = prefs.mDefaultFantasyFont.size;
 }
 
 FontSizePrefs
 Gecko_GetBaseSize(nsIAtom* aLanguage)
 {
   LangGroupFontPrefs prefs;
-  nsCOMPtr<nsIAtom> langGroupAtom = StaticPresData::Get()->GetUncachedLangGroup(aLanguage);
+  RefPtr<nsIAtom> langGroupAtom = StaticPresData::Get()->GetUncachedLangGroup(aLanguage);
 
   prefs.Initialize(langGroupAtom);
   FontSizePrefs sizes;
   sizes.CopyFrom(prefs);
 
   return sizes;
 }
 
--- a/layout/style/ServoKeyframesRule.cpp
+++ b/layout/style/ServoKeyframesRule.cpp
@@ -256,17 +256,17 @@ ServoKeyframesRule::GetName(nsAString& a
   nsIAtom* name = Servo_KeyframesRule_GetName(mRawRule);
   aName = nsDependentAtomString(name);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 ServoKeyframesRule::SetName(const nsAString& aName)
 {
-  nsCOMPtr<nsIAtom> name = NS_Atomize(aName);
+  RefPtr<nsIAtom> name = NS_Atomize(aName);
   nsIAtom* oldName = Servo_KeyframesRule_GetName(mRawRule);
   if (name == oldName) {
     return NS_OK;
   }
 
   UpdateRule([this, &name]() {
     Servo_KeyframesRule_SetName(mRawRule, name.forget().take());
   });
--- a/layout/style/ServoSpecifiedValues.cpp
+++ b/layout/style/ServoSpecifiedValues.cpp
@@ -30,17 +30,17 @@ ServoSpecifiedValues::PropertyIsSet(nsCS
 {
   return Servo_DeclarationBlock_PropertyIsSet(mDecl, aId);
 }
 
 void
 ServoSpecifiedValues::SetIdentStringValue(nsCSSPropertyID aId,
                                           const nsString& aValue)
 {
-  nsCOMPtr<nsIAtom> atom = NS_Atomize(aValue);
+  RefPtr<nsIAtom> atom = NS_Atomize(aValue);
   SetIdentAtomValue(aId, atom);
 }
 
 void
 ServoSpecifiedValues::SetIdentAtomValue(nsCSSPropertyID aId, nsIAtom* aValue)
 {
   Servo_DeclarationBlock_SetIdentStringValue(mDecl, aId, aValue);
   if (aId == eCSSProperty__x_lang) {
--- a/layout/style/ServoStyleRule.cpp
+++ b/layout/style/ServoStyleRule.cpp
@@ -277,17 +277,17 @@ ServoStyleRule::GetSpecificity(uint32_t 
 nsresult
 ServoStyleRule::SelectorMatchesElement(Element* aElement,
                                        uint32_t aSelectorIndex,
                                        const nsAString& aPseudo,
                                        bool* aMatches)
 {
   CSSPseudoElementType pseudoType = CSSPseudoElementType::NotPseudo;
   if (!aPseudo.IsEmpty()) {
-    nsCOMPtr<nsIAtom> pseudoElt = NS_Atomize(aPseudo);
+    RefPtr<nsIAtom> pseudoElt = NS_Atomize(aPseudo);
     pseudoType = nsCSSPseudoElements::GetPseudoType(
         pseudoElt, CSSEnabledState::eIgnoreEnabledState);
 
     if (pseudoType == CSSPseudoElementType::NotPseudo) {
       *aMatches = false;
       return NS_OK;
     }
   }
--- a/layout/style/StyleRule.cpp
+++ b/layout/style/StyleRule.cpp
@@ -1484,17 +1484,17 @@ StyleRule::SelectorMatchesElement(Elemen
   if (aPseudo.IsEmpty() == sel->mSelectors->IsPseudoElement()) {
     *aMatches = false;
     return NS_OK;
   }
 
   if (!aPseudo.IsEmpty()) {
     // We need to make sure that the requested pseudo element type
     // matches the selector pseudo element type before proceeding.
-    nsCOMPtr<nsIAtom> pseudoElt = NS_Atomize(aPseudo);
+    RefPtr<nsIAtom> pseudoElt = NS_Atomize(aPseudo);
     if (sel->mSelectors->PseudoType() != nsCSSPseudoElements::
           GetPseudoType(pseudoElt, CSSEnabledState::eIgnoreEnabledState)) {
       *aMatches = false;
       return NS_OK;
     }
 
     // We have a matching pseudo element, now remove it so we can compare
     // directly against |element| when proceeding into SelectorListMatches.
--- a/layout/style/StyleRule.h
+++ b/layout/style/StyleRule.h
@@ -37,17 +37,17 @@ public:
   explicit nsAtomList(const nsString& aAtomValue);
   ~nsAtomList(void);
 
   /** Do a deep clone.  Should be used only on the first in the linked list. */
   nsAtomList* Clone() const { return Clone(true); }
 
   size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
 
-  nsCOMPtr<nsIAtom> mAtom;
+  RefPtr<nsIAtom> mAtom;
   nsAtomList*       mNext;
 private:
   nsAtomList* Clone(bool aDeep) const;
 
   nsAtomList(const nsAtomList& aCopy) = delete;
   nsAtomList& operator=(const nsAtomList& aCopy) = delete;
 };
 
@@ -125,18 +125,18 @@ public:
   bool IsValueCaseSensitive(bool aInHTML) const {
     return mValueCaseSensitivity == ValueCaseSensitivity::CaseSensitive ||
       (!aInHTML &&
        mValueCaseSensitivity == ValueCaseSensitivity::CaseInsensitiveInHTML);
   }
 
   nsString        mValue;
   nsAttrSelector* mNext;
-  nsCOMPtr<nsIAtom> mLowercaseAttr;
-  nsCOMPtr<nsIAtom> mCasedAttr;
+  RefPtr<nsIAtom> mLowercaseAttr;
+  RefPtr<nsIAtom> mCasedAttr;
   int32_t         mNameSpace;
   uint8_t         mFunction;
   ValueCaseSensitivity mValueCaseSensitivity;
 
 private:
   nsAttrSelector* Clone(bool aDeep) const;
 
   nsAttrSelector(const nsAttrSelector& aCopy) = delete;
@@ -221,18 +221,18 @@ public:
   }
 
   size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
 
   // For case-sensitive documents, mLowercaseTag is the same as mCasedTag,
   // but in case-insensitive documents (HTML) mLowercaseTag is lowercase.
   // Also, for pseudo-elements mCasedTag will be null but mLowercaseTag
   // contains their name.
-  nsCOMPtr<nsIAtom> mLowercaseTag;
-  nsCOMPtr<nsIAtom> mCasedTag;
+  RefPtr<nsIAtom> mLowercaseTag;
+  RefPtr<nsIAtom> mCasedTag;
   nsAtomList*     mIDList;
   nsAtomList*     mClassList;
   nsPseudoClassList* mPseudoClassList; // atom for the pseudo, string for
                                        // the argument to functional pseudos
   nsAttrSelector* mAttrList;
   nsCSSSelector*  mNegations;
   nsCSSSelector*  mNext;
   int32_t         mNameSpace;
--- a/layout/style/nsCSSCounterStyleRule.h
+++ b/layout/style/nsCSSCounterStyleRule.h
@@ -97,14 +97,14 @@ public:
 
 private:
   typedef decltype(&nsCSSCounterStyleRule::GetSymbols) Getter;
   static const Getter kGetters[];
 
   nsresult GetDescriptor(nsCSSCounterDesc aDescID, nsAString& aValue);
   nsresult SetDescriptor(nsCSSCounterDesc aDescID, const nsAString& aValue);
 
-  nsCOMPtr<nsIAtom> mName;
+  RefPtr<nsIAtom> mName;
   nsCSSValue mValues[eCSSCounterDesc_COUNT];
   uint32_t   mGeneration;
 };
 
 #endif // nsCSSCounterStyleRule_h
--- a/layout/style/nsCSSParser.cpp
+++ b/layout/style/nsCSSParser.cpp
@@ -2942,17 +2942,17 @@ CSSParserImpl::ParsePropertyWithVariable
 
 already_AddRefed<nsIAtom>
 CSSParserImpl::ParseCounterStyleName(const nsAString& aBuffer, nsIURI* aURL)
 {
   nsCSSScanner scanner(aBuffer, 0);
   css::ErrorReporter reporter(scanner, mSheet, mChildLoader, aURL);
   InitScanner(scanner, reporter, aURL, aURL, nullptr);
 
-  nsCOMPtr<nsIAtom> name = ParseCounterStyleName(true);
+  RefPtr<nsIAtom> name = ParseCounterStyleName(true);
   bool success = name && !GetToken(true);
 
   OUTPUT_ERROR();
   ReleaseScanner();
 
   return success ? name.forget() : nullptr;
 }
 
@@ -3352,17 +3352,17 @@ CSSParserImpl::ParseMediaQuery(eMediaQue
     }
   } else if (singleCondition) {
     // Since we are only trying to consume a single condition, which precludes
     // media types and not/only, this should be the same as reaching immediate
     // EOF (no condition to parse)
     *aHitStop = true;
     return true;
   } else {
-    nsCOMPtr<nsIAtom> mediaType;
+    RefPtr<nsIAtom> mediaType;
     bool gotNotOrOnly = false;
     for (;;) {
       if (!GetToken(true)) {
         REPORT_UNEXPECTED_EOF(PEGatherMediaEOF);
         return false;
       }
       if (eCSSToken_Ident != mToken.mType) {
         REPORT_UNEXPECTED_TOKEN(PEGatherMediaNotIdent);
@@ -3518,17 +3518,17 @@ CSSParserImpl::ParseMediaQueryExpression
     featureString.Rebind(featureString, 4);
   } else if (StringBeginsWith(featureString, NS_LITERAL_STRING("max-"))) {
     expr->mRange = nsMediaExpression::eMax;
     featureString.Rebind(featureString, 4);
   } else {
     expr->mRange = nsMediaExpression::eEqual;
   }
 
-  nsCOMPtr<nsIAtom> mediaFeatureAtom = NS_Atomize(featureString);
+  RefPtr<nsIAtom> mediaFeatureAtom = NS_Atomize(featureString);
   const nsMediaFeature *feature = nsMediaFeatures::features;
   for (; feature->mName; ++feature) {
     // See if name matches & all requirement flags are satisfied:
     // (We check requirements by turning off all of the flags that have been
     // satisfied, and then see if the result is 0.)
     if (*(feature->mName) == mediaFeatureAtom &&
         !(feature->mReqFlags & ~satisfiedReqFlags)) {
       break;
@@ -3879,17 +3879,17 @@ CSSParserImpl::ParseNameSpaceRule(RuleAp
 void
 CSSParserImpl::ProcessNameSpace(const nsString& aPrefix,
                                 const nsString& aURLSpec,
                                 RuleAppendFunc aAppendFunc,
                                 void* aData,
                                 uint32_t aLineNumber,
                                 uint32_t aColumnNumber)
 {
-  nsCOMPtr<nsIAtom> prefix;
+  RefPtr<nsIAtom> prefix;
 
   if (!aPrefix.IsEmpty()) {
     prefix = NS_Atomize(aPrefix);
   }
 
   RefPtr<css::NameSpaceRule> rule = new css::NameSpaceRule(prefix, aURLSpec,
                                                              aLineNumber,
                                                              aColumnNumber);
@@ -4707,17 +4707,17 @@ CSSParserImpl::ParseSupportsConditionTer
       return true;
     }
   }
 }
 
 bool
 CSSParserImpl::ParseCounterStyleRule(RuleAppendFunc aAppendFunc, void* aData)
 {
-  nsCOMPtr<nsIAtom> name;
+  RefPtr<nsIAtom> name;
   uint32_t linenum, colnum;
   if (!GetNextTokenLocation(true, &linenum, &colnum) ||
       !(name = ParseCounterStyleName(true))) {
     REPORT_UNEXPECTED_TOKEN(PECounterStyleNotIdent);
     return false;
   }
 
   if (!ExpectSymbol('{', true)) {
@@ -4829,17 +4829,17 @@ CSSParserImpl::ParseCounterStyleName(boo
     ToLowerCase(name);
   }
   return NS_Atomize(name);
 }
 
 bool
 CSSParserImpl::ParseCounterStyleNameValue(nsCSSValue& aValue)
 {
-  if (nsCOMPtr<nsIAtom> name = ParseCounterStyleName(false)) {
+  if (RefPtr<nsIAtom> name = ParseCounterStyleName(false)) {
     aValue.SetAtomIdentValue(name.forget());
     return true;
   }
   return false;
 }
 
 bool
 CSSParserImpl::ParseCounterDescriptor(nsCSSCounterStyleRule* aRule)
@@ -5863,17 +5863,17 @@ CSSParserImpl::ParsePseudoSelector(int32
   }
 
   // OK, now we know we have an mIdent.  Atomize it.  All the atoms, for
   // pseudo-classes as well as pseudo-elements, start with a single ':'.
   nsAutoString buffer;
   buffer.Append(char16_t(':'));
   buffer.Append(mToken.mIdent);
   nsContentUtils::ASCIIToLower(buffer);
-  nsCOMPtr<nsIAtom> pseudo = NS_Atomize(buffer);
+  RefPtr<nsIAtom> pseudo = NS_Atomize(buffer);
 
   // stash away some info about this pseudo so we only have to get it once.
   bool isTreePseudo = false;
   CSSEnabledState enabledState = EnabledState();
   CSSPseudoElementType pseudoElementType =
     nsCSSPseudoElements::GetPseudoType(pseudo, enabledState);
   CSSPseudoClassType pseudoClassType =
     nsCSSPseudoClasses::GetPseudoType(pseudo, enabledState);
@@ -6405,17 +6405,17 @@ CSSParserImpl::ParseSelector(nsCSSSelect
                              char16_t aPrevCombinator)
 {
   if (! GetToken(true)) {
     REPORT_UNEXPECTED_EOF(PESelectorEOF);
     return false;
   }
 
   nsCSSSelector* selector = aList->AddSelector(aPrevCombinator);
-  nsCOMPtr<nsIAtom> pseudoElement;
+  RefPtr<nsIAtom> pseudoElement;
   nsAutoPtr<nsAtomList> pseudoElementArgs;
   CSSPseudoElementType pseudoElementType = CSSPseudoElementType::NotPseudo;
 
   int32_t dataMask = 0;
   nsSelectorParsingStatus parsingStatus =
     ParseTypeOrUniversalSelector(dataMask, *selector, false);
 
   while (parsingStatus == eSelectorParsingStatus_Continue) {
@@ -17204,17 +17204,17 @@ CSSParserImpl::ParseShadowList(nsCSSProp
 int32_t
 CSSParserImpl::GetNamespaceIdForPrefix(const nsString& aPrefix)
 {
   NS_PRECONDITION(!aPrefix.IsEmpty(), "Must have a prefix here");
 
   int32_t nameSpaceID = kNameSpaceID_Unknown;
   if (mNameSpaceMap) {
     // user-specified identifiers are case-sensitive (bug 416106)
-    nsCOMPtr<nsIAtom> prefix = NS_Atomize(aPrefix);
+    RefPtr<nsIAtom> prefix = NS_Atomize(aPrefix);
     nameSpaceID = mNameSpaceMap->FindNameSpaceID(prefix);
   }
   // else no declared namespaces
 
   if (nameSpaceID == kNameSpaceID_Unknown) {   // unknown prefix, dump it
     REPORT_UNEXPECTED_P(PEUnknownNamespacePrefix, aPrefix);
   }
 
--- a/layout/style/nsCSSPseudoElements.cpp
+++ b/layout/style/nsCSSPseudoElements.cpp
@@ -132,17 +132,17 @@ nsCSSPseudoElements::GetPseudoAtom(const
   aPseudoElement.EndReading(end);
   NS_ASSERTION(start != end, "aPseudoElement is not empty!");
   ++start;
   bool haveTwoColons = true;
   if (start == end || *start != char16_t(':')) {
     --start;
     haveTwoColons = false;
   }
-  nsCOMPtr<nsIAtom> pseudo = NS_Atomize(Substring(start, end));
+  RefPtr<nsIAtom> pseudo = NS_Atomize(Substring(start, end));
   MOZ_ASSERT(pseudo);
 
   // There aren't any non-CSS2 pseudo-elements with a single ':'
   if (!haveTwoColons &&
       (!IsPseudoElement(pseudo) || !IsCSS2PseudoElement(pseudo))) {
     // XXXbz I'd really rather we threw an exception or something, but
     // the DOM spec sucks.
     return nullptr;
--- a/layout/style/nsCSSRuleProcessor.cpp
+++ b/layout/style/nsCSSRuleProcessor.cpp
@@ -61,17 +61,17 @@ using namespace mozilla;
 using namespace mozilla::dom;
 
 typedef ArenaAllocator<4096, 8> CascadeAllocator;
 
 #define VISITED_PSEUDO_PREF "layout.css.visited_links_enabled"
 
 static bool gSupportVisitedPseudo = true;
 
-static nsTArray< nsCOMPtr<nsIAtom> >* sSystemMetrics = 0;
+static nsTArray< RefPtr<nsIAtom> >* sSystemMetrics = 0;
 
 #ifdef XP_WIN
 uint8_t nsCSSRuleProcessor::sWinThemeId = LookAndFeel::eWindowsTheme_Generic;
 #endif
 
 /**
  * A struct representing a given CSS rule and a particular selector
  * from that rule's selector list.
@@ -177,17 +177,17 @@ struct RuleHashTableEntry : public PLDHa
   // logic in SizeOfRuleHashTable().
   // Auto length 1, because we always have at least one entry in mRules.
   AutoTArray<RuleValue, 1> mRules;
 };
 
 struct RuleHashTagTableEntry : public RuleHashTableEntry {
   // If you add members that have heap allocated memory be sure to change the
   // logic in RuleHash::SizeOf{In,Ex}cludingThis.
-  nsCOMPtr<nsIAtom> mTag;
+  RefPtr<nsIAtom> mTag;
 };
 
 static PLDHashNumber
 RuleHash_CIHashKey(const void *key)
 {
   nsIAtom *atom = const_cast<nsIAtom*>(static_cast<const nsIAtom*>(key));
 
   nsAutoString str;
@@ -1077,17 +1077,17 @@ nsCSSRuleProcessor::VisitedLinksEnabled(
 /* static */ void
 nsCSSRuleProcessor::InitSystemMetrics()
 {
   if (sSystemMetrics)
     return;
 
   MOZ_ASSERT(NS_IsMainThread());
 
-  sSystemMetrics = new nsTArray< nsCOMPtr<nsIAtom> >;
+  sSystemMetrics = new nsTArray< RefPtr<nsIAtom> >;
 
   /***************************************************************************
    * ANY METRICS ADDED HERE SHOULD ALSO BE ADDED AS MEDIA QUERIES IN         *
    * nsMediaFeatures.cpp                                                     *
    ***************************************************************************/
 
   int32_t metricResult =
     LookAndFeel::GetInt(LookAndFeel::eIntID_ScrollArrowStyle);
@@ -1783,17 +1783,17 @@ nsCSSRuleProcessor::StringPseudoMatches(
           // Selectors specifying other directions never match.
           return false;
         }
       }
       break;
 
     case CSSPseudoClassType::mozSystemMetric:
       {
-        nsCOMPtr<nsIAtom> metric = NS_Atomize(aString);
+        RefPtr<nsIAtom> metric = NS_Atomize(aString);
         if (!nsCSSRuleProcessor::HasSystemMetric(metric)) {
           return false;
         }
       }
       break;
 
     case CSSPseudoClassType::mozEmptyExceptChildrenWithLocalname:
       {
--- a/layout/style/nsCSSRules.cpp
+++ b/layout/style/nsCSSRules.cpp
@@ -2278,17 +2278,17 @@ nsCSSCounterStyleRule::GetName(nsAString
   nsStyleUtil::AppendEscapedCSSIdent(name, aName);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsCSSCounterStyleRule::SetName(const nsAString& aName)
 {
   nsCSSParser parser;
-  if (nsCOMPtr<nsIAtom> name = parser.ParseCounterStyleName(aName, nullptr)) {
+  if (RefPtr<nsIAtom> name = parser.ParseCounterStyleName(aName, nullptr)) {
     nsIDocument* doc = GetDocument();
     MOZ_AUTO_DOC_UPDATE(doc, UPDATE_STYLE, true);
 
     mName = name;
 
     if (StyleSheet* sheet = GetStyleSheet()) {
       if (sheet->IsGecko()) {
         sheet->AsGecko()->SetModifiedByChildRule();
--- a/layout/style/nsCSSValue.cpp
+++ b/layout/style/nsCSSValue.cpp
@@ -984,17 +984,17 @@ nsCSSValue::BufferFromString(const nsStr
   data[length] = 0;
   return buffer.forget();
 }
 
 void
 nsCSSValue::AtomizeIdentValue()
 {
   MOZ_ASSERT(mUnit == eCSSUnit_Ident);
-  nsCOMPtr<nsIAtom> atom = NS_Atomize(GetStringBufferValue());
+  RefPtr<nsIAtom> atom = NS_Atomize(GetStringBufferValue());
   Reset();
   mUnit = eCSSUnit_AtomIdent;
   mValue.mAtom = atom.forget().take();
 }
 
 namespace {
 
 struct CSSValueSerializeCalcOps {
--- a/layout/style/nsComputedDOMStyle.cpp
+++ b/layout/style/nsComputedDOMStyle.cpp
@@ -5006,17 +5006,17 @@ nsComputedDOMStyle::DoGetClip()
   }
 
   return val.forget();
 }
 
 already_AddRefed<CSSValue>
 nsComputedDOMStyle::DoGetWillChange()
 {
-  const nsCOMArray<nsIAtom>& willChange = StyleDisplay()->mWillChange;
+  const nsTArray<RefPtr<nsIAtom>>& willChange = StyleDisplay()->mWillChange;
 
   if (willChange.IsEmpty()) {
     RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
     val->SetIdent(eCSSKeyword_auto);
     return val.forget();
   }
 
   RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(true);
@@ -6691,17 +6691,17 @@ nsComputedDOMStyle::DoGetMaskType()
     nsCSSProps::ValueToKeywordEnum(StyleSVGReset()->mMaskType,
                                    nsCSSProps::kMaskTypeKTable));
   return val.forget();
 }
 
 already_AddRefed<CSSValue>
 nsComputedDOMStyle::DoGetContextProperties()
 {
-  const nsTArray<nsCOMPtr<nsIAtom>>& contextProps = StyleSVG()->mContextProps;
+  const nsTArray<RefPtr<nsIAtom>>& contextProps = StyleSVG()->mContextProps;
 
   if (contextProps.IsEmpty()) {
     RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
     val->SetIdent(eCSSKeyword_none);
     return val.forget();
   }
 
   RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(true);
--- a/layout/style/nsComputedDOMStyle.h
+++ b/layout/style/nsComputedDOMStyle.h
@@ -740,17 +740,17 @@ private:
    * in this case will check that the style context is still valid to be used,
    * by checking whether flush styles results in any restyles having been
    * processed.
    *
    * Since an ArenaRefPtr is used to hold the style context, it will be cleared
    * if the pres arena from which it was allocated goes away.
    */
   mozilla::ArenaRefPtr<nsStyleContext> mStyleContext;
-  nsCOMPtr<nsIAtom> mPseudo;
+  RefPtr<nsIAtom> mPseudo;
 
   /*
    * While computing style data, the primary frame for mContent --- named "outer"
    * because we should use it to compute positioning data.  Null
    * otherwise.
    */
   nsIFrame* mOuterFrame;
   /*
--- a/layout/style/nsHTMLStyleSheet.cpp
+++ b/layout/style/nsHTMLStyleSheet.cpp
@@ -143,17 +143,17 @@ GetDiscretelyAnimatedCSSValue(nsCSSPrope
 NS_IMPL_ISUPPORTS(nsHTMLStyleSheet::LangRule, nsIStyleRule)
 
 /* virtual */ void
 nsHTMLStyleSheet::LangRule::MapRuleInfoInto(nsRuleData* aRuleData)
 {
   if (aRuleData->mSIDs & NS_STYLE_INHERIT_BIT(Font)) {
     nsCSSValue* lang = aRuleData->ValueForLang();
     if (lang->GetUnit() == eCSSUnit_Null) {
-      nsCOMPtr<nsIAtom> langAtom = mLang;
+      RefPtr<nsIAtom> langAtom = mLang;
       lang->SetAtomIdentValue(langAtom.forget());
     }
   }
 }
 
 /* virtual */ bool
 nsHTMLStyleSheet::LangRule::MightMapInheritedStyleData()
 {
--- a/layout/style/nsHTMLStyleSheet.h
+++ b/layout/style/nsHTMLStyleSheet.h
@@ -178,17 +178,17 @@ public: // for mLangRuleTable structures
     virtual void MapRuleInfoInto(nsRuleData* aRuleData) override;
     virtual bool MightMapInheritedStyleData() override;
     virtual bool GetDiscretelyAnimatedCSSValue(nsCSSPropertyID aProperty,
                                                nsCSSValue* aValue) override;
   #ifdef DEBUG
     virtual void List(FILE* out = stdout, int32_t aIndent = 0) const override;
   #endif
 
-    nsCOMPtr<nsIAtom> mLang;
+    RefPtr<nsIAtom> mLang;
   };
 
 private:
   nsIDocument*            mDocument;
   RefPtr<HTMLColorRule> mLinkRule;
   RefPtr<HTMLColorRule> mVisitedRule;
   RefPtr<HTMLColorRule> mActiveRule;
   RefPtr<RawServoDeclarationBlock> mServoUnvisitedLinkDecl;
--- a/layout/style/nsMediaList.h
+++ b/layout/style/nsMediaList.h
@@ -121,17 +121,17 @@ private:
     bool operator==(const FeatureEntry& aOther) const {
       return mFeature == aOther.mFeature &&
              mExpressions == aOther.mExpressions;
     }
     bool operator!=(const FeatureEntry& aOther) const {
       return !(*this == aOther);
     }
   };
-  nsCOMPtr<nsIAtom> mMedium;
+  RefPtr<nsIAtom> mMedium;
   nsTArray<FeatureEntry> mFeatureCache;
 };
 
 /**
  * nsDocumentRuleResultCacheKey is analagous to nsMediaQueryResultCacheKey
  * and stores the result of matching the @-moz-document rules from a set
  * of style sheets.  nsCSSRuleProcessor builds up an
  * nsDocumentRuleResultCacheKey as it visits the @-moz-document rules
@@ -238,17 +238,17 @@ public:
   bool Matches(nsPresContext* aPresContext,
                nsMediaQueryResultCacheKey* aKey) const;
 
 private:
   bool mNegated;
   bool mHasOnly; // only needed for serialization
   bool mTypeOmitted; // only needed for serialization
   bool mHadUnknownExpression;
-  nsCOMPtr<nsIAtom> mMediaType;
+  RefPtr<nsIAtom> mMediaType;
   nsTArray<nsMediaExpression> mExpressions;
 };
 
 class nsMediaList final : public mozilla::dom::MediaList
 {
 public:
   nsMediaList();
 
--- a/layout/style/nsRuleData.h
+++ b/layout/style/nsRuleData.h
@@ -132,17 +132,17 @@ struct nsRuleData final : mozilla::Gener
 
   void SetIdentStringValue(nsCSSPropertyID aId, const nsString& aValue)
   {
     ValueFor(aId)->SetStringValue(aValue, eCSSUnit_Ident);
   }
 
   void SetIdentAtomValue(nsCSSPropertyID aId, nsIAtom* aValue)
   {
-    nsCOMPtr<nsIAtom> atom = aValue;
+    RefPtr<nsIAtom> atom = aValue;
     ValueFor(aId)->SetAtomIdentValue(atom.forget());
   }
 
   void SetKeywordValue(nsCSSPropertyID aId, int32_t aValue)
   {
     ValueFor(aId)->SetIntValue(aValue, eCSSUnit_Enumerated);
   }
 
--- a/layout/style/nsRuleNode.cpp
+++ b/layout/style/nsRuleNode.cpp
@@ -1462,17 +1462,17 @@ static void SetStyleImage(GeckoStyleCont
     {
       nsStyleGradient* gradient = new nsStyleGradient();
       SetGradient(aValue, presContext, aStyleContext, *gradient, aConditions);
       aResult.SetGradientData(gradient);
       break;
     }
     case eCSSUnit_Element:
     {
-      nsCOMPtr<nsIAtom> atom = NS_Atomize(aValue.GetStringBufferValue());
+      RefPtr<nsIAtom> atom = NS_Atomize(aValue.GetStringBufferValue());
       aResult.SetElementId(atom.forget());
       break;
     }
     case eCSSUnit_Initial:
     case eCSSUnit_Unset:
     case eCSSUnit_None:
       break;
     case eCSSUnit_URL:
@@ -8102,17 +8102,17 @@ nsRuleNode::ComputeListData(void* aStart
       break;
     }
     case eCSSUnit_Enumerated: {
       // For compatibility with html attribute map. This branch should
       // never be called for value from CSS. The values can only come
       // from the items in EnumTable listed in HTMLLIElement.cpp and
       // HTMLSharedListElement.cpp.
       int32_t intValue = typeValue->GetIntValue();
-      nsCOMPtr<nsIAtom> name;
+      RefPtr<nsIAtom> name;
       switch (intValue) {
         case NS_STYLE_LIST_STYLE_LOWER_ROMAN:
           name = nsGkAtoms::lowerRoman;
           break;
         case NS_STYLE_LIST_STYLE_UPPER_ROMAN:
           name = nsGkAtoms::upperRoman;
           break;
         case NS_STYLE_LIST_STYLE_LOWER_ALPHA:
--- a/layout/style/nsStyleContext.h
+++ b/layout/style/nsStyleContext.h
@@ -334,17 +334,17 @@ protected:
     const nsStyle##name_ * DoGetStyle##name_();
 
   #include "nsStyleStructList.h"
   #undef STYLE_STRUCT_RESET
   #undef STYLE_STRUCT_INHERITED
 
   // If this style context is for a pseudo-element or anonymous box,
   // the relevant atom.
-  nsCOMPtr<nsIAtom> mPseudoTag;
+  RefPtr<nsIAtom> mPseudoTag;
 
   // mBits stores a number of things:
   //  - It records (using the style struct bits) which structs are
   //    inherited from the parent context or owned by the rule node (i.e.,
   //    not owned by the style context).
   //  - It also stores the additional bits listed at the top of
   //    nsStyleStruct.h.
   uint64_t                mBits;
--- a/layout/style/nsStyleStruct.cpp
+++ b/layout/style/nsStyleStruct.cpp
@@ -2322,17 +2322,17 @@ nsStyleImage::SetGradientData(nsStyleGra
 
 void
 nsStyleImage::SetElementId(already_AddRefed<nsIAtom> aElementId)
 {
   if (mType != eStyleImageType_Null) {
     SetNull();
   }
 
-  if (nsCOMPtr<nsIAtom> atom = aElementId) {
+  if (RefPtr<nsIAtom> atom = aElementId) {
     mElementId = atom.forget().take();
     mType = eStyleImageType_Element;
   }
 }
 
 void
 nsStyleImage::SetCropRect(UniquePtr<nsStyleSides> aCropRect)
 {
@@ -3296,17 +3296,17 @@ StyleTransition::SetInitialValues()
 void
 StyleTransition::SetUnknownProperty(nsCSSPropertyID aProperty,
                                     const nsAString& aPropertyString)
 {
   MOZ_ASSERT(nsCSSProps::LookupProperty(aPropertyString,
                                         CSSEnabledState::eForAllContent) ==
                aProperty,
              "property and property string should match");
-  nsCOMPtr<nsIAtom> temp = NS_Atomize(aPropertyString);
+  RefPtr<nsIAtom> temp = NS_Atomize(aPropertyString);
   SetUnknownProperty(aProperty, temp);
 }
 
 void
 StyleTransition::SetUnknownProperty(nsCSSPropertyID aProperty,
                                     nsIAtom* aPropertyString)
 {
   MOZ_ASSERT(aProperty == eCSSProperty_UNKNOWN ||
@@ -4094,17 +4094,17 @@ nsStyleText::nsStyleText(const nsPresCon
   , mWordSpacing(0, nsStyleCoord::CoordConstructor)
   , mLetterSpacing(eStyleUnit_Normal)
   , mLineHeight(eStyleUnit_Normal)
   , mTextIndent(0, nsStyleCoord::CoordConstructor)
   , mWebkitTextStrokeWidth(0)
   , mTextShadow(nullptr)
 {
   MOZ_COUNT_CTOR(nsStyleText);
-  nsCOMPtr<nsIAtom> language = aContext->GetContentLanguage();
+  RefPtr<nsIAtom> language = aContext->GetContentLanguage();
   mTextEmphasisPosition = language &&
     nsStyleUtil::MatchesLanguagePrefix(language, u"zh") ?
     NS_STYLE_TEXT_EMPHASIS_POSITION_DEFAULT_ZH :
     NS_STYLE_TEXT_EMPHASIS_POSITION_DEFAULT;
 }
 
 nsStyleText::nsStyleText(const nsStyleText& aSource)
   : mTextAlign(aSource.mTextAlign)
--- a/layout/style/nsStyleStruct.h
+++ b/layout/style/nsStyleStruct.h
@@ -225,17 +225,17 @@ struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsSt
   // should calls to ZoomText() and UnZoomText() be made to the font
   // size on this nsStyleFont?
   bool mAllowZoom;               // [inherited]
 
   // The value mSize would have had if scriptminsize had never been applied
   nscoord mScriptUnconstrainedSize;
   nscoord mScriptMinSize;        // [inherited] length
   float   mScriptSizeMultiplier; // [inherited]
-  nsCOMPtr<nsIAtom> mLanguage;   // [inherited]
+  RefPtr<nsIAtom> mLanguage;   // [inherited]
 };
 
 struct nsStyleGradientStop
 {
   nsStyleCoord mLocation; // percent, coord, calc, none
   nscolor mColor;
   bool mIsInterpolationHint;
 
@@ -2288,17 +2288,17 @@ struct StyleTransition
   bool operator!=(const StyleTransition& aOther) const
     { return !(*this == aOther); }
 
 private:
   nsTimingFunction mTimingFunction;
   float mDuration;
   float mDelay;
   nsCSSPropertyID mProperty;
-  nsCOMPtr<nsIAtom> mUnknownProperty; // used when mProperty is
+  RefPtr<nsIAtom> mUnknownProperty; // used when mProperty is
                                       // eCSSProperty_UNKNOWN or
                                       // eCSSPropertyExtra_variable
 };
 
 struct StyleAnimation
 {
   StyleAnimation() { /* leaves uninitialized; see also SetInitialValues */ }
   explicit StyleAnimation(const StyleAnimation& aCopy);
@@ -2669,17 +2669,17 @@ struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsSt
   uint8_t mIsolation;           // [reset] see nsStyleConsts.h
   uint8_t mTopLayer;            // [reset] see nsStyleConsts.h
   uint8_t mWillChangeBitField;  // [reset] see nsStyleConsts.h. Stores a
                                 // bitfield representation of the properties
                                 // that are frequently queried. This should
                                 // match mWillChange. Also tracks if any of the
                                 // properties in the will-change list require
                                 // a stacking context.
-  nsCOMArray<nsIAtom> mWillChange;
+  nsTArray<RefPtr<nsIAtom>> mWillChange;
 
   uint8_t mTouchAction;         // [reset] see nsStyleConsts.h
   uint8_t mScrollBehavior;      // [reset] see nsStyleConsts.h NS_STYLE_SCROLL_BEHAVIOR_*
   uint8_t mScrollSnapTypeX;     // [reset] see nsStyleConsts.h NS_STYLE_SCROLL_SNAP_TYPE_*
   uint8_t mScrollSnapTypeY;     // [reset] see nsStyleConsts.h NS_STYLE_SCROLL_SNAP_TYPE_*
   nsStyleCoord mScrollSnapPointsX; // [reset]
   nsStyleCoord mScrollSnapPointsY; // [reset]
   mozilla::Position mScrollSnapDestination; // [reset]
@@ -3463,17 +3463,17 @@ struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsSt
   nsChangeHint CalcDifference(const nsStyleSVG& aNewData) const;
 
   nsStyleSVGPaint  mFill;             // [inherited]
   nsStyleSVGPaint  mStroke;           // [inherited]
   RefPtr<mozilla::css::URLValue> mMarkerEnd;   // [inherited]
   RefPtr<mozilla::css::URLValue> mMarkerMid;   // [inherited]
   RefPtr<mozilla::css::URLValue> mMarkerStart; // [inherited]
   nsTArray<nsStyleCoord> mStrokeDasharray;  // [inherited] coord, percent, factor
-  nsTArray<nsCOMPtr<nsIAtom>> mContextProps;
+  nsTArray<RefPtr<nsIAtom>> mContextProps;
 
   nsStyleCoord     mStrokeDashoffset; // [inherited] coord, percent, factor
   nsStyleCoord     mStrokeWidth;      // [inherited] coord, percent, factor
 
   float            mFillOpacity;      // [inherited]
   float            mStrokeMiterlimit; // [inherited]
   float            mStrokeOpacity;    // [inherited]
 
--- a/layout/xul/nsMenuFrame.cpp
+++ b/layout/xul/nsMenuFrame.cpp
@@ -139,17 +139,17 @@ public:
       frame->BuildAcceleratorText(true);
     } else if (mAttr == nsGkAtoms::type || mAttr == nsGkAtoms::name) {
       frame->UpdateMenuType();
     }
     return NS_OK;
   }
 protected:
   WeakFrame         mFrame;
-  nsCOMPtr<nsIAtom> mAttr;
+  RefPtr<nsIAtom> mAttr;
 };
 
 //
 // NS_NewMenuFrame and NS_NewMenuItemFrame
 //
 // Wrappers for creating a new menu popup container
 //
 nsIFrame*
--- a/layout/xul/nsMenuPopupFrame.cpp
+++ b/layout/xul/nsMenuPopupFrame.cpp
@@ -153,17 +153,17 @@ nsMenuPopupFrame::Init(nsIContent*      
   // about that constraint.
   nsView* ourView = GetView();
   nsViewManager* viewManager = ourView->GetViewManager();
   viewManager->SetViewFloating(ourView, true);
 
   mPopupType = ePopupTypePanel;
   nsIDocument* doc = aContent->OwnerDoc();
   int32_t namespaceID;
-  nsCOMPtr<nsIAtom> tag = doc->BindingManager()->ResolveTag(aContent, &namespaceID);
+  RefPtr<nsIAtom> tag = doc->BindingManager()->ResolveTag(aContent, &namespaceID);
   if (namespaceID == kNameSpaceID_XUL) {
     if (tag == nsGkAtoms::menupopup || tag == nsGkAtoms::popup)
       mPopupType = ePopupTypeMenu;
     else if (tag == nsGkAtoms::tooltip)
       mPopupType = ePopupTypeTooltip;
   }
 
   nsCOMPtr<nsIDocShellTreeItem> dsti = PresContext()->GetDocShell();
--- a/layout/xul/nsSliderFrame.cpp
+++ b/layout/xul/nsSliderFrame.cpp
@@ -219,17 +219,17 @@ public:
 
   NS_IMETHOD Run() override
   {
     return mListener->ValueChanged(nsDependentAtomString(mWhich),
                                    mValue, mUserChanged);
   }
 
   nsCOMPtr<nsISliderListener> mListener;
-  nsCOMPtr<nsIAtom> mWhich;
+  RefPtr<nsIAtom> mWhich;
   int32_t mValue;
   bool mUserChanged;
 };
 
 class nsDragStateChangedRunnable : public Runnable
 {
 public:
   nsDragStateChangedRunnable(nsISliderListener* aListener, bool aDragBeginning)
--- a/layout/xul/nsSplitterFrame.cpp
+++ b/layout/xul/nsSplitterFrame.cpp
@@ -957,17 +957,17 @@ nsSplitterFrameInner::SetPreferredSize(n
       pref = rect.height;
   } else {
     pref = *aSize;
   }
 
   nsMargin margin(0,0,0,0);
   aChildBox->GetXULMargin(margin);
 
-  nsCOMPtr<nsIAtom> attribute;
+  RefPtr<nsIAtom> attribute;
 
   if (aIsHorizontal) {
     pref -= (margin.left + margin.right);
     attribute = nsGkAtoms::width;
   } else {
     pref -= (margin.top + margin.bottom);
     attribute = nsGkAtoms::height;
   }
--- a/layout/xul/tree/nsTreeColumns.h
+++ b/layout/xul/tree/nsTreeColumns.h
@@ -132,17 +132,17 @@ private:
   /**
    * Non-null nsIContent for the associated <treecol> element.
    */
   nsCOMPtr<nsIContent> mContent;
 
   nsTreeColumns* mColumns;
 
   nsString mId;
-  nsCOMPtr<nsIAtom> mAtom;
+  RefPtr<nsIAtom> mAtom;
 
   int32_t mIndex;
 
   bool mIsPrimary;
   bool mIsCycler;
   bool mIsEditable;
   bool mIsSelectable;
   bool mOverflow;
--- a/layout/xul/tree/nsTreeContentView.cpp
+++ b/layout/xul/tree/nsTreeContentView.cpp
@@ -1565,17 +1565,17 @@ nsTreeContentView::UpdateParentIndexes(i
       row->mParentIndex += aCount;
     }
   }
 }
 
 nsIContent*
 nsTreeContentView::GetCell(nsIContent* aContainer, nsTreeColumn& aCol)
 {
-  nsCOMPtr<nsIAtom> colAtom(aCol.GetAtom());
+  RefPtr<nsIAtom> colAtom(aCol.GetAtom());
   int32_t colIndex(aCol.GetIndex());
 
   // Traverse through cells, try to find the cell by "ref" attribute or by cell
   // index in a row. "ref" attribute has higher priority.
   nsIContent* result = nullptr;
   int32_t j = 0;
   dom::FlattenedChildIterator iter(aContainer);
   for (nsIContent* cell = iter.GetNextChild(); cell; cell = iter.GetNextChild()) {
--- a/layout/xul/tree/nsTreeStyleCache.h
+++ b/layout/xul/tree/nsTreeStyleCache.h
@@ -9,17 +9,17 @@
 #include "mozilla/Attributes.h"
 #include "nsAutoPtr.h"
 #include "nsIAtom.h"
 #include "nsCOMArray.h"
 #include "nsICSSPseudoComparator.h"
 #include "nsRefPtrHashtable.h"
 #include "nsStyleContext.h"
 
-typedef nsCOMArray<nsIAtom> AtomArray;
+typedef nsTArray<RefPtr<nsIAtom>> AtomArray;
 
 class nsTreeStyleCache
 {
 public:
   nsTreeStyleCache()
     : mNextState(0)
   {
   }
@@ -50,17 +50,17 @@ protected:
   {
   public:
     Transition(DFAState aState, nsIAtom* aSymbol);
     bool operator==(const Transition& aOther) const;
     uint32_t Hash() const;
 
   private:
     DFAState mState;
-    nsCOMPtr<nsIAtom> mInputSymbol;
+    RefPtr<nsIAtom> mInputSymbol;
   };
 
   typedef nsDataHashtable<nsGenericHashKey<Transition>, DFAState> TransitionTable;
 
   // A transition table for a deterministic finite automaton.  The DFA
   // takes as its input a single pseudoelement and an ordered set of properties.
   // It transitions on an input word that is the concatenation of the pseudoelement supplied
   // with the properties in the array.
--- a/layout/xul/tree/nsTreeUtils.cpp
+++ b/layout/xul/tree/nsTreeUtils.cpp
@@ -39,17 +39,17 @@ nsTreeUtils::TokenizeProperties(const ns
     while (iter != end && ! nsCRT::IsAsciiSpace(*iter))
       ++iter;
 
     // XXX this would be nonsensical
     NS_ASSERTION(iter != first, "eh? something's wrong here");
     if (iter == first)
       break;
 
-    nsCOMPtr<nsIAtom> atom = NS_Atomize(Substring(first, iter));
+    RefPtr<nsIAtom> atom = NS_Atomize(Substring(first, iter));
     aPropertiesArray.AppendElement(atom);
   } while (iter != end);
 
   return NS_OK;
 }
 
 nsIContent*
 nsTreeUtils::GetImmediateChild(nsIContent* aContainer, nsIAtom* aTag)
--- a/netwerk/streamconv/nsStreamConverterService.cpp
+++ b/netwerk/streamconv/nsStreamConverterService.cpp
@@ -119,39 +119,39 @@ nsStreamConverterService::AddAdjacency(c
 
     nsAutoCString fromStr, toStr;
     rv = ParseFromTo(aContractID, fromStr, toStr);
     if (NS_FAILED(rv)) return rv;
 
     // Each MIME-type is a vertex in the graph, so first lets make sure
     // each MIME-type is represented as a key in our hashtable.
 
-    nsCOMArray<nsIAtom> *fromEdges = mAdjacencyList.Get(fromStr);
+    nsTArray<RefPtr<nsIAtom>>* fromEdges = mAdjacencyList.Get(fromStr);
     if (!fromEdges) {
         // There is no fromStr vertex, create one.
-        fromEdges = new nsCOMArray<nsIAtom>();
+        fromEdges = new nsTArray<RefPtr<nsIAtom>>();
         mAdjacencyList.Put(fromStr, fromEdges);
     }
 
     if (!mAdjacencyList.Get(toStr)) {
         // There is no toStr vertex, create one.
-        mAdjacencyList.Put(toStr, new nsCOMArray<nsIAtom>());
+        mAdjacencyList.Put(toStr, new nsTArray<RefPtr<nsIAtom>>());
     }
 
     // Now we know the FROM and TO types are represented as keys in the hashtable.
     // Let's "connect" the verticies, making an edge.
 
-    nsCOMPtr<nsIAtom> vertex = NS_Atomize(toStr);
+    RefPtr<nsIAtom> vertex = NS_Atomize(toStr);
     if (!vertex) return NS_ERROR_OUT_OF_MEMORY;
 
     NS_ASSERTION(fromEdges, "something wrong in adjacency list construction");
     if (!fromEdges)
         return NS_ERROR_FAILURE;
 
-    return fromEdges->AppendObject(vertex) ? NS_OK : NS_ERROR_FAILURE;
+    return fromEdges->AppendElement(vertex) ? NS_OK : NS_ERROR_FAILURE;
 }
 
 nsresult
 nsStreamConverterService::ParseFromTo(const char *aContractID, nsCString &aFromRes, nsCString &aToRes) {
 
     nsAutoCString ContractIDStr(aContractID);
 
     int32_t fromLoc = ContractIDStr.Find("from=");
@@ -226,28 +226,28 @@ nsStreamConverterService::FindConverter(
     auto *dtorFunc = new CStreamConvDeallocator();
 
     nsDeque grayQ(dtorFunc);
 
     // Now generate the shortest path tree.
     grayQ.Push(new nsCString(fromC));
     while (0 < grayQ.GetSize()) {
         nsCString *currentHead = (nsCString*)grayQ.PeekFront();
-        nsCOMArray<nsIAtom> *data2 = mAdjacencyList.Get(*currentHead);
+        nsTArray<RefPtr<nsIAtom>>* data2 = mAdjacencyList.Get(*currentHead);
         if (!data2) return NS_ERROR_FAILURE;
 
         // Get the state of the current head to calculate the distance of each
         // reachable vertex in the loop.
         BFSTableData *headVertexState = lBFSTable.Get(*currentHead);
         if (!headVertexState) return NS_ERROR_FAILURE;
 
-        int32_t edgeCount = data2->Count();
+        int32_t edgeCount = data2->Length();
 
         for (int32_t i = 0; i < edgeCount; i++) {
-            nsIAtom* curVertexAtom = data2->ObjectAt(i);
+            nsIAtom* curVertexAtom = data2->ElementAt(i);
             auto *curVertex = new nsCString();
             curVertexAtom->ToUTF8String(*curVertex);
 
             BFSTableData *curVertexState = lBFSTable.Get(*curVertex);
             if (!curVertexState) {
                 delete curVertex;
                 return NS_ERROR_FAILURE;
             }
--- a/netwerk/streamconv/nsStreamConverterService.h
+++ b/netwerk/streamconv/nsStreamConverterService.h
@@ -35,12 +35,13 @@ private:
 
     // Responsible for finding a converter for the given MIME-type.
     nsresult FindConverter(const char *aContractID, nsTArray<nsCString> **aEdgeList);
     nsresult BuildGraph(void);
     nsresult AddAdjacency(const char *aContractID);
     nsresult ParseFromTo(const char *aContractID, nsCString &aFromRes, nsCString &aToRes);
 
     // member variables
-    nsClassHashtable<nsCStringHashKey, nsCOMArray<nsIAtom>> mAdjacencyList;
+    nsClassHashtable<nsCStringHashKey, nsTArray<RefPtr<nsIAtom>>>
+        mAdjacencyList;
 };
 
 #endif // __nsstreamconverterservice__h___
--- a/parser/html/nsHtml5TreeBuilderCppSupplement.h
+++ b/parser/html/nsHtml5TreeBuilderCppSupplement.h
@@ -77,17 +77,17 @@ nsHtml5TreeBuilder::createElement(int32_
   NS_PRECONDITION(aAttributes, "Got null attributes.");
   NS_PRECONDITION(aName, "Got null name.");
   NS_PRECONDITION(aNamespace == kNameSpaceID_XHTML || 
                   aNamespace == kNameSpaceID_SVG || 
                   aNamespace == kNameSpaceID_MathML,
                   "Bogus namespace.");
 
   if (mBuilder) {
-    nsCOMPtr<nsIAtom> name = nsHtml5TreeOperation::Reget(aName);
+    RefPtr<nsIAtom> 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() :
@@ -764,17 +764,17 @@ nsHtml5TreeBuilder::appendDoctypeToDocum
                                             nsHtml5String aSystemId)
 {
   NS_PRECONDITION(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) {
-    nsCOMPtr<nsIAtom> name = nsHtml5TreeOperation::Reget(aName);
+    RefPtr<nsIAtom> name = nsHtml5TreeOperation::Reget(aName);
     nsresult rv = nsHtml5TreeOperation::AppendDoctypeToDocument(
       name, publicId, systemId, mBuilder);
     if (NS_FAILED(rv)) {
       MarkAsBrokenAndRequestSuspension(rv);
     }
     return;
   }
 
--- a/parser/html/nsHtml5TreeOperation.cpp
+++ b/parser/html/nsHtml5TreeOperation.cpp
@@ -310,17 +310,17 @@ nsHtml5TreeOperation::AddAttributes(nsIC
   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
-    nsCOMPtr<nsIAtom> localName =
+    RefPtr<nsIAtom> localName =
       Reget(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(
@@ -415,19 +415,19 @@ nsHtml5TreeOperation::CreateHTMLElement(
   for (int32_t i = 0; i < len; i++) {
     nsHtml5String val = aAttributes->getValueNoBoundsCheck(i);
     nsIAtom* 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
-      nsCOMPtr<nsIAtom> localName =
+      RefPtr<nsIAtom> localName =
         Reget(aAttributes->getLocalNameNoBoundsCheck(i));
-      nsCOMPtr<nsIAtom> prefix = aAttributes->getPrefixNoBoundsCheck(i);
+      RefPtr<nsIAtom> 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);
@@ -507,19 +507,19 @@ nsHtml5TreeOperation::CreateSVGElement(
   for (int32_t i = 0; i < len; i++) {
     nsHtml5String val = aAttributes->getValueNoBoundsCheck(i);
     nsIAtom* 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
-      nsCOMPtr<nsIAtom> localName =
+      RefPtr<nsIAtom> localName =
         Reget(aAttributes->getLocalNameNoBoundsCheck(i));
-      nsCOMPtr<nsIAtom> prefix = aAttributes->getPrefixNoBoundsCheck(i);
+      RefPtr<nsIAtom> 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;
@@ -561,19 +561,19 @@ nsHtml5TreeOperation::CreateMathMLElemen
   for (int32_t i = 0; i < len; i++) {
     nsHtml5String val = aAttributes->getValueNoBoundsCheck(i);
     nsIAtom* 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
-      nsCOMPtr<nsIAtom> localName =
+      RefPtr<nsIAtom> localName =
         Reget(aAttributes->getLocalNameNoBoundsCheck(i));
-      nsCOMPtr<nsIAtom> prefix = aAttributes->getPrefixNoBoundsCheck(i);
+      RefPtr<nsIAtom> 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;
@@ -794,17 +794,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;
-      nsCOMPtr<nsIAtom> name = Reget(mTwo.atom);
+      RefPtr<nsIAtom> name = Reget(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();
@@ -818,17 +818,17 @@ nsHtml5TreeOperation::Perform(nsHtml5Tre
                                   aBuilder,
                                   creator);
       return NS_OK;
     }
     case eTreeOpCreateSVGElementNetwork:
     case eTreeOpCreateSVGElementNotNetwork: {
       nsIContent** target = mOne.node;
       mozilla::dom::SVGContentCreatorFunction creator = mFour.svgCreator;
-      nsCOMPtr<nsIAtom> name = Reget(mTwo.atom);
+      RefPtr<nsIAtom> name = Reget(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();
@@ -840,17 +840,17 @@ nsHtml5TreeOperation::Perform(nsHtml5Tre
                                    : dom::FROM_PARSER_DOCUMENT_WRITE,
                                  nodeInfoManager,
                                  aBuilder,
                                  creator);
       return NS_OK;
     }
     case eTreeOpCreateMathMLElement: {
       nsIContent** target = mOne.node;
-      nsCOMPtr<nsIAtom> name = Reget(mTwo.atom);
+      RefPtr<nsIAtom> name = Reget(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();
@@ -885,17 +885,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: {
-      nsCOMPtr<nsIAtom> name = Reget(mOne.atom);
+      RefPtr<nsIAtom> name = Reget(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);
@@ -1088,18 +1088,18 @@ nsHtml5TreeOperation::Perform(nsHtml5Tre
       int32_t length = mFour.integer;
       nsDependentString baseUrl(buffer, length);
       aBuilder->AddBase(baseUrl);
       return NS_OK;
     }
     case eTreeOpAddError: {
       nsIContent* node = *(mOne.node);
       char* msgId = mTwo.charPtr;
-      nsCOMPtr<nsIAtom> atom = Reget(mThree.atom);
-      nsCOMPtr<nsIAtom> otherAtom = Reget(mFour.atom);
+      RefPtr<nsIAtom> atom = Reget(mThree.atom);
+      RefPtr<nsIAtom> otherAtom = Reget(mFour.atom);
       // See viewsource.css for the possible classes in addition to "error".
       nsAutoString klass;
       node->GetAttr(kNameSpaceID_None, nsGkAtoms::_class, klass);
       if (!klass.IsEmpty()) {
         klass.AppendLiteral(" error");
         node->SetAttr(kNameSpaceID_None, nsGkAtoms::_class, klass, true);
       } else {
         node->SetAttr(kNameSpaceID_None,
--- a/parser/htmlparser/nsHTMLTags.cpp
+++ b/parser/htmlparser/nsHTMLTags.cpp
@@ -199,17 +199,17 @@ nsHTMLTags::StringTagToId(const nsAStrin
 }
 
 #ifdef DEBUG
 void
 nsHTMLTags::TestTagTable()
 {
      const char16_t *tag;
      nsHTMLTag id;
-     nsCOMPtr<nsIAtom> atom;
+     RefPtr<nsIAtom> atom;
 
      nsHTMLTags::AddRefTable();
      // Make sure we can find everything we are supposed to
      for (int i = 0; i < NS_HTML_TAG_MAX; ++i) {
        tag = sTagUnicodeTable[i];
        id = StringTagToId(nsDependentString(tag));
        NS_ASSERTION(id != eHTMLTag_userdefined, "can't find tag id");
 
--- a/rdf/base/nsNameSpaceMap.h
+++ b/rdf/base/nsNameSpaceMap.h
@@ -18,17 +18,17 @@ public:
     public:
         Entry(const nsACString& aURI, nsIAtom* aPrefix)
             : mURI(aURI), mPrefix(aPrefix), mNext(nullptr) {
             MOZ_COUNT_CTOR(nsNameSpaceMap::Entry); }
 
         ~Entry() { MOZ_COUNT_DTOR(nsNameSpaceMap::Entry); }
 
         nsCString mURI;
-        nsCOMPtr<nsIAtom> mPrefix;
+        RefPtr<nsIAtom> mPrefix;
 
         Entry* mNext;
     };
 
     nsNameSpaceMap();
     ~nsNameSpaceMap();
 
     nsresult
--- a/rdf/base/nsRDFContentSink.cpp
+++ b/rdf/base/nsRDFContentSink.cpp
@@ -777,17 +777,17 @@ RDFContentSinkImpl::GetIdAboutAttribute(
                                         nsIRDFResource** aResource,
                                         bool* aIsAnonymous)
 {
     // This corresponds to the dirty work of production [6.5]
     nsresult rv = NS_OK;
 
     nsAutoString nodeID;
 
-    nsCOMPtr<nsIAtom> localName;
+    RefPtr<nsIAtom> localName;
     for (; *aAttributes; aAttributes += 2) {
         const nsDependentSubstring& nameSpaceURI =
             SplitExpatName(aAttributes[0], getter_AddRefs(localName));
 
         // We'll accept either `ID' or `rdf:ID' (ibid with `about' or
         // `rdf:about') in the spirit of being liberal towards the
         // input that we receive.
         if (!nameSpaceURI.IsEmpty() &&
@@ -865,17 +865,17 @@ RDFContentSinkImpl::GetIdAboutAttribute(
 
     return rv;
 }
 
 nsresult
 RDFContentSinkImpl::GetResourceAttribute(const char16_t** aAttributes,
                                          nsIRDFResource** aResource)
 {
-  nsCOMPtr<nsIAtom> localName;
+  RefPtr<nsIAtom> localName;
 
   nsAutoString nodeID;
 
   for (; *aAttributes; aAttributes += 2) {
       const nsDependentSubstring& nameSpaceURI =
           SplitExpatName(aAttributes[0], getter_AddRefs(localName));
 
       // We'll accept `resource' or `rdf:resource', under the spirit
@@ -933,17 +933,17 @@ RDFContentSinkImpl::GetResourceAttribute
 nsresult
 RDFContentSinkImpl::AddProperties(const char16_t** aAttributes,
                                   nsIRDFResource* aSubject,
                                   int32_t* aCount)
 {
   if (aCount)
       *aCount = 0;
 
-  nsCOMPtr<nsIAtom> localName;
+  RefPtr<nsIAtom> localName;
   for (; *aAttributes; aAttributes += 2) {
       const nsDependentSubstring& nameSpaceURI =
           SplitExpatName(aAttributes[0], getter_AddRefs(localName));
 
       // skip 'xmlns' directives, these are "meta" information
       if (nameSpaceURI.EqualsLiteral("http://www.w3.org/2000/xmlns/")) {
         continue;
       }
@@ -982,17 +982,17 @@ RDFContentSinkImpl::AddProperties(const 
       mDataSource->Assert(aSubject, property, target, true);
   }
   return NS_OK;
 }
 
 void
 RDFContentSinkImpl::SetParseMode(const char16_t **aAttributes)
 {
-    nsCOMPtr<nsIAtom> localName;
+    RefPtr<nsIAtom> localName;
     for (; *aAttributes; aAttributes += 2) {
         const nsDependentSubstring& nameSpaceURI =
             SplitExpatName(aAttributes[0], getter_AddRefs(localName));
 
         if (localName == kParseTypeAtom) {
             nsDependentString v(aAttributes[1]);
 
             if (nameSpaceURI.IsEmpty() ||
@@ -1018,17 +1018,17 @@ RDFContentSinkImpl::SetParseMode(const c
 // RDF-specific routines used to build the model
 
 nsresult
 RDFContentSinkImpl::OpenRDF(const char16_t* aName)
 {
     // ensure that we're actually reading RDF by making sure that the
     // opening tag is <rdf:RDF>, where "rdf:" corresponds to whatever
     // they've declared the standard RDF namespace to be.
-    nsCOMPtr<nsIAtom> localName;
+    RefPtr<nsIAtom> localName;
     const nsDependentSubstring& nameSpaceURI =
         SplitExpatName(aName, getter_AddRefs(localName));
 
     if (!nameSpaceURI.EqualsLiteral(RDF_NAMESPACE_URI) || localName != kRDFAtom) {
        // MOZ_LOG(gLog, LogLevel::Info,
        //        ("rdfxml: expected RDF:RDF at line %d",
        //         aNode.GetSourceLineNumber()));
 
@@ -1042,17 +1042,17 @@ RDFContentSinkImpl::OpenRDF(const char16
 
 nsresult
 RDFContentSinkImpl::OpenObject(const char16_t* aName,
                                const char16_t** aAttributes)
 {
     // an "object" non-terminal is either a "description", a "typed
     // node", or a "container", so this change the content sink's
     // state appropriately.
-    nsCOMPtr<nsIAtom> localName;
+    RefPtr<nsIAtom> localName;
     const nsDependentSubstring& nameSpaceURI =
         SplitExpatName(aName, getter_AddRefs(localName));
 
     // Figure out the URI of this object, and create an RDF node for it.
     nsCOMPtr<nsIRDFResource> source;
     GetIdAboutAttribute(aAttributes, getter_AddRefs(source));
 
     // If there is no `ID' or `about', then there's not much we can do.
@@ -1117,17 +1117,17 @@ RDFContentSinkImpl::OpenObject(const cha
 nsresult
 RDFContentSinkImpl::OpenProperty(const char16_t* aName, const char16_t** aAttributes)
 {
     nsresult rv;
 
     // an "object" non-terminal is either a "description", a "typed
     // node", or a "container", so this change the content sink's
     // state appropriately.
-    nsCOMPtr<nsIAtom> localName;
+    RefPtr<nsIAtom> localName;
     const nsDependentSubstring& nameSpaceURI =
         SplitExpatName(aName, getter_AddRefs(localName));
 
     NS_ConvertUTF16toUTF8 propertyStr(nameSpaceURI);
     propertyStr.Append(nsAtomCString(localName));
 
     nsCOMPtr<nsIRDFResource> property;
     rv = gRDFService->GetResource(propertyStr, getter_AddRefs(property));
@@ -1191,17 +1191,17 @@ nsresult
 RDFContentSinkImpl::OpenMember(const char16_t* aName,
                                const char16_t** aAttributes)
 {
     // ensure that we're actually reading a member element by making
     // sure that the opening tag is <rdf:li>, where "rdf:" corresponds
     // to whatever they've declared the standard RDF namespace to be.
     nsresult rv;
 
-    nsCOMPtr<nsIAtom> localName;
+    RefPtr<nsIAtom> localName;
     const nsDependentSubstring& nameSpaceURI =
         SplitExpatName(aName, getter_AddRefs(localName));
 
     if (!nameSpaceURI.EqualsLiteral(RDF_NAMESPACE_URI) ||
         localName != kLiAtom) {
         MOZ_LOG(gLog, LogLevel::Error,
                ("rdfxml: expected RDF:li at line %d",
                 -1)); // XXX pass in line number
@@ -1274,17 +1274,17 @@ RDFContentSinkImpl::RegisterNamespaces(c
             continue;
         }
         // get the localname (or "xmlns" for the default namespace)
         const char16_t* endLocal = ++attr;
         while (*endLocal && *endLocal != 0xFFFF) {
             ++endLocal;
         }
         nsDependentSubstring lname(attr, endLocal);
-        nsCOMPtr<nsIAtom> preferred = NS_Atomize(lname);
+        RefPtr<nsIAtom> preferred = NS_Atomize(lname);
         if (preferred == kXMLNSAtom) {
             preferred = nullptr;
         }
         sink->AddNameSpace(preferred, nsDependentString(aAttributes[1]));
     }
 }
 
 ////////////////////////////////////////////////////////////////////////
--- a/rdf/base/nsRDFXMLSerializer.cpp
+++ b/rdf/base/nsRDFXMLSerializer.cpp
@@ -116,33 +116,33 @@ nsRDFXMLSerializer::Init(nsIRDFDataSourc
 {
     if (! aDataSource)
         return NS_ERROR_NULL_POINTER;
 
     mDataSource = aDataSource;
     mDataSource->GetURI(getter_Copies(mBaseURLSpec));
 
     // Add the ``RDF'' prefix, by default.
-    nsCOMPtr<nsIAtom> prefix;
+    RefPtr<nsIAtom> prefix;
 
     prefix = NS_Atomize("RDF");
     AddNameSpace(prefix, NS_LITERAL_STRING("http://www.w3.org/1999/02/22-rdf-syntax-ns#"));
 
     prefix = NS_Atomize("NC");
     AddNameSpace(prefix, NS_LITERAL_STRING("http://home.netscape.com/NC-rdf#"));
 
     mPrefixID = 0;
 
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsRDFXMLSerializer::AddNameSpace(nsIAtom* aPrefix, const nsAString& aURI)
 {
-    nsCOMPtr<nsIAtom> prefix = aPrefix;
+    RefPtr<nsIAtom> prefix = aPrefix;
     if (!prefix) {
         // Make up a prefix, we don't want default namespaces, so
         // that we can use QNames for elements and attributes alike.
         prefix = EnsureNewPrefix();
     }
     mNameSpaces.Put(aURI, prefix);
     return NS_OK;
 }
@@ -177,17 +177,17 @@ rdf_BlockingWrite(nsIOutputStream* strea
     NS_ConvertUTF16toUTF8 utf8(s);
     return rdf_BlockingWrite(stream, utf8.get(), utf8.Length());
 }
 
 already_AddRefed<nsIAtom>
 nsRDFXMLSerializer::EnsureNewPrefix()
 {
     nsAutoString qname;
-    nsCOMPtr<nsIAtom> prefix;
+    RefPtr<nsIAtom> prefix;
     bool isNewPrefix;
     do {
         isNewPrefix = true;
         qname.AssignLiteral("NS");
         qname.AppendInt(++mPrefixID, 10);
         prefix = NS_Atomize(qname);
         nsNameSpaceMap::const_iterator iter = mNameSpaces.first();
         while (iter != mNameSpaces.last() && isNewPrefix) {
@@ -228,17 +228,17 @@ nsRDFXMLSerializer::RegisterQName(nsIRDF
             // this thing...
             mQNames.Put(aResource, uri);
             return NS_OK;
         }
     }
 
     // Take whatever is to the right of the '#' or '/' and call it the
     // local name, make up a prefix.
-    nsCOMPtr<nsIAtom> prefix = EnsureNewPrefix();
+    RefPtr<nsIAtom> prefix = EnsureNewPrefix();
     mNameSpaces.Put(StringHead(uri, i+1), prefix);
     prefix->ToUTF8String(qname);
     qname.Append(':');
     qname += StringTail(uri, uri.Length() - (i + 1));
 
     mQNames.Put(aResource, qname);
     return NS_OK;
 }
--- a/toolkit/components/extensions/ExtensionPolicyService.h
+++ b/toolkit/components/extensions/ExtensionPolicyService.h
@@ -51,17 +51,17 @@ public:
   WebExtensionPolicy*
   GetByID(const nsIAtom* aAddonId)
   {
     return mExtensions.GetWeak(aAddonId);
   }
 
   WebExtensionPolicy* GetByID(const nsAString& aAddonId)
   {
-    nsCOMPtr<nsIAtom> atom = NS_AtomizeMainThread(aAddonId);
+    RefPtr<nsIAtom> atom = NS_AtomizeMainThread(aAddonId);
     return GetByID(atom);
   }
 
   WebExtensionPolicy* GetByURL(const extensions::URLInfo& aURL);
 
   WebExtensionPolicy* GetByHost(const nsACString& aHost) const
   {
     return mExtensionHosts.GetWeak(aHost);
--- a/toolkit/components/extensions/MatchPattern.cpp
+++ b/toolkit/components/extensions/MatchPattern.cpp
@@ -287,17 +287,17 @@ MatchPattern::Init(JSContext* aCx, const
    * Scheme
    ***************************************************************************/
   int32_t index = aPattern.FindChar(':');
   if (index <= 0) {
     aRv.Throw(NS_ERROR_INVALID_ARG);
     return;
   }
 
-  nsCOMPtr<nsIAtom> scheme = NS_AtomizeMainThread(StringHead(aPattern, index));
+  RefPtr<nsIAtom> scheme = NS_AtomizeMainThread(StringHead(aPattern, index));
   if (scheme == nsGkAtoms::_asterisk) {
     mSchemes = AtomSet::Get<WILDCARD_SCHEMES>();
   } else if (permittedSchemes->Contains(scheme) || scheme == nsGkAtoms::moz_extension) {
     mSchemes = new AtomSet({scheme});
   } else {
     aRv.Throw(NS_ERROR_INVALID_ARG);
     return;
   }
--- a/toolkit/components/extensions/MatchPattern.h
+++ b/toolkit/components/extensions/MatchPattern.h
@@ -44,46 +44,46 @@ public:
   explicit AtomSet(const nsTArray<nsString>& aElems);
 
   explicit AtomSet(const char** aElems);
 
   MOZ_IMPLICIT AtomSet(std::initializer_list<nsIAtom*> aIL);
 
   bool Contains(const nsAString& elem) const
   {
-    nsCOMPtr<nsIAtom> atom = NS_AtomizeMainThread(elem);
+    RefPtr<nsIAtom> atom = NS_AtomizeMainThread(elem);
     return Contains(atom);
   }
 
   bool Contains(const nsACString& aElem) const
   {
-    nsCOMPtr<nsIAtom> atom = NS_Atomize(aElem);
+    RefPtr<nsIAtom> atom = NS_Atomize(aElem);
     return Contains(atom);
   }
 
   bool Contains(const nsIAtom* aAtom) const
   {
     return mElems.BinaryIndexOf(aAtom) != mElems.NoIndex;
   }
 
   bool Intersects(const AtomSet& aOther) const;
 
 
   void Add(nsIAtom* aElem);
   void Remove(nsIAtom* aElem);
 
   void Add(const nsAString& aElem)
   {
-    nsCOMPtr<nsIAtom> atom = NS_AtomizeMainThread(aElem);
+    RefPtr<nsIAtom> atom = NS_AtomizeMainThread(aElem);
     return Add(atom);
   }
 
   void Remove(const nsAString& aElem)
   {
-    nsCOMPtr<nsIAtom> atom = NS_AtomizeMainThread(aElem);
+    RefPtr<nsIAtom> atom = NS_AtomizeMainThread(aElem);
     return Remove(atom);
   }
 
   // Returns a cached, statically-allocated matcher for the given set of
   // literal strings.
   template <const char** schemes>
   static already_AddRefed<AtomSet>
   Get()
@@ -154,17 +154,17 @@ public:
   bool InheritsPrincipal() const;
 
 private:
   nsIURI* URINoRef() const;
 
   nsCOMPtr<nsIURI> mURI;
   mutable nsCOMPtr<nsIURI> mURINoRef;
 
-  mutable nsCOMPtr<nsIAtom> mScheme;
+  mutable RefPtr<nsIAtom> mScheme;
   mutable nsCString mHost;
 
   mutable nsAutoString mPath;
   mutable nsAutoString mFilePath;
   mutable nsAutoString mSpec;
 
   mutable Maybe<bool> mInheritsPrincipal;
 };
--- a/toolkit/components/extensions/WebExtensionPolicy.h
+++ b/toolkit/components/extensions/WebExtensionPolicy.h
@@ -154,17 +154,17 @@ protected:
 private:
   WebExtensionPolicy(dom::GlobalObject& aGlobal, const WebExtensionInit& aInit, ErrorResult& aRv);
 
   bool Enable();
   bool Disable();
 
   nsCOMPtr<nsISupports> mParent;
 
-  nsCOMPtr<nsIAtom> mId;
+  RefPtr<nsIAtom> mId;
   nsCString mHostname;
   nsCOMPtr<nsIURI> mBaseURI;
 
   nsString mName;
   nsString mContentSecurityPolicy;
 
   bool mActive = false;
 
--- a/toolkit/components/extensions/webrequest/StreamFilter.h
+++ b/toolkit/components/extensions/webrequest/StreamFilter.h
@@ -91,15 +91,15 @@ private:
   void ForgetActor();
 
   nsCOMPtr<nsIGlobalObject> mParent;
   RefPtr<StreamFilterChild> mActor;
 
   nsString mError;
 
   const uint64_t mChannelId;
-  const nsCOMPtr<nsIAtom> mAddonId;
+  const RefPtr<nsIAtom> mAddonId;
 };
 
 } // namespace extensions
 } // namespace mozilla
 
 #endif // mozilla_extensions_StreamFilter_h
--- a/toolkit/components/extensions/webrequest/StreamFilterParent.cpp
+++ b/toolkit/components/extensions/webrequest/StreamFilterParent.cpp
@@ -49,17 +49,17 @@ StreamFilterParent::~StreamFilterParent(
 bool
 StreamFilterParent::Create(dom::ContentParent* aContentParent, uint64_t aChannelId, const nsAString& aAddonId,
                            Endpoint<PStreamFilterChild>* aEndpoint)
 {
   AssertIsMainThread();
 
   auto& webreq = WebRequestService::GetSingleton();
 
-  nsCOMPtr<nsIAtom> addonId = NS_Atomize(aAddonId);
+  RefPtr<nsIAtom> addonId = NS_Atomize(aAddonId);
   nsCOMPtr<nsIChannel> channel = webreq.GetTraceableChannel(aChannelId, addonId, aContentParent);
 
   RefPtr<nsHttpChannel> chan = do_QueryObject(channel);
   NS_ENSURE_TRUE(chan, false);
 
   Endpoint<PStreamFilterParent> parent;
   Endpoint<PStreamFilterChild> child;
   nsresult rv = PStreamFilter::CreateEndpoints(chan->ProcessId(),
--- a/toolkit/components/extensions/webrequest/WebRequestService.cpp
+++ b/toolkit/components/extensions/webrequest/WebRequestService.cpp
@@ -68,17 +68,17 @@ WebRequestService::RegisterTraceableChan
                                             nsIChannel* aChannel,
                                             const nsAString& aAddonId,
                                             nsITabParent* aTabParent,
                                             nsIJSRAIIHelper** aHelper)
 {
   nsCOMPtr<nsITraceableChannel> traceableChannel = do_QueryInterface(aChannel);
   NS_ENSURE_TRUE(traceableChannel, NS_ERROR_INVALID_ARG);
 
-  nsCOMPtr<nsIAtom> addonId = NS_Atomize(aAddonId);
+  RefPtr<nsIAtom> addonId = NS_Atomize(aAddonId);
   ChannelParent* entry = new ChannelParent(aChannelId, aChannel,
                                            addonId, aTabParent);
 
   RefPtr<Destructor> destructor = new Destructor(entry);
   destructor.forget(aHelper);
 
   return NS_OK;
 }
--- a/toolkit/components/extensions/webrequest/WebRequestService.h
+++ b/toolkit/components/extensions/webrequest/WebRequestService.h
@@ -54,17 +54,17 @@ private:
   {
   public:
     explicit ChannelParent(uint64_t aChannelId, nsIChannel* aChannel, nsIAtom* aAddonId, nsITabParent* aTabParent);
     ~ChannelParent();
 
     void Detach();
 
     const RefPtr<dom::TabParent> mTabParent;
-    const nsCOMPtr<nsIAtom> mAddonId;
+    const RefPtr<nsIAtom> mAddonId;
 
   private:
     const uint64_t mChannelId;
     bool mDetached = false;
   };
 
   class Destructor : public nsIJSRAIIHelper
   {
--- a/toolkit/components/typeaheadfind/nsTypeAheadFind.cpp
+++ b/toolkit/components/typeaheadfind/nsTypeAheadFind.cpp
@@ -918,18 +918,18 @@ nsTypeAheadFind::RangeStartsInsideLink(n
     }
   }
 
   // ------- Check to see if inside link ---------
 
   // We now have the correct start node for the range
   // Search for links, starting with startNode, and going up parent chain
 
-  nsCOMPtr<nsIAtom> hrefAtom(NS_Atomize("href"));
-  nsCOMPtr<nsIAtom> typeAtom(NS_Atomize("type"));
+  RefPtr<nsIAtom> hrefAtom(NS_Atomize("href"));
+  RefPtr<nsIAtom> typeAtom(NS_Atomize("type"));
 
   while (true) {
     // Keep testing while startContent is equal to something,
     // eventually we'll run out of ancestors
 
     if (startContent->IsHTMLElement()) {
       nsCOMPtr<mozilla::dom::Link> link(do_QueryInterface(startContent));
       if (link) {
--- a/widget/BasicEvents.h
+++ b/widget/BasicEvents.h
@@ -569,17 +569,17 @@ public:
   // and focus can be reconfirmed for async keyboard scrolling.
   uint64_t mFocusSequenceNumber;
   // See BaseEventFlags definition for the detail.
   BaseEventFlags mFlags;
 
   // If JS creates an event with unknown event type or known event type but
   // for different event interface, the event type is stored to this.
   // NOTE: This is always used if the instance is a WidgetCommandEvent instance.
-  nsCOMPtr<nsIAtom> mSpecifiedEventType;
+  RefPtr<nsIAtom> mSpecifiedEventType;
 
   // nsIAtom isn't available on non-main thread due to unsafe.  Therefore,
   // mSpecifiedEventTypeString is used instead of mSpecifiedEventType if
   // the event is created in non-main thread.
   nsString mSpecifiedEventTypeString;
 
   // Event targets, needed by DOM Events
   // Note that when you need event target for DOM event, you should use
--- a/widget/MiscEvents.h
+++ b/widget/MiscEvents.h
@@ -122,17 +122,17 @@ public:
     // Not copying widget, it is a weak reference.
     WidgetCommandEvent* result =
       new WidgetCommandEvent(false, mSpecifiedEventType, mCommand, nullptr);
     result->AssignCommandEventData(*this, true);
     result->mFlags = mFlags;
     return result;
   }
 
-  nsCOMPtr<nsIAtom> mCommand;
+  RefPtr<nsIAtom> mCommand;
 
   // XXX Not tested by test_assign_event_data.html
   void AssignCommandEventData(const WidgetCommandEvent& aEvent,
                               bool aCopyTargets)
   {
     AssignGUIEventData(aEvent, aCopyTargets);
 
     // mCommand must have been initialized with the constructor.
--- a/widget/cocoa/nsMenuX.mm
+++ b/widget/cocoa/nsMenuX.mm
@@ -630,32 +630,32 @@ void nsMenuX::GetMenuPopupContent(nsICon
 {
   if (!aResult)
     return;
   *aResult = nullptr;
 
   // Check to see if we are a "menupopup" node (if we are a native menu).
   {
     int32_t dummy;
-    nsCOMPtr<nsIAtom> tag = mContent->OwnerDoc()->BindingManager()->ResolveTag(mContent, &dummy);
+    RefPtr<nsIAtom> tag = mContent->OwnerDoc()->BindingManager()->ResolveTag(mContent, &dummy);
     if (tag == nsGkAtoms::menupopup) {
       *aResult = mContent;
       NS_ADDREF(*aResult);
       return;
     }
   }
 
   // Otherwise check our child nodes.
 
   uint32_t count = mContent->GetChildCount();
 
   for (uint32_t i = 0; i < count; i++) {
     int32_t dummy;
     nsIContent *child = mContent->GetChildAt(i);
-    nsCOMPtr<nsIAtom> tag = child->OwnerDoc()->BindingManager()->ResolveTag(child, &dummy);
+    RefPtr<nsIAtom> tag = child->OwnerDoc()->BindingManager()->ResolveTag(child, &dummy);
     if (tag == nsGkAtoms::menupopup) {
       *aResult = child;
       NS_ADDREF(*aResult);
       return;
     }
   }
 }
 
--- a/widget/windows/KeyboardLayout.cpp
+++ b/widget/windows/KeyboardLayout.cpp
@@ -1970,17 +1970,17 @@ NativeKey::MaybeInitPluginEventOfKeyEven
   pluginEvent.wParam = aMsgSentToPlugin.wParam;
   pluginEvent.lParam = aMsgSentToPlugin.lParam;
   aKeyEvent.mPluginEvent.Copy(pluginEvent);
 }
 
 bool
 NativeKey::DispatchCommandEvent(uint32_t aEventCommand) const
 {
-  nsCOMPtr<nsIAtom> command;
+  RefPtr<nsIAtom> command;
   switch (aEventCommand) {
     case APPCOMMAND_BROWSER_BACKWARD:
       command = nsGkAtoms::Back;
       break;
     case APPCOMMAND_BROWSER_FORWARD:
       command = nsGkAtoms::Forward;
       break;
     case APPCOMMAND_BROWSER_REFRESH:
--- a/xpcom/ds/nsAtomTable.cpp
+++ b/xpcom/ds/nsAtomTable.cpp
@@ -81,30 +81,30 @@ public:
                                   uint32_t aAtomCount);
 
   static void AtomTableClearEntry(PLDHashTable* aTable,
                                   PLDHashEntryHdr* aEntry);
 
   static void GCAtomTableLocked(const MutexAutoLock& aProofOfLock,
                                 GCKind aKind);
 
-  static already_AddRefed<nsIAtom> Atomize(const nsACString& aUTF8String);
-  static already_AddRefed<nsIAtom> Atomize(const nsAString& aUTF16String);
-  static already_AddRefed<nsIAtom> AtomizeMainThread(const nsAString& aUTF16Str);
+  static already_AddRefed<nsAtom> Atomize(const nsACString& aUTF8String);
+  static already_AddRefed<nsAtom> Atomize(const nsAString& aUTF16String);
+  static already_AddRefed<nsAtom> AtomizeMainThread(const nsAString& aUTF16Str);
 };
 
 //----------------------------------------------------------------------
 
 // gUnusedAtomCount is incremented when an atom loses its last reference
 // (and thus turned into unused state), and decremented when an unused
 // atom gets a reference again. The atom table relies on this value to
 // schedule GC. This value can temporarily go below zero when multiple
 // threads are operating the same atom, so it has to be signed so that
 // we wouldn't use overflow value for comparison.
-// See Atom::DynamicAddRef and Atom::DynamicRelease.
+// See nsAtom::AddRef() and nsAtom::Release().
 static Atomic<int32_t, ReleaseAcquire> gUnusedAtomCount(0);
 
 #if defined(NS_BUILD_REFCNT_LOGGING)
 // nsFakeStringBuffers don't really use the refcounting system, but we
 // have to give a coherent series of addrefs and releases to the
 // refcount logging system, or we'll hit assertions when running with
 // XPCOM_MEM_LOG_CLASSES=nsStringBuffer.
 class FakeBufferRefcountHelper
@@ -131,17 +131,17 @@ public:
 private:
   nsStringBuffer* mBuffer;
 };
 
 UniquePtr<nsTArray<FakeBufferRefcountHelper>> gFakeBuffers;
 #endif
 
 // This constructor is for dynamic atoms and HTML5 atoms.
-nsAtom::nsAtom(AtomKind aKind, const nsAString& aString, uint32_t aHash)
+nsIAtom::nsIAtom(AtomKind aKind, const nsAString& aString, uint32_t aHash)
   : mRefCnt(1)
 {
   mLength = aString.Length();
   SetKind(aKind);
   MOZ_ASSERT(IsDynamicAtom() || IsHTML5Atom());
   RefPtr<nsStringBuffer> buf = nsStringBuffer::FromString(aString);
   if (buf) {
     mString = static_cast<char16_t*>(buf->Data());
@@ -166,17 +166,18 @@ nsAtom::nsAtom(AtomKind aKind, const nsA
                "enough storage");
   NS_ASSERTION(Equals(aString), "correct data");
 
   // Take ownership of buffer
   mozilla::Unused << buf.forget();
 }
 
 // This constructor is for static atoms.
-nsAtom::nsAtom(nsStringBuffer* aStringBuffer, uint32_t aLength, uint32_t aHash)
+nsIAtom::nsIAtom(nsStringBuffer* aStringBuffer, uint32_t aLength,
+                 uint32_t aHash)
 {
   mLength = aLength;
   SetKind(AtomKind::StaticAtom);
   mString = static_cast<char16_t*>(aStringBuffer->Data());
 
 #if defined(NS_BUILD_REFCNT_LOGGING)
   MOZ_ASSERT(NS_IsMainThread());
   if (!gFakeBuffers) {
@@ -193,78 +194,49 @@ nsAtom::nsAtom(nsStringBuffer* aStringBu
   MOZ_ASSERT(mHash == HashString(mString, mLength));
 
   MOZ_ASSERT(mString[mLength] == char16_t(0), "null terminated");
   MOZ_ASSERT(aStringBuffer &&
              aStringBuffer->StorageSize() == (mLength + 1) * sizeof(char16_t),
              "correct storage");
 }
 
-// We don't need a virtual destructor because we always delete via an nsAtom*
-// pointer (in AtomTableClearEntry() for static atoms, and in
-// GCAtomTableLocked() for dynamic atoms), not an nsIAtom* pointer.
-nsAtom::~nsAtom()
+nsIAtom::~nsIAtom()
 {
   if (!IsStaticAtom()) {
     MOZ_ASSERT(IsDynamicAtom() || IsHTML5Atom());
     nsStringBuffer::FromData(mString)->Release();
   }
 }
 
-NS_IMPL_QUERY_INTERFACE(nsAtom, nsIAtom);
-
-NS_IMETHODIMP_(void)
-nsAtom::ToUTF8String(nsACString& aBuf)
+void
+nsAtom::ToUTF8String(nsACString& aBuf) const
 {
   MOZ_ASSERT(!IsHTML5Atom(), "Called ToUTF8String() on an HTML5 atom");
   CopyUTF16toUTF8(nsDependentString(mString, mLength), aBuf);
 }
 
-NS_IMETHODIMP_(size_t)
-nsAtom::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf)
+size_t
+nsAtom::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
 {
   MOZ_ASSERT(!IsHTML5Atom(), "Called SizeOfIncludingThis() on an HTML5 atom");
   size_t n = aMallocSizeOf(this);
   // String buffers pointed to by static atoms are in static memory, and so
   // are not measured here.
   if (IsDynamicAtom()) {
     n += nsStringBuffer::FromData(mString)->SizeOfIncludingThisIfUnshared(
            aMallocSizeOf);
   } else {
     MOZ_ASSERT(IsStaticAtom());
   }
   return n;
 }
 
 //----------------------------------------------------------------------
 
-NS_IMETHODIMP_(MozExternalRefCountType)
-nsIAtom::AddRef()
-{
-  MOZ_ASSERT(!IsHTML5Atom(), "Attempt to AddRef an HTML5 atom");
-  if (!IsDynamicAtom()) {
-    MOZ_ASSERT(IsStaticAtom());
-    return 2;
-  }
-  return static_cast<nsAtom*>(this)->DynamicAddRef();
-}
-
-NS_IMETHODIMP_(MozExternalRefCountType)
-nsIAtom::Release()
-{
-  MOZ_ASSERT(!IsHTML5Atom(), "Attempt to Release an HTML5 atom");
-  if (!IsDynamicAtom()) {
-    MOZ_ASSERT(IsStaticAtom());
-    return 1;
-  }
-  return static_cast<nsAtom*>(this)->DynamicRelease();
-}
-
-//----------------------------------------------------------------------
-
 /**
  * The shared hash table for atom lookups.
  *
  * Callers must hold gAtomTableLock before manipulating the table.
  */
 static PLDHashTable* gAtomTable;
 static Mutex* gAtomTableLock;
 
@@ -457,39 +429,50 @@ GCAtomTable()
 {
   if (NS_IsMainThread()) {
     MutexAutoLock lock(*gAtomTableLock);
     nsAtomFriend::GCAtomTableLocked(lock, GCKind::RegularOperation);
   }
 }
 
 MozExternalRefCountType
-nsAtom::DynamicAddRef()
+nsAtom::AddRef()
 {
-  MOZ_ASSERT(IsDynamicAtom());
+  MOZ_ASSERT(!IsHTML5Atom(), "Attempt to AddRef an HTML5 atom");
+  if (!IsDynamicAtom()) {
+    MOZ_ASSERT(IsStaticAtom());
+    return 2;
+  }
+
+  MOZ_ASSERT(int32_t(mRefCnt) >= 0, "illegal refcnt");
   nsrefcnt count = ++mRefCnt;
   if (count == 1) {
     gUnusedAtomCount--;
   }
   return count;
 }
 
-#ifdef DEBUG
-// We set a lower GC threshold for atoms in debug builds so that we exercise
-// the GC machinery more often.
-static const int32_t kAtomGCThreshold = 20;
-#else
-static const int32_t kAtomGCThreshold = 10000;
-#endif
+MozExternalRefCountType
+nsAtom::Release()
+{
+  MOZ_ASSERT(!IsHTML5Atom(), "Attempt to Release an HTML5 atom");
+  if (!IsDynamicAtom()) {
+    MOZ_ASSERT(IsStaticAtom());
+    return 1;
+  }
 
-MozExternalRefCountType
-nsAtom::DynamicRelease()
-{
-  MOZ_ASSERT(IsDynamicAtom());
-  MOZ_ASSERT(mRefCnt > 0);
+  #ifdef DEBUG
+  // We set a lower GC threshold for atoms in debug builds so that we exercise
+  // the GC machinery more often.
+  static const int32_t kAtomGCThreshold = 20;
+  #else
+  static const int32_t kAtomGCThreshold = 10000;
+  #endif
+
+  MOZ_ASSERT(int32_t(mRefCnt) > 0, "dup release");
   nsrefcnt count = --mRefCnt;
   if (count == 0) {
     if (++gUnusedAtomCount >= kAtomGCThreshold) {
       GCAtomTable();
     }
   }
 
   return count;
@@ -564,17 +547,17 @@ NS_InitAtomTable()
 
   // Bug 1340710 has caused us to generate an empty atom at arbitrary times
   // after startup.  If we end up creating one before nsGkAtoms::_empty is
   // registered, we get an assertion about transmuting a dynamic atom into a
   // static atom.  In order to avoid that, we register an empty string static
   // atom as soon as we initialize the atom table to guarantee that the empty
   // string atom will always be static.
   NS_STATIC_ATOM_BUFFER(empty, "");
-  static nsIAtom* empty_atom = nullptr;
+  static nsAtom* empty_atom = nullptr;
   static const nsStaticAtom default_atoms[] = {
     NS_STATIC_ATOM(empty, &empty_atom)
   };
   NS_RegisterStaticAtoms(default_atoms);
 }
 
 void
 NS_ShutdownAtomTable()
@@ -647,17 +630,17 @@ nsAtomFriend::RegisterStaticAtoms(const 
                      "Atom table has already been sealed!");
 
   if (!gStaticAtomTable) {
     gStaticAtomTable = new StaticAtomTable();
   }
 
   for (uint32_t i = 0; i < aAtomCount; ++i) {
     nsStringBuffer* stringBuffer = aAtoms[i].mStringBuffer;
-    nsIAtom** atomp = aAtoms[i].mAtom;
+    nsAtom** atomp = aAtoms[i].mAtom;
 
     MOZ_ASSERT(nsCRT::IsAscii(static_cast<char16_t*>(stringBuffer->Data())));
 
     uint32_t stringLen = stringBuffer->StorageSize() / sizeof(char16_t) - 1;
 
     uint32_t hash;
     AtomTableEntry* he =
       GetAtomHashEntry(static_cast<char16_t*>(stringBuffer->Data()),
@@ -691,33 +674,33 @@ nsAtomFriend::RegisterStaticAtoms(const 
 }
 
 void
 RegisterStaticAtoms(const nsStaticAtom* aAtoms, uint32_t aAtomCount)
 {
   nsAtomFriend::RegisterStaticAtoms(aAtoms, aAtomCount);
 }
 
-already_AddRefed<nsIAtom>
+already_AddRefed<nsAtom>
 NS_Atomize(const char* aUTF8String)
 {
   return nsAtomFriend::Atomize(nsDependentCString(aUTF8String));
 }
 
-already_AddRefed<nsIAtom>
+already_AddRefed<nsAtom>
 nsAtomFriend::Atomize(const nsACString& aUTF8String)
 {
   MutexAutoLock lock(*gAtomTableLock);
   uint32_t hash;
   AtomTableEntry* he = GetAtomHashEntry(aUTF8String.Data(),
                                         aUTF8String.Length(),
                                         &hash);
 
   if (he->mAtom) {
-    nsCOMPtr<nsIAtom> atom = he->mAtom;
+    RefPtr<nsAtom> atom = he->mAtom;
 
     return atom.forget();
   }
 
   // This results in an extra addref/release of the nsStringBuffer.
   // Unfortunately there doesn't seem to be any APIs to avoid that.
   // Actually, now there is, sort of: ForgetSharedBuffer.
   nsString str;
@@ -725,61 +708,61 @@ nsAtomFriend::Atomize(const nsACString& 
   RefPtr<nsAtom> atom =
     dont_AddRef(new nsAtom(nsAtom::AtomKind::DynamicAtom, str, hash));
 
   he->mAtom = atom;
 
   return atom.forget();
 }
 
-already_AddRefed<nsIAtom>
+already_AddRefed<nsAtom>
 NS_Atomize(const nsACString& aUTF8String)
 {
   return nsAtomFriend::Atomize(aUTF8String);
 }
 
-already_AddRefed<nsIAtom>
+already_AddRefed<nsAtom>
 NS_Atomize(const char16_t* aUTF16String)
 {
   return nsAtomFriend::Atomize(nsDependentString(aUTF16String));
 }
 
-already_AddRefed<nsIAtom>
+already_AddRefed<nsAtom>
 nsAtomFriend::Atomize(const nsAString& aUTF16String)
 {
   MutexAutoLock lock(*gAtomTableLock);
   uint32_t hash;
   AtomTableEntry* he = GetAtomHashEntry(aUTF16String.Data(),
                                         aUTF16String.Length(),
                                         &hash);
 
   if (he->mAtom) {
-    nsCOMPtr<nsIAtom> atom = he->mAtom;
+    RefPtr<nsAtom> atom = he->mAtom;
 
     return atom.forget();
   }
 
   RefPtr<nsAtom> atom =
     dont_AddRef(new nsAtom(nsAtom::AtomKind::DynamicAtom, aUTF16String, hash));
   he->mAtom = atom;
 
   return atom.forget();
 }
 
-already_AddRefed<nsIAtom>
+already_AddRefed<nsAtom>
 NS_Atomize(const nsAString& aUTF16String)
 {
   return nsAtomFriend::Atomize(aUTF16String);
 }
 
-already_AddRefed<nsIAtom>
+already_AddRefed<nsAtom>
 nsAtomFriend::AtomizeMainThread(const nsAString& aUTF16String)
 {
   MOZ_ASSERT(NS_IsMainThread());
-  nsCOMPtr<nsIAtom> retVal;
+  RefPtr<nsAtom> retVal;
   uint32_t hash;
   AtomTableKey key(aUTF16String.Data(), aUTF16String.Length(), &hash);
   uint32_t index = hash % RECENTLY_USED_MAIN_THREAD_ATOM_CACHE_SIZE;
   nsAtom* atom = sRecentlyUsedMainThreadAtoms[index];
   if (atom) {
     uint32_t length = atom->GetLength();
     if (length == key.mLength &&
         (memcmp(atom->GetUTF16String(),
@@ -800,17 +783,17 @@ nsAtomFriend::AtomizeMainThread(const ns
     he->mAtom = newAtom;
     retVal = newAtom.forget();
   }
 
   sRecentlyUsedMainThreadAtoms[index] = he->mAtom;
   return retVal.forget();
 }
 
-already_AddRefed<nsIAtom>
+already_AddRefed<nsAtom>
 NS_AtomizeMainThread(const nsAString& aUTF16String)
 {
   return nsAtomFriend::AtomizeMainThread(aUTF16String);
 }
 
 nsrefcnt
 NS_GetNumberOfAtoms(void)
 {
@@ -820,17 +803,17 @@ NS_GetNumberOfAtoms(void)
 }
 
 int32_t
 NS_GetUnusedAtomCount(void)
 {
   return gUnusedAtomCount;
 }
 
-nsIAtom*
+nsAtom*
 NS_GetStaticAtom(const nsAString& aUTF16String)
 {
   NS_PRECONDITION(gStaticAtomTable, "Static atom table not created yet.");
   NS_PRECONDITION(gStaticAtomTableSealed, "Static atom table not sealed yet.");
   StaticAtomEntry* entry = gStaticAtomTable->GetEntry(aUTF16String);
   return entry ? entry->mAtom : nullptr;
 }
 
--- a/xpcom/ds/nsIAtom.h
+++ b/xpcom/ds/nsIAtom.h
@@ -2,38 +2,28 @@
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsIAtom_h
 #define nsIAtom_h
 
-#include "nsISupports.h"
+#include "nsISupportsImpl.h"
 #include "nsString.h"
 #include "nsStringBuffer.h"
 
-#define NS_IATOM_IID_STR "8b8c11d4-3ed5-4079-8974-73c7576cdb34"
-
-#define NS_IATOM_IID \
-  {0x8b8c11d4, 0x3ed5, 0x4079, \
-    { 0x89, 0x74, 0x73, 0xc7, 0x57, 0x6c, 0xdb, 0x34 }}
-
-class nsIAtom : public nsISupports
+// This class would be |final| if it wasn't for nsICSSAnonBoxPseudo and
+// nsICSSPseudoElement, which are trivial subclasses used to ensure only
+// certain atoms are passed to certain functions.
+class nsIAtom
 {
 public:
-  NS_DECLARE_STATIC_IID_ACCESSOR(NS_IATOM_IID)
-
-  NS_IMETHOD_(void) ToUTF8String(nsACString& aString) = 0;
+  size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
 
-  NS_IMETHOD_(size_t)
-  SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) = 0;
-
-  // The kind of atom we have, in order to be able to devirtualize hot stuff
-  // looking at mKind.
   enum class AtomKind : uint8_t {
     DynamicAtom = 0,
     StaticAtom = 1,
     HTML5Atom = 2,
   };
 
   bool Equals(char16ptr_t aString, uint32_t aLength) const
   {
@@ -63,119 +53,110 @@ public:
   uint32_t GetLength() const { return mLength; }
 
   void ToString(nsAString& aBuf) const
   {
     // See the comment on |mString|'s declaration.
     nsStringBuffer::FromData(mString)->ToString(mLength, aBuf);
   }
 
+  void ToUTF8String(nsACString& aString) const;
+
   nsStringBuffer* GetStringBuffer() const
   {
     // See the comment on |mString|'s declaration.
     return nsStringBuffer::FromData(mString);
   }
 
-  NS_IMETHOD_(MozExternalRefCountType) AddRef() final;
-  NS_IMETHOD_(MozExternalRefCountType) Release() final;
-
   // A hashcode that is better distributed than the actual atom pointer, for
   // use in situations that need a well-distributed hashcode.
   uint32_t hash() const
   {
     MOZ_ASSERT(!IsHTML5Atom());
     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;
+
+private:
+  friend class nsAtomFriend;
+  friend class nsHtml5AtomEntry;
+
+  // Construction and destruction is done entirely by |friend|s.
+  nsIAtom(AtomKind aKind, const nsAString& aString, uint32_t aHash);
+  nsIAtom(nsStringBuffer* aStringBuffer, uint32_t aLength, uint32_t aHash);
 protected:
+  ~nsIAtom();
+
+private:
+  mozilla::ThreadSafeAutoRefCnt mRefCnt;
   uint32_t mLength: 30;
-  uint32_t mKind: 2; // nsIAtom::AtomKind
+  uint32_t mKind: 2; // nsAtom::AtomKind
   uint32_t mHash;
   // WARNING! There is an invisible constraint on |mString|: the chars it
   // points to must belong to an nsStringBuffer. This is so that the
   // nsStringBuffer::FromData() calls above are valid.
   char16_t* mString;
 };
 
-NS_DEFINE_STATIC_IID_ACCESSOR(nsIAtom, NS_IATOM_IID)
-
-#define NS_DECL_NSIATOM \
-  NS_IMETHOD_(void) ToUTF8String(nsACString& _retval) override; \
-  NS_IMETHOD_(size_t) SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) override;
-
-class nsAtom final : public nsIAtom
-{
-public:
-  NS_DECL_NSIATOM
-  NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr) final;
-  typedef mozilla::TrueType HasThreadSafeRefCnt;
+// XXX: Bug 1400460 will rename nsIAtom as nsAtom, now that it no longer
+// inherits from nsISupports. Until that happens, we have this typedef.
+typedef nsIAtom nsAtom;
 
-private:
-  friend class nsIAtom;
-  friend class nsAtomFriend;
-  friend class nsHtml5AtomEntry;
-
-  // Construction and destruction is done entirely by |friend|s.
-  nsAtom(AtomKind aKind, const nsAString& aString, uint32_t aHash);
-  nsAtom(nsStringBuffer* aStringBuffer, uint32_t aLength, uint32_t aHash);
-  ~nsAtom();
-
-  MozExternalRefCountType DynamicAddRef();
-  MozExternalRefCountType DynamicRelease();
-
-  mozilla::ThreadSafeAutoRefCnt mRefCnt;
-  NS_DECL_OWNINGTHREAD
-};
-
-// The four forms of NS_Atomize (for use with |nsCOMPtr<nsIAtom>|) return the
+// The four forms of NS_Atomize (for use with |RefPtr<nsAtom>|) return the
 // atom for the string given. At any given time there will always be one atom
 // representing a given string. Atoms are intended to make string comparison
 // cheaper by simplifying it to pointer equality. A pointer to the atom that
 // does not own a reference is not guaranteed to be valid.
 
 // Find an atom that matches the given UTF-8 string. The string is assumed to
 // be zero terminated. Never returns null.
-already_AddRefed<nsIAtom> NS_Atomize(const char* aUTF8String);
+already_AddRefed<nsAtom> NS_Atomize(const char* aUTF8String);
 
 // Find an atom that matches the given UTF-8 string. Never returns null.
-already_AddRefed<nsIAtom> NS_Atomize(const nsACString& aUTF8String);
+already_AddRefed<nsAtom> NS_Atomize(const nsACString& aUTF8String);
 
 // Find an atom that matches the given UTF-16 string. The string is assumed to
 // be zero terminated. Never returns null.
-already_AddRefed<nsIAtom> NS_Atomize(const char16_t* aUTF16String);
+already_AddRefed<nsAtom> NS_Atomize(const char16_t* aUTF16String);
 
 // Find an atom that matches the given UTF-16 string. Never returns null.
-already_AddRefed<nsIAtom> NS_Atomize(const nsAString& aUTF16String);
+already_AddRefed<nsAtom> NS_Atomize(const nsAString& aUTF16String);
 
 // An optimized version of the method above for the main thread.
-already_AddRefed<nsIAtom> NS_AtomizeMainThread(const nsAString& aUTF16String);
+already_AddRefed<nsAtom> NS_AtomizeMainThread(const nsAString& aUTF16String);
 
 // Return a count of the total number of atoms currently alive in the system.
 nsrefcnt NS_GetNumberOfAtoms();
 
 // Return a pointer for a static atom for the string or null if there's no
 // static atom for this string.
-nsIAtom* NS_GetStaticAtom(const nsAString& aUTF16String);
+nsAtom* NS_GetStaticAtom(const nsAString& aUTF16String);
 
 // Seal the static atom table.
 void NS_SealStaticAtomTable();
 
 class nsAtomString : public nsString
 {
 public:
-  explicit nsAtomString(const nsIAtom* aAtom) { aAtom->ToString(*this); }
+  explicit nsAtomString(const nsAtom* aAtom) { aAtom->ToString(*this); }
 };
 
 class nsAtomCString : public nsCString
 {
 public:
-  explicit nsAtomCString(nsIAtom* aAtom) { aAtom->ToUTF8String(*this); }
+  explicit nsAtomCString(nsAtom* aAtom) { aAtom->ToUTF8String(*this); }
 };
 
 class nsDependentAtomString : public nsDependentString
 {
 public:
-  explicit nsDependentAtomString(const nsIAtom* aAtom)
+  explicit nsDependentAtomString(const nsAtom* aAtom)
     : nsDependentString(aAtom->GetUTF16String(), aAtom->GetLength())
   {}
 };
 
 #endif  // nsIAtom_h
--- a/xpcom/ds/nsRefPtrHashtable.h
+++ b/xpcom/ds/nsRefPtrHashtable.h
@@ -37,16 +37,21 @@ public:
   /**
    * @copydoc nsBaseHashtable::Get
    * @param aData This is an XPCOM getter, so aData is already_addrefed.
    *   If the key doesn't exist, aData will be set to nullptr.
    */
   bool Get(KeyType aKey, UserDataType* aData) const;
 
   /**
+   * @copydoc nsBaseHashtable::Get
+   */
+  already_AddRefed<PtrType> Get(KeyType aKey) const;
+
+  /**
    * Gets a weak reference to the hashtable entry.
    * @param aFound If not nullptr, will be set to true if the entry is found,
    *               to false otherwise.
    * @return The entry, or nullptr if not found. Do not release this pointer!
    */
   PtrType* GetWeak(KeyType aKey, bool* aFound = nullptr) const;
 
   // Overload Put, rather than overriding it.
@@ -114,16 +119,29 @@ nsRefPtrHashtable<KeyClass, PtrType>::Ge
   if (aRefPtr) {
     *aRefPtr = nullptr;
   }
 
   return false;
 }
 
 template<class KeyClass, class PtrType>
+already_AddRefed<PtrType>
+nsRefPtrHashtable<KeyClass, PtrType>::Get(KeyType aKey) const
+{
+  typename base_type::EntryType* ent = this->GetEntry(aKey);
+  if (!ent) {
+    return nullptr;
+  }
+
+  RefPtr<PtrType> copy = ent->mData;
+  return copy.forget();
+}
+
+template<class KeyClass, class PtrType>
 PtrType*
 nsRefPtrHashtable<KeyClass, PtrType>::GetWeak(KeyType aKey, bool* aFound) const
 {
   typename base_type::EntryType* ent = this->GetEntry(aKey);
 
   if (ent) {
     if (aFound) {
       *aFound = true;
--- a/xpcom/io/nsDirectoryService.cpp
+++ b/xpcom/io/nsDirectoryService.cpp
@@ -518,17 +518,17 @@ nsDirectoryService::GetFile(const char* 
                             nsIFile** aResult)
 {
   nsCOMPtr<nsIFile> localFile;
   nsresult rv = NS_ERROR_FAILURE;
 
   *aResult = nullptr;
   *aPersistent = true;
 
-  nsCOMPtr<nsIAtom> inAtom = NS_Atomize(aProp);
+  RefPtr<nsIAtom> inAtom = NS_Atomize(aProp);
 
   // check to see if it is one of our defaults
 
   if (inAtom == nsDirectoryService::sCurrentProcess ||
       inAtom == nsDirectoryService::sOS_CurrentProcessDirectory) {
     rv = GetCurrentProcessDirectory(getter_AddRefs(localFile));
   }
 
--- a/xpcom/tests/gtest/TestAtoms.cpp
+++ b/xpcom/tests/gtest/TestAtoms.cpp
@@ -22,17 +22,17 @@ int32_t NS_GetUnusedAtomCount(void);
 namespace TestAtoms {
 
 TEST(Atoms, Basic)
 {
   for (unsigned int i = 0; i < ArrayLength(ValidStrings); ++i) {
     nsDependentString str16(ValidStrings[i].m16);
     nsDependentCString str8(ValidStrings[i].m8);
 
-    nsCOMPtr<nsIAtom> atom = NS_Atomize(str16);
+    RefPtr<nsIAtom> atom = NS_Atomize(str16);
 
     EXPECT_TRUE(atom->Equals(str16));
 
     nsString tmp16;
     nsCString tmp8;
     atom->ToString(tmp16);
     atom->ToUTF8String(tmp8);
     EXPECT_TRUE(str16.Equals(tmp16));
@@ -44,82 +44,82 @@ TEST(Atoms, Basic)
     EXPECT_TRUE(nsDependentAtomString(atom).Equals(str16));
     EXPECT_TRUE(nsAtomCString(atom).Equals(str8));
   }
 }
 
 TEST(Atoms, 16vs8)
 {
   for (unsigned int i = 0; i < ArrayLength(ValidStrings); ++i) {
-    nsCOMPtr<nsIAtom> atom16 = NS_Atomize(ValidStrings[i].m16);
-    nsCOMPtr<nsIAtom> atom8 = NS_Atomize(ValidStrings[i].m8);
+    RefPtr<nsIAtom> atom16 = NS_Atomize(ValidStrings[i].m16);
+    RefPtr<nsIAtom> atom8 = NS_Atomize(ValidStrings[i].m8);
     EXPECT_EQ(atom16, atom8);
   }
 }
 
 TEST(Atoms, BufferSharing)
 {
   nsString unique;
   unique.AssignLiteral("this is a unique string !@#$");
 
-  nsCOMPtr<nsIAtom> atom = NS_Atomize(unique);
+  RefPtr<nsIAtom> atom = NS_Atomize(unique);
 
   EXPECT_EQ(unique.get(), atom->GetUTF16String());
 }
 
 TEST(Atoms, Null)
 {
   nsAutoString str(NS_LITERAL_STRING("string with a \0 char"));
   nsDependentString strCut(str.get());
 
   EXPECT_FALSE(str.Equals(strCut));
 
-  nsCOMPtr<nsIAtom> atomCut = NS_Atomize(strCut);
-  nsCOMPtr<nsIAtom> atom = NS_Atomize(str);
+  RefPtr<nsIAtom> atomCut = NS_Atomize(strCut);
+  RefPtr<nsIAtom> atom = NS_Atomize(str);
 
   EXPECT_EQ(atom->GetLength(), str.Length());
   EXPECT_TRUE(atom->Equals(str));
   EXPECT_NE(atom, atomCut);
   EXPECT_TRUE(atomCut->Equals(strCut));
 }
 
 TEST(Atoms, Invalid)
 {
   for (unsigned int i = 0; i < ArrayLength(Invalid16Strings); ++i) {
     nsrefcnt count = NS_GetNumberOfAtoms();
 
     {
-      nsCOMPtr<nsIAtom> atom16 = NS_Atomize(Invalid16Strings[i].m16);
+      RefPtr<nsIAtom> atom16 = NS_Atomize(Invalid16Strings[i].m16);
       EXPECT_TRUE(atom16->Equals(nsDependentString(Invalid16Strings[i].m16)));
     }
 
     EXPECT_EQ(count, NS_GetNumberOfAtoms());
   }
 
   for (unsigned int i = 0; i < ArrayLength(Invalid8Strings); ++i) {
     nsrefcnt count = NS_GetNumberOfAtoms();
 
     {
-      nsCOMPtr<nsIAtom> atom8 = NS_Atomize(Invalid8Strings[i].m8);
-      nsCOMPtr<nsIAtom> atom16 = NS_Atomize(Invalid8Strings[i].m16);
+      RefPtr<nsIAtom> atom8 = NS_Atomize(Invalid8Strings[i].m8);
+      RefPtr<nsIAtom> atom16 = NS_Atomize(Invalid8Strings[i].m16);
       EXPECT_EQ(atom16, atom8);
       EXPECT_TRUE(atom16->Equals(nsDependentString(Invalid8Strings[i].m16)));
     }
 
     EXPECT_EQ(count, NS_GetNumberOfAtoms());
   }
 
 // Don't run this test in debug builds as that intentionally asserts.
 #ifndef DEBUG
-  nsCOMPtr<nsIAtom> emptyAtom = NS_Atomize("");
+  RefPtr<nsIAtom> emptyAtom = NS_Atomize("");
 
   for (unsigned int i = 0; i < ArrayLength(Malformed8Strings); ++i) {
     nsrefcnt count = NS_GetNumberOfAtoms();
 
-    nsCOMPtr<nsIAtom> atom8 = NS_Atomize(Malformed8Strings[i]);
+    RefPtr<nsIAtom> atom8 = NS_Atomize(Malformed8Strings[i]);
     EXPECT_EQ(atom8, emptyAtom);
     EXPECT_EQ(count, NS_GetNumberOfAtoms());
   }
 #endif
 }
 
 #define FIRST_ATOM_STR "first static atom. Hello!"
 #define SECOND_ATOM_STR "second static atom. @World!"
@@ -140,33 +140,33 @@ isStaticAtom(nsIAtom* atom)
   rv &= (atom->Release() == 1);
   return rv;
 }
 
 TEST(Atoms, Table)
 {
   nsrefcnt count = NS_GetNumberOfAtoms();
 
-  nsCOMPtr<nsIAtom> thirdDynamic = NS_Atomize(THIRD_ATOM_STR);
+  RefPtr<nsIAtom> thirdDynamic = NS_Atomize(THIRD_ATOM_STR);
 
   EXPECT_FALSE(isStaticAtom(thirdDynamic));
 
   EXPECT_TRUE(thirdDynamic);
   EXPECT_EQ(NS_GetNumberOfAtoms(), count + 1);
 }
 
 class nsAtomRunner final : public nsIRunnable
 {
 public:
   NS_DECL_THREADSAFE_ISUPPORTS
 
   NS_IMETHOD Run() final
   {
     for (int i = 0; i < 10000; i++) {
-      nsCOMPtr<nsIAtom> atom = NS_Atomize(u"A Testing Atom");
+      RefPtr<nsIAtom> atom = NS_Atomize(u"A Testing Atom");
     }
     return NS_OK;
   }
 
 private:
   ~nsAtomRunner() {}
 };