Title: [121412] trunk/Source/WebCore
Revision
121412
Author
[email protected]
Date
2012-06-27 23:29:27 -0700 (Wed, 27 Jun 2012)

Log Message

Performance: Optimize Dromaeo/dom-query.html by caching NodeRareData on Document
https://bugs.webkit.org/show_bug.cgi?id=90059

Reviewed by Ryosuke Niwa.

This patch improves performance of document.getElementsBy*().
e.g. the patch makes Dromaeo/dom-query.html 5.4% faster.

Dromaeo/dom-query.html without the patch (Chromium/Linux):
784714 runs/s, 765947 runs/s, 803109 runs/s, 804450 runs/s

Dromaeo/dom-query.html with the patch (Chromium/Linux):
839245 runs/s, 829867 runs/s, 811032 runs/s, 847486 runs/s

Based on the assumption that document.getElementsByClassName(),
document.getElementsByTagName() and document.getElementsByName()
would be used frequently in the real world, this patch implements
a fast path for Document methods that require to access NodeRareData.
Specifically, this patch caches a pointer to NodeRareData on Document,
by which Document can access NodeRareData without looking up a HashMap.

The only performance concern is the overhead of the isDocumentNode() check
that this patch added to Node::ensureRareData. However, I could not
observe any performance regression caused by the overhead.

No tests. No change in behavior.

* dom/Document.cpp:
(WebCore::Document::Document):
(WebCore::Document::setCachedRareData): I didn't inline this method,
since the inlining slightly regressed performance for some reason.
(WebCore):
* dom/Document.h:
(WebCore):
(WebCore::Document::cachedRareData):
(Document):
(~Document): Moved 'm_document = 0' to the tail of the destructor,
since isDocumentNode() has to return true in clearRareData() that is called
in ~Document().
* dom/Node.cpp:
(WebCore::Node::ensureRareData):
(~Node): Moved the assertion into clearRareData().

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (121411 => 121412)


--- trunk/Source/WebCore/ChangeLog	2012-06-28 06:24:56 UTC (rev 121411)
+++ trunk/Source/WebCore/ChangeLog	2012-06-28 06:29:27 UTC (rev 121412)
@@ -1,3 +1,48 @@
+2012-06-27  Kentaro Hara  <[email protected]>
+
+        Performance: Optimize Dromaeo/dom-query.html by caching NodeRareData on Document
+        https://bugs.webkit.org/show_bug.cgi?id=90059
+
+        Reviewed by Ryosuke Niwa.
+
+        This patch improves performance of document.getElementsBy*().
+        e.g. the patch makes Dromaeo/dom-query.html 5.4% faster.
+
+        Dromaeo/dom-query.html without the patch (Chromium/Linux):
+        784714 runs/s, 765947 runs/s, 803109 runs/s, 804450 runs/s
+
+        Dromaeo/dom-query.html with the patch (Chromium/Linux):
+        839245 runs/s, 829867 runs/s, 811032 runs/s, 847486 runs/s
+
+        Based on the assumption that document.getElementsByClassName(),
+        document.getElementsByTagName() and document.getElementsByName()
+        would be used frequently in the real world, this patch implements
+        a fast path for Document methods that require to access NodeRareData.
+        Specifically, this patch caches a pointer to NodeRareData on Document,
+        by which Document can access NodeRareData without looking up a HashMap.
+
+        The only performance concern is the overhead of the isDocumentNode() check
+        that this patch added to Node::ensureRareData. However, I could not
+        observe any performance regression caused by the overhead.
+
+        No tests. No change in behavior.
+
+        * dom/Document.cpp:
+        (WebCore::Document::Document):
+        (WebCore::Document::setCachedRareData): I didn't inline this method,
+        since the inlining slightly regressed performance for some reason.
+        (WebCore):
+        * dom/Document.h:
+        (WebCore):
+        (WebCore::Document::cachedRareData):
+        (Document):
+        (~Document): Moved 'm_document = 0' to the tail of the destructor,
+        since isDocumentNode() has to return true in clearRareData() that is called
+        in ~Document().
+        * dom/Node.cpp:
+        (WebCore::Node::ensureRareData):
+        (~Node): Moved the assertion into clearRareData().
+
 2012-06-27  Mary Wu  <[email protected]>
 
         [BlackBerry] 0-length response with no content-type shouldn't download

Modified: trunk/Source/WebCore/dom/Document.cpp (121411 => 121412)


--- trunk/Source/WebCore/dom/Document.cpp	2012-06-28 06:24:56 UTC (rev 121411)
+++ trunk/Source/WebCore/dom/Document.cpp	2012-06-28 06:29:27 UTC (rev 121412)
@@ -470,6 +470,7 @@
     , m_isViewSource(false)
     , m_sawElementsInKnownNamespaces(false)
     , m_isSrcdocDocument(false)
+    , m_documentRareData(0)
     , m_eventQueue(DocumentEventQueue::create(this))
     , m_weakReference(DocumentWeakReference::create(this))
     , m_idAttributeName(idAttr)
