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

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

Issue 100563004: Redirect HTML resource bytes directly to parser thread (Blink side CL) (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@parserthread_decodermove
Patch Set: Cache parser thread pointer in HTMLDocumentParser Created 6 years, 10 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) 2013 Google, Inc. All Rights Reserved. 2 * Copyright (C) 2013 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
11 * documentation and/or other materials provided with the distribution. 11 * documentation and/or other materials provided with the distribution.
12 * 12 *
13 * THIS SOFTWARE IS PROVIDED BY GOOGLE INC. ``AS IS'' AND ANY 13 * THIS SOFTWARE IS PROVIDED BY GOOGLE INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GOOGLE INC. OR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GOOGLE INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */ 24 */
25 25
26 #include "config.h" 26 #include "config.h"
27 #include "core/html/parser/BackgroundHTMLParser.h" 27 #include "core/html/parser/BackgroundHTMLParser.h"
28 28
29 #include "core/html/parser/HTMLDocumentParser.h" 29 #include "core/html/parser/HTMLDocumentParser.h"
30 #include "core/html/parser/HTMLParserThread.h"
31 #include "core/html/parser/TextResourceDecoder.h" 30 #include "core/html/parser/TextResourceDecoder.h"
32 #include "core/html/parser/XSSAuditor.h" 31 #include "core/html/parser/XSSAuditor.h"
33 #include "wtf/MainThread.h" 32 #include "wtf/MainThread.h"
34 #include "wtf/text/TextPosition.h" 33 #include "wtf/text/TextPosition.h"
35 34
36 namespace WebCore { 35 namespace WebCore {
37 36
38 // On a network with high latency and high bandwidth, using a device 37 // On a network with high latency and high bandwidth, using a device
39 // with a fast CPU, we could end up speculatively tokenizing 38 // with a fast CPU, we could end up speculatively tokenizing
40 // the whole document, well ahead of when the main-thread actually needs it. 39 // the whole document, well ahead of when the main-thread actually needs it.
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
87 : m_weakFactory(reference, this) 86 : m_weakFactory(reference, this)
88 , m_token(adoptPtr(new HTMLToken)) 87 , m_token(adoptPtr(new HTMLToken))
89 , m_tokenizer(HTMLTokenizer::create(config->options)) 88 , m_tokenizer(HTMLTokenizer::create(config->options))
90 , m_treeBuilderSimulator(config->options) 89 , m_treeBuilderSimulator(config->options)
91 , m_options(config->options) 90 , m_options(config->options)
92 , m_parser(config->parser) 91 , m_parser(config->parser)
93 , m_pendingTokens(adoptPtr(new CompactHTMLTokenStream)) 92 , m_pendingTokens(adoptPtr(new CompactHTMLTokenStream))
94 , m_xssAuditor(config->xssAuditor.release()) 93 , m_xssAuditor(config->xssAuditor.release())
95 , m_preloadScanner(config->preloadScanner.release()) 94 , m_preloadScanner(config->preloadScanner.release())
96 , m_decoder(config->decoder.release()) 95 , m_decoder(config->decoder.release())
96 , m_resourceProvider(config->resourceProvider.release())
97 , m_receivingDataOnlyFromResourceProvider(false)
97 { 98 {
99 // Tell the resource provider that we're ready to start receiving
100 // chunks of data directly from the parser thread.
101 if (m_resourceProvider)
102 m_resourceProvider->setBackgroundClient(this);
98 } 103 }
99 104
100 BackgroundHTMLParser::~BackgroundHTMLParser() 105 BackgroundHTMLParser::~BackgroundHTMLParser()
101 { 106 {
107 if (m_resourceProvider) {
108 // Tell the resource provider that calling into this instance
109 // is no longer safe and any further data received should be
110 // ignored.
111 m_resourceProvider->setBackgroundClient(0);
112 // The resource provider needs to be destructed on the main thread,
113 // as the filter it installs on the I/O thread can only be removed
abarth-chromium 2014/02/03 21:17:36 Blink doesn't know anything about I/O threads.
oystein (OOO til 10th of July) 2014/02/05 00:05:00 Removed that part of the comment; it was just a cl
114 // from the main thread...
115 // Note we can only call static functions on the HTMLDocumentParser at t his point
116 // as the weakptr we have for it is likely invalidated now.
117 callOnMainThread(bind(&HTMLDocumentParser::destroyResourceProvider, m_re sourceProvider.release()));
118 }
119 }
120
121 void BackgroundHTMLParser::didReceivedData(const char* data, size_t length)
122 {
123 if (m_receivingDataOnlyFromResourceProvider && m_decoder) {
124 updateDocument(m_decoder->decode(data, length));
125 return;
126 }
127
128 // If the parser thread is not standalone yet, it means we may get
129 // further data packets from the main thread and will need to queue
130 // up any data coming directly from the parser thread until we're
131 // sure we're complete. This is also necessary if we've lost our
132 // decoder, until we get a new one passed from the main thread.
133
134 OwnPtr<Vector<char> > buffer = adoptPtr(new Vector<char>(length));
135 memcpy(buffer->data(), data, length);
abarth-chromium 2014/02/03 21:17:36 buffer.append(data, length)
oystein (OOO til 10th of July) 2014/02/05 00:05:00 Done.
136 m_queuedData.append(buffer.release());
102 } 137 }
103 138
104 void BackgroundHTMLParser::append(const String& input) 139 void BackgroundHTMLParser::append(const String& input)
105 { 140 {
106 ASSERT(!m_input.current().isClosed()); 141 ASSERT(!m_input.current().isClosed());
107 m_input.append(input); 142 m_input.append(input);
108 pumpTokenizer(); 143 pumpTokenizer();
109 } 144 }
110 145
111 void BackgroundHTMLParser::appendBytes(PassOwnPtr<Vector<char> > buffer) 146 void BackgroundHTMLParser::appendBytes(PassOwnPtr<Vector<char> > buffer)
112 { 147 {
148 ASSERT(!m_receivingDataOnlyFromResourceProvider);
113 updateDocument(m_decoder->decode(buffer->data(), buffer->size())); 149 updateDocument(m_decoder->decode(buffer->data(), buffer->size()));
114 } 150 }
115 151
116 void BackgroundHTMLParser::setDecoder(PassOwnPtr<TextResourceDecoder> decoder) 152 void BackgroundHTMLParser::setDecoder(PassOwnPtr<TextResourceDecoder> decoder)
117 { 153 {
118 m_decoder = decoder; 154 m_decoder = decoder;
155
156 // If our decoder got reset in mid-stream and got recreated, we may have
157 // some pending data here.
158 if (m_decoder)
159 flushQueuedData();
119 } 160 }
120 161
121 void BackgroundHTMLParser::flush() 162 void BackgroundHTMLParser::flush()
122 { 163 {
123 updateDocument(m_decoder->flush()); 164 updateDocument(m_decoder->flush());
124 } 165 }
125 166
126 void BackgroundHTMLParser::updateDocument(const String& decodedData) 167 void BackgroundHTMLParser::updateDocument(const String& decodedData)
127 { 168 {
128 DocumentEncodingData encodingData(*m_decoder.get()); 169 DocumentEncodingData encodingData(*m_decoder.get());
129 170
130 if (encodingData != m_lastSeenEncodingData) { 171 if (encodingData != m_lastSeenEncodingData) {
131 m_lastSeenEncodingData = encodingData; 172 m_lastSeenEncodingData = encodingData;
132
133 m_xssAuditor->setEncoding(encodingData.encoding()); 173 m_xssAuditor->setEncoding(encodingData.encoding());
134 callOnMainThread(bind(&HTMLDocumentParser::didReceiveEncodingDataFromBac kgroundParser, m_parser, encodingData)); 174 callOnMainThread(bind(&HTMLDocumentParser::didReceiveEncodingDataFromBac kgroundParser, m_parser, encodingData));
135 } 175 }
136 176
137 if (decodedData.isEmpty()) 177 if (decodedData.isEmpty())
138 return; 178 return;
139 179
140 append(decodedData); 180 append(decodedData);
141 } 181 }
142 182
(...skipping 20 matching lines...) Expand all
163 { 203 {
164 markEndOfFile(); 204 markEndOfFile();
165 pumpTokenizer(); 205 pumpTokenizer();
166 } 206 }
167 207
168 void BackgroundHTMLParser::stop() 208 void BackgroundHTMLParser::stop()
169 { 209 {
170 delete this; 210 delete this;
171 } 211 }
172 212
213 void BackgroundHTMLParser::flushQueuedData()
214 {
215 // We only process queued chunks if we have a decoder and if we know
216 // we won't be receiving any more chunks for the main thread. Otherwise
217 // we hang on to the chunks for a bit longer.
218 if (!m_decoder || !m_receivingDataOnlyFromResourceProvider)
219 return;
220
221 for (Vector<OwnPtr<Vector<char> > >::iterator entry = m_queuedData.begin(); entry != m_queuedData.end(); ++entry)
222 updateDocument(m_decoder->decode((*entry)->data(), (*entry)->size()));
abarth-chromium 2014/02/03 21:17:36 SharedBuffer has a better way of doing this sort o
oystein (OOO til 10th of July) 2014/02/05 00:05:00 Done.
223
224 m_queuedData.clear();
225 }
226
227 void BackgroundHTMLParser::resourceFilterAdded()
228 {
229 m_receivingDataOnlyFromResourceProvider = true;
230
231 // At this point we know for sure that no further data will
232 // be coming from the main thread, so we can process anything
233 // we've received directly on the parser thread in the meantime.
234 flushQueuedData();
235 }
236
173 void BackgroundHTMLParser::forcePlaintextForTextDocument() 237 void BackgroundHTMLParser::forcePlaintextForTextDocument()
174 { 238 {
175 // This is only used by the TextDocumentParser (a subclass of HTMLDocumentPa rser) 239 // This is only used by the TextDocumentParser (a subclass of HTMLDocumentPa rser)
176 // to force us into the PLAINTEXT state w/o using a <plaintext> tag. 240 // to force us into the PLAINTEXT state w/o using a <plaintext> tag.
177 // The TextDocumentParser uses a <pre> tag for historical/compatibility reas ons. 241 // The TextDocumentParser uses a <pre> tag for historical/compatibility reas ons.
178 m_tokenizer->setState(HTMLTokenizer::PLAINTEXTState); 242 m_tokenizer->setState(HTMLTokenizer::PLAINTEXTState);
179 } 243 }
180 244
181 void BackgroundHTMLParser::markEndOfFile() 245 void BackgroundHTMLParser::markEndOfFile()
182 { 246 {
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
244 chunk->treeBuilderState = m_treeBuilderSimulator.state(); 308 chunk->treeBuilderState = m_treeBuilderSimulator.state();
245 chunk->inputCheckpoint = m_input.createCheckpoint(m_pendingTokens->size()); 309 chunk->inputCheckpoint = m_input.createCheckpoint(m_pendingTokens->size());
246 chunk->preloadScannerCheckpoint = m_preloadScanner->createCheckpoint(); 310 chunk->preloadScannerCheckpoint = m_preloadScanner->createCheckpoint();
247 chunk->tokens = m_pendingTokens.release(); 311 chunk->tokens = m_pendingTokens.release();
248 callOnMainThread(bind(&HTMLDocumentParser::didReceiveParsedChunkFromBackgrou ndParser, m_parser, chunk.release())); 312 callOnMainThread(bind(&HTMLDocumentParser::didReceiveParsedChunkFromBackgrou ndParser, m_parser, chunk.release()));
249 313
250 m_pendingTokens = adoptPtr(new CompactHTMLTokenStream); 314 m_pendingTokens = adoptPtr(new CompactHTMLTokenStream);
251 } 315 }
252 316
253 } 317 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698