chromium/third_party/blink/renderer/bindings/core/v8/script_streamer.cc

// Copyright 2014 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "third_party/blink/renderer/bindings/core/v8/script_streamer.h"

#include <atomic>
#include <memory>
#include <utility>

#include "base/check_op.h"
#include "base/containers/heap_array.h"
#include "base/containers/span.h"
#include "base/memory/ptr_util.h"
#include "base/memory/scoped_refptr.h"
#include "base/metrics/histogram_functions.h"
#include "base/notreached.h"
#include "base/numerics/safe_conversions.h"
#include "base/sequence_checker.h"
#include "base/state_transitions.h"
#include "base/synchronization/lock.h"
#include "base/task/sequenced_task_runner.h"
#include "base/task/single_thread_task_runner.h"
#include "base/threading/scoped_blocking_call.h"
#include "base/threading/thread_restrictions.h"
#include "base/types/pass_key.h"
#include "mojo/public/cpp/system/data_pipe_drainer.h"
#include "mojo/public/cpp/system/wait.h"
#include "services/network/public/mojom/url_response_head.mojom.h"
#include "third_party/abseil-cpp/absl/types/variant.h"
#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/common/page/v8_compile_hints_histograms.h"
#include "third_party/blink/public/mojom/script/script_type.mojom-blink-forward.h"
#include "third_party/blink/public/mojom/script/script_type.mojom-shared.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_code_cache.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_compile_hints_common.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_compile_hints_consumer.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_compile_hints_for_streaming.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_compile_hints_producer.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_local_compile_hints_consumer.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/dom/element.h"
#include "third_party/blink/renderer/core/frame/settings.h"
#include "third_party/blink/renderer/core/inspector/inspector_trace_events.h"
#include "third_party/blink/renderer/core/loader/resource/script_resource.h"
#include "third_party/blink/renderer/platform/bindings/v8_per_isolate_data.h"
#include "third_party/blink/renderer/platform/heap/cross_thread_handle.h"
#include "third_party/blink/renderer/platform/heap/cross_thread_persistent.h"
#include "third_party/blink/renderer/platform/instrumentation/histogram.h"
#include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h"
#include "third_party/blink/renderer/platform/loader/fetch/cached_metadata.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource.h"
#include "third_party/blink/renderer/platform/loader/fetch/response_body_loader.h"
#include "third_party/blink/renderer/platform/network/mime/mime_type_registry.h"
#include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h"
#include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h"
#include "third_party/blink/renderer/platform/scheduler/public/worker_pool.h"
#include "third_party/blink/renderer/platform/wtf/cross_thread_copier.h"
#include "third_party/blink/renderer/platform/wtf/cross_thread_copier_base.h"
#include "third_party/blink/renderer/platform/wtf/cross_thread_copier_mojo.h"
#include "third_party/blink/renderer/platform/wtf/cross_thread_copier_std.h"
#include "third_party/blink/renderer/platform/wtf/cross_thread_functional.h"
#include "third_party/blink/renderer/platform/wtf/deque.h"
#include "third_party/blink/renderer/platform/wtf/forward.h"
#include "third_party/blink/renderer/platform/wtf/shared_buffer.h"
#include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
#include "third_party/blink/renderer/platform/wtf/text/text_encoding_registry.h"

namespace WTF {

template <>
struct CrossThreadCopier<mojo_base::BigBuffer> {};

}  // namespace WTF

