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 |