OLD | NEW |
---|---|
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 15 matching lines...) Expand all Loading... | |
26 #include "config.h" | 26 #include "config.h" |
27 #include "core/html/parser/HTMLDocumentParser.h" | 27 #include "core/html/parser/HTMLDocumentParser.h" |
28 | 28 |
29 #include "HTMLNames.h" | 29 #include "HTMLNames.h" |
30 #include "core/dom/DocumentFragment.h" | 30 #include "core/dom/DocumentFragment.h" |
31 #include "core/dom/Element.h" | 31 #include "core/dom/Element.h" |
32 #include "core/html/HTMLDocument.h" | 32 #include "core/html/HTMLDocument.h" |
33 #include "core/html/parser/AtomicHTMLToken.h" | 33 #include "core/html/parser/AtomicHTMLToken.h" |
34 #include "core/html/parser/BackgroundHTMLParser.h" | 34 #include "core/html/parser/BackgroundHTMLParser.h" |
35 #include "core/html/parser/HTMLParserScheduler.h" | 35 #include "core/html/parser/HTMLParserScheduler.h" |
36 #include "core/html/parser/HTMLParserThread.h" | |
37 #include "core/html/parser/HTMLScriptRunner.h" | 36 #include "core/html/parser/HTMLScriptRunner.h" |
38 #include "core/html/parser/HTMLTreeBuilder.h" | 37 #include "core/html/parser/HTMLTreeBuilder.h" |
39 #include "core/inspector/InspectorInstrumentation.h" | 38 #include "core/inspector/InspectorInstrumentation.h" |
40 #include "core/frame/Frame.h" | 39 #include "core/frame/Frame.h" |
40 #include "core/loader/DocumentLoader.h" | |
41 #include "platform/SharedBuffer.h" | 41 #include "platform/SharedBuffer.h" |
42 #include "platform/Task.h" | |
42 #include "platform/TraceEvent.h" | 43 #include "platform/TraceEvent.h" |
44 #include "public/platform/WebParserResourceBridge.h" | |
45 #include "public/platform/WebThread.h" | |
43 #include "wtf/Functional.h" | 46 #include "wtf/Functional.h" |
44 | 47 |
45 namespace WebCore { | 48 namespace WebCore { |
46 | 49 |
47 using namespace HTMLNames; | 50 using namespace HTMLNames; |
48 | 51 |
49 // This is a direct transcription of step 4 from: | 52 // This is a direct transcription of step 4 from: |
50 // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-end.html#frag ment-case | 53 // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-end.html#frag ment-case |
51 static HTMLTokenizer::State tokenizerStateForContextElement(Element* contextElem ent, bool reportErrors, const HTMLParserOptions& options) | 54 static HTMLTokenizer::State tokenizerStateForContextElement(Element* contextElem ent, bool reportErrors, const HTMLParserOptions& options) |
52 { | 55 { |
(...skipping 14 matching lines...) Expand all Loading... | |
67 if (contextTag.matches(scriptTag)) | 70 if (contextTag.matches(scriptTag)) |
68 return reportErrors ? HTMLTokenizer::ScriptDataState : HTMLTokenizer::PL AINTEXTState; | 71 return reportErrors ? HTMLTokenizer::ScriptDataState : HTMLTokenizer::PL AINTEXTState; |
69 if (contextTag.matches(plaintextTag)) | 72 if (contextTag.matches(plaintextTag)) |
70 return HTMLTokenizer::PLAINTEXTState; | 73 return HTMLTokenizer::PLAINTEXTState; |
71 return HTMLTokenizer::DataState; | 74 return HTMLTokenizer::DataState; |
72 } | 75 } |
73 | 76 |
74 HTMLDocumentParser::HTMLDocumentParser(HTMLDocument* document, bool reportErrors ) | 77 HTMLDocumentParser::HTMLDocumentParser(HTMLDocument* document, bool reportErrors ) |
75 : ScriptableDocumentParser(document) | 78 : ScriptableDocumentParser(document) |
76 , m_options(document) | 79 , m_options(document) |
77 , m_token(m_options.useThreading ? nullptr : adoptPtr(new HTMLToken)) | |
78 , m_tokenizer(m_options.useThreading ? nullptr : HTMLTokenizer::create(m_opt ions)) | |
79 , m_scriptRunner(HTMLScriptRunner::create(document, this)) | 80 , m_scriptRunner(HTMLScriptRunner::create(document, this)) |
80 , m_treeBuilder(HTMLTreeBuilder::create(this, document, parserContentPolicy( ), reportErrors, m_options)) | 81 , m_treeBuilder(HTMLTreeBuilder::create(this, document, parserContentPolicy( ), reportErrors, m_options)) |
81 , m_parserScheduler(HTMLParserScheduler::create(this)) | 82 , m_parserScheduler(HTMLParserScheduler::create(this)) |
82 , m_xssAuditorDelegate(document) | 83 , m_xssAuditorDelegate(document) |
83 , m_weakFactory(this) | 84 , m_weakFactory(this) |
84 , m_preloader(adoptPtr(new HTMLResourcePreloader(document))) | 85 , m_preloader(adoptPtr(new HTMLResourcePreloader(document))) |
85 , m_isPinnedToMainThread(false) | 86 , m_isPinnedToMainThread(false) |
86 , m_endWasDelayed(false) | 87 , m_endWasDelayed(false) |
87 , m_haveBackgroundParser(false) | |
88 , m_pumpSessionNestingLevel(0) | 88 , m_pumpSessionNestingLevel(0) |
89 , m_parserThread(0) | |
90 , m_parserThreadIsStandalone(false) | |
89 { | 91 { |
90 ASSERT(shouldUseThreading() || (m_token && m_tokenizer)); | 92 if (shouldUseThreading()) |
93 startBackgroundParser(); | |
abarth-chromium
2013/12/18 18:28:49
Does this integrate correctly with m_isPinnedToMai
oystein (OOO til 10th of July)
2014/01/13 23:19:50
As far as I can tell so far, parsers which aren't
| |
94 | |
95 if (!m_parserThread) { | |
96 m_token = adoptPtr(new HTMLToken); | |
97 m_tokenizer = HTMLTokenizer::create(m_options); | |
98 } | |
91 } | 99 } |
92 | 100 |
93 // FIXME: Member variables should be grouped into self-initializing structs to | 101 // FIXME: Member variables should be grouped into self-initializing structs to |
94 // minimize code duplication between these constructors. | 102 // minimize code duplication between these constructors. |
95 HTMLDocumentParser::HTMLDocumentParser(DocumentFragment* fragment, Element* cont extElement, ParserContentPolicy parserContentPolicy) | 103 HTMLDocumentParser::HTMLDocumentParser(DocumentFragment* fragment, Element* cont extElement, ParserContentPolicy parserContentPolicy) |
96 : ScriptableDocumentParser(&fragment->document(), parserContentPolicy) | 104 : ScriptableDocumentParser(&fragment->document(), parserContentPolicy) |
97 , m_options(&fragment->document()) | 105 , m_options(&fragment->document()) |
98 , m_token(adoptPtr(new HTMLToken)) | 106 , m_token(adoptPtr(new HTMLToken)) |
99 , m_tokenizer(HTMLTokenizer::create(m_options)) | 107 , m_tokenizer(HTMLTokenizer::create(m_options)) |
100 , m_treeBuilder(HTMLTreeBuilder::create(this, fragment, contextElement, this ->parserContentPolicy(), m_options)) | 108 , m_treeBuilder(HTMLTreeBuilder::create(this, fragment, contextElement, this ->parserContentPolicy(), m_options)) |
101 , m_xssAuditorDelegate(&fragment->document()) | 109 , m_xssAuditorDelegate(&fragment->document()) |
102 , m_weakFactory(this) | 110 , m_weakFactory(this) |
103 , m_isPinnedToMainThread(true) | 111 , m_isPinnedToMainThread(true) |
104 , m_endWasDelayed(false) | 112 , m_endWasDelayed(false) |
105 , m_haveBackgroundParser(false) | |
106 , m_pumpSessionNestingLevel(0) | 113 , m_pumpSessionNestingLevel(0) |
114 , m_parserThread(0) | |
115 , m_parserThreadIsStandalone(false) | |
107 { | 116 { |
108 ASSERT(!shouldUseThreading()); | 117 ASSERT(!shouldUseThreading()); |
109 bool reportErrors = false; // For now document fragment parsing never report s errors. | 118 bool reportErrors = false; // For now document fragment parsing never report s errors. |
110 m_tokenizer->setState(tokenizerStateForContextElement(contextElement, report Errors, m_options)); | 119 m_tokenizer->setState(tokenizerStateForContextElement(contextElement, report Errors, m_options)); |
111 m_xssAuditor.initForFragment(); | 120 m_xssAuditor.initForFragment(); |
112 } | 121 } |
113 | 122 |
114 HTMLDocumentParser::~HTMLDocumentParser() | 123 HTMLDocumentParser::~HTMLDocumentParser() |
115 { | 124 { |
116 ASSERT(!m_parserScheduler); | 125 ASSERT(!m_parserScheduler); |
117 ASSERT(!m_pumpSessionNestingLevel); | 126 ASSERT(!m_pumpSessionNestingLevel); |
118 ASSERT(!m_preloadScanner); | 127 ASSERT(!m_preloadScanner); |
119 ASSERT(!m_insertionPreloadScanner); | 128 ASSERT(!m_insertionPreloadScanner); |
120 ASSERT(!m_haveBackgroundParser); | 129 ASSERT(!m_parserThread); |
121 // FIXME: We should be able to ASSERT(m_speculations.isEmpty()), | 130 // FIXME: We should be able to ASSERT(m_speculations.isEmpty()), |
122 // but there are cases where that's not true currently. For example, | 131 // but there are cases where that's not true currently. For example, |
123 // we we're told to stop parsing before we've consumed all the input. | 132 // we we're told to stop parsing before we've consumed all the input. |
124 } | 133 } |
125 | 134 |
126 void HTMLDocumentParser::pinToMainThread() | 135 void HTMLDocumentParser::pinToMainThread() |
127 { | 136 { |
128 ASSERT(!m_haveBackgroundParser); | 137 ASSERT(!m_parserThread); |
129 ASSERT(!m_isPinnedToMainThread); | 138 ASSERT(!m_isPinnedToMainThread); |
130 m_isPinnedToMainThread = true; | 139 m_isPinnedToMainThread = true; |
131 if (!m_tokenizer) { | 140 if (!m_tokenizer) { |
132 ASSERT(!m_token); | 141 ASSERT(!m_token); |
133 m_token = adoptPtr(new HTMLToken); | 142 m_token = adoptPtr(new HTMLToken); |
134 m_tokenizer = HTMLTokenizer::create(m_options); | 143 m_tokenizer = HTMLTokenizer::create(m_options); |
135 } | 144 } |
136 } | 145 } |
137 | 146 |
138 void HTMLDocumentParser::detach() | 147 void HTMLDocumentParser::detach() |
139 { | 148 { |
140 if (m_haveBackgroundParser) | 149 if (m_parserThread) |
141 stopBackgroundParser(); | 150 stopBackgroundParser(); |
142 DocumentParser::detach(); | 151 DocumentParser::detach(); |
143 if (m_scriptRunner) | 152 if (m_scriptRunner) |
144 m_scriptRunner->detach(); | 153 m_scriptRunner->detach(); |
145 m_treeBuilder->detach(); | 154 m_treeBuilder->detach(); |
146 // FIXME: It seems wrong that we would have a preload scanner here. | 155 // FIXME: It seems wrong that we would have a preload scanner here. |
147 // Yet during fast/dom/HTMLScriptElement/script-load-events.html we do. | 156 // Yet during fast/dom/HTMLScriptElement/script-load-events.html we do. |
148 m_preloadScanner.clear(); | 157 m_preloadScanner.clear(); |
149 m_insertionPreloadScanner.clear(); | 158 m_insertionPreloadScanner.clear(); |
150 m_parserScheduler.clear(); // Deleting the scheduler will clear any timers. | 159 m_parserScheduler.clear(); // Deleting the scheduler will clear any timers. |
151 } | 160 } |
152 | 161 |
153 void HTMLDocumentParser::stopParsing() | 162 void HTMLDocumentParser::stopParsing() |
154 { | 163 { |
155 DocumentParser::stopParsing(); | 164 DocumentParser::stopParsing(); |
156 m_parserScheduler.clear(); // Deleting the scheduler will clear any timers. | 165 m_parserScheduler.clear(); // Deleting the scheduler will clear any timers. |
157 if (m_haveBackgroundParser) | 166 if (m_parserThread) |
158 stopBackgroundParser(); | 167 stopBackgroundParser(); |
159 } | 168 } |
160 | 169 |
161 // This kicks off "Once the user agent stops parsing" as described by: | 170 // This kicks off "Once the user agent stops parsing" as described by: |
162 // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-end.html#the- end | 171 // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-end.html#the- end |
163 void HTMLDocumentParser::prepareToStopParsing() | 172 void HTMLDocumentParser::prepareToStopParsing() |
164 { | 173 { |
165 // FIXME: It may not be correct to disable this for the background parser. | 174 // FIXME: It may not be correct to disable this for the background parser. |
166 // That means hasInsertionPoint() may not be correct in some cases. | 175 // That means hasInsertionPoint() may not be correct in some cases. |
167 ASSERT(!hasInsertionPoint() || m_haveBackgroundParser); | 176 ASSERT(!hasInsertionPoint() || m_parserThread); |
168 | 177 |
169 // pumpTokenizer can cause this parser to be detached from the Document, | 178 // pumpTokenizer can cause this parser to be detached from the Document, |
170 // but we need to ensure it isn't deleted yet. | 179 // but we need to ensure it isn't deleted yet. |
171 RefPtr<HTMLDocumentParser> protect(this); | 180 RefPtr<HTMLDocumentParser> protect(this); |
172 | 181 |
173 // NOTE: This pump should only ever emit buffered character tokens, | 182 // NOTE: This pump should only ever emit buffered character tokens, |
174 // so ForceSynchronous vs. AllowYield should be meaningless. | 183 // so ForceSynchronous vs. AllowYield should be meaningless. |
175 if (m_tokenizer) { | 184 if (m_tokenizer) { |
176 ASSERT(!m_haveBackgroundParser); | 185 ASSERT(!m_parserThread); |
177 pumpTokenizerIfPossible(ForceSynchronous); | 186 pumpTokenizerIfPossible(ForceSynchronous); |
178 } | 187 } |
179 | 188 |
180 if (isStopped()) | 189 if (isStopped()) |
181 return; | 190 return; |
182 | 191 |
183 DocumentParser::prepareToStopParsing(); | 192 DocumentParser::prepareToStopParsing(); |
184 | 193 |
185 // We will not have a scriptRunner when parsing a DocumentFragment. | 194 // We will not have a scriptRunner when parsing a DocumentFragment. |
186 if (m_scriptRunner) | 195 if (m_scriptRunner) |
187 document()->setReadyState(Document::Interactive); | 196 document()->setReadyState(Document::Interactive); |
188 | 197 |
189 // Setting the ready state above can fire mutation event and detach us | 198 // Setting the ready state above can fire mutation event and detach us |
190 // from underneath. In that case, just bail out. | 199 // from underneath. In that case, just bail out. |
191 if (isDetached()) | 200 if (isDetached()) |
192 return; | 201 return; |
193 | 202 |
194 attemptToRunDeferredScriptsAndEnd(); | 203 attemptToRunDeferredScriptsAndEnd(); |
195 } | 204 } |
196 | 205 |
197 bool HTMLDocumentParser::isParsingFragment() const | 206 bool HTMLDocumentParser::isParsingFragment() const |
198 { | 207 { |
199 return m_treeBuilder->isParsingFragment(); | 208 return m_treeBuilder->isParsingFragment(); |
200 } | 209 } |
201 | 210 |
202 bool HTMLDocumentParser::processingData() const | 211 bool HTMLDocumentParser::processingData() const |
203 { | 212 { |
204 return isScheduledForResume() || inPumpSession() || m_haveBackgroundParser; | 213 return isScheduledForResume() || inPumpSession() || m_parserThread; |
205 } | 214 } |
206 | 215 |
207 void HTMLDocumentParser::pumpTokenizerIfPossible(SynchronousMode mode) | 216 void HTMLDocumentParser::pumpTokenizerIfPossible(SynchronousMode mode) |
208 { | 217 { |
209 if (isStopped()) | 218 if (isStopped()) |
210 return; | 219 return; |
211 if (isWaitingForScripts()) | 220 if (isWaitingForScripts()) |
212 return; | 221 return; |
213 | 222 |
214 // Once a resume is scheduled, HTMLParserScheduler controls when we next pum p. | 223 // Once a resume is scheduled, HTMLParserScheduler controls when we next pum p. |
(...skipping 11 matching lines...) Expand all Loading... | |
226 } | 235 } |
227 | 236 |
228 // Used by HTMLParserScheduler | 237 // Used by HTMLParserScheduler |
229 void HTMLDocumentParser::resumeParsingAfterYield() | 238 void HTMLDocumentParser::resumeParsingAfterYield() |
230 { | 239 { |
231 ASSERT(!m_isPinnedToMainThread); | 240 ASSERT(!m_isPinnedToMainThread); |
232 // pumpTokenizer can cause this parser to be detached from the Document, | 241 // pumpTokenizer can cause this parser to be detached from the Document, |
233 // but we need to ensure it isn't deleted yet. | 242 // but we need to ensure it isn't deleted yet. |
234 RefPtr<HTMLDocumentParser> protect(this); | 243 RefPtr<HTMLDocumentParser> protect(this); |
235 | 244 |
236 if (m_haveBackgroundParser) { | 245 if (m_parserThread) { |
237 pumpPendingSpeculations(); | 246 pumpPendingSpeculations(); |
238 return; | 247 return; |
239 } | 248 } |
240 | 249 |
241 // We should never be here unless we can pump immediately. Call pumpTokeniz er() | 250 // We should never be here unless we can pump immediately. Call pumpTokeniz er() |
242 // directly so that ASSERTS will fire if we're wrong. | 251 // directly so that ASSERTS will fire if we're wrong. |
243 pumpTokenizer(AllowYield); | 252 pumpTokenizer(AllowYield); |
244 endIfDelayed(); | 253 endIfDelayed(); |
245 } | 254 } |
246 | 255 |
247 void HTMLDocumentParser::runScriptsForPausedTreeBuilder() | 256 void HTMLDocumentParser::runScriptsForPausedTreeBuilder() |
248 { | 257 { |
249 ASSERT(scriptingContentIsAllowed(parserContentPolicy())); | 258 ASSERT(scriptingContentIsAllowed(parserContentPolicy())); |
250 | 259 |
251 TextPosition scriptStartPosition = TextPosition::belowRangePosition(); | 260 TextPosition scriptStartPosition = TextPosition::belowRangePosition(); |
252 RefPtr<Element> scriptElement = m_treeBuilder->takeScriptToProcess(scriptSta rtPosition); | 261 RefPtr<Element> scriptElement = m_treeBuilder->takeScriptToProcess(scriptSta rtPosition); |
253 // We will not have a scriptRunner when parsing a DocumentFragment. | 262 // We will not have a scriptRunner when parsing a DocumentFragment. |
254 if (m_scriptRunner) | 263 if (m_scriptRunner) |
255 m_scriptRunner->execute(scriptElement.release(), scriptStartPosition); | 264 m_scriptRunner->execute(scriptElement.release(), scriptStartPosition); |
256 } | 265 } |
257 | 266 |
258 bool HTMLDocumentParser::canTakeNextToken(SynchronousMode mode, PumpSession& ses sion) | 267 bool HTMLDocumentParser::canTakeNextToken(SynchronousMode mode, PumpSession& ses sion) |
259 { | 268 { |
260 if (isStopped()) | 269 if (isStopped()) |
261 return false; | 270 return false; |
262 | 271 |
263 ASSERT(!m_haveBackgroundParser || mode == ForceSynchronous); | 272 ASSERT(!m_parserThread || mode == ForceSynchronous); |
264 | 273 |
265 if (isWaitingForScripts()) { | 274 if (isWaitingForScripts()) { |
266 if (mode == AllowYield) | 275 if (mode == AllowYield) |
267 m_parserScheduler->checkForYieldBeforeScript(session); | 276 m_parserScheduler->checkForYieldBeforeScript(session); |
268 | 277 |
269 // If we don't run the script, we cannot allow the next token to be take n. | 278 // If we don't run the script, we cannot allow the next token to be take n. |
270 if (session.needsYield) | 279 if (session.needsYield) |
271 return false; | 280 return false; |
272 | 281 |
273 // If we're paused waiting for a script, we try to execute scripts befor e continuing. | 282 // If we're paused waiting for a script, we try to execute scripts befor e continuing. |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
315 chunk->preloads.clear(); // We don't need to preload because we're going to parse immediately. | 324 chunk->preloads.clear(); // We don't need to preload because we're going to parse immediately. |
316 m_speculations.append(chunk); | 325 m_speculations.append(chunk); |
317 pumpPendingSpeculations(); | 326 pumpPendingSpeculations(); |
318 } | 327 } |
319 | 328 |
320 void HTMLDocumentParser::didReceiveEncodingDataFromBackgroundParser(const Docume ntEncodingData& data) | 329 void HTMLDocumentParser::didReceiveEncodingDataFromBackgroundParser(const Docume ntEncodingData& data) |
321 { | 330 { |
322 document()->setEncodingData(data); | 331 document()->setEncodingData(data); |
323 } | 332 } |
324 | 333 |
334 void HTMLDocumentParser::destructResourceBridge(PassOwnPtr<blink::WebParserResou rceBridge> resourceBridge) | |
335 { | |
336 // Here to let the resource bridge be destructed on the main thread. | |
337 } | |
338 | |
325 void HTMLDocumentParser::validateSpeculations(PassOwnPtr<ParsedChunk> chunk) | 339 void HTMLDocumentParser::validateSpeculations(PassOwnPtr<ParsedChunk> chunk) |
326 { | 340 { |
327 ASSERT(chunk); | 341 ASSERT(chunk); |
328 if (isWaitingForScripts()) { | 342 if (isWaitingForScripts()) { |
329 // We're waiting on a network script, just save the chunk, we'll get | 343 // We're waiting on a network script, just save the chunk, we'll get |
330 // a second validateSpeculations call after the script completes. | 344 // a second validateSpeculations call after the script completes. |
331 // This call should have been made immediately after runScriptsForPaused TreeBuilder | 345 // This call should have been made immediately after runScriptsForPaused TreeBuilder |
332 // which may have started a network load and left us waiting. | 346 // which may have started a network load and left us waiting. |
333 ASSERT(!m_lastChunkBeforeScript); | 347 ASSERT(!m_lastChunkBeforeScript); |
334 m_lastChunkBeforeScript = chunk; | 348 m_lastChunkBeforeScript = chunk; |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
370 checkpoint->parser = m_weakFactory.createWeakPtr(); | 384 checkpoint->parser = m_weakFactory.createWeakPtr(); |
371 checkpoint->token = token; | 385 checkpoint->token = token; |
372 checkpoint->tokenizer = tokenizer; | 386 checkpoint->tokenizer = tokenizer; |
373 checkpoint->treeBuilderState = HTMLTreeBuilderSimulator::stateFor(m_treeBuil der.get()); | 387 checkpoint->treeBuilderState = HTMLTreeBuilderSimulator::stateFor(m_treeBuil der.get()); |
374 checkpoint->inputCheckpoint = lastChunkBeforeScript->inputCheckpoint; | 388 checkpoint->inputCheckpoint = lastChunkBeforeScript->inputCheckpoint; |
375 checkpoint->preloadScannerCheckpoint = lastChunkBeforeScript->preloadScanner Checkpoint; | 389 checkpoint->preloadScannerCheckpoint = lastChunkBeforeScript->preloadScanner Checkpoint; |
376 checkpoint->unparsedInput = m_input.current().toString().isolatedCopy(); | 390 checkpoint->unparsedInput = m_input.current().toString().isolatedCopy(); |
377 m_input.current().clear(); // FIXME: This should be passed in instead of cle ared. | 391 m_input.current().clear(); // FIXME: This should be passed in instead of cle ared. |
378 | 392 |
379 ASSERT(checkpoint->unparsedInput.isSafeToSendToAnotherThread()); | 393 ASSERT(checkpoint->unparsedInput.isSafeToSendToAnotherThread()); |
380 HTMLParserThread::shared()->postTask(bind(&BackgroundHTMLParser::resumeFrom, m_backgroundParser, checkpoint.release())); | 394 ASSERT(m_parserThread); |
395 m_parserThread->postTask(new Task(bind(&BackgroundHTMLParser::resumeFrom, m_ backgroundParser, checkpoint.release()))); | |
381 } | 396 } |
382 | 397 |
383 void HTMLDocumentParser::processParsedChunkFromBackgroundParser(PassOwnPtr<Parse dChunk> popChunk) | 398 void HTMLDocumentParser::processParsedChunkFromBackgroundParser(PassOwnPtr<Parse dChunk> popChunk) |
384 { | 399 { |
385 TRACE_EVENT0("webkit", "HTMLDocumentParser::processParsedChunkFromBackground Parser"); | 400 TRACE_EVENT0("webkit", "HTMLDocumentParser::processParsedChunkFromBackground Parser"); |
386 | 401 |
387 ASSERT_WITH_SECURITY_IMPLICATION(!document()->activeParserCount()); | 402 ASSERT_WITH_SECURITY_IMPLICATION(!document()->activeParserCount()); |
388 ASSERT(!isParsingFragment()); | 403 ASSERT(!isParsingFragment()); |
389 ASSERT(!isWaitingForScripts()); | 404 ASSERT(!isWaitingForScripts()); |
390 ASSERT(!isStopped()); | 405 ASSERT(!isStopped()); |
391 // ASSERT that this object is both attached to the Document and protected. | 406 // ASSERT that this object is both attached to the Document and protected. |
392 ASSERT(refCount() >= 2); | 407 ASSERT(refCount() >= 2); |
393 ASSERT(shouldUseThreading()); | 408 ASSERT(shouldUseThreading()); |
394 ASSERT(!m_tokenizer); | 409 ASSERT(!m_tokenizer); |
395 ASSERT(!m_token); | 410 ASSERT(!m_token); |
396 ASSERT(!m_lastChunkBeforeScript); | 411 ASSERT(!m_lastChunkBeforeScript); |
412 ASSERT(m_parserThread); | |
397 | 413 |
398 ActiveParserSession session(contextForParsingSession()); | 414 ActiveParserSession session(contextForParsingSession()); |
399 | 415 |
400 OwnPtr<ParsedChunk> chunk(popChunk); | 416 OwnPtr<ParsedChunk> chunk(popChunk); |
401 OwnPtr<CompactHTMLTokenStream> tokens = chunk->tokens.release(); | 417 OwnPtr<CompactHTMLTokenStream> tokens = chunk->tokens.release(); |
402 | 418 |
403 HTMLParserThread::shared()->postTask(bind(&BackgroundHTMLParser::startedChun kWithCheckpoint, m_backgroundParser, chunk->inputCheckpoint)); | 419 m_parserThread->postTask(new Task(bind(&BackgroundHTMLParser::startedChunkWi thCheckpoint, m_backgroundParser, chunk->inputCheckpoint))); |
404 | 420 |
405 for (XSSInfoStream::const_iterator it = chunk->xssInfos.begin(); it != chunk ->xssInfos.end(); ++it) { | 421 for (XSSInfoStream::const_iterator it = chunk->xssInfos.begin(); it != chunk ->xssInfos.end(); ++it) { |
406 m_textPosition = (*it)->m_textPosition; | 422 m_textPosition = (*it)->m_textPosition; |
407 m_xssAuditorDelegate.didBlockScript(**it); | 423 m_xssAuditorDelegate.didBlockScript(**it); |
408 if (isStopped()) | 424 if (isStopped()) |
409 break; | 425 break; |
410 } | 426 } |
411 | 427 |
412 for (Vector<CompactHTMLToken>::const_iterator it = tokens->begin(); it != to kens->end(); ++it) { | 428 for (Vector<CompactHTMLToken>::const_iterator it = tokens->begin(); it != to kens->end(); ++it) { |
413 ASSERT(!isWaitingForScripts()); | 429 ASSERT(!isWaitingForScripts()); |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
484 m_parserScheduler->scheduleForResume(); | 500 m_parserScheduler->scheduleForResume(); |
485 break; | 501 break; |
486 } | 502 } |
487 } | 503 } |
488 | 504 |
489 InspectorInstrumentation::didWriteHTML(cookie, lineNumber().zeroBasedInt()); | 505 InspectorInstrumentation::didWriteHTML(cookie, lineNumber().zeroBasedInt()); |
490 } | 506 } |
491 | 507 |
492 void HTMLDocumentParser::forcePlaintextForTextDocument() | 508 void HTMLDocumentParser::forcePlaintextForTextDocument() |
493 { | 509 { |
494 if (shouldUseThreading()) { | 510 if (m_parserThread) |
495 // This method is called before any data is appended, so we have to star t | 511 m_parserThread->postTask(new Task(bind(&BackgroundHTMLParser::forcePlain textForTextDocument, m_backgroundParser))); |
496 // the background parser ourselves. | 512 else |
497 if (!m_haveBackgroundParser) | |
498 startBackgroundParser(); | |
499 | |
500 HTMLParserThread::shared()->postTask(bind(&BackgroundHTMLParser::forcePl aintextForTextDocument, m_backgroundParser)); | |
501 } else | |
502 m_tokenizer->setState(HTMLTokenizer::PLAINTEXTState); | 513 m_tokenizer->setState(HTMLTokenizer::PLAINTEXTState); |
503 } | 514 } |
504 | 515 |
505 Document* HTMLDocumentParser::contextForParsingSession() | 516 Document* HTMLDocumentParser::contextForParsingSession() |
506 { | 517 { |
507 // The parsing session should interact with the document only when parsing | 518 // The parsing session should interact with the document only when parsing |
508 // non-fragments. Otherwise, we might delay the load event mistakenly. | 519 // non-fragments. Otherwise, we might delay the load event mistakenly. |
509 if (isParsingFragment()) | 520 if (isParsingFragment()) |
510 return 0; | 521 return 0; |
511 return document(); | 522 return document(); |
512 } | 523 } |
513 | 524 |
514 void HTMLDocumentParser::pumpTokenizer(SynchronousMode mode) | 525 void HTMLDocumentParser::pumpTokenizer(SynchronousMode mode) |
515 { | 526 { |
516 ASSERT(!isStopped()); | 527 ASSERT(!isStopped()); |
517 ASSERT(!isScheduledForResume()); | 528 ASSERT(!isScheduledForResume()); |
518 // ASSERT that this object is both attached to the Document and protected. | 529 // ASSERT that this object is both attached to the Document and protected. |
519 ASSERT(refCount() >= 2); | 530 ASSERT(refCount() >= 2); |
520 ASSERT(m_tokenizer); | 531 ASSERT(m_tokenizer); |
521 ASSERT(m_token); | 532 ASSERT(m_token); |
522 ASSERT(!m_haveBackgroundParser || mode == ForceSynchronous); | 533 ASSERT(!m_parserThread || mode == ForceSynchronous); |
523 | 534 |
524 PumpSession session(m_pumpSessionNestingLevel, contextForParsingSession()); | 535 PumpSession session(m_pumpSessionNestingLevel, contextForParsingSession()); |
525 | 536 |
526 // We tell the InspectorInstrumentation about every pump, even if we | 537 // We tell the InspectorInstrumentation about every pump, even if we |
527 // end up pumping nothing. It can filter out empty pumps itself. | 538 // end up pumping nothing. It can filter out empty pumps itself. |
528 // FIXME: m_input.current().length() is only accurate if we | 539 // FIXME: m_input.current().length() is only accurate if we |
529 // end up parsing the whole buffer in this pump. We should pass how | 540 // end up parsing the whole buffer in this pump. We should pass how |
530 // much we parsed as part of didWriteHTML instead of willWriteHTML. | 541 // much we parsed as part of didWriteHTML instead of willWriteHTML. |
531 InspectorInstrumentationCookie cookie = InspectorInstrumentation::willWriteH TML(document(), m_input.current().currentLine().zeroBasedInt()); | 542 InspectorInstrumentationCookie cookie = InspectorInstrumentation::willWriteH TML(document(), m_input.current().currentLine().zeroBasedInt()); |
532 | 543 |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
627 return; | 638 return; |
628 | 639 |
629 TRACE_EVENT0("webkit", "HTMLDocumentParser::insert"); | 640 TRACE_EVENT0("webkit", "HTMLDocumentParser::insert"); |
630 | 641 |
631 // pumpTokenizer can cause this parser to be detached from the Document, | 642 // pumpTokenizer can cause this parser to be detached from the Document, |
632 // but we need to ensure it isn't deleted yet. | 643 // but we need to ensure it isn't deleted yet. |
633 RefPtr<HTMLDocumentParser> protect(this); | 644 RefPtr<HTMLDocumentParser> protect(this); |
634 | 645 |
635 if (!m_tokenizer) { | 646 if (!m_tokenizer) { |
636 ASSERT(!inPumpSession()); | 647 ASSERT(!inPumpSession()); |
637 ASSERT(m_haveBackgroundParser || wasCreatedByScript()); | 648 ASSERT(m_parserThread || wasCreatedByScript()); |
638 m_token = adoptPtr(new HTMLToken); | 649 m_token = adoptPtr(new HTMLToken); |
639 m_tokenizer = HTMLTokenizer::create(m_options); | 650 m_tokenizer = HTMLTokenizer::create(m_options); |
640 } | 651 } |
641 | 652 |
642 SegmentedString excludedLineNumberSource(source); | 653 SegmentedString excludedLineNumberSource(source); |
643 excludedLineNumberSource.setExcludeLineNumbers(); | 654 excludedLineNumberSource.setExcludeLineNumbers(); |
644 m_input.insertAtCurrentInsertionPoint(excludedLineNumberSource); | 655 m_input.insertAtCurrentInsertionPoint(excludedLineNumberSource); |
645 pumpTokenizerIfPossible(ForceSynchronous); | 656 pumpTokenizerIfPossible(ForceSynchronous); |
646 | 657 |
647 if (isWaitingForScripts()) { | 658 if (isWaitingForScripts()) { |
648 // Check the document.write() output with a separate preload scanner as | 659 // Check the document.write() output with a separate preload scanner as |
649 // the main scanner can't deal with insertions. | 660 // the main scanner can't deal with insertions. |
650 if (!m_insertionPreloadScanner) | 661 if (!m_insertionPreloadScanner) |
651 m_insertionPreloadScanner = adoptPtr(new HTMLPreloadScanner(m_option s, document()->url(), document()->devicePixelRatio())); | 662 m_insertionPreloadScanner = adoptPtr(new HTMLPreloadScanner(m_option s, document()->url(), document()->devicePixelRatio())); |
652 | 663 |
653 m_insertionPreloadScanner->appendToEnd(source); | 664 m_insertionPreloadScanner->appendToEnd(source); |
654 m_insertionPreloadScanner->scan(m_preloader.get(), document()->baseEleme ntURL()); | 665 m_insertionPreloadScanner->scan(m_preloader.get(), document()->baseEleme ntURL()); |
655 } | 666 } |
656 | 667 |
657 endIfDelayed(); | 668 endIfDelayed(); |
658 } | 669 } |
659 | 670 |
660 void HTMLDocumentParser::startBackgroundParser() | 671 void HTMLDocumentParser::startBackgroundParser() |
661 { | 672 { |
662 ASSERT(shouldUseThreading()); | 673 ASSERT(shouldUseThreading()); |
663 ASSERT(!m_haveBackgroundParser); | 674 ASSERT(!m_parserThread); |
664 m_haveBackgroundParser = true; | 675 |
676 OwnPtr<blink::WebParserResourceBridge> resourceBridge = document()->loader() ->constructParserResourceBridge(); | |
677 if (!resourceBridge) | |
678 return; | |
679 | |
680 m_parserThread = resourceBridge->getParserThread(); | |
abarth-chromium
2013/12/18 18:28:49
getParserThread -> parserThread
| |
681 ASSERT(m_parserThread); | |
665 | 682 |
666 RefPtr<WeakReference<BackgroundHTMLParser> > reference = WeakReference<Backg roundHTMLParser>::createUnbound(); | 683 RefPtr<WeakReference<BackgroundHTMLParser> > reference = WeakReference<Backg roundHTMLParser>::createUnbound(); |
667 m_backgroundParser = WeakPtr<BackgroundHTMLParser>(reference); | 684 m_backgroundParser = WeakPtr<BackgroundHTMLParser>(reference); |
668 | 685 |
669 OwnPtr<BackgroundHTMLParser::Configuration> config = adoptPtr(new Background HTMLParser::Configuration); | 686 OwnPtr<BackgroundHTMLParser::Configuration> config = adoptPtr(new Background HTMLParser::Configuration); |
670 config->options = m_options; | 687 config->options = m_options; |
671 config->parser = m_weakFactory.createWeakPtr(); | 688 config->parser = m_weakFactory.createWeakPtr(); |
672 config->xssAuditor = adoptPtr(new XSSAuditor); | 689 config->xssAuditor = adoptPtr(new XSSAuditor); |
673 config->xssAuditor->init(document(), &m_xssAuditorDelegate); | 690 config->xssAuditor->init(document(), &m_xssAuditorDelegate); |
674 config->preloadScanner = adoptPtr(new TokenPreloadScanner(document()->url(). copy(), document()->devicePixelRatio())); | 691 config->preloadScanner = adoptPtr(new TokenPreloadScanner(document()->url(). copy(), document()->devicePixelRatio())); |
675 config->decoder = takeDecoder(); | 692 config->decoder = takeDecoder(); |
693 config->resourceBridge = resourceBridge.release(); | |
676 | 694 |
677 ASSERT(config->xssAuditor->isSafeToSendToAnotherThread()); | 695 ASSERT(config->xssAuditor->isSafeToSendToAnotherThread()); |
678 ASSERT(config->preloadScanner->isSafeToSendToAnotherThread()); | 696 ASSERT(config->preloadScanner->isSafeToSendToAnotherThread()); |
679 HTMLParserThread::shared()->postTask(bind(&BackgroundHTMLParser::start, refe rence.release(), config.release())); | 697 m_parserThread->postTask(new Task(bind(&BackgroundHTMLParser::start, referen ce.release(), config.release()))); |
680 } | 698 } |
681 | 699 |
682 void HTMLDocumentParser::stopBackgroundParser() | 700 void HTMLDocumentParser::stopBackgroundParser() |
683 { | 701 { |
684 ASSERT(shouldUseThreading()); | 702 ASSERT(shouldUseThreading()); |
685 ASSERT(m_haveBackgroundParser); | 703 ASSERT(m_parserThread); |
686 m_haveBackgroundParser = false; | |
687 | 704 |
688 HTMLParserThread::shared()->postTask(bind(&BackgroundHTMLParser::stop, m_bac kgroundParser)); | 705 m_parserThread->postTask(new Task(bind(&BackgroundHTMLParser::stop, m_backgr oundParser))); |
706 m_parserThread = 0; | |
689 m_weakFactory.revokeAll(); | 707 m_weakFactory.revokeAll(); |
690 } | 708 } |
691 | 709 |
692 void HTMLDocumentParser::append(PassRefPtr<StringImpl> inputSource) | 710 void HTMLDocumentParser::append(PassRefPtr<StringImpl> inputSource) |
693 { | 711 { |
694 if (isStopped()) | 712 if (isStopped()) |
695 return; | 713 return; |
696 | 714 |
697 // We should never reach this point if we're using a parser thread, | 715 // We should never reach this point if we're using a parser thread, |
698 // as appendBytes() will directly ship the data to the thread. | 716 // as appendBytes() will directly ship the data to the thread. |
699 ASSERT(!shouldUseThreading()); | 717 ASSERT(!m_parserThread); |
700 | 718 |
701 // pumpTokenizer can cause this parser to be detached from the Document, | 719 // pumpTokenizer can cause this parser to be detached from the Document, |
702 // but we need to ensure it isn't deleted yet. | 720 // but we need to ensure it isn't deleted yet. |
703 RefPtr<HTMLDocumentParser> protect(this); | 721 RefPtr<HTMLDocumentParser> protect(this); |
704 TRACE_EVENT1("net", "HTMLDocumentParser::append", "size", inputSource->lengt h()); | 722 TRACE_EVENT1("net", "HTMLDocumentParser::append", "size", inputSource->lengt h()); |
705 String source(inputSource); | 723 String source(inputSource); |
706 | 724 |
707 if (m_preloadScanner) { | 725 if (m_preloadScanner) { |
708 if (m_input.current().isEmpty() && !isWaitingForScripts()) { | 726 if (m_input.current().isEmpty() && !isWaitingForScripts()) { |
709 // We have parsed until the end of the current input and so are now moving ahead of the preload scanner. | 727 // We have parsed until the end of the current input and so are now moving ahead of the preload scanner. |
(...skipping 26 matching lines...) Expand all Loading... | |
736 pumpTokenizerIfPossible(AllowYield); | 754 pumpTokenizerIfPossible(AllowYield); |
737 | 755 |
738 endIfDelayed(); | 756 endIfDelayed(); |
739 } | 757 } |
740 | 758 |
741 void HTMLDocumentParser::end() | 759 void HTMLDocumentParser::end() |
742 { | 760 { |
743 ASSERT(!isDetached()); | 761 ASSERT(!isDetached()); |
744 ASSERT(!isScheduledForResume()); | 762 ASSERT(!isScheduledForResume()); |
745 | 763 |
746 if (m_haveBackgroundParser) | 764 if (m_parserThread) |
747 stopBackgroundParser(); | 765 stopBackgroundParser(); |
748 | 766 |
749 // Informs the the rest of WebCore that parsing is really finished (and dele tes this). | 767 // Informs the the rest of WebCore that parsing is really finished (and dele tes this). |
750 m_treeBuilder->finished(); | 768 m_treeBuilder->finished(); |
751 } | 769 } |
752 | 770 |
753 void HTMLDocumentParser::attemptToRunDeferredScriptsAndEnd() | 771 void HTMLDocumentParser::attemptToRunDeferredScriptsAndEnd() |
754 { | 772 { |
755 ASSERT(isStopping()); | 773 ASSERT(isStopping()); |
756 // FIXME: It may not be correct to disable this for the background parser. | 774 // FIXME: It may not be correct to disable this for the background parser. |
757 // That means hasInsertionPoint() may not be correct in some cases. | 775 // That means hasInsertionPoint() may not be correct in some cases. |
758 ASSERT(!hasInsertionPoint() || m_haveBackgroundParser); | 776 ASSERT(!hasInsertionPoint() || m_parserThread); |
759 if (m_scriptRunner && !m_scriptRunner->executeScriptsWaitingForParsing()) | 777 if (m_scriptRunner && !m_scriptRunner->executeScriptsWaitingForParsing()) |
760 return; | 778 return; |
761 end(); | 779 end(); |
762 } | 780 } |
763 | 781 |
764 void HTMLDocumentParser::attemptToEnd() | 782 void HTMLDocumentParser::attemptToEnd() |
765 { | 783 { |
766 // finish() indicates we will not receive any more data. If we are waiting o n | 784 // finish() indicates we will not receive any more data. If we are waiting o n |
767 // an external script to load, we can't finish parsing quite yet. | 785 // an external script to load, we can't finish parsing quite yet. |
768 | 786 |
(...skipping 19 matching lines...) Expand all Loading... | |
788 | 806 |
789 void HTMLDocumentParser::finish() | 807 void HTMLDocumentParser::finish() |
790 { | 808 { |
791 // FIXME: We should ASSERT(!m_parserStopped) here, since it does not | 809 // FIXME: We should ASSERT(!m_parserStopped) here, since it does not |
792 // makes sense to call any methods on DocumentParser once it's been stopped. | 810 // makes sense to call any methods on DocumentParser once it's been stopped. |
793 // However, FrameLoader::stop calls DocumentParser::finish unconditionally. | 811 // However, FrameLoader::stop calls DocumentParser::finish unconditionally. |
794 | 812 |
795 // Empty documents never got an append() call, and thus have never started | 813 // Empty documents never got an append() call, and thus have never started |
796 // a background parser. In those cases, we ignore shouldUseThreading() | 814 // a background parser. In those cases, we ignore shouldUseThreading() |
797 // and fall through to the non-threading case. | 815 // and fall through to the non-threading case. |
798 if (m_haveBackgroundParser) { | 816 if (m_parserThread) { |
799 if (!m_input.haveSeenEndOfFile()) | 817 if (!m_input.haveSeenEndOfFile()) |
800 m_input.closeWithoutMarkingEndOfFile(); | 818 m_input.closeWithoutMarkingEndOfFile(); |
801 HTMLParserThread::shared()->postTask(bind(&BackgroundHTMLParser::finish, m_backgroundParser)); | 819 m_parserThread->postTask(new Task(bind(&BackgroundHTMLParser::finish, m_ backgroundParser))); |
802 return; | 820 return; |
803 } | 821 } |
804 | 822 |
805 if (!m_tokenizer) { | 823 if (!m_tokenizer) { |
806 ASSERT(!m_token); | 824 ASSERT(!m_token); |
807 // We're finishing before receiving any data. Rather than booting up | 825 // We're finishing before receiving any data. Rather than booting up |
808 // the background parser just to spin it down, we finish parsing | 826 // the background parser just to spin it down, we finish parsing |
809 // synchronously. | 827 // synchronously. |
810 m_token = adoptPtr(new HTMLToken); | 828 m_token = adoptPtr(new HTMLToken); |
811 m_tokenizer = HTMLTokenizer::create(m_options); | 829 m_tokenizer = HTMLTokenizer::create(m_options); |
(...skipping 10 matching lines...) Expand all Loading... | |
822 | 840 |
823 bool HTMLDocumentParser::isExecutingScript() const | 841 bool HTMLDocumentParser::isExecutingScript() const |
824 { | 842 { |
825 if (!m_scriptRunner) | 843 if (!m_scriptRunner) |
826 return false; | 844 return false; |
827 return m_scriptRunner->isExecutingScript(); | 845 return m_scriptRunner->isExecutingScript(); |
828 } | 846 } |
829 | 847 |
830 OrdinalNumber HTMLDocumentParser::lineNumber() const | 848 OrdinalNumber HTMLDocumentParser::lineNumber() const |
831 { | 849 { |
832 if (m_haveBackgroundParser) | 850 if (m_parserThread) |
833 return m_textPosition.m_line; | 851 return m_textPosition.m_line; |
834 | 852 |
835 return m_input.current().currentLine(); | 853 return m_input.current().currentLine(); |
836 } | 854 } |
837 | 855 |
838 TextPosition HTMLDocumentParser::textPosition() const | 856 TextPosition HTMLDocumentParser::textPosition() const |
839 { | 857 { |
840 if (m_haveBackgroundParser) | 858 if (m_parserThread) |
841 return m_textPosition; | 859 return m_textPosition; |
842 | 860 |
843 const SegmentedString& currentString = m_input.current(); | 861 const SegmentedString& currentString = m_input.current(); |
844 OrdinalNumber line = currentString.currentLine(); | 862 OrdinalNumber line = currentString.currentLine(); |
845 OrdinalNumber column = currentString.currentColumn(); | 863 OrdinalNumber column = currentString.currentColumn(); |
846 | 864 |
847 return TextPosition(line, column); | 865 return TextPosition(line, column); |
848 } | 866 } |
849 | 867 |
850 bool HTMLDocumentParser::isWaitingForScripts() const | 868 bool HTMLDocumentParser::isWaitingForScripts() const |
(...skipping 10 matching lines...) Expand all Loading... | |
861 ASSERT(!(treeBuilderHasBlockingScript && scriptRunnerHasBlockingScript)); | 879 ASSERT(!(treeBuilderHasBlockingScript && scriptRunnerHasBlockingScript)); |
862 // If either object has a blocking script, the parser should be paused. | 880 // If either object has a blocking script, the parser should be paused. |
863 return treeBuilderHasBlockingScript || scriptRunnerHasBlockingScript; | 881 return treeBuilderHasBlockingScript || scriptRunnerHasBlockingScript; |
864 } | 882 } |
865 | 883 |
866 void HTMLDocumentParser::resumeParsingAfterScriptExecution() | 884 void HTMLDocumentParser::resumeParsingAfterScriptExecution() |
867 { | 885 { |
868 ASSERT(!isExecutingScript()); | 886 ASSERT(!isExecutingScript()); |
869 ASSERT(!isWaitingForScripts()); | 887 ASSERT(!isWaitingForScripts()); |
870 | 888 |
871 if (m_haveBackgroundParser) { | 889 if (m_parserThread) { |
872 validateSpeculations(m_lastChunkBeforeScript.release()); | 890 validateSpeculations(m_lastChunkBeforeScript.release()); |
873 ASSERT(!m_lastChunkBeforeScript); | 891 ASSERT(!m_lastChunkBeforeScript); |
874 // processParsedChunkFromBackgroundParser can cause this parser to be de tached from the Document, | 892 // processParsedChunkFromBackgroundParser can cause this parser to be de tached from the Document, |
875 // but we need to ensure it isn't deleted yet. | 893 // but we need to ensure it isn't deleted yet. |
876 RefPtr<HTMLDocumentParser> protect(this); | 894 RefPtr<HTMLDocumentParser> protect(this); |
877 pumpPendingSpeculations(); | 895 pumpPendingSpeculations(); |
878 return; | 896 return; |
879 } | 897 } |
880 | 898 |
881 m_insertionPreloadScanner.clear(); | 899 m_insertionPreloadScanner.clear(); |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
960 { | 978 { |
961 if (m_parserScheduler) | 979 if (m_parserScheduler) |
962 m_parserScheduler->resume(); | 980 m_parserScheduler->resume(); |
963 } | 981 } |
964 | 982 |
965 void HTMLDocumentParser::appendBytes(const char* data, size_t length) | 983 void HTMLDocumentParser::appendBytes(const char* data, size_t length) |
966 { | 984 { |
967 if (!length || isDetached()) | 985 if (!length || isDetached()) |
968 return; | 986 return; |
969 | 987 |
970 if (shouldUseThreading()) { | 988 if (m_parserThread) { |
971 if (!m_haveBackgroundParser) | 989 if (m_parserThreadIsStandalone) |
972 startBackgroundParser(); | 990 return; // If this is set, the parser thread will receive the data d irectly. |
973 | 991 |
974 OwnPtr<Vector<char> > buffer = adoptPtr(new Vector<char>(length)); | 992 OwnPtr<Vector<char> > buffer = adoptPtr(new Vector<char>(length)); |
975 memcpy(buffer->data(), data, length); | 993 memcpy(buffer->data(), data, length); |
976 TRACE_EVENT1("net", "HTMLDocumentParser::appendBytes", "size", (unsigned )length); | 994 TRACE_EVENT1("net", "HTMLDocumentParser::appendBytes", "size", (unsigned )length); |
977 | 995 |
978 HTMLParserThread::shared()->postTask(bind(&BackgroundHTMLParser::appendB ytes, m_backgroundParser, buffer.release())); | 996 m_parserThread->postTask(new Task(bind(&BackgroundHTMLParser::appendByte s, m_backgroundParser, buffer.release()))); |
979 return; | 997 return; |
980 } | 998 } |
981 | 999 |
982 DecodedDataDocumentParser::appendBytes(data, length); | 1000 DecodedDataDocumentParser::appendBytes(data, length); |
983 } | 1001 } |
984 | 1002 |
1003 void HTMLDocumentParser::parserResourceMessageFilterAdded() | |
1004 { | |
1005 if (isDetached()) | |
1006 return; | |
1007 | |
1008 ASSERT(m_parserThread && !needsDecoder()); | |
1009 // At this point the background parser will start receiving data chunks dire ctly | |
1010 // from the I/O thread and we no longer need to pass it any data. | |
1011 m_parserThreadIsStandalone = true; | |
1012 m_parserThread->postTask(new Task(bind(&BackgroundHTMLParser::resourceFilter Added, m_backgroundParser))); | |
1013 } | |
1014 | |
985 void HTMLDocumentParser::flush() | 1015 void HTMLDocumentParser::flush() |
986 { | 1016 { |
987 // If we've got no decoder, we never received any data. | 1017 // If we've got no decoder, we never received any data. |
988 if (isDetached() || needsDecoder()) | 1018 if (isDetached() || needsDecoder()) |
989 return; | 1019 return; |
990 | 1020 |
991 if (m_haveBackgroundParser) | 1021 if (m_parserThread) |
992 HTMLParserThread::shared()->postTask(bind(&BackgroundHTMLParser::flush, m_backgroundParser)); | 1022 m_parserThread->postTask(new Task(bind(&BackgroundHTMLParser::flush, m_b ackgroundParser))); |
993 else | 1023 else |
994 DecodedDataDocumentParser::flush(); | 1024 DecodedDataDocumentParser::flush(); |
995 } | 1025 } |
996 | 1026 |
997 void HTMLDocumentParser::setDecoder(PassOwnPtr<TextResourceDecoder> decoder) | 1027 void HTMLDocumentParser::setDecoder(PassOwnPtr<TextResourceDecoder> decoder) |
998 { | 1028 { |
999 DecodedDataDocumentParser::setDecoder(decoder); | 1029 DecodedDataDocumentParser::setDecoder(decoder); |
1000 | 1030 |
1001 if (m_haveBackgroundParser) | 1031 if (m_parserThread) |
1002 HTMLParserThread::shared()->postTask(bind(&BackgroundHTMLParser::setDeco der, m_backgroundParser, takeDecoder())); | 1032 m_parserThread->postTask(new Task(bind(&BackgroundHTMLParser::setDecoder , m_backgroundParser, takeDecoder()))); |
1003 } | 1033 } |
1004 | 1034 |
1005 } | 1035 } |
OLD | NEW |