Update To 11.40.268.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 "bindings/core/v8/ScriptStreamingMode.h"
9 #include "core/dom/PendingScript.h"
10 #include "wtf/RefCounted.h"
11
12 #include <v8.h>
13
14 namespace blink {
15
16 class PendingScript;
17 class Resource;
18 class ScriptResource;
19 class ScriptResourceClient;
20 class ScriptState;
21 class Settings;
22 class SourceStream;
23
24 // ScriptStreamer streams incomplete script data to V8 so that it can be parsed
25 // while it's loaded. PendingScript holds a reference to ScriptStreamer. At the
26 // moment, ScriptStreamer is only used for parser blocking scripts; this means
27 // that the Document stays stable and no other scripts are executing while we're
28 // streaming. It is possible, though, that Document and the PendingScript are
29 // destroyed while the streaming is in progress, and ScriptStreamer handles it
30 // gracefully.
31 class ScriptStreamer : public RefCounted<ScriptStreamer> {
32     WTF_MAKE_NONCOPYABLE(ScriptStreamer);
33 public:
34     // Launches a task (on a background thread) which will stream the given
35     // PendingScript into V8 as it loads. It's also possible that V8 cannot
36     // stream the given script; in that case this function returns
37     // false. Internally, this constructs a ScriptStreamer and attaches it to
38     // the PendingScript. Use ScriptStreamer::addClient to get notified when the
39     // streaming finishes.
40     static void startStreaming(PendingScript&, Settings*, ScriptState*, PendingScript::Type);
41
42     bool isFinished() const
43     {
44         return m_loadingFinished && (m_parsingFinished || m_streamingSuppressed);
45     }
46
47     v8::ScriptCompiler::StreamedSource* source() { return m_source.get(); }
48     ScriptResource* resource() const { return m_resource; }
49
50     // Called when the script is not needed any more (e.g., loading was
51     // cancelled). After calling cancel, PendingScript can drop its reference to
52     // ScriptStreamer, and ScriptStreamer takes care of eventually deleting
53     // itself (after the V8 side has finished too).
54     void cancel();
55
56     // When the streaming is suppressed, the data is not given to V8, but
57     // ScriptStreamer still watches the resource load and notifies the upper
58     // layers when loading is finished. It is used in situations when we have
59     // started streaming but then we detect we don't want to stream (e.g., when
60     // we have the code cache for the script) and we still want to parse and
61     // execute it when it has finished loading.
62     void suppressStreaming();
63     bool streamingSuppressed() const { return m_streamingSuppressed; }
64
65     unsigned cachedDataType() const;
66
67     void addClient(ScriptResourceClient* client)
68     {
69         ASSERT(!m_client);
70         m_client = client;
71         notifyFinishedToClient();
72     }
73
74     void removeClient(ScriptResourceClient* client)
75     {
76         ASSERT(m_client == client);
77         m_client = 0;
78     }
79
80     // Called by PendingScript when data arrives from the network.
81     void notifyAppendData(ScriptResource*);
82     void notifyFinished(Resource*);
83
84     // Called by ScriptStreamingTask when it has streamed all data to V8 and V8
85     // has processed it.
86     void streamingCompleteOnBackgroundThread();
87
88     static void setSmallScriptThresholdForTesting(size_t threshold)
89     {
90         kSmallScriptThreshold = threshold;
91     }
92
93     static size_t smallScriptThreshold() { return kSmallScriptThreshold; }
94
95 private:
96     // Scripts whose first data chunk is smaller than this constant won't be
97     // streamed. Non-const for testing.
98     static size_t kSmallScriptThreshold;
99
100     ScriptStreamer(ScriptResource*, PendingScript::Type, ScriptStreamingMode, ScriptState*, v8::ScriptCompiler::CompileOptions);
101
102     void streamingComplete();
103     void notifyFinishedToClient();
104
105     bool shouldBlockMainThread() const
106     {
107         return m_scriptStreamingMode == ScriptStreamingModeAllPlusBlockParsingBlocking && m_scriptType == PendingScript::ParsingBlocking;
108     }
109
110     static const char* startedStreamingHistogramName(PendingScript::Type);
111
112     static bool startStreamingInternal(PendingScript&, Settings*, ScriptState*, PendingScript::Type);
113
114     // This pointer is weak. If PendingScript and its Resource are deleted
115     // before ScriptStreamer, PendingScript will notify ScriptStreamer of its
116     // deletion by calling cancel().
117     ScriptResource* m_resource;
118     // Whether ScriptStreamer is detached from the Resource. In those cases, the
119     // script data is not needed any more, and the client won't get notified
120     // when the loading and streaming are done.
121     bool m_detached;
122
123     SourceStream* m_stream;
124     OwnPtr<v8::ScriptCompiler::StreamedSource> m_source;
125     ScriptResourceClient* m_client;
126     bool m_loadingFinished; // Whether loading from the network is done.
127     // Whether the V8 side processing is done. Will be used by the main thread
128     // and the streamer thread; guarded by m_mutex.
129     bool m_parsingFinished;
130     // Whether we have received enough data to start the streaming.
131     bool m_haveEnoughDataForStreaming;
132
133     // Whether the script source code should be retrieved from the Resource
134     // instead of the ScriptStreamer; guarded by m_mutex.
135     bool m_streamingSuppressed;
136
137     // What kind of cached data V8 produces during streaming.
138     v8::ScriptCompiler::CompileOptions m_compileOptions;
139
140     RefPtr<ScriptState> m_scriptState;
141
142     // For recording metrics for different types of scripts separately.
143     PendingScript::Type m_scriptType;
144
145     // Streaming mode defines whether the main thread should block and wait for
146     // the parsing to complete after the load has finished. See
147     // ScriptStreamer::notifyFinished for more information.
148     ScriptStreamingMode m_scriptStreamingMode;
149     Mutex m_mutex;
150     ThreadCondition m_parsingFinishedCondition;
151     // Whether the main thread is currently waiting on the parser thread in
152     // notifyFinished(). This also defines which thread should do the cleanup of
153     // the parsing task: if the main thread is waiting, the main thread should
154     // do it, otherwise the parser thread should do it. Guarded by m_mutex.
155     bool m_mainThreadWaitingForParserThread;
156 };
157
158 } // namespace blink
159
160 #endif // ScriptStreamer_h