| 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" |
| (...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 168 }; | 168 }; |
| 169 | 169 |
| 170 // SourceStream implements the streaming interface towards V8. The main | 170 // SourceStream implements the streaming interface towards V8. The main |
| 171 // functionality is preparing the data to give to V8 on main thread, and | 171 // functionality is preparing the data to give to V8 on main thread, and |
| 172 // actually giving the data (via GetMoreData which is called on a background | 172 // actually giving the data (via GetMoreData which is called on a background |
| 173 // thread). | 173 // thread). |
| 174 class SourceStream : public v8::ScriptCompiler::ExternalSourceStream { | 174 class SourceStream : public v8::ScriptCompiler::ExternalSourceStream { |
| 175 WTF_MAKE_NONCOPYABLE(SourceStream); | 175 WTF_MAKE_NONCOPYABLE(SourceStream); |
| 176 | 176 |
| 177 public: | 177 public: |
| 178 explicit SourceStream(WebTaskRunner* loadingTaskRunner) | 178 explicit SourceStream(RefPtr<WebTaskRunner> loadingTaskRunner) |
| 179 : v8::ScriptCompiler::ExternalSourceStream(), | 179 : v8::ScriptCompiler::ExternalSourceStream(), |
| 180 m_cancelled(false), | 180 m_cancelled(false), |
| 181 m_finished(false), | 181 m_finished(false), |
| 182 m_queueLeadPosition(0), | 182 m_queueLeadPosition(0), |
| 183 m_queueTailPosition(0), | 183 m_queueTailPosition(0), |
| 184 m_loadingTaskRunner(loadingTaskRunner->clone()) {} | 184 m_loadingTaskRunner(std::move(loadingTaskRunner)) {} |
| 185 | 185 |
| 186 virtual ~SourceStream() override {} | 186 virtual ~SourceStream() override {} |
| 187 | 187 |
| 188 // 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 |
| 189 // some data. | 189 // some data. |
| 190 size_t GetMoreData(const uint8_t** src) override { | 190 size_t GetMoreData(const uint8_t** src) override { |
| 191 DCHECK(!isMainThread()); | 191 DCHECK(!isMainThread()); |
| 192 { | 192 { |
| 193 MutexLocker locker(m_mutex); | 193 MutexLocker locker(m_mutex); |
| 194 if (m_cancelled) | 194 if (m_cancelled) |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 310 RefPtr<const SharedBuffer> m_resourceBuffer; // Only used by the main thread. | 310 RefPtr<const SharedBuffer> m_resourceBuffer; // Only used by the main thread. |
| 311 | 311 |
| 312 // The queue contains the data to be passed to the V8 thread. | 312 // The queue contains the data to be passed to the V8 thread. |
| 313 // queueLeadPosition: data we have handed off to the V8 thread. | 313 // queueLeadPosition: data we have handed off to the V8 thread. |
| 314 // queueTailPosition: end of data we have enqued in the queue. | 314 // queueTailPosition: end of data we have enqued in the queue. |
| 315 // bookmarkPosition: position of the bookmark. | 315 // bookmarkPosition: position of the bookmark. |
| 316 SourceStreamDataQueue m_dataQueue; // Thread safe. | 316 SourceStreamDataQueue m_dataQueue; // Thread safe. |
| 317 size_t m_queueLeadPosition; // Only used by v8 thread. | 317 size_t m_queueLeadPosition; // Only used by v8 thread. |
| 318 size_t m_queueTailPosition; // Used by both threads; guarded by m_mutex. | 318 size_t m_queueTailPosition; // Used by both threads; guarded by m_mutex. |
| 319 | 319 |
| 320 std::unique_ptr<WebTaskRunner> m_loadingTaskRunner; | 320 RefPtr<WebTaskRunner> m_loadingTaskRunner; |
| 321 }; | 321 }; |
| 322 | 322 |
| 323 size_t ScriptStreamer::s_smallScriptThreshold = 30 * 1024; | 323 size_t ScriptStreamer::s_smallScriptThreshold = 30 * 1024; |
| 324 | 324 |
| 325 void ScriptStreamer::startStreaming(PendingScript* script, | 325 void ScriptStreamer::startStreaming(PendingScript* script, |
| 326 Type scriptType, | 326 Type scriptType, |
| 327 Settings* settings, | 327 Settings* settings, |
| 328 ScriptState* scriptState, | 328 ScriptState* scriptState, |
| 329 WebTaskRunner* loadingTaskRunner) { | 329 RefPtr<WebTaskRunner> loadingTaskRunner) { |
| 330 // We don't yet know whether the script will really be streamed. E.g., | 330 // We don't yet know whether the script will really be streamed. E.g., |
| 331 // suppressing streaming for short scripts is done later. Record only the | 331 // suppressing streaming for short scripts is done later. Record only the |
| 332 // sure negative cases here. | 332 // sure negative cases here. |
| 333 bool startedStreaming = startStreamingInternal( | 333 bool startedStreaming = startStreamingInternal( |
| 334 script, scriptType, settings, scriptState, loadingTaskRunner); | 334 script, scriptType, settings, scriptState, std::move(loadingTaskRunner)); |
| 335 if (!startedStreaming) | 335 if (!startedStreaming) |
| 336 recordStartedStreamingHistogram(scriptType, 0); | 336 recordStartedStreamingHistogram(scriptType, 0); |
| 337 } | 337 } |
| 338 | 338 |
| 339 bool ScriptStreamer::convertEncoding( | 339 bool ScriptStreamer::convertEncoding( |
| 340 const char* encodingName, | 340 const char* encodingName, |
| 341 v8::ScriptCompiler::StreamedSource::Encoding* encoding) { | 341 v8::ScriptCompiler::StreamedSource::Encoding* encoding) { |
| 342 // Here's a list of encodings we can use for streaming. These are | 342 // Here's a list of encodings we can use for streaming. These are |
| 343 // the canonical names. | 343 // the canonical names. |
| 344 if (strcmp(encodingName, "windows-1252") == 0 || | 344 if (strcmp(encodingName, "windows-1252") == 0 || |
| (...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 515 m_loadingFinished = true; | 515 m_loadingFinished = true; |
| 516 | 516 |
| 517 notifyFinishedToClient(); | 517 notifyFinishedToClient(); |
| 518 } | 518 } |
| 519 | 519 |
| 520 ScriptStreamer::ScriptStreamer( | 520 ScriptStreamer::ScriptStreamer( |
| 521 PendingScript* script, | 521 PendingScript* script, |
| 522 Type scriptType, | 522 Type scriptType, |
| 523 ScriptState* scriptState, | 523 ScriptState* scriptState, |
| 524 v8::ScriptCompiler::CompileOptions compileOptions, | 524 v8::ScriptCompiler::CompileOptions compileOptions, |
| 525 WebTaskRunner* loadingTaskRunner) | 525 RefPtr<WebTaskRunner> loadingTaskRunner) |
| 526 : m_pendingScript(script), | 526 : m_pendingScript(script), |
| 527 m_resource(script->resource()), | 527 m_resource(script->resource()), |
| 528 m_detached(false), | 528 m_detached(false), |
| 529 m_stream(0), | 529 m_stream(0), |
| 530 m_loadingFinished(false), | 530 m_loadingFinished(false), |
| 531 m_parsingFinished(false), | 531 m_parsingFinished(false), |
| 532 m_haveEnoughDataForStreaming(false), | 532 m_haveEnoughDataForStreaming(false), |
| 533 m_streamingSuppressed(false), | 533 m_streamingSuppressed(false), |
| 534 m_compileOptions(compileOptions), | 534 m_compileOptions(compileOptions), |
| 535 m_scriptState(scriptState), | 535 m_scriptState(scriptState), |
| 536 m_scriptType(scriptType), | 536 m_scriptType(scriptType), |
| 537 m_scriptURLString(m_resource->url().copy().getString()), | 537 m_scriptURLString(m_resource->url().copy().getString()), |
| 538 m_scriptResourceIdentifier(m_resource->identifier()), | 538 m_scriptResourceIdentifier(m_resource->identifier()), |
| 539 // Unfortunately there's no dummy encoding value in the enum; let's use | 539 // Unfortunately there's no dummy encoding value in the enum; let's use |
| 540 // one we don't stream. | 540 // one we don't stream. |
| 541 m_encoding(v8::ScriptCompiler::StreamedSource::TWO_BYTE), | 541 m_encoding(v8::ScriptCompiler::StreamedSource::TWO_BYTE), |
| 542 m_loadingTaskRunner(loadingTaskRunner->clone()) {} | 542 m_loadingTaskRunner(std::move(loadingTaskRunner)) {} |
| 543 | 543 |
| 544 ScriptStreamer::~ScriptStreamer() {} | 544 ScriptStreamer::~ScriptStreamer() {} |
| 545 | 545 |
| 546 DEFINE_TRACE(ScriptStreamer) { | 546 DEFINE_TRACE(ScriptStreamer) { |
| 547 visitor->trace(m_pendingScript); | 547 visitor->trace(m_pendingScript); |
| 548 visitor->trace(m_resource); | 548 visitor->trace(m_resource); |
| 549 } | 549 } |
| 550 | 550 |
| 551 void ScriptStreamer::streamingComplete() { | 551 void ScriptStreamer::streamingComplete() { |
| 552 // The background task is completed; do the necessary ramp-down in the main | 552 // The background task is completed; do the necessary ramp-down in the main |
| (...skipping 23 matching lines...) Expand all Loading... |
| 576 // completed. Here we also check that we have a client: it can happen that a | 576 // completed. Here we also check that we have a client: it can happen that a |
| 577 // function calling notifyFinishedToClient was already scheduled in the task | 577 // function calling notifyFinishedToClient was already scheduled in the task |
| 578 // queue and the upper layer decided that it's not interested in the script | 578 // queue and the upper layer decided that it's not interested in the script |
| 579 // and called removeClient. | 579 // and called removeClient. |
| 580 if (!isFinished()) | 580 if (!isFinished()) |
| 581 return; | 581 return; |
| 582 | 582 |
| 583 m_pendingScript->streamingFinished(); | 583 m_pendingScript->streamingFinished(); |
| 584 } | 584 } |
| 585 | 585 |
| 586 bool ScriptStreamer::startStreamingInternal(PendingScript* script, | 586 bool ScriptStreamer::startStreamingInternal( |
| 587 Type scriptType, | 587 PendingScript* script, |
| 588 Settings* settings, | 588 Type scriptType, |
| 589 ScriptState* scriptState, | 589 Settings* settings, |
| 590 WebTaskRunner* loadingTaskRunner) { | 590 ScriptState* scriptState, |
| 591 RefPtr<WebTaskRunner> loadingTaskRunner) { |
| 591 DCHECK(isMainThread()); | 592 DCHECK(isMainThread()); |
| 592 DCHECK(scriptState->contextIsValid()); | 593 DCHECK(scriptState->contextIsValid()); |
| 593 ScriptResource* resource = script->resource(); | 594 ScriptResource* resource = script->resource(); |
| 594 if (resource->isLoaded()) { | 595 if (resource->isLoaded()) { |
| 595 recordNotStreamingReasonHistogram(scriptType, AlreadyLoaded); | 596 recordNotStreamingReasonHistogram(scriptType, AlreadyLoaded); |
| 596 return false; | 597 return false; |
| 597 } | 598 } |
| 598 if (!resource->url().protocolIsInHTTPFamily()) { | 599 if (!resource->url().protocolIsInHTTPFamily()) { |
| 599 recordNotStreamingReasonHistogram(scriptType, NotHTTP); | 600 recordNotStreamingReasonHistogram(scriptType, NotHTTP); |
| 600 return false; | 601 return false; |
| (...skipping 13 matching lines...) Expand all Loading... |
| 614 // produce parser cache if the non-streaming compile takes advantage of it. | 615 // produce parser cache if the non-streaming compile takes advantage of it. |
| 615 v8::ScriptCompiler::CompileOptions compileOption = | 616 v8::ScriptCompiler::CompileOptions compileOption = |
| 616 v8::ScriptCompiler::kNoCompileOptions; | 617 v8::ScriptCompiler::kNoCompileOptions; |
| 617 if (settings->v8CacheOptions() == V8CacheOptionsParse) | 618 if (settings->v8CacheOptions() == V8CacheOptionsParse) |
| 618 compileOption = v8::ScriptCompiler::kProduceParserCache; | 619 compileOption = v8::ScriptCompiler::kProduceParserCache; |
| 619 | 620 |
| 620 // The Resource might go out of scope if the script is no longer | 621 // The Resource might go out of scope if the script is no longer |
| 621 // needed. This makes PendingScript notify the ScriptStreamer when it is | 622 // needed. This makes PendingScript notify the ScriptStreamer when it is |
| 622 // destroyed. | 623 // destroyed. |
| 623 script->setStreamer(ScriptStreamer::create(script, scriptType, scriptState, | 624 script->setStreamer(ScriptStreamer::create(script, scriptType, scriptState, |
| 624 compileOption, loadingTaskRunner)); | 625 compileOption, |
| 626 std::move(loadingTaskRunner))); |
| 625 | 627 |
| 626 return true; | 628 return true; |
| 627 } | 629 } |
| 628 | 630 |
| 629 } // namespace blink | 631 } // namespace blink |
| OLD | NEW |