Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(37)

Side by Side Diff: Source/core/dom/ContainerNode.cpp

Issue 15871005: Avoid N^2 walk placing renderers when building the render tree (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Adding a mitigation for the perf regression to Element::recalcStyle. Created 7 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « Source/core/dom/ContainerNode.h ('k') | Source/core/dom/ContainerNodeAlgorithms.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3 * (C) 1999 Antti Koivisto (koivisto@kde.org) 3 * (C) 1999 Antti Koivisto (koivisto@kde.org)
4 * (C) 2001 Dirk Mueller (mueller@kde.org) 4 * (C) 2001 Dirk Mueller (mueller@kde.org)
5 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserv ed. 5 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserv ed.
6 * 6 *
7 * This library is free software; you can redistribute it and/or 7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public 8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either 9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version. 10 * version 2 of the License, or (at your option) any later version.
(...skipping 29 matching lines...) Expand all
40 #include "wtf/Vector.h" 40 #include "wtf/Vector.h"
41 41
42 using namespace std; 42 using namespace std;
43 43
44 namespace WebCore { 44 namespace WebCore {
45 45
46 static void dispatchChildInsertionEvents(Node*); 46 static void dispatchChildInsertionEvents(Node*);
47 static void dispatchChildRemovalEvents(Node*); 47 static void dispatchChildRemovalEvents(Node*);
48 static void updateTreeAfterInsertion(ContainerNode*, Node*, AttachBehavior); 48 static void updateTreeAfterInsertion(ContainerNode*, Node*, AttachBehavior);
49 49
50 typedef pair<NodeCallback, RefPtr<Node> > CallbackInfo; 50 typedef pair<NodeCallback, RefPtr<Node> > NodeCallbackInfo;
51 typedef Vector<CallbackInfo> NodeCallbackQueue; 51 typedef Vector<NodeCallbackInfo> NodeCallbackQueue;
52 typedef pair<ElementCallback, RefPtr<Element> > ElementCallbackInfo;
53 typedef Vector<ElementCallbackInfo> ElementCallbackQueue;
52 54
53 static NodeCallbackQueue* s_postAttachCallbackQueue; 55 static NodeCallbackQueue* s_postAttachCallbackQueue;
56 static ElementCallbackQueue* s_insertionCallbackQueue;
54 57
58 static size_t s_insertionDepth;
55 static size_t s_attachDepth; 59 static size_t s_attachDepth;
56 60
57 ChildNodesLazySnapshot* ChildNodesLazySnapshot::latestSnapshot = 0; 61 ChildNodesLazySnapshot* ChildNodesLazySnapshot::latestSnapshot = 0;
58 62
59 #ifndef NDEBUG 63 #ifndef NDEBUG
60 unsigned NoEventDispatchAssertion::s_count = 0; 64 unsigned NoEventDispatchAssertion::s_count = 0;
61 #endif 65 #endif
62 66
63 static void collectChildrenAndRemoveFromOldParent(Node* node, NodeVector& nodes, ExceptionCode& ec) 67 static void collectChildrenAndRemoveFromOldParent(Node* node, NodeVector& nodes, ExceptionCode& ec)
64 { 68 {
(...skipping 617 matching lines...) Expand 10 before | Expand all | Expand 10 after
682 { 686 {
683 if (s_attachDepth == 1) { 687 if (s_attachDepth == 1) {
684 RefPtr<ContainerNode> protect(this); 688 RefPtr<ContainerNode> protect(this);
685 689
686 if (s_postAttachCallbackQueue) 690 if (s_postAttachCallbackQueue)
687 dispatchPostAttachCallbacks(); 691 dispatchPostAttachCallbacks();
688 } 692 }
689 --s_attachDepth; 693 --s_attachDepth;
690 } 694 }
691 695
696 void ContainerNode::suspendInsertionCallbacks()
697 {
698 ++s_insertionDepth;
699 }
700
701 void ContainerNode::resumeInsertionCallbacks()
702 {
703 if (s_insertionDepth == 1 && s_insertionCallbackQueue)
704 dispatchInsertionCallbacks();
705 --s_insertionDepth;
706 }
707
708 void ContainerNode::queueInsertionCallback(ElementCallback callback, Element* el ement)
709 {
710 if (!s_insertionDepth) {
711 (*callback)(element);
712 return;
713 }
714 if (!s_insertionCallbackQueue)
715 s_insertionCallbackQueue = new ElementCallbackQueue;
716 s_insertionCallbackQueue->append(ElementCallbackInfo(callback, element));
717 }
718
692 void ContainerNode::queuePostAttachCallback(NodeCallback callback, Node* node) 719 void ContainerNode::queuePostAttachCallback(NodeCallback callback, Node* node)
693 { 720 {
694 if (!s_postAttachCallbackQueue) 721 if (!s_postAttachCallbackQueue)
695 s_postAttachCallbackQueue = new NodeCallbackQueue; 722 s_postAttachCallbackQueue = new NodeCallbackQueue;
696 s_postAttachCallbackQueue->append(CallbackInfo(callback, node)); 723 s_postAttachCallbackQueue->append(NodeCallbackInfo(callback, node));
697 } 724 }
698 725
699 bool ContainerNode::postAttachCallbacksAreSuspended() 726 bool ContainerNode::postAttachCallbacksAreSuspended()
700 { 727 {
701 return s_attachDepth; 728 return s_attachDepth;
702 } 729 }
703 730
704 void ContainerNode::dispatchPostAttachCallbacks() 731 void ContainerNode::dispatchPostAttachCallbacks()
705 { 732 {
706 // We recalculate size() each time through the loop because a callback 733 // We recalculate size() each time through the loop because a callback
707 // can add more callbacks to the end of the queue. 734 // can add more callbacks to the end of the queue.
708 for (size_t i = 0; i < s_postAttachCallbackQueue->size(); ++i) { 735 for (size_t i = 0; i < s_postAttachCallbackQueue->size(); ++i) {
709 const CallbackInfo& info = (*s_postAttachCallbackQueue)[i]; 736 const NodeCallbackInfo& info = (*s_postAttachCallbackQueue)[i];
710 info.first(info.second.get()); 737 info.first(info.second.get());
711 } 738 }
712 s_postAttachCallbackQueue->clear(); 739 s_postAttachCallbackQueue->clear();
713 } 740 }
714 741
715 void ContainerNode::attach(const AttachContext& context) 742 void ContainerNode::attach(const AttachContext& context)
716 { 743 {
717 attachChildren(context); 744 attachChildren(context);
718 Node::attach(context); 745 Node::attach(context);
719 } 746 }
(...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after
1027 if (c->parentNode() && document->hasListenerType(Document::DOMNODEREMOVED_LI STENER)) 1054 if (c->parentNode() && document->hasListenerType(Document::DOMNODEREMOVED_LI STENER))
1028 c->dispatchScopedEvent(MutationEvent::create(eventNames().DOMNodeRemoved Event, true, c->parentNode())); 1055 c->dispatchScopedEvent(MutationEvent::create(eventNames().DOMNodeRemoved Event, true, c->parentNode()));
1029 1056
1030 // dispatch the DOMNodeRemovedFromDocument event to all descendants 1057 // dispatch the DOMNodeRemovedFromDocument event to all descendants
1031 if (c->inDocument() && document->hasListenerType(Document::DOMNODEREMOVEDFRO MDOCUMENT_LISTENER)) { 1058 if (c->inDocument() && document->hasListenerType(Document::DOMNODEREMOVEDFRO MDOCUMENT_LISTENER)) {
1032 for (; c; c = NodeTraversal::next(c.get(), child)) 1059 for (; c; c = NodeTraversal::next(c.get(), child))
1033 c->dispatchScopedEvent(MutationEvent::create(eventNames().DOMNodeRem ovedFromDocumentEvent, false)); 1060 c->dispatchScopedEvent(MutationEvent::create(eventNames().DOMNodeRem ovedFromDocumentEvent, false));
1034 } 1061 }
1035 } 1062 }
1036 1063
1064 void ContainerNode::dispatchInsertionCallbacks()
1065 {
1066 for (size_t i = s_insertionCallbackQueue->size(); i; --i) {
1067 const ElementCallbackInfo& info = (*s_insertionCallbackQueue)[i - 1];
1068 info.first(info.second.get());
1069 }
1070 s_insertionCallbackQueue->clear();
1071 }
1072
1037 static void updateTreeAfterInsertion(ContainerNode* parent, Node* child, AttachB ehavior attachBehavior) 1073 static void updateTreeAfterInsertion(ContainerNode* parent, Node* child, AttachB ehavior attachBehavior)
1038 { 1074 {
1039 ASSERT(parent->refCount()); 1075 ASSERT(parent->refCount());
1040 ASSERT(child->refCount()); 1076 ASSERT(child->refCount());
1041 1077
1042 ChildListMutationScope(parent).childAdded(child); 1078 ChildListMutationScope(parent).childAdded(child);
1043 1079
1044 parent->childrenChanged(false, child->previousSibling(), child->nextSibling( ), 1); 1080 parent->childrenChanged(false, child->previousSibling(), child->nextSibling( ), 1);
1045 1081
1046 ChildNodeInsertionNotifier(parent).notify(child); 1082 ChildNodeInsertionNotifier(parent).notify(child);
(...skipping 20 matching lines...) Expand all
1067 return true; 1103 return true;
1068 1104
1069 if (node->isElementNode() && toElement(node)->shadow()) 1105 if (node->isElementNode() && toElement(node)->shadow())
1070 return true; 1106 return true;
1071 1107
1072 return false; 1108 return false;
1073 } 1109 }
1074 #endif 1110 #endif
1075 1111
1076 } // namespace WebCore 1112 } // namespace WebCore
OLDNEW
« no previous file with comments | « Source/core/dom/ContainerNode.h ('k') | Source/core/dom/ContainerNodeAlgorithms.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698