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

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

Issue 625583002: Properly suspend HTMLDocumentParser (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Fixed wrong method called Created 6 years, 2 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 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
109 , m_tokenizer(m_options.useThreading ? nullptr : HTMLTokenizer::create(m_opt ions)) 109 , m_tokenizer(m_options.useThreading ? nullptr : HTMLTokenizer::create(m_opt ions))
110 , m_scriptRunner(HTMLScriptRunner::create(&document, this)) 110 , m_scriptRunner(HTMLScriptRunner::create(&document, this))
111 , m_treeBuilder(HTMLTreeBuilder::create(this, &document, parserContentPolicy (), reportErrors, m_options)) 111 , m_treeBuilder(HTMLTreeBuilder::create(this, &document, parserContentPolicy (), reportErrors, m_options))
112 , m_parserScheduler(HTMLParserScheduler::create(this)) 112 , m_parserScheduler(HTMLParserScheduler::create(this))
113 , m_xssAuditorDelegate(&document) 113 , m_xssAuditorDelegate(&document)
114 , m_weakFactory(this) 114 , m_weakFactory(this)
115 , m_preloader(HTMLResourcePreloader::create(document)) 115 , m_preloader(HTMLResourcePreloader::create(document))
116 , m_isPinnedToMainThread(false) 116 , m_isPinnedToMainThread(false)
117 , m_endWasDelayed(false) 117 , m_endWasDelayed(false)
118 , m_haveBackgroundParser(false) 118 , m_haveBackgroundParser(false)
119 , m_tasksWereSuspended(false)
119 , m_pumpSessionNestingLevel(0) 120 , m_pumpSessionNestingLevel(0)
120 { 121 {
121 ASSERT(shouldUseThreading() || (m_token && m_tokenizer)); 122 ASSERT(shouldUseThreading() || (m_token && m_tokenizer));
122 } 123 }
123 124
124 // FIXME: Member variables should be grouped into self-initializing structs to 125 // FIXME: Member variables should be grouped into self-initializing structs to
125 // minimize code duplication between these constructors. 126 // minimize code duplication between these constructors.
126 HTMLDocumentParser::HTMLDocumentParser(DocumentFragment* fragment, Element* cont extElement, ParserContentPolicy parserContentPolicy) 127 HTMLDocumentParser::HTMLDocumentParser(DocumentFragment* fragment, Element* cont extElement, ParserContentPolicy parserContentPolicy)
127 : ScriptableDocumentParser(fragment->document(), parserContentPolicy) 128 : ScriptableDocumentParser(fragment->document(), parserContentPolicy)
128 , m_options(&fragment->document()) 129 , m_options(&fragment->document())
129 , m_token(adoptPtr(new HTMLToken)) 130 , m_token(adoptPtr(new HTMLToken))
130 , m_tokenizer(HTMLTokenizer::create(m_options)) 131 , m_tokenizer(HTMLTokenizer::create(m_options))
131 , m_treeBuilder(HTMLTreeBuilder::create(this, fragment, contextElement, this ->parserContentPolicy(), m_options)) 132 , m_treeBuilder(HTMLTreeBuilder::create(this, fragment, contextElement, this ->parserContentPolicy(), m_options))
132 , m_xssAuditorDelegate(&fragment->document()) 133 , m_xssAuditorDelegate(&fragment->document())
133 , m_weakFactory(this) 134 , m_weakFactory(this)
134 , m_isPinnedToMainThread(true) 135 , m_isPinnedToMainThread(true)
135 , m_endWasDelayed(false) 136 , m_endWasDelayed(false)
136 , m_haveBackgroundParser(false) 137 , m_haveBackgroundParser(false)
138 , m_tasksWereSuspended(false)
137 , m_pumpSessionNestingLevel(0) 139 , m_pumpSessionNestingLevel(0)
138 { 140 {
139 ASSERT(!shouldUseThreading()); 141 ASSERT(!shouldUseThreading());
140 bool reportErrors = false; // For now document fragment parsing never report s errors. 142 bool reportErrors = false; // For now document fragment parsing never report s errors.
141 m_tokenizer->setState(tokenizerStateForContextElement(contextElement, report Errors, m_options)); 143 m_tokenizer->setState(tokenizerStateForContextElement(contextElement, report Errors, m_options));
142 m_xssAuditor.initForFragment(); 144 m_xssAuditor.initForFragment();
143 } 145 }
144 146
145 HTMLDocumentParser::~HTMLDocumentParser() 147 HTMLDocumentParser::~HTMLDocumentParser()
146 { 148 {
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
274 } 276 }
275 277
276 // Used by HTMLParserScheduler 278 // Used by HTMLParserScheduler
277 void HTMLDocumentParser::resumeParsingAfterYield() 279 void HTMLDocumentParser::resumeParsingAfterYield()
278 { 280 {
279 ASSERT(!m_isPinnedToMainThread); 281 ASSERT(!m_isPinnedToMainThread);
280 // pumpTokenizer can cause this parser to be detached from the Document, 282 // pumpTokenizer can cause this parser to be detached from the Document,
281 // but we need to ensure it isn't deleted yet. 283 // but we need to ensure it isn't deleted yet.
282 RefPtrWillBeRawPtr<HTMLDocumentParser> protect(this); 284 RefPtrWillBeRawPtr<HTMLDocumentParser> protect(this);
283 285
284 if (m_haveBackgroundParser) { 286 if (m_haveBackgroundParser || !m_speculations.isEmpty()) {
João Eiras 2014/10/06 12:14:30 I'm a bit unsure about how these two variables rel
eseidel 2014/10/06 18:07:08 Speculations are parsed chunks sent to us from the
João Eiras 2014/10/07 13:25:07 OK, line reverted.
285 pumpPendingSpeculations(); 287 pumpPendingSpeculations();
286 return; 288 return;
287 } 289 }
288 290
289 // We should never be here unless we can pump immediately. Call pumpTokeniz er() 291 // We should never be here unless we can pump immediately. Call pumpTokeniz er()
290 // directly so that ASSERTS will fire if we're wrong. 292 // directly so that ASSERTS will fire if we're wrong.
291 pumpTokenizer(AllowYield); 293 if (m_tokenizer)
João Eiras 2014/10/06 12:14:31 As consequence of forcing a call to this method wh
eseidel 2014/10/06 18:07:08 This seems wrong. We should just be more careful
João Eiras 2014/10/07 13:25:07 Ok, added a couple extra checks in HTMLDocumentPar
294 pumpTokenizer(AllowYield);
292 endIfDelayed(); 295 endIfDelayed();
293 } 296 }
294 297
295 void HTMLDocumentParser::runScriptsForPausedTreeBuilder() 298 void HTMLDocumentParser::runScriptsForPausedTreeBuilder()
296 { 299 {
297 ASSERT(scriptingContentIsAllowed(parserContentPolicy())); 300 ASSERT(scriptingContentIsAllowed(parserContentPolicy()));
298 301
299 TextPosition scriptStartPosition = TextPosition::belowRangePosition(); 302 TextPosition scriptStartPosition = TextPosition::belowRangePosition();
300 RefPtrWillBeRawPtr<Element> scriptElement = m_treeBuilder->takeScriptToProce ss(scriptStartPosition); 303 RefPtrWillBeRawPtr<Element> scriptElement = m_treeBuilder->takeScriptToProce ss(scriptStartPosition);
301 // We will not have a scriptRunner when parsing a DocumentFragment. 304 // We will not have a scriptRunner when parsing a DocumentFragment.
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
342 return true; 345 return true;
343 } 346 }
344 347
345 void HTMLDocumentParser::didReceiveParsedChunkFromBackgroundParser(PassOwnPtr<Pa rsedChunk> chunk) 348 void HTMLDocumentParser::didReceiveParsedChunkFromBackgroundParser(PassOwnPtr<Pa rsedChunk> chunk)
346 { 349 {
347 TRACE_EVENT0("blink", "HTMLDocumentParser::didReceiveParsedChunkFromBackgrou ndParser"); 350 TRACE_EVENT0("blink", "HTMLDocumentParser::didReceiveParsedChunkFromBackgrou ndParser");
348 351
349 // alert(), runModalDialog, and the JavaScript Debugger all run nested event loops 352 // alert(), runModalDialog, and the JavaScript Debugger all run nested event loops
350 // which can cause this method to be re-entered. We detect re-entry using 353 // which can cause this method to be re-entered. We detect re-entry using
351 // hasActiveParser(), save the chunk as a speculation, and return. 354 // hasActiveParser(), save the chunk as a speculation, and return.
352 if (isWaitingForScripts() || !m_speculations.isEmpty() || document()->active ParserCount() > 0) { 355 if (isWaitingForScripts() || !m_speculations.isEmpty() || document()->active ParserCount() > 0 || m_tasksWereSuspended) {
353 m_preloader->takeAndPreload(chunk->preloads); 356 m_preloader->takeAndPreload(chunk->preloads);
354 m_speculations.append(chunk); 357 m_speculations.append(chunk);
355 return; 358 return;
356 } 359 }
357 360
358 // processParsedChunkFromBackgroundParser can cause this parser to be detach ed from the Document, 361 // processParsedChunkFromBackgroundParser can cause this parser to be detach ed from the Document,
359 // but we need to ensure it isn't deleted yet. 362 // but we need to ensure it isn't deleted yet.
360 RefPtrWillBeRawPtr<HTMLDocumentParser> protect(this); 363 RefPtrWillBeRawPtr<HTMLDocumentParser> protect(this);
361 364
362 ASSERT(m_speculations.isEmpty()); 365 ASSERT(m_speculations.isEmpty());
(...skipping 659 matching lines...) Expand 10 before | Expand all | Expand 10 after
1022 { 1025 {
1023 RefPtrWillBeRawPtr<HTMLDocumentParser> parser = HTMLDocumentParser::create(f ragment, contextElement, parserContentPolicy); 1026 RefPtrWillBeRawPtr<HTMLDocumentParser> parser = HTMLDocumentParser::create(f ragment, contextElement, parserContentPolicy);
1024 parser->insert(source); // Use insert() so that the parser will not yield. 1027 parser->insert(source); // Use insert() so that the parser will not yield.
1025 parser->finish(); 1028 parser->finish();
1026 ASSERT(!parser->processingData()); // Make sure we're done. <rdar://problem/ 3963151> 1029 ASSERT(!parser->processingData()); // Make sure we're done. <rdar://problem/ 3963151>
1027 parser->detach(); // Allows ~DocumentParser to assert it was detached before destruction. 1030 parser->detach(); // Allows ~DocumentParser to assert it was detached before destruction.
1028 } 1031 }
1029 1032
1030 void HTMLDocumentParser::suspendScheduledTasks() 1033 void HTMLDocumentParser::suspendScheduledTasks()
1031 { 1034 {
1035 ASSERT(!m_tasksWereSuspended);
1036 m_tasksWereSuspended = true;
1032 if (m_parserScheduler) 1037 if (m_parserScheduler)
1033 m_parserScheduler->suspend(); 1038 m_parserScheduler->suspend();
1034 } 1039 }
1035 1040
1036 void HTMLDocumentParser::resumeScheduledTasks() 1041 void HTMLDocumentParser::resumeScheduledTasks()
1037 { 1042 {
1043 ASSERT(m_tasksWereSuspended);
1044 m_tasksWereSuspended = false;
1038 if (m_parserScheduler) 1045 if (m_parserScheduler)
1039 m_parserScheduler->resume(); 1046 m_parserScheduler->scheduleForResume();
1040 } 1047 }
1041 1048
1042 void HTMLDocumentParser::appendBytes(const char* data, size_t length) 1049 void HTMLDocumentParser::appendBytes(const char* data, size_t length)
1043 { 1050 {
1044 if (!length || isStopped()) 1051 if (!length || isStopped())
1045 return; 1052 return;
1046 1053
1047 if (shouldUseThreading()) { 1054 if (shouldUseThreading()) {
1048 if (!m_haveBackgroundParser) 1055 if (!m_haveBackgroundParser)
1049 startBackgroundParser(); 1056 startBackgroundParser();
(...skipping 24 matching lines...) Expand all
1074 void HTMLDocumentParser::setDecoder(PassOwnPtr<TextResourceDecoder> decoder) 1081 void HTMLDocumentParser::setDecoder(PassOwnPtr<TextResourceDecoder> decoder)
1075 { 1082 {
1076 ASSERT(decoder); 1083 ASSERT(decoder);
1077 DecodedDataDocumentParser::setDecoder(decoder); 1084 DecodedDataDocumentParser::setDecoder(decoder);
1078 1085
1079 if (m_haveBackgroundParser) 1086 if (m_haveBackgroundParser)
1080 HTMLParserThread::shared()->postTask(bind(&BackgroundHTMLParser::setDeco der, m_backgroundParser, takeDecoder())); 1087 HTMLParserThread::shared()->postTask(bind(&BackgroundHTMLParser::setDeco der, m_backgroundParser, takeDecoder()));
1081 } 1088 }
1082 1089
1083 } 1090 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698