| 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 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 516 m_loadingFinished = true; | 516 m_loadingFinished = true; |
| 517 | 517 |
| 518 notifyFinishedToClient(); | 518 notifyFinishedToClient(); |
| 519 } | 519 } |
| 520 | 520 |
| 521 ScriptStreamer::ScriptStreamer( | 521 ScriptStreamer::ScriptStreamer( |
| 522 PendingScript* script, | 522 PendingScript* script, |
| 523 Type scriptType, | 523 Type scriptType, |
| 524 ScriptState* scriptState, | 524 ScriptState* scriptState, |
| 525 v8::ScriptCompiler::CompileOptions compileOptions, | 525 v8::ScriptCompiler::CompileOptions compileOptions, |
| 526 WebTaskRunner* loadingTaskRunner) | 526 RefPtr<WebTaskRunner> loadingTaskRunner) |
| 527 : m_pendingScript(script), | 527 : m_pendingScript(script), |
| 528 m_resource(script->resource()), | 528 m_resource(script->resource()), |
| 529 m_detached(false), | 529 m_detached(false), |
| 530 m_stream(0), | 530 m_stream(0), |
| 531 m_loadingFinished(false), | 531 m_loadingFinished(false), |
| 532 m_parsingFinished(false), | 532 m_parsingFinished(false), |
| 533 m_haveEnoughDataForStreaming(false), | 533 m_haveEnoughDataForStreaming(false), |
| 534 m_streamingSuppressed(false), | 534 m_streamingSuppressed(false), |
| 535 m_compileOptions(compileOptions), | 535 m_compileOptions(compileOptions), |
| 536 m_scriptState(scriptState), | 536 m_scriptState(scriptState), |
| 537 m_scriptType(scriptType), | 537 m_scriptType(scriptType), |
| 538 m_scriptURLString(m_resource->url().copy().getString()), | 538 m_scriptURLString(m_resource->url().copy().getString()), |
| 539 m_scriptResourceIdentifier(m_resource->identifier()), | 539 m_scriptResourceIdentifier(m_resource->identifier()), |
| 540 // Unfortunately there's no dummy encoding value in the enum; let's use | 540 // Unfortunately there's no dummy encoding value in the enum; let's use |
| 541 // one we don't stream. | 541 // one we don't stream. |
| 542 m_encoding(v8::ScriptCompiler::StreamedSource::TWO_BYTE), | 542 m_encoding(v8::ScriptCompiler::StreamedSource::TWO_BYTE), |
| 543 m_loadingTaskRunner(loadingTaskRunner->clone()) {} | 543 m_loadingTaskRunner(std::move(loadingTaskRunner)) {} |
| 544 | 544 |
| 545 ScriptStreamer::~ScriptStreamer() {} | 545 ScriptStreamer::~ScriptStreamer() {} |
| 546 | 546 |
| 547 DEFINE_TRACE(ScriptStreamer) { | 547 DEFINE_TRACE(ScriptStreamer) { |
| 548 visitor->trace(m_pendingScript); | 548 visitor->trace(m_pendingScript); |
| 549 visitor->trace(m_resource); | 549 visitor->trace(m_resource); |
| 550 } | 550 } |
| 551 | 551 |
| 552 void ScriptStreamer::streamingComplete() { | 552 void ScriptStreamer::streamingComplete() { |
| 553 // The background task is completed; do the necessary ramp-down in the main | 553 // The background task is completed; do the necessary ramp-down in the main |
| (...skipping 23 matching lines...) Expand all Loading... |
| 577 // completed. Here we also check that we have a client: it can happen that a | 577 // completed. Here we also check that we have a client: it can happen that a |
| 578 // function calling notifyFinishedToClient was already scheduled in the task | 578 // function calling notifyFinishedToClient was already scheduled in the task |
| 579 // queue and the upper layer decided that it's not interested in the script | 579 // queue and the upper layer decided that it's not interested in the script |
| 580 // and called removeClient. | 580 // and called removeClient. |
| 581 if (!isFinished()) | 581 if (!isFinished()) |
| 582 return; | 582 return; |
| 583 | 583 |
| 584 m_pendingScript->streamingFinished(); | 584 m_pendingScript->streamingFinished(); |
| 585 } | 585 } |
| 586 | 586 |
| 587 bool ScriptStreamer::startStreamingInternal(PendingScript* script, | 587 bool ScriptStreamer::startStreamingInternal( |
| 588 Type scriptType, | 588 PendingScript* script, |
| 589 Settings* settings, | 589 Type scriptType, |
| 590 ScriptState* scriptState, | 590 Settings* settings, |
| 591 WebTaskRunner* loadingTaskRunner) { | 591 ScriptState* scriptState, |
| 592 RefPtr<WebTaskRunner> loadingTaskRunner) { |
| 592 DCHECK(isMainThread()); | 593 DCHECK(isMainThread()); |
| 593 DCHECK(scriptState->contextIsValid()); | 594 DCHECK(scriptState->contextIsValid()); |
| 594 ScriptResource* resource = script->resource(); | 595 ScriptResource* resource = script->resource(); |
| 595 if (resource->isLoaded()) { | 596 if (resource->isLoaded()) { |
| 596 recordNotStreamingReasonHistogram(scriptType, AlreadyLoaded); | 597 recordNotStreamingReasonHistogram(scriptType, AlreadyLoaded); |
| 597 return false; | 598 return false; |
| 598 } | 599 } |
| 599 if (!resource->url().protocolIsInHTTPFamily()) { | 600 if (!resource->url().protocolIsInHTTPFamily()) { |
| 600 recordNotStreamingReasonHistogram(scriptType, NotHTTP); | 601 recordNotStreamingReasonHistogram(scriptType, NotHTTP); |
| 601 return false; | 602 return false; |
| (...skipping 13 matching lines...) Expand all Loading... |
| 615 // produce parser cache if the non-streaming compile takes advantage of it. | 616 // produce parser cache if the non-streaming compile takes advantage of it. |
| 616 v8::ScriptCompiler::CompileOptions compileOption = | 617 v8::ScriptCompiler::CompileOptions compileOption = |
| 617 v8::ScriptCompiler::kNoCompileOptions; | 618 v8::ScriptCompiler::kNoCompileOptions; |
| 618 if (settings->getV8CacheOptions() == V8CacheOptionsParse) | 619 if (settings->getV8CacheOptions() == V8CacheOptionsParse) |
| 619 compileOption = v8::ScriptCompiler::kProduceParserCache; | 620 compileOption = v8::ScriptCompiler::kProduceParserCache; |
| 620 | 621 |
| 621 // The Resource might go out of scope if the script is no longer | 622 // The Resource might go out of scope if the script is no longer |
| 622 // needed. This makes PendingScript notify the ScriptStreamer when it is | 623 // needed. This makes PendingScript notify the ScriptStreamer when it is |
| 623 // destroyed. | 624 // destroyed. |
| 624 script->setStreamer(ScriptStreamer::create(script, scriptType, scriptState, | 625 script->setStreamer(ScriptStreamer::create(script, scriptType, scriptState, |
| 625 compileOption, loadingTaskRunner)); | 626 compileOption, |
| 627 std::move(loadingTaskRunner))); |
| 626 | 628 |
| 627 return true; | 629 return true; |
| 628 } | 630 } |
| 629 | 631 |
| 630 } // namespace blink | 632 } // namespace blink |
| OLD | NEW |