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

Side by Side Diff: Source/bindings/core/v8/ScriptStreamer.cpp

Issue 1315873003: Fix BOM handling w/ bookmark + streaming parsing. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Created 5 years, 3 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
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "config.h" 5 #include "config.h"
6 #include "bindings/core/v8/ScriptStreamer.h" 6 #include "bindings/core/v8/ScriptStreamer.h"
7 7
8 #include "bindings/core/v8/ScriptStreamerThread.h" 8 #include "bindings/core/v8/ScriptStreamerThread.h"
9 #include "bindings/core/v8/V8ScriptRunner.h" 9 #include "bindings/core/v8/V8ScriptRunner.h"
10 #include "core/dom/Document.h" 10 #include "core/dom/Document.h"
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after
162 class SourceStream : public v8::ScriptCompiler::ExternalSourceStream { 162 class SourceStream : public v8::ScriptCompiler::ExternalSourceStream {
163 WTF_MAKE_NONCOPYABLE(SourceStream); 163 WTF_MAKE_NONCOPYABLE(SourceStream);
164 public: 164 public:
165 SourceStream() 165 SourceStream()
166 : v8::ScriptCompiler::ExternalSourceStream() 166 : v8::ScriptCompiler::ExternalSourceStream()
167 , m_cancelled(false) 167 , m_cancelled(false)
168 , m_finished(false) 168 , m_finished(false)
169 , m_queueLeadPosition(0) 169 , m_queueLeadPosition(0)
170 , m_queueTailPosition(0) 170 , m_queueTailPosition(0)
171 , m_bookmarkPosition(0) 171 , m_bookmarkPosition(0)
172 , m_lengthOfBOM(0)
172 { 173 {
173 } 174 }
174 175
175 virtual ~SourceStream() override { } 176 virtual ~SourceStream() override { }
176 177
177 // Called by V8 on a background thread. Should block until we can return 178 // Called by V8 on a background thread. Should block until we can return
178 // some data. 179 // some data.
179 size_t GetMoreData(const uint8_t** src) override 180 size_t GetMoreData(const uint8_t** src) override
180 { 181 {
181 ASSERT(!isMainThread()); 182 ASSERT(!isMainThread());
(...skipping 12 matching lines...) Expand all
194 } 195 }
195 m_queueLeadPosition += length; 196 m_queueLeadPosition += length;
196 return length; 197 return length;
197 } 198 }
198 199
199 // Called by V8 on background thread. 200 // Called by V8 on background thread.
200 bool SetBookmark() override 201 bool SetBookmark() override
201 { 202 {
202 ASSERT(!isMainThread()); 203 ASSERT(!isMainThread());
203 m_bookmarkPosition = m_queueLeadPosition; 204 m_bookmarkPosition = m_queueLeadPosition;
204 return m_bookmarkPosition != 0; // Don't mess with BOM. 205 return true;
205 } 206 }
206 207
207 // Called by V8 on background thread. 208 // Called by V8 on background thread.
208 void ResetToBookmark() override 209 void ResetToBookmark() override
209 { 210 {
210 ASSERT(!isMainThread()); 211 ASSERT(!isMainThread());
211 { 212 {
212 MutexLocker locker(m_mutex); 213 MutexLocker locker(m_mutex);
213 m_queueLeadPosition = m_bookmarkPosition; 214 m_queueLeadPosition = m_bookmarkPosition;
214 m_queueTailPosition = m_bookmarkPosition; 215 // See comments at m_lengthOfBOM declaration below for why
216 // we need this here.
217 m_queueTailPosition = m_bookmarkPosition + m_lengthOfBOM;
215 m_dataQueue.clear(); 218 m_dataQueue.clear();
216 } 219 }
217 220
218 // Inform main thread to re-queue the data. 221 // Inform main thread to re-queue the data.
219 Platform::current()->mainThread()->taskRunner()->postTask( 222 Platform::current()->mainThread()->taskRunner()->postTask(
220 FROM_HERE, bind(&SourceStream::fetchDataFromResourceBuffer, this, 0) ); 223 FROM_HERE, bind(&SourceStream::fetchDataFromResourceBuffer, this, 0) );
221 } 224 }
222 225
223 void didFinishLoading() 226 void didFinishLoading()
224 { 227 {
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
301 // FIXME: Here we can limit based on the total length, if it tur ns 304 // FIXME: Here we can limit based on the total length, if it tur ns
302 // out that we don't want to give all the data we have (memory 305 // out that we don't want to give all the data we have (memory
303 // vs. speed). 306 // vs. speed).
304 chunks.append(data); 307 chunks.append(data);
305 chunkLengths.append(length); 308 chunkLengths.append(length);
306 dataLength += length; 309 dataLength += length;
307 m_queueTailPosition += length; 310 m_queueTailPosition += length;
308 } 311 }
309 } 312 }
310 313
314 if (lengthOfBOM > 0) {
315 ASSERT(!m_lengthOfBOM); // There should be only one BOM.
316 m_lengthOfBOM = lengthOfBOM;
317 }
318
311 // Copy the data chunks into a new buffer, since we're going to give the 319 // Copy the data chunks into a new buffer, since we're going to give the
312 // data to a background thread. 320 // data to a background thread.
313 if (dataLength > lengthOfBOM) { 321 if (dataLength > lengthOfBOM) {
314 dataLength -= lengthOfBOM; 322 dataLength -= lengthOfBOM;
315 uint8_t* copiedData = new uint8_t[dataLength]; 323 uint8_t* copiedData = new uint8_t[dataLength];
316 unsigned offset = 0; 324 unsigned offset = 0;
317 for (size_t i = 0; i < chunks.size(); ++i) { 325 for (size_t i = 0; i < chunks.size(); ++i) {
318 memcpy(copiedData + offset, chunks[i] + lengthOfBOM, chunkLength s[i] - lengthOfBOM); 326 memcpy(copiedData + offset, chunks[i] + lengthOfBOM, chunkLength s[i] - lengthOfBOM);
319 offset += chunkLengths[i] - lengthOfBOM; 327 offset += chunkLengths[i] - lengthOfBOM;
320 // BOM is only in the first chunk 328 // BOM is only in the first chunk
(...skipping 18 matching lines...) Expand all
339 RefPtr<SharedBuffer> m_resourceBuffer; // Only used by the main thread. 347 RefPtr<SharedBuffer> m_resourceBuffer; // Only used by the main thread.
340 348
341 // The queue contains the data to be passed to the V8 thread. 349 // The queue contains the data to be passed to the V8 thread.
342 // queueLeadPosition: data we have handed off to the V8 thread. 350 // queueLeadPosition: data we have handed off to the V8 thread.
343 // queueTailPosition: end of data we have enqued in the queue. 351 // queueTailPosition: end of data we have enqued in the queue.
344 // bookmarkPosition: position of the bookmark. 352 // bookmarkPosition: position of the bookmark.
345 SourceStreamDataQueue m_dataQueue; // Thread safe. 353 SourceStreamDataQueue m_dataQueue; // Thread safe.
346 unsigned m_queueLeadPosition; // Only used by v8 thread. 354 unsigned m_queueLeadPosition; // Only used by v8 thread.
347 unsigned m_queueTailPosition; // Used by both threads; guarded by m_mutex. 355 unsigned m_queueTailPosition; // Used by both threads; guarded by m_mutex.
348 unsigned m_bookmarkPosition; // Only used by v8 thread. 356 unsigned m_bookmarkPosition; // Only used by v8 thread.
357
358 // BOM (Unicode Byte Order Mark) handling:
359 // This class is responsible for stripping out the BOM, since Chrome
360 // delivers the input stream potentially with BOM, but V8 doesn't want
361 // to see the BOM. This is mostly easy to do, except for a funky edge
362 // condition with bookmarking:
363 // - m_queueLeadPosition counts the bytes that V8 has received
364 // (i.e., without BOM)
365 // - m_queueTailPosition counts the bytes that Chrome has sent
366 // (i.e., with BOM)
367 // So when resetting the bookmark, we have to adjust the lead position
368 // to account for the BOM (which happens implicitly in the regular
369 // streaming case).
370 // We store this separately, to avoid having to guard all
371 // m_queueLeadPosition references with a mutex.
372 unsigned m_lengthOfBOM; // Used by both threads; guarded by m_mutex.
349 }; 373 };
350 374
351 size_t ScriptStreamer::kSmallScriptThreshold = 30 * 1024; 375 size_t ScriptStreamer::kSmallScriptThreshold = 30 * 1024;
352 376
353 void ScriptStreamer::startStreaming(PendingScript& script, PendingScript::Type s criptType, Settings* settings, ScriptState* scriptState) 377 void ScriptStreamer::startStreaming(PendingScript& script, PendingScript::Type s criptType, Settings* settings, ScriptState* scriptState)
354 { 378 {
355 // We don't yet know whether the script will really be streamed. E.g., 379 // We don't yet know whether the script will really be streamed. E.g.,
356 // suppressing streaming for short scripts is done later. Record only the 380 // suppressing streaming for short scripts is done later. Record only the
357 // sure negative cases here. 381 // sure negative cases here.
358 bool startedStreaming = startStreamingInternal(script, scriptType, settings, scriptState); 382 bool startedStreaming = startStreamingInternal(script, scriptType, settings, scriptState);
(...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after
640 664
641 // The Resource might go out of scope if the script is no longer 665 // The Resource might go out of scope if the script is no longer
642 // needed. This makes PendingScript notify the ScriptStreamer when it is 666 // needed. This makes PendingScript notify the ScriptStreamer when it is
643 // destroyed. 667 // destroyed.
644 script.setStreamer(ScriptStreamer::create(resource, scriptType, scriptState, compileOption)); 668 script.setStreamer(ScriptStreamer::create(resource, scriptType, scriptState, compileOption));
645 669
646 return true; 670 return true;
647 } 671 }
648 672
649 } // namespace blink 673 } // namespace blink
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698