Skip to content

Commit c387aeb

Browse files
author
zhangjipeng
committed
feat: remove DeprecatedPtrList code
Signed-off-by: zhangjipeng <zhangjipeng@xiaomi.com>
1 parent bfd4abf commit c387aeb

File tree

13 files changed

+607
-159
lines changed

13 files changed

+607
-159
lines changed

src/webcore/dom/Document.cpp

Lines changed: 41 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,7 @@ static bool acceptsEditingFocus(Node *node)
258258
return frame->editor()->shouldBeginEditing(rangeOfContents(root).get());
259259
}
260260

261-
DeprecatedPtrList<Document>* Document::changedDocuments = 0;
261+
Vector<Document*>* Document::changedDocuments = 0;
262262

263263
// FrameView might be 0
264264
Document::Document(DOMImplementation* impl, Frame* frame, bool isXHTML)
@@ -418,8 +418,14 @@ Document::~Document()
418418
}
419419
#endif
420420

421-
if (m_docChanged && changedDocuments)
422-
changedDocuments->remove(this);
421+
if (m_docChanged && changedDocuments) {
422+
for (unsigned i = 0; i < changedDocuments->size(); ++i) {
423+
if (changedDocuments->at(i) == this) {
424+
changedDocuments->remove(i);
425+
break;
426+
}
427+
}
428+
}
423429
delete m_tokenizer;
424430
m_document.resetSkippingRef(0);
425431
delete m_styleSelector;
@@ -993,16 +999,22 @@ void Document::setDocumentChanged(bool b)
993999
if (b) {
9941000
if (!m_docChanged) {
9951001
if (!changedDocuments)
996-
changedDocuments = new DeprecatedPtrList<Document>;
1002+
changedDocuments = new Vector<Document*>;
9971003
changedDocuments->append(this);
9981004
}
9991005
if (m_accessKeyMapValid) {
10001006
m_accessKeyMapValid = false;
10011007
m_elementsByAccessKey.clear();
10021008
}
10031009
} else {
1004-
if (m_docChanged && changedDocuments)
1005-
changedDocuments->remove(this);
1010+
if (m_docChanged && changedDocuments) {
1011+
for (unsigned i = 0; i < changedDocuments->size(); ++i) {
1012+
if (changedDocuments->at(i) == this) {
1013+
changedDocuments->remove(i);
1014+
break;
1015+
}
1016+
}
1017+
}
10061018
}
10071019

10081020
m_docChanged = b;
@@ -1102,7 +1114,10 @@ void Document::updateDocumentsRendering()
11021114
if (!changedDocuments)
11031115
return;
11041116

