Chromium Code Reviews| 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 307 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 } |
| OLD | NEW |