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

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

Issue 258013009: Make the HTMLDocumentParser yield more aggressively Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2010 Google, Inc. All Rights Reserved. 2 * Copyright (C) 2010 Google, Inc. All Rights Reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions 5 * modification, are permitted provided that the following conditions
6 * are met: 6 * are met:
7 * 1. Redistributions of source code must retain the above copyright 7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer. 8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright 9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the 10 * notice, this list of conditions and the following disclaimer in the
(...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after
318 if (mode == AllowYield) 318 if (mode == AllowYield)
319 m_parserScheduler->checkForYieldBeforeToken(session); 319 m_parserScheduler->checkForYieldBeforeToken(session);
320 320
321 return true; 321 return true;
322 } 322 }
323 323
324 void HTMLDocumentParser::didReceiveParsedChunkFromBackgroundParser(PassOwnPtr<Pa rsedChunk> chunk) 324 void HTMLDocumentParser::didReceiveParsedChunkFromBackgroundParser(PassOwnPtr<Pa rsedChunk> chunk)
325 { 325 {
326 TRACE_EVENT0("webkit", "HTMLDocumentParser::didReceiveParsedChunkFromBackgro undParser"); 326 TRACE_EVENT0("webkit", "HTMLDocumentParser::didReceiveParsedChunkFromBackgro undParser");
327 327
328 // alert(), runModalDialog, and the JavaScript Debugger all run nested event loops 328 m_preloader->takeAndPreload(chunk->preloads);
329 // which can cause this method to be re-entered. We detect re-entry using
330 // hasActiveParser(), save the chunk as a speculation, and return.
331 if (isWaitingForScripts() || !m_speculations.isEmpty() || document()->active ParserCount() > 0) {
332 m_preloader->takeAndPreload(chunk->preloads);
333 m_speculations.append(chunk);
334 return;
335 }
336
337 // processParsedChunkFromBackgroundParser can cause this parser to be detach ed from the Document,
338 // but we need to ensure it isn't deleted yet.
339 RefPtr<HTMLDocumentParser> protect(this);
340
341 ASSERT(m_speculations.isEmpty());
342 chunk->preloads.clear(); // We don't need to preload because we're going to parse immediately.
343 m_speculations.append(chunk); 329 m_speculations.append(chunk);
abarth-chromium 2014/04/29 18:29:00 Should we rename m_speculations? I'm not sure tha
344 pumpPendingSpeculations(); 330 // If we're already paused waiting for scripts, no need to schedule a resume .
331 if (!isWaitingForScripts())
332 m_parserScheduler->scheduleForResume();
345 } 333 }
346 334
347 void HTMLDocumentParser::didReceiveEncodingDataFromBackgroundParser(const Docume ntEncodingData& data) 335 void HTMLDocumentParser::didReceiveEncodingDataFromBackgroundParser(const Docume ntEncodingData& data)
348 { 336 {
349 document()->setEncodingData(data); 337 document()->setEncodingData(data);
350 } 338 }
351 339
352 void HTMLDocumentParser::validateSpeculations(PassOwnPtr<ParsedChunk> chunk) 340 void HTMLDocumentParser::validateSpeculations(PassOwnPtr<ParsedChunk> chunk)
353 { 341 {
354 ASSERT(chunk); 342 ASSERT(chunk);
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
429 417
430 HTMLParserThread::shared()->postTask(bind(&BackgroundHTMLParser::startedChun kWithCheckpoint, m_backgroundParser, chunk->inputCheckpoint)); 418 HTMLParserThread::shared()->postTask(bind(&BackgroundHTMLParser::startedChun kWithCheckpoint, m_backgroundParser, chunk->inputCheckpoint));
431 419
432 for (XSSInfoStream::const_iterator it = chunk->xssInfos.begin(); it != chunk ->xssInfos.end(); ++it) { 420 for (XSSInfoStream::const_iterator it = chunk->xssInfos.begin(); it != chunk ->xssInfos.end(); ++it) {
433 m_textPosition = (*it)->m_textPosition; 421 m_textPosition = (*it)->m_textPosition;
434 m_xssAuditorDelegate.didBlockScript(**it); 422 m_xssAuditorDelegate.didBlockScript(**it);
435 if (isStopped()) 423 if (isStopped())
436 break; 424 break;
437 } 425 }
438 426
427 // FIXME: Currently this always consumes an entire chunk at once thus the ti me
428 // between deadline checks is controlled by BackgroundHTMLParser.cpp's pendi ngTokenLimit.
429 // We could make this code able to yield within a chunk, which would separat e the
430 // question of how much the tokenizer should batch into a chunk from how lon g
431 // the main thread should spend treebuilding before yielding.
439 for (Vector<CompactHTMLToken>::const_iterator it = tokens->begin(); it != to kens->end(); ++it) { 432 for (Vector<CompactHTMLToken>::const_iterator it = tokens->begin(); it != to kens->end(); ++it) {
440 ASSERT(!isWaitingForScripts()); 433 ASSERT(!isWaitingForScripts());
441 434
442 if (document()->frame() && document()->frame()->navigationScheduler().lo cationChangePending()) { 435 if (document()->frame() && document()->frame()->navigationScheduler().lo cationChangePending()) {
443 436
444 // To match main-thread parser behavior (which never checks location ChangePending on the EOF path) 437 // To match main-thread parser behavior (which never checks location ChangePending on the EOF path)
445 // we peek to see if this chunk has an EOF and process it anyway. 438 // we peek to see if this chunk has an EOF and process it anyway.
446 if (tokens->last().type() == HTMLToken::EndOfFile) { 439 if (tokens->last().type() == HTMLToken::EndOfFile) {
447 ASSERT(m_speculations.isEmpty()); // There should never be any c hunks after the EOF. 440 ASSERT(m_speculations.isEmpty()); // There should never be any c hunks after the EOF.
448 prepareToStopParsing(); 441 prepareToStopParsing();
(...skipping 27 matching lines...) Expand all
476 } 469 }
477 470
478 // Make sure any pending text nodes are emitted before returning. 471 // Make sure any pending text nodes are emitted before returning.
479 if (!isStopped()) 472 if (!isStopped())
480 m_treeBuilder->flush(); 473 m_treeBuilder->flush();
481 } 474 }
482 475
483 void HTMLDocumentParser::pumpPendingSpeculations() 476 void HTMLDocumentParser::pumpPendingSpeculations()
484 { 477 {
485 // FIXME: Share this constant with the parser scheduler. 478 // FIXME: Share this constant with the parser scheduler.
486 const double parserTimeLimit = 0.500; 479 // FIXME: This could be much larger during intial load where it may be OK to hog the main thread.
480 const double parserTimeLimit = 0.008;
abarth-chromium 2014/04/29 18:29:00 Again, this seems like a value the scheduler might
487 481
488 // ASSERT that this object is both attached to the Document and protected. 482 // ASSERT that this object is both attached to the Document and protected.
489 ASSERT(refCount() >= 2); 483 ASSERT(refCount() >= 2);
490 // If this assert fails, you need to call validateSpeculations to make sure 484 // If this assert fails, you need to call validateSpeculations to make sure
491 // m_tokenizer and m_token don't have state that invalidates m_speculations. 485 // m_tokenizer and m_token don't have state that invalidates m_speculations.
492 ASSERT(!m_tokenizer); 486 ASSERT(!m_tokenizer);
493 ASSERT(!m_token); 487 ASSERT(!m_token);
494 ASSERT(!m_lastChunkBeforeScript); 488 ASSERT(!m_lastChunkBeforeScript);
495 ASSERT(!isWaitingForScripts()); 489 ASSERT(!isWaitingForScripts());
496 ASSERT(!isStopped()); 490 ASSERT(!isStopped());
(...skipping 538 matching lines...) Expand 10 before | Expand all | Expand 10 after
1035 void HTMLDocumentParser::setDecoder(PassOwnPtr<TextResourceDecoder> decoder) 1029 void HTMLDocumentParser::setDecoder(PassOwnPtr<TextResourceDecoder> decoder)
1036 { 1030 {
1037 ASSERT(decoder); 1031 ASSERT(decoder);
1038 DecodedDataDocumentParser::setDecoder(decoder); 1032 DecodedDataDocumentParser::setDecoder(decoder);
1039 1033
1040 if (m_haveBackgroundParser) 1034 if (m_haveBackgroundParser)
1041 HTMLParserThread::shared()->postTask(bind(&BackgroundHTMLParser::setDeco der, m_backgroundParser, takeDecoder())); 1035 HTMLParserThread::shared()->postTask(bind(&BackgroundHTMLParser::setDeco der, m_backgroundParser, takeDecoder()));
1042 } 1036 }
1043 1037
1044 } 1038 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698