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 25 matching lines...) Expand all Loading... |
36 #include "core/html/parser/BackgroundHTMLParser.h" | 36 #include "core/html/parser/BackgroundHTMLParser.h" |
37 #include "core/html/parser/HTMLParserScheduler.h" | 37 #include "core/html/parser/HTMLParserScheduler.h" |
38 #include "core/html/parser/HTMLParserThread.h" | 38 #include "core/html/parser/HTMLParserThread.h" |
39 #include "core/html/parser/HTMLScriptRunner.h" | 39 #include "core/html/parser/HTMLScriptRunner.h" |
40 #include "core/html/parser/HTMLTreeBuilder.h" | 40 #include "core/html/parser/HTMLTreeBuilder.h" |
41 #include "core/inspector/InspectorInstrumentation.h" | 41 #include "core/inspector/InspectorInstrumentation.h" |
42 #include "core/inspector/InspectorTraceEvents.h" | 42 #include "core/inspector/InspectorTraceEvents.h" |
43 #include "core/loader/DocumentLoader.h" | 43 #include "core/loader/DocumentLoader.h" |
44 #include "platform/SharedBuffer.h" | 44 #include "platform/SharedBuffer.h" |
45 #include "platform/TraceEvent.h" | 45 #include "platform/TraceEvent.h" |
46 #include "platform/scheduler/Scheduler.h" | |
47 #include "public/platform/WebThreadedDataReceiver.h" | 46 #include "public/platform/WebThreadedDataReceiver.h" |
48 #include "wtf/Functional.h" | 47 #include "wtf/Functional.h" |
49 | 48 |
50 namespace blink { | 49 namespace blink { |
51 | 50 |
52 using namespace HTMLNames; | 51 using namespace HTMLNames; |
53 | 52 |
54 // This is a direct transcription of step 4 from: | 53 // This is a direct transcription of step 4 from: |
55 // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-end.html#frag
ment-case | 54 // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-end.html#frag
ment-case |
56 static HTMLTokenizer::State tokenizerStateForContextElement(Element* contextElem
ent, bool reportErrors, const HTMLParserOptions& options) | 55 static HTMLTokenizer::State tokenizerStateForContextElement(Element* contextElem
ent, bool reportErrors, const HTMLParserOptions& options) |
(...skipping 348 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
405 m_input.current().clear(); // FIXME: This should be passed in instead of cle
ared. | 404 m_input.current().clear(); // FIXME: This should be passed in instead of cle
ared. |
406 | 405 |
407 ASSERT(checkpoint->unparsedInput.isSafeToSendToAnotherThread()); | 406 ASSERT(checkpoint->unparsedInput.isSafeToSendToAnotherThread()); |
408 HTMLParserThread::shared()->postTask(bind(&BackgroundHTMLParser::resumeFrom,
m_backgroundParser, checkpoint.release())); | 407 HTMLParserThread::shared()->postTask(bind(&BackgroundHTMLParser::resumeFrom,
m_backgroundParser, checkpoint.release())); |
409 } | 408 } |
410 | 409 |
411 void HTMLDocumentParser::processParsedChunkFromBackgroundParser(PassOwnPtr<Parse
dChunk> popChunk) | 410 void HTMLDocumentParser::processParsedChunkFromBackgroundParser(PassOwnPtr<Parse
dChunk> popChunk) |
412 { | 411 { |
413 TRACE_EVENT0("blink", "HTMLDocumentParser::processParsedChunkFromBackgroundP
arser"); | 412 TRACE_EVENT0("blink", "HTMLDocumentParser::processParsedChunkFromBackgroundP
arser"); |
414 | 413 |
415 ASSERT_WITH_SECURITY_IMPLICATION(!document()->activeParserCount()); | 414 ASSERT_WITH_SECURITY_IMPLICATION(document()->activeParserCount() == 1); |
416 ASSERT(!isParsingFragment()); | 415 ASSERT(!isParsingFragment()); |
417 ASSERT(!isWaitingForScripts()); | 416 ASSERT(!isWaitingForScripts()); |
418 ASSERT(!isStopped()); | 417 ASSERT(!isStopped()); |
419 #if !ENABLE(OILPAN) | 418 #if !ENABLE(OILPAN) |
420 // ASSERT that this object is both attached to the Document and protected. | 419 // ASSERT that this object is both attached to the Document and protected. |
421 ASSERT(refCount() >= 2); | 420 ASSERT(refCount() >= 2); |
422 #endif | 421 #endif |
423 ASSERT(shouldUseThreading()); | 422 ASSERT(shouldUseThreading()); |
424 ASSERT(!m_tokenizer); | 423 ASSERT(!m_tokenizer); |
425 ASSERT(!m_token); | 424 ASSERT(!m_token); |
426 ASSERT(!m_lastChunkBeforeScript); | 425 ASSERT(!m_lastChunkBeforeScript); |
427 | 426 |
428 ActiveParserSession session(contextForParsingSession()); | |
429 | |
430 OwnPtr<ParsedChunk> chunk(popChunk); | 427 OwnPtr<ParsedChunk> chunk(popChunk); |
431 OwnPtr<CompactHTMLTokenStream> tokens = chunk->tokens.release(); | 428 OwnPtr<CompactHTMLTokenStream> tokens = chunk->tokens.release(); |
432 | 429 |
433 HTMLParserThread::shared()->postTask(bind(&BackgroundHTMLParser::startedChun
kWithCheckpoint, m_backgroundParser, chunk->inputCheckpoint)); | 430 HTMLParserThread::shared()->postTask(bind(&BackgroundHTMLParser::startedChun
kWithCheckpoint, m_backgroundParser, chunk->inputCheckpoint)); |
434 | 431 |
435 for (XSSInfoStream::const_iterator it = chunk->xssInfos.begin(); it != chunk
->xssInfos.end(); ++it) { | 432 for (XSSInfoStream::const_iterator it = chunk->xssInfos.begin(); it != chunk
->xssInfos.end(); ++it) { |
436 m_textPosition = (*it)->m_textPosition; | 433 m_textPosition = (*it)->m_textPosition; |
437 m_xssAuditorDelegate.didBlockScript(**it); | 434 m_xssAuditorDelegate.didBlockScript(**it); |
438 if (isStopped()) | 435 if (isStopped()) |
439 break; | 436 break; |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
479 } | 476 } |
480 | 477 |
481 // Make sure all required pending text nodes are emitted before returning. | 478 // Make sure all required pending text nodes are emitted before returning. |
482 // This leaves "script", "style" and "svg" nodes text nodes intact. | 479 // This leaves "script", "style" and "svg" nodes text nodes intact. |
483 if (!isStopped()) | 480 if (!isStopped()) |
484 m_treeBuilder->flush(FlushIfAtTextLimit); | 481 m_treeBuilder->flush(FlushIfAtTextLimit); |
485 } | 482 } |
486 | 483 |
487 void HTMLDocumentParser::pumpPendingSpeculations() | 484 void HTMLDocumentParser::pumpPendingSpeculations() |
488 { | 485 { |
489 // FIXME: Share this constant with the parser scheduler. | |
490 const double parserTimeLimit = 0.500; | |
491 | |
492 #if !ENABLE(OILPAN) | 486 #if !ENABLE(OILPAN) |
493 // ASSERT that this object is both attached to the Document and protected. | 487 // ASSERT that this object is both attached to the Document and protected. |
494 ASSERT(refCount() >= 2); | 488 ASSERT(refCount() >= 2); |
495 #endif | 489 #endif |
496 // If this assert fails, you need to call validateSpeculations to make sure | 490 // If this assert fails, you need to call validateSpeculations to make sure |
497 // m_tokenizer and m_token don't have state that invalidates m_speculations. | 491 // m_tokenizer and m_token don't have state that invalidates m_speculations. |
498 ASSERT(!m_tokenizer); | 492 ASSERT(!m_tokenizer); |
499 ASSERT(!m_token); | 493 ASSERT(!m_token); |
500 ASSERT(!m_lastChunkBeforeScript); | 494 ASSERT(!m_lastChunkBeforeScript); |
501 ASSERT(!isWaitingForScripts()); | 495 ASSERT(!isWaitingForScripts()); |
502 ASSERT(!isStopped()); | 496 ASSERT(!isStopped()); |
503 | 497 |
504 // FIXME: Pass in current input length. | 498 // FIXME: Pass in current input length. |
505 TRACE_EVENT_BEGIN1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "ParseHTM
L", "beginData", InspectorParseHtmlEvent::beginData(document(), lineNumber().zer
oBasedInt())); | 499 TRACE_EVENT_BEGIN1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "ParseHTM
L", "beginData", InspectorParseHtmlEvent::beginData(document(), lineNumber().zer
oBasedInt())); |
506 TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline.stack"), "
CallStack", "stack", InspectorCallStackEvent::currentCallStack()); | 500 TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline.stack"), "
CallStack", "stack", InspectorCallStackEvent::currentCallStack()); |
507 // FIXME(361045): remove InspectorInstrumentation calls once DevTools Timeli
ne migrates to tracing. | 501 // FIXME(361045): remove InspectorInstrumentation calls once DevTools Timeli
ne migrates to tracing. |
508 InspectorInstrumentationCookie cookie = InspectorInstrumentation::willWriteH
TML(document(), lineNumber().zeroBasedInt()); | 502 InspectorInstrumentationCookie cookie = InspectorInstrumentation::willWriteH
TML(document(), lineNumber().zeroBasedInt()); |
509 | 503 |
510 double startTime = currentTime(); | 504 SpeculationsPumpSession session(contextForParsingSession()); |
511 | |
512 while (!m_speculations.isEmpty()) { | 505 while (!m_speculations.isEmpty()) { |
513 processParsedChunkFromBackgroundParser(m_speculations.takeFirst()); | 506 processParsedChunkFromBackgroundParser(m_speculations.takeFirst()); |
514 | 507 |
515 // Always check isStopped first as m_document may be null. | 508 // Always check isStopped first as m_document may be null. |
516 if (isStopped() || isWaitingForScripts()) | 509 if (isStopped() || isWaitingForScripts()) |
517 break; | 510 break; |
518 | 511 |
519 if ((Scheduler::shared()->shouldYieldForHighPriorityWork() || currentTim
e() - startTime > parserTimeLimit) && !m_speculations.isEmpty()) { | 512 if (m_speculations.isEmpty() || m_parserScheduler->yieldIfNeeded(session
)) |
520 m_parserScheduler->scheduleForResume(); | |
521 break; | 513 break; |
522 } | |
523 } | 514 } |
524 | 515 |
525 TRACE_EVENT_END1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "ParseHTML"
, "endLine", lineNumber().zeroBasedInt()); | 516 TRACE_EVENT_END1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "ParseHTML"
, "endLine", lineNumber().zeroBasedInt()); |
526 // FIXME(361045): remove InspectorInstrumentation calls once DevTools Timeli
ne migrates to tracing. | 517 // FIXME(361045): remove InspectorInstrumentation calls once DevTools Timeli
ne migrates to tracing. |
527 InspectorInstrumentation::didWriteHTML(cookie, lineNumber().zeroBasedInt()); | 518 InspectorInstrumentation::didWriteHTML(cookie, lineNumber().zeroBasedInt()); |
528 TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "Update
Counters", "data", InspectorUpdateCountersEvent::data()); | 519 TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "Update
Counters", "data", InspectorUpdateCountersEvent::data()); |
529 } | 520 } |
530 | 521 |
531 void HTMLDocumentParser::forcePlaintextForTextDocument() | 522 void HTMLDocumentParser::forcePlaintextForTextDocument() |
532 { | 523 { |
(...skipping 514 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1047 void HTMLDocumentParser::setDecoder(PassOwnPtr<TextResourceDecoder> decoder) | 1038 void HTMLDocumentParser::setDecoder(PassOwnPtr<TextResourceDecoder> decoder) |
1048 { | 1039 { |
1049 ASSERT(decoder); | 1040 ASSERT(decoder); |
1050 DecodedDataDocumentParser::setDecoder(decoder); | 1041 DecodedDataDocumentParser::setDecoder(decoder); |
1051 | 1042 |
1052 if (m_haveBackgroundParser) | 1043 if (m_haveBackgroundParser) |
1053 HTMLParserThread::shared()->postTask(bind(&BackgroundHTMLParser::setDeco
der, m_backgroundParser, takeDecoder())); | 1044 HTMLParserThread::shared()->postTask(bind(&BackgroundHTMLParser::setDeco
der, m_backgroundParser, takeDecoder())); |
1054 } | 1045 } |
1055 | 1046 |
1056 } | 1047 } |
OLD | NEW |