WebKit Bugzilla
New
Browse
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
RESOLVED FIXED
92965
Optimize ChildNode{Insertion,Removal}Notifier::notify() by lazily taking a snapshot of child nodes
https://bugs.webkit.org/show_bug.cgi?id=92965
Summary
Optimize ChildNode{Insertion,Removal}Notifier::notify() by lazily taking a sn...
Kentaro Hara
Reported
2012-08-02 02:45:42 PDT
notifyDescendantRemovedFromDocument() cannot iterate child nodes in this way: void notifyDescendantRemovedFromDocument(Node* node) { for (Node* child = node->firstChild(); child; child = child->nextSibling()) { ...; notifyNodeRemovedFromDocument(child); } } This is because notifyNodeRemovedFromDocument(child) might dispatch events and the events might change child trees. To avoid security issues, the current code takes a snapshot of child nodes before starting the iteration, like this. void notifyDescendantRemovedFromDocument(Node* node) { NodeVector children; getChildNodes(node, children); // Take a snapshot. for (int i = 0; i < children.size(); i++) { ...; notifyNodeRemovedFromDocument(children[i]); } } Based on the observation that in almost all cases events won't be dispatched from inside notifyNodeRemovedFromDocument(), we can implement a "lazy" snapshot. The snapshot is taken at the point where EventDispatcher::dispatchEvent() is invoked. The snapshot is not taken unless any event is dispatched.
Attachments
Patch
(8.67 KB, patch)
2012-08-02 02:50 PDT
,
Kentaro Hara
no flags
Details
Formatted Diff
Diff
Patch
(8.67 KB, patch)
2012-08-02 02:51 PDT
,
Kentaro Hara
no flags
Details
Formatted Diff
Diff
Patch
(8.77 KB, patch)
2012-08-02 04:30 PDT
,
Kentaro Hara
no flags
Details
Formatted Diff
Diff
Patch
(9.49 KB, patch)
2012-08-02 19:58 PDT
,
Kentaro Hara
no flags
Details
Formatted Diff
Diff
patch for landing
(10.01 KB, patch)
2012-08-07 18:08 PDT
,
Kentaro Hara
no flags
Details
Formatted Diff
Diff
patch for landing
(9.54 KB, patch)
2012-08-07 18:09 PDT
,
Kentaro Hara
no flags
Details
Formatted Diff
Diff
Show Obsolete
(3)
View All
Add attachment
proposed patch, testcase, etc.
Kentaro Hara
Comment 1
2012-08-02 02:50:06 PDT
Created
attachment 156020
[details]
Patch
Kentaro Hara
Comment 2
2012-08-02 02:51:10 PDT
Created
attachment 156022
[details]
Patch
Kentaro Hara
Comment 3
2012-08-02 04:30:24 PDT
Created
attachment 156040
[details]
Patch
Adam Barth
Comment 4
2012-08-02 08:17:13 PDT
Comment on
attachment 156040
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=156040&action=review
Nice idea. Some detailed comments below.
> Source/WebCore/dom/ContainerNode.h:304 > +static ChildNodesSnapshot* latestSnapshot = 0;
Please don't add static global variables to header files. That will add storage for this variable to every complication unit that includes this header!
> Source/WebCore/dom/ContainerNode.h:324 > + if (m_childNodes) > + delete m_childNodes;
Can we use an OwnPtr to have this delete happen automatically?
> Source/WebCore/dom/ContainerNode.h:338 > + Node* ret = (*m_childNodes)[m_currentIndex++].get();
ret -> node (prefer complete words in variable names)
> Source/WebCore/dom/ContainerNode.h:344 > + if (!hasSnapshot()) {
Prefer early return.
> Source/WebCore/dom/ContainerNodeAlgorithms.cpp:69 > + ChildNodesSnapshot snapshot(node);
I'd put the word "Lazy" into the name of this class to make it clear that the snapshot is happening lazily.
Kentaro Hara
Comment 5
2012-08-02 19:58:14 PDT
Created
attachment 156248
[details]
Patch
Kentaro Hara
Comment 6
2012-08-02 19:58:57 PDT
(In reply to
comment #3
)
> > Source/WebCore/dom/ContainerNode.h:304 > > +static ChildNodesSnapshot* latestSnapshot = 0; > > Please don't add static global variables to header files. That will add storage for this variable to every complication unit that includes this header! > > > Source/WebCore/dom/ContainerNode.h:324 > > + if (m_childNodes) > > + delete m_childNodes; > > Can we use an OwnPtr to have this delete happen automatically? > > > Source/WebCore/dom/ContainerNode.h:338 > > + Node* ret = (*m_childNodes)[m_currentIndex++].get(); > > ret -> node (prefer complete words in variable names) > > > Source/WebCore/dom/ContainerNode.h:344 > > + if (!hasSnapshot()) { > > Prefer early return. > > > Source/WebCore/dom/ContainerNodeAlgorithms.cpp:69 > > + ChildNodesSnapshot snapshot(node); > > I'd put the word "Lazy" into the name of this class to make it clear that the snapshot is happening lazily.
All done. Thanks.
Adam Barth
Comment 7
2012-08-07 17:01:44 PDT
Comment on
attachment 156248
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=156248&action=review
> Source/WebCore/dom/ContainerNode.h:308 > + ChildNodesLazySnapshot(Node* parentNode)
explicit
> Source/WebCore/dom/ContainerNode.h:325 > + if (LIKELY(!m_childNodes.get())) {
Can we call hasSnapshot() here? That would be slightly more readable.
Kentaro Hara
Comment 8
2012-08-07 18:08:03 PDT
Created
attachment 157065
[details]
patch for landing
Kentaro Hara
Comment 9
2012-08-07 18:09:35 PDT
Created
attachment 157066
[details]
patch for landing
WebKit Review Bot
Comment 10
2012-08-07 22:38:51 PDT
Comment on
attachment 157066
[details]
patch for landing Clearing flags on attachment: 157066 Committed
r124990
: <
http://trac.webkit.org/changeset/124990
>
Ojan Vafai
Comment 11
2012-08-08 11:59:36 PDT
Could we do this same trick for the methods in ContainerNode that call collectChildrenAndRemoveFromOldParent and/or collectTargetNodes? It might have a performance benefit for large innerHTML calls for example.
Kentaro Hara
Comment 12
2012-08-08 16:39:03 PDT
(In reply to
comment #11
)
> Could we do this same trick for the methods in ContainerNode that call collectChildrenAndRemoveFromOldParent and/or collectTargetNodes? It might have a performance benefit for large innerHTML calls for example.
Yes, I'll do after investigating performance and security stuff.
Ryosuke Niwa
Comment 13
2012-08-09 21:55:36 PDT
Nice! 9% improvement indeed.
http://webkit-perf.appspot.com/graph.html#tests=[[40018,2001,32196]]&sel=1344366304381.4546,1344436602563.2727,2520.1612903225805,4758.064516129032&displayrange=7&datatype=running
Note
You need to
log in
before you can comment on or make changes to this bug.
Top of Page
Format For Printing
XML
Clone This Bug