1105-
while (Document* doc = changedDocuments->take()) {
1117+
// Process and clear in FIFO order.
1118+
while (!changedDocuments->isEmpty()) {
1119+
Document* doc = changedDocuments->at(0);
1120+
changedDocuments->remove(0);
11061121
doc->m_docChanged = false;
11071122
doc->updateRendering();
11081123
}
@@ -2497,8 +2512,18 @@ void Document::removeImage(HTMLImageLoader* image)
24972512
{
24982513
// Remove instances of this image from both lists.
24992514
// Use loops because we allow multiple instances to get into the lists.
2500-
while (m_imageLoadEventDispatchSoonList.removeRef(image)) { }
2501-
while (m_imageLoadEventDispatchingList.removeRef(image)) { }
2515+
for (unsigned i = 0; i < m_imageLoadEventDispatchSoonList.size();) {
2516+
if (m_imageLoadEventDispatchSoonList[i] == image)
2517+
m_imageLoadEventDispatchSoonList.remove(i);
2518+
else
2519+
++i;
2520+
}
2521+
for (unsigned i = 0; i < m_imageLoadEventDispatchingList.size();) {
2522+
if (m_imageLoadEventDispatchingList[i] == image)
2523+
m_imageLoadEventDispatchingList.remove(i);
2524+
else
2525+
++i;
2526+
}
25022527
if (m_imageLoadEventDispatchSoonList.isEmpty())
25032528
m_imageLoadEventTimer.stop();
25042529
}
@@ -2516,15 +2541,13 @@ void Document::dispatchImageLoadEventsNow()
25162541

25172542
m_imageLoadEventDispatchingList = m_imageLoadEventDispatchSoonList;
25182543
m_imageLoadEventDispatchSoonList.clear();
2519-
for (DeprecatedPtrListIterator<HTMLImageLoader> it(m_imageLoadEventDispatchingList); it.current();) {
2520-
HTMLImageLoader* image = it.current();
2521-
// Must advance iterator *before* dispatching call.
2522-
// Otherwise, it might be advanced automatically if dispatching the call had a side effect
2523-
// of destroying the current HTMLImageLoader, and then we would advance past the *next* item,
2524-
// missing one altogether.
2525-
++it;
2526-
image->dispatchLoadEvent();
2527-
}
2544+
2545+
// Iterate over a snapshot so that side effects during dispatch (including calling removeImage)
2546+
// do not cause us to skip items.
2547+
Vector<HTMLImageLoader*> toDispatch = m_imageLoadEventDispatchingList;
2548+
for (unsigned i = 0; i < toDispatch.size(); ++i)
2549+
toDispatch[i]->dispatchLoadEvent();
2550+
25282551
m_imageLoadEventDispatchingList.clear();
25292552
}
25302553

src/webcore/dom/Document.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@
2727

2828
#include "Attr.h"
2929
#include "Color.h"
30-
#include "DeprecatedPtrList.h"
3130
#include "DocumentMarker.h"
3231
#include "HTMLCollection.h"
3332
#include "HTMLFormElement.h"
@@ -37,6 +36,7 @@
3736
#include <wtf/Deque.h>
3837
#include <wtf/HashCountedSet.h>
3938
#include <wtf/ListHashSet.h>
39+
#include <wtf/Vector.h>
4040