namespace blink {
namespace {

v8::ScriptType ScriptTypeForStreamingTask(ScriptResource* script_resource) {}

}  // namespace

// 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 {};

std::tuple<ScriptStreamer*, ScriptStreamer::NotStreamingReason>
ScriptStreamer::TakeFrom(ScriptResource* script_resource,
                         mojom::blink::ScriptType expected_type) {}

namespace {

enum class StreamedBoolean {};

void RecordStartedStreamingHistogram(ScriptSchedulingType type,
                                     bool did_use_streamer) {}

void RecordNotStreamingReasonHistogram(
    ScriptSchedulingType type,
    ScriptStreamer::NotStreamingReason reason) {}

}  // namespace

void ScriptStreamer::RecordStreamingHistogram(
    ScriptSchedulingType type,
    bool can_use_streamer,
    ScriptStreamer::NotStreamingReason reason) {}

bool ScriptStreamer::ConvertEncoding(
    const char* encoding_name,
    v8::ScriptCompiler::StreamedSource::Encoding* encoding) {}

v8_compile_hints::V8LocalCompileHintsConsumer*
ResourceScriptStreamer::GetV8LocalCompileHintsConsumerForTest() const {}

bool ResourceScriptStreamer::IsStreamingStarted() const {}

bool ResourceScriptStreamer::IsStreamingSuppressed() const {}

bool ResourceScriptStreamer::IsLoaded() const {}

bool ResourceScriptStreamer::CanStartStreaming() const {}

bool ResourceScriptStreamer::IsFinished() const {}

bool ResourceScriptStreamer::IsClientDetached() const {}

void ResourceScriptStreamer::StreamingCompleteOnBackgroundThread(
    LoadingState state) {}

void ResourceScriptStreamer::Cancel() {}

void ResourceScriptStreamer::SuppressStreaming(NotStreamingReason reason) {}

void ResourceScriptStreamer::RunScriptStreamingTask(
    std::unique_ptr<v8::ScriptCompiler::ScriptStreamingTask> task,
    ResourceScriptStreamer* streamer,
    SourceStream* stream) {}

// Try to start a task streaming the script from the datapipe, with the task
// taking ownership of the datapipe and weak ownership of the client. Returns
// true if streaming succeeded and false otherwise.
//
// Streaming may fail to start because:
//
//   * The encoding is invalid (not UTF-8 or one-byte data)
//   * The script is too small to check for a byte-order marker
//   * There is a code cache for this script already
//   * V8 failed to create a script streamer
//
// If this method returns true, the datapipe handle will be cleared and the
// streaming task becomes responsible for draining the datapipe and forwarding
// data to the client. Otherwise, we should continue as if this were a no-op.
bool ResourceScriptStreamer::TryStartStreamingTask() {}

v8::ScriptType ResourceScriptStreamer::GetScriptType() const {}

ResourceScriptStreamer::ResourceScriptStreamer(
    ScriptResource* script_resource,
    mojo::ScopedDataPipeConsumerHandle data_pipe,
    ResponseBodyLoaderClient* response_body_loader_client,
    std::unique_ptr<TextResourceDecoder> decoder,
    scoped_refptr<base::SingleThreadTaskRunner> loading_task_runner)
    :{}

void ResourceScriptStreamer::OnDataPipeReadable(
    MojoResult result,
    const mojo::HandleSignalsState& state) {}

ResourceScriptStreamer::~ResourceScriptStreamer() = default;

void ResourceScriptStreamer::Prefinalize() {}

void ResourceScriptStreamer::Trace(Visitor* visitor) const {}

void ResourceScriptStreamer::StreamingComplete(LoadingState loading_state) {}

void ResourceScriptStreamer::LoadCompleteWithoutStreaming(
    LoadingState state,
    NotStreamingReason no_streaming_reason) {}

void ResourceScriptStreamer::SendClientLoadFinishedCallback() {}

void ResourceScriptStreamer::AdvanceLoadingState(LoadingState new_state) {}

void ResourceScriptStreamer::CheckState() const {}

class InlineSourceStream final
    : public v8::ScriptCompiler::ExternalSourceStream {};

BackgroundInlineScriptStreamer::BackgroundInlineScriptStreamer(
    v8::Isolate* isolate,
    const String& text,
    v8::ScriptCompiler::CompileOptions compile_options) {}

void BackgroundInlineScriptStreamer::Run() {}

v8::ScriptCompiler::StreamedSource* BackgroundInlineScriptStreamer::Source(
    v8::ScriptType expected_type) {}

// static
InlineScriptStreamer* InlineScriptStreamer::From(
    scoped_refptr<BackgroundInlineScriptStreamer> streamer) {}

namespace {

enum class BackgroundProcessorState {};

#if DCHECK_IS_ON()
std::ostream& operator<<(std::ostream& o, const BackgroundProcessorState& s) {}
#endif  // DCHECK_IS_ON()

std::unique_ptr<v8::ScriptCompiler::ConsumeCodeCacheTask>
MaybeCreateConsumeCodeCacheTask(std::optional<mojo_base::BigBuffer>& big_buffer,
                                const String& encoding,
                                v8::Isolate* isolate,
                                bool& has_code_cache,
                                v8::ScriptType script_type) {}

std::unique_ptr<v8_compile_hints::CompileHintsForStreaming>
BuildCompileHintsForStreaming(
    v8_compile_hints::CompileHintsForStreaming::Builder& builder,
    std::optional<mojo_base::BigBuffer>& big_buffer,
    const String& encoding) {}

}  // namespace

BackgroundResourceScriptStreamer::Result::Result(
    String decoded_data,
    std::unique_ptr<ParkableStringImpl::SecureDigest> digest,
    std::unique_ptr<v8::ScriptCompiler::StreamedSource> streamed_source)
    :{}

BackgroundResourceScriptStreamer::Result::Result(
    String decoded_data,
    std::unique_ptr<ParkableStringImpl::SecureDigest> digest,
    std::unique_ptr<v8::ScriptCompiler::ConsumeCodeCacheTask>
        consume_code_cache_task)
    :{}

class BackgroundResourceScriptStreamer::BackgroundProcessor final
    : public BackgroundResponseProcessor {};

class BackgroundResourceScriptStreamer::BackgroundProcessorFactory final
    : public BackgroundResponseProcessorFactory {};

BackgroundResourceScriptStreamer::BackgroundProcessor::BackgroundProcessor(
    v8::ScriptType script_type,
    const String script_url_string,
    uint64_t script_resource_identifier,
    v8::Isolate* isolate,
    WTF::TextEncoding encoding,
    std::unique_ptr<v8_compile_hints::CompileHintsForStreaming::Builder>
        compile_hints_builder,
    CrossThreadWeakHandle<BackgroundResourceScriptStreamer> streamer_handle)
    :{}

BackgroundResourceScriptStreamer::BackgroundProcessor::~BackgroundProcessor() {}

void BackgroundResourceScriptStreamer::BackgroundProcessor::SetState(
    BackgroundProcessorState state) {}

bool BackgroundResourceScriptStreamer::BackgroundProcessor::
    MaybeStartProcessingResponse(
        network::mojom::URLResponseHeadPtr& head,
        mojo::ScopedDataPipeConsumerHandle& body,
        std::optional<mojo_base::BigBuffer>& cached_metadata,
        scoped_refptr<base::SequencedTaskRunner> background_task_runner,
        Client* client) {}

void BackgroundResourceScriptStreamer::BackgroundProcessor::OnDataPipeReadable(
    MojoResult ready_result,
    const mojo::HandleSignalsState& ready_state) {}

bool BackgroundResourceScriptStreamer::BackgroundProcessor::
    TryStartStreamingTask(MojoResult result,
                          const mojo::HandleSignalsState& state) {}

// static
void BackgroundResourceScriptStreamer::BackgroundProcessor::
    RunScriptStreamingTask(
        const String script_url_string,
        uint64_t script_resource_identifier,
        std::unique_ptr<v8::ScriptCompiler::ScriptStreamingTask>
            script_streaming_task,
        std::unique_ptr<v8::ScriptCompiler::StreamedSource> streamed_source,
        SourceStream* source_stream_ptr,
        ScriptDecoderPtr script_decoder,
        std::unique_ptr<v8_compile_hints::CompileHintsForStreaming>
            compile_hints,
        base::WeakPtr<BackgroundProcessor> background_processor_weak_ptr) {}

void BackgroundResourceScriptStreamer::BackgroundProcessor::OnFinishStreaming(
    std::unique_ptr<v8::ScriptCompiler::StreamedSource> streamed_source,
    ScriptDecoderPtr script_decoder,
    ScriptDecoder::Result result) {}

// static
void BackgroundResourceScriptStreamer::BackgroundProcessor::
    RunConsumingCodeCacheTask(
        const String script_url_string,
        uint64_t script_resource_identifier,
        std::unique_ptr<v8::ScriptCompiler::ConsumeCodeCacheTask>
            consume_code_cache_task,
        scoped_refptr<base::SequencedTaskRunner> background_task_runner,
        mojo_base::BigBuffer cached_metadata,
        base::WeakPtr<BackgroundProcessor> background_processor_weak_ptr,
        const uint64_t trace_id) {}

void BackgroundResourceScriptStreamer::BackgroundProcessor::
    OnFinishCodeCacheConsumer(
        std::unique_ptr<v8::ScriptCompiler::ConsumeCodeCacheTask>
            consume_code_cache_task,
        mojo_base::BigBuffer cached_metadata) {}

void BackgroundResourceScriptStreamer::BackgroundProcessor::
    OnFinishScriptDecode(ScriptDecoder::Result result) {}

void BackgroundResourceScriptStreamer::BackgroundProcessor::
    OnFinishCodeCacheConsumerScriptDecode() {}

bool BackgroundResourceScriptStreamer::BackgroundProcessor::
    IsStreamingSuppressed() {}

void BackgroundResourceScriptStreamer::BackgroundProcessor::SuppressStreaming(
    NotStreamingReason reason) {}

BackgroundResourceScriptStreamer::BackgroundResourceScriptStreamer(
    ScriptResource* script_resource)
    :{}

BackgroundResourceScriptStreamer::~BackgroundResourceScriptStreamer() = default;

void BackgroundResourceScriptStreamer::Trace(Visitor* visitor) const {}

v8::ScriptCompiler::StreamedSource* BackgroundResourceScriptStreamer::Source(
    v8::ScriptType expected_type) {}

std::unique_ptr<BackgroundResponseProcessorFactory>
BackgroundResourceScriptStreamer::CreateBackgroundResponseProcessorFactory() {}

ParkableString BackgroundResourceScriptStreamer::TakeDecodedData() {}

std::unique_ptr<v8::ScriptCompiler::ConsumeCodeCacheTask>
BackgroundResourceScriptStreamer::TakeConsumeCodeCacheTask() {}

v8::ScriptType BackgroundResourceScriptStreamer::GetScriptType() const {}

void BackgroundResourceScriptStreamer::OnResult(
    std::unique_ptr<Result> result,
    NotStreamingReason suppressed_reason) {}

}  // namespace blink