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

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

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: Merging ToT Created 7 years, 6 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
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, 2009, 2010, 2011 Apple Inc. All rights reserved. 5 * Copyright (C) 2004, 2005, 2006, 2007, 2009, 2010, 2011 Apple Inc. All rights reserved.
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 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
73 #endif 73 #endif
74 74
75 private: 75 private:
76 #ifndef NDEBUG 76 #ifndef NDEBUG
77 static unsigned s_count; 77 static unsigned s_count;
78 #endif 78 #endif
79 }; 79 };
80 80
81 class ContainerNode : public Node { 81 class ContainerNode : public Node {
82 friend class PostAttachCallbackDisabler; 82 friend class PostAttachCallbackDisabler;
83 friend class InsertionCallbackDeferer;
83 public: 84 public:
84 virtual ~ContainerNode(); 85 virtual ~ContainerNode();
85 86
86 Node* firstChild() const { return m_firstChild; } 87 Node* firstChild() const { return m_firstChild; }
87 Node* lastChild() const { return m_lastChild; } 88 Node* lastChild() const { return m_lastChild; }
88 bool hasChildNodes() const { return m_firstChild; } 89 bool hasChildNodes() const { return m_firstChild; }
89 90
90 // ParentNode interface API 91 // ParentNode interface API
91 PassRefPtr<HTMLCollection> children(); 92 PassRefPtr<HTMLCollection> children();
92 Element* firstElementChild() const; 93 Element* firstElementChild() const;
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
133 134
134 void disconnectDescendantFrames(); 135 void disconnectDescendantFrames();
135 136
136 virtual bool childShouldCreateRenderer(const NodeRenderingContext&) const { return true; } 137 virtual bool childShouldCreateRenderer(const NodeRenderingContext&) const { return true; }
137 138
138 virtual void reportMemoryUsage(MemoryObjectInfo*) const OVERRIDE; 139 virtual void reportMemoryUsage(MemoryObjectInfo*) const OVERRIDE;
139 140
140 protected: 141 protected:
141 ContainerNode(TreeScope*, ConstructionType = CreateContainer); 142 ContainerNode(TreeScope*, ConstructionType = CreateContainer);
142 143
144 static void queueInsertionCallback(NodeCallback, Node*);
145 static bool insertionCallbacksAreSuspended();
143 static void queuePostAttachCallback(NodeCallback, Node*); 146 static void queuePostAttachCallback(NodeCallback, Node*);
144 static bool postAttachCallbacksAreSuspended(); 147 static bool postAttachCallbacksAreSuspended();
145 148
146 template<class GenericNode, class GenericNodeContainer> 149 template<class GenericNode, class GenericNodeContainer>
147 friend void appendChildToContainer(GenericNode* child, GenericNodeContainer* ); 150 friend void appendChildToContainer(GenericNode* child, GenericNodeContainer* );
148 151
149 template<class GenericNode, class GenericNodeContainer> 152 template<class GenericNode, class GenericNodeContainer>
150 friend void Private::addChildNodesToDeletionQueue(GenericNode*& head, Generi cNode*& tail, GenericNodeContainer*); 153 friend void Private::addChildNodesToDeletionQueue(GenericNode*& head, Generi cNode*& tail, GenericNodeContainer*);
151 154
152 void removeDetachedChildren(); 155 void removeDetachedChildren();
153 void setFirstChild(Node* child) { m_firstChild = child; } 156 void setFirstChild(Node* child) { m_firstChild = child; }
154 void setLastChild(Node* child) { m_lastChild = child; } 157 void setLastChild(Node* child) { m_lastChild = child; }
155 158
156 private: 159 private:
157 void removeBetween(Node* previousChild, Node* nextChild, Node* oldChild); 160 void removeBetween(Node* previousChild, Node* nextChild, Node* oldChild);
158 void insertBeforeCommon(Node* nextChild, Node* oldChild); 161 void insertBeforeCommon(Node* nextChild, Node* oldChild);
159 162
160 static void dispatchPostAttachCallbacks(); 163 static void dispatchPostAttachCallbacks();
164
161 void suspendPostAttachCallbacks(); 165 void suspendPostAttachCallbacks();
162 void resumePostAttachCallbacks(); 166 void resumePostAttachCallbacks();
163 167
168 static void dispatchInsertionCallbacks();
169
170 static void suspendInsertionCallbacks();
171 static void resumeInsertionCallbacks();
172
164 Node* m_firstChild; 173 Node* m_firstChild;
165 Node* m_lastChild; 174 Node* m_lastChild;
166 }; 175 };
167 176
168 #ifndef NDEBUG 177 #ifndef NDEBUG
169 bool childAttachedAllowedWhenAttachingChildren(ContainerNode*); 178 bool childAttachedAllowedWhenAttachingChildren(ContainerNode*);
170 #endif 179 #endif
171 180
172 inline ContainerNode* toContainerNode(Node* node) 181 inline ContainerNode* toContainerNode(Node* node)
173 { 182 {
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
277 ASSERT(!nodes.size()); 286 ASSERT(!nodes.size());
278 for (Node* child = node->firstChild(); child; child = child->nextSibling()) 287 for (Node* child = node->firstChild(); child; child = child->nextSibling())
279 nodes.append(child); 288 nodes.append(child);
280 } 289 }
281 290
282 class ChildNodesLazySnapshot { 291 class ChildNodesLazySnapshot {
283 WTF_MAKE_NONCOPYABLE(ChildNodesLazySnapshot); 292 WTF_MAKE_NONCOPYABLE(ChildNodesLazySnapshot);
284 WTF_MAKE_FAST_ALLOCATED; 293 WTF_MAKE_FAST_ALLOCATED;
285 public: 294 public:
286 explicit ChildNodesLazySnapshot(Node* parentNode) 295 explicit ChildNodesLazySnapshot(Node* parentNode)
287 : m_currentNode(parentNode->firstChild()) 296 : m_currentNode(parentNode->lastChild())
288 , m_currentIndex(0) 297 , m_currentIndex(0)
289 { 298 {
290 m_nextSnapshot = latestSnapshot; 299 m_nextSnapshot = latestSnapshot;
291 latestSnapshot = this; 300 latestSnapshot = this;
292 } 301 }
293 302
294 ~ChildNodesLazySnapshot() 303 ~ChildNodesLazySnapshot()
295 { 304 {
296 latestSnapshot = m_nextSnapshot; 305 latestSnapshot = m_nextSnapshot;
297 } 306 }
298 307
299 // Returns 0 if there is no next Node. 308 // Returns 0 if there is no previous Node.
300 PassRefPtr<Node> nextNode() 309 PassRefPtr<Node> previousNode()
301 { 310 {
302 if (LIKELY(!hasSnapshot())) { 311 if (LIKELY(!hasSnapshot())) {
303 RefPtr<Node> node = m_currentNode; 312 RefPtr<Node> node = m_currentNode;
304 if (node) 313 if (node)
305 m_currentNode = node->nextSibling(); 314 m_currentNode = node->previousSibling();
306 return node.release(); 315 return node.release();
307 } 316 }
308 Vector<RefPtr<Node> >& nodeVector = *m_childNodes; 317 Vector<RefPtr<Node> >& nodeVector = *m_childNodes;
309 if (m_currentIndex >= nodeVector.size()) 318 if (m_currentIndex >= nodeVector.size())
310 return 0; 319 return 0;
311 return nodeVector[m_currentIndex++]; 320 return nodeVector[m_currentIndex++];
312 } 321 }
313 322
314 void takeSnapshot() 323 void takeSnapshot()
315 { 324 {
316 if (hasSnapshot()) 325 if (hasSnapshot())
317 return; 326 return;
318 m_childNodes = adoptPtr(new Vector<RefPtr<Node> >()); 327 m_childNodes = adoptPtr(new Vector<RefPtr<Node> >());
319 Node* node = m_currentNode.get(); 328 Node* node = m_currentNode.get();
320 while (node) { 329 while (node) {
321 m_childNodes->append(node); 330 m_childNodes->append(node);
322 node = node->nextSibling(); 331 node = node->previousSibling();
323 } 332 }
324 } 333 }
325 334
326 ChildNodesLazySnapshot* nextSnapshot() { return m_nextSnapshot; } 335 ChildNodesLazySnapshot* nextSnapshot() { return m_nextSnapshot; }
327 bool hasSnapshot() { return !!m_childNodes.get(); } 336 bool hasSnapshot() { return !!m_childNodes.get(); }
328 337
329 static void takeChildNodesLazySnapshot() 338 static void takeChildNodesLazySnapshot()
330 { 339 {
331 ChildNodesLazySnapshot* snapshot = latestSnapshot; 340 ChildNodesLazySnapshot* snapshot = latestSnapshot;
332 while (snapshot && !snapshot->hasSnapshot()) { 341 while (snapshot && !snapshot->hasSnapshot()) {
333 snapshot->takeSnapshot(); 342 snapshot->takeSnapshot();
334 snapshot = snapshot->nextSnapshot(); 343 snapshot = snapshot->nextSnapshot();
335 } 344 }
336 } 345 }
337 346
338 private: 347 private:
339 static ChildNodesLazySnapshot* latestSnapshot; 348 static ChildNodesLazySnapshot* latestSnapshot;
340 349
341 RefPtr<Node> m_currentNode; 350 RefPtr<Node> m_currentNode;
342 unsigned m_currentIndex; 351 unsigned m_currentIndex;
343 OwnPtr<Vector<RefPtr<Node> > > m_childNodes; // Lazily instantiated. 352 OwnPtr<Vector<RefPtr<Node> > > m_childNodes; // Lazily instantiated.
344 ChildNodesLazySnapshot* m_nextSnapshot; 353 ChildNodesLazySnapshot* m_nextSnapshot;
345 }; 354 };
346 355
356 // Used to ensure Radio Buttons resolve their checked state in document
357 // order when a subtree of them is inserted. This is necessary because
358 // we resolve style in reverse document order.
359 class InsertionCallbackDeferer {
360 public:
361 InsertionCallbackDeferer()
362 {
363 ContainerNode::suspendInsertionCallbacks();
364 }
365
366 ~InsertionCallbackDeferer()
367 {
368 ContainerNode::resumeInsertionCallbacks();
369 }
370 };
371
347 class PostAttachCallbackDisabler { 372 class PostAttachCallbackDisabler {
348 public: 373 public:
349 PostAttachCallbackDisabler(ContainerNode* node) 374 PostAttachCallbackDisabler(ContainerNode* node)
350 : m_node(node) 375 : m_node(node)
351 { 376 {
352 ASSERT(m_node); 377 ASSERT(m_node);
353 m_node->suspendPostAttachCallbacks(); 378 m_node->suspendPostAttachCallbacks();
354 } 379 }
355 380
356 ~PostAttachCallbackDisabler() 381 ~PostAttachCallbackDisabler()
357 { 382 {
358 m_node->resumePostAttachCallbacks(); 383 m_node->resumePostAttachCallbacks();
359 } 384 }
360 385
361 private: 386 private:
362 ContainerNode* m_node; 387 ContainerNode* m_node;
363 }; 388 };
364 389
365 } // namespace WebCore 390 } // namespace WebCore
366 391
367 #endif // ContainerNode_h 392 #endif // ContainerNode_h
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698