Title: [131993] trunk/Source/WebCore
Revision
131993
Author
kl...@webkit.org
Date
2012-10-20 16:08:07 -0700 (Sat, 20 Oct 2012)

Log Message

Clean up QualifiedName-as-hash-key scenario.
<http://webkit.org/b/99394>

Reviewed by Anders Carlsson.

Cache the hash on QualifiedNameImpl after the first time it's computed.
This grows QualifiedNameImpl by 4 bytes on 32-bit (no change on 64-bit due to base class padding)
which I believe is fine, since QualifiedName is a shared object.

Add a global nullQName() function that returns a QualifiedName(nullAtom, nullAtom, nullAtom)
and use this to implement HashTraits<QualifiedName>::emptyValue(). The old implementation would
create a new QualifiedName(nullAtom, nullAtom, nullAtom) each time, which had to be hashed,
added to  the global QualifiedName cache, etc.

Finally, don't have SVGAttributeHashTranslator create a temporary QualifiedName just to compute
the hash of a (namespace, prefix, localName) tuple, use QualifiedNameComponents and hashComponents()
directly instead.

Altogether this shaves ~100ms off of the RoboHornet svgresize.html benchmark on my MBP.

* dom/QualifiedName.cpp:
(WebCore::nullQName):
(WebCore::QualifiedName::QualifiedNameImpl::computeHash):
* dom/QualifiedName.h:
(QualifiedNameImpl):
(WebCore::QualifiedName::QualifiedNameImpl::QualifiedNameImpl):
(WebCore::QualifiedNameHash::hash):
* svg/SVGElement.h:
(WebCore::SVGAttributeHashTranslator::hash):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (131992 => 131993)


--- trunk/Source/WebCore/ChangeLog	2012-10-20 22:44:52 UTC (rev 131992)
+++ trunk/Source/WebCore/ChangeLog	2012-10-20 23:08:07 UTC (rev 131993)
@@ -1,3 +1,35 @@
+2012-10-20  Andreas Kling  <kl...@webkit.org>
+
+        Clean up QualifiedName-as-hash-key scenario.
+        <http://webkit.org/b/99394>
+
+        Reviewed by Anders Carlsson.
+
+        Cache the hash on QualifiedNameImpl after the first time it's computed.
+        This grows QualifiedNameImpl by 4 bytes on 32-bit (no change on 64-bit due to base class padding)
+        which I believe is fine, since QualifiedName is a shared object.
+
+        Add a global nullQName() function that returns a QualifiedName(nullAtom, nullAtom, nullAtom)
+        and use this to implement HashTraits<QualifiedName>::emptyValue(). The old implementation would
+        create a new QualifiedName(nullAtom, nullAtom, nullAtom) each time, which had to be hashed,
+        added to  the global QualifiedName cache, etc.
+
+        Finally, don't have SVGAttributeHashTranslator create a temporary QualifiedName just to compute
+        the hash of a (namespace, prefix, localName) tuple, use QualifiedNameComponents and hashComponents()
+        directly instead.
+
+        Altogether this shaves ~100ms off of the RoboHornet svgresize.html benchmark on my MBP.
+
+        * dom/QualifiedName.cpp:
+        (WebCore::nullQName):
+        (WebCore::QualifiedName::QualifiedNameImpl::computeHash):
+        * dom/QualifiedName.h:
+        (QualifiedNameImpl):
+        (WebCore::QualifiedName::QualifiedNameImpl::QualifiedNameImpl):
+        (WebCore::QualifiedNameHash::hash):
+        * svg/SVGElement.h:
+        (WebCore::SVGAttributeHashTranslator::hash):
+
 2012-10-20  Yael Aharon  <yael.aha...@intel.com>
 
         [EFL][AC] Build fix after r131933

Modified: trunk/Source/WebCore/dom/QualifiedName.cpp (131992 => 131993)


--- trunk/Source/WebCore/dom/QualifiedName.cpp	2012-10-20 22:44:52 UTC (rev 131992)
+++ trunk/Source/WebCore/dom/QualifiedName.cpp	2012-10-20 23:08:07 UTC (rev 131993)
@@ -135,6 +135,12 @@
     }
 }
 
