| Index: third_party/WebKit/Source/bindings/core/v8/ScriptStreamer.cpp
|
| diff --git a/third_party/WebKit/Source/bindings/core/v8/ScriptStreamer.cpp b/third_party/WebKit/Source/bindings/core/v8/ScriptStreamer.cpp
|
| deleted file mode 100644
|
| index b60b02b9cf4110718e8006e4e30cff44e567b863..0000000000000000000000000000000000000000
|
| --- a/third_party/WebKit/Source/bindings/core/v8/ScriptStreamer.cpp
|
| +++ /dev/null
|
| @@ -1,628 +0,0 @@
|
| -// Copyright 2014 The Chromium Authors. All rights reserved.
|
| -// Use of this source code is governed by a BSD-style license that can be
|
| -// found in the LICENSE file.
|
| -
|
| -#include "bindings/core/v8/ScriptStreamer.h"
|
| -
|
| -#include <memory>
|
| -#include "bindings/core/v8/ScriptStreamerThread.h"
|
| -#include "bindings/core/v8/V8ScriptRunner.h"
|
| -#include "core/dom/Document.h"
|
| -#include "core/dom/Element.h"
|
| -#include "core/dom/PendingScript.h"
|
| -#include "core/frame/Settings.h"
|
| -#include "core/html/parser/TextResourceDecoder.h"
|
| -#include "core/loader/resource/ScriptResource.h"
|
| -#include "platform/CrossThreadFunctional.h"
|
| -#include "platform/Histogram.h"
|
| -#include "platform/SharedBuffer.h"
|
| -#include "platform/instrumentation/tracing/TraceEvent.h"
|
| -#include "platform/loader/fetch/CachedMetadata.h"
|
| -#include "platform/wtf/Deque.h"
|
| -#include "platform/wtf/PtrUtil.h"
|
| -#include "platform/wtf/text/TextEncodingRegistry.h"
|
| -#include "public/platform/WebScheduler.h"
|
| -
|
| -namespace blink {
|
| -
|
| -namespace {
|
| -
|
| -void RecordStartedStreamingHistogram(ScriptStreamer::Type script_type,
|
| - int reason) {
|
| - switch (script_type) {
|
| - case ScriptStreamer::kParsingBlocking: {
|
| - DEFINE_STATIC_LOCAL(
|
| - EnumerationHistogram, parse_blocking_histogram,
|
| - ("WebCore.Scripts.ParsingBlocking.StartedStreaming", 2));
|
| - parse_blocking_histogram.Count(reason);
|
| - break;
|
| - }
|
| - case ScriptStreamer::kDeferred: {
|
| - DEFINE_STATIC_LOCAL(EnumerationHistogram, deferred_histogram,
|
| - ("WebCore.Scripts.Deferred.StartedStreaming", 2));
|
| - deferred_histogram.Count(reason);
|
| - break;
|
| - }
|
| - case ScriptStreamer::kAsync: {
|
| - DEFINE_STATIC_LOCAL(EnumerationHistogram, async_histogram,
|
| - ("WebCore.Scripts.Async.StartedStreaming", 2));
|
| - async_histogram.Count(reason);
|
| - break;
|
| - }
|
| - default:
|
| - NOTREACHED();
|
| - break;
|
| - }
|
| -}
|
| -
|
| -// For tracking why some scripts are not streamed. Not streaming is part of
|
| -// normal operation (e.g., script already loaded, script too small) and doesn't
|
| -// necessarily indicate a failure.
|
| -enum NotStreamingReason {
|
| - kAlreadyLoaded,
|
| - kNotHTTP,
|
| - kReload,
|
| - kContextNotValid,
|
| - kEncodingNotSupported,
|
| - kThreadBusy,
|
| - kV8CannotStream,
|
| - kScriptTooSmall,
|
| - kNotStreamingReasonEnd
|
| -};
|
| -
|
| -void RecordNotStreamingReasonHistogram(ScriptStreamer::Type script_type,
|
| - NotStreamingReason reason) {
|
| - switch (script_type) {
|
| - case ScriptStreamer::kParsingBlocking: {
|
| - DEFINE_STATIC_LOCAL(EnumerationHistogram, parse_blocking_histogram,
|
| - ("WebCore.Scripts.ParsingBlocking.NotStreamingReason",
|
| - kNotStreamingReasonEnd));
|
| - parse_blocking_histogram.Count(reason);
|
| - break;
|
| - }
|
| - case ScriptStreamer::kDeferred: {
|
| - DEFINE_STATIC_LOCAL(EnumerationHistogram, deferred_histogram,
|
| - ("WebCore.Scripts.Deferred.NotStreamingReason",
|
| - kNotStreamingReasonEnd));
|
| - deferred_histogram.Count(reason);
|
| - break;
|
| - }
|
| - case ScriptStreamer::kAsync: {
|
| - DEFINE_STATIC_LOCAL(
|
| - EnumerationHistogram, async_histogram,
|
| - ("WebCore.Scripts.Async.NotStreamingReason", kNotStreamingReasonEnd));
|
| - async_histogram.Count(reason);
|
| - break;
|
| - }
|
| - default:
|
| - NOTREACHED();
|
| - break;
|
| - }
|
| -}
|
| -
|
| -} // namespace
|
| -
|
| -// For passing data between the main thread (producer) and the streamer thread
|
| -// (consumer). The main thread prepares the data (copies it from Resource) and
|
| -// the streamer thread feeds it to V8.
|
| -class SourceStreamDataQueue {
|
| - WTF_MAKE_NONCOPYABLE(SourceStreamDataQueue);
|
| -
|
| - public:
|
| - SourceStreamDataQueue() : finished_(false) {}
|
| -
|
| - ~SourceStreamDataQueue() { DiscardQueuedData(); }
|
| -
|
| - void Clear() {
|
| - MutexLocker locker(mutex_);
|
| - finished_ = false;
|
| - DiscardQueuedData();
|
| - }
|
| -
|
| - void Produce(const uint8_t* data, size_t length) {
|
| - MutexLocker locker(mutex_);
|
| - DCHECK(!finished_);
|
| - data_.push_back(std::make_pair(data, length));
|
| - have_data_.Signal();
|
| - }
|
| -
|
| - void Finish() {
|
| - MutexLocker locker(mutex_);
|
| - finished_ = true;
|
| - have_data_.Signal();
|
| - }
|
| -
|
| - void Consume(const uint8_t** data, size_t* length) {
|
| - MutexLocker locker(mutex_);
|
| - while (!TryGetData(data, length))
|
| - have_data_.Wait(mutex_);
|
| - }
|
| -
|
| - private:
|
| - bool TryGetData(const uint8_t** data, size_t* length) {
|
| -#if DCHECK_IS_ON()
|
| - DCHECK(mutex_.Locked());
|
| -#endif
|
| - if (!data_.IsEmpty()) {
|
| - std::pair<const uint8_t*, size_t> next_data = data_.TakeFirst();
|
| - *data = next_data.first;
|
| - *length = next_data.second;
|
| - return true;
|
| - }
|
| - if (finished_) {
|
| - *length = 0;
|
| - return true;
|
| - }
|
| - return false;
|
| - }
|
| -
|
| - void DiscardQueuedData() {
|
| - while (!data_.IsEmpty()) {
|
| - std::pair<const uint8_t*, size_t> next_data = data_.TakeFirst();
|
| - delete[] next_data.first;
|
| - }
|
| - }
|
| -
|
| - Deque<std::pair<const uint8_t*, size_t>> data_;
|
| - bool finished_;
|
| - Mutex mutex_;
|
| - ThreadCondition have_data_;
|
| -};
|
| -
|
| -// SourceStream implements the streaming interface towards V8. The main
|
| -// functionality is preparing the data to give to V8 on main thread, and
|
| -// actually giving the data (via GetMoreData which is called on a background
|
| -// thread).
|
| -class SourceStream : public v8::ScriptCompiler::ExternalSourceStream {
|
| - WTF_MAKE_NONCOPYABLE(SourceStream);
|
| -
|
| - public:
|
| - explicit SourceStream(RefPtr<WebTaskRunner> loading_task_runner)
|
| - : v8::ScriptCompiler::ExternalSourceStream(),
|
| - cancelled_(false),
|
| - finished_(false),
|
| - queue_lead_position_(0),
|
| - queue_tail_position_(0),
|
| - loading_task_runner_(std::move(loading_task_runner)) {}
|
| -
|
| - virtual ~SourceStream() override {}
|
| -
|
| - // Called by V8 on a background thread. Should block until we can return
|
| - // some data.
|
| - size_t GetMoreData(const uint8_t** src) override {
|
| - DCHECK(!IsMainThread());
|
| - {
|
| - MutexLocker locker(mutex_);
|
| - if (cancelled_)
|
| - return 0;
|
| - }
|
| - size_t length = 0;
|
| - // This will wait until there is data.
|
| - data_queue_.Consume(src, &length);
|
| - {
|
| - MutexLocker locker(mutex_);
|
| - if (cancelled_)
|
| - return 0;
|
| - }
|
| - queue_lead_position_ += length;
|
| - return length;
|
| - }
|
| -
|
| - void DidFinishLoading() {
|
| - DCHECK(IsMainThread());
|
| - finished_ = true;
|
| - data_queue_.Finish();
|
| - }
|
| -
|
| - void DidReceiveData(ScriptStreamer* streamer) {
|
| - DCHECK(IsMainThread());
|
| - PrepareDataOnMainThread(streamer);
|
| - }
|
| -
|
| - void Cancel() {
|
| - DCHECK(IsMainThread());
|
| - // The script is no longer needed by the upper layers. Stop streaming
|
| - // it. The next time GetMoreData is called (or woken up), it will return
|
| - // 0, which will be interpreted as EOS by V8 and the parsing will
|
| - // fail. ScriptStreamer::streamingComplete will be called, and at that
|
| - // point we will release the references to SourceStream.
|
| - {
|
| - MutexLocker locker(mutex_);
|
| - cancelled_ = true;
|
| - }
|
| - data_queue_.Finish();
|
| - }
|
| -
|
| - private:
|
| - void PrepareDataOnMainThread(ScriptStreamer* streamer) {
|
| - DCHECK(IsMainThread());
|
| -
|
| - if (cancelled_) {
|
| - data_queue_.Finish();
|
| - return;
|
| - }
|
| -
|
| - // The Resource must still be alive; otherwise we should've cancelled
|
| - // the streaming (if we have cancelled, the background thread is not
|
| - // waiting).
|
| - DCHECK(streamer->GetResource());
|
| -
|
| - if (!streamer->GetResource()
|
| - ->GetResponse()
|
| - .CacheStorageCacheName()
|
| - .IsNull()) {
|
| - streamer->SuppressStreaming();
|
| - Cancel();
|
| - return;
|
| - }
|
| -
|
| - CachedMetadataHandler* cache_handler =
|
| - streamer->GetResource()->CacheHandler();
|
| - RefPtr<CachedMetadata> code_cache(
|
| - cache_handler ? cache_handler->GetCachedMetadata(
|
| - V8ScriptRunner::TagForCodeCache(cache_handler))
|
| - : nullptr);
|
| - if (code_cache.Get()) {
|
| - // The resource has a code cache, so it's unnecessary to stream and
|
| - // parse the code. Cancel the streaming and resume the non-streaming
|
| - // code path.
|
| - streamer->SuppressStreaming();
|
| - Cancel();
|
| - return;
|
| - }
|
| -
|
| - if (!resource_buffer_) {
|
| - // We don't have a buffer yet. Try to get it from the resource.
|
| - resource_buffer_ = streamer->GetResource()->ResourceBuffer();
|
| - }
|
| -
|
| - FetchDataFromResourceBuffer();
|
| - }
|
| -
|
| - void FetchDataFromResourceBuffer() {
|
| - DCHECK(IsMainThread());
|
| - MutexLocker locker(mutex_);
|
| -
|
| - DCHECK(!finished_);
|
| - if (cancelled_) {
|
| - data_queue_.Finish();
|
| - return;
|
| - }
|
| -
|
| - // Get as much data from the ResourceBuffer as we can.
|
| - const char* data = nullptr;
|
| - while (size_t length =
|
| - resource_buffer_->GetSomeData(data, queue_tail_position_)) {
|
| - // Copy the data chunks into a new buffer, since we're going to
|
| - // give the data to a background thread.
|
| - uint8_t* copied_data = new uint8_t[length];
|
| - memcpy(copied_data, data, length);
|
| - data_queue_.Produce(copied_data, length);
|
| -
|
| - queue_tail_position_ += length;
|
| - }
|
| - }
|
| -
|
| - // For coordinating between the main thread and background thread tasks.
|
| - // Guards m_cancelled and m_queueTailPosition.
|
| - Mutex mutex_;
|
| -
|
| - // The shared buffer containing the resource data + state variables.
|
| - // Used by both threads, guarded by m_mutex.
|
| - bool cancelled_;
|
| - bool finished_;
|
| -
|
| - RefPtr<const SharedBuffer> resource_buffer_; // Only used by the main thread.
|
| -
|
| - // The queue contains the data to be passed to the V8 thread.
|
| - // queueLeadPosition: data we have handed off to the V8 thread.
|
| - // queueTailPosition: end of data we have enqued in the queue.
|
| - // bookmarkPosition: position of the bookmark.
|
| - SourceStreamDataQueue data_queue_; // Thread safe.
|
| - size_t queue_lead_position_; // Only used by v8 thread.
|
| - size_t queue_tail_position_; // Used by both threads; guarded by m_mutex.
|
| -
|
| - RefPtr<WebTaskRunner> loading_task_runner_;
|
| -};
|
| -
|
| -size_t ScriptStreamer::small_script_threshold_ = 30 * 1024;
|
| -
|
| -void ScriptStreamer::StartStreaming(PendingScript* script,
|
| - Type script_type,
|
| - Settings* settings,
|
| - ScriptState* script_state,
|
| - RefPtr<WebTaskRunner> loading_task_runner) {
|
| - // We don't yet know whether the script will really be streamed. E.g.,
|
| - // suppressing streaming for short scripts is done later. Record only the
|
| - // sure negative cases here.
|
| - bool started_streaming =
|
| - StartStreamingInternal(script, script_type, settings, script_state,
|
| - std::move(loading_task_runner));
|
| - if (!started_streaming)
|
| - RecordStartedStreamingHistogram(script_type, 0);
|
| -}
|
| -
|
| -bool ScriptStreamer::ConvertEncoding(
|
| - const char* encoding_name,
|
| - v8::ScriptCompiler::StreamedSource::Encoding* encoding) {
|
| - // Here's a list of encodings we can use for streaming. These are
|
| - // the canonical names.
|
| - if (strcmp(encoding_name, "windows-1252") == 0 ||
|
| - strcmp(encoding_name, "ISO-8859-1") == 0 ||
|
| - strcmp(encoding_name, "US-ASCII") == 0) {
|
| - *encoding = v8::ScriptCompiler::StreamedSource::ONE_BYTE;
|
| - return true;
|
| - }
|
| - if (strcmp(encoding_name, "UTF-8") == 0) {
|
| - *encoding = v8::ScriptCompiler::StreamedSource::UTF8;
|
| - return true;
|
| - }
|
| - // We don't stream other encodings; especially we don't stream two
|
| - // byte scripts to avoid the handling of endianness. Most scripts
|
| - // are Latin1 or UTF-8 anyway, so this should be enough for most
|
| - // real world purposes.
|
| - return false;
|
| -}
|
| -
|
| -bool ScriptStreamer::IsFinished() const {
|
| - DCHECK(IsMainThread());
|
| - return loading_finished_ && (parsing_finished_ || streaming_suppressed_);
|
| -}
|
| -
|
| -void ScriptStreamer::StreamingCompleteOnBackgroundThread() {
|
| - DCHECK(!IsMainThread());
|
| -
|
| - // notifyFinished might already be called, or it might be called in the
|
| - // future (if the parsing finishes earlier because of a parse error).
|
| - loading_task_runner_->PostTask(
|
| - BLINK_FROM_HERE, CrossThreadBind(&ScriptStreamer::StreamingComplete,
|
| - WrapCrossThreadPersistent(this)));
|
| -
|
| - // The task might delete ScriptStreamer, so it's not safe to do anything
|
| - // after posting it. Note that there's no way to guarantee that this
|
| - // function has returned before the task is ran - however, we should not
|
| - // access the "this" object after posting the task.
|
| -}
|
| -
|
| -void ScriptStreamer::Cancel() {
|
| - DCHECK(IsMainThread());
|
| - // The upper layer doesn't need the script any more, but streaming might
|
| - // still be ongoing. Tell SourceStream to try to cancel it whenever it gets
|
| - // the control the next time. It can also be that V8 has already completed
|
| - // its operations and streamingComplete will be called soon.
|
| - detached_ = true;
|
| - resource_ = 0;
|
| - if (stream_)
|
| - stream_->Cancel();
|
| -}
|
| -
|
| -void ScriptStreamer::SuppressStreaming() {
|
| - DCHECK(IsMainThread());
|
| - DCHECK(!loading_finished_);
|
| - // It can be that the parsing task has already finished (e.g., if there was
|
| - // a parse error).
|
| - streaming_suppressed_ = true;
|
| -}
|
| -
|
| -void ScriptStreamer::NotifyAppendData(ScriptResource* resource) {
|
| - DCHECK(IsMainThread());
|
| - CHECK_EQ(resource_, resource);
|
| - if (streaming_suppressed_)
|
| - return;
|
| - if (!have_enough_data_for_streaming_) {
|
| - // Even if the first data chunk is small, the script can still be big
|
| - // enough - wait until the next data chunk comes before deciding whether
|
| - // to start the streaming.
|
| - DCHECK(resource->ResourceBuffer());
|
| - if (resource->ResourceBuffer()->size() < small_script_threshold_)
|
| - return;
|
| - have_enough_data_for_streaming_ = true;
|
| -
|
| - {
|
| - // Check for BOM (byte order marks), because that might change our
|
| - // understanding of the data encoding.
|
| - constexpr size_t kMaximumLengthOfBOM = 4;
|
| - char maybe_bom[kMaximumLengthOfBOM] = {};
|
| - if (!resource->ResourceBuffer()->GetPartAsBytes(
|
| - maybe_bom, static_cast<size_t>(0), kMaximumLengthOfBOM)) {
|
| - NOTREACHED();
|
| - return;
|
| - }
|
| -
|
| - std::unique_ptr<TextResourceDecoder> decoder(TextResourceDecoder::Create(
|
| - "application/javascript", resource->Encoding()));
|
| - decoder->CheckForBOM(maybe_bom, kMaximumLengthOfBOM);
|
| -
|
| - // The encoding may change when we see the BOM. Check for BOM now
|
| - // and update the encoding from the decoder when necessary. Supress
|
| - // streaming if the encoding is unsupported.
|
| - //
|
| - // Also note that have at least s_smallScriptThreshold worth of
|
| - // data, which is more than enough for detecting a BOM.
|
| - if (!ConvertEncoding(decoder->Encoding().GetName(), &encoding_)) {
|
| - SuppressStreaming();
|
| - RecordNotStreamingReasonHistogram(script_type_, kEncodingNotSupported);
|
| - RecordStartedStreamingHistogram(script_type_, 0);
|
| - return;
|
| - }
|
| - }
|
| -
|
| - if (ScriptStreamerThread::Shared()->IsRunningTask()) {
|
| - // At the moment we only have one thread for running the tasks. A
|
| - // new task shouldn't be queued before the running task completes,
|
| - // because the running task can block and wait for data from the
|
| - // network.
|
| - SuppressStreaming();
|
| - RecordNotStreamingReasonHistogram(script_type_, kThreadBusy);
|
| - RecordStartedStreamingHistogram(script_type_, 0);
|
| - return;
|
| - }
|
| -
|
| - if (!script_state_->ContextIsValid()) {
|
| - SuppressStreaming();
|
| - RecordNotStreamingReasonHistogram(script_type_, kContextNotValid);
|
| - RecordStartedStreamingHistogram(script_type_, 0);
|
| - return;
|
| - }
|
| -
|
| - DCHECK(!stream_);
|
| - DCHECK(!source_);
|
| - stream_ = new SourceStream(loading_task_runner_.Get());
|
| - // m_source takes ownership of m_stream.
|
| - source_ = WTF::WrapUnique(
|
| - new v8::ScriptCompiler::StreamedSource(stream_, encoding_));
|
| -
|
| - ScriptState::Scope scope(script_state_.Get());
|
| - std::unique_ptr<v8::ScriptCompiler::ScriptStreamingTask>
|
| - script_streaming_task(
|
| - WTF::WrapUnique(v8::ScriptCompiler::StartStreamingScript(
|
| - script_state_->GetIsolate(), source_.get(), compile_options_)));
|
| - if (!script_streaming_task) {
|
| - // V8 cannot stream the script.
|
| - SuppressStreaming();
|
| - stream_ = 0;
|
| - source_.reset();
|
| - RecordNotStreamingReasonHistogram(script_type_, kV8CannotStream);
|
| - RecordStartedStreamingHistogram(script_type_, 0);
|
| - return;
|
| - }
|
| -
|
| - ScriptStreamerThread::Shared()->PostTask(
|
| - CrossThreadBind(&ScriptStreamerThread::RunScriptStreamingTask,
|
| - WTF::Passed(std::move(script_streaming_task)),
|
| - WrapCrossThreadPersistent(this)));
|
| - RecordStartedStreamingHistogram(script_type_, 1);
|
| - }
|
| - if (stream_)
|
| - stream_->DidReceiveData(this);
|
| -}
|
| -
|
| -void ScriptStreamer::NotifyFinished(Resource* resource) {
|
| - DCHECK(IsMainThread());
|
| - CHECK_EQ(resource_, resource);
|
| - // A special case: empty and small scripts. We didn't receive enough data to
|
| - // start the streaming before this notification. In that case, there won't
|
| - // be a "parsing complete" notification either, and we should not wait for
|
| - // it.
|
| - if (!have_enough_data_for_streaming_) {
|
| - RecordNotStreamingReasonHistogram(script_type_, kScriptTooSmall);
|
| - RecordStartedStreamingHistogram(script_type_, 0);
|
| - SuppressStreaming();
|
| - }
|
| - if (stream_)
|
| - stream_->DidFinishLoading();
|
| - loading_finished_ = true;
|
| -
|
| - NotifyFinishedToClient();
|
| -}
|
| -
|
| -ScriptStreamer::ScriptStreamer(
|
| - PendingScript* script,
|
| - Type script_type,
|
| - ScriptState* script_state,
|
| - v8::ScriptCompiler::CompileOptions compile_options,
|
| - RefPtr<WebTaskRunner> loading_task_runner)
|
| - : pending_script_(script),
|
| - resource_(script->GetResource()),
|
| - detached_(false),
|
| - stream_(0),
|
| - loading_finished_(false),
|
| - parsing_finished_(false),
|
| - have_enough_data_for_streaming_(false),
|
| - streaming_suppressed_(false),
|
| - compile_options_(compile_options),
|
| - script_state_(script_state),
|
| - script_type_(script_type),
|
| - script_url_string_(resource_->Url().Copy().GetString()),
|
| - script_resource_identifier_(resource_->Identifier()),
|
| - // Unfortunately there's no dummy encoding value in the enum; let's use
|
| - // one we don't stream.
|
| - encoding_(v8::ScriptCompiler::StreamedSource::TWO_BYTE),
|
| - loading_task_runner_(std::move(loading_task_runner)) {}
|
| -
|
| -ScriptStreamer::~ScriptStreamer() {}
|
| -
|
| -DEFINE_TRACE(ScriptStreamer) {
|
| - visitor->Trace(pending_script_);
|
| - visitor->Trace(resource_);
|
| -}
|
| -
|
| -void ScriptStreamer::StreamingComplete() {
|
| - // The background task is completed; do the necessary ramp-down in the main
|
| - // thread.
|
| - DCHECK(IsMainThread());
|
| - parsing_finished_ = true;
|
| -
|
| - // It's possible that the corresponding Resource was deleted before V8
|
| - // finished streaming. In that case, the data or the notification is not
|
| - // needed. In addition, if the streaming is suppressed, the non-streaming
|
| - // code path will resume after the resource has loaded, before the
|
| - // background task finishes.
|
| - if (detached_ || streaming_suppressed_)
|
| - return;
|
| -
|
| - // We have now streamed the whole script to V8 and it has parsed the
|
| - // script. We're ready for the next step: compiling and executing the
|
| - // script.
|
| - NotifyFinishedToClient();
|
| -}
|
| -
|
| -void ScriptStreamer::NotifyFinishedToClient() {
|
| - DCHECK(IsMainThread());
|
| - // Usually, the loading will be finished first, and V8 will still need some
|
| - // time to catch up. But the other way is possible too: if V8 detects a
|
| - // parse error, the V8 side can complete before loading has finished. Send
|
| - // the notification after both loading and V8 side operations have
|
| - // completed.
|
| - if (!IsFinished())
|
| - return;
|
| -
|
| - pending_script_->StreamingFinished();
|
| -}
|
| -
|
| -bool ScriptStreamer::StartStreamingInternal(
|
| - PendingScript* script,
|
| - Type script_type,
|
| - Settings* settings,
|
| - ScriptState* script_state,
|
| - RefPtr<WebTaskRunner> loading_task_runner) {
|
| - DCHECK(IsMainThread());
|
| - DCHECK(script_state->ContextIsValid());
|
| - ScriptResource* resource = script->GetResource();
|
| - if (resource->IsLoaded()) {
|
| - RecordNotStreamingReasonHistogram(script_type, kAlreadyLoaded);
|
| - return false;
|
| - }
|
| - if (!resource->Url().ProtocolIsInHTTPFamily()) {
|
| - RecordNotStreamingReasonHistogram(script_type, kNotHTTP);
|
| - return false;
|
| - }
|
| - if (resource->IsCacheValidator()) {
|
| - RecordNotStreamingReasonHistogram(script_type, kReload);
|
| - // This happens e.g., during reloads. We're actually not going to load
|
| - // the current Resource of the PendingScript but switch to another
|
| - // Resource -> don't stream.
|
| - return false;
|
| - }
|
| - // We cannot filter out short scripts, even if we wait for the HTTP headers
|
| - // to arrive: the Content-Length HTTP header is not sent for chunked
|
| - // downloads.
|
| -
|
| - // Decide what kind of cached data we should produce while streaming. Only
|
| - // produce parser cache if the non-streaming compile takes advantage of it.
|
| - v8::ScriptCompiler::CompileOptions compile_option =
|
| - v8::ScriptCompiler::kNoCompileOptions;
|
| - if (settings->GetV8CacheOptions() == kV8CacheOptionsParse)
|
| - compile_option = v8::ScriptCompiler::kProduceParserCache;
|
| -
|
| - // The Resource might go out of scope if the script is no longer
|
| - // needed. This makes PendingScript notify the ScriptStreamer when it is
|
| - // destroyed.
|
| - script->SetStreamer(ScriptStreamer::Create(script, script_type, script_state,
|
| - compile_option,
|
| - std::move(loading_task_runner)));
|
| -
|
| - return true;
|
| -}
|
| -
|
| -} // namespace blink
|
|
|