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

Side by Side Diff: third_party/WebKit/Source/core/dom/ScriptRunner.cpp

Issue 1620983002: Also transfer pending in-order scripts upon element moving to new document (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: also remove is-disposed checking; unnecessary Created 4 years, 11 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) 2010 Google, Inc. All Rights Reserved. 2 * Copyright (C) 2010 Google, Inc. All Rights Reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions 5 * modification, are permitted provided that the following conditions
6 * are met: 6 * are met:
7 * 1. Redistributions of source code must retain the above copyright 7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer. 8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright 9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the 10 * notice, this list of conditions and the following disclaimer in the
(...skipping 24 matching lines...) Expand all
35 #include "public/platform/WebThread.h" 35 #include "public/platform/WebThread.h"
36 36
37 namespace blink { 37 namespace blink {
38 38
39 ScriptRunner::ScriptRunner(Document* document) 39 ScriptRunner::ScriptRunner(Document* document)
40 : m_document(document) 40 : m_document(document)
41 , m_taskRunner(Platform::current()->currentThread()->scheduler()->loadingTas kRunner()) 41 , m_taskRunner(Platform::current()->currentThread()->scheduler()->loadingTas kRunner())
42 , m_numberOfInOrderScriptsWithPendingNotification(0) 42 , m_numberOfInOrderScriptsWithPendingNotification(0)
43 , m_isSuspended(false) 43 , m_isSuspended(false)
44 #if !ENABLE(OILPAN) 44 #if !ENABLE(OILPAN)
45 , m_isDisposed(false)
46 , m_weakPointerFactoryForTasks(this) 45 , m_weakPointerFactoryForTasks(this)
47 #endif 46 #endif
48 { 47 {
49 ASSERT(document); 48 ASSERT(document);
50 #ifndef NDEBUG 49 #ifndef NDEBUG
51 m_hasEverBeenSuspended = false; 50 m_hasEverBeenSuspended = false;
52 #endif 51 #endif
53 } 52 }
54 53
55 ScriptRunner::~ScriptRunner() 54 ScriptRunner::~ScriptRunner()
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
91 scriptLoader->detach(); 90 scriptLoader->detach();
92 for (ScriptLoader* scriptLoader : m_inOrderScriptsToExecuteSoon) 91 for (ScriptLoader* scriptLoader : m_inOrderScriptsToExecuteSoon)
93 scriptLoader->detach(); 92 scriptLoader->detach();
94 for (ScriptLoader* scriptLoader : m_asyncScriptsToExecuteSoon) 93 for (ScriptLoader* scriptLoader : m_asyncScriptsToExecuteSoon)
95 scriptLoader->detach(); 94 scriptLoader->detach();
96 95
97 m_pendingInOrderScripts.clear(); 96 m_pendingInOrderScripts.clear();
98 m_pendingAsyncScripts.clear(); 97 m_pendingAsyncScripts.clear();
99 m_inOrderScriptsToExecuteSoon.clear(); 98 m_inOrderScriptsToExecuteSoon.clear();
100 m_asyncScriptsToExecuteSoon.clear(); 99 m_asyncScriptsToExecuteSoon.clear();
101 m_isDisposed = true; 100 m_numberOfInOrderScriptsWithPendingNotification = 0;
102 } 101 }
103 #endif 102 #endif
104 103
105 void ScriptRunner::addPendingAsyncScript(ScriptLoader* scriptLoader)
106 {
107 m_document->incrementLoadEventDelayCount();
108 m_pendingAsyncScripts.add(scriptLoader);
109 }
110
111 void ScriptRunner::queueScriptForExecution(ScriptLoader* scriptLoader, Execution Type executionType) 104 void ScriptRunner::queueScriptForExecution(ScriptLoader* scriptLoader, Execution Type executionType)
112 { 105 {
113 ASSERT(scriptLoader); 106 ASSERT(scriptLoader);
114 107 m_document->incrementLoadEventDelayCount();
115 switch (executionType) { 108 switch (executionType) {
116 case ASYNC_EXECUTION: 109 case ASYNC_EXECUTION:
117 addPendingAsyncScript(scriptLoader); 110 m_pendingAsyncScripts.add(scriptLoader);
118 break; 111 break;
119 112
120 case IN_ORDER_EXECUTION: 113 case IN_ORDER_EXECUTION:
121 m_document->incrementLoadEventDelayCount();
122 m_pendingInOrderScripts.append(scriptLoader); 114 m_pendingInOrderScripts.append(scriptLoader);
123 m_numberOfInOrderScriptsWithPendingNotification++; 115 m_numberOfInOrderScriptsWithPendingNotification++;
124 break; 116 break;
125 } 117 }
126 } 118 }
127 119
128 void ScriptRunner::postTask(const WebTraceLocation& webTraceLocation) 120 void ScriptRunner::postTask(const WebTraceLocation& webTraceLocation)
129 { 121 {
130 // TODO(altimin): Replace all this with `new Task(this)` when Oilpan is here . 122 // TODO(altimin): Replace all this with `new Task(this)` when Oilpan is here .
131 WeakPtrWillBeRawPtr<ScriptRunner> scriptRunnerForTask; 123 WeakPtrWillBeRawPtr<ScriptRunner> scriptRunnerForTask;
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
184 176
185 while (!m_pendingInOrderScripts.isEmpty() && m_pendingInOrderScripts.fir st()->isReady()) { 177 while (!m_pendingInOrderScripts.isEmpty() && m_pendingInOrderScripts.fir st()->isReady()) {
186 m_inOrderScriptsToExecuteSoon.append(m_pendingInOrderScripts.takeFir st()); 178 m_inOrderScriptsToExecuteSoon.append(m_pendingInOrderScripts.takeFir st());
187 postTask(BLINK_FROM_HERE); 179 postTask(BLINK_FROM_HERE);
188 } 180 }
189 181
190 break; 182 break;
191 } 183 }
192 } 184 }
193 185
186 bool ScriptRunner::removePendingInOrderScript(ScriptLoader* scriptLoader)
187 {
188 for (auto it = m_pendingInOrderScripts.begin(); it != m_pendingInOrderScript s.end(); ++it) {
189 if (*it == scriptLoader) {
190 m_pendingInOrderScripts.remove(it);
191 RELEASE_ASSERT_WITH_SECURITY_IMPLICATION(m_numberOfInOrderScriptsWit hPendingNotification > 0);
192 m_numberOfInOrderScriptsWithPendingNotification--;
193 return true;
194 }
195 }
196 return false;
197 }
198
194 void ScriptRunner::notifyScriptLoadError(ScriptLoader* scriptLoader, ExecutionTy pe executionType) 199 void ScriptRunner::notifyScriptLoadError(ScriptLoader* scriptLoader, ExecutionTy pe executionType)
195 { 200 {
196 switch (executionType) { 201 switch (executionType) {
197 case ASYNC_EXECUTION: { 202 case ASYNC_EXECUTION: {
198 bool foundLoader = m_pendingAsyncScripts.contains(scriptLoader);
199 #if !ENABLE(OILPAN)
200 // If the document and ScriptRunner has been disposed of, there's
201 // no bookkeeping to be done here.
202 foundLoader = foundLoader || m_isDisposed;
203 #endif
204 // RELEASE_ASSERT makes us crash in a controlled way in error cases 203 // RELEASE_ASSERT makes us crash in a controlled way in error cases
205 // where the ScriptLoader is associated with the wrong ScriptRunner 204 // where the ScriptLoader is associated with the wrong ScriptRunner
206 // (otherwise we'd cause a use-after-free in ~ScriptRunner when it tries 205 // (otherwise we'd cause a use-after-free in ~ScriptRunner when it tries
207 // to detach). 206 // to detach).
208 RELEASE_ASSERT_WITH_SECURITY_IMPLICATION(foundLoader); 207 RELEASE_ASSERT_WITH_SECURITY_IMPLICATION(m_pendingAsyncScripts.contains( scriptLoader));
209 m_pendingAsyncScripts.remove(scriptLoader); 208 m_pendingAsyncScripts.remove(scriptLoader);
210 break; 209 break;
211 } 210 }
212 case IN_ORDER_EXECUTION: 211 case IN_ORDER_EXECUTION:
213 RELEASE_ASSERT_WITH_SECURITY_IMPLICATION(m_numberOfInOrderScriptsWithPen dingNotification > 0); 212 RELEASE_ASSERT_WITH_SECURITY_IMPLICATION(removePendingInOrderScript(scri ptLoader));
214 m_numberOfInOrderScriptsWithPendingNotification--;
215
216 bool foundPendingScript = false;
217 for (auto it = m_pendingInOrderScripts.begin(); it != m_pendingInOrderSc ripts.end(); ++it) {
218 if (*it == scriptLoader) {
219 m_pendingInOrderScripts.remove(it);
220 foundPendingScript = true;
221 break;
222 }
223 }
224 #if !ENABLE(OILPAN)
225 foundPendingScript = foundPendingScript || m_isDisposed;
226 #endif
227 RELEASE_ASSERT_WITH_SECURITY_IMPLICATION(foundPendingScript);
228 break; 213 break;
229 } 214 }
230 scriptLoader->detach(); 215 scriptLoader->detach();
231 m_document->decrementLoadEventDelayCount(); 216 m_document->decrementLoadEventDelayCount();
232 } 217 }
233 218
234 void ScriptRunner::movePendingAsyncScript(Document& oldDocument, Document& newDo cument, ScriptLoader* scriptLoader) 219 void ScriptRunner::movePendingScript(Document& oldDocument, Document& newDocumen t, ScriptLoader* scriptLoader)
235 { 220 {
236 RefPtrWillBeRawPtr<Document> newContextDocument = newDocument.contextDocumen t().get(); 221 RefPtrWillBeRawPtr<Document> newContextDocument = newDocument.contextDocumen t().get();
237 if (!newContextDocument) { 222 if (!newContextDocument) {
238 // Document's contextDocument() method will return no Document if the 223 // Document's contextDocument() method will return no Document if the
239 // following conditions both hold: 224 // following conditions both hold:
240 // 225 //
241 // - The Document wasn't created with an explicit context document 226 // - The Document wasn't created with an explicit context document
242 // and that document is otherwise kept alive. 227 // and that document is otherwise kept alive.
243 // - The Document itself is detached from its frame. 228 // - The Document itself is detached from its frame.
244 // 229 //
245 // The script element's loader is in that case moved to document() and 230 // The script element's loader is in that case moved to document() and
246 // its script runner, which is the non-null Document that contextDocumen t() 231 // its script runner, which is the non-null Document that contextDocumen t()
247 // would return if not detached. 232 // would return if not detached.
248 ASSERT(!newDocument.frame()); 233 ASSERT(!newDocument.frame());
249 newContextDocument = &newDocument; 234 newContextDocument = &newDocument;
250 } 235 }
251 RefPtrWillBeRawPtr<Document> oldContextDocument = oldDocument.contextDocumen t().get(); 236 RefPtrWillBeRawPtr<Document> oldContextDocument = oldDocument.contextDocumen t().get();
252 if (!oldContextDocument) { 237 if (!oldContextDocument) {
253 ASSERT(!oldDocument.frame()); 238 ASSERT(!oldDocument.frame());
254 oldContextDocument = &oldDocument; 239 oldContextDocument = &oldDocument;
255 } 240 }
256 if (oldContextDocument != newContextDocument) 241 if (oldContextDocument != newContextDocument)
257 oldContextDocument->scriptRunner()->movePendingAsyncScript(newContextDoc ument->scriptRunner(), scriptLoader); 242 oldContextDocument->scriptRunner()->movePendingScript(newContextDocument ->scriptRunner(), scriptLoader);
258 } 243 }
259 244
260 void ScriptRunner::movePendingAsyncScript(ScriptRunner* newRunner, ScriptLoader* scriptLoader) 245 void ScriptRunner::movePendingScript(ScriptRunner* newRunner, ScriptLoader* scri ptLoader)
261 { 246 {
262 if (m_pendingAsyncScripts.contains(scriptLoader)) { 247 if (m_pendingAsyncScripts.contains(scriptLoader)) {
263 newRunner->addPendingAsyncScript(scriptLoader); 248 newRunner->queueScriptForExecution(scriptLoader, ASYNC_EXECUTION);
264 m_pendingAsyncScripts.remove(scriptLoader); 249 m_pendingAsyncScripts.remove(scriptLoader);
265 m_document->decrementLoadEventDelayCount(); 250 m_document->decrementLoadEventDelayCount();
251 return;
252 }
253 if (removePendingInOrderScript(scriptLoader)) {
254 newRunner->queueScriptForExecution(scriptLoader, IN_ORDER_EXECUTION);
255 m_document->decrementLoadEventDelayCount();
266 } 256 }
267 } 257 }
268 258
269 // Returns true if task was run, and false otherwise. 259 // Returns true if task was run, and false otherwise.
270 bool ScriptRunner::executeTaskFromQueue(WillBeHeapDeque<RawPtrWillBeMember<Scrip tLoader>>* taskQueue) 260 bool ScriptRunner::executeTaskFromQueue(WillBeHeapDeque<RawPtrWillBeMember<Scrip tLoader>>* taskQueue)
271 { 261 {
272 if (taskQueue->isEmpty()) 262 if (taskQueue->isEmpty())
273 return false; 263 return false;
274 taskQueue->takeFirst()->execute(); 264 taskQueue->takeFirst()->execute();
275 265
(...skipping 23 matching lines...) Expand all
299 #if ENABLE(OILPAN) 289 #if ENABLE(OILPAN)
300 visitor->trace(m_document); 290 visitor->trace(m_document);
301 visitor->trace(m_pendingInOrderScripts); 291 visitor->trace(m_pendingInOrderScripts);
302 visitor->trace(m_pendingAsyncScripts); 292 visitor->trace(m_pendingAsyncScripts);
303 visitor->trace(m_asyncScriptsToExecuteSoon); 293 visitor->trace(m_asyncScriptsToExecuteSoon);
304 visitor->trace(m_inOrderScriptsToExecuteSoon); 294 visitor->trace(m_inOrderScriptsToExecuteSoon);
305 #endif 295 #endif
306 } 296 }
307 297
308 } // namespace blink 298 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/dom/ScriptRunner.h ('k') | third_party/WebKit/Source/core/html/HTMLScriptElement.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698