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

Side by Side Diff: Source/core/html/parser/HTMLScriptRunner.cpp

Issue 368283002: Stream scripts to V8 as they load - Blink side. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: renaming Created 6 years, 4 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) 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 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
66 #endif 66 #endif
67 } 67 }
68 68
69 void HTMLScriptRunner::detach() 69 void HTMLScriptRunner::detach()
70 { 70 {
71 if (!m_document) 71 if (!m_document)
72 return; 72 return;
73 73
74 if (m_parserBlockingScript.resource() && m_parserBlockingScript.watchingForL oad()) 74 if (m_parserBlockingScript.resource() && m_parserBlockingScript.watchingForL oad())
75 stopWatchingForLoad(m_parserBlockingScript); 75 stopWatchingForLoad(m_parserBlockingScript);
76 // If the script is streamed, watchingForLoad is false. In that case, we
77 // don't need to do anything (PendingScript will take care of cancelling the
78 // streaming).
haraken 2014/08/17 16:05:28 It's a bit weird that the lifetime of not-streamed
haraken 2014/08/17 16:05:28 Move this comment to above line 74.
marja 2014/08/20 11:45:57 I don't think it's accurate to say "lifetime of no
haraken 2014/08/20 15:00:19 The new version looks nicer to me!
76 79
77 while (!m_scriptsToExecuteAfterParsing.isEmpty()) { 80 while (!m_scriptsToExecuteAfterParsing.isEmpty()) {
78 PendingScript pendingScript = m_scriptsToExecuteAfterParsing.takeFirst() ; 81 PendingScript pendingScript = m_scriptsToExecuteAfterParsing.takeFirst() ;
79 if (pendingScript.resource() && pendingScript.watchingForLoad()) 82 if (pendingScript.resource() && pendingScript.watchingForLoad())
80 stopWatchingForLoad(pendingScript); 83 stopWatchingForLoad(pendingScript);
81 } 84 }
82 m_document = nullptr; 85 m_document = nullptr;
83 } 86 }
84 87
85 static KURL documentURLForScriptExecution(Document* document) 88 static KURL documentURLForScriptExecution(Document* document)
86 { 89 {
87 if (!document) 90 if (!document)
88 return KURL(); 91 return KURL();
89 92
90 if (!document->frame()) { 93 if (!document->frame()) {
91 if (document->importsController()) 94 if (document->importsController())
92 return document->url(); 95 return document->url();
93 return KURL(); 96 return KURL();
94 } 97 }
95 98
96 // Use the URL of the currently active document for this frame. 99 // Use the URL of the currently active document for this frame.
97 return document->frame()->document()->url(); 100 return document->frame()->document()->url();
98 } 101 }
99 102
100 inline PassRefPtrWillBeRawPtr<Event> createScriptLoadEvent() 103 inline PassRefPtrWillBeRawPtr<Event> createScriptLoadEvent()
101 { 104 {
102 return Event::create(EventTypeNames::load); 105 return Event::create(EventTypeNames::load);
103 } 106 }
104 107
105 ScriptSourceCode HTMLScriptRunner::sourceFromPendingScript(const PendingScript& script, bool& errorOccurred) const 108 ScriptSourceCode HTMLScriptRunner::sourceFromPendingScript(PendingScript& script , bool& errorOccurred) const
106 { 109 {
107 if (script.resource()) { 110 if (script.resource()) {
108 errorOccurred = script.resource()->errorOccurred(); 111 errorOccurred = script.resource()->errorOccurred();
109 ASSERT(script.resource()->isLoaded()); 112 ASSERT(script.resource()->isLoaded());
113 if (script.streamer()) {
114 return ScriptSourceCode(script.releaseStreamer(), script.resource()) ;
115 }
110 return ScriptSourceCode(script.resource()); 116 return ScriptSourceCode(script.resource());
111 } 117 }
118 ASSERT(!script.isStreaming());
haraken 2014/08/17 16:05:28 Help me understand: Why is it guaranteed that scri
marja 2014/08/20 11:45:57 Because this function is only called when we want
112 errorOccurred = false; 119 errorOccurred = false;
113 return ScriptSourceCode(script.element()->textContent(), documentURLForScrip tExecution(m_document), script.startingPosition()); 120 return ScriptSourceCode(script.element()->textContent(), documentURLForScrip tExecution(m_document), script.startingPosition());
114 } 121 }
115 122
116 bool HTMLScriptRunner::isPendingScriptReady(const PendingScript& script) 123 bool HTMLScriptRunner::isPendingScriptReady(const PendingScript& script)
117 { 124 {
118 m_hasScriptsWaitingForResources = !m_document->isScriptExecutionReady(); 125 m_hasScriptsWaitingForResources = !m_document->isScriptExecutionReady();
119 if (m_hasScriptsWaitingForResources) 126 if (m_hasScriptsWaitingForResources)
120 return false; 127 return false;
121 if (script.resource() && !script.resource()->isLoaded()) 128 if (script.resource() && !script.resource()->isLoaded())
122 return false; 129 return false;
130 if (script.isStreaming())
131 return false;
123 return true; 132 return true;
124 } 133 }
125 134
126 void HTMLScriptRunner::executeParsingBlockingScript() 135 void HTMLScriptRunner::executeParsingBlockingScript()
127 { 136 {
128 ASSERT(m_document); 137 ASSERT(m_document);
129 ASSERT(!isExecutingScript()); 138 ASSERT(!isExecutingScript());
130 ASSERT(m_document->isScriptExecutionReady()); 139 ASSERT(m_document->isScriptExecutionReady());
131 ASSERT(isPendingScriptReady(m_parserBlockingScript)); 140 ASSERT(isPendingScriptReady(m_parserBlockingScript));
132 141
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
182 191
183 void HTMLScriptRunner::stopWatchingForLoad(PendingScript& pendingScript) 192 void HTMLScriptRunner::stopWatchingForLoad(PendingScript& pendingScript)
184 { 193 {
185 ASSERT(pendingScript.watchingForLoad()); 194 ASSERT(pendingScript.watchingForLoad());
186 pendingScript.resource()->removeClient(this); 195 pendingScript.resource()->removeClient(this);
187 pendingScript.setWatchingForLoad(false); 196 pendingScript.setWatchingForLoad(false);
188 } 197 }
189 198
190 void HTMLScriptRunner::notifyFinished(Resource* cachedResource) 199 void HTMLScriptRunner::notifyFinished(Resource* cachedResource)
191 { 200 {
201 // This function should not be called for the parser blocking script, if
202 // we've finished loading but we're still streaming it. It will be called
203 // when the streaming has completed too.
haraken 2014/08/17 16:05:28 This comment is a bit misleading. Slightly better:
marja 2014/08/20 11:45:57 Done.
204 ASSERT(!(m_parserBlockingScript.resource() == cachedResource
205 && m_parserBlockingScript.isStreaming()));
192 m_host->notifyScriptLoaded(cachedResource); 206 m_host->notifyScriptLoaded(cachedResource);
193 } 207 }
194 208
195 // Implements the steps for 'An end tag whose tag name is "script"' 209 // Implements the steps for 'An end tag whose tag name is "script"'
196 // http://whatwg.org/html#scriptEndTag 210 // http://whatwg.org/html#scriptEndTag
197 // Script handling lives outside the tree builder to keep each class simple. 211 // Script handling lives outside the tree builder to keep each class simple.
198 void HTMLScriptRunner::execute(PassRefPtrWillBeRawPtr<Element> scriptElement, co nst TextPosition& scriptStartPosition) 212 void HTMLScriptRunner::execute(PassRefPtrWillBeRawPtr<Element> scriptElement, co nst TextPosition& scriptStartPosition)
199 { 213 {
200 ASSERT(scriptElement); 214 ASSERT(scriptElement);
201 // FIXME: If scripting is disabled, always just return. 215 // FIXME: If scripting is disabled, always just return.
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
268 void HTMLScriptRunner::requestParsingBlockingScript(Element* element) 282 void HTMLScriptRunner::requestParsingBlockingScript(Element* element)
269 { 283 {
270 if (!requestPendingScript(m_parserBlockingScript, element)) 284 if (!requestPendingScript(m_parserBlockingScript, element))
271 return; 285 return;
272 286
273 ASSERT(m_parserBlockingScript.resource()); 287 ASSERT(m_parserBlockingScript.resource());
274 288
275 // We only care about a load callback if resource is not already 289 // We only care about a load callback if resource is not already
276 // in the cache. Callers will attempt to run the m_parserBlockingScript 290 // in the cache. Callers will attempt to run the m_parserBlockingScript
277 // if possible before returning control to the parser. 291 // if possible before returning control to the parser.
278 if (!m_parserBlockingScript.resource()->isLoaded()) 292 if (!m_parserBlockingScript.resource()->isLoaded()) {
279 watchForLoad(m_parserBlockingScript); 293 if (!V8ScriptStreamer::startStreaming(&m_parserBlockingScript, this)) {
294 watchForLoad(m_parserBlockingScript);
295 }
296 }
280 } 297 }
281 298
282 void HTMLScriptRunner::requestDeferredScript(Element* element) 299 void HTMLScriptRunner::requestDeferredScript(Element* element)
283 { 300 {
284 PendingScript pendingScript; 301 PendingScript pendingScript;
285 if (!requestPendingScript(pendingScript, element)) 302 if (!requestPendingScript(pendingScript, element))
286 return; 303 return;
287 304
288 ASSERT(pendingScript.resource()); 305 ASSERT(pendingScript.resource());
289 m_scriptsToExecuteAfterParsing.append(pendingScript); 306 m_scriptsToExecuteAfterParsing.append(pendingScript);
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
327 344
328 InsertionPointRecord insertionPointRecord(m_host->inputStream()); 345 InsertionPointRecord insertionPointRecord(m_host->inputStream());
329 NestingLevelIncrementer nestingLevelIncrementer(m_scriptNestingLevel); 346 NestingLevelIncrementer nestingLevelIncrementer(m_scriptNestingLevel);
330 347
331 scriptLoader->prepareScript(scriptStartPosition); 348 scriptLoader->prepareScript(scriptStartPosition);
332 349
333 if (!scriptLoader->willBeParserExecuted()) 350 if (!scriptLoader->willBeParserExecuted())
334 return; 351 return;
335 352
336 if (scriptLoader->willExecuteWhenDocumentFinishedParsing()) { 353 if (scriptLoader->willExecuteWhenDocumentFinishedParsing()) {
354 // TODO(marja): in addition to parser blocking scripts, stream also
haraken 2014/08/17 16:05:28 Nit: TODO(marja) => FIXME
marja 2014/08/20 11:45:57 Done.
355 // scripts which are not parser blocking.
haraken 2014/08/17 16:05:28 I wonder if there is any particular reason you can
marja 2014/08/20 11:45:57 (See the other comment.)
337 requestDeferredScript(script); 356 requestDeferredScript(script);
338 } else if (scriptLoader->readyToBeParserExecuted()) { 357 } else if (scriptLoader->readyToBeParserExecuted()) {
339 if (m_scriptNestingLevel == 1) { 358 if (m_scriptNestingLevel == 1) {
340 m_parserBlockingScript.setElement(script); 359 m_parserBlockingScript.setElement(script);
341 m_parserBlockingScript.setStartingPosition(scriptStartPosition); 360 m_parserBlockingScript.setStartingPosition(scriptStartPosition);
342 } else { 361 } else {
343 ScriptSourceCode sourceCode(script->textContent(), documentURLFo rScriptExecution(m_document), scriptStartPosition); 362 ScriptSourceCode sourceCode(script->textContent(), documentURLFo rScriptExecution(m_document), scriptStartPosition);
344 scriptLoader->executeScript(sourceCode); 363 scriptLoader->executeScript(sourceCode);
345 } 364 }
346 } else { 365 } else {
347 requestParsingBlockingScript(script); 366 requestParsingBlockingScript(script);
348 } 367 }
349 } 368 }
350 } 369 }
351 370
352 void HTMLScriptRunner::trace(Visitor* visitor) 371 void HTMLScriptRunner::trace(Visitor* visitor)
353 { 372 {
354 visitor->trace(m_document); 373 visitor->trace(m_document);
355 visitor->trace(m_host); 374 visitor->trace(m_host);
356 visitor->trace(m_parserBlockingScript); 375 visitor->trace(m_parserBlockingScript);
357 visitor->trace(m_scriptsToExecuteAfterParsing); 376 visitor->trace(m_scriptsToExecuteAfterParsing);
358 } 377 }
359 378
360 } 379 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698