+const QualifiedName& nullQName()
+{
+    DEFINE_STATIC_LOCAL(QualifiedName, nullName, (nullAtom, nullAtom, nullAtom));
+    return nullName;
+}
+
 const AtomicString& QualifiedName::localNameUpper() const
 {
     if (!m_impl->m_localNameUpper)
@@ -158,6 +164,12 @@
     info.addMember(m_localNameUpper);
 }
 
+unsigned QualifiedName::QualifiedNameImpl::computeHash() const
+{
+    QualifiedNameComponents components = { m_prefix.impl(), m_localName.impl(), m_namespace.impl() };
+    return hashComponents(components);
+}
+
 void createQualifiedName(void* targetAddress, const char* name, unsigned nameLength, const AtomicString& nameNamespace)
 {
     AtomicString atomicName(name, nameLength, AtomicString::ConstructFromLiteral);

Modified: trunk/Source/WebCore/dom/QualifiedName.h (131992 => 131993)


--- trunk/Source/WebCore/dom/QualifiedName.h	2012-10-20 22:44:52 UTC (rev 131992)
+++ trunk/Source/WebCore/dom/QualifiedName.h	2012-10-20 23:08:07 UTC (rev 131993)
@@ -44,6 +44,9 @@
             return adoptRef(new QualifiedNameImpl(prefix, localName, namespaceURI));
         }
 
+        unsigned computeHash() const;
+
+        mutable unsigned m_existingHash;
         const AtomicString m_prefix;
         const AtomicString m_localName;
         const AtomicString m_namespace;
@@ -53,7 +56,8 @@
 
     private:
         QualifiedNameImpl(const AtomicString& prefix, const AtomicString& localName, const AtomicString& namespaceURI)
-            : m_prefix(prefix)
+            : m_existingHash(0)
+            , m_prefix(prefix)
             , m_localName(localName)
             , m_namespace(namespaceURI)
         {
@@ -110,6 +114,8 @@
 inline const QualifiedName& anyQName() { return anyName; }
 #endif
 
+const QualifiedName& nullQName();
+
 inline bool operator==(const AtomicString& a, const QualifiedName& q) { return a == q.localName(); }
 inline bool operator!=(const AtomicString& a, const QualifiedName& q) { return a != q.localName(); }
 inline bool operator==(const QualifiedName& q, const AtomicString& a) { return a == q.localName(); }
@@ -125,8 +131,9 @@
 
     static unsigned hash(const QualifiedName::QualifiedNameImpl* name) 
     {
-        QualifiedNameComponents c = { name->m_prefix.impl(), name->m_localName.impl(), name->m_namespace.impl() };
-        return hashComponents(c);
+        if (!name->m_existingHash)
+            name->m_existingHash = name->computeHash();
+        return name->m_existingHash;
     }
 
     static bool equal(const QualifiedName& a, const QualifiedName& b) { return a == b; }
@@ -150,7 +157,7 @@
     
     template<> struct HashTraits<WebCore::QualifiedName> : SimpleClassHashTraits<WebCore::QualifiedName> {
         static const bool emptyValueIsZero = false;
-        static WebCore::QualifiedName emptyValue() { return WebCore::QualifiedName(nullAtom, nullAtom, nullAtom); }
+        static WebCore::QualifiedName emptyValue() { return WebCore::nullQName(); }
     };
 }
 

Modified: trunk/Source/WebCore/svg/SVGElement.h (131992 => 131993)


--- trunk/Source/WebCore/svg/SVGElement.h	2012-10-20 22:44:52 UTC (rev 131992)
+++ trunk/Source/WebCore/svg/SVGElement.h	2012-10-20 23:08:07 UTC (rev 131993)
@@ -159,8 +159,10 @@
 struct SVGAttributeHashTranslator {
     static unsigned hash(const QualifiedName& key)
     {
-        if (key.hasPrefix())
-            return DefaultHash<QualifiedName>::Hash::hash(QualifiedName(nullAtom, key.localName(), key.namespaceURI()));
+        if (key.hasPrefix()) {
+            QualifiedNameComponents components = { nullAtom.impl(), key.localName().impl(), key.namespaceURI().impl() };
+            return hashComponents(components);
+        }
         return DefaultHash<QualifiedName>::Hash::hash(key);
     }
     static bool equal(const QualifiedName& a, const QualifiedName& b) { return a.matches(b); }
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
http://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to