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

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

Issue 262093006: Oilpan: Make the Node hierarchy RefCountedGarbageCollected instead of TreeShared. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Address more comments. Created 6 years, 7 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 | Annotate | Revision Log
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2007 Apple Inc. All rights reserved. 2 * Copyright (C) 2007 Apple Inc. All rights reserved.
3 * (C) 2008 Nikolas Zimmermann <zimmermann@kde.org> 3 * (C) 2008 Nikolas Zimmermann <zimmermann@kde.org>
4 * 4 *
5 * This library is free software; you can redistribute it and/or 5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public 6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either 7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version. 8 * version 2 of the License, or (at your option) any later version.
9 * 9 *
10 * This library is distributed in the hope that it will be useful, 10 * This library is distributed in the hope that it will be useful,
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
64 void notifyNodeRemovedFromTree(ContainerNode&); 64 void notifyNodeRemovedFromTree(ContainerNode&);
65 65
66 ContainerNode& m_insertionPoint; 66 ContainerNode& m_insertionPoint;
67 }; 67 };
68 68
69 namespace Private { 69 namespace Private {
70 70
71 template<class GenericNode, class GenericNodeContainer> 71 template<class GenericNode, class GenericNodeContainer>
72 void addChildNodesToDeletionQueue(GenericNode*& head, GenericNode*& tail, Ge nericNodeContainer&); 72 void addChildNodesToDeletionQueue(GenericNode*& head, GenericNode*& tail, Ge nericNodeContainer&);
73 73
74 } 74 // Helper methods for removeDetachedChildrenInContainer, hidden from WebCore namespace
75
76 // Helper functions for TreeShared-derived classes, which have a 'Node' style in terface
77 // This applies to 'ContainerNode' and 'SVGElementInstance'
78 template<class GenericNode, class GenericNodeContainer>
79 inline void removeDetachedChildrenInContainer(GenericNodeContainer& container)
80 {
81 // List of nodes to be deleted.
82 GenericNode* head = 0;
83 GenericNode* tail = 0;
84
85 Private::addChildNodesToDeletionQueue<GenericNode, GenericNodeContainer>(hea d, tail, container);
86
87 GenericNode* n;
88 GenericNode* next;
89 while ((n = head) != 0) {
90 #if !ENABLE(OILPAN)
91 ASSERT_WITH_SECURITY_IMPLICATION(n->m_deletionHasBegun);
92 #endif
93
94 next = n->nextSibling();
95 n->setNextSibling(0);
96
97 head = next;
98 if (next == 0)
99 tail = 0;
100
101 if (n->hasChildren())
102 Private::addChildNodesToDeletionQueue<GenericNode, GenericNodeContai ner>(head, tail, static_cast<GenericNodeContainer&>(*n));
103
104 #if !ENABLE(OILPAN)
105 delete n;
106 #endif
107 }
108 }
109
110 template<class GenericNode, class GenericNodeContainer>
111 inline void appendChildToContainer(GenericNode& child, GenericNodeContainer& con tainer)
112 {
113 child.setParentOrShadowHostNode(&container);
114
115 GenericNode* lastChild = container.lastChild();
116 if (lastChild) {
117 child.setPreviousSibling(lastChild);
118 lastChild->setNextSibling(&child);
119 } else {
120 container.setFirstChild(&child);
121 }
122
123 container.setLastChild(&child);
124 }
125
126 // Helper methods for removeDetachedChildrenInContainer, hidden from WebCore nam espace
127 namespace Private {
128 75
129 template<class GenericNode, class GenericNodeContainer, bool dispatchRemoval Notification> 76 template<class GenericNode, class GenericNodeContainer, bool dispatchRemoval Notification>
130 struct NodeRemovalDispatcher { 77 struct NodeRemovalDispatcher {
131 static void dispatch(GenericNode&, GenericNodeContainer&) 78 static void dispatch(GenericNode&, GenericNodeContainer&)
132 { 79 {
133 // no-op, by default 80 // no-op, by default
134 } 81 }
135 }; 82 };
136 83
137 template<class GenericNode, class GenericNodeContainer> 84 template<class GenericNode, class GenericNodeContainer>
(...skipping 26 matching lines...) Expand all
164 for (GenericNode* n = container.firstChild(); n; n = next) { 111 for (GenericNode* n = container.firstChild(); n; n = next) {
165 ASSERT_WITH_SECURITY_IMPLICATION(!n->m_deletionHasBegun); 112 ASSERT_WITH_SECURITY_IMPLICATION(!n->m_deletionHasBegun);
166 113
167 next = n->nextSibling(); 114 next = n->nextSibling();
168 n->setNextSibling(0); 115 n->setNextSibling(0);
169 n->setParentOrShadowHostNode(0); 116 n->setParentOrShadowHostNode(0);
170 container.setFirstChild(next); 117 container.setFirstChild(next);
171 if (next) 118 if (next)
172 next->setPreviousSibling(0); 119 next->setPreviousSibling(0);
173 120
174 #if ENABLE(OILPAN)
175 {
176 // Always notify nodes of removal from the document even if they
177 // are going to die. Nodes do not immediately die when their
178 // refcounts reach zero with Oilpan. They die at the next garbag e
179 // collection. The notifications when removed from document
180 // allows us to perform cleanup on the nodes when they are remov ed
181 // instead of when their destructors are called.
182 RefPtr<GenericNode> protect(n); // removedFromDocument may remov e all references to this node.
183 NodeRemovalDispatcher<GenericNode, GenericNodeContainer, ShouldD ispatchRemovalNotification<GenericNode>::value>::dispatch(*n, container);
184 }
185 if (!n->refCount()) {
186 // Add the node to the list of nodes to be deleted.
187 // Reuse the nextSibling pointer for this purpose.
188 if (tail)
189 tail->setNextSibling(n);
190 else
191 head = n;
192
193 tail = n;
194 }
195 #else
196 if (!n->refCount()) { 121 if (!n->refCount()) {
197 #if SECURITY_ASSERT_ENABLED 122 #if SECURITY_ASSERT_ENABLED
198 n->m_deletionHasBegun = true; 123 n->m_deletionHasBegun = true;
199 #endif 124 #endif
200 // Add the node to the list of nodes to be deleted. 125 // Add the node to the list of nodes to be deleted.
201 // Reuse the nextSibling pointer for this purpose. 126 // Reuse the nextSibling pointer for this purpose.
202 if (tail) 127 if (tail)
203 tail->setNextSibling(n); 128 tail->setNextSibling(n);
204 else 129 else
205 head = n; 130 head = n;
206 131
207 tail = n; 132 tail = n;
208 } else { 133 } else {
209 RefPtr<GenericNode> protect(n); // removedFromDocument may remov e all references to this node. 134 RefPtr<GenericNode> protect(n); // removedFromDocument may remov e all references to this node.
210 NodeRemovalDispatcher<GenericNode, GenericNodeContainer, ShouldD ispatchRemovalNotification<GenericNode>::value>::dispatch(*n, container); 135 NodeRemovalDispatcher<GenericNode, GenericNodeContainer, ShouldD ispatchRemovalNotification<GenericNode>::value>::dispatch(*n, container);
211 } 136 }
212 #endif // ENABLE(OILPAN)
213 } 137 }
214 138
215 container.setLastChild(0); 139 container.setLastChild(0);
216 } 140 }
217 141
218 } // namespace Private 142 } // namespace Private
219 143
144 // Helper functions for TreeShared-derived classes, which have a 'Node' style in terface
145 // This applies to 'ContainerNode' and 'SVGElementInstance'
haraken 2014/05/06 04:20:16 FYI, SVGElementInstance is going to be removed soo
Mads Ager (chromium) 2014/05/06 08:26:00 That is great! Right now this code is only used fo
146 template<class GenericNode, class GenericNodeContainer>
147 inline void removeDetachedChildrenInContainer(GenericNodeContainer& container)
haraken 2014/05/06 04:20:16 Just help me understand (very fundamental question
Mads Ager (chromium) 2014/05/06 08:26:00 Yes, it is very confusing. This is still called by
148 {
149 #if ENABLE(OILPAN)
150 // Always dispatch node removal notifications when nodes are
151 // removed. This maintains the invariant that either nodes have
152 // been removed from their container and their removedFrom method has
153 // been called, or the nodes die with the their container.
haraken 2014/05/06 04:20:16 the their container => their container Just to co
Mads Ager (chromium) 2014/05/06 08:26:00 That is correct. This is only called from SVGEleme
154 GenericNode* next = 0;
155 for (GenericNode* n = container.firstChild(); n; n = next) {
156 next = n->nextSibling();
157 n->setNextSibling(0);
158 n->setParentOrShadowHostNode(0);
159 if (next)
160 next->setPreviousSibling(0);
161 Private::NodeRemovalDispatcher<GenericNode, GenericNodeContainer, Privat e::ShouldDispatchRemovalNotification<GenericNode>::value>::dispatch(*n, containe r);
162 }
163 container.setFirstChild(0);
164 container.setLastChild(0);
165 #else
166 // List of nodes to be deleted.
167 GenericNode* head = 0;
168 GenericNode* tail = 0;
169
170 Private::addChildNodesToDeletionQueue<GenericNode, GenericNodeContainer>(hea d, tail, container);
171
172 GenericNode* n;
173 GenericNode* next;
174 while ((n = head) != 0) {
175 ASSERT_WITH_SECURITY_IMPLICATION(n->m_deletionHasBegun);
176
177 next = n->nextSibling();
178 n->setNextSibling(0);
179
180 head = next;
181 if (next == 0)
182 tail = 0;
183
184 if (n->hasChildren())
185 Private::addChildNodesToDeletionQueue<GenericNode, GenericNodeContai ner>(head, tail, static_cast<GenericNodeContainer&>(*n));
186
187 delete n;
188 }
189 #endif
190 }
191
192 template<class GenericNode, class GenericNodeContainer>
193 inline void appendChildToContainer(GenericNode& child, GenericNodeContainer& con tainer)
194 {
195 child.setParentOrShadowHostNode(&container);
196
197 GenericNode* lastChild = container.lastChild();
198 if (lastChild) {
199 child.setPreviousSibling(lastChild);
200 lastChild->setNextSibling(&child);
201 } else {
202 container.setFirstChild(&child);
203 }
204
205 container.setLastChild(&child);
206 }
207
220 inline void ChildNodeInsertionNotifier::notifyNodeInsertedIntoDocument(Node& nod e) 208 inline void ChildNodeInsertionNotifier::notifyNodeInsertedIntoDocument(Node& nod e)
221 { 209 {
222 ASSERT(m_insertionPoint.inDocument()); 210 ASSERT(m_insertionPoint.inDocument());
223 RefPtr<Node> protect(node); 211 RefPtr<Node> protect(node);
224 if (Node::InsertionShouldCallDidNotifySubtreeInsertions == node.insertedInto (&m_insertionPoint)) 212 if (Node::InsertionShouldCallDidNotifySubtreeInsertions == node.insertedInto (&m_insertionPoint))
225 m_postInsertionNotificationTargets.append(&node); 213 m_postInsertionNotificationTargets.append(&node);
226 if (node.isContainerNode()) 214 if (node.isContainerNode())
227 notifyDescendantInsertedIntoDocument(toContainerNode(node)); 215 notifyDescendantInsertedIntoDocument(toContainerNode(node));
228 } 216 }
229 217
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
358 for (Node* child = m_root.firstChild(); child; child = child->nextSiblin g()) 346 for (Node* child = m_root.firstChild(); child; child = child->nextSiblin g())
359 collectFrameOwners(*child); 347 collectFrameOwners(*child);
360 } 348 }
361 349
362 disconnectCollectedFrameOwners(); 350 disconnectCollectedFrameOwners();
363 } 351 }
364 352
365 } // namespace WebCore 353 } // namespace WebCore
366 354
367 #endif // ContainerNodeAlgorithms_h 355 #endif // ContainerNodeAlgorithms_h
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698