Bug 661746 - Part 5: Avoid creating atoms during selector matching. r=bzbarsky

This commit is contained in:
David Zbarsky 2011-11-14 16:30:28 +13:00
parent 3cf667fd11
commit 1475029a2d
4 changed files with 29 additions and 29 deletions

View File

@ -143,15 +143,16 @@ nsPseudoClassList::nsPseudoClassList(nsCSSPseudoClasses::Type aType)
}
nsPseudoClassList::nsPseudoClassList(nsCSSPseudoClasses::Type aType,
const PRUnichar* aString)
nsIAtom* aAtom)
: mType(aType),
mNext(nsnull)
{
NS_ASSERTION(nsCSSPseudoClasses::HasStringArg(aType),
"unexpected pseudo-class");
NS_ASSERTION(aString, "string expected");
NS_ASSERTION(aAtom, "atom expected");
MOZ_COUNT_CTOR(nsPseudoClassList);
u.mString = NS_strdup(aString);
NS_ADDREF(aAtom);
u.mAtom = aAtom;
}
nsPseudoClassList::nsPseudoClassList(nsCSSPseudoClasses::Type aType,
@ -187,7 +188,7 @@ nsPseudoClassList::Clone(bool aDeep) const
if (!u.mMemory) {
result = new nsPseudoClassList(mType);
} else if (nsCSSPseudoClasses::HasStringArg(mType)) {
result = new nsPseudoClassList(mType, u.mString);
result = new nsPseudoClassList(mType, u.mAtom);
} else if (nsCSSPseudoClasses::HasNthPairArg(mType)) {
result = new nsPseudoClassList(mType, u.mNumbers);
} else {
@ -210,7 +211,11 @@ nsPseudoClassList::~nsPseudoClassList(void)
if (nsCSSPseudoClasses::HasSelectorListArg(mType)) {
delete u.mSelectors;
} else if (u.mMemory) {
NS_Free(u.mMemory);
if (nsCSSPseudoClasses::HasStringArg(mType)) {
NS_RELEASE(u.mAtom);
} else {
NS_Free(u.mMemory);
}
}
NS_CSS_DELETE_LIST_MEMBER(nsPseudoClassList, this, mNext);
}
@ -414,9 +419,9 @@ void nsCSSSelector::AddPseudoClass(nsCSSPseudoClasses::Type aType)
}
void nsCSSSelector::AddPseudoClass(nsCSSPseudoClasses::Type aType,
const PRUnichar* aString)
nsIAtom* aAtom)
{
AddPseudoClassInternal(new nsPseudoClassList(aType, aString));
AddPseudoClassInternal(new nsPseudoClassList(aType, aAtom));
}
void nsCSSSelector::AddPseudoClass(nsCSSPseudoClasses::Type aType,
@ -772,7 +777,7 @@ nsCSSSelector::AppendToStringWithoutCombinatorsOrNegations
aString.Append(PRUnichar('('));
if (nsCSSPseudoClasses::HasStringArg(list->mType)) {
nsStyleUtil::AppendEscapedCSSIdent(
nsDependentString(list->u.mString), aString);
nsDependentAtomString(list->u.mAtom), aString);
} else if (nsCSSPseudoClasses::HasNthPairArg(list->mType)) {
PRInt32 a = list->u.mNumbers[0],
b = list->u.mNumbers[1];

View File

@ -80,7 +80,7 @@ private:
struct nsPseudoClassList {
public:
nsPseudoClassList(nsCSSPseudoClasses::Type aType);
nsPseudoClassList(nsCSSPseudoClasses::Type aType, const PRUnichar *aString);
nsPseudoClassList(nsCSSPseudoClasses::Type aType, nsIAtom *aAtom);
nsPseudoClassList(nsCSSPseudoClasses::Type aType, const PRInt32 *aIntPair);
nsPseudoClassList(nsCSSPseudoClasses::Type aType,
nsCSSSelectorList *aSelectorList /* takes ownership */);
@ -99,8 +99,8 @@ public:
// (if nsCSSPseudoClasses::HasNthPairArg(mType))
// d. a selector list, which means mSelectors is non-null
// (if nsCSSPseudoClasses::HasSelectorListArg(mType))
void* mMemory; // mString and mNumbers use NS_Alloc/NS_Free
PRUnichar* mString;
void* mMemory; // mNumbers uses NS_Alloc/NS_Free
nsIAtom* mAtom; // STRONG REF
PRInt32* mNumbers;
nsCSSSelectorList* mSelectors;
} u;
@ -165,7 +165,7 @@ public:
void AddID(const nsString& aID);
void AddClass(const nsString& aClass);
void AddPseudoClass(nsCSSPseudoClasses::Type aType);
void AddPseudoClass(nsCSSPseudoClasses::Type aType, const PRUnichar* aString);
void AddPseudoClass(nsCSSPseudoClasses::Type aType, nsIAtom* aAtom);
void AddPseudoClass(nsCSSPseudoClasses::Type aType, const PRInt32* aIntPair);
// takes ownership of aSelectorList
void AddPseudoClass(nsCSSPseudoClasses::Type aType,

View File

@ -3371,16 +3371,16 @@ CSSParserImpl::ParsePseudoClassWithIdentArg(nsCSSSelector& aSelector,
return eSelectorParsingStatus_Error; // our caller calls SkipUntil(')')
}
nsCOMPtr<nsIAtom> atom = do_GetAtom(mToken.mIdent);
// -moz-locale-dir can only have values of 'ltr' or 'rtl'.
if (aType == nsCSSPseudoClasses::ePseudoClass_mozLocaleDir) {
if (!mToken.mIdent.EqualsLiteral("ltr") &&
!mToken.mIdent.EqualsLiteral("rtl")) {
if (atom != nsGkAtoms::ltr && atom != nsGkAtoms::rtl) {
return eSelectorParsingStatus_Error; // our caller calls SkipUntil(')')
}
}
// Add the pseudo with the language parameter
aSelector.AddPseudoClass(aType, mToken.mIdent.get());
aSelector.AddPseudoClass(aType, atom);
// close the parenthesis
if (!ExpectSymbol(')', true)) {

View File

@ -1686,7 +1686,7 @@ static bool SelectorMatches(const Element* aElement,
case nsCSSPseudoClasses::ePseudoClass_mozEmptyExceptChildrenWithLocalname:
{
NS_ASSERTION(pseudoClass->u.mString, "Must have string!");
NS_ASSERTION(pseudoClass->u.mAtom, "Must have atom!");
const nsIContent *child = nsnull;
PRInt32 index = -1;
@ -1702,7 +1702,7 @@ static bool SelectorMatches(const Element* aElement,
} while (child &&
(!IsSignificantChild(child, true, false) ||
(child->GetNameSpaceID() == aElement->GetNameSpaceID() &&
child->Tag()->Equals(nsDependentString(pseudoClass->u.mString)))));
child->Tag() == pseudoClass->u.mAtom)));
if (child != nsnull) {
return false;
}
@ -1711,10 +1711,7 @@ static bool SelectorMatches(const Element* aElement,
case nsCSSPseudoClasses::ePseudoClass_lang:
{
NS_ASSERTION(nsnull != pseudoClass->u.mString, "null lang parameter");
if (!pseudoClass->u.mString || !*pseudoClass->u.mString) {
return false;
}
NS_ASSERTION(pseudoClass->u.mAtom, "Must have atom!");
// We have to determine the language of the current element. Since
// this is currently no property and since the language is inherited
@ -1722,9 +1719,10 @@ static bool SelectorMatches(const Element* aElement,
// nodes. The language itself is encoded in the LANG attribute.
nsAutoString language;
aElement->GetLang(language);
nsDependentAtomString langString(pseudoClass->u.mAtom);
if (!language.IsEmpty()) {
if (!nsStyleUtil::DashMatchCompare(language,
nsDependentString(pseudoClass->u.mString),
langString,
nsASCIICaseInsensitiveStringComparator())) {
return false;
}
@ -1740,7 +1738,6 @@ static bool SelectorMatches(const Element* aElement,
// language codes.
doc->GetContentLanguage(language);
nsDependentString langString(pseudoClass->u.mString);
language.StripWhitespace();
PRInt32 begin = 0;
PRInt32 len = language.Length();
@ -1933,8 +1930,7 @@ static bool SelectorMatches(const Element* aElement,
case nsCSSPseudoClasses::ePseudoClass_mozSystemMetric:
{
nsCOMPtr<nsIAtom> metric = do_GetAtom(pseudoClass->u.mString);
if (!nsCSSRuleProcessor::HasSystemMetric(metric)) {
if (!nsCSSRuleProcessor::HasSystemMetric(pseudoClass->u.mAtom)) {
return false;
}
}
@ -1945,12 +1941,11 @@ static bool SelectorMatches(const Element* aElement,
bool docIsRTL =
aTreeMatchContext.mDocStates.HasState(NS_DOCUMENT_STATE_RTL_LOCALE);
nsDependentString dirString(pseudoClass->u.mString);
NS_ASSERTION(dirString.EqualsLiteral("ltr") ||
dirString.EqualsLiteral("rtl"),
NS_ASSERTION(pseudoClass->u.mAtom == nsGkAtoms::ltr ||
pseudoClass->u.mAtom == nsGkAtoms::rtl,
"invalid value for -moz-locale-dir");
if (dirString.EqualsLiteral("rtl") != docIsRTL) {
if ((pseudoClass->u.mAtom == nsGkAtoms::rtl) != docIsRTL) {
return false;
}
}