Make elements that don't have attributes smaller.
authorkling@webkit.org <kling@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 1 Feb 2012 07:36:21 +0000 (07:36 +0000)
committerkling@webkit.org <kling@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 1 Feb 2012 07:36:21 +0000 (07:36 +0000)
<http://webkit.org/b/76876>

Reviewed by Sam Weinig and Antti Koivisto.

Move the inline style declaration from StyledElement to ElementAttributeData, since having
an inline style declaration also implies having a style attribute on the element.
This saves one CPU word per element that has no attributes.

This reduces memory consumption by 412 kB (on 64-bit) when viewing the full
HTML5 spec at <http://whatwg.org/c>.

This was rolled out once because of a performance regression which has been averted this
time around by adding an Element::ensureAttributeMap() so we can force creation of the
NamedNodeMap without also serializing the inline style for the "style" attribute.

* dom/Element.h:
(Element):
(WebCore::Element::ensureAttributeMap):
(WebCore):
* dom/ElementAttributeData.h:
(ElementAttributeData):
* dom/NamedNodeMap.cpp:
(WebCore::NamedNodeMap::ensureInlineStyleDecl):
(WebCore):
(WebCore::NamedNodeMap::destroyInlineStyleDecl):
* dom/NamedNodeMap.h:
(WebCore::NamedNodeMap::inlineStyleDecl):
(NamedNodeMap):
* dom/StyledElement.cpp:
(WebCore::StyledElement::addSubresourceAttributeURLs):
* dom/StyledElement.h:
(WebCore::StyledElement::inlineStyleDecl):
(WebCore::StyledElement::ensureInlineStyleDecl):
(StyledElement):
(WebCore::StyledElement::destroyInlineStyleDecl):

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@106435 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebCore/ChangeLog
Source/WebCore/dom/Element.h
Source/WebCore/dom/ElementAttributeData.h
Source/WebCore/dom/NamedNodeMap.cpp
Source/WebCore/dom/NamedNodeMap.h
Source/WebCore/dom/StyledElement.cpp
Source/WebCore/dom/StyledElement.h

index cb8a002..0e2318c 100644 (file)
@@ -1,3 +1,42 @@
+2012-01-31  Andreas Kling  <awesomekling@apple.com>
+
+        Make elements that don't have attributes smaller.
+        <http://webkit.org/b/76876>
+
+        Reviewed by Sam Weinig and Antti Koivisto.
+
+        Move the inline style declaration from StyledElement to ElementAttributeData, since having
+        an inline style declaration also implies having a style attribute on the element.
+        This saves one CPU word per element that has no attributes.
+
+        This reduces memory consumption by 412 kB (on 64-bit) when viewing the full
+        HTML5 spec at <http://whatwg.org/c>.
+
+        This was rolled out once because of a performance regression which has been averted this
+        time around by adding an Element::ensureAttributeMap() so we can force creation of the
+        NamedNodeMap without also serializing the inline style for the "style" attribute.
+
+        * dom/Element.h:
+        (Element):
+        (WebCore::Element::ensureAttributeMap):
+        (WebCore):
+        * dom/ElementAttributeData.h:
+        (ElementAttributeData):
+        * dom/NamedNodeMap.cpp:
+        (WebCore::NamedNodeMap::ensureInlineStyleDecl):
+        (WebCore):
+        (WebCore::NamedNodeMap::destroyInlineStyleDecl):
+        * dom/NamedNodeMap.h:
+        (WebCore::NamedNodeMap::inlineStyleDecl):
+        (NamedNodeMap):
+        * dom/StyledElement.cpp:
+        (WebCore::StyledElement::addSubresourceAttributeURLs):
+        * dom/StyledElement.h:
+        (WebCore::StyledElement::inlineStyleDecl):
+        (WebCore::StyledElement::ensureInlineStyleDecl):
+        (StyledElement):
+        (WebCore::StyledElement::destroyInlineStyleDecl):
+
 2012-01-31  Hayato Ito  <hayato@chromium.org>
 
         Add APIs, getElementsByXXX family, to ShadowRoot IDL.
index 014a28d..54e1716 100644 (file)
@@ -223,6 +223,7 @@ public:
     void parserSetAttributeMap(PassOwnPtr<NamedNodeMap>, FragmentScriptingPermission);
 
     NamedNodeMap* attributeMap() const { return m_attributeMap.get(); }
+    NamedNodeMap* ensureAttributeMap();
 
     ElementAttributeData* attributeData() const { return m_attributeMap ? m_attributeMap->attributeData() : 0; }
     ElementAttributeData* ensureAttributeData() const { return attributes()->attributeData(); }
@@ -597,6 +598,13 @@ inline void Element::setIdAttribute(const AtomicString& value)
     setAttribute(document()->idAttributeName(), value);
 }
 
