Bug 414894 - Remove content arena. r=smaug, sr=sicking, a=schrep
authordwitte@stanford.edu
Sat, 02 Feb 2008 15:41:24 -0800
changeset 11169 d9d2444dec2f09a7cc1d9800024be6519737c2e3
parent 11168 3e99864f3c4f474289bae3de5b1bbd33cd35ae3e
child 11170 3d990bd9ef96c5805e0e8e8d8bff72f43845360d
push id1
push userroot
push dateTue, 26 Apr 2011 22:38:44 +0000
treeherdermozilla-beta@bfdb6e623a36 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug, sicking, schrep
bugs414894
milestone1.9b3pre
Bug 414894 - Remove content arena. r=smaug, sr=sicking, a=schrep
content/base/public/nsINode.h
content/base/src/contentbase.gqi
content/base/src/nsAttrAndChildArray.cpp
content/base/src/nsAttrAndChildArray.h
content/base/src/nsCommentNode.cpp
content/base/src/nsDOMAttribute.cpp
content/base/src/nsDOMAttribute.h
content/base/src/nsDOMAttributeMap.cpp
content/base/src/nsDOMDocumentType.cpp
content/base/src/nsDocument.cpp
content/base/src/nsDocument.h
content/base/src/nsDocumentFragment.cpp
content/base/src/nsGenConImageContent.cpp
content/base/src/nsGenericDOMDataNode.cpp
content/base/src/nsGenericDOMDataNode.h
content/base/src/nsGenericElement.cpp
content/base/src/nsGenericElement.h
content/base/src/nsNodeInfoManager.cpp
content/base/src/nsNodeInfoManager.h
content/base/src/nsNodeUtils.cpp
content/base/src/nsTextFragment.cpp
content/base/src/nsTextFragment.h
content/base/src/nsTextNode.cpp
content/events/src/nsXMLEventsElement.cpp
content/html/content/src/nsGenericHTMLElement.h
content/html/content/src/nsHTMLCanvasElement.cpp
content/html/content/src/nsHTMLFormElement.cpp
content/html/content/src/nsHTMLImageElement.cpp
content/html/content/src/nsHTMLInputElement.cpp
content/html/content/src/nsHTMLOptionElement.cpp
content/html/content/src/nsHTMLScriptElement.cpp
content/html/document/src/nsHTMLContentSink.cpp
content/mathml/content/src/nsMathMLElementFactory.cpp
content/svg/content/src/nsSVGElement.cpp
content/svg/content/src/nsSVGElement.h
content/svg/content/src/nsSVGUseElement.cpp
content/xml/content/src/nsXMLCDATASection.cpp
content/xml/content/src/nsXMLElement.cpp
content/xml/content/src/nsXMLProcessingInstruction.cpp
content/xml/content/src/nsXMLStylesheetPI.cpp
content/xtf/src/nsXTFElementWrapper.cpp
content/xul/content/src/nsXULElement.cpp
--- a/content/base/public/nsINode.h
+++ b/content/base/public/nsINode.h
@@ -54,17 +54,16 @@ class nsEventChainPreVisitor;
 class nsEventChainPostVisitor;
 class nsIEventListenerManager;
 class nsIPrincipal;
 class nsVoidArray;
 class nsIMutationObserver;
 class nsChildContentList;
 class nsNodeWeakReference;
 class nsNodeSupportsWeakRefTearoff;
