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

Side by Side Diff: sky/engine/core/html/parser/HTMLDocumentParser.cpp

Issue 814173005: The Sky parser should yield before start tags (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 5 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
« no previous file with comments | « sky/engine/core/html/parser/HTMLDocumentParser.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
51 , m_weakFactory(this) 51 , m_weakFactory(this)
52 , m_isFragment(false) 52 , m_isFragment(false)
53 , m_endWasDelayed(false) 53 , m_endWasDelayed(false)
54 , m_haveBackgroundParser(false) 54 , m_haveBackgroundParser(false)
55 , m_pumpSessionNestingLevel(0) 55 , m_pumpSessionNestingLevel(0)
56 { 56 {
57 } 57 }
58 58
59 HTMLDocumentParser::~HTMLDocumentParser() 59 HTMLDocumentParser::~HTMLDocumentParser()
60 { 60 {
61 #if ENABLE(OILPAN)
62 if (m_haveBackgroundParser)
63 stopBackgroundParser();
64 // In Oilpan, HTMLDocumentParser can die together with Document, and
65 // detach() is not called in this case.
66 #else
67 ASSERT(!m_parserScheduler); 61 ASSERT(!m_parserScheduler);
68 ASSERT(!m_pumpSessionNestingLevel); 62 ASSERT(!m_pumpSessionNestingLevel);
69 ASSERT(!m_haveBackgroundParser); 63 ASSERT(!m_haveBackgroundParser);
70 // FIXME: We should be able to ASSERT(m_speculations.isEmpty()), 64 // FIXME: We should be able to ASSERT(m_speculations.isEmpty()),
71 // but there are cases where that's not true currently. For example, 65 // but there are cases where that's not true currently. For example,
72 // we we're told to stop parsing before we've consumed all the input. 66 // we we're told to stop parsing before we've consumed all the input.
73 #endif
74 } 67 }
75 68
76 void HTMLDocumentParser::parse(mojo::ScopedDataPipeConsumerHandle source, 69 void HTMLDocumentParser::parse(mojo::ScopedDataPipeConsumerHandle source,
77 const base::Closure& completionCallback) 70 const base::Closure& completionCallback)
78 { 71 {
79 ASSERT(!isStopped()); 72 ASSERT(!isStopped());
80 ASSERT(!m_haveBackgroundParser); 73 ASSERT(!m_haveBackgroundParser);
81 m_haveBackgroundParser = true; 74 m_haveBackgroundParser = true;
82 75
83 m_completionCallback = completionCallback; 76 m_completionCallback = completionCallback;
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
185 178
186 // processParsedChunkFromBackgroundParser can cause this parser to be detach ed from the Document, 179 // processParsedChunkFromBackgroundParser can cause this parser to be detach ed from the Document,
187 // but we need to ensure it isn't deleted yet. 180 // but we need to ensure it isn't deleted yet.
188 RefPtr<HTMLDocumentParser> protect(this); 181 RefPtr<HTMLDocumentParser> protect(this);
189 182
190 ASSERT(m_speculations.isEmpty()); 183 ASSERT(m_speculations.isEmpty());
191 m_speculations.append(chunk); 184 m_speculations.append(chunk);
192 pumpPendingSpeculations(); 185 pumpPendingSpeculations();
193 } 186 }
194 187
195 void HTMLDocumentParser::validateSpeculations(PassOwnPtr<ParsedChunk> chunk)
196 {
197 ASSERT(chunk);
198 if (isWaitingForScripts()) {
199 // We're waiting on a network script, just save the chunk, we'll get
200 // a second validateSpeculations call after the script completes.
201 // This call should have been made immediately after runScriptsForPaused TreeBuilder
202 // which may have started a network load and left us waiting.
203 ASSERT(!m_lastChunkBeforeScript);
204 m_lastChunkBeforeScript = chunk;
205 return;
206 }
207 }
208
209 void HTMLDocumentParser::processParsedChunkFromBackgroundParser(PassOwnPtr<Parse dChunk> popChunk) 188 void HTMLDocumentParser::processParsedChunkFromBackgroundParser(PassOwnPtr<Parse dChunk> popChunk)
210 { 189 {
211 TRACE_EVENT0("blink", "HTMLDocumentParser::processParsedChunkFromBackgroundP arser"); 190 TRACE_EVENT0("blink", "HTMLDocumentParser::processParsedChunkFromBackgroundP arser");
212 191
213 ASSERT_WITH_SECURITY_IMPLICATION(!document()->activeParserCount()); 192 ASSERT_WITH_SECURITY_IMPLICATION(!document()->activeParserCount());
214 ASSERT(!isParsingFragment()); 193 ASSERT(!isParsingFragment());
215 ASSERT(!isWaitingForScripts()); 194 ASSERT(!isWaitingForScripts());
216 ASSERT(!isStopped()); 195 ASSERT(!isStopped());
217 #if !ENABLE(OILPAN) 196
218 // ASSERT that this object is both attached to the Document and protected. 197 // ASSERT that this object is both attached to the Document and protected.
219 ASSERT(refCount() >= 2); 198 ASSERT(refCount() >= 2);
220 #endif
221 ASSERT(!m_lastChunkBeforeScript);
222 199
223 ActiveParserSession session(contextForParsingSession()); 200 ActiveParserSession session(contextForParsingSession());
224 201
225 OwnPtr<ParsedChunk> chunk(popChunk); 202 OwnPtr<ParsedChunk> chunk(popChunk);
226 OwnPtr<CompactHTMLTokenStream> tokens = chunk->tokens.release(); 203 OwnPtr<CompactHTMLTokenStream> tokens = chunk->tokens.release();
227 204
228 for (Vector<CompactHTMLToken>::const_iterator it = tokens->begin(); it != to kens->end(); ++it) { 205 for (Vector<CompactHTMLToken>::const_iterator it = tokens->begin(); it != to kens->end(); ++it) {
229 ASSERT(!isWaitingForScripts()); 206 ASSERT(!isWaitingForScripts());
230 207
231 m_textPosition = it->textPosition(); 208 m_textPosition = it->textPosition();
232 209
233 constructTreeFromCompactHTMLToken(*it); 210 constructTreeFromCompactHTMLToken(*it);
234 211
235 if (isStopped()) 212 if (isStopped())
236 break; 213 break;
237 214
238 if (isWaitingForScripts()) { 215 if (isWaitingForScripts()) {
239 ASSERT(it + 1 == tokens->end()); // The </script> is assumed to be t he last token of this bunch. 216 ASSERT(it + 1 == tokens->end()); // The </script> is assumed to be t he last token of this bunch.
240 runScriptsForPausedTreeBuilder(); 217 runScriptsForPausedTreeBuilder();
241 validateSpeculations(chunk.release());
242 break; 218 break;
243 } 219 }
244 220
245 if (it->type() == HTMLToken::EndOfFile) { 221 if (it->type() == HTMLToken::EndOfFile) {
246 ASSERT(it + 1 == tokens->end()); // The EOF is assumed to be the las t token of this bunch. 222 ASSERT(it + 1 == tokens->end()); // The EOF is assumed to be the las t token of this bunch.
247 ASSERT(m_speculations.isEmpty()); // There should never be any chunk s after the EOF. 223 ASSERT(m_speculations.isEmpty()); // There should never be any chunk s after the EOF.
248 prepareToStopParsing(); 224 prepareToStopParsing();
249 break; 225 break;
250 } 226 }
251 } 227 }
252 228
253 // Make sure any pending text nodes are emitted before returning. 229 // Make sure any pending text nodes are emitted before returning.
254 if (!isStopped()) 230 if (!isStopped())
255 m_treeBuilder->flush(); 231 m_treeBuilder->flush();
256 } 232 }
257 233
258 void HTMLDocumentParser::pumpPendingSpeculations() 234 void HTMLDocumentParser::pumpPendingSpeculations()
259 { 235 {
260 // FIXME: Share this constant with the parser scheduler. 236 // FIXME: Share this constant with the parser scheduler.
261 const double parserTimeLimit = 0.500; 237 const double parserTimeLimit = 0.500;
262 238
263 #if !ENABLE(OILPAN)
264 // ASSERT that this object is both attached to the Document and protected. 239 // ASSERT that this object is both attached to the Document and protected.
265 ASSERT(refCount() >= 2); 240 ASSERT(refCount() >= 2);
266 #endif
267 ASSERT(!m_lastChunkBeforeScript);
268 ASSERT(!isWaitingForScripts()); 241 ASSERT(!isWaitingForScripts());
269 ASSERT(!isStopped()); 242 ASSERT(!isStopped());
270 243
271 // FIXME: Pass in current input length. 244 // FIXME: Pass in current input length.
272 TRACE_EVENT_BEGIN1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "ParseHTM L", "beginData", InspectorParseHtmlEvent::beginData(document(), lineNumber().zer oBasedInt())); 245 TRACE_EVENT_BEGIN1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "ParseHTM L", "beginData", InspectorParseHtmlEvent::beginData(document(), lineNumber().zer oBasedInt()));
273 TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline.stack"), " CallStack", TRACE_EVENT_SCOPE_PROCESS, "stack", InspectorCallStackEvent::current CallStack()); 246 TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline.stack"), " CallStack", TRACE_EVENT_SCOPE_PROCESS, "stack", InspectorCallStackEvent::current CallStack());
274 247
275 double startTime = currentTime(); 248 double startTime = currentTime();
276 249
277 while (!m_speculations.isEmpty()) { 250 while (!m_speculations.isEmpty()) {
278 processParsedChunkFromBackgroundParser(m_speculations.takeFirst()); 251 processParsedChunkFromBackgroundParser(m_speculations.takeFirst());
279 252
280 // Always check isStopped first as m_document may be null. 253 // Always check isStopped first as m_document may be null.
281 if (isStopped() || isWaitingForScripts()) 254 if (isStopped() || isWaitingForScripts() || !document()->haveImportsLoad ed())
282 break; 255 break;
283 256
284 if (currentTime() - startTime > parserTimeLimit && !m_speculations.isEmp ty()) { 257 if (currentTime() - startTime > parserTimeLimit && !m_speculations.isEmp ty()) {
285 m_parserScheduler->scheduleForResume(); 258 m_parserScheduler->scheduleForResume();
286 break; 259 break;
287 } 260 }
288 } 261 }
289 262
290 TRACE_EVENT_END1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "ParseHTML" , "endLine", lineNumber().zeroBasedInt()); 263 TRACE_EVENT_END1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "ParseHTML" , "endLine", lineNumber().zeroBasedInt());
291 TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "Update Counters", TRACE_EVENT_SCOPE_PROCESS, "data", InspectorUpdateCountersEvent::data ()); 264 TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "Update Counters", TRACE_EVENT_SCOPE_PROCESS, "data", InspectorUpdateCountersEvent::data ());
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
329 { 302 {
330 AtomicHTMLToken token(compactToken); 303 AtomicHTMLToken token(compactToken);
331 m_treeBuilder->constructTree(&token); 304 m_treeBuilder->constructTree(&token);
332 } 305 }
333 306
334 bool HTMLDocumentParser::hasInsertionPoint() 307 bool HTMLDocumentParser::hasInsertionPoint()
335 { 308 {
336 return false; 309 return false;
337 } 310 }
338 311
339 void HTMLDocumentParser::startBackgroundParser()
340 {
341 }
342
343 void HTMLDocumentParser::stopBackgroundParser() 312 void HTMLDocumentParser::stopBackgroundParser()
344 { 313 {
345 ASSERT(m_haveBackgroundParser); 314 ASSERT(m_haveBackgroundParser);
346 m_haveBackgroundParser = false; 315 m_haveBackgroundParser = false;
347 316
348 HTMLParserThread::taskRunner()->PostTask(FROM_HERE, 317 HTMLParserThread::taskRunner()->PostTask(FROM_HERE,
349 base::Bind(&BackgroundHTMLParser::stop, m_backgroundParser)); 318 base::Bind(&BackgroundHTMLParser::stop, m_backgroundParser));
350 m_weakFactory.InvalidateWeakPtrs(); 319 m_weakFactory.InvalidateWeakPtrs();
351 } 320 }
352 321
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
405 { 374 {
406 ASSERT(m_haveBackgroundParser); 375 ASSERT(m_haveBackgroundParser);
407 return m_textPosition; 376 return m_textPosition;
408 } 377 }
409 378
410 bool HTMLDocumentParser::isWaitingForScripts() const 379 bool HTMLDocumentParser::isWaitingForScripts() const
411 { 380 {
412 return m_treeBuilder->hasParserBlockingScript() || m_scriptRunner.hasPending Scripts(); 381 return m_treeBuilder->hasParserBlockingScript() || m_scriptRunner.hasPending Scripts();
413 } 382 }
414 383
415 void HTMLDocumentParser::resumeParsingAfterScriptExecution() 384 void HTMLDocumentParser::resumeAfterWaitingForImports()
416 { 385 {
386 RefPtr<HTMLDocumentParser> protect(this);
387 if (m_scriptRunner.hasPendingScripts())
388 m_scriptRunner.executePendingScripts();
417 ASSERT(!isExecutingScript()); 389 ASSERT(!isExecutingScript());
418 ASSERT(!isWaitingForScripts()); 390 ASSERT(!isWaitingForScripts());
419 ASSERT(m_haveBackgroundParser); 391 ASSERT(m_haveBackgroundParser);
420
421 validateSpeculations(m_lastChunkBeforeScript.release());
422 ASSERT(!m_lastChunkBeforeScript);
423 // processParsedChunkFromBackgroundParser can cause this parser to be detach ed from the Document,
424 // but we need to ensure it isn't deleted yet.
425 RefPtr<HTMLDocumentParser> protect(this);
426 pumpPendingSpeculations(); 392 pumpPendingSpeculations();
427 } 393 }
428 394
429 void HTMLDocumentParser::executeScriptsWaitingForResources()
430 {
431 if (!m_scriptRunner.hasPendingScripts())
432 return;
433 RefPtr<HTMLDocumentParser> protect(this);
434 m_scriptRunner.executePendingScripts();
435 if (!isWaitingForScripts())
436 resumeParsingAfterScriptExecution();
437 } 395 }
438
439 }
OLDNEW
« no previous file with comments | « sky/engine/core/html/parser/HTMLDocumentParser.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698