Bug 581177 part 2. Separate mParent from the flags it used to cohabit with. r=sicking

This commit is contained in:
Boris Zbarsky 2011-04-07 19:29:49 -07:00
parent f9a250840a
commit 855cef779c
5 changed files with 84 additions and 32 deletions

View File

@ -166,7 +166,7 @@ public:
mIsBeingUsedAsImage(PR_FALSE), mIsBeingUsedAsImage(PR_FALSE),
mPartID(0) mPartID(0)
{ {
mParentPtrBits |= PARENT_BIT_INDOCUMENT; SetInDocument();
} }
#endif #endif

View File

@ -315,12 +315,12 @@ public:
#ifdef MOZILLA_INTERNAL_API #ifdef MOZILLA_INTERNAL_API
nsINode(already_AddRefed<nsINodeInfo> aNodeInfo) nsINode(already_AddRefed<nsINodeInfo> aNodeInfo)
: mNodeInfo(aNodeInfo), : mNodeInfo(aNodeInfo),
mParentPtrBits(0), mParent(nsnull),
mFlags(0), mFlags(0),
mBoolFlags(0),
mNextSibling(nsnull), mNextSibling(nsnull),
mPreviousSibling(nsnull), mPreviousSibling(nsnull),
mFirstChild(nsnull), mFirstChild(nsnull),
mNodeHasRenderingObservers(false),
mSlots(nsnull) mSlots(nsnull)
{ {
} }
@ -433,9 +433,9 @@ public:
* *
* @return whether this content is in a document tree * @return whether this content is in a document tree
*/ */
PRBool IsInDoc() const bool IsInDoc() const
{ {
return mParentPtrBits & PARENT_BIT_INDOCUMENT; return GetBoolFlag(IsInDocument);
} }
/** /**
@ -704,13 +704,11 @@ public:
/** /**
* Get the parent nsIContent for this node. * Get the parent nsIContent for this node.
* @return the parent, or null if no parent or the parent is not an nsIContent * @return the parent, or null if no parent or the parent is not an nsIContent
* Implemented in nsIContent.h
*/ */
nsIContent* GetParent() const nsIContent* GetParent() const {
{ return NS_LIKELY(GetBoolFlag(ParentIsContent)) ?
return NS_LIKELY(mParentPtrBits & PARENT_BIT_PARENT_IS_CONTENT) ? reinterpret_cast<nsIContent*>(mParent) : nsnull;
reinterpret_cast<nsIContent*>
(mParentPtrBits & ~kParentBitMask) :
nsnull;
} }
/** /**
@ -720,7 +718,7 @@ public:
*/ */
nsINode* GetNodeParent() const nsINode* GetNodeParent() const
{ {
return reinterpret_cast<nsINode*>(mParentPtrBits & ~kParentBitMask); return mParent;
} }
/** /**
@ -1136,9 +1134,53 @@ public:
NS_NOTREACHED("How did we get here?"); NS_NOTREACHED("How did we get here?");
} }
bool HasRenderingObservers() { return mNodeHasRenderingObservers; } /**
* Boolean flags
*/
private:
enum BooleanFlag {
// Set if we're being used from -moz-element
NodeHasRenderingObservers,
// Set if our parent chain (including this node itself) terminates
// in a document
IsInDocument,
// Set if mParent is an nsIContent
ParentIsContent,
BooleanFlagCount
};
void SetBoolFlag(BooleanFlag name, bool value) {
PR_STATIC_ASSERT(BooleanFlagCount <= 8*sizeof(mBoolFlags));
mBoolFlags = (mBoolFlags & ~(1 << name)) | (value << name);
}
void SetBoolFlag(BooleanFlag name) {
PR_STATIC_ASSERT(BooleanFlagCount <= 8*sizeof(mBoolFlags));
mBoolFlags |= (1 << name);
}
void ClearBoolFlag(BooleanFlag name) {
PR_STATIC_ASSERT(BooleanFlagCount <= 8*sizeof(mBoolFlags));
mBoolFlags &= ~(1 << name);
}
bool GetBoolFlag(BooleanFlag name) const {
PR_STATIC_ASSERT(BooleanFlagCount <= 8*sizeof(mBoolFlags));
return mBoolFlags & (1 << name);
}
public:
bool HasRenderingObservers() const
{ return GetBoolFlag(NodeHasRenderingObservers); }
void SetHasRenderingObservers(bool aValue) void SetHasRenderingObservers(bool aValue)
{ mNodeHasRenderingObservers = aValue; } { SetBoolFlag(NodeHasRenderingObservers, aValue); }
protected:
void SetParentIsContent(bool aValue) { SetBoolFlag(ParentIsContent, aValue); }
void SetInDocument() { SetBoolFlag(IsInDocument); }
void ClearInDocument() { ClearBoolFlag(IsInDocument); }
public:
// Optimized way to get classinfo. // Optimized way to get classinfo.
virtual nsXPCClassInfo* GetClassInfo() = 0; virtual nsXPCClassInfo* GetClassInfo() = 0;
@ -1244,20 +1286,19 @@ protected:
nsCOMPtr<nsINodeInfo> mNodeInfo; nsCOMPtr<nsINodeInfo> mNodeInfo;
enum { PARENT_BIT_INDOCUMENT = 1 << 0, PARENT_BIT_PARENT_IS_CONTENT = 1 << 1 }; nsINode* mParent;
enum { kParentBitMask = 0x3 };
PtrBits mParentPtrBits;
PRUint32 mFlags; PRUint32 mFlags;
private:
// Boolean flags.
PRUint32 mBoolFlags;
protected:
nsIContent* mNextSibling; nsIContent* mNextSibling;
nsIContent* mPreviousSibling; nsIContent* mPreviousSibling;
nsIContent* mFirstChild; nsIContent* mFirstChild;
// More flags
bool mNodeHasRenderingObservers : 1;
// Storage for more members that are usually not needed; allocated lazily. // Storage for more members that are usually not needed; allocated lazily.
nsSlots* mSlots; nsSlots* mSlots;
}; };

