Title: [148961] trunk/Source/WebCore
Revision
148961
Author
[email protected]
Date
2013-04-23 07:21:05 -0700 (Tue, 23 Apr 2013)

Log Message

Speed up ElementData::getAttributeItem(), which is hot.
<http://webkit.org/b/115031>

Reviewed by Antti Koivisto.

>From Blink r148622 by <[email protected]>.

The previous version had a couple of issues:
- Incurred new WTF::Vector::operator[] checks.
- Had a branch in _every_ loop iteration that checked whether the storage was Vector or array[] backed.

Both these issues are fixed, and CloneNodes.html seems reliably at +2%.
I also believe GetElement.html is maybe +1%.

For WebKit, also applied the same optimization to getAttributeItemIndex().

* dom/Element.h:
(WebCore::ElementData::attributeBase):
(WebCore::ElementData::getAttributeItemIndex):
(WebCore::ElementData::getAttributeItem):
(WebCore::ElementData::attributeItem):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (148960 => 148961)


--- trunk/Source/WebCore/ChangeLog	2013-04-23 12:07:57 UTC (rev 148960)
+++ trunk/Source/WebCore/ChangeLog	2013-04-23 14:21:05 UTC (rev 148961)
@@ -1,3 +1,27 @@
+2013-04-23  Andreas Kling  <[email protected]>
+
+        Speed up ElementData::getAttributeItem(), which is hot.
+        <http://webkit.org/b/115031>
+
+        Reviewed by Antti Koivisto.
+
+        From Blink r148622 by <[email protected]>.
+
+        The previous version had a couple of issues:
+        - Incurred new WTF::Vector::operator[] checks.
+        - Had a branch in _every_ loop iteration that checked whether the storage was Vector or array[] backed.
+
+        Both these issues are fixed, and CloneNodes.html seems reliably at +2%.
+        I also believe GetElement.html is maybe +1%.
+
+        For WebKit, also applied the same optimization to getAttributeItemIndex().
+
+        * dom/Element.h:
+        (WebCore::ElementData::attributeBase):
+        (WebCore::ElementData::getAttributeItemIndex):
+        (WebCore::ElementData::getAttributeItem):
+        (WebCore::ElementData::attributeItem):
+
 2013-04-23  Antoine Quint  <[email protected]>
 
         Initial advance of text runs should be taken into account

Modified: trunk/Source/WebCore/dom/Element.h (148960 => 148961)


--- trunk/Source/WebCore/dom/Element.h	2013-04-23 12:07:57 UTC (rev 148960)
+++ trunk/Source/WebCore/dom/Element.h	2013-04-23 14:21:05 UTC (rev 148961)
@@ -110,6 +110,7 @@
     friend class SVGElement;
 #endif
 
+    const Attribute* attributeBase() const;
     const Attribute* getAttributeItem(const AtomicString& name, bool shouldIgnoreAttributeCase) const;
     size_t getAttributeItemIndexSlowCase(const AtomicString& name, bool shouldIgnoreAttributeCase) const;
 
@@ -940,6 +941,13 @@
     return m_arraySize;
 }
 
+inline const Attribute* ElementData::attributeBase() const
+{
+    if (m_isUnique)
+        return static_cast<const UniqueElementData*>(this)->m_attributeVector.data();
+    return static_cast<const ShareableElementData*>(this)->m_attributeArray;
+}
+
 inline const StylePropertySet* ElementData::presentationAttributeStyle() const
 {
     if (!m_isUnique)
@@ -957,8 +965,9 @@
 
 inline size_t ElementData::getAttributeItemIndex(const QualifiedName& name) const
 {
-    for (unsigned i = 0; i < length(); ++i) {
-        if (attributeItem(i)->name().matches(name))
+    const Attribute* attributes = attributeBase();
+    for (unsigned i = 0, count = length(); i < count; ++i) {
+        if (attributes[i].name().matches(name))
             return i;
     }
     return notFound;
@@ -968,15 +977,14 @@
 // can tune the behavior (hasAttribute is case sensitive whereas getAttribute is not).
 inline size_t ElementData::getAttributeItemIndex(const AtomicString& name, bool shouldIgnoreAttributeCase) const
 {
-    unsigned len = length();
+    const Attribute* attributes = attributeBase();
     bool doSlowCheck = shouldIgnoreAttributeCase;
+    const AtomicString& caseAdjustedName = shouldIgnoreAttributeCase ? name.lower() : name;
 
-    const AtomicString caseAdjustedName = shouldIgnoreAttributeCase ? name.lower() : name;
     // Optimize for the case where the attribute exists and its name exactly matches.
-    for (unsigned i = 0; i < len; ++i) {
-        const Attribute* attribute = attributeItem(i);
-        if (!attribute->name().hasPrefix()) {
-            if (caseAdjustedName == attribute->localName())
+    for (unsigned i = 0, count = length(); i < count; ++i) {
+        if (!attributes[i].name().hasPrefix()) {
+            if (caseAdjustedName == attributes[i].localName())
                 return i;
         } else
             doSlowCheck = true;
@@ -989,9 +997,10 @@
 
 inline const Attribute* ElementData::getAttributeItem(const QualifiedName& name) const
 {
-    for (unsigned i = 0; i < length(); ++i) {
-        if (attributeItem(i)->name().matches(name))
-            return attributeItem(i);
+    const Attribute* attributes = attributeBase();
+    for (unsigned i = 0, count = length(); i < count; ++i) {
+        if (attributes[i].name().matches(name))
+            return &attributes[i];
     }
     return 0;
 }
@@ -999,9 +1008,7 @@
 inline const Attribute* ElementData::attributeItem(unsigned index) const
 {
     ASSERT_WITH_SECURITY_IMPLICATION(index < length());
-    if (m_isUnique)
-        return &static_cast<const UniqueElementData*>(this)->m_attributeVector.at(index);
-    return &static_cast<const ShareableElementData*>(this)->m_attributeArray[index];
+    return attributeBase() + index;
 }
 
 } // namespace
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to