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

Side by Side Diff: third_party/WebKit/Source/core/html/parser/HTMLDocumentParser.cpp

Issue 2751483005: Replace ASSERT, ASSERT_NOT_REACHED, and RELEASE_ASSERT in core/html/parser/ (Closed)
Patch Set: rebase Created 3 years, 9 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 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
146 m_shouldUseThreading(syncPolicy == AllowAsynchronousParsing), 146 m_shouldUseThreading(syncPolicy == AllowAsynchronousParsing),
147 m_endWasDelayed(false), 147 m_endWasDelayed(false),
148 m_haveBackgroundParser(false), 148 m_haveBackgroundParser(false),
149 m_tasksWereSuspended(false), 149 m_tasksWereSuspended(false),
150 m_pumpSessionNestingLevel(0), 150 m_pumpSessionNestingLevel(0),
151 m_pumpSpeculationsSessionNestingLevel(0), 151 m_pumpSpeculationsSessionNestingLevel(0),
152 m_isParsingAtLineNumber(false), 152 m_isParsingAtLineNumber(false),
153 m_triedLoadingLinkHeaders(false), 153 m_triedLoadingLinkHeaders(false),
154 m_addedPendingStylesheetInBody(false), 154 m_addedPendingStylesheetInBody(false),
155 m_isWaitingForStylesheets(false) { 155 m_isWaitingForStylesheets(false) {
156 ASSERT(shouldUseThreading() || (m_token && m_tokenizer)); 156 DCHECK(shouldUseThreading() || (m_token && m_tokenizer));
157 // Threading is not allowed in prefetch mode. 157 // Threading is not allowed in prefetch mode.
158 DCHECK(!document.isPrefetchOnly() || !shouldUseThreading()); 158 DCHECK(!document.isPrefetchOnly() || !shouldUseThreading());
159 } 159 }
160 160
161 HTMLDocumentParser::~HTMLDocumentParser() {} 161 HTMLDocumentParser::~HTMLDocumentParser() {}
162 162
163 void HTMLDocumentParser::dispose() { 163 void HTMLDocumentParser::dispose() {
164 // In Oilpan, HTMLDocumentParser can die together with Document, and detach() 164 // In Oilpan, HTMLDocumentParser can die together with Document, and detach()
165 // is not called in this case. 165 // is not called in this case.
166 if (m_haveBackgroundParser) 166 if (m_haveBackgroundParser)
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
220 } 220 }
221 if (m_haveBackgroundParser) 221 if (m_haveBackgroundParser)
222 stopBackgroundParser(); 222 stopBackgroundParser();
223 } 223 }
224 224
225 // This kicks off "Once the user agent stops parsing" as described by: 225 // This kicks off "Once the user agent stops parsing" as described by:
226 // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-end.html#the- end 226 // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-end.html#the- end
227 void HTMLDocumentParser::prepareToStopParsing() { 227 void HTMLDocumentParser::prepareToStopParsing() {
228 // FIXME: It may not be correct to disable this for the background parser. 228 // FIXME: It may not be correct to disable this for the background parser.
229 // That means hasInsertionPoint() may not be correct in some cases. 229 // That means hasInsertionPoint() may not be correct in some cases.
230 ASSERT(!hasInsertionPoint() || m_haveBackgroundParser); 230 DCHECK(!hasInsertionPoint() || m_haveBackgroundParser);
231 231
232 // NOTE: This pump should only ever emit buffered character tokens. 232 // NOTE: This pump should only ever emit buffered character tokens.
233 if (m_tokenizer) { 233 if (m_tokenizer) {
234 ASSERT(!m_haveBackgroundParser); 234 DCHECK(!m_haveBackgroundParser);
235 pumpTokenizerIfPossible(); 235 pumpTokenizerIfPossible();
236 } 236 }
237 237
238 if (isStopped()) 238 if (isStopped())
239 return; 239 return;
240 240
241 DocumentParser::prepareToStopParsing(); 241 DocumentParser::prepareToStopParsing();
242 242
243 // We will not have a scriptRunner when parsing a DocumentFragment. 243 // We will not have a scriptRunner when parsing a DocumentFragment.
244 if (m_scriptRunner) 244 if (m_scriptRunner)
(...skipping 18 matching lines...) Expand all
263 263
264 pumpTokenizer(); 264 pumpTokenizer();
265 } 265 }
266 266
267 bool HTMLDocumentParser::isScheduledForResume() const { 267 bool HTMLDocumentParser::isScheduledForResume() const {
268 return m_parserScheduler && m_parserScheduler->isScheduledForResume(); 268 return m_parserScheduler && m_parserScheduler->isScheduledForResume();
269 } 269 }
270 270
271 // Used by HTMLParserScheduler 271 // Used by HTMLParserScheduler
272 void HTMLDocumentParser::resumeParsingAfterYield() { 272 void HTMLDocumentParser::resumeParsingAfterYield() {
273 ASSERT(shouldUseThreading()); 273 DCHECK(shouldUseThreading());
274 ASSERT(m_haveBackgroundParser); 274 DCHECK(m_haveBackgroundParser);
275 275
276 checkIfBodyStylesheetAdded(); 276 checkIfBodyStylesheetAdded();
277 if (isStopped() || isPaused()) 277 if (isStopped() || isPaused())
278 return; 278 return;
279 279
280 pumpPendingSpeculations(); 280 pumpPendingSpeculations();
281 } 281 }
282 282
283 void HTMLDocumentParser::runScriptsForPausedTreeBuilder() { 283 void HTMLDocumentParser::runScriptsForPausedTreeBuilder() {
284 ASSERT(scriptingContentIsAllowed(getParserContentPolicy())); 284 DCHECK(scriptingContentIsAllowed(getParserContentPolicy()));
285 285
286 TextPosition scriptStartPosition = TextPosition::belowRangePosition(); 286 TextPosition scriptStartPosition = TextPosition::belowRangePosition();
287 Element* scriptElement = 287 Element* scriptElement =
288 m_treeBuilder->takeScriptToProcess(scriptStartPosition); 288 m_treeBuilder->takeScriptToProcess(scriptStartPosition);
289 // We will not have a scriptRunner when parsing a DocumentFragment. 289 // We will not have a scriptRunner when parsing a DocumentFragment.
290 if (m_scriptRunner) 290 if (m_scriptRunner)
291 m_scriptRunner->processScriptElement(scriptElement, scriptStartPosition); 291 m_scriptRunner->processScriptElement(scriptElement, scriptStartPosition);
292 checkIfBodyStylesheetAdded(); 292 checkIfBodyStylesheetAdded();
293 } 293 }
294 294
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
353 for (auto& request : chunk->preloads) { 353 for (auto& request : chunk->preloads) {
354 // Link rel preloads don't need to wait for AppCache but they 354 // Link rel preloads don't need to wait for AppCache but they
355 // should probably wait for CSP. 355 // should probably wait for CSP.
356 if (!m_pendingCSPMetaToken && request->isLinkRelPreload()) 356 if (!m_pendingCSPMetaToken && request->isLinkRelPreload())
357 linkRelPreloads.push_back(std::move(request)); 357 linkRelPreloads.push_back(std::move(request));
358 else 358 else
359 m_queuedPreloads.push_back(std::move(request)); 359 m_queuedPreloads.push_back(std::move(request));
360 } 360 }
361 for (auto& index : chunk->likelyDocumentWriteScriptIndices) { 361 for (auto& index : chunk->likelyDocumentWriteScriptIndices) {
362 const CompactHTMLToken& token = chunk->tokens->at(index); 362 const CompactHTMLToken& token = chunk->tokens->at(index);
363 ASSERT(token.type() == HTMLToken::TokenType::Character); 363 DCHECK_EQ(token.type(), HTMLToken::TokenType::Character);
364 m_queuedDocumentWriteScripts.push_back(token.data()); 364 m_queuedDocumentWriteScripts.push_back(token.data());
365 } 365 }
366 } 366 }
367 m_preloader->takeAndPreload(linkRelPreloads); 367 m_preloader->takeAndPreload(linkRelPreloads);
368 } else { 368 } else {
369 // We can safely assume that there are no queued preloads request after the 369 // We can safely assume that there are no queued preloads request after the
370 // document element is available, as we empty the queue immediately after 370 // document element is available, as we empty the queue immediately after
371 // the document element is created in documentElementAvailable(). 371 // the document element is created in documentElementAvailable().
372 ASSERT(m_queuedPreloads.isEmpty()); 372 DCHECK(m_queuedPreloads.isEmpty());
373 ASSERT(m_queuedDocumentWriteScripts.isEmpty()); 373 DCHECK(m_queuedDocumentWriteScripts.isEmpty());
374 // Loop through the chunks to generate preloads before any document.write 374 // Loop through the chunks to generate preloads before any document.write
375 // script evaluation takes place. Preloading these scripts is valuable and 375 // script evaluation takes place. Preloading these scripts is valuable and
376 // comparably cheap, while evaluating JS can be expensive. 376 // comparably cheap, while evaluating JS can be expensive.
377 for (auto& chunk : pendingChunks) 377 for (auto& chunk : pendingChunks)
378 m_preloader->takeAndPreload(chunk->preloads); 378 m_preloader->takeAndPreload(chunk->preloads);
379 for (auto& chunk : pendingChunks) { 379 for (auto& chunk : pendingChunks) {
380 for (auto& index : chunk->likelyDocumentWriteScriptIndices) { 380 for (auto& index : chunk->likelyDocumentWriteScriptIndices) {
381 const CompactHTMLToken& token = chunk->tokens->at(index); 381 const CompactHTMLToken& token = chunk->tokens->at(index);
382 ASSERT(token.type() == HTMLToken::TokenType::Character); 382 DCHECK_EQ(token.type(), HTMLToken::TokenType::Character);
383 evaluateAndPreloadScriptForDocumentWrite(token.data()); 383 evaluateAndPreloadScriptForDocumentWrite(token.data());
384 } 384 }
385 } 385 }
386 } 386 }
387 387
388 for (auto& chunk : pendingChunks) 388 for (auto& chunk : pendingChunks)
389 m_speculations.push_back(std::move(chunk)); 389 m_speculations.push_back(std::move(chunk));
390 390
391 if (!isPaused() && !isScheduledForResume()) { 391 if (!isPaused() && !isScheduledForResume()) {
392 if (m_tasksWereSuspended) 392 if (m_tasksWereSuspended)
393 m_parserScheduler->forceResumeAfterYield(); 393 m_parserScheduler->forceResumeAfterYield();
394 else 394 else
395 m_parserScheduler->scheduleForResume(); 395 m_parserScheduler->scheduleForResume();
396 } 396 }
397 } 397 }
398 398
399 void HTMLDocumentParser::didReceiveEncodingDataFromBackgroundParser( 399 void HTMLDocumentParser::didReceiveEncodingDataFromBackgroundParser(
400 const DocumentEncodingData& data) { 400 const DocumentEncodingData& data) {
401 document()->setEncodingData(data); 401 document()->setEncodingData(data);
402 } 402 }
403 403
404 void HTMLDocumentParser::validateSpeculations( 404 void HTMLDocumentParser::validateSpeculations(
405 std::unique_ptr<TokenizedChunk> chunk) { 405 std::unique_ptr<TokenizedChunk> chunk) {
406 ASSERT(chunk); 406 DCHECK(chunk);
407 // TODO(kouhei): We should simplify codepath here by disallowing 407 // TODO(kouhei): We should simplify codepath here by disallowing
408 // validateSpeculations 408 // validateSpeculations
409 // while isPaused, and m_lastChunkBeforePause can simply be 409 // while isPaused, and m_lastChunkBeforePause can simply be
410 // pushed to m_speculations. 410 // pushed to m_speculations.
411 if (isPaused()) { 411 if (isPaused()) {
412 // We're waiting on a network script or stylesheet, just save the chunk, 412 // We're waiting on a network script or stylesheet, just save the chunk,
413 // we'll get a second validateSpeculations call after the script or 413 // we'll get a second validateSpeculations call after the script or
414 // stylesheet completes. This call should have been made immediately after 414 // stylesheet completes. This call should have been made immediately after
415 // runScriptsForPausedTreeBuilder in the script case which may have started 415 // runScriptsForPausedTreeBuilder in the script case which may have started
416 // a network load and left us waiting. 416 // a network load and left us waiting.
(...skipping 15 matching lines...) Expand all
432 // Currently we're only smart enough to reuse the speculation buffer if the 432 // Currently we're only smart enough to reuse the speculation buffer if the
433 // tokenizer both starts and ends in the DataState. That state is simplest 433 // tokenizer both starts and ends in the DataState. That state is simplest
434 // because the HTMLToken is always in the Uninitialized state. We should 434 // because the HTMLToken is always in the Uninitialized state. We should
435 // consider whether we can reuse the speculation buffer in other states, but 435 // consider whether we can reuse the speculation buffer in other states, but
436 // we'd likely need to do something more sophisticated with the HTMLToken. 436 // we'd likely need to do something more sophisticated with the HTMLToken.
437 if (chunk->tokenizerState == HTMLTokenizer::DataState && 437 if (chunk->tokenizerState == HTMLTokenizer::DataState &&
438 tokenizer->getState() == HTMLTokenizer::DataState && 438 tokenizer->getState() == HTMLTokenizer::DataState &&
439 m_input.current().isEmpty() && 439 m_input.current().isEmpty() &&
440 chunk->treeBuilderState == 440 chunk->treeBuilderState ==
441 HTMLTreeBuilderSimulator::stateFor(m_treeBuilder.get())) { 441 HTMLTreeBuilderSimulator::stateFor(m_treeBuilder.get())) {
442 ASSERT(token->isUninitialized()); 442 DCHECK(token->isUninitialized());
443 return; 443 return;
444 } 444 }
445 445
446 discardSpeculationsAndResumeFrom(std::move(chunk), std::move(token), 446 discardSpeculationsAndResumeFrom(std::move(chunk), std::move(token),
447 std::move(tokenizer)); 447 std::move(tokenizer));
448 } 448 }
449 449
450 void HTMLDocumentParser::discardSpeculationsAndResumeFrom( 450 void HTMLDocumentParser::discardSpeculationsAndResumeFrom(
451 std::unique_ptr<TokenizedChunk> lastChunkBeforeScript, 451 std::unique_ptr<TokenizedChunk> lastChunkBeforeScript,
452 std::unique_ptr<HTMLToken> token, 452 std::unique_ptr<HTMLToken> token,
(...skipping 19 matching lines...) Expand all
472 checkpoint->tokenizer = std::move(tokenizer); 472 checkpoint->tokenizer = std::move(tokenizer);
473 checkpoint->treeBuilderState = 473 checkpoint->treeBuilderState =
474 HTMLTreeBuilderSimulator::stateFor(m_treeBuilder.get()); 474 HTMLTreeBuilderSimulator::stateFor(m_treeBuilder.get());
475 checkpoint->inputCheckpoint = lastChunkBeforeScript->inputCheckpoint; 475 checkpoint->inputCheckpoint = lastChunkBeforeScript->inputCheckpoint;
476 checkpoint->preloadScannerCheckpoint = 476 checkpoint->preloadScannerCheckpoint =
477 lastChunkBeforeScript->preloadScannerCheckpoint; 477 lastChunkBeforeScript->preloadScannerCheckpoint;
478 checkpoint->unparsedInput = m_input.current().toString().isolatedCopy(); 478 checkpoint->unparsedInput = m_input.current().toString().isolatedCopy();
479 // FIXME: This should be passed in instead of cleared. 479 // FIXME: This should be passed in instead of cleared.
480 m_input.current().clear(); 480 m_input.current().clear();
481 481
482 ASSERT(checkpoint->unparsedInput.isSafeToSendToAnotherThread()); 482 DCHECK(checkpoint->unparsedInput.isSafeToSendToAnotherThread());
483 m_loadingTaskRunner->postTask( 483 m_loadingTaskRunner->postTask(
484 BLINK_FROM_HERE, 484 BLINK_FROM_HERE,
485 WTF::bind(&BackgroundHTMLParser::resumeFrom, m_backgroundParser, 485 WTF::bind(&BackgroundHTMLParser::resumeFrom, m_backgroundParser,
486 WTF::passed(std::move(checkpoint)))); 486 WTF::passed(std::move(checkpoint))));
487 } 487 }
488 488
489 size_t HTMLDocumentParser::processTokenizedChunkFromBackgroundParser( 489 size_t HTMLDocumentParser::processTokenizedChunkFromBackgroundParser(
490 std::unique_ptr<TokenizedChunk> popChunk) { 490 std::unique_ptr<TokenizedChunk> popChunk) {
491 TRACE_EVENT_WITH_FLOW0( 491 TRACE_EVENT_WITH_FLOW0(
492 "blink,loading", 492 "blink,loading",
493 "HTMLDocumentParser::processTokenizedChunkFromBackgroundParser", 493 "HTMLDocumentParser::processTokenizedChunkFromBackgroundParser",
494 popChunk.get(), TRACE_EVENT_FLAG_FLOW_IN); 494 popChunk.get(), TRACE_EVENT_FLAG_FLOW_IN);
495 AutoReset<bool> hasLineNumber(&m_isParsingAtLineNumber, true); 495 AutoReset<bool> hasLineNumber(&m_isParsingAtLineNumber, true);
496 496
497 SECURITY_DCHECK(m_pumpSpeculationsSessionNestingLevel == 1); 497 SECURITY_DCHECK(m_pumpSpeculationsSessionNestingLevel == 1);
498 SECURITY_DCHECK(!inPumpSession()); 498 SECURITY_DCHECK(!inPumpSession());
499 ASSERT(!isParsingFragment()); 499 DCHECK(!isParsingFragment());
500 DCHECK(!isPaused()); 500 DCHECK(!isPaused());
501 ASSERT(!isStopped()); 501 DCHECK(!isStopped());
502 ASSERT(shouldUseThreading()); 502 DCHECK(shouldUseThreading());
503 ASSERT(!m_tokenizer); 503 DCHECK(!m_tokenizer);
504 ASSERT(!m_token); 504 DCHECK(!m_token);
505 DCHECK(!m_lastChunkBeforePause); 505 DCHECK(!m_lastChunkBeforePause);
506 506
507 std::unique_ptr<TokenizedChunk> chunk(std::move(popChunk)); 507 std::unique_ptr<TokenizedChunk> chunk(std::move(popChunk));
508 std::unique_ptr<CompactHTMLTokenStream> tokens = std::move(chunk->tokens); 508 std::unique_ptr<CompactHTMLTokenStream> tokens = std::move(chunk->tokens);
509 size_t elementTokenCount = 0; 509 size_t elementTokenCount = 0;
510 510
511 m_loadingTaskRunner->postTask( 511 m_loadingTaskRunner->postTask(
512 BLINK_FROM_HERE, 512 BLINK_FROM_HERE,
513 WTF::bind(&BackgroundHTMLParser::startedChunkWithCheckpoint, 513 WTF::bind(&BackgroundHTMLParser::startedChunkWithCheckpoint,
514 m_backgroundParser, chunk->inputCheckpoint)); 514 m_backgroundParser, chunk->inputCheckpoint));
515 515
516 for (const auto& xssInfo : chunk->xssInfos) { 516 for (const auto& xssInfo : chunk->xssInfos) {
517 m_textPosition = xssInfo->m_textPosition; 517 m_textPosition = xssInfo->m_textPosition;
518 m_xssAuditorDelegate.didBlockScript(*xssInfo); 518 m_xssAuditorDelegate.didBlockScript(*xssInfo);
519 if (isStopped()) 519 if (isStopped())
520 break; 520 break;
521 } 521 }
522 // XSSAuditorDelegate can detach the parser if it decides to block the entire 522 // XSSAuditorDelegate can detach the parser if it decides to block the entire
523 // current document. 523 // current document.
524 if (isDetached()) 524 if (isDetached())
525 return elementTokenCount; 525 return elementTokenCount;
526 526
527 for (Vector<CompactHTMLToken>::const_iterator it = tokens->begin(); 527 for (Vector<CompactHTMLToken>::const_iterator it = tokens->begin();
528 it != tokens->end(); ++it) { 528 it != tokens->end(); ++it) {
529 ASSERT(!isWaitingForScripts()); 529 DCHECK(!isWaitingForScripts());
530 530
531 if (!chunk->startingScript && 531 if (!chunk->startingScript &&
532 (it->type() == HTMLToken::StartTag || it->type() == HTMLToken::EndTag)) 532 (it->type() == HTMLToken::StartTag || it->type() == HTMLToken::EndTag))
533 elementTokenCount++; 533 elementTokenCount++;
534 534
535 if (document()->frame() && 535 if (document()->frame() &&
536 document()->frame()->navigationScheduler().locationChangePending()) { 536 document()->frame()->navigationScheduler().locationChangePending()) {
537 // To match main-thread parser behavior (which never checks 537 // To match main-thread parser behavior (which never checks
538 // locationChangePending on the EOF path) we peek to see if this chunk has 538 // locationChangePending on the EOF path) we peek to see if this chunk has
539 // an EOF and process it anyway. 539 // an EOF and process it anyway.
540 if (tokens->back().type() == HTMLToken::EndOfFile) { 540 if (tokens->back().type() == HTMLToken::EndOfFile) {
541 ASSERT( 541 DCHECK(
542 m_speculations 542 m_speculations
543 .isEmpty()); // There should never be any chunks after the EOF. 543 .isEmpty()); // There should never be any chunks after the EOF.
544 prepareToStopParsing(); 544 prepareToStopParsing();
545 } 545 }
546 break; 546 break;
547 } 547 }
548 548
549 m_textPosition = it->textPosition(); 549 m_textPosition = it->textPosition();
550 550
551 constructTreeFromCompactHTMLToken(*it); 551 constructTreeFromCompactHTMLToken(*it);
552 552
553 if (isStopped()) 553 if (isStopped())
554 break; 554 break;
555 555
556 // Preloads were queued if there was a <meta> csp token in a tokenized 556 // Preloads were queued if there was a <meta> csp token in a tokenized
557 // chunk. 557 // chunk.
558 if (m_pendingCSPMetaToken && it == m_pendingCSPMetaToken) { 558 if (m_pendingCSPMetaToken && it == m_pendingCSPMetaToken) {
559 m_pendingCSPMetaToken = nullptr; 559 m_pendingCSPMetaToken = nullptr;
560 fetchQueuedPreloads(); 560 fetchQueuedPreloads();
561 } 561 }
562 562
563 if (isPaused()) { 563 if (isPaused()) {
564 // The script or stylesheet should be the last token of this bunch. 564 // The script or stylesheet should be the last token of this bunch.
565 ASSERT(it + 1 == tokens->end()); 565 DCHECK_EQ(it + 1, tokens->end());
566 if (isWaitingForScripts()) 566 if (isWaitingForScripts())
567 runScriptsForPausedTreeBuilder(); 567 runScriptsForPausedTreeBuilder();
568 validateSpeculations(std::move(chunk)); 568 validateSpeculations(std::move(chunk));
569 break; 569 break;
570 } 570 }
571 571
572 if (it->type() == HTMLToken::EndOfFile) { 572 if (it->type() == HTMLToken::EndOfFile) {
573 // The EOF is assumed to be the last token of this bunch. 573 // The EOF is assumed to be the last token of this bunch.
574 ASSERT(it + 1 == tokens->end()); 574 DCHECK_EQ(it + 1, tokens->end());
575 // There should never be any chunks after the EOF. 575 // There should never be any chunks after the EOF.
576 ASSERT(m_speculations.isEmpty()); 576 DCHECK(m_speculations.isEmpty());
577 prepareToStopParsing(); 577 prepareToStopParsing();
578 break; 578 break;
579 } 579 }
580 580
581 ASSERT(!m_tokenizer); 581 DCHECK(!m_tokenizer);
582 ASSERT(!m_token); 582 DCHECK(!m_token);
583 } 583 }
584 584
585 // Make sure all required pending text nodes are emitted before returning. 585 // Make sure all required pending text nodes are emitted before returning.
586 // This leaves "script", "style" and "svg" nodes text nodes intact. 586 // This leaves "script", "style" and "svg" nodes text nodes intact.
587 if (!isStopped()) 587 if (!isStopped())
588 m_treeBuilder->flush(FlushIfAtTextLimit); 588 m_treeBuilder->flush(FlushIfAtTextLimit);
589 589
590 m_isParsingAtLineNumber = false; 590 m_isParsingAtLineNumber = false;
591 591
592 return elementTokenCount; 592 return elementTokenCount;
593 } 593 }
594 594
595 void HTMLDocumentParser::pumpPendingSpeculations() { 595 void HTMLDocumentParser::pumpPendingSpeculations() {
596 // If this assert fails, you need to call validateSpeculations to make sure 596 // If this assert fails, you need to call validateSpeculations to make sure
597 // m_tokenizer and m_token don't have state that invalidates m_speculations. 597 // m_tokenizer and m_token don't have state that invalidates m_speculations.
598 ASSERT(!m_tokenizer); 598 DCHECK(!m_tokenizer);
599 ASSERT(!m_token); 599 DCHECK(!m_token);
600 DCHECK(!m_lastChunkBeforePause); 600 DCHECK(!m_lastChunkBeforePause);
601 DCHECK(!isPaused()); 601 DCHECK(!isPaused());
602 ASSERT(!isStopped()); 602 DCHECK(!isStopped());
603 ASSERT(!isScheduledForResume()); 603 DCHECK(!isScheduledForResume());
604 ASSERT(!inPumpSession()); 604 DCHECK(!inPumpSession());
605 605
606 // FIXME: Here should never be reached when there is a blocking script, 606 // FIXME: Here should never be reached when there is a blocking script,
607 // but it happens in unknown scenarios. See https://crbug.com/440901 607 // but it happens in unknown scenarios. See https://crbug.com/440901
608 if (isWaitingForScripts()) { 608 if (isWaitingForScripts()) {
609 m_parserScheduler->scheduleForResume(); 609 m_parserScheduler->scheduleForResume();
610 return; 610 return;
611 } 611 }
612 612
613 // Do not allow pumping speculations in nested event loops. 613 // Do not allow pumping speculations in nested event loops.
614 if (m_pumpSpeculationsSessionNestingLevel) { 614 if (m_pumpSpeculationsSessionNestingLevel) {
615 m_parserScheduler->scheduleForResume(); 615 m_parserScheduler->scheduleForResume();
616 return; 616 return;
617 } 617 }
618 618
619 probe::ParseHTML probe(document(), this); 619 probe::ParseHTML probe(document(), this);
620 620
621 SpeculationsPumpSession session(m_pumpSpeculationsSessionNestingLevel); 621 SpeculationsPumpSession session(m_pumpSpeculationsSessionNestingLevel);
622 while (!m_speculations.isEmpty()) { 622 while (!m_speculations.isEmpty()) {
623 ASSERT(!isScheduledForResume()); 623 DCHECK(!isScheduledForResume());
624 size_t elementTokenCount = 624 size_t elementTokenCount =
625 processTokenizedChunkFromBackgroundParser(m_speculations.takeFirst()); 625 processTokenizedChunkFromBackgroundParser(m_speculations.takeFirst());
626 session.addedElementTokens(elementTokenCount); 626 session.addedElementTokens(elementTokenCount);
627 627
628 // Always check isParsing first as m_document may be null. Surprisingly, 628 // Always check isParsing first as m_document may be null. Surprisingly,
629 // isScheduledForResume() may be set here as a result of 629 // isScheduledForResume() may be set here as a result of
630 // processTokenizedChunkFromBackgroundParser running arbitrary javascript 630 // processTokenizedChunkFromBackgroundParser running arbitrary javascript
631 // which invokes nested event loops. (e.g. inspector breakpoints) 631 // which invokes nested event loops. (e.g. inspector breakpoints)
632 checkIfBodyStylesheetAdded(); 632 checkIfBodyStylesheetAdded();
633 if (!isParsing() || isPaused() || isScheduledForResume()) 633 if (!isParsing() || isPaused() || isScheduledForResume())
(...skipping 14 matching lines...) Expand all
648 startBackgroundParser(); 648 startBackgroundParser();
649 649
650 // This task should be synchronous, because otherwise synchronous 650 // This task should be synchronous, because otherwise synchronous
651 // tokenizing can happen before plaintext is forced. 651 // tokenizing can happen before plaintext is forced.
652 m_backgroundParser->forcePlaintextForTextDocument(); 652 m_backgroundParser->forcePlaintextForTextDocument();
653 } else 653 } else
654 m_tokenizer->setState(HTMLTokenizer::PLAINTEXTState); 654 m_tokenizer->setState(HTMLTokenizer::PLAINTEXTState);
655 } 655 }
656 656
657 void HTMLDocumentParser::pumpTokenizer() { 657 void HTMLDocumentParser::pumpTokenizer() {
658 ASSERT(!isStopped()); 658 DCHECK(!isStopped());
659 ASSERT(m_tokenizer); 659 DCHECK(m_tokenizer);
660 ASSERT(m_token); 660 DCHECK(m_token);
661 661
662 PumpSession session(m_pumpSessionNestingLevel); 662 PumpSession session(m_pumpSessionNestingLevel);
663 663
664 // We tell the InspectorInstrumentation about every pump, even if we end up 664 // We tell the InspectorInstrumentation about every pump, even if we end up
665 // pumping nothing. It can filter out empty pumps itself. 665 // pumping nothing. It can filter out empty pumps itself.
666 // FIXME: m_input.current().length() is only accurate if we end up parsing the 666 // FIXME: m_input.current().length() is only accurate if we end up parsing the
667 // whole buffer in this pump. We should pass how much we parsed as part of 667 // whole buffer in this pump. We should pass how much we parsed as part of
668 // didWriteHTML instead of willWriteHTML. 668 // didWriteHTML instead of willWriteHTML.
669 probe::ParseHTML probe(document(), this); 669 probe::ParseHTML probe(document(), this);
670 670
(...skipping 17 matching lines...) Expand all
688 token(), m_sourceTracker, m_tokenizer->shouldAllowCDATA()))) { 688 token(), m_sourceTracker, m_tokenizer->shouldAllowCDATA()))) {
689 m_xssAuditorDelegate.didBlockScript(*xssInfo); 689 m_xssAuditorDelegate.didBlockScript(*xssInfo);
690 // If we're in blocking mode, we might stop the parser in 690 // If we're in blocking mode, we might stop the parser in
691 // 'didBlockScript()'. In that case, exit early. 691 // 'didBlockScript()'. In that case, exit early.
692 if (!isParsing()) 692 if (!isParsing())
693 return; 693 return;
694 } 694 }
695 } 695 }
696 696
697 constructTreeFromHTMLToken(); 697 constructTreeFromHTMLToken();
698 ASSERT(isStopped() || token().isUninitialized()); 698 DCHECK(isStopped() || token().isUninitialized());
699 } 699 }
700 700
701 if (isStopped()) 701 if (isStopped())
702 return; 702 return;
703 703
704 // There should only be PendingText left since the tree-builder always flushes 704 // There should only be PendingText left since the tree-builder always flushes
705 // the task queue before returning. In case that ever changes, crash. 705 // the task queue before returning. In case that ever changes, crash.
706 m_treeBuilder->flush(FlushAlways); 706 m_treeBuilder->flush(FlushAlways);
707 RELEASE_ASSERT(!isStopped()); 707 CHECK(!isStopped());
708 708
709 if (isPaused()) { 709 if (isPaused()) {
710 ASSERT(m_tokenizer->getState() == HTMLTokenizer::DataState); 710 DCHECK_EQ(m_tokenizer->getState(), HTMLTokenizer::DataState);
711 711
712 ASSERT(m_preloader); 712 DCHECK(m_preloader);
713 // TODO(kouhei): m_preloader should be always available for synchronous 713 // TODO(kouhei): m_preloader should be always available for synchronous
714 // parsing case, adding paranoia if for speculative crash fix for 714 // parsing case, adding paranoia if for speculative crash fix for
715 // crbug.com/465478 715 // crbug.com/465478
716 if (m_preloader) { 716 if (m_preloader) {
717 if (!m_preloadScanner) { 717 if (!m_preloadScanner) {
718 m_preloadScanner = createPreloadScanner(); 718 m_preloadScanner = createPreloadScanner();
719 m_preloadScanner->appendToEnd(m_input.current()); 719 m_preloadScanner->appendToEnd(m_input.current());
720 } 720 }
721 scanAndPreload(m_preloadScanner.get()); 721 scanAndPreload(m_preloadScanner.get());
722 } 722 }
(...skipping 17 matching lines...) Expand all
740 token().clear(); 740 token().clear();
741 741
742 m_treeBuilder->constructTree(&atomicToken); 742 m_treeBuilder->constructTree(&atomicToken);
743 checkIfBodyStylesheetAdded(); 743 checkIfBodyStylesheetAdded();
744 744
745 // FIXME: constructTree may synchronously cause Document to be detached. 745 // FIXME: constructTree may synchronously cause Document to be detached.
746 if (!m_token) 746 if (!m_token)
747 return; 747 return;
748 748
749 if (!token().isUninitialized()) { 749 if (!token().isUninitialized()) {
750 ASSERT(token().type() == HTMLToken::Character); 750 DCHECK_EQ(token().type(), HTMLToken::Character);
751 token().clear(); 751 token().clear();
752 } 752 }
753 } 753 }
754 754
755 void HTMLDocumentParser::constructTreeFromCompactHTMLToken( 755 void HTMLDocumentParser::constructTreeFromCompactHTMLToken(
756 const CompactHTMLToken& compactToken) { 756 const CompactHTMLToken& compactToken) {
757 AtomicHTMLToken token(compactToken); 757 AtomicHTMLToken token(compactToken);
758 m_treeBuilder->constructTree(&token); 758 m_treeBuilder->constructTree(&token);
759 checkIfBodyStylesheetAdded(); 759 checkIfBodyStylesheetAdded();
760 } 760 }
761 761
762 bool HTMLDocumentParser::hasInsertionPoint() { 762 bool HTMLDocumentParser::hasInsertionPoint() {
763 // FIXME: The wasCreatedByScript() branch here might not be fully correct. Our 763 // FIXME: The wasCreatedByScript() branch here might not be fully correct. Our
764 // model of the EOF character differs slightly from the one in the spec 764 // model of the EOF character differs slightly from the one in the spec
765 // because our treatment is uniform between network-sourced and script-sourced 765 // because our treatment is uniform between network-sourced and script-sourced
766 // input streams whereas the spec treats them differently. 766 // input streams whereas the spec treats them differently.
767 return m_input.hasInsertionPoint() || 767 return m_input.hasInsertionPoint() ||
768 (wasCreatedByScript() && !m_input.haveSeenEndOfFile()); 768 (wasCreatedByScript() && !m_input.haveSeenEndOfFile());
769 } 769 }
770 770
771 void HTMLDocumentParser::insert(const SegmentedString& source) { 771 void HTMLDocumentParser::insert(const SegmentedString& source) {
772 if (isStopped()) 772 if (isStopped())
773 return; 773 return;
774 774
775 TRACE_EVENT1("blink", "HTMLDocumentParser::insert", "source_length", 775 TRACE_EVENT1("blink", "HTMLDocumentParser::insert", "source_length",
776 source.length()); 776 source.length());
777 777
778 if (!m_tokenizer) { 778 if (!m_tokenizer) {
779 ASSERT(!inPumpSession()); 779 DCHECK(!inPumpSession());
780 ASSERT(m_haveBackgroundParser || wasCreatedByScript()); 780 DCHECK(m_haveBackgroundParser || wasCreatedByScript());
781 m_token = WTF::wrapUnique(new HTMLToken); 781 m_token = WTF::wrapUnique(new HTMLToken);
782 m_tokenizer = HTMLTokenizer::create(m_options); 782 m_tokenizer = HTMLTokenizer::create(m_options);
783 } 783 }
784 784
785 SegmentedString excludedLineNumberSource(source); 785 SegmentedString excludedLineNumberSource(source);
786 excludedLineNumberSource.setExcludeLineNumbers(); 786 excludedLineNumberSource.setExcludeLineNumbers();
787 m_input.insertAtCurrentInsertionPoint(excludedLineNumberSource); 787 m_input.insertAtCurrentInsertionPoint(excludedLineNumberSource);
788 pumpTokenizerIfPossible(); 788 pumpTokenizerIfPossible();
789 789
790 if (isPaused()) { 790 if (isPaused()) {
791 // Check the document.write() output with a separate preload scanner as 791 // Check the document.write() output with a separate preload scanner as
792 // the main scanner can't deal with insertions. 792 // the main scanner can't deal with insertions.
793 if (!m_insertionPreloadScanner) 793 if (!m_insertionPreloadScanner)
794 m_insertionPreloadScanner = createPreloadScanner(); 794 m_insertionPreloadScanner = createPreloadScanner();
795 m_insertionPreloadScanner->appendToEnd(source); 795 m_insertionPreloadScanner->appendToEnd(source);
796 scanAndPreload(m_insertionPreloadScanner.get()); 796 scanAndPreload(m_insertionPreloadScanner.get());
797 } 797 }
798 798
799 endIfDelayed(); 799 endIfDelayed();
800 } 800 }
801 801
802 void HTMLDocumentParser::startBackgroundParser() { 802 void HTMLDocumentParser::startBackgroundParser() {
803 ASSERT(!isStopped()); 803 DCHECK(!isStopped());
804 ASSERT(shouldUseThreading()); 804 DCHECK(shouldUseThreading());
805 ASSERT(!m_haveBackgroundParser); 805 DCHECK(!m_haveBackgroundParser);
806 ASSERT(document()); 806 DCHECK(document());
807 m_haveBackgroundParser = true; 807 m_haveBackgroundParser = true;
808 808
809 // TODO(alexclarke): Remove WebFrameScheduler::setDocumentParsingInBackground 809 // TODO(alexclarke): Remove WebFrameScheduler::setDocumentParsingInBackground
810 // when background parser goes away. 810 // when background parser goes away.
811 if (document()->frame() && document()->frame()->frameScheduler()) 811 if (document()->frame() && document()->frame()->frameScheduler())
812 document()->frame()->frameScheduler()->setDocumentParsingInBackground(true); 812 document()->frame()->frameScheduler()->setDocumentParsingInBackground(true);
813 813
814 // Make sure that a resolver is set up, so that the correct viewport 814 // Make sure that a resolver is set up, so that the correct viewport
815 // dimensions will be fed to the background parser and preload scanner. 815 // dimensions will be fed to the background parser and preload scanner.
816 if (document()->loader()) 816 if (document()->loader())
(...skipping 16 matching lines...) Expand all
833 document() 833 document()
834 ->settings() 834 ->settings()
835 ->getBackgroundHtmlParserOutstandingTokenLimit(); 835 ->getBackgroundHtmlParserOutstandingTokenLimit();
836 } 836 }
837 if (document()->settings()->getBackgroundHtmlParserPendingTokenLimit()) { 837 if (document()->settings()->getBackgroundHtmlParserPendingTokenLimit()) {
838 config->pendingTokenLimit = 838 config->pendingTokenLimit =
839 document()->settings()->getBackgroundHtmlParserPendingTokenLimit(); 839 document()->settings()->getBackgroundHtmlParserPendingTokenLimit();
840 } 840 }
841 } 841 }
842 842
843 ASSERT(config->xssAuditor->isSafeToSendToAnotherThread()); 843 DCHECK(config->xssAuditor->isSafeToSendToAnotherThread());
844 844
845 // The background parser is created on the main thread, but may otherwise 845 // The background parser is created on the main thread, but may otherwise
846 // only be used from the parser thread. 846 // only be used from the parser thread.
847 m_backgroundParser = 847 m_backgroundParser =
848 BackgroundHTMLParser::create(std::move(config), m_loadingTaskRunner); 848 BackgroundHTMLParser::create(std::move(config), m_loadingTaskRunner);
849 // TODO(csharrison): This is a hack to initialize MediaValuesCached on the 849 // TODO(csharrison): This is a hack to initialize MediaValuesCached on the
850 // correct thread. We should get rid of it. 850 // correct thread. We should get rid of it.
851 m_backgroundParser->init( 851 m_backgroundParser->init(
852 document()->url(), CachedDocumentParameters::create(document()), 852 document()->url(), CachedDocumentParameters::create(document()),
853 MediaValuesCached::MediaValuesCachedData(*document())); 853 MediaValuesCached::MediaValuesCachedData(*document()));
854 } 854 }
855 855
856 void HTMLDocumentParser::stopBackgroundParser() { 856 void HTMLDocumentParser::stopBackgroundParser() {
857 ASSERT(shouldUseThreading()); 857 DCHECK(shouldUseThreading());
858 ASSERT(m_haveBackgroundParser); 858 DCHECK(m_haveBackgroundParser);
859 859
860 if (m_haveBackgroundParser && document()->frame() && 860 if (m_haveBackgroundParser && document()->frame() &&
861 document()->frame()->frameScheduler()) 861 document()->frame()->frameScheduler())
862 document()->frame()->frameScheduler()->setDocumentParsingInBackground( 862 document()->frame()->frameScheduler()->setDocumentParsingInBackground(
863 false); 863 false);
864 864
865 m_haveBackgroundParser = false; 865 m_haveBackgroundParser = false;
866 866
867 // Make this sync, as lsan triggers on some unittests if the task runner is 867 // Make this sync, as lsan triggers on some unittests if the task runner is
868 // used. 868 // used.
869 m_backgroundParser->stop(); 869 m_backgroundParser->stop();
870 m_weakFactory.revokeAll(); 870 m_weakFactory.revokeAll();
871 } 871 }
872 872
873 void HTMLDocumentParser::append(const String& inputSource) { 873 void HTMLDocumentParser::append(const String& inputSource) {
874 if (isStopped()) 874 if (isStopped())
875 return; 875 return;
876 876
877 // We should never reach this point if we're using a parser thread, as 877 // We should never reach this point if we're using a parser thread, as
878 // appendBytes() will directly ship the data to the thread. 878 // appendBytes() will directly ship the data to the thread.
879 ASSERT(!shouldUseThreading()); 879 DCHECK(!shouldUseThreading());
880 880
881 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("blink.debug"), 881 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("blink.debug"),
882 "HTMLDocumentParser::append", "size", inputSource.length()); 882 "HTMLDocumentParser::append", "size", inputSource.length());
883 const SegmentedString source(inputSource); 883 const SegmentedString source(inputSource);
884 884
885 if (document()->isPrefetchOnly()) { 885 if (document()->isPrefetchOnly()) {
886 if (!m_preloadScanner) 886 if (!m_preloadScanner)
887 m_preloadScanner = createPreloadScanner(); 887 m_preloadScanner = createPreloadScanner();
888 888
889 m_preloadScanner->appendToEnd(source); 889 m_preloadScanner->appendToEnd(source);
(...skipping 24 matching lines...) Expand all
914 // this data in a less-nested write(). 914 // this data in a less-nested write().
915 return; 915 return;
916 } 916 }
917 917
918 pumpTokenizerIfPossible(); 918 pumpTokenizerIfPossible();
919 919
920 endIfDelayed(); 920 endIfDelayed();
921 } 921 }
922 922
923 void HTMLDocumentParser::end() { 923 void HTMLDocumentParser::end() {
924 ASSERT(!isDetached()); 924 DCHECK(!isDetached());
925 ASSERT(!isScheduledForResume()); 925 DCHECK(!isScheduledForResume());
926 926
927 if (m_haveBackgroundParser) 927 if (m_haveBackgroundParser)
928 stopBackgroundParser(); 928 stopBackgroundParser();
929 929
930 // Informs the the rest of WebCore that parsing is really finished (and 930 // Informs the the rest of WebCore that parsing is really finished (and
931 // deletes this). 931 // deletes this).
932 m_treeBuilder->finished(); 932 m_treeBuilder->finished();
933 933
934 DocumentParser::stopParsing(); 934 DocumentParser::stopParsing();
935 } 935 }
936 936
937 void HTMLDocumentParser::attemptToRunDeferredScriptsAndEnd() { 937 void HTMLDocumentParser::attemptToRunDeferredScriptsAndEnd() {
938 ASSERT(isStopping()); 938 DCHECK(isStopping());
939 // FIXME: It may not be correct to disable this for the background parser. 939 // FIXME: It may not be correct to disable this for the background parser.
940 // That means hasInsertionPoint() may not be correct in some cases. 940 // That means hasInsertionPoint() may not be correct in some cases.
941 ASSERT(!hasInsertionPoint() || m_haveBackgroundParser); 941 DCHECK(!hasInsertionPoint() || m_haveBackgroundParser);
942 if (m_scriptRunner && !m_scriptRunner->executeScriptsWaitingForParsing()) 942 if (m_scriptRunner && !m_scriptRunner->executeScriptsWaitingForParsing())
943 return; 943 return;
944 end(); 944 end();
945 } 945 }
946 946
947 void HTMLDocumentParser::attemptToEnd() { 947 void HTMLDocumentParser::attemptToEnd() {
948 // finish() indicates we will not receive any more data. If we are waiting on 948 // finish() indicates we will not receive any more data. If we are waiting on
949 // an external script to load, we can't finish parsing quite yet. 949 // an external script to load, we can't finish parsing quite yet.
950 950
951 if (shouldDelayEnd()) { 951 if (shouldDelayEnd()) {
(...skipping 30 matching lines...) Expand all
982 if (m_haveBackgroundParser) { 982 if (m_haveBackgroundParser) {
983 if (!m_input.haveSeenEndOfFile()) 983 if (!m_input.haveSeenEndOfFile())
984 m_input.closeWithoutMarkingEndOfFile(); 984 m_input.closeWithoutMarkingEndOfFile();
985 m_loadingTaskRunner->postTask( 985 m_loadingTaskRunner->postTask(
986 BLINK_FROM_HERE, 986 BLINK_FROM_HERE,
987 WTF::bind(&BackgroundHTMLParser::finish, m_backgroundParser)); 987 WTF::bind(&BackgroundHTMLParser::finish, m_backgroundParser));
988 return; 988 return;
989 } 989 }
990 990
991 if (!m_tokenizer) { 991 if (!m_tokenizer) {
992 ASSERT(!m_token); 992 DCHECK(!m_token);
993 // We're finishing before receiving any data. Rather than booting up the 993 // We're finishing before receiving any data. Rather than booting up the
994 // background parser just to spin it down, we finish parsing synchronously. 994 // background parser just to spin it down, we finish parsing synchronously.
995 m_token = WTF::wrapUnique(new HTMLToken); 995 m_token = WTF::wrapUnique(new HTMLToken);
996 m_tokenizer = HTMLTokenizer::create(m_options); 996 m_tokenizer = HTMLTokenizer::create(m_options);
997 } 997 }
998 998
999 // We're not going to get any more data off the network, so we tell the input 999 // We're not going to get any more data off the network, so we tell the input
1000 // stream we've reached the end of file. finish() can be called more than 1000 // stream we've reached the end of file. finish() can be called more than
1001 // once, if the first time does not call end(). 1001 // once, if the first time does not call end().
1002 if (!m_input.haveSeenEndOfFile()) 1002 if (!m_input.haveSeenEndOfFile())
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
1040 // the script runner. The script runner will hold the script until its loaded 1040 // the script runner. The script runner will hold the script until its loaded
1041 // and run. During any of this time, we want to count ourselves as "waiting 1041 // and run. During any of this time, we want to count ourselves as "waiting
1042 // for a script" and thus run the preload scanner, as well as delay completion 1042 // for a script" and thus run the preload scanner, as well as delay completion
1043 // of parsing. 1043 // of parsing.
1044 bool treeBuilderHasBlockingScript = m_treeBuilder->hasParserBlockingScript(); 1044 bool treeBuilderHasBlockingScript = m_treeBuilder->hasParserBlockingScript();
1045 bool scriptRunnerHasBlockingScript = 1045 bool scriptRunnerHasBlockingScript =
1046 m_scriptRunner && m_scriptRunner->hasParserBlockingScript(); 1046 m_scriptRunner && m_scriptRunner->hasParserBlockingScript();
1047 // Since the parser is paused while a script runner has a blocking script, it 1047 // Since the parser is paused while a script runner has a blocking script, it
1048 // should never be possible to end up with both objects holding a blocking 1048 // should never be possible to end up with both objects holding a blocking
1049 // script. 1049 // script.
1050 ASSERT(!(treeBuilderHasBlockingScript && scriptRunnerHasBlockingScript)); 1050 DCHECK(!(treeBuilderHasBlockingScript && scriptRunnerHasBlockingScript));
1051 // If either object has a blocking script, the parser should be paused. 1051 // If either object has a blocking script, the parser should be paused.
1052 return treeBuilderHasBlockingScript || scriptRunnerHasBlockingScript || 1052 return treeBuilderHasBlockingScript || scriptRunnerHasBlockingScript ||
1053 m_reentryPermit->parserPauseFlag(); 1053 m_reentryPermit->parserPauseFlag();
1054 } 1054 }
1055 1055
1056 void HTMLDocumentParser::resumeParsingAfterPause() { 1056 void HTMLDocumentParser::resumeParsingAfterPause() {
1057 ASSERT(!isExecutingScript()); 1057 DCHECK(!isExecutingScript());
1058 DCHECK(!isPaused()); 1058 DCHECK(!isPaused());
1059 1059
1060 checkIfBodyStylesheetAdded(); 1060 checkIfBodyStylesheetAdded();
1061 if (isPaused()) 1061 if (isPaused())
1062 return; 1062 return;
1063 1063
1064 if (m_haveBackgroundParser) { 1064 if (m_haveBackgroundParser) {
1065 if (m_lastChunkBeforePause) { 1065 if (m_lastChunkBeforePause) {
1066 validateSpeculations(std::move(m_lastChunkBeforePause)); 1066 validateSpeculations(std::move(m_lastChunkBeforePause));
1067 DCHECK(!m_lastChunkBeforePause); 1067 DCHECK(!m_lastChunkBeforePause);
1068 pumpPendingSpeculations(); 1068 pumpPendingSpeculations();
1069 } 1069 }
1070 return; 1070 return;
1071 } 1071 }
1072 1072
1073 m_insertionPreloadScanner.reset(); 1073 m_insertionPreloadScanner.reset();
1074 if (m_tokenizer) { 1074 if (m_tokenizer) {
1075 pumpTokenizerIfPossible(); 1075 pumpTokenizerIfPossible();
1076 } 1076 }
1077 endIfDelayed(); 1077 endIfDelayed();
1078 } 1078 }
1079 1079
1080 void HTMLDocumentParser::appendCurrentInputStreamToPreloadScannerAndScan() { 1080 void HTMLDocumentParser::appendCurrentInputStreamToPreloadScannerAndScan() {
1081 ASSERT(m_preloadScanner); 1081 DCHECK(m_preloadScanner);
1082 m_preloadScanner->appendToEnd(m_input.current()); 1082 m_preloadScanner->appendToEnd(m_input.current());
1083 scanAndPreload(m_preloadScanner.get()); 1083 scanAndPreload(m_preloadScanner.get());
1084 } 1084 }
1085 1085
1086 void HTMLDocumentParser::notifyScriptLoaded(PendingScript* pendingScript) { 1086 void HTMLDocumentParser::notifyScriptLoaded(PendingScript* pendingScript) {
1087 ASSERT(m_scriptRunner); 1087 DCHECK(m_scriptRunner);
1088 ASSERT(!isExecutingScript()); 1088 DCHECK(!isExecutingScript());
1089 1089
1090 if (isStopped()) { 1090 if (isStopped()) {
1091 return; 1091 return;
1092 } 1092 }
1093 1093
1094 if (isStopping()) { 1094 if (isStopping()) {
1095 attemptToRunDeferredScriptsAndEnd(); 1095 attemptToRunDeferredScriptsAndEnd();
1096 return; 1096 return;
1097 } 1097 }
1098 1098
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
1148 ParserContentPolicy parserContentPolicy) { 1148 ParserContentPolicy parserContentPolicy) {
1149 HTMLDocumentParser* parser = 1149 HTMLDocumentParser* parser =
1150 HTMLDocumentParser::create(fragment, contextElement, parserContentPolicy); 1150 HTMLDocumentParser::create(fragment, contextElement, parserContentPolicy);
1151 parser->append(source); 1151 parser->append(source);
1152 parser->finish(); 1152 parser->finish();
1153 // Allows ~DocumentParser to assert it was detached before destruction. 1153 // Allows ~DocumentParser to assert it was detached before destruction.
1154 parser->detach(); 1154 parser->detach();
1155 } 1155 }
1156 1156
1157 void HTMLDocumentParser::suspendScheduledTasks() { 1157 void HTMLDocumentParser::suspendScheduledTasks() {
1158 ASSERT(!m_tasksWereSuspended); 1158 DCHECK(!m_tasksWereSuspended);
1159 m_tasksWereSuspended = true; 1159 m_tasksWereSuspended = true;
1160 if (m_parserScheduler) 1160 if (m_parserScheduler)
1161 m_parserScheduler->suspend(); 1161 m_parserScheduler->suspend();
1162 } 1162 }
1163 1163
1164 void HTMLDocumentParser::resumeScheduledTasks() { 1164 void HTMLDocumentParser::resumeScheduledTasks() {
1165 ASSERT(m_tasksWereSuspended); 1165 DCHECK(m_tasksWereSuspended);
1166 m_tasksWereSuspended = false; 1166 m_tasksWereSuspended = false;
1167 if (m_parserScheduler) 1167 if (m_parserScheduler)
1168 m_parserScheduler->resume(); 1168 m_parserScheduler->resume();
1169 } 1169 }
1170 1170
1171 void HTMLDocumentParser::appendBytes(const char* data, size_t length) { 1171 void HTMLDocumentParser::appendBytes(const char* data, size_t length) {
1172 if (!length || isStopped()) 1172 if (!length || isStopped())
1173 return; 1173 return;
1174 1174
1175 if (shouldUseThreading()) { 1175 if (shouldUseThreading()) {
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
1213 m_loadingTaskRunner->postTask( 1213 m_loadingTaskRunner->postTask(
1214 BLINK_FROM_HERE, 1214 BLINK_FROM_HERE,
1215 WTF::bind(&BackgroundHTMLParser::flush, m_backgroundParser)); 1215 WTF::bind(&BackgroundHTMLParser::flush, m_backgroundParser));
1216 } else { 1216 } else {
1217 DecodedDataDocumentParser::flush(); 1217 DecodedDataDocumentParser::flush();
1218 } 1218 }
1219 } 1219 }
1220 1220
1221 void HTMLDocumentParser::setDecoder( 1221 void HTMLDocumentParser::setDecoder(
1222 std::unique_ptr<TextResourceDecoder> decoder) { 1222 std::unique_ptr<TextResourceDecoder> decoder) {
1223 ASSERT(decoder); 1223 DCHECK(decoder);
1224 DecodedDataDocumentParser::setDecoder(std::move(decoder)); 1224 DecodedDataDocumentParser::setDecoder(std::move(decoder));
1225 1225
1226 if (m_haveBackgroundParser) { 1226 if (m_haveBackgroundParser) {
1227 m_loadingTaskRunner->postTask( 1227 m_loadingTaskRunner->postTask(
1228 BLINK_FROM_HERE, 1228 BLINK_FROM_HERE,
1229 WTF::bind(&BackgroundHTMLParser::setDecoder, m_backgroundParser, 1229 WTF::bind(&BackgroundHTMLParser::setDecoder, m_backgroundParser,
1230 WTF::passed(takeDecoder()))); 1230 WTF::passed(takeDecoder())));
1231 } 1231 }
1232 } 1232 }
1233 1233
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
1313 successHistogram.count(duration); 1313 successHistogram.count(duration);
1314 } else { 1314 } else {
1315 DEFINE_STATIC_LOCAL( 1315 DEFINE_STATIC_LOCAL(
1316 CustomCountHistogram, failureHistogram, 1316 CustomCountHistogram, failureHistogram,
1317 ("PreloadScanner.DocumentWrite.ExecutionTime.Failure", 1, 10000, 50)); 1317 ("PreloadScanner.DocumentWrite.ExecutionTime.Failure", 1, 10000, 50));
1318 failureHistogram.count(duration); 1318 failureHistogram.count(duration);
1319 } 1319 }
1320 } 1320 }
1321 1321
1322 } // namespace blink 1322 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698