nsSlots
author Benjamin Smedberg <benjamin@smedbergs.us>
Sat, 26 Jul 2008 22:49:39 -0400
changeset 167 a4da40849f5436e629c5732f4368c6c48189637f
parent 153 cd96178a2e472dc6cd10443a56a3cedf9e8e1140
permissions -rw-r--r--
State as of now

* * *

diff --git a/content/base/public/nsINode.h b/content/base/public/nsINode.h
--- a/content/base/public/nsINode.h
+++ b/content/base/public/nsINode.h
@@ -558,7 +558,7 @@ public:
 
   // This class can be extended by subclasses that wish to store more
   // information in the slots.
-  class nsSlots
+  class nsSlots : public XPCOMGCObject
   {
   public:
     nsSlots(PtrBits aFlags)
@@ -567,10 +567,6 @@ public:
         mWeakReference(nsnull)
     {
     }
-
-    // If needed we could remove the vtable pointer this dtor causes by
-    // putting a DestroySlots function on nsINode
-    virtual ~nsSlots();
 
     /**
      * Storage for flags for this node. These are the same flags as the
diff --git a/content/base/src/nsGenericElement.cpp b/content/base/src/nsGenericElement.cpp
--- a/content/base/src/nsGenericElement.cpp
+++ b/content/base/src/nsGenericElement.cpp
@@ -164,20 +164,6 @@ nsresult NS_NewContentIterator(nsIConten
 
 //----------------------------------------------------------------------
 
-nsINode::nsSlots::~nsSlots()
-{
-  if (mChildNodes) {
-    mChildNodes->DropReference();
-    NS_RELEASE(mChildNodes);
-  }
-
-  if (mWeakReference) {
-    mWeakReference->NoticeNodeDestruction();
-  }
-}
-
-//----------------------------------------------------------------------
-
 nsINode::~nsINode()
 {
   NS_ASSERTION(!HasSlots(), "nsNodeUtils::LastRelease was not called?");
@@ -247,8 +233,8 @@ nsGenericElement::AddEventListenerByIID(
 nsGenericElement::AddEventListenerByIID(nsIDOMEventListener *aListener,
                                        const nsIID& aIID)
 {
-  nsCOMPtr<nsIEventListenerManager> elm;
-  nsresult rv = GetListenerManager(PR_TRUE, getter_AddRefs(elm));
+  nsIEventListenerManager* elm = nsnull;
+  nsresult rv = GetListenerManager(PR_TRUE, &elm);
   if (elm) {
     return elm->AddEventListenerByIID(aListener, aIID, NS_EVENT_FLAG_BUBBLE);
   }
@@ -259,8 +245,8 @@ nsGenericElement::RemoveEventListenerByI
 nsGenericElement::RemoveEventListenerByIID(nsIDOMEventListener *aListener,
                                            const nsIID& aIID)
 {
-  nsCOMPtr<nsIEventListenerManager> elm;
-  GetListenerManager(PR_FALSE, getter_AddRefs(elm));
+  nsIEventListenerManager* elm = nsnull;
+  GetListenerManager(PR_FALSE, &elm);
   if (elm) {
     return elm->RemoveEventListenerByIID(aListener, aIID, NS_EVENT_FLAG_BUBBLE);
   }
@@ -270,8 +256,8 @@ nsresult
 nsresult
 nsGenericElement::GetSystemEventGroup(nsIDOMEventGroup** aGroup)
 {
-  nsCOMPtr<nsIEventListenerManager> elm;
-  nsresult rv = GetListenerManager(PR_TRUE, getter_AddRefs(elm));
+  nsIEventListenerManager* elm = nsnull;
+  nsresult rv = GetListenerManager(PR_TRUE, &elm);
   if (elm) {
     return elm->GetSystemEventGroupLM(aGroup);
   }
@@ -490,7 +476,7 @@ NS_IMETHODIMP
 NS_IMETHODIMP
 nsNode3Tearoff::GetBaseURI(nsAString& aURI)
 {
-  nsCOMPtr<nsIURI> baseURI = mContent->GetBaseURI();
+  nsIURI* baseURI = mContent->GetBaseURI();
   nsCAutoString spec;
 
   if (baseURI) {
@@ -505,7 +491,7 @@ NS_IMETHODIMP
 NS_IMETHODIMP
 nsNode3Tearoff::GetTextContent(nsAString &aTextContent)
 {
-  nsCOMPtr<nsIDOMNode> node(do_QueryInterface(mContent));
+  nsIDOMNode* node(do_QueryInterface(mContent));
   NS_ASSERTION(node, "We have an nsIContent which doesn't support nsIDOMNode");
 
   PRUint16 nodeType;
@@ -535,7 +521,7 @@ nsNode3Tearoff::SetTextContent(const nsA
   // Batch possible DOMSubtreeModified events.
   mozAutoSubtreeModified subtree(mContent->GetOwnerDoc(), nsnull);
 
-  nsCOMPtr<nsIDOMNode> node(do_QueryInterface(mContent));
+  nsIDOMNode* node(do_QueryInterface(mContent));
   NS_ASSERTION(node, "We have an nsIContent which doesn't support nsIDOMNode");
 
   PRUint16 nodeType;
@@ -561,7 +547,7 @@ nsNode3Tearoff::CompareDocumentPosition(
 {
   NS_ENSURE_ARG_POINTER(aOther);
 
-  nsCOMPtr<nsINode> other = do_QueryInterface(aOther);
+  nsINode* other = do_QueryInterface(aOther);
   NS_ENSURE_TRUE(other, NS_ERROR_DOM_NOT_SUPPORTED_ERR);
 
   *aReturn = nsContentUtils::ComparePosition(other, mContent);
@@ -572,7 +558,7 @@ nsNode3Tearoff::IsSameNode(nsIDOMNode* a
 nsNode3Tearoff::IsSameNode(nsIDOMNode* aOther,
                            PRBool* aReturn)
 {
-  nsCOMPtr<nsIContent> other(do_QueryInterface(aOther));
+  nsIContent* other(do_QueryInterface(aOther));
   *aReturn = mContent == other;
 
   return NS_OK;
@@ -594,8 +580,8 @@ nsNode3Tearoff::AreNodesEqual(nsIContent
   }
 
   if (aContent1->Tag() == nsGkAtoms::documentTypeNodeName) {
-    nsCOMPtr<nsIDOMDocumentType> docType1 = do_QueryInterface(aContent1);
-    nsCOMPtr<nsIDOMDocumentType> docType2 = do_QueryInterface(aContent2);
+    nsIDOMDocumentType* docType1 = do_QueryInterface(aContent1);
+    nsIDOMDocumentType* docType2 = do_QueryInterface(aContent2);
 
     NS_ASSERTION(docType1 && docType2, "Why don't we have a document type node?");
 
@@ -651,8 +637,8 @@ nsNode3Tearoff::AreNodesEqual(nsIContent
     }
   } else {
     // aContent1 is not an element.  Node value check.
-    nsCOMPtr<nsIDOMNode> domNode1 = do_QueryInterface(aContent1);
-    nsCOMPtr<nsIDOMNode> domNode2 = do_QueryInterface(aContent2);
+    nsIDOMNode* domNode1 = do_QueryInterface(aContent1);
+    nsIDOMNode* domNode2 = do_QueryInterface(aContent2);
     NS_ASSERTION(domNode1 && domNode2, "How'd we get nsIContent without nsIDOMNode?");
     domNode1->GetNodeValue(string1);
     domNode2->GetNodeValue(string2);
@@ -687,7 +673,7 @@ nsNode3Tearoff::IsEqualNode(nsIDOMNode* 
   *aReturn = PR_FALSE;
 
   // Since we implement nsIContent, aOther must as well.
-  nsCOMPtr<nsIContent> aOtherContent = do_QueryInterface(aOther);
+  nsIContent* aOtherContent = do_QueryInterface(aOther);
   // Documents and attributes don't implement nsIContent.
   if (!aOtherContent) {
     return NS_OK;
@@ -840,7 +826,7 @@ nsNSElementTearoff::GetBoundingClientRec
   if (!rect)
     return NS_ERROR_OUT_OF_MEMORY;
 
-  NS_ADDREF(*aResult = rect);
+  *aResult = rect;
   
   nsIFrame* frame = mContent->GetPrimaryFrame(Flush_Layout);
   if (!frame) {
@@ -907,21 +893,16 @@ NS_IMPL_ISUPPORTS1(nsNodeWeakReference,
 NS_IMPL_ISUPPORTS1(nsNodeWeakReference,
                    nsIWeakReference)
 
-nsNodeWeakReference::~nsNodeWeakReference()
-{
-  if (mNode) {
-    NS_ASSERTION(mNode->GetSlots() &&
-                 mNode->GetSlots()->mWeakReference == this,
-                 "Weak reference has wrong value");
-    mNode->GetSlots()->mWeakReference = nsnull;
-  }
-}
-
 NS_IMETHODIMP
 nsNodeWeakReference::QueryReferent(const nsIID& aIID, void** aInstancePtr)
 {
-  return mNode ? mNode->QueryInterface(aIID, aInstancePtr) :
-                 NS_ERROR_NULL_POINTER;
+  nsINode* node = reinterpret_cast<nsINode*>(mRef->get());
+  if (!node) {
+    *aInstancePtr = nsnull;
+    return NS_ERROR_NULL_POINTER;
+  }
+
+  return node->QueryInterface(aIID, aInstancePtr);
 }
 
 
@@ -945,7 +926,7 @@ nsNodeSupportsWeakRefTearoff::GetWeakRef
     NS_ENSURE_TRUE(slots->mWeakReference, NS_ERROR_OUT_OF_MEMORY);
   }
 
-  NS_ADDREF(*aInstancePtr = slots->mWeakReference);
+  *aInstancePtr = slots->mWeakReference;
 
   return NS_OK;
 }
@@ -966,9 +947,9 @@ nsresult
 nsresult
 nsDOMEventRTTearoff::GetDOM3EventTarget(nsIDOM3EventTarget **aTarget)
 {
-  nsCOMPtr<nsIEventListenerManager> listener_manager;
+  nsIEventListenerManager* listener_manager = nsnull;
   nsresult rv =
-    mContent->GetListenerManager(PR_TRUE, getter_AddRefs(listener_manager));
+    mContent->GetListenerManager(PR_TRUE, &listener_manager);
   NS_ENSURE_SUCCESS(rv, rv);
 
   return CallQueryInterface(listener_manager, aTarget);
@@ -1010,11 +991,11 @@ NS_IMETHODIMP
 NS_IMETHODIMP
 nsDOMEventRTTearoff::DispatchEvent(nsIDOMEvent *aEvt, PRBool* _retval)
 {
-  nsCOMPtr<nsIEventListenerManager> listener_manager;
+  nsIEventListenerManager* listener_manager = nsnull;
   nsresult rv =
-    mContent->GetListenerManager(PR_TRUE, getter_AddRefs(listener_manager));
-  NS_ENSURE_SUCCESS(rv, rv);
-  nsCOMPtr<nsIDOMEventTarget> target = do_QueryInterface(listener_manager);
+    mContent->GetListenerManager(PR_TRUE, &listener_manager);
+  NS_ENSURE_SUCCESS(rv, rv);
+  nsIDOMEventTarget* target = do_QueryInterface(listener_manager);
   NS_ENSURE_STATE(target);
   return target->DispatchEvent(aEvt, _retval);
 }
@@ -1026,8 +1007,8 @@ nsDOMEventRTTearoff::AddGroupedEventList
                                              PRBool aUseCapture,
                                              nsIDOMEventGroup *aEvtGrp)
 {
-  nsCOMPtr<nsIDOM3EventTarget> event_target;
-  nsresult rv = GetDOM3EventTarget(getter_AddRefs(event_target));
+  nsIDOM3EventTarget* event_target = nsnull;
+  nsresult rv = GetDOM3EventTarget(&event_target);
   NS_ENSURE_SUCCESS(rv, rv);
 
   return event_target->AddGroupedEventListener(aType, aListener, aUseCapture,
@@ -1040,8 +1021,8 @@ nsDOMEventRTTearoff::RemoveGroupedEventL
                                                 PRBool aUseCapture,
                                                 nsIDOMEventGroup *aEvtGrp)
 {
-  nsCOMPtr<nsIDOM3EventTarget> event_target;
-  nsresult rv = GetDOM3EventTarget(getter_AddRefs(event_target));
+  nsIDOM3EventTarget* event_target = nsnull;
+  nsresult rv = GetDOM3EventTarget(&event_target);
   NS_ENSURE_SUCCESS(rv, rv);
 
   return event_target->RemoveGroupedEventListener(aType, aListener,
@@ -1067,9 +1048,9 @@ nsDOMEventRTTearoff::AddEventListener(co
                                       PRBool aUseCapture,
                                       PRBool aWantsUntrusted)
 {
-  nsCOMPtr<nsIEventListenerManager> listener_manager;
+  nsIEventListenerManager* listener_manager = nsnull;
   nsresult rv =
-    mContent->GetListenerManager(PR_TRUE, getter_AddRefs(listener_manager));
+    mContent->GetListenerManager(PR_TRUE, &listener_manager);
   NS_ENSURE_SUCCESS(rv, rv);
 
   PRInt32 flags = aUseCapture ? NS_EVENT_FLAG_CAPTURE : NS_EVENT_FLAG_BUBBLE;
@@ -1092,10 +1073,6 @@ nsGenericElement::nsDOMSlots::nsDOMSlots
 {
 }
 
-nsGenericElement::nsDOMSlots::~nsDOMSlots()
-{
-}
-
 nsGenericElement::nsGenericElement(nsINodeInfo *aNodeInfo)
   : nsIContent(aNodeInfo)
 {
@@ -1219,7 +1196,7 @@ nsGenericElement::SetPrefix(const nsAStr
 {
   // XXX: Validate the prefix string!
 
-  nsCOMPtr<nsIAtom> prefix;
+  nsIAtom* prefix = nsnull;
 
   if (!aPrefix.IsEmpty()) {
     prefix = do_GetAtom(aPrefix);
@@ -1231,9 +1208,9 @@ nsGenericElement::SetPrefix(const nsAStr
     return NS_ERROR_DOM_NAMESPACE_ERR;
   }
 
-  nsCOMPtr<nsINodeInfo> newNodeInfo;
+  nsINodeInfo* newNodeInfo = nsnull;
   nsresult rv = nsContentUtils::PrefixChanged(mNodeInfo, prefix,
-                                              getter_AddRefs(newNodeInfo));
+                                              &newNodeInfo);
   NS_ENSURE_SUCCESS(rv, rv);
 
   mNodeInfo = newNodeInfo;
@@ -1300,7 +1277,7 @@ nsGenericElement::InternalIsSupported(ns
   }
 #endif /* MOZ_SVG */
   else {
-    nsCOMPtr<nsIDOMNSFeatureFactory> factory =
+    nsIDOMNSFeatureFactory* factory =
       GetDOMFeatureFactory(aFeature, aVersion);
 
     if (factory) {
@@ -1317,7 +1294,7 @@ nsGenericElement::InternalGetFeature(nsI
                                     nsISupports** aReturn)
 {
   *aReturn = nsnull;
-  nsCOMPtr<nsIDOMNSFeatureFactory> factory =
+  nsIDOMNSFeatureFactory* factory =
     GetDOMFeatureFactory(aFeature, aVersion);
 
   if (factory) {
@@ -1327,12 +1304,12 @@ nsGenericElement::InternalGetFeature(nsI
   return NS_OK;
 }
 
-already_AddRefed<nsIDOMNSFeatureFactory>
+nsIDOMNSFeatureFactory*
 nsGenericElement::GetDOMFeatureFactory(const nsAString& aFeature,
                                        const nsAString& aVersion)
 {
   nsIDOMNSFeatureFactory *factory = nsnull;
-  nsCOMPtr<nsICategoryManager> categoryManager =
+  nsICategoryManager* categoryManager =
     do_GetService(NS_CATEGORYMANAGER_CONTRACTID);
   if (categoryManager) {
     nsCAutoString featureCategory(NS_DOMNS_FEATURE_PREFIX);
@@ -1387,7 +1364,7 @@ nsGenericElement::GetAttributes(nsIDOMNa
     }
   }
 
-  NS_ADDREF(*aAttributes = slots->mAttributeMap);
+  *aAttributes = slots->mAttributeMap;
 
   return NS_OK;
 }
@@ -1406,10 +1383,9 @@ nsGenericElement::GetChildNodes(nsIDOMNo
     if (!slots->mChildNodes) {
       return NS_ERROR_OUT_OF_MEMORY;
     }
-    NS_ADDREF(slots->mChildNodes);
-  }
-
-  NS_ADDREF(*aChildNodes = slots->mChildNodes);
+  }
+
+  *aChildNodes = slots->mChildNodes;
 
   return NS_OK;
 }
@@ -1490,7 +1466,7 @@ nsGenericElement::SetAttribute(const nsA
     nsresult rv = nsContentUtils::CheckQName(aName, PR_FALSE);
     NS_ENSURE_SUCCESS(rv, rv);
 
-    nsCOMPtr<nsIAtom> nameAtom = do_GetAtom(aName);
+    nsIAtom* nameAtom = do_GetAtom(aName);
     NS_ENSURE_TRUE(nameAtom, NS_ERROR_OUT_OF_MEMORY);
 
     return SetAttr(kNameSpaceID_None, nameAtom, aValue, PR_TRUE);
@@ -1524,12 +1500,12 @@ nsGenericElement::GetAttributeNode(const
   NS_ENSURE_ARG_POINTER(aReturn);
   *aReturn = nsnull;
 
-  nsCOMPtr<nsIDOMNamedNodeMap> map;
-  nsresult rv = GetAttributes(getter_AddRefs(map));
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  nsCOMPtr<nsIDOMNode> node;
-  rv = map->GetNamedItem(aName, getter_AddRefs(node));
+  nsIDOMNamedNodeMap* map = nsnull;
+  nsresult rv = GetAttributes(&map);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  nsIDOMNode* node = nsnull;
+  rv = map->GetNamedItem(aName, &node);
 
   if (NS_SUCCEEDED(rv) && node) {
     rv = CallQueryInterface(node, aReturn);
@@ -1547,12 +1523,12 @@ nsGenericElement::SetAttributeNode(nsIDO
 
   *aReturn = nsnull;
 
-  nsCOMPtr<nsIDOMNamedNodeMap> map;
-  nsresult rv = GetAttributes(getter_AddRefs(map));
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  nsCOMPtr<nsIDOMNode> returnNode;
-  rv = map->SetNamedItem(aAttribute, getter_AddRefs(returnNode));
+  nsIDOMNamedNodeMap* map = nsnull;
+  nsresult rv = GetAttributes(&map);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  nsIDOMNode* returnNode = nsnull;
+  rv = map->SetNamedItem(aAttribute, &returnNode);
   NS_ENSURE_SUCCESS(rv, rv);
 
   if (returnNode) {
@@ -1571,16 +1547,16 @@ nsGenericElement::RemoveAttributeNode(ns
 
   *aReturn = nsnull;
 
-  nsCOMPtr<nsIDOMNamedNodeMap> map;
-  nsresult rv = GetAttributes(getter_AddRefs(map));
+  nsIDOMNamedNodeMap* map = nsnull;
+  nsresult rv = GetAttributes(&map);
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsAutoString name;
 
   rv = aAttribute->GetName(name);
   if (NS_SUCCEEDED(rv)) {
-    nsCOMPtr<nsIDOMNode> node;
-    rv = map->RemoveNamedItem(name, getter_AddRefs(node));
+    nsIDOMNode* node = nsnull;
+    rv = map->RemoveNamedItem(name, &node);
 
     if (NS_SUCCEEDED(rv) && node) {
       rv = CallQueryInterface(node, aReturn);
@@ -1594,11 +1570,11 @@ nsGenericElement::GetElementsByTagName(c
 nsGenericElement::GetElementsByTagName(const nsAString& aTagname,
                                        nsIDOMNodeList** aReturn)
 {
-  nsCOMPtr<nsIAtom> nameAtom = do_GetAtom(aTagname);
+  nsIAtom* nameAtom = do_GetAtom(aTagname);
   NS_ENSURE_TRUE(nameAtom, NS_ERROR_OUT_OF_MEMORY);
 
   nsContentList *list = NS_GetContentList(this, nameAtom,
-                                          kNameSpaceID_Unknown).get();
+                                          kNameSpaceID_Unknown);
   NS_ENSURE_TRUE(list, NS_ERROR_OUT_OF_MEMORY);
 
   // transfer ref to aReturn
@@ -1622,7 +1598,7 @@ nsGenericElement::GetAttributeNS(const n
     return NS_OK;
   }
 
-  nsCOMPtr<nsIAtom> name = do_GetAtom(aLocalName);
+  nsIAtom* name = do_GetAtom(aLocalName);
   GetAttr(nsid, name, aReturn);
 
   return NS_OK;
@@ -1633,11 +1609,11 @@ nsGenericElement::SetAttributeNS(const n
                                  const nsAString& aQualifiedName,
                                  const nsAString& aValue)
 {
-  nsCOMPtr<nsINodeInfo> ni;
+  nsINodeInfo* ni = nsnull;
   nsresult rv =
     nsContentUtils::GetNodeInfoFromQName(aNamespaceURI, aQualifiedName,
                                          mNodeInfo->NodeInfoManager(),
-                                         getter_AddRefs(ni));
+                                         &ni);
   NS_ENSURE_SUCCESS(rv, rv);
 
   return SetAttr(ni->NamespaceID(), ni->NameAtom(), ni->GetPrefixAtom(),
@@ -1648,7 +1624,7 @@ nsGenericElement::RemoveAttributeNS(cons
 nsGenericElement::RemoveAttributeNS(const nsAString& aNamespaceURI,
                                     const nsAString& aLocalName)
 {
-  nsCOMPtr<nsIAtom> name = do_GetAtom(aLocalName);
+  nsIAtom* name = do_GetAtom(aLocalName);
   PRInt32 nsid =
     nsContentUtils::NameSpaceManager()->GetNameSpaceID(aNamespaceURI);
 
@@ -1673,12 +1649,12 @@ nsGenericElement::GetAttributeNodeNS(con
 
   *aReturn = nsnull;
 
-  nsCOMPtr<nsIDOMNamedNodeMap> map;
-  nsresult rv = GetAttributes(getter_AddRefs(map));
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  nsCOMPtr<nsIDOMNode> node;
-  rv = map->GetNamedItemNS(aNamespaceURI, aLocalName, getter_AddRefs(node));
+  nsIDOMNamedNodeMap* map = nsnull;
+  nsresult rv = GetAttributes(&map);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  nsIDOMNode* node = nsnull;
+  rv = map->GetNamedItemNS(aNamespaceURI, aLocalName, &node);
 
   if (NS_SUCCEEDED(rv) && node) {
     rv = CallQueryInterface(node, aReturn);
@@ -1696,12 +1672,12 @@ nsGenericElement::SetAttributeNodeNS(nsI
 
   *aReturn = nsnull;
 
-  nsCOMPtr<nsIDOMNamedNodeMap> map;
-  nsresult rv = GetAttributes(getter_AddRefs(map));
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  nsCOMPtr<nsIDOMNode> returnNode;
-  rv = map->SetNamedItemNS(aNewAttr, getter_AddRefs(returnNode));
+  nsIDOMNamedNodeMap* map = nsnull;
+  nsresult rv = GetAttributes(&map);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  nsIDOMNode* returnNode = nsnull;
+  rv = map->SetNamedItemNS(aNewAttr, &returnNode);
   NS_ENSURE_SUCCESS(rv, rv);
 
   if (returnNode) {
@@ -1725,10 +1701,10 @@ nsGenericElement::GetElementsByTagNameNS
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
-  nsCOMPtr<nsIAtom> nameAtom = do_GetAtom(aLocalName);
+  nsIAtom* nameAtom = do_GetAtom(aLocalName);
   NS_ENSURE_TRUE(nameAtom, NS_ERROR_OUT_OF_MEMORY);
 
-  nsContentList *list = NS_GetContentList(this, nameAtom, nameSpaceId).get();
+  nsContentList *list = NS_GetContentList(this, nameAtom, nameSpaceId);
   NS_ENSURE_TRUE(list, NS_ERROR_OUT_OF_MEMORY);
 
   // transfer ref to aReturn
@@ -1765,7 +1741,7 @@ nsGenericElement::HasAttributeNS(const n
     return NS_OK;
   }
 
-  nsCOMPtr<nsIAtom> name = do_GetAtom(aLocalName);
+  nsIAtom* name = do_GetAtom(aLocalName);
   *aReturn = HasAttr(nsid, name);
 
   return NS_OK;
@@ -1776,10 +1752,10 @@ nsGenericElement::JoinTextNodes(nsIConte
                                 nsIContent* aSecond)
 {
   nsresult rv = NS_OK;
-  nsCOMPtr<nsIDOMText> firstText(do_QueryInterface(aFirst, &rv));
-
-  if (NS_SUCCEEDED(rv)) {
-    nsCOMPtr<nsIDOMText> secondText(do_QueryInterface(aSecond, &rv));
+  nsIDOMText* firstText(do_QueryInterface(aFirst, &rv));
+
+  if (NS_SUCCEEDED(rv)) {
+    nsIDOMText* secondText(do_QueryInterface(aSecond, &rv));
 
     if (NS_SUCCEEDED(rv)) {
       nsAutoString str;
@@ -1806,7 +1782,7 @@ nsGenericElement::Normalize()
   for (index = 0; (index < count) && (NS_OK == result); index++) {
     nsIContent *child = GetChildAt(index);
 
-    nsCOMPtr<nsIDOMNode> node = do_QueryInterface(child);
+    nsIDOMNode* node = do_QueryInterface(child);
     if (node) {
       PRUint16 nodeType;
       node->GetNodeType(&nodeType);
@@ -1832,7 +1808,7 @@ nsGenericElement::Normalize()
             // nodes.
             nsIContent *sibling = GetChildAt(index + 1);
 
-            nsCOMPtr<nsIDOMNode> siblingNode = do_QueryInterface(sibling);
+            nsIDOMNode* siblingNode = do_QueryInterface(sibling);
 
             if (siblingNode) {
               PRUint16 siblingNodeType;
@@ -1856,7 +1832,7 @@ nsGenericElement::Normalize()
           break;
 
         case nsIDOMNode::ELEMENT_NODE:
-          nsCOMPtr<nsIDOMElement> element = do_QueryInterface(child);
+          nsIDOMElement* element = do_QueryInterface(child);
 
           if (element) {
             result = element->Normalize();
@@ -1896,16 +1872,16 @@ BindNodesInInsertPoints(nsXBLBinding* aB
   if (inserts) {
     PRBool allowScripts = aBinding->AllowScripts();
 #ifdef MOZ_XUL
-    nsCOMPtr<nsIXULDocument> xulDoc = do_QueryInterface(aDocument);
+    nsIXULDocument* xulDoc = do_QueryInterface(aDocument);
 #endif
     PRUint32 i;
     for (i = 0; i < inserts->Length(); ++i) {
-      nsCOMPtr<nsIContent> insertRoot =
+      nsIContent* insertRoot =
         inserts->ElementAt(i)->GetDefaultContent();
       if (insertRoot) {
         PRUint32 j;
         for (j = 0; j < insertRoot->GetChildCount(); ++j) {
-          nsCOMPtr<nsIContent> child = insertRoot->GetChildAt(j);
+          nsIContent* child = insertRoot->GetChildAt(j);
           rv = child->BindToTree(aDocument, aInsertParent,
                                  aBinding->GetBoundElement(), allowScripts);
           NS_ENSURE_SUCCESS(rv, rv);
@@ -2032,11 +2008,11 @@ nsGenericElement::BindToTree(nsIDocument
       nsXBLBinding* contBinding =
         GetFirstBindingWithContent(bmgr, this);
       if (contBinding) {
-        nsCOMPtr<nsIContent> anonRoot = contBinding->GetAnonymousContent();
+        nsIContent* anonRoot = contBinding->GetAnonymousContent();
         PRBool allowScripts = contBinding->AllowScripts();
         PRUint32 i;
         for (i = 0; i < anonRoot->GetChildCount(); ++i) {
-          nsCOMPtr<nsIContent> child = anonRoot->GetChildAt(i);
+          nsIContent* child = anonRoot->GetChildAt(i);
           rv = child->BindToTree(aDocument, this, this, allowScripts);
           NS_ENSURE_SUCCESS(rv, rv);
         }
@@ -2068,7 +2044,7 @@ nsGenericElement::BindToTree(nsIDocument
   // Additionally, there's not really a need to generate the children here.
   for (i = 0; i < mAttrsAndChildren.ChildCount(); ++i) {
     // The child can remove itself from the parent in BindToTree.
-    nsCOMPtr<nsIContent> child = mAttrsAndChildren.ChildAt(i);
+    nsIContent* child = mAttrsAndChildren.ChildAt(i);
     rv = child->BindToTree(aDocument, this, aBindingParent,
                            aCompileEventHandlers);
     NS_ENSURE_SUCCESS(rv, rv);
@@ -2228,7 +2204,7 @@ nsGenericElement::doPreHandleEvent(nsICo
     }
   }
 
-  nsCOMPtr<nsIContent> parent = aContent->GetParent();
+  nsIContent* parent = aContent->GetParent();
   if (isAnonForEvents) {
     // If a DOM event is explicitly dispatched using node.dispatchEvent(), then
     // all the events are allowed even in the native anonymous content..
@@ -2237,7 +2213,7 @@ nsGenericElement::doPreHandleEvent(nsICo
                  "Mutation event dispatched in native anonymous content!?!");
     aVisitor.mEventTargetAtParent = parent;
   } else if (parent) {
-    nsCOMPtr<nsIContent> content(do_QueryInterface(aVisitor.mEvent->target));
+    nsIContent* content(do_QueryInterface(aVisitor.mEvent->target));
     if (content && content->GetBindingParent() == parent) {
       aVisitor.mEventTargetAtParent = parent;
     }
@@ -2396,7 +2372,7 @@ nsGenericElement::GetExistingAttrNameFro
                                               kNameSpaceID_None, &nodeInfo);
   }
   else {
-    NS_ADDREF(nodeInfo = name->NodeInfo());
+    nodeInfo = name->NodeInfo();
   }
 
   return nodeInfo;
@@ -2415,7 +2391,7 @@ nsGenericElement::GetBaseURI() const
 
   // Our base URL depends on whether we have an xml:base attribute, as
   // well as on whether any of our ancestors do.
-  nsCOMPtr<nsIURI> parentBase;
+  nsIURI* parentBase = nsnull;
 
   nsIContent *parent = GetParent();
   if (parent) {
@@ -2432,13 +2408,13 @@ nsGenericElement::GetBaseURI() const
   if (value.IsEmpty()) {
     // No xml:base, so we just use the parent's base URL
     nsIURI *base = nsnull;
-    parentBase.swap(base);
+    swap(parentBase, base);
 
     return base;
   }
 
-  nsCOMPtr<nsIURI> ourBase;
-  nsresult rv = NS_NewURI(getter_AddRefs(ourBase), value,
+  nsIURI* ourBase = nsnull;
+  nsresult rv = NS_NewURI(&ourBase, value,
                           doc->GetDocumentCharacterSet().get(), parentBase);
   if (NS_SUCCEEDED(rv)) {
     // do a security check, almost the same as nsDocument::SetBaseURL()
@@ -2454,7 +2430,6 @@ nsGenericElement::GetBaseURI() const
     base = ourBase;
   }
 
-  NS_IF_ADDREF(base);
 
   return base;    
 }
@@ -2472,7 +2447,7 @@ nsGenericElement::SetFocus(nsPresContext
   // Traditionally focusable elements can take focus as long as they don't set
   // the disabled attribute
 
-  nsCOMPtr<nsIPresShell> presShell = aPresContext->PresShell();
+  nsIPresShell* presShell = aPresContext->PresShell();
   if (!presShell) {
     return;
   }
@@ -2503,8 +2478,8 @@ nsGenericElement::ShouldFocus(nsIContent
     nsIScriptGlobalObject *sgo = document->GetScriptGlobalObject();
 
     if (sgo) {
-      nsCOMPtr<nsIWebNavigation> webNav(do_GetInterface(sgo));
-      nsCOMPtr<nsIBaseWindow> baseWin(do_QueryInterface(webNav));
+      nsIWebNavigation* webNav(do_GetInterface(sgo));
+      nsIBaseWindow* baseWin(do_QueryInterface(webNav));
 
       if (baseWin) {
         baseWin->GetVisibility(&visible);
@@ -2529,13 +2504,13 @@ nsGenericElement::ShouldBlur(nsIContent 
     nsPIDOMWindow *win = document->GetWindow();
 
     if (win) {
-      nsCOMPtr<nsIFocusController> focusController =
+      nsIFocusController* focusController =
            win->GetRootFocusController();
 
       if (focusController) {
-        nsCOMPtr<nsIDOMElement> focusedElement;
-        focusController->GetFocusedElement(getter_AddRefs(focusedElement));    
-        nsCOMPtr<nsIDOMElement> domElement = do_QueryInterface(aContent);
+        nsIDOMElement* focusedElement = nsnull;
+        focusController->GetFocusedElement(&focusedElement);    
+        nsIDOMElement* domElement = do_QueryInterface(aContent);
         //when the element is the same as the focused element, blur it
         if (domElement == focusedElement)
           isFocused = PR_TRUE;
@@ -2711,7 +2686,7 @@ nsresult
 nsresult
 nsGenericElement::RemoveChildAt(PRUint32 aIndex, PRBool aNotify)
 {
-  nsCOMPtr<nsIContent> oldKid = mAttrsAndChildren.GetSafeChildAt(aIndex);
+  nsIContent* oldKid = mAttrsAndChildren.GetSafeChildAt(aIndex);
   NS_ASSERTION(oldKid == GetChildAt(aIndex), "Unexpected child in RemoveChildAt");
 
   if (oldKid) {
@@ -2739,7 +2714,7 @@ nsGenericElement::doRemoveChildAt(PRUint
   if (aNotify && aDocument) {
     nsIPresShell *presShell = aDocument->GetPrimaryShell();
     if (presShell && presShell->IsAccessibilityActive()) {
-      nsCOMPtr<nsIAccessibilityService> accService = 
+      nsIAccessibilityService* accService = 
         do_GetService("@mozilla.org/accessibilityService;1");
       if (accService) {
         accService->InvalidateSubtreeFor(presShell, aKid,
@@ -2810,7 +2785,7 @@ nsGenericElement::DispatchEvent(nsPresCo
     return NS_OK;
   }
 
-  nsCOMPtr<nsIPresShell> shell = aPresContext->GetPresShell();
+  nsIPresShell* shell = aPresContext->GetPresShell();
   if (!shell) {
     return NS_OK;
   }
@@ -2960,7 +2935,7 @@ PRBool IsAllowedAsChild(nsIContent* aNew
                   "Must have ref content for replace");
 #ifdef DEBUG
   PRUint16 debugNodeType = 0;
-  nsCOMPtr<nsIDOMNode> debugNode(do_QueryInterface(aNewChild));
+  nsIDOMNode* debugNode(do_QueryInterface(aNewChild));
   nsresult debugRv = debugNode->GetNodeType(&debugNodeType);
 
   NS_PRECONDITION(NS_SUCCEEDED(debugRv) && debugNodeType == aNewNodeType,
@@ -3004,11 +2979,11 @@ PRBool IsAllowedAsChild(nsIContent* aNew
       }
 
       // Now grovel for a doctype
-      nsCOMPtr<nsIDOMDocument> doc = do_QueryInterface(aDocument);
+      nsIDOMDocument* doc = do_QueryInterface(aDocument);
       NS_ASSERTION(doc, "Shouldn't happen");
-      nsCOMPtr<nsIDOMDocumentType> docType;
-      doc->GetDoctype(getter_AddRefs(docType));
-      nsCOMPtr<nsIContent> docTypeContent = do_QueryInterface(docType);
+      nsIDOMDocumentType* docType = nsnull;
+      doc->GetDoctype(&docType);
+      nsIContent* docTypeContent = do_QueryInterface(docType);
       
       if (!docTypeContent) {
         // It's all good.
@@ -3031,11 +3006,11 @@ PRBool IsAllowedAsChild(nsIContent* aNew
         return PR_FALSE;
       }
 
-      nsCOMPtr<nsIDOMDocument> doc = do_QueryInterface(aDocument);
+      nsIDOMDocument* doc = do_QueryInterface(aDocument);
       NS_ASSERTION(doc, "Shouldn't happen");
-      nsCOMPtr<nsIDOMDocumentType> docType;
-      doc->GetDoctype(getter_AddRefs(docType));
-      nsCOMPtr<nsIContent> docTypeContent = do_QueryInterface(docType);
+      nsIDOMDocumentType* docType = nsnull;
+      doc->GetDoctype(&docType);
+      nsIContent* docTypeContent = do_QueryInterface(docType);
       if (docTypeContent) {
         // Already have a doctype, so this is only OK if we're replacing it
         return aIsReplace && docTypeContent == aRefContent;
@@ -3086,7 +3061,7 @@ PRBool IsAllowedAsChild(nsIContent* aNew
         }
         // If we can put this content at the the right place, we might be ok;
         // if not, we bail out.
-        nsCOMPtr<nsIDOMNode> childNode(do_QueryInterface(childContent));
+        nsIDOMNode* childNode(do_QueryInterface(childContent));
         PRUint16 type;
         childNode->GetNodeType(&type);
         if (!IsAllowedAsChild(childContent, type, aParent, aDocument,
@@ -3129,9 +3104,9 @@ nsGenericElement::doReplaceOrInsertBefor
 
   // Keep a strong reference to the node that we'll return to ensure it
   // doesn't go away.
-  nsCOMPtr<nsIDOMNode> returnVal = aReplace ? aRefChild : aNewChild;
-
-  nsCOMPtr<nsIContent> refContent;
+  nsIDOMNode* returnVal = aReplace ? aRefChild : aNewChild;
+
+  nsIContent* refContent = nsnull;
   nsresult res = NS_OK;
   PRInt32 insPos;
 
@@ -3146,7 +3121,7 @@ nsGenericElement::doReplaceOrInsertBefor
     }
 
     if (aRefChild == aNewChild) {
-      NS_ADDREF(*aReturn = aNewChild);
+      *aReturn = aNewChild;
 
       return NS_OK;
     }
@@ -3154,7 +3129,7 @@ nsGenericElement::doReplaceOrInsertBefor
     insPos = container->GetChildCount();
   }
 
-  nsCOMPtr<nsIContent> newContent = do_QueryInterface(aNewChild);
+  nsIContent* newContent = do_QueryInterface(aNewChild);
   if (!newContent) {
     return NS_ERROR_DOM_HIERARCHY_REQUEST_ERR;
   }
@@ -3271,7 +3246,7 @@ nsGenericElement::doReplaceOrInsertBefor
           return NS_ERROR_DOM_NOT_FOUND_ERR;
         }
 
-        nsCOMPtr<nsIDOMNode> tmpNode = do_QueryInterface(childContent);
+        nsIDOMNode* tmpNode = do_QueryInterface(childContent);
         PRUint16 tmpType = 0;
         tmpNode->GetNodeType(&tmpType);
 
@@ -3351,7 +3326,7 @@ nsGenericElement::doReplaceOrInsertBefor
     NS_ENSURE_SUCCESS(res, res);
   }
 
-  returnVal.swap(*aReturn);
+  swap(returnVal, *aReturn);
 
   return res;
 }
@@ -3370,7 +3345,7 @@ nsGenericElement::doRemoveChild(nsIDOMNo
 
   nsINode* container = NODE_FROM(aParent, aDocument);
 
-  nsCOMPtr<nsIContent> content = do_QueryInterface(aOldChild);
+  nsIContent* content = do_QueryInterface(aOldChild);
   // fix children to be a passed argument
   PRInt32 index = container->IndexOf(content);
   if (index == -1) {
@@ -3381,7 +3356,6 @@ nsGenericElement::doRemoveChild(nsIDOMNo
   nsresult rv = container->RemoveChildAt(index, PR_TRUE);
 
   *aReturn = aOldChild;
-  NS_ADDREF(aOldChild);
 
   return rv;
 }
@@ -3456,12 +3430,12 @@ nsGenericElement::AddScriptEventListener
   }
 
   NS_PRECONDITION(aEventName, "Must have event name!");
-  nsCOMPtr<nsISupports> target;
+  nsISupports* target = nsnull;
   PRBool defer = PR_TRUE;
-  nsCOMPtr<nsIEventListenerManager> manager;
-
-  nsresult rv = GetEventListenerManagerForAttr(getter_AddRefs(manager),
-                                               getter_AddRefs(target),
+  nsIEventListenerManager* manager = nsnull;
+
+  nsresult rv = GetEventListenerManagerForAttr(&manager,
+                                               &target,
                                                &defer);
   NS_ENSURE_SUCCESS(rv, rv);
 
@@ -3612,10 +3586,10 @@ nsGenericElement::SetAttrAndNotify(PRInt
     }
   }
   else {
-    nsCOMPtr<nsINodeInfo> ni;
+    nsINodeInfo* ni = nsnull;
     rv = mNodeInfo->NodeInfoManager()->GetNodeInfo(aName, aPrefix,
                                                    aNamespaceID,
-                                                   getter_AddRefs(ni));
+                                                   &ni);
     NS_ENSURE_SUCCESS(rv, rv);
 
     rv = mAttrsAndChildren.SetAndTakeAttr(ni, aParsedValue);
@@ -3714,7 +3688,7 @@ nsGenericElement::GetEventListenerManage
 {
   nsresult rv = GetListenerManager(PR_TRUE, aManager);
   if (NS_SUCCEEDED(rv)) {
-    NS_ADDREF(*aTarget = static_cast<nsIContent*>(this));
+    *aTarget = static_cast<nsIContent*>(this);
   }
   *aDefer = PR_TRUE;
   return rv;
@@ -3859,13 +3833,13 @@ nsGenericElement::UnsetAttr(PRInt32 aNam
                                          this);
 
   // Grab the attr node if needed before we remove it from the attr map
-  nsCOMPtr<nsIDOMAttr> attrNode;
+  nsIDOMAttr* attrNode = nsnull;
   if (hasMutationListeners) {
     nsAutoString attrName;
     aName->ToString(attrName);
     nsAutoString ns;
     nsContentUtils::NameSpaceManager()->GetNameSpaceURI(aNameSpaceID, ns);
-    GetAttributeNodeNS(ns, attrName, getter_AddRefs(attrNode));
+    GetAttributeNodeNS(ns, attrName, &attrNode);
   }
 
   // Clear binding to nsIDOMNamedNodeMap
@@ -4051,9 +4025,9 @@ nsGenericElement::List(FILE* out, PRInt3
     // Note: not listing nsIAnonymousContentCreator-created content...
 
     nsBindingManager* bindingManager = document->BindingManager();
-    nsCOMPtr<nsIDOMNodeList> anonymousChildren;
+    nsIDOMNodeList* anonymousChildren = nsnull;
     bindingManager->GetAnonymousNodesFor(nonConstThis,
-                                         getter_AddRefs(anonymousChildren));
+                                         &anonymousChildren);
 
     if (anonymousChildren) {
       anonymousChildren->GetLength(&length);
@@ -4062,9 +4036,9 @@ nsGenericElement::List(FILE* out, PRInt3
         fputs("anonymous-children<\n", out);
 
         for (i = 0; i < length; ++i) {
-          nsCOMPtr<nsIDOMNode> node;
-          anonymousChildren->Item(i, getter_AddRefs(node));
-          nsCOMPtr<nsIContent> child = do_QueryInterface(node);
+          nsIDOMNode* node = nsnull;
+          anonymousChildren->Item(i, &node);
+          nsIContent* child = do_QueryInterface(node);
           child->List(out, aIndent + 1);
         }
 
@@ -4074,9 +4048,9 @@ nsGenericElement::List(FILE* out, PRInt3
     }
 
     if (bindingManager->HasContentListFor(nonConstThis)) {
-      nsCOMPtr<nsIDOMNodeList> contentList;
+      nsIDOMNodeList* contentList = nsnull;
       bindingManager->GetContentListFor(nonConstThis,
-                                        getter_AddRefs(contentList));
+                                        &contentList);
 
       NS_ASSERTION(contentList != nsnull, "oops, binding manager lied");
 
@@ -4086,9 +4060,9 @@ nsGenericElement::List(FILE* out, PRInt3
         fputs("content-list<\n", out);
 
         for (i = 0; i < length; ++i) {
-          nsCOMPtr<nsIDOMNode> node;
-          contentList->Item(i, getter_AddRefs(node));
-          nsCOMPtr<nsIContent> child = do_QueryInterface(node);
+          nsIDOMNode* node = nsnull;
+          contentList->Item(i, &node);
+          nsIContent* child = do_QueryInterface(node);
           child->List(out, aIndent + 1);
         }
 
@@ -4186,8 +4160,8 @@ nsGenericElement::PreHandleEventForLinks
   }
 
   // Make sure we meet the preconditions before continuing
-  nsCOMPtr<nsIURI> absURI;
-  if (!CheckHandleEventForLinksPrecondition(aVisitor, getter_AddRefs(absURI))) {
+  nsIURI* absURI = nsnull;
+  if (!CheckHandleEventForLinksPrecondition(aVisitor, &absURI)) {
     return NS_OK;
   }
 
@@ -4241,8 +4215,8 @@ nsGenericElement::PostHandleEventForLink
   }
 
   // Make sure we meet the preconditions before continuing
-  nsCOMPtr<nsIURI> absURI;
-  if (!CheckHandleEventForLinksPrecondition(aVisitor, getter_AddRefs(absURI))) {
+  nsIURI* absURI = nsnull;
+  if (!CheckHandleEventForLinksPrecondition(aVisitor, &absURI)) {
     return NS_OK;
   }
 
@@ -4269,7 +4243,7 @@ nsGenericElement::PostHandleEventForLink
               PRBool isActive = PR_FALSE;
               focusController->GetActive(&isActive);
               if (!isActive) {
-                nsCOMPtr<nsIDOMElement> domElement = do_QueryInterface(this);
+                nsIDOMElement* domElement = do_QueryInterface(this);
                 if(domElement)
                   focusController->SetFocusedElement(domElement);
                 break;
@@ -4293,7 +4267,7 @@ nsGenericElement::PostHandleEventForLink
       }
 
       // The default action is simply to dispatch DOMActivate
-      nsCOMPtr<nsIPresShell> shell = aVisitor.mPresContext->GetPresShell();
+      nsIPresShell* shell = aVisitor.mPresContext->GetPresShell();
       if (shell) {
         // single-click
         nsEventStatus status = nsEventStatus_eIgnore;
diff --git a/content/base/src/nsGenericElement.h b/content/base/src/nsGenericElement.h
--- a/content/base/src/nsGenericElement.h
+++ b/content/base/src/nsGenericElement.h
@@ -85,7 +85,7 @@ typedef unsigned long PtrBits;
  * and Item to its existing child list.
  * @see nsIDOMNodeList
  */
-class nsChildContentList : public nsGenericDOMNodeList 
+class nsChildContentList : public XPCOMGCFinalizedObject, public nsGenericDOMNodeList 
 {
 public:
   nsChildContentList(nsINode* aNode)
@@ -111,7 +111,7 @@ private:
 /**
  * A tearoff class for nsGenericElement to implement additional interfaces
  */
-class nsNode3Tearoff : public nsIDOM3Node
+class nsNode3Tearoff : public XPCOMGCFinalizedObject, public nsIDOM3Node
 {
 public:
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
@@ -146,15 +146,17 @@ private:
  * A class that implements nsIWeakReference
  */
 
-class nsNodeWeakReference : public nsIWeakReference
+class nsNodeWeakReference : public XPCOMGCFinalizedObject, public nsIWeakReference
 {
 public:
   nsNodeWeakReference(nsINode* aNode)
-    : mNode(aNode)
+    : mRef(NS_GetGC()->GetWeakRef(aNode))
   {
   }
 
-  ~nsNodeWeakReference();
+  ~nsNodeWeakReference()
+  {
+  }
 
   // nsISupports
   NS_DECL_ISUPPORTS
@@ -162,19 +164,14 @@ public:
   // nsIWeakReference
   NS_DECL_NSIWEAKREFERENCE
 
-  void NoticeNodeDestruction()
-  {
-    mNode = nsnull;
-  }
-
 private:
-  nsINode* mNode;
+  MMgc::GCWeakRef *mRef;
 };
 
 /**
  * Tearoff to use for nodes to implement nsISupportsWeakReference
  */
-class nsNodeSupportsWeakRefTearoff : public nsISupportsWeakReference
+class nsNodeSupportsWeakRefTearoff : public XPCOMGCFinalizedObject, public nsISupportsWeakReference
 {
 public:
   nsNodeSupportsWeakRefTearoff(nsINode* aNode)
@@ -578,7 +575,7 @@ public:
                                      const nsAString& aVersion,
                                      nsISupports** aReturn);
   
-  static already_AddRefed<nsIDOMNSFeatureFactory>
+  static nsIDOMNSFeatureFactory*
     GetDOMFeatureFactory(const nsAString& aFeature, const nsAString& aVersion);
 
   static PRBool ShouldFocus(nsIContent *aContent);
@@ -891,7 +888,6 @@ public:
   {
   public:
     nsDOMSlots(PtrBits aFlags);
-    virtual ~nsDOMSlots();
 
     /**
      * The .style attribute (an interface that forwards to the actual
@@ -917,11 +913,6 @@ public:
       */
       nsIControllers* mControllers; // [OWNER]
     };
-    
-    /**
-     * Weak reference to this node
-     */
-    nsNodeWeakReference* mWeakReference;
   };
 
 protected:
@@ -1042,7 +1033,7 @@ _elementName::Clone(nsINodeInfo *aNodeIn
  * Yet another tearoff class for nsGenericElement
  * to implement additional interfaces
  */
-class nsNSElementTearoff : public nsIDOMNSElement
+class nsNSElementTearoff : public XPCOMGCFinalizedObject, public nsIDOMNSElement
 {
 public:
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
diff --git a/content/base/src/nsNodeUtils.cpp b/content/base/src/nsNodeUtils.cpp
--- a/content/base/src/nsNodeUtils.cpp
+++ b/content/base/src/nsNodeUtils.cpp
@@ -184,67 +184,6 @@ nsNodeUtils::ParentChainChanged(nsIConte
   }
 }
 
-void
-nsNodeUtils::LastRelease(nsINode* aNode)
-{
-  nsINode::nsSlots* slots = aNode->GetExistingSlots();
-  if (slots) {
-    if (!slots->mMutationObservers.IsEmpty()) {
-      NS_OBSERVER_ARRAY_NOTIFY_OBSERVERS(slots->mMutationObservers,
-                                         nsIMutationObserver,
-                                         NodeWillBeDestroyed, (aNode));
-    }
-
-    PtrBits flags = slots->mFlags | NODE_DOESNT_HAVE_SLOTS;
-    delete slots;
-    aNode->mFlagsOrSlots = flags;
-  }
-
-  // Kill properties first since that may run external code, so we want to
-  // be in as complete state as possible at that time.
-  if (aNode->IsNodeOfType(nsINode::eDOCUMENT)) {
-    // Delete all properties before tearing down the document. Some of the
-    // properties are bound to nsINode objects and the destructor functions of
-    // the properties may want to use the owner document of the nsINode.
-    static_cast<nsIDocument*>(aNode)->PropertyTable()->DeleteAllProperties();
-  }
-  else if (aNode->HasProperties()) {
-    // Strong reference to the document so that deleting properties can't
-    // delete the document.
-    nsCOMPtr<nsIDocument> document = aNode->GetOwnerDoc();
-    if (document) {
-      document->PropertyTable()->DeleteAllPropertiesFor(aNode);
-    }
-  }
-  aNode->UnsetFlags(NODE_HAS_PROPERTIES);
-
-  if (aNode->HasFlag(NODE_HAS_LISTENERMANAGER)) {
-#ifdef DEBUG
-    if (nsContentUtils::IsInitialized()) {
-      nsCOMPtr<nsIEventListenerManager> manager;
-      nsContentUtils::GetListenerManager(aNode, PR_FALSE,
-                                         getter_AddRefs(manager));
-      if (!manager) {
-        NS_ERROR("Huh, our bit says we have a listener manager list, "
-                 "but there's nothing in the hash!?!!");
-      }
-    }
-#endif
-
-    nsContentUtils::RemoveListenerManager(aNode);
-    aNode->UnsetFlags(NODE_HAS_LISTENERMANAGER);
-  }
-
-  if (aNode->IsNodeOfType(nsINode::eELEMENT)) {
-    nsIDocument* ownerDoc = aNode->GetOwnerDoc();
-    if (ownerDoc) {
-      ownerDoc->ClearBoxObjectFor(static_cast<nsIContent*>(aNode));
-    }
-  }
-
-  delete aNode;
-}
-
 static nsresult
 SetUserDataProperty(PRUint16 aCategory, nsINode *aNode, nsIAtom *aKey,
                     nsISupports* aValue, void** aOldValue)
@@ -255,7 +194,6 @@ SetUserDataProperty(PRUint16 aCategory, 
   NS_ENSURE_SUCCESS(rv, rv);
 
   // Property table owns it now.
-  NS_ADDREF(aValue);
 
   return NS_OK;
 }
@@ -268,7 +206,7 @@ nsNodeUtils::SetUserData(nsINode *aNode,
 {
   *aResult = nsnull;
 
-  nsCOMPtr<nsIAtom> key = do_GetAtom(aKey);
+  nsIAtom* key = do_GetAtom(aKey);
   if (!key) {
     return NS_ERROR_OUT_OF_MEMORY;
   }
@@ -284,12 +222,12 @@ nsNodeUtils::SetUserData(nsINode *aNode,
   }
 
   // Take over ownership of the old data from the property table.
-  nsCOMPtr<nsIVariant> oldData = dont_AddRef(static_cast<nsIVariant*>(data));
+  nsIVariant* oldData = dont_AddRef(static_cast<nsIVariant*>(data));
 
   if (aData && aHandler) {
-    nsCOMPtr<nsIDOMUserDataHandler> oldHandler;
+    nsIDOMUserDataHandler* oldHandler = nsnull;
     rv = SetUserDataProperty(DOM_USER_DATA_HANDLER, aNode, key, aHandler,
-                             getter_AddRefs(oldHandler));
+                             (void**)&oldHandler);
     if (NS_FAILED(rv)) {
       // We failed to set the handler, remove the data.
       aNode->DeleteProperty(DOM_USER_DATA, key);
@@ -301,7 +239,7 @@ nsNodeUtils::SetUserData(nsINode *aNode,
     aNode->DeleteProperty(DOM_USER_DATA_HANDLER, key);
   }
 
-  oldData.swap(*aResult);
+  swap(oldData, *aResult);
 
   return NS_OK;
 }
@@ -311,14 +249,13 @@ nsNodeUtils::GetUserData(nsINode *aNode,
 nsNodeUtils::GetUserData(nsINode *aNode, const nsAString &aKey,
                          nsIVariant **aResult)
 {
-  nsCOMPtr<nsIAtom> key = do_GetAtom(aKey);
+  nsIAtom* key = do_GetAtom(aKey);
   if (!key) {
     return NS_ERROR_OUT_OF_MEMORY;
   }
 
   *aResult = static_cast<nsIVariant*>
                         (aNode->GetProperty(DOM_USER_DATA, key));
-  NS_IF_ADDREF(*aResult);
 
   return NS_OK;
 }
@@ -334,10 +271,10 @@ CallHandler(void *aObject, nsIAtom *aKey
 CallHandler(void *aObject, nsIAtom *aKey, void *aHandler, void *aData)
 {
   nsHandlerData *handlerData = static_cast<nsHandlerData*>(aData);
-  nsCOMPtr<nsIDOMUserDataHandler> handler =
+  nsIDOMUserDataHandler* handler =
     static_cast<nsIDOMUserDataHandler*>(aHandler);
   nsINode *node = static_cast<nsINode*>(aObject);
-  nsCOMPtr<nsIVariant> data =
+  nsIVariant* data =
     static_cast<nsIVariant*>(node->GetProperty(DOM_USER_DATA, aKey));
   NS_ASSERTION(data, "Handler without data?");
 
@@ -361,7 +298,7 @@ nsNodeUtils::CallUserDataHandlers(nsCOMA
 
   // Keep the document alive, just in case one of the handlers causes it to go
   // away.
-  nsCOMPtr<nsIDocument> ownerDoc = aOwnerDocument;
+  nsIDocument* ownerDoc = aOwnerDocument;
 
   nsHandlerData handlerData;
   handlerData.mOperation = aOperation;
@@ -392,10 +329,10 @@ nsNodeUtils::CloneNodeImpl(nsINode *aNod
 {
   *aResult = nsnull;
 
-  nsCOMPtr<nsIDOMNode> newNode;
+  nsIDOMNode* newNode = nsnull;
   nsCOMArray<nsINode> nodesWithProperties;
   nsresult rv = Clone(aNode, aDeep, nsnull, nodesWithProperties,
-                      getter_AddRefs(newNode));
+                      &newNode);
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsIDocument *ownerDoc = aNode->GetOwnerDoc();
@@ -405,7 +342,7 @@ nsNodeUtils::CloneNodeImpl(nsINode *aNod
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
-  newNode.swap(*aResult);
+  swap(newNode, *aResult);
 
   return NS_OK;
 }
@@ -435,7 +372,7 @@ PLDHashOperator PR_CALLBACK
 PLDHashOperator PR_CALLBACK
 AdoptFunc(nsAttrHashKey::KeyType aKey, nsIDOMNode *aData, void* aUserArg)
 {
-  nsCOMPtr<nsIAttribute> attr = do_QueryInterface(aData);
+  nsIAttribute* attr = do_QueryInterface(aData);
   NS_ASSERTION(attr, "non-nsIAttribute somehow made it into the hashmap?!");
 
   AdoptFuncData *data = static_cast<AdoptFuncData*>(aUserArg);
@@ -443,18 +380,18 @@ AdoptFunc(nsAttrHashKey::KeyType aKey, n
   // If we were passed an element we need to clone the attribute nodes and
   // insert them into the element.
   PRBool clone = data->mElement != nsnull;
-  nsCOMPtr<nsIDOMNode> node;
+  nsIDOMNode* node = nsnull;
   nsresult rv = nsNodeUtils::CloneAndAdopt(attr, clone, PR_TRUE,
                                            data->mNewNodeInfoManager,
                                            data->mCx, data->mOldScope,
                                            data->mNewScope,
                                            data->mNodesWithProperties,
-                                           nsnull, getter_AddRefs(node));
+                                           nsnull, &node);
 
   if (NS_SUCCEEDED(rv) && clone) {
-    nsCOMPtr<nsIDOMAttr> dummy, attribute = do_QueryInterface(node, &rv);
+    nsIDOMAttr* dummy = nsnull, *attribute = do_QueryInterface(node, &rv);
     if (NS_SUCCEEDED(rv)) {
-      rv = data->mElement->SetAttributeNode(attribute, getter_AddRefs(dummy));
+      rv = data->mElement->SetAttributeNode(attribute, &dummy);
     }
   }
 
@@ -488,12 +425,12 @@ nsNodeUtils::CloneAndAdopt(nsINode *aNod
 
   // aNode.
   nsINodeInfo *nodeInfo = aNode->mNodeInfo;
-  nsCOMPtr<nsINodeInfo> newNodeInfo;
+  nsINodeInfo* newNodeInfo = nsnull;
   if (nodeInfoManager) {
     rv = nodeInfoManager->GetNodeInfo(nodeInfo->NameAtom(),
                                       nodeInfo->GetPrefixAtom(),
                                       nodeInfo->NamespaceID(),
-                                      getter_AddRefs(newNodeInfo));
+                                      &newNodeInfo);
     NS_ENSURE_SUCCESS(rv, rv);
 
     nodeInfo = newNodeInfo;
@@ -503,15 +440,15 @@ nsNodeUtils::CloneAndAdopt(nsINode *aNod
                            static_cast<nsGenericElement*>(aNode) :
                            nsnull;
 
-  nsCOMPtr<nsINode> clone;
+  nsINode* clone = nsnull;
   if (aClone) {
-    rv = aNode->Clone(nodeInfo, getter_AddRefs(clone));
+    rv = aNode->Clone(nodeInfo, &clone);
     NS_ENSURE_SUCCESS(rv, rv);
 
     if (aParent) {
       // If we're cloning we need to insert the cloned children into the cloned
       // parent.
-      nsCOMPtr<nsIContent> cloneContent = do_QueryInterface(clone, &rv);
+      nsIContent* cloneContent = do_QueryInterface(clone, &rv);
       NS_ENSURE_SUCCESS(rv, rv);
 
       rv = aParent->AppendChildTo(cloneContent, PR_FALSE);
@@ -525,7 +462,7 @@ nsNodeUtils::CloneAndAdopt(nsINode *aNod
     }
   }
   else if (nodeInfoManager) {
-    nsCOMPtr<nsISupports> oldRef;
+    nsISupports* oldRef = nsnull;
     nsIDocument* oldDoc = aNode->GetOwnerDoc();
     if (oldDoc) {
       if (aNode->IsNodeOfType(nsINode::eELEMENT)) {
@@ -547,8 +484,8 @@ nsNodeUtils::CloneAndAdopt(nsINode *aNod
 
       nsPIDOMWindow* window = newDoc->GetInnerWindow();
       if (window) {
-        nsCOMPtr<nsIEventListenerManager> elm;
-        aNode->GetListenerManager(PR_FALSE, getter_AddRefs(elm));
+        nsIEventListenerManager* elm = nsnull;
+        aNode->GetListenerManager(PR_FALSE, &elm);
         if (elm) {
           window->SetMutationListeners(elm->MutationListenerBits());
         }
@@ -562,9 +499,9 @@ nsNodeUtils::CloneAndAdopt(nsINode *aNod
     if (aCx) {
       nsIXPConnect *xpc = nsContentUtils::XPConnect();
       if (xpc) {
-        nsCOMPtr<nsIXPConnectJSObjectHolder> oldWrapper;
+        nsIXPConnectJSObjectHolder* oldWrapper = nsnull;
         rv = xpc->ReparentWrappedNativeIfFound(aCx, aOldScope, aNewScope, aNode,
-                                               getter_AddRefs(oldWrapper));
+                                               &oldWrapper);
         if (NS_FAILED(rv)) {
           aNode->mNodeInfo.swap(nodeInfo);
 
@@ -578,7 +515,7 @@ nsNodeUtils::CloneAndAdopt(nsINode *aNod
     // aNode's attributes.
     const nsDOMAttributeMap *map = elem->GetAttributeMap();
     if (map) {
-      nsCOMPtr<nsIDOMElement> element;
+      nsIDOMElement* element = nsnull;
       if (aClone) {
         // If we're cloning we need to insert the cloned attribute nodes into
         // the cloned element.
@@ -602,11 +539,11 @@ nsNodeUtils::CloneAndAdopt(nsINode *aNod
   //     GetChildAt(0). We can remove this when
   //     https://bugzilla.mozilla.org/show_bug.cgi?id=56758 is fixed.
   if (aClone && aNode->IsNodeOfType(nsINode::eATTRIBUTE)) {
-    nsCOMPtr<nsINode> attrChildNode = aNode->GetChildAt(0);
+    nsINode* attrChildNode = aNode->GetChildAt(0);
     // We only need to do this if the child node has properties (because we
     // might need to call a userdata handler).
     if (attrChildNode && attrChildNode->HasProperties()) {
-      nsCOMPtr<nsINode> clonedAttrChildNode = clone->GetChildAt(0);
+      nsINode* clonedAttrChildNode = clone->GetChildAt(0);
       if (clonedAttrChildNode) {
         PRBool ok = aNodesWithProperties.AppendObject(attrChildNode) &&
                     aNodesWithProperties.AppendObject(clonedAttrChildNode);
@@ -619,10 +556,10 @@ nsNodeUtils::CloneAndAdopt(nsINode *aNod
     // aNode's children.
     PRUint32 i, length = aNode->GetChildCount();
     for (i = 0; i < length; ++i) {
-      nsCOMPtr<nsIDOMNode> child;
+      nsIDOMNode* child = nsnull;
       rv = CloneAndAdopt(aNode->GetChildAt(i), aClone, PR_TRUE, nodeInfoManager,
                          aCx, aOldScope, aNewScope, aNodesWithProperties,
-                         clone, getter_AddRefs(child));
+                         clone, &child);
       NS_ENSURE_SUCCESS(rv, rv);
     }
   }
@@ -668,7 +605,7 @@ nsNodeUtils::UnlinkUserData(nsINode *aNo
 
   // Strong reference to the document so that deleting properties can't
   // delete the document.
-  nsCOMPtr<nsIDocument> document = aNode->GetOwnerDoc();
+  nsIDocument* document = aNode->GetOwnerDoc();
   if (document) {
     document->PropertyTable()->DeleteAllPropertiesFor(aNode, DOM_USER_DATA);
     document->PropertyTable()->DeleteAllPropertiesFor(aNode,
diff --git a/content/base/src/nsNodeUtils.h b/content/base/src/nsNodeUtils.h
--- a/content/base/src/nsNodeUtils.h
+++ b/content/base/src/nsNodeUtils.h
@@ -125,12 +125,6 @@ public:
   static void ParentChainChanged(nsIContent *aContent);
 
   /**
-   * To be called when reference count of aNode drops to zero.
-   * @param aNode The node which is going to be deleted.
-   */
-  static void LastRelease(nsINode* aNode);
-
-  /**
    * Clones aNode, its attributes and, if aDeep is PR_TRUE, its descendant nodes
    * If aNewNodeInfoManager is not null, it is used to create new nodeinfos for
    * the clones. aNodesWithProperties will be filled with all the nodes that
@@ -183,10 +177,10 @@ public:
                         JSObject *aNewScope,
                         nsCOMArray<nsINode> &aNodesWithProperties)
   {
-    nsCOMPtr<nsIDOMNode> dummy;
+    nsIDOMNode* dummy = nsnull;
     return CloneAndAdopt(aNode, PR_FALSE, PR_TRUE, aNewNodeInfoManager, aCx,
                          aOldScope, aNewScope, aNodesWithProperties,
-                         nsnull, getter_AddRefs(dummy));
+                         nsnull, &dummy);
   }
 
   /**