-class nsDOMNodeAllocator;
 
 enum {
   // This bit will be set if the node doesn't have nsSlots
   NODE_DOESNT_HAVE_SLOTS =       0x00000001U,
 
   // This bit will be set if the node has a listener manager in the listener
   // manager hash
   NODE_HAS_LISTENERMANAGER =     0x00000002U,
@@ -118,18 +117,18 @@ inline nsINode* NODE_FROM(C& aContent, D
   if (aContent)
     return static_cast<nsINode*>(aContent);
   return static_cast<nsINode*>(aDocument);
 }
 
 
 // IID for the nsINode interface
 #define NS_INODE_IID \
-{ 0xcf677826, 0xd7f1, 0x4ec5, \
-  { 0xbf, 0x3a, 0xd4, 0x18, 0x11, 0xac, 0x58, 0x46 } }
+{ 0xd1c2e967, 0x854a, 0x436b, \
+  { 0xbf, 0xa5, 0xf6, 0xa4, 0x9a, 0x97, 0x46, 0x74 } }
 
 /**
  * An internal interface that abstracts some DOMNode-related parts that both
  * nsIContent and nsIDocument share.  An instance of this interface has a list
  * of nsIContent children and provides access to them.
  */
 class nsINode : public nsPIDOMEventTarget {
 public:
@@ -568,21 +567,16 @@ public:
      * MSVC 7 doesn't like this as an nsRefPtr
      */
     nsChildContentList* mChildNodes;
 
     /**
      * Weak reference to this node
      */
     nsNodeWeakReference* mWeakReference;
-
-    void* operator new(size_t aSize, nsDOMNodeAllocator* aAllocator);
-    void operator delete(void* aPtr, size_t aSize);
-private:
-    void* operator new(size_t aSize) CPP_THROW_NEW;
   };
 
   /**
    * Functions for managing flags and slots
    */
 #ifdef DEBUG
   nsSlots* DebugGetSlots()
   {
@@ -631,23 +625,16 @@ private:
   {
 #ifdef _IMPL_NS_LAYOUT
     return IsEditableInternal();
 #else
     return IsEditableExternal();
 #endif
   }
 
-  // Returns nsnull only when called on an nsIDocument object.
-  virtual nsDOMNodeAllocator* GetAllocator() = 0;
-
-  void* operator new(size_t aSize, nsINodeInfo* aNodeInfo);
-  void operator delete(void* aPtr, size_t aSize);
-private:
-  void* operator new(size_t aSize) CPP_THROW_NEW;
 protected:
 
   // Override this function to create a custom slots class.
   virtual nsINode::nsSlots* CreateSlots();
 
   PRBool HasSlots() const
   {
     return !(mFlagsOrSlots & NODE_DOESNT_HAVE_SLOTS);
--- a/content/base/src/contentbase.gqi
+++ b/content/base/src/contentbase.gqi
@@ -13,17 +13,17 @@
 %import-idl "nsIDOMNSDocumentStyle.idl"
 %import-idl "nsIDOMDocumentView.idl"
 %import-idl "nsIDOMDocumentRange.idl"
 %import-idl "nsIDOMDocumentTraversal.idl"
 %import-idl "nsIDOMDocumentXBL.idl"
 %import-idl "nsIDOMXPathEvaluator.idl"
 
 %pseudo-iid nsIContent fba9aa39-016e-4d5d-ab62-22a1b84a3c7b
-%pseudo-iid nsINode cf677826-d7f1-4ec5-bf3a-d41811ac5846
+%pseudo-iid nsINode d1c2e967-854a-436b-bfa5-f6a49a974674
 %pseudo-iid nsPIDOMEventTarget 44a6597b-9fc3-4a8d-b7a4-d9009abf9d15
 %pseudo-iid nsIDocument 626d86d2-615f-4a12-94d8-e3db3a298372
 %pseudo-iid nsIScriptObjectPrincipal 3eedba38-8d22-41e1-817a-0e43e165b664
 %pseudo-iid nsIMutationObserver 32e68316-67d4-44a5-8d35-0d390fa9df11
 %pseudo-iid nsIXPathEvaluatorInternal  b4b72daa-65d6-440f-b608-e2ee9a82f313
 %pseudo-iid nsIRadioGroupContainer 06de7839-d0db-47d3-8290-3cb8622ed966
 
 %{C++
--- a/content/base/src/nsAttrAndChildArray.cpp
+++ b/content/base/src/nsAttrAndChildArray.cpp
@@ -114,38 +114,30 @@ GetIndexFromCache(const nsAttrAndChildAr
  */
 #define ATTRS(_impl) \
   reinterpret_cast<InternalAttr*>(&((_impl)->mBuffer[0]))
   
 
 #define NS_IMPL_EXTRA_SIZE \
   ((sizeof(Impl) - sizeof(mImpl->mBuffer)) / sizeof(void*))
 
-nsAttrAndChildArray::nsAttrAndChildArray(nsDOMNodeAllocator* aAllocator)
-  : mImpl(nsnull), mAllocator(aAllocator)
+nsAttrAndChildArray::nsAttrAndChildArray()
+  : mImpl(nsnull)
 {
-  NS_IF_ADDREF(mAllocator);
 }
 
 nsAttrAndChildArray::~nsAttrAndChildArray()
 {
-  if (mImpl) {
-    Clear();
-    mAllocator->Free((mImpl->mBufferSize + NS_IMPL_EXTRA_SIZE) * sizeof(void*),
-                     mImpl);
+  if (!mImpl) {
+    return;
   }
 
-  NS_IF_RELEASE(mAllocator);
-}
+  Clear();
 
-void
-nsAttrAndChildArray::SetAllocator(nsDOMNodeAllocator* aAllocator)
-{
-  NS_ASSERTION(!mAllocator, "Allocator already set!");
-  NS_ADDREF(mAllocator = aAllocator);
+  PR_Free(mImpl);
 }
 
 nsIContent*
 nsAttrAndChildArray::GetSafeChildAt(PRUint32 aPos) const
 {
   if (aPos < ChildCount()) {
     return ChildAt(aPos);
   }
@@ -597,16 +589,49 @@ void
 nsAttrAndChildArray::WalkMappedAttributeStyleRules(nsRuleWalker* aRuleWalker)
 {
   if (mImpl && mImpl->mMappedAttrs && aRuleWalker) {
     aRuleWalker->Forward(mImpl->mMappedAttrs);
   }
 }
 
 void
+nsAttrAndChildArray::Compact()
+{
+  if (!mImpl) {
+    return;
+  }
+
+  // First compress away empty attrslots
+  PRUint32 slotCount = AttrSlotCount();
+  PRUint32 attrCount = NonMappedAttrCount();
+  PRUint32 childCount = ChildCount();
+
+  if (attrCount < slotCount) {
+    memmove(mImpl->mBuffer + attrCount * ATTRSIZE,
+            mImpl->mBuffer + slotCount * ATTRSIZE,
+            childCount * sizeof(nsIContent*));
+    SetAttrSlotCount(attrCount);
+  }
+
+  // Then resize or free buffer
+  PRUint32 newSize = attrCount * ATTRSIZE + childCount;
+  if (!newSize && !mImpl->mMappedAttrs) {
+    PR_Free(mImpl);
+    mImpl = nsnull;
+  }
+  else if (newSize < mImpl->mBufferSize) {
+    mImpl = static_cast<Impl*>(PR_Realloc(mImpl, (newSize + NS_IMPL_EXTRA_SIZE) * sizeof(nsIContent*)));
+    NS_ASSERTION(mImpl, "failed to reallocate to smaller buffer");
+
+    mImpl->mBufferSize = newSize;
+  }
+}
+
+void
 nsAttrAndChildArray::Clear()
 {
   if (!mImpl) {
     return;
   }
 
   if (mImpl->mMappedAttrs) {
     NS_RELEASE(mImpl->mMappedAttrs);
@@ -725,27 +750,26 @@ nsAttrAndChildArray::GrowBy(PRUint32 aGr
     do {
       size += ATTRCHILD_ARRAY_GROWSIZE;
     } while (size < minSize);
   }
   else {
     size = PR_BIT(PR_CeilingLog2(minSize));
   }
 
-  Impl* newImpl = static_cast<Impl*>(mAllocator->Alloc(size * sizeof(void*)));
+  Impl* newImpl = static_cast<Impl*>
+                             (mImpl ? PR_Realloc(mImpl, size * sizeof(void*)) :
+              PR_Malloc(size * sizeof(void*)));
   NS_ENSURE_TRUE(newImpl, PR_FALSE);
+
   Impl* oldImpl = mImpl;
   mImpl = newImpl;
-  if (oldImpl) {
-    PRUint32 oldSize =
-      (oldImpl->mBufferSize + NS_IMPL_EXTRA_SIZE) * sizeof(void*);
-    memcpy(newImpl, oldImpl, oldSize);
-    mAllocator->Free(oldSize, oldImpl);
-  } else {
-    // Set initial counts if we didn't have a buffer before
+
+  // Set initial counts if we didn't have a buffer before
+  if (!oldImpl) {
     mImpl->mMappedAttrs = nsnull;
     SetAttrSlotAndChildCount(0, 0);
   }
 
   mImpl->mBufferSize = size - NS_IMPL_EXTRA_SIZE;
 
   return PR_TRUE;
 }
--- a/content/base/src/nsAttrAndChildArray.h
+++ b/content/base/src/nsAttrAndChildArray.h
@@ -70,20 +70,18 @@ class nsMappedAttributeElement;
     ((1 << ATTRCHILD_ARRAY_ATTR_SLOTS_BITS) - 1)
 
 
 #define ATTRSIZE (sizeof(InternalAttr) / sizeof(void*))
 
 class nsAttrAndChildArray
 {
 public:
-  nsAttrAndChildArray(nsDOMNodeAllocator* aAllocator);
+  nsAttrAndChildArray();
   ~nsAttrAndChildArray();
-  void SetAllocator(nsDOMNodeAllocator* aAllocator);
-  nsDOMNodeAllocator* Allocator() { return mAllocator; }
 
   PRUint32 ChildCount() const
   {
     return mImpl ? (mImpl->mAttrAndChildCount >> ATTRCHILD_ARRAY_ATTR_SLOTS_BITS) : 0;
   }
   nsIContent* ChildAt(PRUint32 aPos) const
   {
     NS_ASSERTION(aPos < ChildCount(), "out-of-bounds access in nsAttrAndChildArray");
@@ -120,16 +118,18 @@ public:
   PRInt32 IndexOfAttr(nsIAtom* aLocalName, PRInt32 aNamespaceID = kNameSpaceID_None) const;
 
   nsresult SetAndTakeMappedAttr(nsIAtom* aLocalName, nsAttrValue& aValue,
                                 nsMappedAttributeElement* aContent,
                                 nsHTMLStyleSheet* aSheet);
   nsresult SetMappedAttrStyleSheet(nsHTMLStyleSheet* aSheet);
   void WalkMappedAttributeStyleRules(nsRuleWalker* aRuleWalker);
 
+  void Compact();
+
 private:
   nsAttrAndChildArray(const nsAttrAndChildArray& aOther); // Not to be implemented
   nsAttrAndChildArray& operator=(const nsAttrAndChildArray& aOther); // Not to be implemented
 
   void Clear();
 
   PRUint32 NonMappedAttrCount() const;
   PRUint32 MappedAttrCount() const;
@@ -181,13 +181,12 @@ private:
 
   struct Impl {
     PRUint32 mAttrAndChildCount;
     PRUint32 mBufferSize;
     nsMappedAttributes* mMappedAttrs;
     void* mBuffer[1];
   };
 
-  Impl*               mImpl;
-  nsDOMNodeAllocator* mAllocator;
+  Impl* mImpl;
 };
 
 #endif
--- a/content/base/src/nsCommentNode.cpp
+++ b/content/base/src/nsCommentNode.cpp
@@ -83,17 +83,17 @@ NS_NewCommentNode(nsIContent** aInstance
 {
   NS_PRECONDITION(aNodeInfoManager, "Missing nodeinfo manager");
 
   *aInstancePtrResult = nsnull;
 
   nsCOMPtr<nsINodeInfo> ni = aNodeInfoManager->GetCommentNodeInfo();
   NS_ENSURE_TRUE(ni, NS_ERROR_OUT_OF_MEMORY);
 
-  nsCommentNode *instance = new (ni) nsCommentNode(ni);
+  nsCommentNode *instance = new nsCommentNode(ni);
   if (!instance) {
     return NS_ERROR_OUT_OF_MEMORY;
   }
 
   NS_ADDREF(*aInstancePtrResult = instance);
 
   return NS_OK;
 }
@@ -158,17 +158,17 @@ nsCommentNode::GetNodeType(PRUint16* aNo
 {
   *aNodeType = (PRUint16)nsIDOMNode::COMMENT_NODE;
   return NS_OK;
 }
 
 nsGenericDOMDataNode*
 nsCommentNode::CloneDataNode(nsINodeInfo *aNodeInfo, PRBool aCloneText) const
 {
-  nsCommentNode *it = new (aNodeInfo) nsCommentNode(aNodeInfo);
+  nsCommentNode *it = new nsCommentNode(aNodeInfo);
   if (it && aCloneText) {
     it->mText = mText;
   }
 
   return it;
 }
 
 #ifdef DEBUG
--- a/content/base/src/nsDOMAttribute.cpp
+++ b/content/base/src/nsDOMAttribute.cpp
@@ -59,19 +59,17 @@
 #include "nsIEventListenerManager.h"
 
 //----------------------------------------------------------------------
 PRBool nsDOMAttribute::sInitialized;
 
 nsDOMAttribute::nsDOMAttribute(nsDOMAttributeMap *aAttrMap,
                                nsINodeInfo       *aNodeInfo,
                                const nsAString   &aValue)
-  : nsIAttribute(aAttrMap, aNodeInfo),
-    mAllocator(aNodeInfo->NodeInfoManager()->NodeAllocator()),
-    mValue(aValue)
+  : nsIAttribute(aAttrMap, aNodeInfo), mValue(aValue)
 {
   NS_ABORT_IF_FALSE(mNodeInfo, "We must get a nodeinfo here!");
 
 
   // We don't add a reference to our content. It will tell us
   // to drop our reference when it goes away.
 }
 
@@ -369,17 +367,17 @@ nsDOMAttribute::AppendChild(nsIDOMNode* 
 }
 
 nsresult
 nsDOMAttribute::Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const
 {
   nsAutoString value;
   const_cast<nsDOMAttribute*>(this)->GetValue(value);
 
-  *aResult = new (aNodeInfo) nsDOMAttribute(nsnull, aNodeInfo, value);
+  *aResult = new nsDOMAttribute(nsnull, aNodeInfo, value);
   if (!*aResult) {
     return NS_ERROR_OUT_OF_MEMORY;
   }
 
   NS_ADDREF(*aResult);
 
   return NS_OK;
 }
--- a/content/base/src/nsDOMAttribute.h
+++ b/content/base/src/nsDOMAttribute.h
@@ -103,30 +103,28 @@ public:
   virtual nsresult GetListenerManager(PRBool aCreateIfNotFound,
                                       nsIEventListenerManager** aResult);
   virtual nsresult AddEventListenerByIID(nsIDOMEventListener *aListener,
                                          const nsIID& aIID);
   virtual nsresult RemoveEventListenerByIID(nsIDOMEventListener *aListener,
                                             const nsIID& aIID);
   virtual nsresult GetSystemEventGroup(nsIDOMEventGroup** aGroup);
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
-  virtual nsDOMNodeAllocator* GetAllocator() { return mAllocator; }
 
   static void Initialize();
   static void Shutdown();
 
   NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsDOMAttribute, nsIAttribute)
 
 protected:
   static PRBool sInitialized;
 
 private:
   nsresult EnsureChildState(PRBool aSetText, PRBool &aHasChild) const;
 
-  nsDOMNodeAllocator* mAllocator;
   nsString mValue;
   // XXX For now, there's only a single child - a text
   // element representing the value
   nsCOMPtr<nsIContent> mChild;
 
   nsIContent *GetContentInternal() const
   {
     return mAttrMap ? mAttrMap->GetContent() : nsnull;
--- a/content/base/src/nsDOMAttributeMap.cpp
+++ b/content/base/src/nsDOMAttributeMap.cpp
@@ -174,18 +174,18 @@ nsDOMAttributeMap::GetAttribute(nsINodeI
 
   if (!mAttributeCache.Get(attr, aReturn)) {
     nsAutoString value;
     if (aRemove) {
       // As we are removing the attribute we need to set the current value in
       // the attribute node.
       mContent->GetAttr(aNodeInfo->NamespaceID(), aNodeInfo->NameAtom(), value);
     }
-    nsCOMPtr<nsIDOMNode> newAttr =
-      new (aNodeInfo) nsDOMAttribute(aRemove ? nsnull : this, aNodeInfo, value);
+    nsCOMPtr<nsIDOMNode> newAttr = new nsDOMAttribute(aRemove ? nsnull : this,
+                                                      aNodeInfo, value);
     if (!newAttr) {
       return NS_ERROR_OUT_OF_MEMORY;
     }
     if (!aRemove && !mAttributeCache.Put(attr, newAttr)) {
       return NS_ERROR_OUT_OF_MEMORY;
     }
     newAttr.swap(*aReturn);
   }
--- a/content/base/src/nsDOMDocumentType.cpp
+++ b/content/base/src/nsDOMDocumentType.cpp
@@ -84,18 +84,18 @@ NS_NewDOMDocumentType(nsIDOMDocumentType
     nimgr->SetDocumentPrincipal(aPrincipal);
   }
 
   nsCOMPtr<nsINodeInfo> ni;
   rv = nimgr->GetNodeInfo(nsGkAtoms::documentTypeNodeName, nsnull,
                           kNameSpaceID_None, getter_AddRefs(ni));
   NS_ENSURE_SUCCESS(rv, rv);
 
-  *aDocType = new (ni) nsDOMDocumentType(ni, aName, aEntities, aNotations,
-                                         aPublicId, aSystemId, aInternalSubset);
+  *aDocType = new nsDOMDocumentType(ni, aName, aEntities, aNotations,
+                                    aPublicId, aSystemId, aInternalSubset);
   if (!*aDocType) {
     return NS_ERROR_OUT_OF_MEMORY;
   }
 
   NS_ADDREF(*aDocType);
 
   return NS_OK;
 }
@@ -230,19 +230,18 @@ nsDOMDocumentType::GetNodeType(PRUint16*
   *aNodeType = nsIDOMNode::DOCUMENT_TYPE_NODE;
 
   return NS_OK;
 }
 
 nsGenericDOMDataNode*
 nsDOMDocumentType::CloneDataNode(nsINodeInfo *aNodeInfo, PRBool aCloneText) const
 {
-  return new (aNodeInfo) nsDOMDocumentType(aNodeInfo, mName, mEntities,
-                                           mNotations, mPublicId, mSystemId,
-                                           mInternalSubset);
+  return new nsDOMDocumentType(aNodeInfo, mName, mEntities, mNotations,
+                               mPublicId, mSystemId, mInternalSubset);
 }
 
 nsresult
 nsDOMDocumentType::BindToTree(nsIDocument *aDocument, nsIContent *aParent,
                               nsIContent *aBindingParent,
                               PRBool aCompileEventHandlers)
 {
   if (!HasSameOwnerDoc(NODE_FROM(aParent, aDocument))) {
--- a/content/base/src/nsDocument.cpp
+++ b/content/base/src/nsDocument.cpp
@@ -763,17 +763,16 @@ nsDOMImplementation::Init(nsIURI* aDocum
 // =
 // ==================================================================
 
   // NOTE! nsDocument::operator new() zeroes out all members, so don't
   // bother initializing members to 0.
 
 nsDocument::nsDocument(const char* aContentType)
   : nsIDocument(),
-    mChildren(nsnull),
     mVisible(PR_TRUE)
 {
   mContentType = aContentType;
   
 #ifdef PR_LOGGING
   if (!gDocumentLeakPRLog)
     gDocumentLeakPRLog = PR_NewLogModule("DocumentLeak");
 
@@ -1050,29 +1049,16 @@ nsDocument::Init()
   mLinkMap.Init();
   mRadioGroups.Init();
 
   // Force initialization.
   nsBindingManager *bindingManager = new nsBindingManager(this);
   NS_ENSURE_TRUE(bindingManager, NS_ERROR_OUT_OF_MEMORY);
   NS_ADDREF(mBindingManager = bindingManager);
 
-  mNodeInfoManager = new nsNodeInfoManager();
-  NS_ENSURE_TRUE(mNodeInfoManager, NS_ERROR_OUT_OF_MEMORY);
-
-  NS_ADDREF(mNodeInfoManager);
-
-  nsresult  rv = mNodeInfoManager->Init(this);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  mChildren.SetAllocator(mNodeInfoManager->NodeAllocator());
-
-  mNodeInfo = mNodeInfoManager->GetDocumentNodeInfo();
-  NS_ENSURE_TRUE(mNodeInfo, NS_ERROR_OUT_OF_MEMORY);
-
   nsINode::nsSlots* slots = GetSlots();
   NS_ENSURE_TRUE(slots,NS_ERROR_OUT_OF_MEMORY);
 
   // Prepend self as mutation-observer whether we need it or not (some
   // subclasses currently do, other don't). This is because the code in
   // nsNodeUtils always notifies the first observer first, expecting the
   // first observer to be the document.
   NS_ENSURE_TRUE(slots->mMutationObservers.PrependElementUnlessExists(static_cast<nsIMutationObserver*>(this)),
@@ -1083,31 +1069,35 @@ nsDocument::Init()
   NS_ENSURE_TRUE(mOnloadBlocker, NS_ERROR_OUT_OF_MEMORY);
   
   NS_NewCSSLoader(this, &mCSSLoader);
   NS_ENSURE_TRUE(mCSSLoader, NS_ERROR_OUT_OF_MEMORY);
   // Assume we're not HTML and not quirky, until we know otherwise
   mCSSLoader->SetCaseSensitive(PR_TRUE);
   mCSSLoader->SetCompatibilityMode(eCompatibility_FullStandards);
 
+  mNodeInfoManager = new nsNodeInfoManager();
+  NS_ENSURE_TRUE(mNodeInfoManager, NS_ERROR_OUT_OF_MEMORY);
+
+  NS_ADDREF(mNodeInfoManager);
+
+  nsresult  rv = mNodeInfoManager->Init(this);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  mNodeInfo = mNodeInfoManager->GetDocumentNodeInfo();
+  NS_ENSURE_TRUE(mNodeInfo, NS_ERROR_OUT_OF_MEMORY);
+
   NS_ASSERTION(GetOwnerDoc() == this, "Our nodeinfo is busted!");
 
   mScriptLoader = new nsScriptLoader(this);
   NS_ENSURE_TRUE(mScriptLoader, NS_ERROR_OUT_OF_MEMORY);
 
   return NS_OK;
 }
 
-nsINode::nsSlots*
-nsDocument::CreateSlots()
-{
-  return
-    new (mNodeInfo->NodeInfoManager()->NodeAllocator()) nsSlots(mFlagsOrSlots);
-}
-
 nsresult
 nsDocument::AddXMLEventsContent(nsIContent *aXMLEventsElement)
 {
   if (!mXMLEventsManager) {
     mXMLEventsManager = new nsXMLEventsManager();
     NS_ENSURE_TRUE(mXMLEventsManager, NS_ERROR_OUT_OF_MEMORY);
     AddObserver(mXMLEventsManager);
   }
@@ -3089,17 +3079,17 @@ nsDocument::CreateAttribute(const nsAStr
   nsAutoString value;
   nsDOMAttribute* attribute;
 
   nsCOMPtr<nsINodeInfo> nodeInfo;
   rv = mNodeInfoManager->GetNodeInfo(aName, nsnull, kNameSpaceID_None,
                                      getter_AddRefs(nodeInfo));
   NS_ENSURE_SUCCESS(rv, rv);
 
-  attribute = new (nodeInfo) nsDOMAttribute(nsnull, nodeInfo, value);
+  attribute = new nsDOMAttribute(nsnull, nodeInfo, value);
   NS_ENSURE_TRUE(attribute, NS_ERROR_OUT_OF_MEMORY);
 
   return CallQueryInterface(attribute, aReturn);
 }
 
 NS_IMETHODIMP
 nsDocument::CreateAttributeNS(const nsAString & aNamespaceURI,
                               const nsAString & aQualifiedName,
@@ -3111,18 +3101,17 @@ nsDocument::CreateAttributeNS(const nsAS
   nsCOMPtr<nsINodeInfo> nodeInfo;
   nsresult rv = nsContentUtils::GetNodeInfoFromQName(aNamespaceURI,
                                                      aQualifiedName,
                                                      mNodeInfoManager,
                                                      getter_AddRefs(nodeInfo));
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsAutoString value;
-  nsDOMAttribute* attribute =
-    new (nodeInfo) nsDOMAttribute(nsnull, nodeInfo, value);
+  nsDOMAttribute* attribute = new nsDOMAttribute(nsnull, nodeInfo, value);
   NS_ENSURE_TRUE(attribute, NS_ERROR_OUT_OF_MEMORY);
 
   return CallQueryInterface(attribute, aResult);
 }
 
 NS_IMETHODIMP
 nsDocument::CreateEntityReference(const nsAString& aName,
                                   nsIDOMEntityReference** aReturn)
--- a/content/base/src/nsDocument.h
+++ b/content/base/src/nsDocument.h
@@ -531,17 +531,16 @@ public:
                                          const nsIID& aIID);
   virtual nsresult RemoveEventListenerByIID(nsIDOMEventListener *aListener,
                                             const nsIID& aIID);
   virtual nsresult GetSystemEventGroup(nsIDOMEventGroup** aGroup);
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const
   {
     return NS_ERROR_NOT_IMPLEMENTED;
   }
-  virtual nsDOMNodeAllocator* GetAllocator() { return nsnull; }
 
   // nsIRadioGroupContainer
   NS_IMETHOD WalkRadioGroup(const nsAString& aName,
                             nsIRadioVisitor* aVisitor,
                             PRBool aFlushContent);
   NS_IMETHOD SetCurrentRadioButton(const nsAString& aName,
                                    nsIDOMHTMLInputElement* aRadio);
   NS_IMETHOD GetCurrentRadioButton(const nsAString& aName,
@@ -654,17 +653,16 @@ public:
   /**
    * Utility method for getElementsByClassName.  aRootNode is the node (either
    * document or element), which getElementsByClassName was called on.
    */
   static nsresult GetElementsByClassNameHelper(nsINode* aRootNode,
                                                const nsAString& aClasses,
                                                nsIDOMNodeList** aReturn);
 protected:
-  virtual nsINode::nsSlots* CreateSlots();
 
   /**
    * Check that aId is not empty and log a message to the console
    * service if it is.
    * @returns PR_TRUE if aId looks correct, PR_FALSE otherwise.
    */
   static PRBool CheckGetElementByIdArg(const nsAString& aId);
 
--- a/content/base/src/nsDocumentFragment.cpp
+++ b/content/base/src/nsDocumentFragment.cpp
@@ -166,17 +166,17 @@ NS_NewDocumentFragment(nsIDOMDocumentFra
 
   nsCOMPtr<nsINodeInfo> nodeInfo;
   nsresult rv =
     aNodeInfoManager->GetNodeInfo(nsGkAtoms::documentFragmentNodeName,
                                   nsnull, kNameSpaceID_None,
                                   getter_AddRefs(nodeInfo));
   NS_ENSURE_SUCCESS(rv, rv);
 
-  nsDocumentFragment *it = new (nodeInfo) nsDocumentFragment(nodeInfo);
+  nsDocumentFragment *it = new nsDocumentFragment(nodeInfo);
   if (!it) {
     return NS_ERROR_OUT_OF_MEMORY;
   }
 
   NS_ADDREF(*aInstancePtrResult = it);
 
   return NS_OK;
 }
--- a/content/base/src/nsGenConImageContent.cpp
+++ b/content/base/src/nsGenConImageContent.cpp
@@ -76,17 +76,17 @@ public:
 NS_IMPL_ISUPPORTS_INHERITED2(nsGenConImageContent, nsXMLElement,
                              nsIImageLoadingContent, imgIDecoderObserver)
 
 nsresult
 NS_NewGenConImageContent(nsIContent** aResult, nsINodeInfo* aNodeInfo,
                          imgIRequest* aImageRequest)
 {
   NS_PRECONDITION(aImageRequest, "Must have request!");
-  nsGenConImageContent *it = new (aNodeInfo) nsGenConImageContent(aNodeInfo);
+  nsGenConImageContent *it = new nsGenConImageContent(aNodeInfo);
   if (!it)
     return NS_ERROR_OUT_OF_MEMORY;
   NS_ADDREF(*aResult = it);
   nsresult rv = it->Init(aImageRequest);
   if (NS_FAILED(rv))
     NS_RELEASE(*aResult);
   return rv;
 }
--- a/content/base/src/nsGenericDOMDataNode.cpp
+++ b/content/base/src/nsGenericDOMDataNode.cpp
@@ -61,17 +61,17 @@
 #include "nsCOMArray.h"
 #include "nsNodeUtils.h"
 #include "nsBindingManager.h"
 
 #include "pldhash.h"
 #include "prprf.h"
 
 nsGenericDOMDataNode::nsGenericDOMDataNode(nsINodeInfo *aNodeInfo)
-  : nsIContent(aNodeInfo), mText(aNodeInfo->NodeInfoManager()->NodeAllocator())
+  : nsIContent(aNodeInfo)
 {
 }
 
 nsGenericDOMDataNode::~nsGenericDOMDataNode()
 {
   NS_PRECONDITION(!IsInDoc(),
                   "Please remove this from the document properly");
 }
@@ -859,17 +859,17 @@ nsGenericDOMDataNode::IsLink(nsIURI** aU
 {
   *aURI = nsnull;
   return PR_FALSE;
 }
 
 nsINode::nsSlots*
 nsGenericDOMDataNode::CreateSlots()
 {
-  return new (GetAllocator()) nsDataSlots(mFlagsOrSlots);
+  return new nsDataSlots(mFlagsOrSlots);
 }
 
 //----------------------------------------------------------------------
 
 // Implementation of the nsIDOMText interface
 
 nsresult
 nsGenericDOMDataNode::SplitText(PRUint32 aOffset, nsIDOMText** aReturn)
--- a/content/base/src/nsGenericDOMDataNode.h
+++ b/content/base/src/nsGenericDOMDataNode.h
@@ -182,17 +182,16 @@ public:
                                     nsEventStatus* aEventStatus);
   virtual nsresult GetListenerManager(PRBool aCreateIfNotFound,
                                       nsIEventListenerManager** aResult);
   virtual nsresult AddEventListenerByIID(nsIDOMEventListener *aListener,
                                          const nsIID& aIID);
   virtual nsresult RemoveEventListenerByIID(nsIDOMEventListener *aListener,
                                             const nsIID& aIID);
   virtual nsresult GetSystemEventGroup(nsIDOMEventGroup** aGroup);
-  virtual nsDOMNodeAllocator* GetAllocator() { return mText.Allocator(); }
 
   // Implementation for nsIContent
   virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
                               nsIContent* aBindingParent,
                               PRBool aCompileEventHandlers);
   virtual void UnbindFromTree(PRBool aDeep = PR_TRUE,
                               PRBool aNullParent = PR_TRUE);
 
--- a/content/base/src/nsGenericElement.cpp
+++ b/content/base/src/nsGenericElement.cpp
@@ -166,54 +166,18 @@ nsINode::nsSlots::~nsSlots()
     NS_RELEASE(mChildNodes);
   }
 
   if (mWeakReference) {
     mWeakReference->NoticeNodeDestruction();
   }
 }
 
-void*
-nsINode::nsSlots::operator new(size_t aSize, nsDOMNodeAllocator* aAllocator)
-{
-  void* result = aAllocator->Alloc(aSize);
-  if (result) {
-    NS_ADDREF(aAllocator);
-  }
-  return result;
-}
-
-void
-nsINode::nsSlots::operator delete(void* aPtr, size_t aSize)
-{
-  size_t* szPtr = static_cast<size_t*>(aPtr);
-  *szPtr = aSize;
-}
-
 //----------------------------------------------------------------------
 
-void*
-nsINode::operator new(size_t aSize, nsINodeInfo* aNodeInfo)
-{
-  nsDOMNodeAllocator* allocator =
-    aNodeInfo->NodeInfoManager()->NodeAllocator();
-  void* result = allocator->Alloc(aSize);
-  if (result) {
-    NS_ADDREF(allocator);
-  }
-  return result;
-}
-
-void
-nsINode::operator delete(void* aPtr, size_t aSize)
-{
-  size_t* szPtr = static_cast<size_t*>(aPtr);
-  *szPtr = aSize;
-}
-
 nsINode::~nsINode()
 {
   NS_ASSERTION(!HasSlots(), "nsNodeUtils::LastRelease was not called?");
 }
 
 void*
 nsINode::GetProperty(PRUint16 aCategory, nsIAtom *aPropertyName,
                      nsresult *aStatus) const
@@ -307,17 +271,17 @@ nsGenericElement::GetSystemEventGroup(ns
     return elm->GetSystemEventGroupLM(aGroup);
   }
   return rv;
 }
 
 nsINode::nsSlots*
 nsINode::CreateSlots()
 {
-  return new (GetAllocator()) nsSlots(mFlagsOrSlots);
+  return new nsSlots(mFlagsOrSlots);
 }
 
 void
 nsINode::AddMutationObserver(nsIMutationObserver* aMutationObserver)
 {
   nsSlots* slots = GetSlots();
   if (slots) {
     slots->mMutationObservers.AppendElementUnlessExists(aMutationObserver);
@@ -1153,18 +1117,17 @@ nsGenericElement::nsDOMSlots::~nsDOMSlot
   }
 
   if (mAttributeMap) {
     mAttributeMap->DropReference();
   }
 }
 
 nsGenericElement::nsGenericElement(nsINodeInfo *aNodeInfo)
-  : nsIContent(aNodeInfo),
-    mAttrsAndChildren(aNodeInfo->NodeInfoManager()->NodeAllocator())
+  : nsIContent(aNodeInfo)
 {
   // Set the default scriptID to JS - but skip SetScriptTypeID as it
   // does extra work we know isn't necessary here...
   SetFlags(nsIProgrammingLanguage::JAVASCRIPT << NODE_SCRIPT_TYPE_OFFSET);
 }
 
 nsGenericElement::~nsGenericElement()
 {
@@ -4213,17 +4176,17 @@ PRInt32
 nsGenericElement::IndexOf(nsINode* aPossibleChild) const
 {
   return mAttrsAndChildren.IndexOfChild(aPossibleChild);
 }
 
 nsINode::nsSlots*
 nsGenericElement::CreateSlots()
 {
-  return new (GetAllocator()) nsDOMSlots(mFlagsOrSlots);
+  return new nsDOMSlots(mFlagsOrSlots);
 }
 
 PRBool
 nsGenericElement::CheckHandleEventForLinksPrecondition(nsEventChainVisitor& aVisitor,
                                                        nsIURI** aURI) const
 {
   if (aVisitor.mEventStatus == nsEventStatus_eConsumeNoDefault ||
       !NS_IS_TRUSTED_EVENT(aVisitor.mEvent) ||
--- a/content/base/src/nsGenericElement.h
+++ b/content/base/src/nsGenericElement.h
@@ -371,20 +371,16 @@ public:
                                     nsEventStatus* aEventStatus);
   virtual nsresult GetListenerManager(PRBool aCreateIfNotFound,
                                       nsIEventListenerManager** aResult);
   virtual nsresult AddEventListenerByIID(nsIDOMEventListener *aListener,
                                          const nsIID& aIID);
   virtual nsresult RemoveEventListenerByIID(nsIDOMEventListener *aListener,
                                             const nsIID& aIID);
   virtual nsresult GetSystemEventGroup(nsIDOMEventGroup** aGroup);
-  virtual nsDOMNodeAllocator* GetAllocator()
-  {
-    return mAttrsAndChildren.Allocator();
-  }
 
   // nsIContent interface methods
   virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
                               nsIContent* aBindingParent,
                               PRBool aCompileEventHandlers);
   virtual void UnbindFromTree(PRBool aDeep = PR_TRUE,
                               PRBool aNullParent = PR_TRUE);
   virtual nsIAtom *GetIDAttributeName() const;
@@ -1009,17 +1005,17 @@ protected:
  * Clone.
  */
 #define NS_IMPL_ELEMENT_CLONE(_elementName)                                 \
 nsresult                                                                    \
 _elementName::Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const        \
 {                                                                           \
   *aResult = nsnull;                                                        \
                                                                             \
-  _elementName *it = new (aNodeInfo) _elementName(aNodeInfo);               \
+  _elementName *it = new _elementName(aNodeInfo);                           \
   if (!it) {                                                                \
     return NS_ERROR_OUT_OF_MEMORY;                                          \
   }                                                                         \
                                                                             \
   nsCOMPtr<nsINode> kungFuDeathGrip = it;                                   \
   nsresult rv = CopyInnerTo(it);                                            \
   if (NS_SUCCEEDED(rv)) {                                                   \
     kungFuDeathGrip.swap(*aResult);                                         \
@@ -1029,17 +1025,17 @@ nsresult                                
 }
 
 #define NS_IMPL_ELEMENT_CLONE_WITH_INIT(_elementName)                       \
 nsresult                                                                    \
 _elementName::Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const        \
 {                                                                           \
   *aResult = nsnull;                                                        \
                                                                             \
-  _elementName *it = new (aNodeInfo) _elementName(aNodeInfo);               \
+  _elementName *it = new _elementName(aNodeInfo);                           \
   if (!it) {                                                                \
     return NS_ERROR_OUT_OF_MEMORY;                                          \
   }                                                                         \
                                                                             \
   nsCOMPtr<nsINode> kungFuDeathGrip = it;                                   \
   nsresult rv = it->Init();                                                 \
   rv |= CopyInnerTo(it);                                                    \
   if (NS_SUCCEEDED(rv)) {                                                   \
--- a/content/base/src/nsNodeInfoManager.cpp
+++ b/content/base/src/nsNodeInfoManager.cpp
@@ -46,185 +46,18 @@
 #include "nsIAtom.h"
 #include "nsIDocument.h"
 #include "nsIPrincipal.h"
 #include "nsIURI.h"
 #include "nsContentUtils.h"
 #include "nsReadableUtils.h"
 #include "nsGkAtoms.h"
 #include "nsComponentManagerUtils.h"
-#include "prbit.h"
-#include "plarena.h"
-#include "nsMemory.h"
 #include "nsLayoutStatics.h"
 
-#define NS_SMALL_NODE_ARENA_SIZE \
-  (512 * (sizeof(void*)/4))
-
-#define NS_LARGE_NODE_ARENA_SIZE \
-  (4096 * (sizeof(void*)/4))
-
-#define NS_MAX_NODE_RECYCLE_SIZE \
-  (NS_NODE_RECYCLER_SIZE * sizeof(void*))
-
-#ifdef DEBUG
-static PRUint32 gDOMNodeAllocators = 0;
-// Counts the number of non-freed allocations.
-static size_t   gDOMNodeAllocations = 0;
-static PRUint32 gDOMNodeRecyclerCounters[NS_NODE_RECYCLER_SIZE];
-static PRUint32 gDOMNodeNormalAllocations = 0;
-class nsDOMNodeAllocatorTester
-{
-public:
-  nsDOMNodeAllocatorTester()
-  {
-    memset(gDOMNodeRecyclerCounters, 0, sizeof(gDOMNodeRecyclerCounters));
-  }
-  ~nsDOMNodeAllocatorTester()
-  {
-#ifdef DEBUG_smaug
-    for (PRInt32 i = 0 ; i < NS_NODE_RECYCLER_SIZE; ++i) {
-      if (gDOMNodeRecyclerCounters[i]) {
-        printf("DOMNodeAllocator, arena allocation: %u bytes %u times\n",
-               static_cast<unsigned int>((i + 1) * sizeof(void*)),
-               gDOMNodeRecyclerCounters[i]);
-      }
-    }
-    if (gDOMNodeNormalAllocations) {
-      printf("DOMNodeAllocator, normal allocations: %i times \n",
-             gDOMNodeNormalAllocations);
-    }
-#endif
-    if (gDOMNodeAllocations != 0) {
-      printf("nsDOMNodeAllocator leaked %u bytes \n",
-             static_cast<unsigned int>(gDOMNodeAllocations));
-    }
-  }
-};
-nsDOMNodeAllocatorTester gDOMAllocatorTester;
-#endif
-
-nsDOMNodeAllocator::~nsDOMNodeAllocator()
-{
-  if (mSmallPool) {
-    PL_FinishArenaPool(mSmallPool);
-    delete mSmallPool;
-  }
-  if (mLargePool) {
-    PL_FinishArenaPool(mLargePool);
-    delete mLargePool;
-  }
-#ifdef DEBUG
-  --gDOMNodeAllocators;
-#endif
-}
-
-nsresult
-nsDOMNodeAllocator::Init()
-{
-#ifdef DEBUG
-  ++gDOMNodeAllocators;
-#endif
-  memset(mRecyclers, 0, sizeof(mRecyclers));
-  return NS_OK;
-}
-
-nsrefcnt
-nsDOMNodeAllocator::Release()
-{
-  NS_PRECONDITION(0 != mRefCnt, "dup release");
-  --mRefCnt;
-  NS_LOG_RELEASE(this, mRefCnt, "nsDOMNodeAllocator");
-  if (mRefCnt == 0) {
-    mRefCnt = 1; /* stabilize */
-    delete this;
-    return 0;
-  }
-  return mRefCnt;
-}
-
-void*
-nsDOMNodeAllocator::Alloc(size_t aSize)
-{
-  void* result = nsnull;
-
-  // Ensure we have correct alignment for pointers.
-  aSize = aSize ? PR_ROUNDUP(aSize, sizeof(void*)) : sizeof(void*);
-  // Check recyclers first
-  if (aSize <= NS_MAX_NODE_RECYCLE_SIZE) {
-    const PRInt32 index = (aSize / sizeof(void*)) - 1;
-    result = mRecyclers[index];
-    if (result) {
-      // Need to move to the next object
-      void* next = *((void**)result);
-      mRecyclers[index] = next;
-    }
-    if (!result) {
-      if ((mSmallPoolAllocated + aSize) > NS_LARGE_NODE_ARENA_SIZE) {
-        if (!mLargePool) {
-          mLargePool = new PLArenaPool();
-          NS_ENSURE_TRUE(mLargePool, nsnull);
-          PL_InitArenaPool(mLargePool, "nsDOMNodeAllocator-large",
-                           NS_LARGE_NODE_ARENA_SIZE, 0);
-        }
-        // Allocate a new chunk from the 'large' arena
-        PL_ARENA_ALLOCATE(result, mLargePool, aSize);
-      } else {
-       if (!mSmallPool) {
-          mSmallPool = new PLArenaPool();
-          NS_ENSURE_TRUE(mSmallPool, nsnull);
-          PL_InitArenaPool(mSmallPool, "nsDOMNodeAllocator-small",
-                           NS_SMALL_NODE_ARENA_SIZE, 0);
-        }
-        // Allocate a new chunk from the 'small' arena
-        PL_ARENA_ALLOCATE(result, mSmallPool, aSize);
-        if (result) {
-          mSmallPoolAllocated += aSize;
-        }
-      }
-    }
-#ifdef DEBUG
-    ++gDOMNodeRecyclerCounters[index];
-#endif
-  } else {
-    result = nsMemory::Alloc(aSize);
-#ifdef DEBUG
-    ++gDOMNodeNormalAllocations;
-#endif
-  }
-
-#ifdef DEBUG
-  gDOMNodeAllocations += aSize;
-#endif
-  return result;
-}
-
-void
-nsDOMNodeAllocator::Free(size_t aSize, void* aPtr)
-{
-  if (!aPtr) {
-    return;
-  }
-  // Ensure we have correct alignment for pointers.
-  aSize = aSize ? PR_ROUNDUP(aSize, sizeof(void*)) : sizeof(void*);
-  // See if it's a size that we recycle
-  if (aSize <= NS_MAX_NODE_RECYCLE_SIZE) {
-    const PRInt32 index = (aSize / sizeof(void*)) - 1;
-    void* currentTop = mRecyclers[index];
-    mRecyclers[index] = aPtr;
-    *((void**)aPtr) = currentTop;
-  } else {
-    nsMemory::Free(aPtr);
-  }
-
-#ifdef DEBUG
-  gDOMNodeAllocations -= aSize;
-#endif
-}
-
 PLHashNumber
 nsNodeInfoManager::GetNodeInfoInnerHashValue(const void *key)
 {
   NS_ASSERTION(key, "Null key passed to nsNodeInfo::GetHashValue!");
 
   const nsINodeInfo::nsNodeInfoInner *node =
     reinterpret_cast<const nsINodeInfo::nsNodeInfoInner *>(key);
 
@@ -302,20 +135,16 @@ nsNodeInfoManager::Release()
   return count;
 }
 
 nsresult
 nsNodeInfoManager::Init(nsIDocument *aDocument)
 {
   NS_ENSURE_TRUE(mNodeInfoHash, NS_ERROR_OUT_OF_MEMORY);
 
-  mNodeAllocator = new nsDOMNodeAllocator();
-  NS_ENSURE_TRUE(mNodeAllocator && NS_SUCCEEDED(mNodeAllocator->Init()),
-                 NS_ERROR_OUT_OF_MEMORY);
-
   NS_PRECONDITION(!mPrincipal,
                   "Being inited when we already have a principal?");
   nsresult rv = CallCreateInstance("@mozilla.org/nullprincipal;1",
                                    &mPrincipal);
   NS_ENSURE_TRUE(mPrincipal, rv);
 
   mDefaultPrincipal = mPrincipal;
 
--- a/content/base/src/nsNodeInfoManager.h
+++ b/content/base/src/nsNodeInfoManager.h
@@ -39,66 +39,29 @@
  * A class for handing out nodeinfos and ensuring sharing of them as needed.
  */
 
 #ifndef nsNodeInfoManager_h___
 #define nsNodeInfoManager_h___
 
 #include "nsCOMPtr.h" // for already_AddRefed
 #include "plhash.h"
-#include "nsAutoPtr.h"
 
 class nsIAtom;
 class nsIDocument;
 class nsINodeInfo;
 class nsNodeInfo;
 class nsIPrincipal;
 class nsIURI;
 class nsDocument;
 class nsIDOMDocumentType;
 class nsIDOMDocument;
 class nsAString;
 class nsIDOMNamedNodeMap;
 class nsXULPrototypeDocument;
-class nsNodeInfoManager;
-struct PLArenaPool;
-
-// The size of mRecyclers array. The max size of recycled memory is
-// sizeof(void*) * NS_NODE_RECYCLER_SIZE.
-#define NS_NODE_RECYCLER_SIZE 64
-
-class nsDOMNodeAllocator
-{
-public:
-  nsDOMNodeAllocator()
-  : mSmallPool(nsnull), mLargePool(nsnull), mSmallPoolAllocated(0) {}
-  ~nsDOMNodeAllocator();
-
-  nsrefcnt AddRef()
-  {
-    NS_ASSERTION(PRInt32(mRefCnt) >= 0, "illegal refcnt");
-    ++mRefCnt;
-    NS_LOG_ADDREF(this, mRefCnt, "nsDOMNodeAllocator", sizeof(*this));
-    return mRefCnt;
-  }
-  nsrefcnt Release();
-
-  void* Alloc(size_t aSize);
-  void Free(size_t aSize, void* aPtr);
-protected:
-  friend class nsNodeInfoManager;
-  nsresult Init();
-  nsAutoRefCnt mRefCnt;
-  PLArenaPool* mSmallPool;
-  PLArenaPool* mLargePool;
-  size_t       mSmallPoolAllocated;
-  // The recycler array points to recycled memory, where the size of
-  // block is index*sizeof(void*), i.e., 0, 4, 8, 12, 16, ... or 0, 8, 16, ...
-  void*        mRecyclers[NS_NODE_RECYCLER_SIZE];
-};
 
 class nsNodeInfoManager
 {
 public:
   nsNodeInfoManager();
   ~nsNodeInfoManager();
 
   nsrefcnt AddRef(void);
@@ -155,17 +118,16 @@ public:
    */
   nsIPrincipal *DocumentPrincipal() const {
     NS_ASSERTION(mPrincipal, "How'd that happen?");
     return mPrincipal;
   }
 
   void RemoveNodeInfo(nsNodeInfo *aNodeInfo);
 
-  nsDOMNodeAllocator* NodeAllocator() { return mNodeAllocator; }
 protected:
   friend class nsDocument;
   friend class nsXULPrototypeDocument;
   friend nsresult NS_NewDOMDocumentType(nsIDOMDocumentType** ,
                                         nsNodeInfoManager *,
                                         nsIPrincipal *,
                                         nsIAtom *,
                                         nsIDOMNamedNodeMap *,
@@ -191,13 +153,11 @@ private:
   nsIDocument *mDocument; // WEAK
   nsIPrincipal *mPrincipal; // STRONG, but not nsCOMPtr to avoid include hell
                             // while inlining DocumentPrincipal().  Never null
                             // after Init() succeeds.
   nsCOMPtr<nsIPrincipal> mDefaultPrincipal; // Never null after Init() succeeds
   nsINodeInfo *mTextNodeInfo; // WEAK to avoid circular ownership
   nsINodeInfo *mCommentNodeInfo; // WEAK to avoid circular ownership
   nsINodeInfo *mDocumentNodeInfo; // WEAK to avoid circular ownership
-
-  nsRefPtr<nsDOMNodeAllocator> mNodeAllocator;
 };
 
 #endif /* nsNodeInfoManager_h___ */
--- a/content/base/src/nsNodeUtils.cpp
+++ b/content/base/src/nsNodeUtils.cpp
@@ -183,33 +183,25 @@ nsNodeUtils::ParentChainChanged(nsIConte
         (aContent));
   }
 }
 
 void
 nsNodeUtils::LastRelease(nsINode* aNode)
 {
   nsINode::nsSlots* slots = aNode->GetExistingSlots();
-  nsRefPtr<nsDOMNodeAllocator> allocator = aNode->GetAllocator();
   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; // Calls destructor and sets size to *slots.
-    NS_ASSERTION(allocator || aNode->IsNodeOfType(nsINode::eDOCUMENT),
-                 "Should have allocator or document!");
-    nsDOMNodeAllocator* slotsAllocator = allocator ?
-      allocator.get() : aNode->mNodeInfo->NodeInfoManager()->NodeAllocator();
-    size_t* sz = reinterpret_cast<size_t*>(slots);
-    slotsAllocator->Free(*sz, static_cast<void*>(slots));
-    NS_RELEASE(slotsAllocator);
+    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
@@ -238,26 +230,17 @@ nsNodeUtils::LastRelease(nsINode* aNode)
       }
     }
 #endif
 
     nsContentUtils::RemoveListenerManager(aNode);
     aNode->UnsetFlags(NODE_HAS_LISTENERMANAGER);
   }
 
-  if (aNode->IsNodeOfType(nsINode::eDOCUMENT)) {
-    delete aNode;
-  } else {
-    NS_ASSERTION(allocator, "Should have allocator here!");
-    delete aNode; // Calls destructor and sets size to *aNode.
-    size_t* sz = reinterpret_cast<size_t*>(aNode);
-    allocator->Free(*sz, static_cast<void*>(aNode));
-    nsDOMNodeAllocator* tmpAlloc = allocator;
-    NS_RELEASE(tmpAlloc);
-  }
+  delete aNode;
 }
 
 static nsresult
 SetUserDataProperty(PRUint16 aCategory, nsINode *aNode, nsIAtom *aKey,
                     nsISupports* aValue, void** aOldValue)
 {
   nsresult rv = aNode->SetProperty(aCategory, aKey, aValue,
                                    nsPropertyTable::SupportsDtorFunc, PR_TRUE,
--- a/content/base/src/nsTextFragment.cpp
+++ b/content/base/src/nsTextFragment.cpp
@@ -40,19 +40,19 @@
  * node); if only codepoints below 256 are used, the text is stored as
  * a char*; otherwise the text is stored as a PRUnichar*
  */
 
 #include "nsTextFragment.h"
 #include "nsString.h"
 #include "nsCRT.h"
 #include "nsReadableUtils.h"
+#include "nsMemory.h"
 #include "nsBidiUtils.h"
 #include "nsUnicharUtils.h"
-#include "nsNodeInfoManager.h"
 
 #define TEXTFRAG_WHITE_AFTER_NEWLINE 50
 #define TEXTFRAG_MAX_NEWLINES 7
 
 // Static buffer used for common fragments
 static char* sSpaceSharedString[TEXTFRAG_MAX_NEWLINES + 1];
 static char* sTabSharedString[TEXTFRAG_MAX_NEWLINES + 1];
 static char sSingleCharSharedString[256];
@@ -97,70 +97,47 @@ nsTextFragment::Shutdown()
   for (i = 0; i <= TEXTFRAG_MAX_NEWLINES; ++i) {
     delete [] sSpaceSharedString[i];
     delete [] sTabSharedString[i];
     sSpaceSharedString[i] = nsnull;
     sTabSharedString[i] = nsnull;
   }
 }
 
-nsTextFragment::nsTextFragment(nsDOMNodeAllocator* aAllocator)
-  : m1b(nsnull), mAllBits(0), mAllocator(aAllocator)
-{
-  NS_ADDREF(mAllocator);
-  NS_ASSERTION(sizeof(FragmentBits) == 4, "Bad field packing!");
-}
-
 nsTextFragment::~nsTextFragment()
 {
   ReleaseText();
-  NS_RELEASE(mAllocator);
 }
 
 void
 nsTextFragment::ReleaseText()
 {
   if (mState.mLength && m1b && mState.mInHeap) {
-    // m1b == m2b as far as memory is concerned
-    mAllocator->Free(mState.mLength *
-                       (mState.mIs2b ? sizeof(PRUnichar) : sizeof(char)),
-                     m2b);
+    nsMemory::Free(m2b); // m1b == m2b as far as nsMemory is concerned
   }
 
   m1b = nsnull;
 
   // Set mState.mIs2b, mState.mInHeap, and mState.mLength = 0 with mAllBits;
   mAllBits = 0;
 }
 
-void*
-nsTextFragment::CloneMemory(const void* aPtr, PRSize aSize)
-{
-  void* newPtr = mAllocator->Alloc(aSize);
-  if (newPtr) {
-    memcpy(newPtr, aPtr, aSize);
-  }
- return newPtr;
-}
-
 nsTextFragment&
 nsTextFragment::operator=(const nsTextFragment& aOther)
 {
   ReleaseText();
 
   if (aOther.mState.mLength) {
     if (!aOther.mState.mInHeap) {
       m1b = aOther.m1b; // This will work even if aOther is using m2b
     }
     else {
-      m2b =
-        static_cast<PRUnichar*>
-          (CloneMemory(aOther.m2b, aOther.mState.mLength *
-                       (aOther.mState.mIs2b ?
-                          sizeof(PRUnichar) : sizeof(char))));
+      m2b = static_cast<PRUnichar*>
+                       (nsMemory::Clone(aOther.m2b, aOther.mState.mLength *
+                                    (aOther.mState.mIs2b ? sizeof(PRUnichar) : sizeof(char))));
     }
 
     if (m1b) {
       mAllBits = aOther.mAllBits;
     }
   }
 
   return *this;
@@ -231,23 +208,24 @@ nsTextFragment::SetTo(const PRUnichar* a
     if (ch >= 256) {
       need2 = PR_TRUE;
       break;
     }
   }
 
   if (need2) {
     // Use ucs2 storage because we have to
-    m2b = (PRUnichar *)CloneMemory(aBuffer, aLength * sizeof(PRUnichar));
+    m2b = (PRUnichar *)nsMemory::Clone(aBuffer,
+                                       aLength * sizeof(PRUnichar));
     if (!m2b) {
       return;
     }
   } else {
     // Use 1 byte storage because we can
-    char* buff = (char *)mAllocator->Alloc(aLength * sizeof(char));
+    char* buff = (char *)nsMemory::Alloc(aLength * sizeof(char));
     if (!buff) {
       return;
     }
 
     // Copy data
     for (PRUint32 i = 0; i < (PRUint32)aLength; ++i) {
       buff[i] = (char)aBuffer[i];
     }
@@ -318,30 +296,25 @@ nsTextFragment::Append(const PRUnichar* 
 
     return;
   }
 
   // Should we optimize for aData.Length() == 0?
 
   if (mState.mIs2b) {
     // Already a 2-byte string so the result will be too
-    PRUnichar* buff =
-      (PRUnichar*)mAllocator->Alloc((mState.mLength + aLength) *
-                                    sizeof(PRUnichar));
+    PRUnichar* buff = (PRUnichar*)nsMemory::Realloc(m2b, (mState.mLength + aLength) * sizeof(PRUnichar));
     if (!buff) {
       return;
     }
-    memcpy(buff, m2b, mState.mLength * sizeof(PRUnichar));
+    
     memcpy(buff + mState.mLength, aBuffer, aLength * sizeof(PRUnichar));
-    if (mState.mInHeap) {
-      mAllocator->Free(mState.mLength * sizeof(PRUnichar), m2b);
-    }
     mState.mLength += aLength;
     m2b = buff;
-    mState.mInHeap = PR_TRUE;
+
     return;
   }
 
   // Current string is a 1-byte string, check if the new data fits in one byte too.
 
   const PRUnichar* ucp = aBuffer;
   const PRUnichar* uend = ucp + aLength;
   PRBool need2 = PR_FALSE;
@@ -351,57 +324,65 @@ nsTextFragment::Append(const PRUnichar* 
       need2 = PR_TRUE;
       break;
     }
   }
 
   if (need2) {
     // The old data was 1-byte, but the new is not so we have to expand it
     // all to 2-byte
-    PRUnichar* buff = (PRUnichar*)mAllocator->Alloc((mState.mLength + aLength) *
-                                                    sizeof(PRUnichar));
+    PRUnichar* buff = (PRUnichar*)nsMemory::Alloc((mState.mLength + aLength) *
+                                                  sizeof(PRUnichar));
     if (!buff) {
       return;
     }
 
     // Copy data
     for (PRUint32 i = 0; i < mState.mLength; ++i) {
       buff[i] = (unsigned char)m1b[i];
     }
     
     memcpy(buff + mState.mLength, aBuffer, aLength * sizeof(PRUnichar));
 
-    if (mState.mInHeap) {
-      mAllocator->Free(mState.mLength * sizeof(char), m2b);
-    }
     mState.mLength += aLength;
     mState.mIs2b = PR_TRUE;
+
+    if (mState.mInHeap) {
+      nsMemory::Free(m2b);
+    }
     m2b = buff;
+
     mState.mInHeap = PR_TRUE;
 
     return;
   }
 
   // The new and the old data is all 1-byte
-  char* buff =
-    (char*)mAllocator->Alloc((mState.mLength + aLength) * sizeof(char));
-  if (!buff) {
-    return;
+  char* buff;
+  if (mState.mInHeap) {
+    buff = (char*)nsMemory::Realloc(const_cast<char*>(m1b),
+                                    (mState.mLength + aLength) * sizeof(char));
+    if (!buff) {
+      return;
+    }
   }
+  else {
+    buff = (char*)nsMemory::Alloc((mState.mLength + aLength) * sizeof(char));
+    if (!buff) {
+      return;
+    }
 
-  memcpy(buff, m1b, mState.mLength);
-
+    memcpy(buff, m1b, mState.mLength);
+    mState.mInHeap = PR_TRUE;
+  }
+    
   for (PRUint32 i = 0; i < aLength; ++i) {
     buff[mState.mLength + i] = (char)aBuffer[i];
   }
 
-  if (mState.mInHeap) {
-    mAllocator->Free(mState.mLength * sizeof(char), const_cast<char*>(m1b));
-  }
-  mState.mInHeap = PR_TRUE;
   m1b = buff;
   mState.mLength += aLength;
 
 }
 
 // To save time we only do this when we really want to know, not during
 // every allocation
 void
--- a/content/base/src/nsTextFragment.h
+++ b/content/base/src/nsTextFragment.h
@@ -42,17 +42,16 @@
  */
 
 #ifndef nsTextFragment_h___
 #define nsTextFragment_h___
 
 #include "nsAString.h"
 class nsString;
 class nsCString;
-class nsDOMNodeAllocator;
 
 // XXX should this normalize the code to keep a \u0000 at the end?
 
 // XXX nsTextFragmentPool?
 
 // XXX these need I18N spankage
 #define XP_IS_SPACE(_ch) \
   (((_ch) == ' ') || ((_ch) == '\t') || ((_ch) == '\n'))
@@ -81,22 +80,24 @@ class nsDOMNodeAllocator;
 class nsTextFragment {
 public:
   static nsresult Init();
   static void Shutdown();
 
   /**
    * Default constructor. Initialize the fragment to be empty.
    */
-  nsTextFragment(nsDOMNodeAllocator* aAllocator);
+  nsTextFragment()
+    : m1b(nsnull), mAllBits(0)
+  {
+    NS_ASSERTION(sizeof(FragmentBits) == 4, "Bad field packing!");
+  }
 
   ~nsTextFragment();
 
-  nsDOMNodeAllocator* Allocator() { return mAllocator; }
-
   /**
    * Change the contents of this fragment to be a copy of the
    * the argument fragment.
    */
   nsTextFragment& operator=(const nsTextFragment& aOther);
 
   /**
    * Return PR_TRUE if this fragment is represented by PRUnichar data
@@ -199,24 +200,22 @@ public:
     PRUint32 mInHeap : 1;
     PRUint32 mIs2b : 1;
     PRUint32 mIsBidi : 1;
     PRUint32 mLength : 29;
   };
 
 private:
   void ReleaseText();
-  void* CloneMemory(const void* aPtr, PRSize aSize);
 
   union {
     PRUnichar *m2b;
     const char *m1b; // This is const since it can point to shared data
   };
 
   union {
     PRUint32 mAllBits;
     FragmentBits mState;
   };
-  nsDOMNodeAllocator* mAllocator;
 };
 
 #endif /* nsTextFragment_h___ */
 
--- a/content/base/src/nsTextNode.cpp
+++ b/content/base/src/nsTextNode.cpp
@@ -109,19 +109,19 @@ public:
   virtual void UnbindFromTree(PRBool aDeep = PR_TRUE,
                               PRBool aNullParent = PR_TRUE);
 
   NS_DECL_NSIMUTATIONOBSERVER_ATTRIBUTECHANGED
 
   virtual nsGenericDOMDataNode *CloneDataNode(nsINodeInfo *aNodeInfo,
                                               PRBool aCloneText) const
   {
-    nsAttributeTextNode *it = new (aNodeInfo) nsAttributeTextNode(aNodeInfo,
-                                                                  mNameSpaceID,
-                                                                  mAttrName);
+    nsAttributeTextNode *it = new nsAttributeTextNode(aNodeInfo,
+                                                      mNameSpaceID,
+                                                      mAttrName);
     if (it && aCloneText) {
       it->mText = mText;
     }
 
     return it;
   }
 
   // Public method for the event to run
@@ -149,17 +149,17 @@ NS_NewTextNode(nsIContent** aInstancePtr
 
   *aInstancePtrResult = nsnull;
 
   nsCOMPtr<nsINodeInfo> ni = aNodeInfoManager->GetTextNodeInfo();
   if (!ni) {
     return NS_ERROR_OUT_OF_MEMORY;
   }
 
-  nsIContent *instance = new (ni) nsTextNode(ni);
+  nsIContent *instance = new nsTextNode(ni);
   if (!instance) {
     return NS_ERROR_OUT_OF_MEMORY;
   }
 
   NS_ADDREF(*aInstancePtrResult = instance);
 
   return NS_OK;
 }
@@ -215,17 +215,17 @@ PRBool
 nsTextNode::IsNodeOfType(PRUint32 aFlags) const
 {
   return !(aFlags & ~(eCONTENT | eTEXT | eDATA_NODE));
 }
 
 nsGenericDOMDataNode*
 nsTextNode::CloneDataNode(nsINodeInfo *aNodeInfo, PRBool aCloneText) const
 {
-  nsTextNode *it = new (aNodeInfo) nsTextNode(aNodeInfo);
+  nsTextNode *it = new nsTextNode(aNodeInfo);
   if (it && aCloneText) {
     it->mText = mText;
   }
 
   return it;
 }
 
 #ifdef DEBUG
@@ -275,18 +275,18 @@ NS_NewAttributeContent(nsNodeInfoManager
   
   *aResult = nsnull;
 
   nsCOMPtr<nsINodeInfo> ni = aNodeInfoManager->GetTextNodeInfo();
   if (!ni) {
     return NS_ERROR_OUT_OF_MEMORY;
   }
 
-  nsAttributeTextNode* textNode = new (ni) nsAttributeTextNode(ni, aNameSpaceID,
-                                                               aAttrName);
+  nsAttributeTextNode* textNode = new nsAttributeTextNode(ni, aNameSpaceID,
+                                                          aAttrName);
   if (!textNode) {
     return NS_ERROR_OUT_OF_MEMORY;
   }
 
   NS_ADDREF(*aResult = textNode);
 
   return NS_OK;
 }
--- a/content/events/src/nsXMLEventsElement.cpp
+++ b/content/events/src/nsXMLEventsElement.cpp
@@ -82,16 +82,16 @@ nsXMLEventsElement::SetAttr(PRInt32 aNam
                                    aNotify);
 }
 
 NS_IMPL_ELEMENT_CLONE(nsXMLEventsElement)
 
 nsresult
 NS_NewXMLEventsElement(nsIContent** aInstancePtrResult, nsINodeInfo *aNodeInfo)
 {
-  nsXMLEventsElement* it = new (aNodeInfo) nsXMLEventsElement(aNodeInfo);
+  nsXMLEventsElement* it = new nsXMLEventsElement(aNodeInfo);
   if (!it) {
     return NS_ERROR_OUT_OF_MEMORY;
   }
   NS_ADDREF(*aInstancePtrResult = it);
   return NS_OK;
 }
 
--- a/content/html/content/src/nsGenericHTMLElement.h
+++ b/content/html/content/src/nsGenericHTMLElement.h
@@ -227,16 +227,17 @@ public:
   nsresult PostHandleEventForAnchors(nsEventChainPostVisitor& aVisitor);
   PRBool IsHTMLLink(nsIURI** aURI) const;
 
   // Used by A, AREA, LINK, and STYLE.
   // Callers must hold a reference to nsHTMLUtils's global reference count.
   nsresult GetHrefURIForAnchors(nsIURI** aURI) const;
 
   // HTML element methods
+  void Compact() { mAttrsAndChildren.Compact(); }
   const nsAttrValue* GetParsedAttr(nsIAtom* aAttr) const
   {
     return mAttrsAndChildren.GetAttr(aAttr);
   }
 
   virtual void UpdateEditableState();
 
   already_AddRefed<nsIURI> GetBaseURI() const;
@@ -967,25 +968,24 @@ private:
 
 /**
  * A macro to implement the NS_NewHTMLXXXElement() functions.
  */
 #define NS_IMPL_NS_NEW_HTML_ELEMENT(_elementName)                            \
 nsGenericHTMLElement*                                                        \
 NS_NewHTML##_elementName##Element(nsINodeInfo *aNodeInfo, PRBool aFromParser)\
 {                                                                            \
-  return new (aNodeInfo) nsHTML##_elementName##Element(aNodeInfo);           \
+  return new nsHTML##_elementName##Element(aNodeInfo);                       \
 }
 
 #define NS_IMPL_NS_NEW_HTML_ELEMENT_CHECK_PARSER(_elementName)               \
 nsGenericHTMLElement*                                                        \
 NS_NewHTML##_elementName##Element(nsINodeInfo *aNodeInfo, PRBool aFromParser)\
 {                                                                            \
-  return                                                                     \
-    new (aNodeInfo) nsHTML##_elementName##Element(aNodeInfo, aFromParser);   \
+  return new nsHTML##_elementName##Element(aNodeInfo, aFromParser);          \
 }
 
 
 /**
  * A macro to implement the getter and setter for a given string
  * valued content property. The method uses the generic GetAttr and
  * SetAttr methods.
  */
--- a/content/html/content/src/nsHTMLCanvasElement.cpp
+++ b/content/html/content/src/nsHTMLCanvasElement.cpp
@@ -130,17 +130,17 @@ public:
   // We also transitively set it when script paints a canvas which
   // is itself write-only.
   PRPackedBool             mWriteOnly;
 };
 
 nsGenericHTMLElement*
 NS_NewHTMLCanvasElement(nsINodeInfo *aNodeInfo, PRBool aFromParser)
 {
-  return new (aNodeInfo) nsHTMLCanvasElement(aNodeInfo);
+  return new nsHTMLCanvasElement(aNodeInfo);
 }
 
 nsHTMLCanvasElement::nsHTMLCanvasElement(nsINodeInfo *aNodeInfo)
   : nsGenericHTMLElement(aNodeInfo), mWriteOnly(PR_FALSE)
 {
 }
 
 nsHTMLCanvasElement::~nsHTMLCanvasElement()
--- a/content/html/content/src/nsHTMLFormElement.cpp
+++ b/content/html/content/src/nsHTMLFormElement.cpp
@@ -456,17 +456,17 @@ ShouldBeInElements(nsIFormControl* aForm
 }
 
 // nsHTMLFormElement implementation
 
 // construction, destruction
 nsGenericHTMLElement*
 NS_NewHTMLFormElement(nsINodeInfo *aNodeInfo, PRBool aFromParser)
 {
-  nsHTMLFormElement* it = new (aNodeInfo) nsHTMLFormElement(aNodeInfo);
+  nsHTMLFormElement* it = new nsHTMLFormElement(aNodeInfo);
   if (!it) {
     return nsnull;
   }
 
   nsresult rv = it->Init();
 
   if (NS_FAILED(rv)) {
     delete it;
--- a/content/html/content/src/nsHTMLImageElement.cpp
+++ b/content/html/content/src/nsHTMLImageElement.cpp
@@ -167,17 +167,17 @@ NS_NewHTMLImageElement(nsINodeInfo *aNod
     NS_ENSURE_TRUE(doc, nsnull);
 
     rv = doc->NodeInfoManager()->GetNodeInfo(nsGkAtoms::img, nsnull,
                                              kNameSpaceID_None,
                                              getter_AddRefs(nodeInfo));
     NS_ENSURE_SUCCESS(rv, nsnull);
   }
 
-  return new (nodeInfo) nsHTMLImageElement(nodeInfo);
+  return new nsHTMLImageElement(nodeInfo);
 }
 
 nsHTMLImageElement::nsHTMLImageElement(nsINodeInfo *aNodeInfo)
   : nsGenericHTMLElement(aNodeInfo)
 {
 }
 
 nsHTMLImageElement::~nsHTMLImageElement()
--- a/content/html/content/src/nsHTMLInputElement.cpp
+++ b/content/html/content/src/nsHTMLInputElement.cpp
@@ -425,18 +425,17 @@ NS_HTML_CONTENT_INTERFACE_TABLE_TAIL_CLA
 
 // nsIDOMNode
 
 nsresult
 nsHTMLInputElement::Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const
 {
   *aResult = nsnull;
 
-  nsHTMLInputElement *it =
-    new (aNodeInfo) nsHTMLInputElement(aNodeInfo, PR_FALSE);
+  nsHTMLInputElement *it = new nsHTMLInputElement(aNodeInfo, PR_FALSE);
   if (!it) {
     return NS_ERROR_OUT_OF_MEMORY;
   }
 
   nsCOMPtr<nsINode> kungFuDeathGrip = it;
   nsresult rv = CopyInnerTo(it);
   NS_ENSURE_SUCCESS(rv, rv);
 
--- a/content/html/content/src/nsHTMLOptionElement.cpp
+++ b/content/html/content/src/nsHTMLOptionElement.cpp
@@ -152,17 +152,17 @@ NS_NewHTMLOptionElement(nsINodeInfo *aNo
     NS_ENSURE_TRUE(doc, nsnull);
 
     rv = doc->NodeInfoManager()->GetNodeInfo(nsGkAtoms::option, nsnull,
                                              kNameSpaceID_None,
                                              getter_AddRefs(nodeInfo));
     NS_ENSURE_SUCCESS(rv, nsnull);
   }
 
-  return new (nodeInfo) nsHTMLOptionElement(nodeInfo);
+  return new nsHTMLOptionElement(nodeInfo);
 }
 
 nsHTMLOptionElement::nsHTMLOptionElement(nsINodeInfo *aNodeInfo)
   : nsGenericHTMLElement(aNodeInfo),
     mSelectedChanged(PR_FALSE),
     mIsSelected(PR_FALSE),
     mIsInSetDefaultSelected(PR_FALSE)
 {
--- a/content/html/content/src/nsHTMLScriptElement.cpp
+++ b/content/html/content/src/nsHTMLScriptElement.cpp
@@ -415,18 +415,17 @@ nsHTMLScriptElement::BindToTree(nsIDocum
   return NS_OK;
 }
 
 nsresult
 nsHTMLScriptElement::Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const
 {
   *aResult = nsnull;
 
-  nsHTMLScriptElement* it =
-    new (aNodeInfo) nsHTMLScriptElement(aNodeInfo, PR_FALSE);
+  nsHTMLScriptElement* it = new nsHTMLScriptElement(aNodeInfo, PR_FALSE);
   if (!it) {
     return NS_ERROR_OUT_OF_MEMORY;
   }
 
   nsCOMPtr<nsINode> kungFuDeathGrip = it;
   nsresult rv = CopyInnerTo(it);
   NS_ENSURE_SUCCESS(rv, rv);
 
--- a/content/html/document/src/nsHTMLContentSink.cpp
+++ b/content/html/document/src/nsHTMLContentSink.cpp
@@ -926,16 +926,17 @@ SinkContext::CloseContainer(const nsHTML
   --mStackPos;
   nsHTMLTag nodeType = mStack[mStackPos].mType;
 
   NS_ASSERTION(nodeType == eHTMLTag_form || nodeType == aTag,
                "Tag mismatch.  Closing tag on wrong context or something?");
 
   nsGenericHTMLElement* content = mStack[mStackPos].mContent;
 
+  content->Compact();
 
   // If we're in a state where we do append notifications as
   // we go up the tree, and we're at the level where the next
   // notification needs to be done, do the notification.
   if (mNotifyLevel >= mStackPos) {
     // Check to see if new content has been added after our last
     // notification
 
--- a/content/mathml/content/src/nsMathMLElementFactory.cpp
+++ b/content/mathml/content/src/nsMathMLElementFactory.cpp
@@ -42,14 +42,14 @@
 #include "nsMathMLElement.h"
 
 // MathML Element Factory (declared in nsContentCreatorFunctions.h)
 nsresult
 NS_NewMathMLElement(nsIContent** aResult, nsINodeInfo* aNodeInfo)
 {
   aNodeInfo->SetIDAttributeAtom(nsGkAtoms::id);
 
-  nsMathMLElement* it = new (aNodeInfo) nsMathMLElement(aNodeInfo);
+  nsMathMLElement* it = new nsMathMLElement(aNodeInfo);
   NS_ENSURE_TRUE(it, NS_ERROR_OUT_OF_MEMORY);
 
   NS_ADDREF(*aResult = it);
   return NS_OK;
 }
--- a/content/svg/content/src/nsSVGElement.cpp
+++ b/content/svg/content/src/nsSVGElement.cpp
@@ -92,19 +92,17 @@
 
 nsSVGEnumMapping nsSVGElement::sSVGUnitTypesMap[] = {
   {&nsGkAtoms::userSpaceOnUse, nsIDOMSVGUnitTypes::SVG_UNIT_TYPE_USERSPACEONUSE},
   {&nsGkAtoms::objectBoundingBox, nsIDOMSVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX},
   {nsnull, 0}
 };
 
 nsSVGElement::nsSVGElement(nsINodeInfo *aNodeInfo)
-  : nsSVGElementBase(aNodeInfo),
-    mMappedAttributes(aNodeInfo->NodeInfoManager()->NodeAllocator()),
-    mSuppressNotification(PR_FALSE)
+  : nsSVGElementBase(aNodeInfo), mSuppressNotification(PR_FALSE)
 {
 }
 
 nsresult
 nsSVGElement::Init()
 {
   // Set up length attributes - can't do this in the constructor
   // because we can't do a virtual call at that point
--- a/content/svg/content/src/nsSVGElement.h
+++ b/content/svg/content/src/nsSVGElement.h
@@ -317,17 +317,17 @@ private:
  * A macro to implement the NS_NewSVGXXXElement() functions.
  */
 #define NS_IMPL_NS_NEW_SVG_ELEMENT(_elementName)                             \
 nsresult                                                                     \
 NS_NewSVG##_elementName##Element(nsIContent **aResult,                       \
                                  nsINodeInfo *aNodeInfo)                     \
 {                                                                            \
   nsSVG##_elementName##Element *it =                                         \
-    new (aNodeInfo) nsSVG##_elementName##Element(aNodeInfo);                 \
+    new nsSVG##_elementName##Element(aNodeInfo);                             \
   if (!it)                                                                   \
     return NS_ERROR_OUT_OF_MEMORY;                                           \
                                                                              \
   NS_ADDREF(it);                                                             \
                                                                              \
   nsresult rv = it->Init();                                                  \
                                                                              \
   if (NS_FAILED(rv)) {                                                       \
--- a/content/svg/content/src/nsSVGUseElement.cpp
+++ b/content/svg/content/src/nsSVGUseElement.cpp
@@ -128,17 +128,17 @@ nsSVGUseElement::Init()
 //----------------------------------------------------------------------
 // nsIDOMNode methods
 
 nsresult
 nsSVGUseElement::Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const
 {
   *aResult = nsnull;
 
-  nsSVGUseElement *it = new (aNodeInfo) nsSVGUseElement(aNodeInfo);
+  nsSVGUseElement *it = new nsSVGUseElement(aNodeInfo);
   if (!it) {
     return NS_ERROR_OUT_OF_MEMORY;
   }
 
   nsCOMPtr<nsINode> kungFuDeathGrip(it);
   nsresult rv = it->Init();
   rv |= CopyInnerTo(it);
 
--- a/content/xml/content/src/nsXMLCDATASection.cpp
+++ b/content/xml/content/src/nsXMLCDATASection.cpp
@@ -81,17 +81,17 @@ NS_NewXMLCDATASection(nsIContent** aInst
   *aInstancePtrResult = nsnull;
 
   nsCOMPtr<nsINodeInfo> ni;
   nsresult rv = aNodeInfoManager->GetNodeInfo(nsGkAtoms::cdataTagName,
                                               nsnull, kNameSpaceID_None,
                                               getter_AddRefs(ni));
   NS_ENSURE_SUCCESS(rv, rv);
 
-  nsXMLCDATASection *instance = new (ni) nsXMLCDATASection(ni);
+  nsXMLCDATASection *instance = new nsXMLCDATASection(ni);
   if (!instance) {
     return NS_ERROR_OUT_OF_MEMORY;
   }
 
   NS_ADDREF(*aInstancePtrResult = instance);
 
   return NS_OK;
 }
@@ -149,17 +149,17 @@ nsXMLCDATASection::GetNodeType(PRUint16*
 {
   *aNodeType = (PRUint16)nsIDOMNode::CDATA_SECTION_NODE;
   return NS_OK;
 }
 
 nsGenericDOMDataNode*
 nsXMLCDATASection::CloneDataNode(nsINodeInfo *aNodeInfo, PRBool aCloneText) const
 {
-  nsXMLCDATASection *it = new (aNodeInfo) nsXMLCDATASection(aNodeInfo);
+  nsXMLCDATASection *it = new nsXMLCDATASection(aNodeInfo);
   if (it && aCloneText) {
     it->mText = mText;
   }
 
   return it;
 }
 
 #ifdef DEBUG
--- a/content/xml/content/src/nsXMLElement.cpp
+++ b/content/xml/content/src/nsXMLElement.cpp
@@ -42,17 +42,17 @@
 #include "nsIRefreshURI.h"
 #include "nsPresContext.h"
 #include "nsContentErrors.h"
 #include "nsIDocument.h"
 
 nsresult
 NS_NewXMLElement(nsIContent** aInstancePtrResult, nsINodeInfo *aNodeInfo)
 {
-  nsXMLElement* it = new (aNodeInfo) nsXMLElement(aNodeInfo);
+  nsXMLElement* it = new nsXMLElement(aNodeInfo);
   if (!it) {
     return NS_ERROR_OUT_OF_MEMORY;
   }
 
   NS_ADDREF(*aInstancePtrResult = it);
 
   return NS_OK;
 }
--- a/content/xml/content/src/nsXMLProcessingInstruction.cpp
+++ b/content/xml/content/src/nsXMLProcessingInstruction.cpp
@@ -60,17 +60,17 @@ NS_NewXMLProcessingInstruction(nsIConten
   nsCOMPtr<nsINodeInfo> ni;
   nsresult rv =
     aNodeInfoManager->GetNodeInfo(nsGkAtoms::processingInstructionTagName,
                                   nsnull, kNameSpaceID_None,
                                   getter_AddRefs(ni));
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsXMLProcessingInstruction *instance =
-    new (ni) nsXMLProcessingInstruction(ni, aTarget, aData);
+    new nsXMLProcessingInstruction(ni, aTarget, aData);
   if (!instance) {
     return NS_ERROR_OUT_OF_MEMORY;
   }
 
   NS_ADDREF(*aInstancePtrResult = instance);
 
   return NS_OK;
 }
@@ -171,17 +171,17 @@ nsXMLProcessingInstruction::GetNodeType(
 
 nsGenericDOMDataNode*
 nsXMLProcessingInstruction::CloneDataNode(nsINodeInfo *aNodeInfo,
                                           PRBool aCloneText) const
 {
   nsAutoString data;
   nsGenericDOMDataNode::GetData(data);
 
-  return new (aNodeInfo) nsXMLProcessingInstruction(aNodeInfo, mTarget, data);
+  return new nsXMLProcessingInstruction(aNodeInfo, mTarget, data);
 }
 
 #ifdef DEBUG
 void
 nsXMLProcessingInstruction::List(FILE* out, PRInt32 aIndent) const
 {
   PRInt32 index;
   for (index = aIndent; --index >= 0; ) fputs("  ", out);
--- a/content/xml/content/src/nsXMLStylesheetPI.cpp
+++ b/content/xml/content/src/nsXMLStylesheetPI.cpp
@@ -241,17 +241,17 @@ nsXMLStylesheetPI::GetStyleSheetInfo(nsA
 }
 
 nsGenericDOMDataNode*
 nsXMLStylesheetPI::CloneDataNode(nsINodeInfo *aNodeInfo, PRBool aCloneText) const
 {
   nsAutoString data;
   nsGenericDOMDataNode::GetData(data);
 
-  return new (aNodeInfo) nsXMLStylesheetPI(aNodeInfo, data);
+  return new nsXMLStylesheetPI(aNodeInfo, data);
 }
 
 nsresult
 NS_NewXMLStylesheetProcessingInstruction(nsIContent** aInstancePtrResult,
                                          nsNodeInfoManager *aNodeInfoManager,
                                          const nsAString& aData)
 {
   NS_PRECONDITION(aNodeInfoManager, "Missing nodeinfo manager");
@@ -260,17 +260,17 @@ NS_NewXMLStylesheetProcessingInstruction
   
   nsCOMPtr<nsINodeInfo> ni;
   nsresult rv =
     aNodeInfoManager->GetNodeInfo(nsGkAtoms::processingInstructionTagName,
                                   nsnull, kNameSpaceID_None,
                                   getter_AddRefs(ni));
   NS_ENSURE_SUCCESS(rv, rv);
 
-  nsXMLStylesheetPI *instance = new (ni) nsXMLStylesheetPI(ni, aData);
+  nsXMLStylesheetPI *instance = new nsXMLStylesheetPI(ni, aData);
   if (!instance) {
     return NS_ERROR_OUT_OF_MEMORY;
   }
 
   NS_ADDREF(*aInstancePtrResult = instance);
 
   return NS_OK;
 }
--- a/content/xtf/src/nsXTFElementWrapper.cpp
+++ b/content/xtf/src/nsXTFElementWrapper.cpp
@@ -998,18 +998,17 @@ nsXTFElementWrapper::RegUnregAccessKey(P
 nsresult
 NS_NewXTFElementWrapper(nsIXTFElement* aXTFElement,
                         nsINodeInfo* aNodeInfo,
                         nsIContent** aResult)
 {
   *aResult = nsnull;
    NS_ENSURE_ARG(aXTFElement);
 
-  nsXTFElementWrapper* result =
-    new (aNodeInfo) nsXTFElementWrapper(aNodeInfo, aXTFElement);
+  nsXTFElementWrapper* result = new nsXTFElementWrapper(aNodeInfo, aXTFElement);
   if (!result) {
     return NS_ERROR_OUT_OF_MEMORY;
   }
 
   NS_ADDREF(result);
 
   nsresult rv = result->Init();
   if (NS_FAILED(rv)) {
--- a/content/xul/content/src/nsXULElement.cpp
+++ b/content/xul/content/src/nsXULElement.cpp
@@ -257,25 +257,25 @@ nsXULElement::nsXULSlots::nsXULSlots(Ptr
 nsXULElement::nsXULSlots::~nsXULSlots()
 {
     NS_IF_RELEASE(mControllers); // Forces release
 }
 
 nsINode::nsSlots*
 nsXULElement::CreateSlots()
 {
-    return new (GetAllocator()) nsXULSlots(mFlagsOrSlots);
+    return new nsXULSlots(mFlagsOrSlots);
 }
 
 /* static */
 already_AddRefed<nsXULElement>
 nsXULElement::Create(nsXULPrototypeElement* aPrototype, nsINodeInfo *aNodeInfo,
                      PRBool aIsScriptable)
 {
-    nsXULElement *element = new (aNodeInfo) nsXULElement(aNodeInfo);
+    nsXULElement *element = new nsXULElement(aNodeInfo);
     if (element) {
         NS_ADDREF(element);
 
         element->mPrototype = aPrototype;
         if (aPrototype->mHasIdAttribute) {
             element->SetFlags(NODE_MAY_HAVE_ID);
         }
         if (aPrototype->mHasClassAttribute) {
@@ -346,17 +346,17 @@ nsXULElement::Create(nsXULPrototypeEleme
 nsresult
 NS_NewXULElement(nsIContent** aResult, nsINodeInfo *aNodeInfo)
 {
     NS_PRECONDITION(aNodeInfo, "need nodeinfo for non-proto Create");
 
     *aResult = nsnull;
 
     // Create an nsXULElement with the specified namespace and tag.
-    nsXULElement* element = new (aNodeInfo) nsXULElement(aNodeInfo);
+    nsXULElement* element = new nsXULElement(aNodeInfo);
     NS_ENSURE_TRUE(element, NS_ERROR_OUT_OF_MEMORY);
 
     NS_ADDREF(*aResult = element);
 
     return NS_OK;
 }
 
 //----------------------------------------------------------------------
@@ -426,17 +426,17 @@ nsXULElement::Clone(nsINodeInfo *aNodeIn
     // If we have a prototype, so will our clone.
     nsRefPtr<nsXULElement> element;
     if (mPrototype) {
         element = nsXULElement::Create(mPrototype, aNodeInfo, PR_TRUE);
         NS_ASSERTION(GetScriptTypeID() == mPrototype->mScriptTypeID,
                      "Didn't get the default language from proto?");
     }
     else {
-        element = new (aNodeInfo) nsXULElement(aNodeInfo);
+        element = new nsXULElement(aNodeInfo);
         if (element) {
         	// If created from a prototype, we will already have the script
         	// language specified by the proto - otherwise copy it directly
         	element->SetScriptTypeID(GetScriptTypeID());
         }
     }
 
     if (!element) {