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
3 // found in the LICENSE file.
5 #ifndef ScriptStreamer_h
6 #define ScriptStreamer_h
8 #include "core/dom/PendingScript.h"
9 #include "wtf/RefCounted.h"
18 class ScriptResourceClient;
23 // ScriptStreamer streams incomplete script data to V8 so that it can be parsed
24 // while it's loaded. PendingScript holds a reference to ScriptStreamer. At the
25 // moment, ScriptStreamer is only used for parser blocking scripts; this means
26 // that the Document stays stable and no other scripts are executing while we're
27 // streaming. It is possible, though, that Document and the PendingScript are
28 // destroyed while the streaming is in progress, and ScriptStreamer handles it
30 class ScriptStreamer : public RefCounted<ScriptStreamer> {
31 WTF_MAKE_NONCOPYABLE(ScriptStreamer);
33 // Launches a task (on a background thread) which will stream the given
34 // PendingScript into V8 as it loads. It's also possible that V8 cannot
35 // stream the given script; in that case this function returns
36 // false. Internally, this constructs a ScriptStreamer and attaches it to
37 // the PendingScript. Use ScriptStreamer::addClient to get notified when the
38 // streaming finishes.
39 static void startStreaming(PendingScript&, Settings*, ScriptState*, PendingScript::Type);
41 bool isFinished() const
43 return m_loadingFinished && (m_parsingFinished || m_streamingSuppressed);
46 v8::ScriptCompiler::StreamedSource* source() { return &m_source; }
47 ScriptResource* resource() const { return m_resource; }
49 // Called when the script is not needed any more (e.g., loading was
50 // cancelled). After calling cancel, PendingScript can drop its reference to
51 // ScriptStreamer, and ScriptStreamer takes care of eventually deleting
52 // itself (after the V8 side has finished too).
55 // When the streaming is suppressed, the data is not given to V8, but
56 // ScriptStreamer still watches the resource load and notifies the upper
57 // layers when loading is finished. It is used in situations when we have
58 // started streaming but then we detect we don't want to stream (e.g., when
59 // we have the code cache for the script) and we still want to parse and
60 // execute it when it has finished loading.
61 void suppressStreaming();
62 bool streamingSuppressed() const { return m_streamingSuppressed; }
64 unsigned cachedDataType() const { return m_cachedDataType; }
66 void addClient(ScriptResourceClient* client)
69 ASSERT(!isFinished());
73 void removeClient(ScriptResourceClient* client)
75 ASSERT(m_client == client);
79 // Called by PendingScript when data arrives from the network.
80 void notifyAppendData(ScriptResource*);
81 void notifyFinished(Resource*);
83 // Called by ScriptStreamingTask when it has streamed all data to V8 and V8
85 void streamingComplete();
87 static void removeSmallScriptThresholdForTesting()
89 kSmallScriptThreshold = 0;
92 static size_t smallScriptThreshold() { return kSmallScriptThreshold; }
95 // Scripts whose first data chunk is smaller than this constant won't be
96 // streamed. Non-const for testing.
97 static size_t kSmallScriptThreshold;
99 ScriptStreamer(ScriptResource*, v8::ScriptCompiler::StreamedSource::Encoding, PendingScript::Type);
101 void notifyFinishedToClient();
103 static const char* startedStreamingHistogramName(PendingScript::Type);
105 static bool startStreamingInternal(PendingScript&, Settings*, ScriptState*, PendingScript::Type);
107 // This pointer is weak. If PendingScript and its Resource are deleted
108 // before ScriptStreamer, PendingScript will notify ScriptStreamer of its
109 // deletion by calling cancel().
110 ScriptResource* m_resource;
111 // Whether ScriptStreamer is detached from the Resource. In those cases, the
112 // script data is not needed any more, and the client won't get notified
113 // when the loading and streaming are done.
116 SourceStream* m_stream;
117 v8::ScriptCompiler::StreamedSource m_source;
118 ScriptResourceClient* m_client;
119 v8::ScriptCompiler::ScriptStreamingTask* m_task;
120 bool m_loadingFinished; // Whether loading from the network is done.
121 bool m_parsingFinished; // Whether the V8 side processing is done.
122 bool m_firstDataChunkReceived;
124 // Whether the script source code should be retrieved from the Resource
125 // instead of the ScriptStreamer.
126 bool m_streamingSuppressed;
128 // What kind of cached data V8 produces during streaming.
129 unsigned m_cachedDataType;
131 // For recording metrics for different types of scripts separately.
132 PendingScript::Type m_scriptType;
137 #endif // ScriptStreamer_h