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

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

Issue 1402103002: Revert of Revert "Post loading tasks on the appropriate WebFrameScheduler's queue." (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 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 // 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"
11 #include "core/dom/Element.h" 11 #include "core/dom/Element.h"
12 #include "core/dom/PendingScript.h" 12 #include "core/dom/PendingScript.h"
13 #include "core/fetch/ScriptResource.h" 13 #include "core/fetch/ScriptResource.h"
14 #include "core/frame/Settings.h" 14 #include "core/frame/Settings.h"
15 #include "core/html/parser/TextResourceDecoder.h" 15 #include "core/html/parser/TextResourceDecoder.h"
16 #include "platform/SharedBuffer.h" 16 #include "platform/SharedBuffer.h"
17 #include "platform/Task.h" 17 #include "platform/Task.h"
18 #include "platform/ThreadSafeFunctional.h" 18 #include "platform/ThreadSafeFunctional.h"
19 #include "platform/TraceEvent.h" 19 #include "platform/TraceEvent.h"
20 #include "public/platform/Platform.h" 20 #include "public/platform/Platform.h"
21 #include "public/platform/WebScheduler.h"
21 #include "wtf/MainThread.h" 22 #include "wtf/MainThread.h"
22 #include "wtf/text/TextEncodingRegistry.h" 23 #include "wtf/text/TextEncodingRegistry.h"
23 24
24 namespace blink { 25 namespace blink {
25 26
26 namespace { 27 namespace {
27 28
28 const char* startedStreamingHistogramName(PendingScript::Type scriptType) 29 const char* startedStreamingHistogramName(PendingScript::Type scriptType)
29 { 30 {
30 switch (scriptType) { 31 switch (scriptType) {
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
155 }; 156 };
156 157
157 158
158 // SourceStream implements the streaming interface towards V8. The main 159 // SourceStream implements the streaming interface towards V8. The main
159 // functionality is preparing the data to give to V8 on main thread, and 160 // functionality is preparing the data to give to V8 on main thread, and
160 // actually giving the data (via GetMoreData which is called on a background 161 // actually giving the data (via GetMoreData which is called on a background
161 // thread). 162 // thread).
162 class SourceStream : public v8::ScriptCompiler::ExternalSourceStream { 163 class SourceStream : public v8::ScriptCompiler::ExternalSourceStream {
163 WTF_MAKE_NONCOPYABLE(SourceStream); 164 WTF_MAKE_NONCOPYABLE(SourceStream);
164 public: 165 public:
165 SourceStream() 166 explicit SourceStream(WebTaskRunner* loadingTaskRunner)
166 : v8::ScriptCompiler::ExternalSourceStream() 167 : v8::ScriptCompiler::ExternalSourceStream()
167 , m_cancelled(false) 168 , m_cancelled(false)
168 , m_finished(false) 169 , m_finished(false)
169 , m_queueLeadPosition(0) 170 , m_queueLeadPosition(0)
170 , m_queueTailPosition(0) 171 , m_queueTailPosition(0)
171 , m_bookmarkPosition(0) 172 , m_bookmarkPosition(0)
172 , m_lengthOfBOM(0) 173 , m_lengthOfBOM(0)
174 , m_loadingTaskRunner(adoptPtr(loadingTaskRunner->clone()))
173 { 175 {
174 } 176 }
175 177
176 virtual ~SourceStream() override { } 178 virtual ~SourceStream() override { }
177 179
178 // Called by V8 on a background thread. Should block until we can return 180 // Called by V8 on a background thread. Should block until we can return
179 // some data. 181 // some data.
180 size_t GetMoreData(const uint8_t** src) override 182 size_t GetMoreData(const uint8_t** src) override
181 { 183 {
182 ASSERT(!isMainThread()); 184 ASSERT(!isMainThread());
(...skipping 29 matching lines...) Expand all
212 { 214 {
213 MutexLocker locker(m_mutex); 215 MutexLocker locker(m_mutex);
214 m_queueLeadPosition = m_bookmarkPosition; 216 m_queueLeadPosition = m_bookmarkPosition;
215 // See comments at m_lengthOfBOM declaration below for why 217 // See comments at m_lengthOfBOM declaration below for why
216 // we need this here. 218 // we need this here.
217 m_queueTailPosition = m_bookmarkPosition + m_lengthOfBOM; 219 m_queueTailPosition = m_bookmarkPosition + m_lengthOfBOM;
218 m_dataQueue.clear(); 220 m_dataQueue.clear();
219 } 221 }
220 222
221 // Inform main thread to re-queue the data. 223 // Inform main thread to re-queue the data.
222 Platform::current()->mainThread()->taskRunner()->postTask( 224 m_loadingTaskRunner->postTask(
223 FROM_HERE, bind(&SourceStream::fetchDataFromResourceBuffer, this, 0) ); 225 FROM_HERE, bind(&SourceStream::fetchDataFromResourceBuffer, this, 0) );
224 } 226 }
225 227
226 void didFinishLoading() 228 void didFinishLoading()
227 { 229 {
228 ASSERT(isMainThread()); 230 ASSERT(isMainThread());
229 231
230 // ResetToBookmark may reset the data queue's 'finished' status, 232 // ResetToBookmark may reset the data queue's 'finished' status,
231 // so we may need to re-finish after a ResetToBookmark happened. 233 // so we may need to re-finish after a ResetToBookmark happened.
232 // We do this by remembering m_finished, and always checking for it 234 // We do this by remembering m_finished, and always checking for it
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
363 // - m_queueLeadPosition counts the bytes that V8 has received 365 // - m_queueLeadPosition counts the bytes that V8 has received
364 // (i.e., without BOM) 366 // (i.e., without BOM)
365 // - m_queueTailPosition counts the bytes that Chrome has sent 367 // - m_queueTailPosition counts the bytes that Chrome has sent
366 // (i.e., with BOM) 368 // (i.e., with BOM)
367 // So when resetting the bookmark, we have to adjust the lead position 369 // So when resetting the bookmark, we have to adjust the lead position
368 // to account for the BOM (which happens implicitly in the regular 370 // to account for the BOM (which happens implicitly in the regular
369 // streaming case). 371 // streaming case).
370 // We store this separately, to avoid having to guard all 372 // We store this separately, to avoid having to guard all
371 // m_queueLeadPosition references with a mutex. 373 // m_queueLeadPosition references with a mutex.
372 unsigned m_lengthOfBOM; // Used by both threads; guarded by m_mutex. 374 unsigned m_lengthOfBOM; // Used by both threads; guarded by m_mutex.
375
376 OwnPtr<WebTaskRunner> m_loadingTaskRunner;
373 }; 377 };
374 378
375 size_t ScriptStreamer::kSmallScriptThreshold = 30 * 1024; 379 size_t ScriptStreamer::kSmallScriptThreshold = 30 * 1024;
376 380
377 void ScriptStreamer::startStreaming(PendingScript& script, PendingScript::Type s criptType, Settings* settings, ScriptState* scriptState) 381 void ScriptStreamer::startStreaming(PendingScript& script, PendingScript::Type s criptType, Settings* settings, ScriptState* scriptState, WebTaskRunner* loadingT askRunner)
378 { 382 {
379 // We don't yet know whether the script will really be streamed. E.g., 383 // We don't yet know whether the script will really be streamed. E.g.,
380 // suppressing streaming for short scripts is done later. Record only the 384 // suppressing streaming for short scripts is done later. Record only the
381 // sure negative cases here. 385 // sure negative cases here.
382 bool startedStreaming = startStreamingInternal(script, scriptType, settings, scriptState); 386 bool startedStreaming = startStreamingInternal(script, scriptType, settings, scriptState, loadingTaskRunner);
383 if (!startedStreaming) 387 if (!startedStreaming)
384 Platform::current()->histogramEnumeration(startedStreamingHistogramName( scriptType), 0, 2); 388 Platform::current()->histogramEnumeration(startedStreamingHistogramName( scriptType), 0, 2);
385 } 389 }
386 390
387 bool ScriptStreamer::convertEncoding(const char* encodingName, v8::ScriptCompile r::StreamedSource::Encoding* encoding) 391 bool ScriptStreamer::convertEncoding(const char* encodingName, v8::ScriptCompile r::StreamedSource::Encoding* encoding)
388 { 392 {
389 // Here's a list of encodings we can use for streaming. These are 393 // Here's a list of encodings we can use for streaming. These are
390 // the canonical names. 394 // the canonical names.
391 if (strcmp(encodingName, "windows-1252") == 0 395 if (strcmp(encodingName, "windows-1252") == 0
392 || strcmp(encodingName, "ISO-8859-1") == 0 396 || strcmp(encodingName, "ISO-8859-1") == 0
(...skipping 21 matching lines...) Expand all
414 void ScriptStreamer::streamingCompleteOnBackgroundThread() 418 void ScriptStreamer::streamingCompleteOnBackgroundThread()
415 { 419 {
416 ASSERT(!isMainThread()); 420 ASSERT(!isMainThread());
417 { 421 {
418 MutexLocker locker(m_mutex); 422 MutexLocker locker(m_mutex);
419 m_parsingFinished = true; 423 m_parsingFinished = true;
420 } 424 }
421 425
422 // notifyFinished might already be called, or it might be called in the 426 // notifyFinished might already be called, or it might be called in the
423 // future (if the parsing finishes earlier because of a parse error). 427 // future (if the parsing finishes earlier because of a parse error).
424 Platform::current()->mainThread()->taskRunner()->postTask(FROM_HERE, threadS afeBind(&ScriptStreamer::streamingComplete, AllowCrossThreadAccess(this))); 428 m_loadingTaskRunner->postTask(FROM_HERE, threadSafeBind(&ScriptStreamer::str eamingComplete, AllowCrossThreadAccess(this)));
425 429
426 // The task might delete ScriptStreamer, so it's not safe to do anything 430 // The task might delete ScriptStreamer, so it's not safe to do anything
427 // after posting it. Note that there's no way to guarantee that this 431 // after posting it. Note that there's no way to guarantee that this
428 // function has returned before the task is ran - however, we should not 432 // function has returned before the task is ran - however, we should not
429 // access the "this" object after posting the task. (Especially, we should 433 // access the "this" object after posting the task. (Especially, we should
430 // not be holding the mutex at this point.) 434 // not be holding the mutex at this point.)
431 } 435 }
432 436
433 void ScriptStreamer::cancel() 437 void ScriptStreamer::cancel()
434 { 438 {
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
506 510
507 if (!m_scriptState->contextIsValid()) { 511 if (!m_scriptState->contextIsValid()) {
508 suppressStreaming(); 512 suppressStreaming();
509 Platform::current()->histogramEnumeration(notStreamingReasonHistogra mName(m_scriptType), ContextNotValid, NotStreamingReasonEnd); 513 Platform::current()->histogramEnumeration(notStreamingReasonHistogra mName(m_scriptType), ContextNotValid, NotStreamingReasonEnd);
510 Platform::current()->histogramEnumeration(startedStreamingHistogramN ame(m_scriptType), 0, 2); 514 Platform::current()->histogramEnumeration(startedStreamingHistogramN ame(m_scriptType), 0, 2);
511 return; 515 return;
512 } 516 }
513 517
514 ASSERT(!m_stream); 518 ASSERT(!m_stream);
515 ASSERT(!m_source); 519 ASSERT(!m_source);
516 m_stream = new SourceStream(); 520 m_stream = new SourceStream(m_loadingTaskRunner.get());
517 // m_source takes ownership of m_stream. 521 // m_source takes ownership of m_stream.
518 m_source = adoptPtr(new v8::ScriptCompiler::StreamedSource(m_stream, m_e ncoding)); 522 m_source = adoptPtr(new v8::ScriptCompiler::StreamedSource(m_stream, m_e ncoding));
519 523
520 ScriptState::Scope scope(m_scriptState.get()); 524 ScriptState::Scope scope(m_scriptState.get());
521 WTF::OwnPtr<v8::ScriptCompiler::ScriptStreamingTask> scriptStreamingTask (adoptPtr(v8::ScriptCompiler::StartStreamingScript(m_scriptState->isolate(), m_s ource.get(), m_compileOptions))); 525 WTF::OwnPtr<v8::ScriptCompiler::ScriptStreamingTask> scriptStreamingTask (adoptPtr(v8::ScriptCompiler::StartStreamingScript(m_scriptState->isolate(), m_s ource.get(), m_compileOptions)));
522 if (!scriptStreamingTask) { 526 if (!scriptStreamingTask) {
523 // V8 cannot stream the script. 527 // V8 cannot stream the script.
524 suppressStreaming(); 528 suppressStreaming();
525 m_stream = 0; 529 m_stream = 0;
526 m_source.clear(); 530 m_source.clear();
(...skipping 30 matching lines...) Expand all
557 m_stream->didFinishLoading(); 561 m_stream->didFinishLoading();
558 m_loadingFinished = true; 562 m_loadingFinished = true;
559 563
560 // Calling notifyFinishedToClient can result into the upper layers dropping 564 // Calling notifyFinishedToClient can result into the upper layers dropping
561 // references to ScriptStreamer. Keep it alive until this function ends. 565 // references to ScriptStreamer. Keep it alive until this function ends.
562 RefPtrWillBeRawPtr<ScriptStreamer> protect(this); 566 RefPtrWillBeRawPtr<ScriptStreamer> protect(this);
563 567
564 notifyFinishedToClient(); 568 notifyFinishedToClient();
565 } 569 }
566 570
567 ScriptStreamer::ScriptStreamer(ScriptResource* resource, PendingScript::Type scr iptType, ScriptState* scriptState, v8::ScriptCompiler::CompileOptions compileOpt ions) 571 ScriptStreamer::ScriptStreamer(ScriptResource* resource, PendingScript::Type scr iptType, ScriptState* scriptState, v8::ScriptCompiler::CompileOptions compileOpt ions, WebTaskRunner* loadingTaskRunner)
568 : m_resource(resource) 572 : m_resource(resource)
569 , m_detached(false) 573 , m_detached(false)
570 , m_stream(0) 574 , m_stream(0)
571 , m_client(0) 575 , m_client(0)
572 , m_loadingFinished(false) 576 , m_loadingFinished(false)
573 , m_parsingFinished(false) 577 , m_parsingFinished(false)
574 , m_haveEnoughDataForStreaming(false) 578 , m_haveEnoughDataForStreaming(false)
575 , m_streamingSuppressed(false) 579 , m_streamingSuppressed(false)
576 , m_compileOptions(compileOptions) 580 , m_compileOptions(compileOptions)
577 , m_scriptState(scriptState) 581 , m_scriptState(scriptState)
578 , m_scriptType(scriptType) 582 , m_scriptType(scriptType)
579 , m_encoding(v8::ScriptCompiler::StreamedSource::TWO_BYTE) // Unfortunately there's no dummy encoding value in the enum; let's use one we don't stream. 583 , m_encoding(v8::ScriptCompiler::StreamedSource::TWO_BYTE) // Unfortunately there's no dummy encoding value in the enum; let's use one we don't stream.
584 , m_loadingTaskRunner(adoptPtr(loadingTaskRunner->clone()))
580 { 585 {
581 } 586 }
582 587
583 ScriptStreamer::~ScriptStreamer() 588 ScriptStreamer::~ScriptStreamer()
584 { 589 {
585 } 590 }
586 591
587 DEFINE_TRACE(ScriptStreamer) 592 DEFINE_TRACE(ScriptStreamer)
588 { 593 {
589 visitor->trace(m_resource); 594 visitor->trace(m_resource);
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
625 // function calling notifyFinishedToClient was already scheduled in the task 630 // function calling notifyFinishedToClient was already scheduled in the task
626 // queue and the upper layer decided that it's not interested in the script 631 // queue and the upper layer decided that it's not interested in the script
627 // and called removeClient. 632 // and called removeClient.
628 if (!isFinished()) 633 if (!isFinished())
629 return; 634 return;
630 635
631 if (m_client) 636 if (m_client)
632 m_client->notifyFinished(m_resource); 637 m_client->notifyFinished(m_resource);
633 } 638 }
634 639
635 bool ScriptStreamer::startStreamingInternal(PendingScript& script, PendingScript ::Type scriptType, Settings* settings, ScriptState* scriptState) 640 bool ScriptStreamer::startStreamingInternal(PendingScript& script, PendingScript ::Type scriptType, Settings* settings, ScriptState* scriptState, WebTaskRunner* loadingTaskRunner)
636 { 641 {
637 ASSERT(isMainThread()); 642 ASSERT(isMainThread());
638 ASSERT(scriptState->contextIsValid()); 643 ASSERT(scriptState->contextIsValid());
639 ScriptResource* resource = script.resource(); 644 ScriptResource* resource = script.resource();
640 if (resource->isLoaded()) { 645 if (resource->isLoaded()) {
641 Platform::current()->histogramEnumeration(notStreamingReasonHistogramNam e(scriptType), AlreadyLoaded, NotStreamingReasonEnd); 646 Platform::current()->histogramEnumeration(notStreamingReasonHistogramNam e(scriptType), AlreadyLoaded, NotStreamingReasonEnd);
642 return false; 647 return false;
643 } 648 }
644 if (!resource->url().protocolIsInHTTPFamily()) { 649 if (!resource->url().protocolIsInHTTPFamily()) {
645 Platform::current()->histogramEnumeration(notStreamingReasonHistogramNam e(scriptType), NotHTTP, NotStreamingReasonEnd); 650 Platform::current()->histogramEnumeration(notStreamingReasonHistogramNam e(scriptType), NotHTTP, NotStreamingReasonEnd);
(...skipping 12 matching lines...) Expand all
658 663
659 // Decide what kind of cached data we should produce while streaming. Only 664 // Decide what kind of cached data we should produce while streaming. Only
660 // produce parser cache if the non-streaming compile takes advantage of it. 665 // produce parser cache if the non-streaming compile takes advantage of it.
661 v8::ScriptCompiler::CompileOptions compileOption = v8::ScriptCompiler::kNoCo mpileOptions; 666 v8::ScriptCompiler::CompileOptions compileOption = v8::ScriptCompiler::kNoCo mpileOptions;
662 if (settings->v8CacheOptions() == V8CacheOptionsParse) 667 if (settings->v8CacheOptions() == V8CacheOptionsParse)
663 compileOption = v8::ScriptCompiler::kProduceParserCache; 668 compileOption = v8::ScriptCompiler::kProduceParserCache;
664 669
665 // The Resource might go out of scope if the script is no longer 670 // The Resource might go out of scope if the script is no longer
666 // needed. This makes PendingScript notify the ScriptStreamer when it is 671 // needed. This makes PendingScript notify the ScriptStreamer when it is
667 // destroyed. 672 // destroyed.
668 script.setStreamer(ScriptStreamer::create(resource, scriptType, scriptState, compileOption)); 673 script.setStreamer(ScriptStreamer::create(resource, scriptType, scriptState, compileOption, loadingTaskRunner));
669 674
670 return true; 675 return true;
671 } 676 }
672 677
673 } // namespace blink 678 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698