@@ -606,7 +607,6 @@
     // if the DocumentParser outlives the Document it won't cause badness.
     ASSERT(!m_parser || m_parser->refCount() == 1);
     detachParser();
-    m_document = 0;
 
     m_renderArena.clear();
 
@@ -650,6 +650,8 @@
     if (hasRareData())
         clearRareData();
 
+    m_document = 0;
+
     InspectorCounters::decrementCounter(InspectorCounters::DocumentCounter);
 }
 
@@ -2009,6 +2011,11 @@
     marginLeft = style->marginLeft().isAuto() ? marginLeft : intValueForLength(style->marginLeft(), width, view);
 }
 
+void Document::setDocumentRareData(NodeRareData* rareData)
+{
+    m_documentRareData = rareData;
+}
+
 void Document::setIsViewSource(bool isViewSource)
 {
     m_isViewSource = isViewSource;

Modified: trunk/Source/WebCore/dom/Document.h (121411 => 121412)


--- trunk/Source/WebCore/dom/Document.h	2012-06-28 06:24:56 UTC (rev 121411)
+++ trunk/Source/WebCore/dom/Document.h	2012-06-28 06:29:27 UTC (rev 121412)
@@ -111,6 +111,7 @@
 class MouseEventWithHitTestResults;
 class NodeFilter;
 class NodeIterator;
+class NodeRareData;
 class Page;
 class PlatformMouseEvent;
 class ProcessingInstruction;
@@ -432,6 +433,9 @@
 
     bool isSrcdocDocument() const { return m_isSrcdocDocument; }
 
+    NodeRareData* documentRareData() const { return m_documentRareData; };
+    void setDocumentRareData(NodeRareData*);
+
     StyleResolver* styleResolverIfExists() const { return m_styleResolver.get(); }
 
     bool isViewSource() const { return m_isViewSource; }
@@ -1435,6 +1439,8 @@
     bool m_sawElementsInKnownNamespaces;
     bool m_isSrcdocDocument;
 
+    NodeRareData* m_documentRareData;
+
     RefPtr<DocumentEventQueue> m_eventQueue;
 
     RefPtr<DocumentWeakReference> m_weakReference;

Modified: trunk/Source/WebCore/dom/Node.cpp (121411 => 121412)


--- trunk/Source/WebCore/dom/Node.cpp	2012-06-28 06:24:56 UTC (rev 121411)
+++ trunk/Source/WebCore/dom/Node.cpp	2012-06-28 06:29:27 UTC (rev 121412)
@@ -399,7 +399,6 @@
     liveNodeSet.remove(this);
 #endif
 
-    ASSERT(hasRareData() == NodeRareData::rareDataMap().contains(this));
     if (hasRareData())
         clearRareData();
 
@@ -459,17 +458,25 @@
 NodeRareData* Node::rareData() const
 {
     ASSERT(hasRareData());
-    return NodeRareData::rareDataFromMap(this);
+    NodeRareData* data = "" ? static_cast<const Document*>(this)->documentRareData() : NodeRareData::rareDataFromMap(this);
+    ASSERT(data);
+    return data;
 }
 
 NodeRareData* Node::ensureRareData()
 {
     if (hasRareData())
         return rareData();
-    
-    ASSERT(!NodeRareData::rareDataMap().contains(this));
+
     NodeRareData* data = ""
-    NodeRareData::rareDataMap().set(this, data);
+    if (isDocumentNode()) {
+        // Fast path for a Document. A Document knows a pointer to NodeRareData.
+        ASSERT(!static_cast<Document*>(this)->documentRareData());
+        static_cast<Document*>(this)->setDocumentRareData(data);
+    } else {
+        ASSERT(!NodeRareData::rareDataMap().contains(this));
+        NodeRareData::rareDataMap().set(this, data);
+    }
     setFlag(HasRareDataFlag);
     return data;
 }
@@ -489,11 +496,19 @@
     ASSERT(!transientMutationObserverRegistry() || transientMutationObserverRegistry()->isEmpty());
 #endif
 
-    NodeRareData::NodeRareDataMap& dataMap = NodeRareData::rareDataMap();
-    NodeRareData::NodeRareDataMap::iterator it = dataMap.find(this);
-    ASSERT(it != dataMap.end());
-    delete it->second;
-    dataMap.remove(it);
+    if (isDocumentNode()) {
+        Document* document = static_cast<Document*>(this);
+        NodeRareData* data = ""
+        ASSERT(data);
+        delete data;
+        document->setDocumentRareData(0);
+    } else {
+        NodeRareData::NodeRareDataMap& dataMap = NodeRareData::rareDataMap();
+        NodeRareData::NodeRareDataMap::iterator it = dataMap.find(this);
+        ASSERT(it != dataMap.end());
+        delete it->second;
+        dataMap.remove(it);
+    }
     clearFlag(HasRareDataFlag);
 }
 
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to