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 // IID for the nsIContent interface
#define NS_ICONTENT_IID \ #define NS_ICONTENT_IID \
{ 0x0acd0482, 0x09a2, 0x42fd, \ { 0x2813b1d9, 0x7fe1, 0x496f, \
{ 0xb6, 0x1b, 0x95, 0xa2, 0x01, 0x6a, 0x55, 0xd3 } } { 0x85, 0x52, 0xa2, 0xc1, 0xc5, 0x6b, 0x15, 0x40 } }
/** /**
* A node of content in a document's content model. This interface * 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 * Get the class list of this content node (this corresponds to the
* value of the null-namespace attribute whose name is given by * 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. * 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 * Walk aRuleWalker over the content style rules (presentational
@ -849,6 +854,14 @@ public:
*/ */
virtual void SaveSubtreeState() = 0; 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 #ifdef DEBUG
/** /**
* List the content (and anything it contains) out to the given * 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 // Optimizations to quickly check whether element may have ID, class or style
// attributes. Not all element implementations may use these! // attributes. Not all element implementations may use these!
NODE_MAY_HAVE_ID = 0x00000200U, 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_CLASS = 0x00000400U,
NODE_MAY_HAVE_STYLE = 0x00000800U, NODE_MAY_HAVE_STYLE = 0x00000800U,

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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