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

Side by Side Diff: sky/engine/core/html/parser/BackgroundHTMLParser.cpp

Issue 676763003: Remove BackgroundHTMLInputStream (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: 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) 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
(...skipping 15 matching lines...) Expand all
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/TextResourceDecoder.h" 30 #include "core/html/parser/TextResourceDecoder.h"
31 #include "wtf/MainThread.h" 31 #include "wtf/MainThread.h"
32 #include "wtf/text/TextPosition.h" 32 #include "wtf/text/TextPosition.h"
33 33
34 namespace blink { 34 namespace blink {
35 35
36 // On a network with high latency and high bandwidth, using a device
37 // with a fast CPU, we could end up speculatively tokenizing
38 // the whole document, well ahead of when the main-thread actually needs it.
39 // This is a waste of memory (and potentially time if the speculation fails).
40 // So we limit our outstanding tokens arbitrarily to 10,000.
41 // Our maximal memory spent speculating will be approximately:
42 // (outstandingTokenLimit + pendingTokenLimit) * sizeof(CompactToken)
43 // We use a separate low and high water mark to avoid constantly topping
44 // off the main thread's token buffer.
45 // At time of writing, this is (10000 + 1000) * 28 bytes = ~308kb of memory.
46 // These numbers have not been tuned.
47 static const size_t outstandingTokenLimit = 10000;
48
49 // We limit our chucks to 1000 tokens, to make sure the main 36 // We limit our chucks to 1000 tokens, to make sure the main
50 // thread is never waiting on the parser thread for tokens. 37 // thread is never waiting on the parser thread for tokens.
51 // This was tuned in https://bugs.webkit.org/show_bug.cgi?id=110408. 38 // This was tuned in https://bugs.webkit.org/show_bug.cgi?id=110408.
52 static const size_t pendingTokenLimit = 1000; 39 static const size_t pendingTokenLimit = 1000;
53 40
54 #if ENABLE(ASSERT) 41 #if ENABLE(ASSERT)
55 42
56 static void checkThatTokensAreSafeToSendToAnotherThread(const CompactHTMLTokenSt ream* tokens) 43 static void checkThatTokensAreSafeToSendToAnotherThread(const CompactHTMLTokenSt ream* tokens)
57 { 44 {
58 for (size_t i = 0; i < tokens->size(); ++i) 45 for (size_t i = 0; i < tokens->size(); ++i)
(...skipping 30 matching lines...) Expand all
89 updateDocument(m_decoder->decode(data, dataLength)); 76 updateDocument(m_decoder->decode(data, dataLength));
90 } 77 }
91 78
92 void BackgroundHTMLParser::appendRawBytesFromMainThread(PassOwnPtr<Vector<char> > buffer) 79 void BackgroundHTMLParser::appendRawBytesFromMainThread(PassOwnPtr<Vector<char> > buffer)
93 { 80 {
94 updateDocument(m_decoder->decode(buffer->data(), buffer->size())); 81 updateDocument(m_decoder->decode(buffer->data(), buffer->size()));
95 } 82 }
96 83
97 void BackgroundHTMLParser::appendDecodedBytes(const String& input) 84 void BackgroundHTMLParser::appendDecodedBytes(const String& input)
98 { 85 {
99 ASSERT(!m_input.current().isClosed()); 86 ASSERT(!m_input.isClosed());
100 m_input.append(input); 87 m_input.append(SegmentedString(input));
101 pumpTokenizer(); 88 pumpTokenizer();
102 } 89 }
103 90
104 void BackgroundHTMLParser::flush() 91 void BackgroundHTMLParser::flush()
105 { 92 {
106 updateDocument(m_decoder->flush()); 93 updateDocument(m_decoder->flush());
107 } 94 }
108 95
109 void BackgroundHTMLParser::updateDocument(const String& decodedData) 96 void BackgroundHTMLParser::updateDocument(const String& decodedData)
110 { 97 {
111 if (decodedData.isEmpty()) 98 if (decodedData.isEmpty())
112 return; 99 return;
113 100
114 appendDecodedBytes(decodedData); 101 appendDecodedBytes(decodedData);
115 } 102 }
116 103
117 void BackgroundHTMLParser::startedChunkWithCheckpoint(HTMLInputCheckpoint inputC heckpoint)
118 {
119 // Note, we should not have to worry about the index being invalid
120 // as messages from the main thread will be processed in FIFO order.
121 m_input.invalidateCheckpointsBefore(inputCheckpoint);
122 pumpTokenizer();
123 }
124
125 void BackgroundHTMLParser::finish() 104 void BackgroundHTMLParser::finish()
126 { 105 {
127 markEndOfFile(); 106 markEndOfFile();
128 pumpTokenizer(); 107 pumpTokenizer();
129 } 108 }
130 109
131 void BackgroundHTMLParser::stop() 110 void BackgroundHTMLParser::stop()
132 { 111 {
133 delete this; 112 delete this;
134 } 113 }
135 114
136 void BackgroundHTMLParser::markEndOfFile() 115 void BackgroundHTMLParser::markEndOfFile()
137 { 116 {
138 ASSERT(!m_input.current().isClosed()); 117 ASSERT(!m_input.isClosed());
139 m_input.append(String(&kEndOfFileMarker, 1)); 118 m_input.append(SegmentedString(String(&kEndOfFileMarker, 1)));
140 m_input.close(); 119 m_input.close();
141 } 120 }
142 121
143 void BackgroundHTMLParser::pumpTokenizer() 122 void BackgroundHTMLParser::pumpTokenizer()
144 { 123 {
145 // No need to start speculating until the main thread has almost caught up.
146 if (m_input.totalCheckpointTokenCount() > outstandingTokenLimit)
147 return;
148
149 while (true) { 124 while (true) {
150 if (!m_tokenizer->nextToken(m_input.current(), *m_token)) { 125 if (!m_tokenizer->nextToken(m_input, *m_token)) {
151 // We've reached the end of our current input. 126 // We've reached the end of our current input.
152 sendTokensToMainThread(); 127 sendTokensToMainThread();
153 break; 128 break;
154 } 129 }
155 130
156 { 131 {
157 CompactHTMLToken token(m_token.get(), TextPosition(m_input.current() .currentLine(), m_input.current().currentColumn())); 132 CompactHTMLToken token(m_token.get(), TextPosition(m_input.currentLi ne(), m_input.currentColumn()));
158 m_pendingTokens->append(token); 133 m_pendingTokens->append(token);
159 } 134 }
160 135
161 m_token->clear(); 136 m_token->clear();
162 137
163 if (!m_treeBuilderSimulator.simulate(m_pendingTokens->last(), m_tokenize r.get()) || m_pendingTokens->size() >= pendingTokenLimit) { 138 if (!m_treeBuilderSimulator.simulate(m_pendingTokens->last(), m_tokenize r.get()) || m_pendingTokens->size() >= pendingTokenLimit)
164 sendTokensToMainThread(); 139 sendTokensToMainThread();
165 // If we're far ahead of the main thread, yield for a bit to avoid c onsuming too much memory.
166 if (m_input.totalCheckpointTokenCount() > outstandingTokenLimit)
167 break;
168 }
169 } 140 }
170 } 141 }
171 142
172 void BackgroundHTMLParser::sendTokensToMainThread() 143 void BackgroundHTMLParser::sendTokensToMainThread()
173 { 144 {
174 if (m_pendingTokens->isEmpty()) 145 if (m_pendingTokens->isEmpty())
175 return; 146 return;
176 147
177 #if ENABLE(ASSERT) 148 #if ENABLE(ASSERT)
178 checkThatTokensAreSafeToSendToAnotherThread(m_pendingTokens.get()); 149 checkThatTokensAreSafeToSendToAnotherThread(m_pendingTokens.get());
179 #endif 150 #endif
180 151
181 OwnPtr<HTMLDocumentParser::ParsedChunk> chunk = adoptPtr(new HTMLDocumentPar ser::ParsedChunk); 152 OwnPtr<HTMLDocumentParser::ParsedChunk> chunk = adoptPtr(new HTMLDocumentPar ser::ParsedChunk);
182 chunk->tokenizerState = m_tokenizer->state(); 153 chunk->tokenizerState = m_tokenizer->state();
183 chunk->inputCheckpoint = m_input.createCheckpoint(m_pendingTokens->size());
184 chunk->tokens = m_pendingTokens.release(); 154 chunk->tokens = m_pendingTokens.release();
185 callOnMainThread(bind(&HTMLDocumentParser::didReceiveParsedChunkFromBackgrou ndParser, m_parser, chunk.release())); 155 callOnMainThread(bind(&HTMLDocumentParser::didReceiveParsedChunkFromBackgrou ndParser, m_parser, chunk.release()));
186 156
187 m_pendingTokens = adoptPtr(new CompactHTMLTokenStream); 157 m_pendingTokens = adoptPtr(new CompactHTMLTokenStream);
188 } 158 }
189 159
190 } 160 }
OLDNEW
« no previous file with comments | « sky/engine/core/html/parser/BackgroundHTMLParser.h ('k') | sky/engine/core/html/parser/HTMLDocumentParser.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698