| 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 #ifndef ScriptStreamer_h | 5 #ifndef ScriptStreamer_h |
| 6 #define ScriptStreamer_h | 6 #define ScriptStreamer_h |
| 7 | 7 |
| 8 #include <memory> | 8 #include <memory> |
| 9 | 9 |
| 10 #include "core/CoreExport.h" | 10 #include "core/CoreExport.h" |
| 11 #include "platform/heap/Handle.h" | 11 #include "platform/heap/Handle.h" |
| 12 #include "platform/wtf/Noncopyable.h" | 12 #include "platform/wtf/Noncopyable.h" |
| 13 #include "platform/wtf/text/WTFString.h" | |
| 14 #include "v8/include/v8.h" | 13 #include "v8/include/v8.h" |
| 15 | 14 |
| 16 namespace blink { | 15 namespace blink { |
| 17 | 16 |
| 18 class PendingScript; | |
| 19 class Resource; | 17 class Resource; |
| 20 class ScriptResource; | 18 class ScriptResource; |
| 21 class ScriptState; | |
| 22 class Settings; | |
| 23 class SourceStream; | |
| 24 class WebTaskRunner; | |
| 25 | 19 |
| 26 // ScriptStreamer streams incomplete script data to V8 so that it can be parsed | 20 // ScriptStreamer streams incomplete script data to V8 so that it can be parsed |
| 27 // while it's loaded. PendingScript holds a reference to ScriptStreamer. At the | 21 // while it's loaded. PendingScript holds a reference to ScriptStreamer. At the |
| 28 // moment, ScriptStreamer is only used for parser blocking scripts; this means | 22 // moment, ScriptStreamer is only used for parser blocking scripts; this means |
| 29 // that the Document stays stable and no other scripts are executing while we're | 23 // that the Document stays stable and no other scripts are executing while we're |
| 30 // streaming. It is possible, though, that Document and the PendingScript are | 24 // streaming. It is possible, though, that Document and the PendingScript are |
| 31 // destroyed while the streaming is in progress, and ScriptStreamer handles it | 25 // destroyed while the streaming is in progress, and ScriptStreamer handles it |
| 32 // gracefully. | 26 // gracefully. |
| 33 class CORE_EXPORT ScriptStreamer final | 27 // |
| 28 // ScriptStreamer is abstract just to implement unit tests. ScriptStreamerImpl |
| 29 // is the only subclass in non-test code that implements the functionality. |
| 30 class CORE_EXPORT ScriptStreamer |
| 34 : public GarbageCollectedFinalized<ScriptStreamer> { | 31 : public GarbageCollectedFinalized<ScriptStreamer> { |
| 35 WTF_MAKE_NONCOPYABLE(ScriptStreamer); | 32 WTF_MAKE_NONCOPYABLE(ScriptStreamer); |
| 36 | 33 |
| 37 public: | 34 public: |
| 38 enum Type { kParsingBlocking, kDeferred, kAsync }; | 35 enum Type { kParsingBlocking, kDeferred, kAsync }; |
| 39 | 36 |
| 40 ~ScriptStreamer(); | 37 ScriptStreamer() {} |
| 41 DECLARE_TRACE(); | 38 virtual ~ScriptStreamer() {} |
| 42 | 39 |
| 43 // Launches a task (on a background thread) which will stream the given | 40 DEFINE_INLINE_VIRTUAL_TRACE() {} |
| 44 // PendingScript into V8 as it loads. | |
| 45 static void StartStreaming(PendingScript*, | |
| 46 Type, | |
| 47 Settings*, | |
| 48 ScriptState*, | |
| 49 RefPtr<WebTaskRunner>); | |
| 50 | 41 |
| 51 // Returns false if we cannot stream the given encoding. | 42 virtual bool IsFinished() const = 0; |
| 52 static bool ConvertEncoding(const char* encoding_name, | |
| 53 v8::ScriptCompiler::StreamedSource::Encoding*); | |
| 54 | 43 |
| 55 bool IsFinished() const; | 44 virtual v8::ScriptCompiler::StreamedSource* Source() = 0; |
| 56 | 45 virtual ScriptResource* GetResource() const = 0; |
| 57 v8::ScriptCompiler::StreamedSource* Source() { return source_.get(); } | |
| 58 ScriptResource* GetResource() const { return resource_; } | |
| 59 | 46 |
| 60 // Called when the script is not needed any more (e.g., loading was | 47 // Called when the script is not needed any more (e.g., loading was |
| 61 // cancelled). After calling cancel, PendingScript can drop its reference to | 48 // cancelled). After calling cancel, PendingScript can drop its reference to |
| 62 // ScriptStreamer, and ScriptStreamer takes care of eventually deleting | 49 // ScriptStreamer, and ScriptStreamer takes care of eventually deleting |
| 63 // itself (after the V8 side has finished too). | 50 // itself (after the V8 side has finished too). |
| 64 void Cancel(); | 51 virtual void Cancel() = 0; |
| 65 | 52 |
| 66 // When the streaming is suppressed, the data is not given to V8, but | 53 // When the streaming is suppressed, the data is not given to V8, but |
| 67 // ScriptStreamer still watches the resource load and notifies the upper | 54 // ScriptStreamer still watches the resource load and notifies the upper |
| 68 // layers when loading is finished. It is used in situations when we have | 55 // layers when loading is finished. It is used in situations when we have |
| 69 // started streaming but then we detect we don't want to stream (e.g., when | 56 // started streaming but then we detect we don't want to stream (e.g., when |
| 70 // we have the code cache for the script) and we still want to parse and | 57 // we have the code cache for the script) and we still want to parse and |
| 71 // execute it when it has finished loading. | 58 // execute it when it has finished loading. |
| 72 void SuppressStreaming(); | 59 virtual bool StreamingSuppressed() const = 0; |
| 73 bool StreamingSuppressed() const { return streaming_suppressed_; } | |
| 74 | 60 |
| 75 // Called by PendingScript when data arrives from the network. | 61 // Called by ClassicPendingScript when data arrives from the network. |
| 76 void NotifyAppendData(ScriptResource*); | 62 virtual void NotifyAppendData(ScriptResource*) = 0; |
| 77 void NotifyFinished(Resource*); | 63 virtual void NotifyFinished(Resource*) = 0; |
| 78 | |
| 79 // Called by ScriptStreamingTask when it has streamed all data to V8 and V8 | |
| 80 // has processed it. | |
| 81 void StreamingCompleteOnBackgroundThread(); | |
| 82 | |
| 83 const String& ScriptURLString() const { return script_url_string_; } | |
| 84 unsigned long ScriptResourceIdentifier() const { | |
| 85 return script_resource_identifier_; | |
| 86 } | |
| 87 | |
| 88 static void SetSmallScriptThresholdForTesting(size_t threshold) { | |
| 89 small_script_threshold_ = threshold; | |
| 90 } | |
| 91 | |
| 92 private: | |
| 93 // Scripts whose first data chunk is smaller than this constant won't be | |
| 94 // streamed. Non-const for testing. | |
| 95 static size_t small_script_threshold_; | |
| 96 | |
| 97 static ScriptStreamer* Create( | |
| 98 PendingScript* script, | |
| 99 Type script_type, | |
| 100 ScriptState* script_state, | |
| 101 v8::ScriptCompiler::CompileOptions compile_options, | |
| 102 RefPtr<WebTaskRunner> loading_task_runner) { | |
| 103 return new ScriptStreamer(script, script_type, script_state, | |
| 104 compile_options, std::move(loading_task_runner)); | |
| 105 } | |
| 106 ScriptStreamer(PendingScript*, | |
| 107 Type, | |
| 108 ScriptState*, | |
| 109 v8::ScriptCompiler::CompileOptions, | |
| 110 RefPtr<WebTaskRunner>); | |
| 111 | |
| 112 void StreamingComplete(); | |
| 113 void NotifyFinishedToClient(); | |
| 114 | |
| 115 static bool StartStreamingInternal(PendingScript*, | |
| 116 Type, | |
| 117 Settings*, | |
| 118 ScriptState*, | |
| 119 RefPtr<WebTaskRunner>); | |
| 120 | |
| 121 Member<PendingScript> pending_script_; | |
| 122 // This pointer is weak. If PendingScript and its Resource are deleted | |
| 123 // before ScriptStreamer, PendingScript will notify ScriptStreamer of its | |
| 124 // deletion by calling cancel(). | |
| 125 Member<ScriptResource> resource_; | |
| 126 // Whether ScriptStreamer is detached from the Resource. In those cases, the | |
| 127 // script data is not needed any more, and the client won't get notified | |
| 128 // when the loading and streaming are done. | |
| 129 bool detached_; | |
| 130 | |
| 131 SourceStream* stream_; | |
| 132 std::unique_ptr<v8::ScriptCompiler::StreamedSource> source_; | |
| 133 bool loading_finished_; // Whether loading from the network is done. | |
| 134 bool parsing_finished_; // Whether the V8 side processing is done. | |
| 135 // Whether we have received enough data to start the streaming. | |
| 136 bool have_enough_data_for_streaming_; | |
| 137 | |
| 138 // Whether the script source code should be retrieved from the Resource | |
| 139 // instead of the ScriptStreamer. | |
| 140 bool streaming_suppressed_; | |
| 141 | |
| 142 // What kind of cached data V8 produces during streaming. | |
| 143 v8::ScriptCompiler::CompileOptions compile_options_; | |
| 144 | |
| 145 RefPtr<ScriptState> script_state_; | |
| 146 | |
| 147 // For recording metrics for different types of scripts separately. | |
| 148 Type script_type_; | |
| 149 | |
| 150 // Keep the script URL string for event tracing. | |
| 151 const String script_url_string_; | |
| 152 | |
| 153 // Keep the script resource dentifier for event tracing. | |
| 154 const unsigned long script_resource_identifier_; | |
| 155 | |
| 156 // Encoding of the streamed script. Saved for sanity checking purposes. | |
| 157 v8::ScriptCompiler::StreamedSource::Encoding encoding_; | |
| 158 | |
| 159 RefPtr<WebTaskRunner> loading_task_runner_; | |
| 160 }; | 64 }; |
| 161 | 65 |
| 162 } // namespace blink | 66 } // namespace blink |
| 163 | 67 |
| 164 #endif // ScriptStreamer_h | 68 #endif // ScriptStreamer_h |
| OLD | NEW |