Bug 454317. Improve GetClasses to not do virtual calls when not needed. r=smaug, sr=jst

This commit is contained in:
Boris Zbarsky 2008-09-10 23:22:20 -04:00
parent 3de7c6c512
commit 215e95380a
14 changed files with 39 additions and 23 deletions

View File

@ -62,8 +62,8 @@ class nsIDocShell;
// IID for the nsIContent interface
#define NS_ICONTENT_IID \
{ 0x0acd0482, 0x09a2, 0x42fd, \
{ 0xb6, 0x1b, 0x95, 0xa2, 0x01, 0x6a, 0x55, 0xd3 } }
{ 0x2813b1d9, 0x7fe1, 0x496f, \
{ 0x85, 0x52, 0xa2, 0xc1, 0xc5, 0x6b, 0x15, 0x40 } }
/**
* A node of content in a document's content model. This interface
@ -784,10 +784,15 @@ public:
/**
* Get the class list of this content node (this corresponds to the
* value of the null-namespace attribute whose name is given by
* GetClassAttributeName(). This may be null if there are no
* GetClassAttributeName()). This may be null if there are no
* classes, but that's not guaranteed.
*/
virtual const nsAttrValue* GetClasses() const = 0;
const nsAttrValue* GetClasses() const {
if (HasFlag(NODE_MAY_HAVE_CLASS)) {
return DoGetClasses();
}
return nsnull;
}
/**
* Walk aRuleWalker over the content style rules (presentational
@ -849,6 +854,14 @@ public:
*/
virtual void SaveSubtreeState() = 0;
private:
/**
* Hook for implementing GetClasses. This is guaranteed to only be
* called if the NODE_MAY_HAVE_CLASS flag is set.
*/
virtual const nsAttrValue* DoGetClasses() const = 0;
public:
#ifdef DEBUG
/**
* List the content (and anything it contains) out to the given

View File

@ -95,6 +95,8 @@ enum {
// Optimizations to quickly check whether element may have ID, class or style
// attributes. Not all element implementations may use these!
NODE_MAY_HAVE_ID = 0x00000200U,
// For all Element nodes, NODE_MAY_HAVE_CLASS is guaranteed to be set if the
// node in fact has a class, but may be set even if it doesn't.
NODE_MAY_HAVE_CLASS = 0x00000400U,
NODE_MAY_HAVE_STYLE = 0x00000800U,

View File

@ -1217,8 +1217,9 @@ nsGenericDOMDataNode::GetID() const
}
const nsAttrValue*
nsGenericDOMDataNode::GetClasses() const
nsGenericDOMDataNode::DoGetClasses() const
{
NS_NOTREACHED("Shouldn't ever be called");
return nsnull;
}

View File

@ -248,7 +248,7 @@ public:
virtual PRBool MayHaveFrame() const;
virtual nsIAtom* GetID() const;
virtual const nsAttrValue* GetClasses() const;
virtual const nsAttrValue* DoGetClasses() const;
NS_IMETHOD WalkContentStyleRules(nsRuleWalker* aRuleWalker);
virtual nsICSSStyleRule* GetInlineStyleRule();
NS_IMETHOD SetInlineStyleRule(nsICSSStyleRule* aStyleRule, PRBool aNotify);

View File

@ -2916,8 +2916,9 @@ nsGenericElement::GetID() const
}
const nsAttrValue*
nsGenericElement::GetClasses() const
nsGenericElement::DoGetClasses() const
{
NS_NOTREACHED("Shouldn't ever be called");
return nsnull;
}

View File

@ -417,7 +417,7 @@ public:
#endif
virtual nsIAtom* GetID() const;
virtual const nsAttrValue* GetClasses() const;
virtual const nsAttrValue* DoGetClasses() const;
NS_IMETHOD WalkContentStyleRules(nsRuleWalker* aRuleWalker);
virtual nsICSSStyleRule* GetInlineStyleRule();
NS_IMETHOD SetInlineStyleRule(nsICSSStyleRule* aStyleRule, PRBool aNotify);

View File

@ -71,11 +71,9 @@ nsStyledElement::GetIDAttributeName() const
}
const nsAttrValue*
nsStyledElement::GetClasses() const
nsStyledElement::DoGetClasses() const
{
if (!HasFlag(NODE_MAY_HAVE_CLASS)) {
return nsnull;
}
NS_ASSERTION(HasFlag(NODE_MAY_HAVE_CLASS), "Unexpected call");
return mAttrsAndChildren.GetAttr(nsGkAtoms::_class);
}

View File

@ -67,7 +67,7 @@ public:
// nsIContent interface methods for styling
virtual nsIAtom* GetClassAttributeName() const;
virtual nsIAtom* GetIDAttributeName() const;
virtual const nsAttrValue* GetClasses() const;
virtual const nsAttrValue* DoGetClasses() const;
virtual nsICSSStyleRule* GetInlineStyleRule();
NS_IMETHOD SetInlineStyleRule(nsICSSStyleRule* aStyleRule, PRBool aNotify);

View File

@ -60,7 +60,8 @@ NS_INTERFACE_MAP_END_INHERITING(nsSVGStylableElementBase)
nsSVGStylableElement::nsSVGStylableElement(nsINodeInfo *aNodeInfo)
: nsSVGStylableElementBase(aNodeInfo)
{
// We never know when we might have a class
SetFlags(NODE_MAY_HAVE_CLASS);
}
nsresult
@ -88,7 +89,7 @@ nsSVGStylableElement::Init()
// nsIContent methods
const nsAttrValue*
nsSVGStylableElement::GetClasses() const
nsSVGStylableElement::DoGetClasses() const
{
return mClassName->GetAttrValue();
}

View File

@ -60,7 +60,7 @@ public:
NS_DECL_NSIDOMSVGSTYLABLE
// nsIContent
virtual const nsAttrValue* GetClasses() const;
virtual const nsAttrValue* DoGetClasses() const;
protected:
nsRefPtr<nsSVGClassValue> mClassName;

View File

@ -73,6 +73,8 @@ nsXTFElementWrapper::nsXTFElementWrapper(nsINodeInfo* aNodeInfo,
mTmpAttrName(nsGkAtoms::_asterix) // XXX this is a hack, but names
// have to have a value
{
// We never know when we might have a class
SetFlags(NODE_MAY_HAVE_CLASS);
}
nsXTFElementWrapper::~nsXTFElementWrapper()
@ -931,7 +933,7 @@ nsXTFElementWrapper::GetClassAttributeName() const
}
const nsAttrValue*
nsXTFElementWrapper::GetClasses() const
nsXTFElementWrapper::DoGetClasses() const
{
const nsAttrValue* val = nsnull;
nsIAtom* clazzAttr = GetClassAttributeName();

View File

@ -109,7 +109,7 @@ public:
virtual nsresult DoneAddingChildren(PRBool aHaveNotified);
virtual nsIAtom *GetClassAttributeName() const;
virtual const nsAttrValue* GetClasses() const;
virtual const nsAttrValue* DoGetClasses() const;
virtual void PerformAccesskey(PRBool aKeyCausesActivation,
PRBool aIsTrustedEvent);

View File

@ -1830,11 +1830,9 @@ nsXULElement::GetID() const
}
const nsAttrValue*
nsXULElement::GetClasses() const
nsXULElement::DoGetClasses() const
{
if (!HasFlag(NODE_MAY_HAVE_CLASS)) {
return nsnull;
}
NS_ASSERTION(HasFlag(NODE_MAY_HAVE_CLASS), "Unexpected call");
return FindLocalOrProtoAttr(kNameSpaceID_None, nsGkAtoms::_class);
}

View File

@ -592,7 +592,7 @@ public:
virtual PRBool IsNodeOfType(PRUint32 aFlags) const;
virtual PRBool IsFocusable(PRInt32 *aTabIndex = nsnull);
virtual nsIAtom* GetID() const;
virtual const nsAttrValue* GetClasses() const;
virtual const nsAttrValue* DoGetClasses() const;
NS_IMETHOD WalkContentStyleRules(nsRuleWalker* aRuleWalker);
virtual nsICSSStyleRule* GetInlineStyleRule();