Bug 1400459 (part 2) - Devirtualize nsIAtom. r=heycam.
authorNicholas Nethercote <nnethercote@mozilla.com>
Tue, 26 Sep 2017 08:33:21 +1000
changeset 433923 1ede5092b3695bac4248f6f9435120a7ef603a7c
parent 433922 3ed0fecec71ef745dd62008170e2aaadd1034c74
child 433924 31a7d05125ccb219dcbdfc7e2e34578e9c31bcf0
push id8114
push userjlorenzo@mozilla.com
push dateThu, 02 Nov 2017 16:33:21 +0000
treeherdermozilla-beta@73e0d89a540f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersheycam
bugs1400459
milestone58.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1400459 (part 2) - Devirtualize nsIAtom. r=heycam. 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 co