View File

@ -523,19 +523,19 @@ nsGenericDOMDataNode::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
// Set parent // Set parent
if (aParent) { if (aParent) {
mParentPtrBits = mParent = aParent;
reinterpret_cast<PtrBits>(aParent) | PARENT_BIT_PARENT_IS_CONTENT;
} }
else { else {
mParentPtrBits = reinterpret_cast<PtrBits>(aDocument); mParent = aDocument;
} }
SetParentIsContent(aParent);
// XXXbz sXBL/XBL2 issue! // XXXbz sXBL/XBL2 issue!
// Set document // Set document
if (aDocument) { if (aDocument) {
// XXX See the comment in nsGenericElement::BindToTree // XXX See the comment in nsGenericElement::BindToTree
mParentPtrBits |= PARENT_BIT_INDOCUMENT; SetInDocument();
if (mText.IsBidi()) { if (mText.IsBidi()) {
aDocument->SetBidiEnabled(); aDocument->SetBidiEnabled();
} }
@ -570,7 +570,11 @@ nsGenericDOMDataNode::UnbindFromTree(PRBool aDeep, PRBool aNullParent)
document->BindingManager()->RemovedFromDocument(this, document); document->BindingManager()->RemovedFromDocument(this, document);
} }
mParentPtrBits = aNullParent ? 0 : mParentPtrBits & ~PARENT_BIT_INDOCUMENT; if (aNullParent) {
mParent = nsnull;
SetParentIsContent(false);
}
ClearInDocument();
nsDataSlots *slots = GetExistingDataSlots(); nsDataSlots *slots = GetExistingDataSlots();
if (slots) { if (slots) {

View File

@ -2943,15 +2943,16 @@ nsGenericElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
// Now set the parent and set the "Force attach xbl" flag if needed. // Now set the parent and set the "Force attach xbl" flag if needed.
if (aParent) { if (aParent) {
mParentPtrBits = reinterpret_cast<PtrBits>(aParent) | PARENT_BIT_PARENT_IS_CONTENT; mParent = aParent;
if (aParent->HasFlag(NODE_FORCE_XBL_BINDINGS)) { if (aParent->HasFlag(NODE_FORCE_XBL_BINDINGS)) {
SetFlags(NODE_FORCE_XBL_BINDINGS); SetFlags(NODE_FORCE_XBL_BINDINGS);
} }
} }
else { else {
mParentPtrBits = reinterpret_cast<PtrBits>(aDocument); mParent = aDocument;
} }
SetParentIsContent(aParent);
// XXXbz sXBL/XBL2 issue! // XXXbz sXBL/XBL2 issue!
@ -2967,7 +2968,7 @@ nsGenericElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
// aDocument); // aDocument);
// Being added to a document. // Being added to a document.
mParentPtrBits |= PARENT_BIT_INDOCUMENT; SetInDocument();
// Unset this flag since we now really are in a document. // Unset this flag since we now really are in a document.
UnsetFlags(NODE_FORCE_XBL_BINDINGS | UnsetFlags(NODE_FORCE_XBL_BINDINGS |
@ -3049,7 +3050,11 @@ nsGenericElement::UnbindFromTree(PRBool aDeep, PRBool aNullParent)
nsIDocument *document = nsIDocument *document =
HasFlag(NODE_FORCE_XBL_BINDINGS) ? GetOwnerDoc() : GetCurrentDoc(); HasFlag(NODE_FORCE_XBL_BINDINGS) ? GetOwnerDoc() : GetCurrentDoc();
mParentPtrBits = aNullParent ? 0 : mParentPtrBits & ~PARENT_BIT_INDOCUMENT; if (aNullParent) {
mParent = nsnull;
SetParentIsContent(false);
}
ClearInDocument();
if (document) { if (document) {
// Notify XBL- & nsIAnonymousContentCreator-generated // Notify XBL- & nsIAnonymousContentCreator-generated

View File

@ -215,7 +215,9 @@ nsTextNode::BindToAttribute(nsIAttribute* aAttr)
NS_ASSERTION(!GetNodeParent(), "Unbind before binding!"); NS_ASSERTION(!GetNodeParent(), "Unbind before binding!");
NS_ASSERTION(HasSameOwnerDoc(aAttr), "Wrong owner document!"); NS_ASSERTION(HasSameOwnerDoc(aAttr), "Wrong owner document!");
mParentPtrBits = reinterpret_cast<PtrBits>(aAttr); mParent = aAttr;
SetParentIsContent(false);
ClearInDocument();
return NS_OK; return NS_OK;
} }
@ -226,7 +228,7 @@ nsTextNode::UnbindFromAttribute()
NS_ASSERTION(GetNodeParent() && NS_ASSERTION(GetNodeParent() &&
GetNodeParent()->IsNodeOfType(nsINode::eATTRIBUTE), GetNodeParent()->IsNodeOfType(nsINode::eATTRIBUTE),
"Use this method only to unbind from an attribute!"); "Use this method only to unbind from an attribute!");
mParentPtrBits = 0; mParent = nsnull;
return NS_OK; return NS_OK;
} }