4141
namespace WebCore {
4242

@@ -333,7 +333,7 @@ class Document : public ContainerNode {
333333
PassRefPtr<EditingText> createEditingTextNode(const String&);
334334

335335
virtual void recalcStyle( StyleChange = NoChange );
336-
static DeprecatedPtrList<Document>* changedDocuments;
336+
static Vector<Document*>* changedDocuments;
337337
virtual void updateRendering();
338338
void updateLayout();
339339
void updateLayoutIgnorePendingStylesheets();
@@ -779,8 +779,8 @@ class Document : public ContainerNode {
779779
typedef HashMap<RefPtr<Node>, MarkerMapVectorPair*> MarkerMap;
780780
MarkerMap m_markers;
781781

782-
DeprecatedPtrList<HTMLImageLoader> m_imageLoadEventDispatchSoonList;
783-
DeprecatedPtrList<HTMLImageLoader> m_imageLoadEventDispatchingList;
782+
Vector<HTMLImageLoader*> m_imageLoadEventDispatchSoonList;
783+
Vector<HTMLImageLoader*> m_imageLoadEventDispatchingList;
784784
Timer<Document> m_imageLoadEventTimer;
785785

786786
Timer<Document> m_updateFocusAppearanceTimer;

src/webcore/dom/EventTargetNode.cpp

Lines changed: 48 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -183,52 +183,56 @@ bool EventTargetNode::dispatchGenericEvent(PassRefPtr<Event> e, ExceptionCode&,
183183
ASSERT(!evt->type().isNull()); // JavaScript code could create an event with an empty name
184184

185185
// work out what nodes to send event to
186-
DeprecatedPtrList<Node> nodeChain;
186+
Vector<Node*> nodeChain;
187187

188188
if (inDocument()) {
189189
for (Node* n = this; n; n = n->eventParentNode()) {
190190
n->ref();
191-
nodeChain.prepend(n);
191+
nodeChain.insert(0, n);
192192
}
193193
} else {
194194
// if node is not in the document just send event to itself
195195
ref();
196-
nodeChain.prepend(this);
196+
nodeChain.append(this);
197197
}
198-
199-
DeprecatedPtrListIterator<Node> it(nodeChain);
198+
199+
unsigned chainSize = nodeChain.size();
200+
unsigned index = 0;
200201

201202
// Before we begin dispatching events, give the target node a chance to do some work prior
202203
// to the DOM event handlers getting a crack.
203204
void* data = preDispatchEventHandler(evt.get());
204205

205206
// trigger any capturing event handlers on our way down
206207
evt->setEventPhase(Event::CAPTURING_PHASE);
207-
208-
it.toFirst();
208+
209+
index = 0;
209210
// Handle window events for capture phase, except load events, this quirk is needed
210211
// because Mozilla used to never propagate load events to the window object
211-
if (evt->type() != loadEvent && it.current()->isDocumentNode() && !evt->propagationStopped())
212-
static_cast<Document*>(it.current())->handleWindowEvent(evt.get(), true);
212+
if (evt->type() != loadEvent && chainSize && nodeChain[0]->isDocumentNode() && !evt->propagationStopped())
213+
static_cast<Document*>(nodeChain[0])->handleWindowEvent(evt.get(), true);
213214

214-
for (; it.current() && it.current() != this && !evt->propagationStopped(); ++it) {
215-
evt->setCurrentTarget(EventTargetNodeCast(it.current()));
216-
EventTargetNodeCast(it.current())->handleLocalEvents(evt.get(), true);
215+
for (; index < chainSize && nodeChain[index] != this && !evt->propagationStopped(); ++index) {
216+
evt->setCurrentTarget(EventTargetNodeCast(nodeChain[index]));
217+
EventTargetNodeCast(nodeChain[index])->handleLocalEvents(evt.get(), true);
217218
}
218219

219220
// dispatch to the actual target node
220-
it.toLast();
221+
if (chainSize)
222+
index = chainSize - 1;
221223
if (!evt->propagationStopped()) {
222224
evt->setEventPhase(Event::AT_TARGET);
223-
evt->setCurrentTarget(EventTargetNodeCast(it.current()));
225+
evt->setCurrentTarget(EventTargetNodeCast(nodeChain[index]));
224226

225227
// We do want capturing event listeners to be invoked here, even though
226228
// that violates the specification since Mozilla does it.
227-
EventTargetNodeCast(it.current())->handleLocalEvents(evt.get(), true);
229+
EventTargetNodeCast(nodeChain[index])->handleLocalEvents(evt.get(), true);
228230

229-
EventTargetNodeCast(it.current())->handleLocalEvents(evt.get(), false);
231+
EventTargetNodeCast(nodeChain[index])->handleLocalEvents(evt.get(), false);
230232
}
231-
--it;
233+
234+
if (index)
235+
--index;
232236

233237
// ok, now bubble up again (only non-capturing event handlers will be called)
234238
// ### recalculate the node chain here? (e.g. if target node moved in document by previous event handlers)
@@ -244,17 +248,21 @@ bool EventTargetNode::dispatchGenericEvent(PassRefPtr<Event> e, ExceptionCode&,
244248

245249
if (evt->bubbles()) {
246250
evt->setEventPhase(Event::BUBBLING_PHASE);
247-
for (; it.current() && !evt->propagationStopped() && !evt->cancelBubble(); --it) {
248-
evt->setCurrentTarget(EventTargetNodeCast(it.current()));
249-
EventTargetNodeCast(it.current())->handleLocalEvents(evt.get(), false);
251+
for (;; ) {
252+
if (!chainSize || evt->propagationStopped() || evt->cancelBubble())
253+
break;
254+
evt->setCurrentTarget(EventTargetNodeCast(nodeChain[index]));
255+
EventTargetNodeCast(nodeChain[index])->handleLocalEvents(evt.get(), false);
256+
if (!index)
257+
break;
258+
--index;
250259
}
251260
// Handle window events for bubbling phase, except load events, this quirk is needed
252261
// because Mozilla used to never propagate load events at all
253262

254-
it.toFirst();
255-
if (evt->type() != loadEvent && it.current()->isDocumentNode() && !evt->propagationStopped() && !evt->cancelBubble()) {
256-
evt->setCurrentTarget(EventTargetNodeCast(it.current()));
257-
static_cast<Document*>(it.current())->handleWindowEvent(evt.get(), false);
263+
if (evt->type() != loadEvent && chainSize && nodeChain[0]->isDocumentNode() && !evt->propagationStopped() && !evt->cancelBubble()) {
264+
evt->setCurrentTarget(EventTargetNodeCast(nodeChain[0]));
265+
static_cast<Document*>(nodeChain[0])->handleWindowEvent(evt.get(), false);
258266
}
259267
}
260268

@@ -268,17 +276,24 @@ bool EventTargetNode::dispatchGenericEvent(PassRefPtr<Event> e, ExceptionCode&,
268276

269277
// now we call all default event handlers (this is not part of DOM - it is internal to khtml)
270278

271-
it.toLast();
272-
if (evt->bubbles())
273-
for (; it.current() && !evt->defaultPrevented() && !evt->defaultHandled(); --it)
274-
EventTargetNodeCast(it.current())->defaultEventHandler(evt.get());
275-
else if (!evt->defaultPrevented() && !evt->defaultHandled())
276-
EventTargetNodeCast(it.current())->defaultEventHandler(evt.get());
279+
if (chainSize) {
280+
unsigned defaultIndex = chainSize - 1;
281+
if (evt->bubbles()) {
282+
for (;; ) {
283+
if (evt->defaultPrevented() || evt->defaultHandled())
284+
break;
285+
EventTargetNodeCast(nodeChain[defaultIndex])->defaultEventHandler(evt.get());
286+
if (!defaultIndex)
287+
break;
288+
--defaultIndex;
289+
}
290+
} else if (!evt->defaultPrevented() && !evt->defaultHandled())
291+
EventTargetNodeCast(nodeChain[defaultIndex])->defaultEventHandler(evt.get());
292+
}
277293

278294
// deref all nodes in chain
279-
it.toFirst();
280-
for (; it.current(); ++it)
281-
it.current()->deref(); // this may delete us
295+
for (unsigned i = 0; i < chainSize; ++i)
296+
nodeChain[i]->deref(); // this may delete us
282297

283298
Document::updateDocumentsRendering();
284299

src/webcore/dom/XMLTokenizer.cpp

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353
#include <libxml/parserInternals.h>
5454
#include <wtf/Platform.h>
5555
#include <wtf/StringExtras.h>
56+
#include <wtf/Deque.h>
5657
#include <wtf/Vector.h>
5758

5859
#if ENABLE(XSLT)
@@ -78,7 +79,11 @@ class PendingCallbacks {
7879
public:
7980
PendingCallbacks()
8081
{
81-
m_callbacks.setAutoDelete(true);
82+
}
83+
84+
~PendingCallbacks()
85+
{
86+
deleteAllValues(m_callbacks);
8287
}
8388

8489
void appendStartElementNSCallback(const xmlChar* xmlLocalName, const xmlChar* xmlPrefix, const xmlChar* xmlURI, int nb_namespaces,
@@ -183,7 +188,7 @@ class PendingCallbacks {
183188

184189
void callAndRemoveFirstCallback(XMLTokenizer* tokenizer)
185190
{
186-
PendingCallback* cb = m_callbacks.getFirst();
191+
PendingCallback* cb = m_callbacks.first();
187192

188193
cb->call(tokenizer);
189194
m_callbacks.removeFirst();
@@ -332,7 +337,7 @@ class PendingCallbacks {
332337
};
333338

334339
public:
335-
DeprecatedPtrList<PendingCallback> m_callbacks;
340+
Deque<PendingCallback*> m_callbacks;
336341
};
337342
// --------------------------------
338343

0 commit comments

Comments
 (0)