Make what FindChildWithRules does actually be an MRU cache, and condense some if-else chains over mChild and mEmptyChild. b=335733 r+sr=bzbarsky

git-svn-id: svn://10.0.0.236/trunk@195616 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
dbaron%dbaron.org
2006-04-28 00:09:05 +00:00
parent db9c24c976
commit e981649f18
2 changed files with 57 additions and 84 deletions

View File

@@ -81,14 +81,15 @@ nsStyleContext::nsStyleContext(nsStyleContext* aParent,
mPrevSibling = this;
if (mParent) {
mParent->AddRef();
mParent->AppendChild(this);
mParent->AddChild(this);
}
ApplyStyleFixups(aPresContext);
NS_ASSERTION(NS_STYLE_INHERIT_MASK &
(1 << PRInt32(nsStyleStructID_Length - 1)) != 0,
#define eStyleStruct_LastItem (nsStyleStructID_Length - 1)
NS_ASSERTION(NS_STYLE_INHERIT_MASK & NS_STYLE_INHERIT_BIT(LastItem),
"NS_STYLE_INHERIT_MASK must be bigger, and other bits shifted");
#undef eStyleStruct_LastItem
}
nsStyleContext::~nsStyleContext()
@@ -111,61 +112,41 @@ nsStyleContext::~nsStyleContext()
}
}
void nsStyleContext::AppendChild(nsStyleContext* aChild)
void nsStyleContext::AddChild(nsStyleContext* aChild)
{
if (aChild->mRuleNode->IsRoot()) {
// The child matched no rules.
if (!mEmptyChild) {
mEmptyChild = aChild;
}
else {
aChild->mNextSibling = mEmptyChild;
aChild->mPrevSibling = mEmptyChild->mPrevSibling;
mEmptyChild->mPrevSibling->mNextSibling = aChild;
mEmptyChild->mPrevSibling = aChild;
}
}
else {
if (!mChild) {
mChild = aChild;
}
else {
aChild->mNextSibling = mChild;
aChild->mPrevSibling = mChild->mPrevSibling;
mChild->mPrevSibling->mNextSibling = aChild;
mChild->mPrevSibling = aChild;
}
NS_ASSERTION(aChild->mPrevSibling == aChild &&
aChild->mNextSibling == aChild,
"child already in a child list");
nsStyleContext **list = aChild->mRuleNode->IsRoot() ? &mEmptyChild : &mChild;
// Insert at the beginning of the list. See also FindChildWithRules.
if (*list) {
// Link into existing elements, if there are any.
aChild->mNextSibling = (*list);
aChild->mPrevSibling = (*list)->mPrevSibling;
(*list)->mPrevSibling->mNextSibling = aChild;
(*list)->mPrevSibling = aChild;
}
(*list) = aChild;
}
void nsStyleContext::RemoveChild(nsStyleContext* aChild)
{
NS_PRECONDITION(nsnull != aChild && this == aChild->mParent, "bad argument");
if (aChild->mRuleNode->IsRoot()) { // is empty
if (aChild->mPrevSibling != aChild) { // has siblings
if (mEmptyChild == aChild) {
mEmptyChild = mEmptyChild->mNextSibling;
}
}
else {
NS_ASSERTION(mEmptyChild == aChild, "bad sibling pointers");
mEmptyChild = nsnull;
}
}
else { // isn't empty
if (aChild->mPrevSibling != aChild) { // has siblings
if (mChild == aChild) {
mChild = mChild->mNextSibling;
}
}
else {
NS_ASSERTION(mChild == aChild, "bad sibling pointers");
if (mChild == aChild) {
mChild = nsnull;
}
nsStyleContext **list = aChild->mRuleNode->IsRoot() ? &mEmptyChild : &mChild;
if (aChild->mPrevSibling != aChild) { // has siblings
if ((*list) == aChild) {
(*list) = (*list)->mNextSibling;
}
}
else {
NS_ASSERTION((*list) == aChild, "bad sibling pointers");
(*list) = nsnull;
}
aChild->mPrevSibling->mNextSibling = aChild->mNextSibling;
aChild->mNextSibling->mPrevSibling = aChild->mPrevSibling;
aChild->mNextSibling = aChild;
@@ -179,45 +160,35 @@ nsStyleContext::FindChildWithRules(const nsIAtom* aPseudoTag,
PRUint32 threshold = 10; // The # of siblings we're willing to examine
// before just giving this whole thing up.
nsStyleContext* aResult = nsnull;
nsStyleContext* result = nsnull;
nsStyleContext *list = aRuleNode->IsRoot() ? mEmptyChild : mChild;
if ((nsnull != mChild) || (nsnull != mEmptyChild)) {
nsStyleContext* child;
if (aRuleNode->IsRoot()) {
if (nsnull != mEmptyChild) {
child = mEmptyChild;
do {
if (aPseudoTag == child->mPseudoTag) {
aResult = child;
break;
}
child = child->mNextSibling;
threshold--;
if (threshold == 0)
break;
} while (child != mEmptyChild);
if (list) {
nsStyleContext *child = list;
do {
if (child->mRuleNode == aRuleNode && child->mPseudoTag == aPseudoTag) {
result = child;
break;
}
}
else if (nsnull != mChild) {
child = mChild;
do {
if (child->mRuleNode == aRuleNode && child->mPseudoTag == aPseudoTag) {
aResult = child;
break;
}
child = child->mNextSibling;
threshold--;
if (threshold == 0)
break;
} while (child != mChild);
}
child = child->mNextSibling;
threshold--;
if (threshold == 0)
break;
} while (child != list);
}
if (aResult)
aResult->AddRef();
if (result) {
if (result != list) {
// Move result to the front of the list.
RemoveChild(result);
AddChild(result);
}
return aResult;
// Add reference for the caller.
result->AddRef();
}
return result;
}

View File

@@ -175,14 +175,16 @@ public:
#endif
protected:
NS_HIDDEN_(void) AppendChild(nsStyleContext* aChild);
NS_HIDDEN_(void) AddChild(nsStyleContext* aChild);
NS_HIDDEN_(void) RemoveChild(nsStyleContext* aChild);
NS_HIDDEN_(void) ApplyStyleFixups(nsPresContext* aPresContext);
nsStyleContext* mParent;
// children are maintained in two circular doubly-linked lists,
// Children are kept in two circularly-linked lists. The list anchor
// is not part of the list (null for empty), and we point to the first
// child.
// mEmptyChild for children whose rule node is the root rule node, and
// mChild for other children. The order of children is not
// meaningful.