зеркало из https://github.com/mozilla/pjs.git
Bug 403830, arena for content, r=sicking, sr=jst
This commit is contained in:
Родитель
a83b9e0d0d
Коммит
e52650feb7
|
@ -59,6 +59,7 @@ class nsIMutationObserver;
|
|||
class nsChildContentList;
|
||||
class nsNodeWeakReference;
|
||||
class nsNodeSupportsWeakRefTearoff;
|
||||
class nsDOMNodeAllocator;
|
||||
|
||||
enum {
|
||||
// This bit will be set if the node doesn't have nsSlots
|
||||
|
@ -126,8 +127,8 @@ inline nsINode* NODE_FROM(C& aContent, D& aDocument)
|
|||
|
||||
// IID for the nsINode interface
|
||||
#define NS_INODE_IID \
|
||||
{ 0x8cef8b4e, 0x4b7f, 0x4f86, \
|
||||
{ 0xba, 0x64, 0x75, 0xdf, 0xed, 0x0d, 0xa2, 0x3e } }
|
||||
{ 0x42f3a894, 0xe5d4, 0x44b1, \
|
||||
{ 0x96, 0x34, 0x73, 0x8f, 0xf8, 0xbe, 0x5d, 0x9b } }
|
||||
|
||||
// hack to make egcs / gcc 2.95.2 happy
|
||||
class nsINode_base : public nsPIDOMEventTarget {
|
||||
|
@ -578,6 +579,11 @@ public:
|
|||
* 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;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -636,6 +642,13 @@ public:
|
|||
#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.
|
||||
|
|
|
@ -119,20 +119,28 @@ GetIndexFromCache(const nsAttrAndChildArray* aArray)
|
|||
#define NS_IMPL_EXTRA_SIZE \
|
||||
((sizeof(Impl) - sizeof(mImpl->mBuffer)) / sizeof(void*))
|
||||
|
||||
nsAttrAndChildArray::nsAttrAndChildArray()
|
||||
: mImpl(nsnull)
|
||||
nsAttrAndChildArray::nsAttrAndChildArray(nsDOMNodeAllocator* aAllocator)
|
||||
: mImpl(nsnull), mAllocator(aAllocator)
|
||||
{
|
||||
NS_IF_ADDREF(mAllocator);
|
||||
}
|
||||
|
||||
nsAttrAndChildArray::~nsAttrAndChildArray()
|
||||
{
|
||||
if (!mImpl) {
|
||||
return;
|
||||
if (mImpl) {
|
||||
Clear();
|
||||
mAllocator->Free((mImpl->mBufferSize + NS_IMPL_EXTRA_SIZE) * sizeof(void*),
|
||||
mImpl);
|
||||
}
|
||||
|
||||
Clear();
|
||||
NS_IF_RELEASE(mAllocator);
|
||||
}
|
||||
|
||||
PR_Free(mImpl);
|
||||
void
|
||||
nsAttrAndChildArray::SetAllocator(nsDOMNodeAllocator* aAllocator)
|
||||
{
|
||||
NS_ASSERTION(!mAllocator, "Allocator already set!");
|
||||
NS_ADDREF(mAllocator = aAllocator);
|
||||
}
|
||||
|
||||
nsIContent*
|
||||
|
@ -593,39 +601,6 @@ nsAttrAndChildArray::WalkMappedAttributeStyleRules(nsRuleWalker* aRuleWalker)
|
|||
}
|
||||
}
|
||||
|
||||
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()
|
||||
{
|
||||
|
@ -755,16 +730,17 @@ nsAttrAndChildArray::GrowBy(PRUint32 aGrowSize)
|
|||
size = PR_BIT(PR_CeilingLog2(minSize));
|
||||
}
|
||||
|
||||
Impl* newImpl = static_cast<Impl*>
|
||||
(mImpl ? PR_Realloc(mImpl, size * sizeof(void*)) :
|
||||
PR_Malloc(size * sizeof(void*)));
|
||||
Impl* newImpl = static_cast<Impl*>(mAllocator->Alloc(size * sizeof(void*)));
|
||||
NS_ENSURE_TRUE(newImpl, PR_FALSE);
|
||||
|
||||
Impl* oldImpl = mImpl;
|
||||
mImpl = newImpl;
|
||||
|
||||
// Set initial counts if we didn't have a buffer before
|
||||
if (!oldImpl) {
|
||||
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
|
||||
mImpl->mMappedAttrs = nsnull;
|
||||
SetAttrSlotAndChildCount(0, 0);
|
||||
}
|
||||
|
|
|
@ -75,8 +75,10 @@ class nsGenericHTMLElement;
|
|||
class nsAttrAndChildArray
|
||||
{
|
||||
public:
|
||||
nsAttrAndChildArray();
|
||||
nsAttrAndChildArray(nsDOMNodeAllocator* aAllocator);
|
||||
~nsAttrAndChildArray();
|
||||
void SetAllocator(nsDOMNodeAllocator* aAllocator);
|
||||
nsDOMNodeAllocator* Allocator() { return mAllocator; }
|
||||
|
||||
PRUint32 ChildCount() const
|
||||
{
|
||||
|
@ -123,8 +125,6 @@ public:
|
|||
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
|
||||
|
@ -186,7 +186,8 @@ private:
|
|||
void* mBuffer[1];
|
||||
};
|
||||
|
||||
Impl* mImpl;
|
||||
Impl* mImpl;
|
||||
nsDOMNodeAllocator* mAllocator;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -88,7 +88,7 @@ NS_NewCommentNode(nsIContent** aInstancePtrResult,
|
|||
nsCOMPtr<nsINodeInfo> ni = aNodeInfoManager->GetCommentNodeInfo();
|
||||
NS_ENSURE_TRUE(ni, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
nsCommentNode *instance = new nsCommentNode(ni);
|
||||
nsCommentNode *instance = new (ni) nsCommentNode(ni);
|
||||
if (!instance) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
@ -163,7 +163,7 @@ nsCommentNode::GetNodeType(PRUint16* aNodeType)
|
|||
nsGenericDOMDataNode*
|
||||
nsCommentNode::CloneDataNode(nsINodeInfo *aNodeInfo, PRBool aCloneText) const
|
||||
{
|
||||
nsCommentNode *it = new nsCommentNode(aNodeInfo);
|
||||
nsCommentNode *it = new (aNodeInfo) nsCommentNode(aNodeInfo);
|
||||
if (it && aCloneText) {
|
||||
it->mText = mText;
|
||||
}
|
||||
|
|
|
@ -64,7 +64,9 @@ PRBool nsDOMAttribute::sInitialized;
|
|||
nsDOMAttribute::nsDOMAttribute(nsDOMAttributeMap *aAttrMap,
|
||||
nsINodeInfo *aNodeInfo,
|
||||
const nsAString &aValue)
|
||||
: nsIAttribute(aAttrMap, aNodeInfo), mValue(aValue)
|
||||
: nsIAttribute(aAttrMap, aNodeInfo),
|
||||
mAllocator(aNodeInfo->NodeInfoManager()->NodeAllocator()),
|
||||
mValue(aValue)
|
||||
{
|
||||
NS_ABORT_IF_FALSE(mNodeInfo, "We must get a nodeinfo here!");
|
||||
|
||||
|
@ -372,7 +374,7 @@ nsDOMAttribute::Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const
|
|||
nsAutoString value;
|
||||
const_cast<nsDOMAttribute*>(this)->GetValue(value);
|
||||
|
||||
*aResult = new nsDOMAttribute(nsnull, aNodeInfo, value);
|
||||
*aResult = new (aNodeInfo) nsDOMAttribute(nsnull, aNodeInfo, value);
|
||||
if (!*aResult) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
|
|
@ -59,9 +59,9 @@ class nsDOMAttribute;
|
|||
|
||||
// Attribute helper class used to wrap up an attribute with a dom
|
||||
// object that implements nsIDOMAttr, nsIDOM3Attr, nsIDOMNode, nsIDOM3Node
|
||||
class nsDOMAttribute : public nsIDOMAttr,
|
||||
public nsIDOM3Attr,
|
||||
public nsIAttribute
|
||||
class nsDOMAttribute : public nsIAttribute,
|
||||
public nsIDOMAttr,
|
||||
public nsIDOM3Attr
|
||||
{
|
||||
public:
|
||||
nsDOMAttribute(nsDOMAttributeMap* aAttrMap, nsINodeInfo *aNodeInfo,
|
||||
|
@ -108,6 +108,7 @@ public:
|
|||
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();
|
||||
|
@ -120,6 +121,7 @@ protected:
|
|||
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
|
||||
|
|
|
@ -179,8 +179,8 @@ nsDOMAttributeMap::GetAttribute(nsINodeInfo* aNodeInfo,
|
|||
// the attribute node.
|
||||
mContent->GetAttr(aNodeInfo->NamespaceID(), aNodeInfo->NameAtom(), value);
|
||||
}
|
||||
nsCOMPtr<nsIDOMNode> newAttr = new nsDOMAttribute(aRemove ? nsnull : this,
|
||||
aNodeInfo, value);
|
||||
nsCOMPtr<nsIDOMNode> newAttr =
|
||||
new (aNodeInfo) nsDOMAttribute(aRemove ? nsnull : this, aNodeInfo, value);
|
||||
if (!newAttr) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
|
|
@ -89,8 +89,8 @@ NS_NewDOMDocumentType(nsIDOMDocumentType** aDocType,
|
|||
kNameSpaceID_None, getter_AddRefs(ni));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
*aDocType = new nsDOMDocumentType(ni, aName, aEntities, aNotations,
|
||||
aPublicId, aSystemId, aInternalSubset);
|
||||
*aDocType = new (ni) nsDOMDocumentType(ni, aName, aEntities, aNotations,
|
||||
aPublicId, aSystemId, aInternalSubset);
|
||||
if (!*aDocType) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
@ -235,8 +235,9 @@ nsDOMDocumentType::GetNodeType(PRUint16* aNodeType)
|
|||
nsGenericDOMDataNode*
|
||||
nsDOMDocumentType::CloneDataNode(nsINodeInfo *aNodeInfo, PRBool aCloneText) const
|
||||
{
|
||||
return new nsDOMDocumentType(aNodeInfo, mName, mEntities, mNotations,
|
||||
mPublicId, mSystemId, mInternalSubset);
|
||||
return new (aNodeInfo) nsDOMDocumentType(aNodeInfo, mName, mEntities,
|
||||
mNotations, mPublicId, mSystemId,
|
||||
mInternalSubset);
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
|
|
@ -769,6 +769,7 @@ nsDOMImplementation::Init(nsIURI* aDocumentURI, nsIURI* aBaseURI,
|
|||
|
||||
nsDocument::nsDocument(const char* aContentType)
|
||||
: nsIDocument(),
|
||||
mChildren(nsnull),
|
||||
mVisible(PR_TRUE)
|
||||
{
|
||||
nsLayoutStatics::AddRef();
|
||||
|
@ -1105,6 +1106,19 @@ nsDocument::Init()
|
|||
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);
|
||||
|
||||
|
@ -1125,17 +1139,6 @@ nsDocument::Init()
|
|||
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);
|
||||
|
@ -1144,6 +1147,13 @@ nsDocument::Init()
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
nsINode::nsSlots*
|
||||
nsDocument::CreateSlots()
|
||||
{
|
||||
return
|
||||
new (mNodeInfo->NodeInfoManager()->NodeAllocator()) nsSlots(mFlagsOrSlots);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDocument::AddXMLEventsContent(nsIContent *aXMLEventsElement)
|
||||
{
|
||||
|
@ -3124,7 +3134,7 @@ nsDocument::CreateAttribute(const nsAString& aName,
|
|||
getter_AddRefs(nodeInfo));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
attribute = new nsDOMAttribute(nsnull, nodeInfo, value);
|
||||
attribute = new (nodeInfo) nsDOMAttribute(nsnull, nodeInfo, value);
|
||||
NS_ENSURE_TRUE(attribute, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
return CallQueryInterface(attribute, aReturn);
|
||||
|
@ -3146,7 +3156,8 @@ nsDocument::CreateAttributeNS(const nsAString & aNamespaceURI,
|
|||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsAutoString value;
|
||||
nsDOMAttribute* attribute = new nsDOMAttribute(nsnull, nodeInfo, value);
|
||||
nsDOMAttribute* attribute =
|
||||
new (nodeInfo) nsDOMAttribute(nsnull, nodeInfo, value);
|
||||
NS_ENSURE_TRUE(attribute, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
return CallQueryInterface(attribute, aResult);
|
||||
|
|
|
@ -536,6 +536,7 @@ public:
|
|||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
virtual nsDOMNodeAllocator* GetAllocator() { return nsnull; }
|
||||
|
||||
// nsIRadioGroupContainer
|
||||
NS_IMETHOD WalkRadioGroup(const nsAString& aName,
|
||||
|
@ -658,6 +659,7 @@ public:
|
|||
const nsAString& aClasses,
|
||||
nsIDOMNodeList** aReturn);
|
||||
protected:
|
||||
virtual nsINode::nsSlots* CreateSlots();
|
||||
|
||||
/**
|
||||
* Check that aId is not empty and log a message to the console
|
||||
|
|
|
@ -171,7 +171,7 @@ NS_NewDocumentFragment(nsIDOMDocumentFragment** aInstancePtrResult,
|
|||
getter_AddRefs(nodeInfo));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsDocumentFragment *it = new nsDocumentFragment(nodeInfo);
|
||||
nsDocumentFragment *it = new (nodeInfo) nsDocumentFragment(nodeInfo);
|
||||
if (!it) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
|
|
@ -81,7 +81,7 @@ NS_NewGenConImageContent(nsIContent** aResult, nsINodeInfo* aNodeInfo,
|
|||
imgIRequest* aImageRequest)
|
||||
{
|
||||
NS_PRECONDITION(aImageRequest, "Must have request!");
|
||||
nsGenConImageContent *it = new nsGenConImageContent(aNodeInfo);
|
||||
nsGenConImageContent *it = new (aNodeInfo) nsGenConImageContent(aNodeInfo);
|
||||
if (!it)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
NS_ADDREF(*aResult = it);
|
||||
|
|
|
@ -66,7 +66,7 @@
|
|||
#include "prprf.h"
|
||||
|
||||
nsGenericDOMDataNode::nsGenericDOMDataNode(nsINodeInfo *aNodeInfo)
|
||||
: nsIContent(aNodeInfo)
|
||||
: nsIContent(aNodeInfo), mText(aNodeInfo->NodeInfoManager()->NodeAllocator())
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -864,7 +864,7 @@ nsGenericDOMDataNode::IsLink(nsIURI** aURI) const
|
|||
nsINode::nsSlots*
|
||||
nsGenericDOMDataNode::CreateSlots()
|
||||
{
|
||||
return new nsDataSlots(mFlagsOrSlots);
|
||||
return new (GetAllocator()) nsDataSlots(mFlagsOrSlots);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
|
|
@ -187,6 +187,7 @@ public:
|
|||
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,
|
||||
|
|
|
@ -171,8 +171,44 @@ nsINode::nsSlots::~nsSlots()
|
|||
}
|
||||
}
|
||||
|
||||
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?");
|
||||
|
@ -276,7 +312,7 @@ nsGenericElement::GetSystemEventGroup(nsIDOMEventGroup** aGroup)
|
|||
nsINode::nsSlots*
|
||||
nsINode::CreateSlots()
|
||||
{
|
||||
return new nsSlots(mFlagsOrSlots);
|
||||
return new (GetAllocator()) nsSlots(mFlagsOrSlots);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1094,7 +1130,8 @@ nsGenericElement::nsDOMSlots::~nsDOMSlots()
|
|||
}
|
||||
|
||||
nsGenericElement::nsGenericElement(nsINodeInfo *aNodeInfo)
|
||||
: nsIContent(aNodeInfo)
|
||||
: nsIContent(aNodeInfo),
|
||||
mAttrsAndChildren(aNodeInfo->NodeInfoManager()->NodeAllocator())
|
||||
{
|
||||
// Set the default scriptID to JS - but skip SetScriptTypeID as it
|
||||
// does extra work we know isn't necessary here...
|
||||
|
@ -4170,7 +4207,7 @@ nsGenericElement::IndexOf(nsINode* aPossibleChild) const
|
|||
nsINode::nsSlots*
|
||||
nsGenericElement::CreateSlots()
|
||||
{
|
||||
return new nsDOMSlots(mFlagsOrSlots);
|
||||
return new (GetAllocator()) nsDOMSlots(mFlagsOrSlots);
|
||||
}
|
||||
|
||||
PRBool
|
||||
|
|
|
@ -376,6 +376,10 @@ public:
|
|||
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,
|
||||
|
@ -1010,7 +1014,7 @@ _elementName::Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const \
|
|||
{ \
|
||||
*aResult = nsnull; \
|
||||
\
|
||||
_elementName *it = new _elementName(aNodeInfo); \
|
||||
_elementName *it = new (aNodeInfo) _elementName(aNodeInfo); \
|
||||
if (!it) { \
|
||||
return NS_ERROR_OUT_OF_MEMORY; \
|
||||
} \
|
||||
|
@ -1030,7 +1034,7 @@ _elementName::Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const \
|
|||
{ \
|
||||
*aResult = nsnull; \
|
||||
\
|
||||
_elementName *it = new _elementName(aNodeInfo); \
|
||||
_elementName *it = new (aNodeInfo) _elementName(aNodeInfo); \
|
||||
if (!it) { \
|
||||
return NS_ERROR_OUT_OF_MEMORY; \
|
||||
} \
|
||||
|
|
|
@ -51,6 +51,146 @@
|
|||
#include "nsReadableUtils.h"
|
||||
#include "nsGkAtoms.h"
|
||||
#include "nsComponentManagerUtils.h"
|
||||
#include "prbit.h"
|
||||
#include "plarena.h"
|
||||
#include "nsMemory.h"
|
||||
|
||||
#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 (mPool) {
|
||||
PL_FinishArenaPool(mPool);
|
||||
delete mPool;
|
||||
}
|
||||
#ifdef DEBUG
|
||||
--gDOMNodeAllocators;
|
||||
#endif
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDOMNodeAllocator::Init()
|
||||
{
|
||||
#ifdef DEBUG
|
||||
++gDOMNodeAllocators;
|
||||
#endif
|
||||
mPool = new PLArenaPool();
|
||||
NS_ENSURE_TRUE(mPool, NS_ERROR_OUT_OF_MEMORY);
|
||||
PL_InitArenaPool(mPool, "nsDOMNodeAllocator", 4096 * (sizeof(void*)/2), 0);
|
||||
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) {
|
||||
// Allocate a new chunk from the arena
|
||||
PL_ARENA_ALLOCATE(result, mPool, 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
|
||||
}
|
||||
|
||||
PRUint32 nsNodeInfoManager::gNodeManagerCount;
|
||||
|
||||
|
@ -154,6 +294,10 @@ 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",
|
||||
|
|
|
@ -44,6 +44,8 @@
|
|||
|
||||
#include "nsCOMPtr.h" // for already_AddRefed
|
||||
#include "plhash.h"
|
||||
#include "prlog.h"
|
||||
#include "nsAutoPtr.h"
|
||||
|
||||
class nsIAtom;
|
||||
class nsIDocument;
|
||||
|
@ -57,6 +59,39 @@ 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() : mPool(nsnull) {}
|
||||
~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* mPool;
|
||||
// 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
|
||||
{
|
||||
|
@ -123,6 +158,7 @@ public:
|
|||
|
||||
void RemoveNodeInfo(nsNodeInfo *aNodeInfo);
|
||||
|
||||
nsDOMNodeAllocator* NodeAllocator() { return mNodeAllocator; }
|
||||
protected:
|
||||
friend class nsDocument;
|
||||
friend class nsXULPrototypeDocument;
|
||||
|
@ -159,6 +195,8 @@ private:
|
|||
nsINodeInfo *mCommentNodeInfo; // WEAK to avoid circular ownership
|
||||
nsINodeInfo *mDocumentNodeInfo; // WEAK to avoid circular ownership
|
||||
|
||||
nsRefPtr<nsDOMNodeAllocator> mNodeAllocator;
|
||||
|
||||
static PRUint32 gNodeManagerCount;
|
||||
};
|
||||
|
||||
|
|
|
@ -188,6 +188,7 @@ 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,
|
||||
|
@ -196,7 +197,14 @@ nsNodeUtils::LastRelease(nsINode* aNode)
|
|||
}
|
||||
|
||||
PtrBits flags = slots->mFlags | NODE_DOESNT_HAVE_SLOTS;
|
||||
delete 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);
|
||||
aNode->mFlagsOrSlots = flags;
|
||||
}
|
||||
|
||||
|
@ -235,7 +243,15 @@ nsNodeUtils::LastRelease(nsINode* aNode)
|
|||
aNode->UnsetFlags(NODE_HAS_LISTENERMANAGER);
|
||||
}
|
||||
|
||||
delete aNode;
|
||||
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));
|
||||
NS_RELEASE(allocator);
|
||||
}
|
||||
}
|
||||
|
||||
static nsresult
|
||||
|
|
|
@ -45,9 +45,9 @@
|
|||
#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
|
||||
|
@ -102,16 +102,27 @@ nsTextFragment::Shutdown()
|
|||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
nsMemory::Free(m2b); // m1b == m2b as far as nsMemory is concerned
|
||||
// m1b == m2b as far as memory is concerned
|
||||
mAllocator->Free(mState.mLength *
|
||||
(mState.mIs2b ? sizeof(PRUnichar) : sizeof(char)),
|
||||
m2b);
|
||||
}
|
||||
|
||||
m1b = nsnull;
|
||||
|
@ -120,6 +131,16 @@ nsTextFragment::ReleaseText()
|
|||
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)
|
||||
{
|
||||
|
@ -130,9 +151,11 @@ nsTextFragment::operator=(const nsTextFragment& aOther)
|
|||
m1b = aOther.m1b; // This will work even if aOther is using m2b
|
||||
}
|
||||
else {
|
||||
m2b = static_cast<PRUnichar*>
|
||||
(nsMemory::Clone(aOther.m2b, aOther.mState.mLength *
|
||||
(aOther.mState.mIs2b ? sizeof(PRUnichar) : sizeof(char))));
|
||||
m2b =
|
||||
static_cast<PRUnichar*>
|
||||
(CloneMemory(aOther.m2b, aOther.mState.mLength *
|
||||
(aOther.mState.mIs2b ?
|
||||
sizeof(PRUnichar) : sizeof(char))));
|
||||
}
|
||||
|
||||
if (m1b) {
|
||||
|
@ -213,14 +236,13 @@ nsTextFragment::SetTo(const PRUnichar* aBuffer, PRInt32 aLength)
|
|||
|
||||
if (need2) {
|
||||
// Use ucs2 storage because we have to
|
||||
m2b = (PRUnichar *)nsMemory::Clone(aBuffer,
|
||||
aLength * sizeof(PRUnichar));
|
||||
m2b = (PRUnichar *)CloneMemory(aBuffer, aLength * sizeof(PRUnichar));
|
||||
if (!m2b) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
// Use 1 byte storage because we can
|
||||
char* buff = (char *)nsMemory::Alloc(aLength * sizeof(char));
|
||||
char* buff = (char *)mAllocator->Alloc(aLength * sizeof(char));
|
||||
if (!buff) {
|
||||
return;
|
||||
}
|
||||
|
@ -301,15 +323,20 @@ nsTextFragment::Append(const PRUnichar* aBuffer, PRUint32 aLength)
|
|||
|
||||
if (mState.mIs2b) {
|
||||
// Already a 2-byte string so the result will be too
|
||||
PRUnichar* buff = (PRUnichar*)nsMemory::Realloc(m2b, (mState.mLength + aLength) * sizeof(PRUnichar));
|
||||
PRUnichar* buff =
|
||||
(PRUnichar*)mAllocator->Alloc((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;
|
||||
}
|
||||
|
||||
|
@ -329,8 +356,8 @@ nsTextFragment::Append(const PRUnichar* aBuffer, PRUint32 aLength)
|
|||
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*)nsMemory::Alloc((mState.mLength + aLength) *
|
||||
sizeof(PRUnichar));
|
||||
PRUnichar* buff = (PRUnichar*)mAllocator->Alloc((mState.mLength + aLength) *
|
||||
sizeof(PRUnichar));
|
||||
if (!buff) {
|
||||
return;
|
||||
}
|
||||
|
@ -342,42 +369,34 @@ nsTextFragment::Append(const PRUnichar* aBuffer, PRUint32 aLength)
|
|||
|
||||
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;
|
||||
if (mState.mInHeap) {
|
||||
buff = (char*)nsMemory::Realloc(const_cast<char*>(m1b),
|
||||
(mState.mLength + aLength) * sizeof(char));
|
||||
if (!buff) {
|
||||
return;
|
||||
}
|
||||
char* buff =
|
||||
(char*)mAllocator->Alloc((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);
|
||||
mState.mInHeap = PR_TRUE;
|
||||
}
|
||||
|
||||
memcpy(buff, m1b, mState.mLength);
|
||||
|
||||
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;
|
||||
|
||||
|
|
|
@ -47,6 +47,7 @@
|
|||
#include "nsAString.h"
|
||||
class nsString;
|
||||
class nsCString;
|
||||
class nsDOMNodeAllocator;
|
||||
|
||||
// XXX should this normalize the code to keep a \u0000 at the end?
|
||||
|
||||
|
@ -85,14 +86,12 @@ public:
|
|||
/**
|
||||
* Default constructor. Initialize the fragment to be empty.
|
||||
*/
|
||||
nsTextFragment()
|
||||
: m1b(nsnull), mAllBits(0)
|
||||
{
|
||||
NS_ASSERTION(sizeof(FragmentBits) == 4, "Bad field packing!");
|
||||
}
|
||||
nsTextFragment(nsDOMNodeAllocator* aAllocator);
|
||||
|
||||
~nsTextFragment();
|
||||
|
||||
nsDOMNodeAllocator* Allocator() { return mAllocator; }
|
||||
|
||||
/**
|
||||
* Change the contents of this fragment to be a copy of the
|
||||
* the argument fragment.
|
||||
|
@ -205,6 +204,7 @@ public:
|
|||
|
||||
private:
|
||||
void ReleaseText();
|
||||
void* CloneMemory(const void* aPtr, PRSize aSize);
|
||||
|
||||
union {
|
||||
PRUnichar *m2b;
|
||||
|
@ -215,6 +215,7 @@ private:
|
|||
PRUint32 mAllBits;
|
||||
FragmentBits mState;
|
||||
};
|
||||
nsDOMNodeAllocator* mAllocator;
|
||||
};
|
||||
|
||||
#endif /* nsTextFragment_h___ */
|
||||
|
|
|
@ -114,9 +114,9 @@ public:
|
|||
virtual nsGenericDOMDataNode *CloneDataNode(nsINodeInfo *aNodeInfo,
|
||||
PRBool aCloneText) const
|
||||
{
|
||||
nsAttributeTextNode *it = new nsAttributeTextNode(aNodeInfo,
|
||||
mNameSpaceID,
|
||||
mAttrName);
|
||||
nsAttributeTextNode *it = new (aNodeInfo) nsAttributeTextNode(aNodeInfo,
|
||||
mNameSpaceID,
|
||||
mAttrName);
|
||||
if (it && aCloneText) {
|
||||
it->mText = mText;
|
||||
}
|
||||
|
@ -154,7 +154,7 @@ NS_NewTextNode(nsIContent** aInstancePtrResult,
|
|||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
nsIContent *instance = new nsTextNode(ni);
|
||||
nsIContent *instance = new (ni) nsTextNode(ni);
|
||||
if (!instance) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
@ -220,7 +220,7 @@ nsTextNode::IsNodeOfType(PRUint32 aFlags) const
|
|||
nsGenericDOMDataNode*
|
||||
nsTextNode::CloneDataNode(nsINodeInfo *aNodeInfo, PRBool aCloneText) const
|
||||
{
|
||||
nsTextNode *it = new nsTextNode(aNodeInfo);
|
||||
nsTextNode *it = new (aNodeInfo) nsTextNode(aNodeInfo);
|
||||
if (it && aCloneText) {
|
||||
it->mText = mText;
|
||||
}
|
||||
|
@ -280,8 +280,8 @@ NS_NewAttributeContent(nsNodeInfoManager *aNodeInfoManager,
|
|||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
nsAttributeTextNode* textNode = new nsAttributeTextNode(ni, aNameSpaceID,
|
||||
aAttrName);
|
||||
nsAttributeTextNode* textNode = new (ni) nsAttributeTextNode(ni, aNameSpaceID,
|
||||
aAttrName);
|
||||
if (!textNode) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
|
|
@ -87,7 +87,7 @@ NS_IMPL_ELEMENT_CLONE(nsXMLEventsElement)
|
|||
nsresult
|
||||
NS_NewXMLEventsElement(nsIContent** aInstancePtrResult, nsINodeInfo *aNodeInfo)
|
||||
{
|
||||
nsXMLEventsElement* it = new nsXMLEventsElement(aNodeInfo);
|
||||
nsXMLEventsElement* it = new (aNodeInfo) nsXMLEventsElement(aNodeInfo);
|
||||
if (!it) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
|
|
@ -235,7 +235,6 @@ public:
|
|||
nsresult GetHrefURIForAnchors(nsIURI** aURI) const;
|
||||
|
||||
// HTML element methods
|
||||
void Compact() { mAttrsAndChildren.Compact(); }
|
||||
const nsAttrValue* GetParsedAttr(nsIAtom* aAttr) const
|
||||
{
|
||||
return mAttrsAndChildren.GetAttr(aAttr);
|
||||
|
@ -960,14 +959,15 @@ protected:
|
|||
nsGenericHTMLElement* \
|
||||
NS_NewHTML##_elementName##Element(nsINodeInfo *aNodeInfo, PRBool aFromParser)\
|
||||
{ \
|
||||
return new nsHTML##_elementName##Element(aNodeInfo); \
|
||||
return new (aNodeInfo) 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 nsHTML##_elementName##Element(aNodeInfo, aFromParser); \
|
||||
return \
|
||||
new (aNodeInfo) nsHTML##_elementName##Element(aNodeInfo, aFromParser); \
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -135,7 +135,7 @@ public:
|
|||
nsGenericHTMLElement*
|
||||
NS_NewHTMLCanvasElement(nsINodeInfo *aNodeInfo, PRBool aFromParser)
|
||||
{
|
||||
return new nsHTMLCanvasElement(aNodeInfo);
|
||||
return new (aNodeInfo) nsHTMLCanvasElement(aNodeInfo);
|
||||
}
|
||||
|
||||
nsHTMLCanvasElement::nsHTMLCanvasElement(nsINodeInfo *aNodeInfo)
|
||||
|
|
|
@ -461,7 +461,7 @@ ShouldBeInElements(nsIFormControl* aFormControl)
|
|||
nsGenericHTMLElement*
|
||||
NS_NewHTMLFormElement(nsINodeInfo *aNodeInfo, PRBool aFromParser)
|
||||
{
|
||||
nsHTMLFormElement* it = new nsHTMLFormElement(aNodeInfo);
|
||||
nsHTMLFormElement* it = new (aNodeInfo) nsHTMLFormElement(aNodeInfo);
|
||||
if (!it) {
|
||||
return nsnull;
|
||||
}
|
||||
|
|
|
@ -172,7 +172,7 @@ NS_NewHTMLImageElement(nsINodeInfo *aNodeInfo, PRBool aFromParser)
|
|||
NS_ENSURE_SUCCESS(rv, nsnull);
|
||||
}
|
||||
|
||||
return new nsHTMLImageElement(nodeInfo);
|
||||
return new (nodeInfo) nsHTMLImageElement(nodeInfo);
|
||||
}
|
||||
|
||||
nsHTMLImageElement::nsHTMLImageElement(nsINodeInfo *aNodeInfo)
|
||||
|
|
|
@ -430,7 +430,8 @@ nsHTMLInputElement::Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const
|
|||
{
|
||||
*aResult = nsnull;
|
||||
|
||||
nsHTMLInputElement *it = new nsHTMLInputElement(aNodeInfo, PR_FALSE);
|
||||
nsHTMLInputElement *it =
|
||||
new (aNodeInfo) nsHTMLInputElement(aNodeInfo, PR_FALSE);
|
||||
if (!it) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
|
|
@ -157,7 +157,7 @@ NS_NewHTMLOptionElement(nsINodeInfo *aNodeInfo, PRBool aFromParser)
|
|||
NS_ENSURE_SUCCESS(rv, nsnull);
|
||||
}
|
||||
|
||||
return new nsHTMLOptionElement(nodeInfo);
|
||||
return new (nodeInfo) nsHTMLOptionElement(nodeInfo);
|
||||
}
|
||||
|
||||
nsHTMLOptionElement::nsHTMLOptionElement(nsINodeInfo *aNodeInfo)
|
||||
|
|
|
@ -420,7 +420,8 @@ nsHTMLScriptElement::Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const
|
|||
{
|
||||
*aResult = nsnull;
|
||||
|
||||
nsHTMLScriptElement* it = new nsHTMLScriptElement(aNodeInfo, PR_FALSE);
|
||||
nsHTMLScriptElement* it =
|
||||
new (aNodeInfo) nsHTMLScriptElement(aNodeInfo, PR_FALSE);
|
||||
if (!it) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
|
|
@ -931,7 +931,6 @@ SinkContext::CloseContainer(const nsHTMLTag aTag, PRBool aMalformed)
|
|||
|
||||
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
|
||||
|
|
|
@ -97,7 +97,9 @@ nsSVGEnumMapping nsSVGElement::sSVGUnitTypesMap[] = {
|
|||
};
|
||||
|
||||
nsSVGElement::nsSVGElement(nsINodeInfo *aNodeInfo)
|
||||
: nsSVGElementBase(aNodeInfo), mSuppressNotification(PR_FALSE)
|
||||
: nsSVGElementBase(aNodeInfo),
|
||||
mMappedAttributes(aNodeInfo->NodeInfoManager()->NodeAllocator()),
|
||||
mSuppressNotification(PR_FALSE)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -313,7 +313,7 @@ NS_NewSVG##_elementName##Element(nsIContent **aResult, \
|
|||
nsINodeInfo *aNodeInfo) \
|
||||
{ \
|
||||
nsSVG##_elementName##Element *it = \
|
||||
new nsSVG##_elementName##Element(aNodeInfo); \
|
||||
new (aNodeInfo) nsSVG##_elementName##Element(aNodeInfo); \
|
||||
if (!it) \
|
||||
return NS_ERROR_OUT_OF_MEMORY; \
|
||||
\
|
||||
|
|
|
@ -133,7 +133,7 @@ nsSVGUseElement::Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const
|
|||
{
|
||||
*aResult = nsnull;
|
||||
|
||||
nsSVGUseElement *it = new nsSVGUseElement(aNodeInfo);
|
||||
nsSVGUseElement *it = new (aNodeInfo) nsSVGUseElement(aNodeInfo);
|
||||
if (!it) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
|
|
@ -86,7 +86,7 @@ NS_NewXMLCDATASection(nsIContent** aInstancePtrResult,
|
|||
getter_AddRefs(ni));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsXMLCDATASection *instance = new nsXMLCDATASection(ni);
|
||||
nsXMLCDATASection *instance = new (ni) nsXMLCDATASection(ni);
|
||||
if (!instance) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
@ -154,7 +154,7 @@ nsXMLCDATASection::GetNodeType(PRUint16* aNodeType)
|
|||
nsGenericDOMDataNode*
|
||||
nsXMLCDATASection::CloneDataNode(nsINodeInfo *aNodeInfo, PRBool aCloneText) const
|
||||
{
|
||||
nsXMLCDATASection *it = new nsXMLCDATASection(aNodeInfo);
|
||||
nsXMLCDATASection *it = new (aNodeInfo) nsXMLCDATASection(aNodeInfo);
|
||||
if (it && aCloneText) {
|
||||
it->mText = mText;
|
||||
}
|
||||
|
|
|
@ -47,7 +47,7 @@
|
|||
nsresult
|
||||
NS_NewXMLElement(nsIContent** aInstancePtrResult, nsINodeInfo *aNodeInfo)
|
||||
{
|
||||
nsXMLElement* it = new nsXMLElement(aNodeInfo);
|
||||
nsXMLElement* it = new (aNodeInfo) nsXMLElement(aNodeInfo);
|
||||
if (!it) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
|
|
@ -65,7 +65,7 @@ NS_NewXMLProcessingInstruction(nsIContent** aInstancePtrResult,
|
|||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsXMLProcessingInstruction *instance =
|
||||
new nsXMLProcessingInstruction(ni, aTarget, aData);
|
||||
new (ni) nsXMLProcessingInstruction(ni, aTarget, aData);
|
||||
if (!instance) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
@ -176,7 +176,7 @@ nsXMLProcessingInstruction::CloneDataNode(nsINodeInfo *aNodeInfo,
|
|||
nsAutoString data;
|
||||
nsGenericDOMDataNode::GetData(data);
|
||||
|
||||
return new nsXMLProcessingInstruction(aNodeInfo, mTarget, data);
|
||||
return new (aNodeInfo) nsXMLProcessingInstruction(aNodeInfo, mTarget, data);
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
|
|
|
@ -246,7 +246,7 @@ nsXMLStylesheetPI::CloneDataNode(nsINodeInfo *aNodeInfo, PRBool aCloneText) cons
|
|||
nsAutoString data;
|
||||
nsGenericDOMDataNode::GetData(data);
|
||||
|
||||
return new nsXMLStylesheetPI(aNodeInfo, data);
|
||||
return new (aNodeInfo) nsXMLStylesheetPI(aNodeInfo, data);
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
@ -265,7 +265,7 @@ NS_NewXMLStylesheetProcessingInstruction(nsIContent** aInstancePtrResult,
|
|||
getter_AddRefs(ni));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsXMLStylesheetPI *instance = new nsXMLStylesheetPI(ni, aData);
|
||||
nsXMLStylesheetPI *instance = new (ni) nsXMLStylesheetPI(ni, aData);
|
||||
if (!instance) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
|
|
@ -1003,7 +1003,8 @@ NS_NewXTFElementWrapper(nsIXTFElement* aXTFElement,
|
|||
*aResult = nsnull;
|
||||
NS_ENSURE_ARG(aXTFElement);
|
||||
|
||||
nsXTFElementWrapper* result = new nsXTFElementWrapper(aNodeInfo, aXTFElement);
|
||||
nsXTFElementWrapper* result =
|
||||
new (aNodeInfo) nsXTFElementWrapper(aNodeInfo, aXTFElement);
|
||||
if (!result) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
|
|
@ -262,7 +262,7 @@ nsXULElement::nsXULSlots::~nsXULSlots()
|
|||
nsINode::nsSlots*
|
||||
nsXULElement::CreateSlots()
|
||||
{
|
||||
return new nsXULSlots(mFlagsOrSlots);
|
||||
return new (GetAllocator()) nsXULSlots(mFlagsOrSlots);
|
||||
}
|
||||
|
||||
/* static */
|
||||
|
@ -270,7 +270,7 @@ already_AddRefed<nsXULElement>
|
|||
nsXULElement::Create(nsXULPrototypeElement* aPrototype, nsINodeInfo *aNodeInfo,
|
||||
PRBool aIsScriptable)
|
||||
{
|
||||
nsXULElement *element = new nsXULElement(aNodeInfo);
|
||||
nsXULElement *element = new (aNodeInfo) nsXULElement(aNodeInfo);
|
||||
if (element) {
|
||||
NS_ADDREF(element);
|
||||
|
||||
|
@ -351,7 +351,7 @@ NS_NewXULElement(nsIContent** aResult, nsINodeInfo *aNodeInfo)
|
|||
*aResult = nsnull;
|
||||
|
||||
// Create an nsXULElement with the specified namespace and tag.
|
||||
nsXULElement* element = new nsXULElement(aNodeInfo);
|
||||
nsXULElement* element = new (aNodeInfo) nsXULElement(aNodeInfo);
|
||||
NS_ENSURE_TRUE(element, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
NS_ADDREF(*aResult = element);
|
||||
|
@ -431,7 +431,7 @@ nsXULElement::Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const
|
|||
"Didn't get the default language from proto?");
|
||||
}
|
||||
else {
|
||||
element = new nsXULElement(aNodeInfo);
|
||||
element = new (aNodeInfo) nsXULElement(aNodeInfo);
|
||||
if (element) {
|
||||
// If created from a prototype, we will already have the script
|
||||
// language specified by the proto - otherwise copy it directly
|
||||
|
|
Загрузка…
Ссылка в новой задаче