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

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

Issue 2683653004: Put the BackgroundHTMLParser on oilpan heap (Closed)
Patch Set: remove <memory> Created 3 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 "core/html/parser/BackgroundHTMLParser.h" 26 #include "core/html/parser/BackgroundHTMLParser.h"
27 27
28 #include "core/HTMLNames.h" 28 #include "core/HTMLNames.h"
29 #include "core/dom/Document.h"
30 #include "core/dom/TaskRunnerHelper.h"
29 #include "core/html/parser/HTMLDocumentParser.h" 31 #include "core/html/parser/HTMLDocumentParser.h"
30 #include "core/html/parser/TextResourceDecoder.h" 32 #include "core/html/parser/TextResourceDecoder.h"
33 #include "core/html/parser/TokenizedChunkQueue.h"
31 #include "core/html/parser/XSSAuditor.h" 34 #include "core/html/parser/XSSAuditor.h"
32 #include "platform/CrossThreadFunctional.h" 35 #include "platform/CrossThreadFunctional.h"
33 #include "platform/Histogram.h" 36 #include "platform/Histogram.h"
34 #include "platform/WebTaskRunner.h" 37 #include "platform/WebTaskRunner.h"
35 #include "platform/instrumentation/tracing/TraceEvent.h" 38 #include "platform/instrumentation/tracing/TraceEvent.h"
36 #include "public/platform/Platform.h" 39 #include "public/platform/Platform.h"
37 #include "wtf/CurrentTime.h" 40 #include "wtf/CurrentTime.h"
38 #include "wtf/Functional.h" 41 #include "wtf/Functional.h"
39 #include "wtf/PtrUtil.h" 42 #include "wtf/PtrUtil.h"
40 #include "wtf/text/TextPosition.h" 43 #include "wtf/text/TextPosition.h"
41 #include <memory>
42 44
43 namespace blink { 45 namespace blink {
44 46
45 // On a network with high latency and high bandwidth, using a device with a fast 47 // On a network with high latency and high bandwidth, using a device with a fast
46 // CPU, we could end up speculatively tokenizing the whole document, well ahead 48 // CPU, we could end up speculatively tokenizing the whole document, well ahead
47 // of when the main-thread actually needs it. This is a waste of memory (and 49 // of when the main-thread actually needs it. This is a waste of memory (and
48 // potentially time if the speculation fails). So we limit our outstanding 50 // potentially time if the speculation fails). So we limit our outstanding
49 // tokens arbitrarily to 10,000. Our maximal memory spent speculating will be 51 // tokens arbitrarily to 10,000. Our maximal memory spent speculating will be
50 // approximately: 52 // approximately:
51 // (defaultOutstandingTokenLimit + defaultPendingTokenLimit) * 53 // (defaultOutstandingTokenLimit + defaultPendingTokenLimit) *
(...skipping 27 matching lines...) Expand all
79 } 81 }
80 82
81 static void checkThatXSSInfosAreSafeToSendToAnotherThread( 83 static void checkThatXSSInfosAreSafeToSendToAnotherThread(
82 const XSSInfoStream& infos) { 84 const XSSInfoStream& infos) {
83 for (size_t i = 0; i < infos.size(); ++i) 85 for (size_t i = 0; i < infos.size(); ++i)
84 ASSERT(infos[i]->isSafeToSendToAnotherThread()); 86 ASSERT(infos[i]->isSafeToSendToAnotherThread());
85 } 87 }
86 88
87 #endif 89 #endif
88 90
89 WeakPtr<BackgroundHTMLParser> BackgroundHTMLParser::create( 91 BackgroundHTMLParser* BackgroundHTMLParser::create(
90 std::unique_ptr<Configuration> config, 92 HTMLDocumentParser* parser,
91 RefPtr<WebTaskRunner> loadingTaskRunner) { 93 Document& document,
92 auto* backgroundParser = 94 std::unique_ptr<Configuration> config) {
93 new BackgroundHTMLParser(std::move(config), std::move(loadingTaskRunner)); 95 return new BackgroundHTMLParser(
94 return backgroundParser->m_weakFactory.createWeakPtr(); 96 parser, std::move(config),
97 TaskRunnerHelper::get(TaskType::Networking, &document),
98 WTF::makeUnique<TokenPreloadScanner>(
99 document.url(), CachedDocumentParameters::create(&document),
100 MediaValuesCached::MediaValuesCachedData(document)));
95 } 101 }
96 102
97 void BackgroundHTMLParser::init( 103 DEFINE_TRACE(BackgroundHTMLParser) {
98 const KURL& documentURL, 104 visitor->trace(m_parser);
99 std::unique_ptr<CachedDocumentParameters> cachedDocumentParameters,
100 const MediaValuesCached::MediaValuesCachedData& mediaValuesCachedData) {
101 m_preloadScanner.reset(new TokenPreloadScanner(
102 documentURL, std::move(cachedDocumentParameters), mediaValuesCachedData));
103 } 105 }
104 106
105 BackgroundHTMLParser::Configuration::Configuration() 107 BackgroundHTMLParser::Configuration::Configuration()
106 : outstandingTokenLimit(defaultOutstandingTokenLimit), 108 : outstandingTokenLimit(defaultOutstandingTokenLimit),
107 pendingTokenLimit(defaultPendingTokenLimit), 109 pendingTokenLimit(defaultPendingTokenLimit),
108 shouldCoalesceChunks(false) {} 110 shouldCoalesceChunks(false) {}
109 111
110 BackgroundHTMLParser::BackgroundHTMLParser( 112 BackgroundHTMLParser::BackgroundHTMLParser(
113 HTMLDocumentParser* parser,
111 std::unique_ptr<Configuration> config, 114 std::unique_ptr<Configuration> config,
112 RefPtr<WebTaskRunner> loadingTaskRunner) 115 RefPtr<WebTaskRunner> loadingTaskRunner,
113 : m_weakFactory(this), 116 std::unique_ptr<TokenPreloadScanner> scanner)
114 m_token(WTF::wrapUnique(new HTMLToken)), 117 : m_token(WTF::wrapUnique(new HTMLToken)),
115 m_tokenizer(HTMLTokenizer::create(config->options)), 118 m_tokenizer(HTMLTokenizer::create(config->options)),
116 m_treeBuilderSimulator(config->options), 119 m_treeBuilderSimulator(config->options),
117 m_options(config->options), 120 m_options(config->options),
118 m_outstandingTokenLimit(config->outstandingTokenLimit), 121 m_outstandingTokenLimit(config->outstandingTokenLimit),
119 m_parser(config->parser), 122 m_parser(parser),
120 m_pendingTokens(WTF::wrapUnique(new CompactHTMLTokenStream)), 123 m_pendingTokens(WTF::wrapUnique(new CompactHTMLTokenStream)),
121 m_pendingTokenLimit(config->pendingTokenLimit), 124 m_pendingTokenLimit(config->pendingTokenLimit),
122 m_xssAuditor(std::move(config->xssAuditor)), 125 m_xssAuditor(std::move(config->xssAuditor)),
126 m_preloadScanner(std::move(scanner)),
123 m_decoder(std::move(config->decoder)), 127 m_decoder(std::move(config->decoder)),
124 m_loadingTaskRunner(std::move(loadingTaskRunner)), 128 m_loadingTaskRunner(std::move(loadingTaskRunner)),
125 m_tokenizedChunkQueue(std::move(config->tokenizedChunkQueue)),
126 m_pendingCSPMetaTokenIndex( 129 m_pendingCSPMetaTokenIndex(
127 HTMLDocumentParser::TokenizedChunk::noPendingToken), 130 HTMLDocumentParser::TokenizedChunk::noPendingToken),
128 m_startingScript(false), 131 m_startingScript(false),
129 m_lastBytesReceivedTime(0.0), 132 m_lastBytesReceivedTime(0.0),
130 m_shouldCoalesceChunks(config->shouldCoalesceChunks) { 133 m_shouldCoalesceChunks(config->shouldCoalesceChunks) {
131 ASSERT(m_outstandingTokenLimit > 0); 134 ASSERT(m_outstandingTokenLimit > 0);
132 ASSERT(m_pendingTokenLimit > 0); 135 ASSERT(m_pendingTokenLimit > 0);
133 ASSERT(m_outstandingTokenLimit >= m_pendingTokenLimit); 136 ASSERT(m_outstandingTokenLimit >= m_pendingTokenLimit);
134 } 137 }
135 138
136 BackgroundHTMLParser::~BackgroundHTMLParser() {} 139 BackgroundHTMLParser::~BackgroundHTMLParser() {}
137 140
138 void BackgroundHTMLParser::appendRawBytesFromMainThread( 141 void BackgroundHTMLParser::appendRawBytesFromMainThread(
139 std::unique_ptr<Vector<char>> buffer, 142 std::unique_ptr<Vector<char>> buffer,
140 double bytesReceivedTime) { 143 double bytesReceivedTime) {
141 ASSERT(m_decoder); 144 ASSERT(m_decoder);
142 m_lastBytesReceivedTime = bytesReceivedTime; 145 m_lastBytesReceivedTime = bytesReceivedTime;
143 DEFINE_STATIC_LOCAL(CustomCountHistogram, queueDelay, 146 DEFINE_STATIC_LOCAL(CustomCountHistogram, queueDelay,
144 ("Parser.AppendBytesDelay", 1, 5000, 50)); 147 ("Parser.AppendBytesDelay", 1, 5000, 50));
145 queueDelay.count(monotonicallyIncreasingTimeMS() - bytesReceivedTime); 148 queueDelay.count(monotonicallyIncreasingTimeMS() - bytesReceivedTime);
146 updateDocument(m_decoder->decode(buffer->data(), buffer->size())); 149 m_loadingTaskRunner->postTask(
150 BLINK_FROM_HERE,
151 WTF::bind(&BackgroundHTMLParser::updateDocument, wrapPersistent(this),
152 m_decoder->decode(buffer->data(), buffer->size())));
147 } 153 }
148 154
149 void BackgroundHTMLParser::appendDecodedBytes(const String& input) { 155 void BackgroundHTMLParser::appendDecodedBytes(const String& input) {
150 ASSERT(!m_input.current().isClosed()); 156 ASSERT(!m_input.current().isClosed());
151 m_input.append(input); 157 m_input.append(input);
152 pumpTokenizer(); 158 pumpTokenizer();
153 } 159 }
154 160
155 void BackgroundHTMLParser::setDecoder( 161 void BackgroundHTMLParser::setDecoder(
156 std::unique_ptr<TextResourceDecoder> decoder) { 162 std::unique_ptr<TextResourceDecoder> decoder) {
157 ASSERT(decoder); 163 ASSERT(decoder);
158 m_decoder = std::move(decoder); 164 m_decoder = std::move(decoder);
159 } 165 }
160 166
161 void BackgroundHTMLParser::flush() { 167 void BackgroundHTMLParser::flush() {
162 ASSERT(m_decoder); 168 ASSERT(m_decoder);
163 updateDocument(m_decoder->flush()); 169 m_loadingTaskRunner->postTask(
170 BLINK_FROM_HERE, WTF::bind(&BackgroundHTMLParser::updateDocument,
171 wrapPersistent(this), m_decoder->flush()));
164 } 172 }
165 173
166 void BackgroundHTMLParser::updateDocument(const String& decodedData) { 174 void BackgroundHTMLParser::updateDocument(const String& decodedData) {
167 DocumentEncodingData encodingData(*m_decoder.get()); 175 DocumentEncodingData encodingData(*m_decoder.get());
168 176
169 if (encodingData != m_lastSeenEncodingData) { 177 if (encodingData != m_lastSeenEncodingData) {
170 m_lastSeenEncodingData = encodingData; 178 m_lastSeenEncodingData = encodingData;
171 179
172 m_xssAuditor->setEncoding(encodingData.encoding()); 180 m_xssAuditor->setEncoding(encodingData.encoding());
173 runOnMainThread( 181 m_parser->didReceiveEncodingDataFromBackgroundParser(encodingData);
174 &HTMLDocumentParser::didReceiveEncodingDataFromBackgroundParser,
175 m_parser, encodingData);
176 } 182 }
177 183
178 if (decodedData.isEmpty()) 184 if (decodedData.isEmpty())
179 return; 185 return;
180 186
181 appendDecodedBytes(decodedData); 187 appendDecodedBytes(decodedData);
182 } 188 }
183 189
184 void BackgroundHTMLParser::resumeFrom(std::unique_ptr<Checkpoint> checkpoint) { 190 void BackgroundHTMLParser::resumeFrom(std::unique_ptr<Checkpoint> checkpoint) {
185 m_parser = checkpoint->parser; 191 m_loadingTaskRunner->postTask(
192 BLINK_FROM_HERE,
193 WTF::bind(&BackgroundHTMLParser::onResumeFrom, wrapPersistent(this),
194 WTF::passed(std::move(checkpoint))));
195 }
196
197 void BackgroundHTMLParser::onResumeFrom(
198 std::unique_ptr<Checkpoint> checkpoint) {
186 m_token = std::move(checkpoint->token); 199 m_token = std::move(checkpoint->token);
187 m_tokenizer = std::move(checkpoint->tokenizer); 200 m_tokenizer = std::move(checkpoint->tokenizer);
188 m_treeBuilderSimulator.setState(checkpoint->treeBuilderState); 201 m_treeBuilderSimulator.setState(checkpoint->treeBuilderState);
189 m_input.rewindTo(checkpoint->inputCheckpoint, checkpoint->unparsedInput); 202 m_input.rewindTo(checkpoint->inputCheckpoint, checkpoint->unparsedInput);
190 m_preloadScanner->rewindTo(checkpoint->preloadScannerCheckpoint); 203 m_preloadScanner->rewindTo(checkpoint->preloadScannerCheckpoint);
191 m_startingScript = false; 204 m_startingScript = false;
192 m_tokenizedChunkQueue->clear(); 205 m_parser->tokenizedChunkQueue()->clear();
193 m_lastBytesReceivedTime = monotonicallyIncreasingTimeMS(); 206 m_lastBytesReceivedTime = monotonicallyIncreasingTimeMS();
194 pumpTokenizer(); 207 pumpTokenizer();
195 } 208 }
196 209
197 void BackgroundHTMLParser::startedChunkWithCheckpoint( 210 void BackgroundHTMLParser::startedChunkWithCheckpoint(
198 HTMLInputCheckpoint inputCheckpoint) { 211 HTMLInputCheckpoint inputCheckpoint) {
199 // Note, we should not have to worry about the index being invalid as messages 212 // Note, we should not have to worry about the index being invalid as messages
200 // from the main thread will be processed in FIFO order. 213 // from the main thread will be processed in FIFO order.
201 m_input.invalidateCheckpointsBefore(inputCheckpoint); 214 m_input.invalidateCheckpointsBefore(inputCheckpoint);
215 m_loadingTaskRunner->postTask(
216 BLINK_FROM_HERE,
217 WTF::bind(&BackgroundHTMLParser::pumpTokenizer, wrapPersistent(this)));
218 }
219
220 void BackgroundHTMLParser::onFinish() {
221 markEndOfFile();
202 pumpTokenizer(); 222 pumpTokenizer();
203 } 223 }
204 224
205 void BackgroundHTMLParser::finish() { 225 void BackgroundHTMLParser::finish() {
206 markEndOfFile(); 226 m_loadingTaskRunner->postTask(
207 pumpTokenizer(); 227 BLINK_FROM_HERE,
208 } 228 WTF::bind(&BackgroundHTMLParser::onFinish, wrapPersistent(this)));
209
210 void BackgroundHTMLParser::stop() {
211 delete this;
212 } 229 }
213 230
214 void BackgroundHTMLParser::forcePlaintextForTextDocument() { 231 void BackgroundHTMLParser::forcePlaintextForTextDocument() {
215 // This is only used by the TextDocumentParser (a subclass of 232 // This is only used by the TextDocumentParser (a subclass of
216 // HTMLDocumentParser) to force us into the PLAINTEXT state w/o using a 233 // HTMLDocumentParser) to force us into the PLAINTEXT state w/o using a
217 // <plaintext> tag. The TextDocumentParser uses a <pre> tag for historical / 234 // <plaintext> tag. The TextDocumentParser uses a <pre> tag for historical /
218 // compatibility reasons. 235 // compatibility reasons.
219 m_tokenizer->setState(HTMLTokenizer::PLAINTEXTState); 236 m_tokenizer->setState(HTMLTokenizer::PLAINTEXTState);
220 } 237 }
221 238
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
295 simulatedToken == HTMLTreeBuilderSimulator::Link || 312 simulatedToken == HTMLTreeBuilderSimulator::Link ||
296 m_pendingTokens->size() >= m_pendingTokenLimit) { 313 m_pendingTokens->size() >= m_pendingTokenLimit) {
297 shouldNotifyMainThread |= queueChunkForMainThread(); 314 shouldNotifyMainThread |= queueChunkForMainThread();
298 // If we're far ahead of the main thread, yield for a bit to avoid 315 // If we're far ahead of the main thread, yield for a bit to avoid
299 // consuming too much memory. 316 // consuming too much memory.
300 if (m_input.totalCheckpointTokenCount() > m_outstandingTokenLimit) 317 if (m_input.totalCheckpointTokenCount() > m_outstandingTokenLimit)
301 break; 318 break;
302 } 319 }
303 320
304 if (!m_shouldCoalesceChunks && shouldNotifyMainThread) { 321 if (!m_shouldCoalesceChunks && shouldNotifyMainThread) {
305 runOnMainThread(&HTMLDocumentParser::notifyPendingTokenizedChunks, 322 m_parser->notifyPendingTokenizedChunks();
306 m_parser);
307 shouldNotifyMainThread = false; 323 shouldNotifyMainThread = false;
308 } 324 }
309 } 325 }
310 // Wait to notify the main thread about the chunks until we're at the limit. 326 // Wait to notify the main thread about the chunks until we're at the limit.
311 // This lets the background parser generate lots of valuable preloads before 327 // This lets the background parser generate lots of valuable preloads before
312 // anything expensive (extensions, scripts) take up time on the main thread. A 328 // anything expensive (extensions, scripts) take up time on the main thread. A
313 // busy main thread can cause preload delays. 329 // busy main thread can cause preload delays.
314 if (shouldNotifyMainThread) { 330 if (shouldNotifyMainThread) {
315 runOnMainThread(&HTMLDocumentParser::notifyPendingTokenizedChunks, 331 m_parser->notifyPendingTokenizedChunks();
316 m_parser);
317 } 332 }
318 } 333 }
319 334
320 bool BackgroundHTMLParser::queueChunkForMainThread() { 335 bool BackgroundHTMLParser::queueChunkForMainThread() {
321 if (m_pendingTokens->isEmpty()) 336 if (m_pendingTokens->isEmpty())
322 return false; 337 return false;
323 338
324 #if DCHECK_IS_ON() 339 #if DCHECK_IS_ON()
325 checkThatTokensAreSafeToSendToAnotherThread(m_pendingTokens.get()); 340 checkThatTokensAreSafeToSendToAnotherThread(m_pendingTokens.get());
326 checkThatPreloadsAreSafeToSendToAnotherThread(m_pendingPreloads); 341 checkThatPreloadsAreSafeToSendToAnotherThread(m_pendingPreloads);
(...skipping 24 matching lines...) Expand all
351 chunk->preloadScannerCheckpoint = m_preloadScanner->createCheckpoint(); 366 chunk->preloadScannerCheckpoint = m_preloadScanner->createCheckpoint();
352 chunk->tokens = std::move(m_pendingTokens); 367 chunk->tokens = std::move(m_pendingTokens);
353 chunk->startingScript = m_startingScript; 368 chunk->startingScript = m_startingScript;
354 chunk->likelyDocumentWriteScriptIndices.swap( 369 chunk->likelyDocumentWriteScriptIndices.swap(
355 m_likelyDocumentWriteScriptIndices); 370 m_likelyDocumentWriteScriptIndices);
356 chunk->pendingCSPMetaTokenIndex = m_pendingCSPMetaTokenIndex; 371 chunk->pendingCSPMetaTokenIndex = m_pendingCSPMetaTokenIndex;
357 m_startingScript = false; 372 m_startingScript = false;
358 m_pendingCSPMetaTokenIndex = 373 m_pendingCSPMetaTokenIndex =
359 HTMLDocumentParser::TokenizedChunk::noPendingToken; 374 HTMLDocumentParser::TokenizedChunk::noPendingToken;
360 375
361 bool isEmpty = m_tokenizedChunkQueue->enqueue(std::move(chunk)); 376 bool isEmpty = m_parser->tokenizedChunkQueue()->enqueue(std::move(chunk));
362 377
363 DEFINE_STATIC_LOCAL(CustomCountHistogram, chunkEnqueueTime, 378 DEFINE_STATIC_LOCAL(CustomCountHistogram, chunkEnqueueTime,
364 ("Parser.ChunkEnqueueTime", 1, 10000, 50)); 379 ("Parser.ChunkEnqueueTime", 1, 10000, 50));
365 chunkEnqueueTime.count(monotonicallyIncreasingTimeMS() - chunkStartTime); 380 chunkEnqueueTime.count(monotonicallyIncreasingTimeMS() - chunkStartTime);
366 381
367 m_pendingTokens = WTF::wrapUnique(new CompactHTMLTokenStream); 382 m_pendingTokens = WTF::wrapUnique(new CompactHTMLTokenStream);
368 return isEmpty; 383 return isEmpty;
369 } 384 }
370 385
371 // If the background parser is already running on the main thread, then it is
372 // not necessary to post a task to the main thread to run asynchronously. The
373 // main parser deals with chunking up its own work.
374 // TODO(csharrison): This is a pretty big hack because we don't actually need a
375 // CrossThreadClosure in these cases. This is just experimental.
376 template <typename FunctionType, typename... Ps>
377 void BackgroundHTMLParser::runOnMainThread(FunctionType function,
378 Ps&&... parameters) {
379 if (isMainThread()) {
380 (*WTF::bind(function, std::forward<Ps>(parameters)...))();
381 } else {
382 m_loadingTaskRunner->postTask(
383 BLINK_FROM_HERE,
384 crossThreadBind(function, std::forward<Ps>(parameters)...));
385 }
386 }
387
388 } // namespace blink 386 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698