Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / bindings / core / v8 / ScriptStreamer.h
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.
4
5 #ifndef ScriptStreamer_h
6 #define ScriptStreamer_h
7
8 #include "core/dom/PendingScript.h"
9 #include "wtf/RefCounted.h"
10
11 #include <v8.h>
12
13 namespace blink {
14
15 class PendingScript;
16 class Resource;
17 class ScriptResource;
18 class ScriptResourceClient;
19 class ScriptState;
20 class Settings;
21 class SourceStream;
22
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
29 // gracefully.
30 class ScriptStreamer : public RefCounted<ScriptStreamer> {
31     WTF_MAKE_NONCOPYABLE(ScriptStreamer);
32 public:
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);
40
41     bool isFinished() const
42     {
43         return m_loadingFinished && (m_parsingFinished || m_streamingSuppressed);
44     }
45
46     v8::ScriptCompiler::StreamedSource* source() { return &m_source; }
47     ScriptResource* resource() const { return m_resource; }
48
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).
53     void cancel();
54
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; }
63
64     unsigned cachedDataType() const { return m_cachedDataType; }
65
66     void addClient(ScriptResourceClient* client)
67     {
68         ASSERT(!m_client);
69         ASSERT(!isFinished());
70         m_client = client;
71     }
72
73     void removeClient(ScriptResourceClient* client)
74     {
75         ASSERT(m_client == client);
76         m_client = 0;
77     }
78
79     // Called by PendingScript when data arrives from the network.
80     void notifyAppendData(ScriptResource*);
81     void notifyFinished(Resource*);
82
83     // Called by ScriptStreamingTask when it has streamed all data to V8 and V8
84     // has processed it.
85     void streamingComplete();
86
87     static void removeSmallScriptThresholdForTesting()
88     {
89         kSmallScriptThreshold = 0;
90     }
91
92     static size_t smallScriptThreshold() { return kSmallScriptThreshold; }
93
94 private:
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;
98
99     ScriptStreamer(ScriptResource*, v8::ScriptCompiler::StreamedSource::Encoding, PendingScript::Type);
100
101     void notifyFinishedToClient();
102
103     static const char* startedStreamingHistogramName(PendingScript::Type);
104
105     static bool startStreamingInternal(PendingScript&, Settings*, ScriptState*, PendingScript::Type);
106
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.
114     bool m_detached;
115
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;
123
124     // Whether the script source code should be retrieved from the Resource
125     // instead of the ScriptStreamer.
126     bool m_streamingSuppressed;
127
128     // What kind of cached data V8 produces during streaming.
129     unsigned m_cachedDataType;
130
131     // For recording metrics for different types of scripts separately.
132     PendingScript::Type m_scriptType;
133 };
134
135 } // namespace blink
136
137 #endif // ScriptStreamer_h