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),
mPartID(0)
{
mParentPtrBits |= PARENT_BIT_INDOCUMENT;
SetInDocument();
}
#endif

View File

@ -315,12 +315,12 @@ public:
#ifdef MOZILLA_INTERNAL_API
nsINode(already_AddRefed<nsINodeInfo> aNodeInfo)
: mNodeInfo(aNodeInfo),
mParentPtrBits(0),
mParent(nsnull),
mFlags(0),
mBoolFlags(0),
mNextSibling(nsnull),
mPreviousSibling(nsnull),
mFirstChild(nsnull),
mNodeHasRenderingObservers(false),
mSlots(nsnull)
{
}
@ -433,9 +433,9 @@ public:
*
* @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.
* @return the parent, or null if no parent or the parent is not an nsIContent
* Implemented in nsIContent.h
*/
nsIContent* GetParent() const
{
return NS_LIKELY(mParentPtrBits & PARENT_BIT_PARENT_IS_CONTENT) ?
reinterpret_cast<nsIContent*>
(mParentPtrBits & ~kParentBitMask) :
nsnull;
nsIContent* GetParent() const {
return NS_LIKELY(GetBoolFlag(ParentIsContent)) ?
reinterpret_cast<nsIContent*>(mParent) : nsnull;
}
/**
@ -720,7 +718,7 @@ public:
*/
nsINode* GetNodeParent() const
{
return reinterpret_cast<nsINode*>(mParentPtrBits & ~kParentBitMask);
return mParent;
}
/**
@ -1136,9 +1134,53 @@ public:
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)
{ 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.
virtual nsXPCClassInfo* GetClassInfo() = 0;
@ -1244,20 +1286,19 @@ protected:
nsCOMPtr<nsINodeInfo> mNodeInfo;
enum { PARENT_BIT_INDOCUMENT = 1 << 0, PARENT_BIT_PARENT_IS_CONTENT = 1 << 1 };
enum { kParentBitMask = 0x3 };
PtrBits mParentPtrBits;
nsINode* mParent;
PRUint32 mFlags;
private:
// Boolean flags.
PRUint32 mBoolFlags;
protected:
nsIContent* mNextSibling;
nsIContent* mPreviousSibling;
nsIContent* mFirstChild;
// More flags
bool mNodeHasRenderingObservers : 1;
// Storage for more members that are usually not needed; allocated lazily.
nsSlots* mSlots;
};

View File

@ -523,19 +523,19 @@ nsGenericDOMDataNode::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
// Set parent
if (aParent) {
mParentPtrBits =
reinterpret_cast<PtrBits>(aParent) | PARENT_BIT_PARENT_IS_CONTENT;
mParent = aParent;
}
else {
mParentPtrBits = reinterpret_cast<PtrBits>(aDocument);
mParent = aDocument;
}
SetParentIsContent(aParent);
// XXXbz sXBL/XBL2 issue!
// Set document
if (aDocument) {
// XXX See the comment in nsGenericElement::BindToTree
mParentPtrBits |= PARENT_BIT_INDOCUMENT;
SetInDocument();
if (mText.IsBidi()) {
aDocument->SetBidiEnabled();
}
@ -570,7 +570,11 @@ nsGenericDOMDataNode::UnbindFromTree(PRBool aDeep, PRBool aNullParent)
document->BindingManager()->RemovedFromDocument(this, document);
}
mParentPtrBits = aNullParent ? 0 : mParentPtrBits & ~PARENT_BIT_INDOCUMENT;
if (aNullParent) {
mParent = nsnull;
SetParentIsContent(false);
}
ClearInDocument();
nsDataSlots *slots = GetExistingDataSlots();
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.
if (aParent) {
mParentPtrBits = reinterpret_cast<PtrBits>(aParent) | PARENT_BIT_PARENT_IS_CONTENT;
mParent = aParent;
if (aParent->HasFlag(NODE_FORCE_XBL_BINDINGS)) {
SetFlags(NODE_FORCE_XBL_BINDINGS);
}
}
else {
mParentPtrBits = reinterpret_cast<PtrBits>(aDocument);
mParent = aDocument;
}
SetParentIsContent(aParent);
// XXXbz sXBL/XBL2 issue!
@ -2967,7 +2968,7 @@ nsGenericElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
// aDocument);
// Being added to a document.
mParentPtrBits |= PARENT_BIT_INDOCUMENT;
SetInDocument();
// Unset this flag since we now really are in a document.
UnsetFlags(NODE_FORCE_XBL_BINDINGS |
@ -3049,7 +3050,11 @@ nsGenericElement::UnbindFromTree(PRBool aDeep, PRBool aNullParent)
nsIDocument *document =
HasFlag(NODE_FORCE_XBL_BINDINGS) ? GetOwnerDoc() : GetCurrentDoc();
mParentPtrBits = aNullParent ? 0 : mParentPtrBits & ~PARENT_BIT_INDOCUMENT;
if (aNullParent) {
mParent = nsnull;
SetParentIsContent(false);
}
ClearInDocument();
if (document) {
// Notify XBL- & nsIAnonymousContentCreator-generated

View File

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