| OLD | NEW |
| 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 "bindings/core/v8/ScriptStreamer.h" | 5 #include "bindings/core/v8/ScriptStreamer.h" |
| 6 | 6 |
| 7 #include "bindings/core/v8/ScriptStreamerThread.h" | 7 #include "bindings/core/v8/ScriptStreamerThread.h" |
| 8 #include "bindings/core/v8/V8ScriptRunner.h" | 8 #include "bindings/core/v8/V8ScriptRunner.h" |
| 9 #include "core/dom/Document.h" | 9 #include "core/dom/Document.h" |
| 10 #include "core/dom/Element.h" | 10 #include "core/dom/Element.h" |
| 11 #include "core/dom/PendingScript.h" | 11 #include "core/dom/PendingScript.h" |
| 12 #include "core/fetch/ScriptResource.h" | 12 #include "core/fetch/ScriptResource.h" |
| 13 #include "core/frame/Settings.h" | 13 #include "core/frame/Settings.h" |
| 14 #include "core/html/parser/TextResourceDecoder.h" | 14 #include "core/html/parser/TextResourceDecoder.h" |
| 15 #include "platform/Histogram.h" | 15 #include "platform/Histogram.h" |
| 16 #include "platform/SharedBuffer.h" | 16 #include "platform/SharedBuffer.h" |
| 17 #include "platform/ThreadSafeFunctional.h" | 17 #include "platform/ThreadSafeFunctional.h" |
| 18 #include "platform/TraceEvent.h" | 18 #include "platform/TraceEvent.h" |
| 19 #include "public/platform/WebScheduler.h" | 19 #include "public/platform/WebScheduler.h" |
| 20 #include "wtf/Deque.h" | 20 #include "wtf/Deque.h" |
| 21 #include "wtf/PtrUtil.h" | |
| 22 #include "wtf/text/TextEncodingRegistry.h" | 21 #include "wtf/text/TextEncodingRegistry.h" |
| 23 #include <memory> | |
| 24 | 22 |
| 25 namespace blink { | 23 namespace blink { |
| 26 | 24 |
| 27 namespace { | 25 namespace { |
| 28 | 26 |
| 29 void recordStartedStreamingHistogram(ScriptStreamer::Type scriptType, int reason
) | 27 void recordStartedStreamingHistogram(ScriptStreamer::Type scriptType, int reason
) |
| 30 { | 28 { |
| 31 switch (scriptType) { | 29 switch (scriptType) { |
| 32 case ScriptStreamer::ParsingBlocking: { | 30 case ScriptStreamer::ParsingBlocking: { |
| 33 DEFINE_STATIC_LOCAL(EnumerationHistogram, parseBlockingHistogram, ("WebC
ore.Scripts.ParsingBlocking.StartedStreaming", 2)); | 31 DEFINE_STATIC_LOCAL(EnumerationHistogram, parseBlockingHistogram, ("WebC
ore.Scripts.ParsingBlocking.StartedStreaming", 2)); |
| (...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 174 WTF_MAKE_NONCOPYABLE(SourceStream); | 172 WTF_MAKE_NONCOPYABLE(SourceStream); |
| 175 public: | 173 public: |
| 176 explicit SourceStream(WebTaskRunner* loadingTaskRunner) | 174 explicit SourceStream(WebTaskRunner* loadingTaskRunner) |
| 177 : v8::ScriptCompiler::ExternalSourceStream() | 175 : v8::ScriptCompiler::ExternalSourceStream() |
| 178 , m_cancelled(false) | 176 , m_cancelled(false) |
| 179 , m_finished(false) | 177 , m_finished(false) |
| 180 , m_queueLeadPosition(0) | 178 , m_queueLeadPosition(0) |
| 181 , m_queueTailPosition(0) | 179 , m_queueTailPosition(0) |
| 182 , m_bookmarkPosition(0) | 180 , m_bookmarkPosition(0) |
| 183 , m_lengthOfBOM(0) | 181 , m_lengthOfBOM(0) |
| 184 , m_loadingTaskRunner(wrapUnique(loadingTaskRunner->clone())) | 182 , m_loadingTaskRunner(adoptPtr(loadingTaskRunner->clone())) |
| 185 { | 183 { |
| 186 } | 184 } |
| 187 | 185 |
| 188 virtual ~SourceStream() override { } | 186 virtual ~SourceStream() override { } |
| 189 | 187 |
| 190 // Called by V8 on a background thread. Should block until we can return | 188 // Called by V8 on a background thread. Should block until we can return |
| 191 // some data. | 189 // some data. |
| 192 size_t GetMoreData(const uint8_t** src) override | 190 size_t GetMoreData(const uint8_t** src) override |
| 193 { | 191 { |
| 194 ASSERT(!isMainThread()); | 192 ASSERT(!isMainThread()); |
| (...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 382 // (i.e., without BOM) | 380 // (i.e., without BOM) |
| 383 // - m_queueTailPosition counts the bytes that Chrome has sent | 381 // - m_queueTailPosition counts the bytes that Chrome has sent |
| 384 // (i.e., with BOM) | 382 // (i.e., with BOM) |
| 385 // So when resetting the bookmark, we have to adjust the lead position | 383 // So when resetting the bookmark, we have to adjust the lead position |
| 386 // to account for the BOM (which happens implicitly in the regular | 384 // to account for the BOM (which happens implicitly in the regular |
| 387 // streaming case). | 385 // streaming case). |
| 388 // We store this separately, to avoid having to guard all | 386 // We store this separately, to avoid having to guard all |
| 389 // m_queueLeadPosition references with a mutex. | 387 // m_queueLeadPosition references with a mutex. |
| 390 size_t m_lengthOfBOM; // Used by both threads; guarded by m_mutex. | 388 size_t m_lengthOfBOM; // Used by both threads; guarded by m_mutex. |
| 391 | 389 |
| 392 std::unique_ptr<WebTaskRunner> m_loadingTaskRunner; | 390 OwnPtr<WebTaskRunner> m_loadingTaskRunner; |
| 393 }; | 391 }; |
| 394 | 392 |
| 395 size_t ScriptStreamer::s_smallScriptThreshold = 30 * 1024; | 393 size_t ScriptStreamer::s_smallScriptThreshold = 30 * 1024; |
| 396 | 394 |
| 397 void ScriptStreamer::startStreaming(PendingScript* script, Type scriptType, Sett
ings* settings, ScriptState* scriptState, WebTaskRunner* loadingTaskRunner) | 395 void ScriptStreamer::startStreaming(PendingScript* script, Type scriptType, Sett
ings* settings, ScriptState* scriptState, WebTaskRunner* loadingTaskRunner) |
| 398 { | 396 { |
| 399 // We don't yet know whether the script will really be streamed. E.g., | 397 // We don't yet know whether the script will really be streamed. E.g., |
| 400 // suppressing streaming for short scripts is done later. Record only the | 398 // suppressing streaming for short scripts is done later. Record only the |
| 401 // sure negative cases here. | 399 // sure negative cases here. |
| 402 bool startedStreaming = startStreamingInternal(script, scriptType, settings,
scriptState, loadingTaskRunner); | 400 bool startedStreaming = startStreamingInternal(script, scriptType, settings,
scriptState, loadingTaskRunner); |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 495 // possible that resource->encoding() returns a different encoding | 493 // possible that resource->encoding() returns a different encoding |
| 496 // before the loading has started and after we got some data. In | 494 // before the loading has started and after we got some data. In |
| 497 // addition, check for byte order marks. Note that checking the byte | 495 // addition, check for byte order marks. Note that checking the byte |
| 498 // order mark might change the encoding. We cannot decode the full text | 496 // order mark might change the encoding. We cannot decode the full text |
| 499 // here, because it might contain incomplete UTF-8 characters. Also note | 497 // here, because it might contain incomplete UTF-8 characters. Also note |
| 500 // that have at least s_smallScriptThreshold worth of data, which is mor
e | 498 // that have at least s_smallScriptThreshold worth of data, which is mor
e |
| 501 // than enough for detecting a BOM. | 499 // than enough for detecting a BOM. |
| 502 const char* data = 0; | 500 const char* data = 0; |
| 503 size_t length = resource->resourceBuffer()->getSomeData(data, static_cas
t<size_t>(0)); | 501 size_t length = resource->resourceBuffer()->getSomeData(data, static_cas
t<size_t>(0)); |
| 504 | 502 |
| 505 std::unique_ptr<TextResourceDecoder> decoder(TextResourceDecoder::create
("application/javascript", resource->encoding())); | 503 OwnPtr<TextResourceDecoder> decoder(TextResourceDecoder::create("applica
tion/javascript", resource->encoding())); |
| 506 lengthOfBOM = decoder->checkForBOM(data, length); | 504 lengthOfBOM = decoder->checkForBOM(data, length); |
| 507 | 505 |
| 508 // Maybe the encoding changed because we saw the BOM; get the encoding | 506 // Maybe the encoding changed because we saw the BOM; get the encoding |
| 509 // from the decoder. | 507 // from the decoder. |
| 510 if (!convertEncoding(decoder->encoding().name(), &m_encoding)) { | 508 if (!convertEncoding(decoder->encoding().name(), &m_encoding)) { |
| 511 suppressStreaming(); | 509 suppressStreaming(); |
| 512 recordNotStreamingReasonHistogram(m_scriptType, EncodingNotSupported
); | 510 recordNotStreamingReasonHistogram(m_scriptType, EncodingNotSupported
); |
| 513 recordStartedStreamingHistogram(m_scriptType, 0); | 511 recordStartedStreamingHistogram(m_scriptType, 0); |
| 514 return; | 512 return; |
| 515 } | 513 } |
| (...skipping 12 matching lines...) Expand all Loading... |
| 528 suppressStreaming(); | 526 suppressStreaming(); |
| 529 recordNotStreamingReasonHistogram(m_scriptType, ContextNotValid); | 527 recordNotStreamingReasonHistogram(m_scriptType, ContextNotValid); |
| 530 recordStartedStreamingHistogram(m_scriptType, 0); | 528 recordStartedStreamingHistogram(m_scriptType, 0); |
| 531 return; | 529 return; |
| 532 } | 530 } |
| 533 | 531 |
| 534 ASSERT(!m_stream); | 532 ASSERT(!m_stream); |
| 535 ASSERT(!m_source); | 533 ASSERT(!m_source); |
| 536 m_stream = new SourceStream(m_loadingTaskRunner.get()); | 534 m_stream = new SourceStream(m_loadingTaskRunner.get()); |
| 537 // m_source takes ownership of m_stream. | 535 // m_source takes ownership of m_stream. |
| 538 m_source = wrapUnique(new v8::ScriptCompiler::StreamedSource(m_stream, m
_encoding)); | 536 m_source = adoptPtr(new v8::ScriptCompiler::StreamedSource(m_stream, m_e
ncoding)); |
| 539 | 537 |
| 540 ScriptState::Scope scope(m_scriptState.get()); | 538 ScriptState::Scope scope(m_scriptState.get()); |
| 541 std::unique_ptr<v8::ScriptCompiler::ScriptStreamingTask> scriptStreaming
Task(wrapUnique(v8::ScriptCompiler::StartStreamingScript(m_scriptState->isolate(
), m_source.get(), m_compileOptions))); | 539 OwnPtr<v8::ScriptCompiler::ScriptStreamingTask> scriptStreamingTask(adop
tPtr(v8::ScriptCompiler::StartStreamingScript(m_scriptState->isolate(), m_source
.get(), m_compileOptions))); |
| 542 if (!scriptStreamingTask) { | 540 if (!scriptStreamingTask) { |
| 543 // V8 cannot stream the script. | 541 // V8 cannot stream the script. |
| 544 suppressStreaming(); | 542 suppressStreaming(); |
| 545 m_stream = 0; | 543 m_stream = 0; |
| 546 m_source.reset(); | 544 m_source.reset(); |
| 547 recordNotStreamingReasonHistogram(m_scriptType, V8CannotStream); | 545 recordNotStreamingReasonHistogram(m_scriptType, V8CannotStream); |
| 548 recordStartedStreamingHistogram(m_scriptType, 0); | 546 recordStartedStreamingHistogram(m_scriptType, 0); |
| 549 return; | 547 return; |
| 550 } | 548 } |
| 551 | 549 |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 584 , m_loadingFinished(false) | 582 , m_loadingFinished(false) |
| 585 , m_parsingFinished(false) | 583 , m_parsingFinished(false) |
| 586 , m_haveEnoughDataForStreaming(false) | 584 , m_haveEnoughDataForStreaming(false) |
| 587 , m_streamingSuppressed(false) | 585 , m_streamingSuppressed(false) |
| 588 , m_compileOptions(compileOptions) | 586 , m_compileOptions(compileOptions) |
| 589 , m_scriptState(scriptState) | 587 , m_scriptState(scriptState) |
| 590 , m_scriptType(scriptType) | 588 , m_scriptType(scriptType) |
| 591 , m_scriptURLString(m_resource->url().copy().getString()) | 589 , m_scriptURLString(m_resource->url().copy().getString()) |
| 592 , m_scriptResourceIdentifier(m_resource->identifier()) | 590 , m_scriptResourceIdentifier(m_resource->identifier()) |
| 593 , 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. | 591 , 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. |
| 594 , m_loadingTaskRunner(wrapUnique(loadingTaskRunner->clone())) | 592 , m_loadingTaskRunner(adoptPtr(loadingTaskRunner->clone())) |
| 595 { | 593 { |
| 596 } | 594 } |
| 597 | 595 |
| 598 ScriptStreamer::~ScriptStreamer() | 596 ScriptStreamer::~ScriptStreamer() |
| 599 { | 597 { |
| 600 } | 598 } |
| 601 | 599 |
| 602 DEFINE_TRACE(ScriptStreamer) | 600 DEFINE_TRACE(ScriptStreamer) |
| 603 { | 601 { |
| 604 visitor->trace(m_pendingScript); | 602 visitor->trace(m_pendingScript); |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 674 | 672 |
| 675 // The Resource might go out of scope if the script is no longer | 673 // The Resource might go out of scope if the script is no longer |
| 676 // needed. This makes PendingScript notify the ScriptStreamer when it is | 674 // needed. This makes PendingScript notify the ScriptStreamer when it is |
| 677 // destroyed. | 675 // destroyed. |
| 678 script->setStreamer(ScriptStreamer::create(script, scriptType, scriptState,
compileOption, loadingTaskRunner)); | 676 script->setStreamer(ScriptStreamer::create(script, scriptType, scriptState,
compileOption, loadingTaskRunner)); |
| 679 | 677 |
| 680 return true; | 678 return true; |
| 681 } | 679 } |
| 682 | 680 |
| 683 } // namespace blink | 681 } // namespace blink |
| OLD | NEW |