+inline NamedNodeMap* Element::ensureAttributeMap()
+{
+    if (!m_attributeMap)
+        createAttributeMap();
+    return m_attributeMap.get();
+}
+
 inline Element* firstElementChild(const ContainerNode* container)
 {
     ASSERT_ARG(container, container);
index ee65921..20116c6 100644 (file)
@@ -26,6 +26,7 @@
 #ifndef ElementAttributeData_h
 #define ElementAttributeData_h
 
+#include "CSSMutableStyleDeclaration.h"
 #include "SpaceSplitString.h"
 
 namespace WebCore {
@@ -48,6 +49,7 @@ private:
     {
     }
 
+    RefPtr<CSSMutableStyleDeclaration> m_inlineStyleDecl;
     SpaceSplitString m_classNames;
     AtomicString m_idForStyleResolution;
 };
index 05bec1f..0134441 100644 (file)
@@ -30,6 +30,7 @@
 #include "Element.h"
 #include "ExceptionCode.h"
 #include "HTMLNames.h"
+#include "StyledElement.h"
 
 namespace WebCore {
 
@@ -320,4 +321,22 @@ bool NamedNodeMap::mapsEquivalent(const NamedNodeMap* otherMap) const
     return true;
 }
 
+CSSMutableStyleDeclaration* NamedNodeMap::ensureInlineStyleDecl()
+{
+    if (!attributeData()->m_inlineStyleDecl) {
+        ASSERT(m_element->isStyledElement());
+        attributeData()->m_inlineStyleDecl = CSSMutableStyleDeclaration::createInline(static_cast<StyledElement*>(m_element));
+        attributeData()->m_inlineStyleDecl->setStrictParsing(m_element->isHTMLElement() && !m_element->document()->inQuirksMode());
+    }
+    return attributeData()->m_inlineStyleDecl.get();
+}
+
+void NamedNodeMap::destroyInlineStyleDecl()
+{
+    if (!attributeData()->m_inlineStyleDecl)
+        return;
+    attributeData()->m_inlineStyleDecl->clearParentElement();
+    attributeData()->m_inlineStyleDecl = 0;
+}
+
 } // namespace WebCore
index f6e8170..f53047c 100644 (file)
@@ -99,6 +99,10 @@ public:
     ElementAttributeData* attributeData() { return &m_attributeData; }
     const ElementAttributeData* attributeData() const { return &m_attributeData; }
 
+    CSSMutableStyleDeclaration* inlineStyleDecl() { return attributeData()->m_inlineStyleDecl.get(); }
+    CSSMutableStyleDeclaration* ensureInlineStyleDecl();
+    void destroyInlineStyleDecl();
+
 private:
     NamedNodeMap(Element* element)
         : m_element(element)
index 4be224c..7e99217 100644 (file)
@@ -127,21 +127,6 @@ PassRefPtr<Attribute> StyledElement::createAttribute(const QualifiedName& name,
     return Attribute::createMapped(name, value);
 }
 
-void StyledElement::createInlineStyleDecl()
-{
-    ASSERT(!m_inlineStyleDecl);
-    m_inlineStyleDecl = CSSMutableStyleDeclaration::createInline(this);
-    m_inlineStyleDecl->setStrictParsing(isHTMLElement() && !document()->inQuirksMode());
-}
-
-void StyledElement::destroyInlineStyleDecl()
-{
-    if (!m_inlineStyleDecl)
-        return;
-    m_inlineStyleDecl->clearParentElement();
-    m_inlineStyleDecl = 0;
-}
-
 void StyledElement::attributeChanged(Attribute* attr, bool preserveDecls)
 {
     if (attr->name() == HTMLNames::nameAttr)
@@ -241,18 +226,6 @@ void StyledElement::parseMappedAttribute(Attribute* attr)
     }
 }
 
-CSSMutableStyleDeclaration* StyledElement::ensureInlineStyleDecl()
-{
-    if (!m_inlineStyleDecl)
-        createInlineStyleDecl();
-    return m_inlineStyleDecl.get();
-}
-
-CSSStyleDeclaration* StyledElement::style()
-{
-    return ensureInlineStyleDecl();
-}
-
 void StyledElement::removeCSSProperty(Attribute* attribute, int id)
 {
     if (!attribute->decl())
@@ -444,9 +417,8 @@ void StyledElement::copyNonAttributeProperties(const Element* sourceElement)
 
 void StyledElement::addSubresourceAttributeURLs(ListHashSet<KURL>& urls) const
 {
-    if (!m_inlineStyleDecl)
-        return;
-    m_inlineStyleDecl->addSubresourceStyleURLs(urls);
+    if (CSSMutableStyleDeclaration* inlineStyle = inlineStyleDecl())
+        inlineStyle->addSubresourceStyleURLs(urls);
 }
 
 }
index 847c50f..d61f0af 100644 (file)
@@ -58,9 +58,9 @@ public:
     virtual PassRefPtr<CSSMutableStyleDeclaration> additionalAttributeStyle() { return 0; }
     void invalidateStyleAttribute();
 
-    CSSMutableStyleDeclaration* inlineStyleDecl() const { return m_inlineStyleDecl.get(); }
-    CSSMutableStyleDeclaration* ensureInlineStyleDecl();
-    virtual CSSStyleDeclaration* style() OVERRIDE;
+    CSSMutableStyleDeclaration* inlineStyleDecl() const { return attributeMap() ? attributeMap()->inlineStyleDecl() : 0; }
+    CSSMutableStyleDeclaration* ensureInlineStyleDecl() { return ensureAttributeMap()->ensureInlineStyleDecl(); }
+    virtual CSSStyleDeclaration* style() OVERRIDE { return ensureInlineStyleDecl(); }
 
     const SpaceSplitString& classNames() const;
 
@@ -88,11 +88,13 @@ protected:
 private:
     void createMappedDecl(Attribute*);
 
-    void createInlineStyleDecl();
-    void destroyInlineStyleDecl();
     virtual void updateStyleAttribute() const;
 
-    RefPtr<CSSMutableStyleDeclaration> m_inlineStyleDecl;
+    void destroyInlineStyleDecl()
+    {
+        if (attributeMap())
+            attributeMap()->destroyInlineStyleDecl();
+    }
 };
 
 inline const SpaceSplitString& StyledElement::classNames() const