Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(530)

Side by Side Diff: Source/bindings/core/v8/ScriptStreamerTest.cpp

Issue 651163002: Script streaming: Add an option to make the main thread block (wait for parsing) (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: . Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 5
6 #include "config.h" 6 #include "config.h"
7 #include "bindings/core/v8/ScriptStreamer.h" 7 #include "bindings/core/v8/ScriptStreamer.h"
8 8
9 #include "bindings/core/v8/ScriptSourceCode.h" 9 #include "bindings/core/v8/ScriptSourceCode.h"
10 #include "bindings/core/v8/ScriptStreamerThread.h" 10 #include "bindings/core/v8/ScriptStreamerThread.h"
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
51 } 51 }
52 52
53 PendingScriptWrapper(Element* element, ScriptResource* resource) 53 PendingScriptWrapper(Element* element, ScriptResource* resource)
54 : m_pendingScript(PendingScript(element, resource)) 54 : m_pendingScript(PendingScript(element, resource))
55 { 55 {
56 } 56 }
57 57
58 PendingScript m_pendingScript; 58 PendingScript m_pendingScript;
59 }; 59 };
60 60
61 class ScriptStreamingTest : public testing::Test { 61 // The bool param for ScriptStreamingTest controls whether to make the main
62 // thread block and wait for parsing.
63 class ScriptStreamingTest : public testing::TestWithParam<bool> {
62 public: 64 public:
63 ScriptStreamingTest() 65 ScriptStreamingTest()
64 : m_scope(v8::Isolate::GetCurrent()) 66 : m_scope(v8::Isolate::GetCurrent())
65 , m_settings(Settings::create()) 67 , m_settings(Settings::create())
66 , m_resourceRequest("http://www.streaming-test.com/") 68 , m_resourceRequest("http://www.streaming-test.com/")
67 , m_resource(new ScriptResource(m_resourceRequest, "text/utf-8")) 69 , m_resource(new ScriptResource(m_resourceRequest, "text/utf-8"))
68 , m_pendingScript(PendingScriptWrapper::create(0, m_resource)) // Takes ownership of m_resource. 70 , m_pendingScript(PendingScriptWrapper::create(0, m_resource)) // Takes ownership of m_resource.
69 { 71 {
70 m_settings->setV8ScriptStreamingEnabled(true); 72 m_settings->setV8ScriptStreamingEnabled(true);
73 m_settings->setV8ScriptStreamingBlocking(GetParam());
71 m_resource->setLoading(true); 74 m_resource->setLoading(true);
72 ScriptStreamer::removeSmallScriptThresholdForTesting(); 75 ScriptStreamer::removeSmallScriptThresholdForTesting();
73 } 76 }
74 77
75 ScriptState* scriptState() const { return m_scope.scriptState(); } 78 ScriptState* scriptState() const { return m_scope.scriptState(); }
76 v8::Isolate* isolate() const { return m_scope.isolate(); } 79 v8::Isolate* isolate() const { return m_scope.isolate(); }
77 80
78 PendingScript& pendingScript() const { return m_pendingScript->get(); } 81 PendingScript& pendingScript() const { return m_pendingScript->get(); }
79 82
80 protected: 83 protected:
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
133 : m_finished(false) { } 136 : m_finished(false) { }
134 137
135 virtual void notifyFinished(Resource*) override { m_finished = true; } 138 virtual void notifyFinished(Resource*) override { m_finished = true; }
136 139
137 bool finished() const { return m_finished; } 140 bool finished() const { return m_finished; }
138 141
139 private: 142 private:
140 bool m_finished; 143 bool m_finished;
141 }; 144 };
142 145
143 TEST_F(ScriptStreamingTest, CompilingStreamedScript) 146 TEST_P(ScriptStreamingTest, CompilingStreamedScript)
144 { 147 {
145 // Test that we can successfully compile a streamed script. 148 // Test that we can successfully compile a streamed script.
146 ScriptStreamer::startStreaming(pendingScript(), m_settings.get(), m_scope.sc riptState(), PendingScript::ParsingBlocking); 149 ScriptStreamer::startStreaming(pendingScript(), m_settings.get(), m_scope.sc riptState(), PendingScript::ParsingBlocking);
147 TestScriptResourceClient client; 150 TestScriptResourceClient client;
148 pendingScript().watchForLoad(&client); 151 pendingScript().watchForLoad(&client);
149 152
150 appendData("function foo() {"); 153 appendData("function foo() {");
151 appendPadding(); 154 appendPadding();
152 appendData("return 5; }"); 155 appendData("return 5; }");
153 appendPadding(); 156 appendPadding();
154 appendData("foo();"); 157 appendData("foo();");
155 EXPECT_FALSE(client.finished()); 158 EXPECT_FALSE(client.finished());
156 finish(); 159 finish();
157 160
158 // Process tasks on the main thread until the streaming background thread 161 // Process tasks on the main thread until the streaming background thread
159 // has completed its tasks. 162 // has completed its tasks.
160 processTasksUntilStreamingComplete(); 163 processTasksUntilStreamingComplete();
161 EXPECT_TRUE(client.finished()); 164 EXPECT_TRUE(client.finished());
162 bool errorOccurred = false; 165 bool errorOccurred = false;
163 ScriptSourceCode sourceCode = pendingScript().getSource(KURL(), errorOccurre d); 166 ScriptSourceCode sourceCode = pendingScript().getSource(KURL(), errorOccurre d);
164 EXPECT_FALSE(errorOccurred); 167 EXPECT_FALSE(errorOccurred);
165 EXPECT_TRUE(sourceCode.streamer()); 168 EXPECT_TRUE(sourceCode.streamer());
166 v8::TryCatch tryCatch; 169 v8::TryCatch tryCatch;
167 v8::Handle<v8::Script> script = V8ScriptRunner::compileScript(sourceCode, is olate()); 170 v8::Handle<v8::Script> script = V8ScriptRunner::compileScript(sourceCode, is olate());
168 EXPECT_FALSE(script.IsEmpty()); 171 EXPECT_FALSE(script.IsEmpty());
169 EXPECT_FALSE(tryCatch.HasCaught()); 172 EXPECT_FALSE(tryCatch.HasCaught());
170 } 173 }
171 174
172 TEST_F(ScriptStreamingTest, CompilingStreamedScriptWithParseError) 175 TEST_P(ScriptStreamingTest, CompilingStreamedScriptWithParseError)
173 { 176 {
174 // Test that scripts with parse errors are handled properly. In those cases, 177 // Test that scripts with parse errors are handled properly. In those cases,
175 // the V8 side typically finished before loading finishes: make sure we 178 // the V8 side typically finished before loading finishes: make sure we
176 // handle it gracefully. 179 // handle it gracefully.
177 ScriptStreamer::startStreaming(pendingScript(), m_settings.get(), m_scope.sc riptState(), PendingScript::ParsingBlocking); 180 ScriptStreamer::startStreaming(pendingScript(), m_settings.get(), m_scope.sc riptState(), PendingScript::ParsingBlocking);
178 TestScriptResourceClient client; 181 TestScriptResourceClient client;
179 pendingScript().watchForLoad(&client); 182 pendingScript().watchForLoad(&client);
180 appendData("function foo() {"); 183 appendData("function foo() {");
181 appendData("this is the part which will be a parse error"); 184 appendData("this is the part which will be a parse error");
182 // V8 won't realize the parse error until it actually starts parsing the 185 // V8 won't realize the parse error until it actually starts parsing the
(...skipping 12 matching lines...) Expand all
195 bool errorOccurred = false; 198 bool errorOccurred = false;
196 ScriptSourceCode sourceCode = pendingScript().getSource(KURL(), errorOccurre d); 199 ScriptSourceCode sourceCode = pendingScript().getSource(KURL(), errorOccurre d);
197 EXPECT_FALSE(errorOccurred); 200 EXPECT_FALSE(errorOccurred);
198 EXPECT_TRUE(sourceCode.streamer()); 201 EXPECT_TRUE(sourceCode.streamer());
199 v8::TryCatch tryCatch; 202 v8::TryCatch tryCatch;
200 v8::Handle<v8::Script> script = V8ScriptRunner::compileScript(sourceCode, is olate()); 203 v8::Handle<v8::Script> script = V8ScriptRunner::compileScript(sourceCode, is olate());
201 EXPECT_TRUE(script.IsEmpty()); 204 EXPECT_TRUE(script.IsEmpty());
202 EXPECT_TRUE(tryCatch.HasCaught()); 205 EXPECT_TRUE(tryCatch.HasCaught());
203 } 206 }
204 207
205 TEST_F(ScriptStreamingTest, CancellingStreaming) 208 TEST_P(ScriptStreamingTest, CancellingStreaming)
206 { 209 {
207 // Test that the upper layers (PendingScript and up) can be ramped down 210 // Test that the upper layers (PendingScript and up) can be ramped down
208 // while streaming is ongoing, and ScriptStreamer handles it gracefully. 211 // while streaming is ongoing, and ScriptStreamer handles it gracefully.
209 ScriptStreamer::startStreaming(pendingScript(), m_settings.get(), m_scope.sc riptState(), PendingScript::ParsingBlocking); 212 ScriptStreamer::startStreaming(pendingScript(), m_settings.get(), m_scope.sc riptState(), PendingScript::ParsingBlocking);
210 TestScriptResourceClient client; 213 TestScriptResourceClient client;
211 pendingScript().watchForLoad(&client); 214 pendingScript().watchForLoad(&client);
212 appendData("function foo() {"); 215 appendData("function foo() {");
213 216
214 // In general, we cannot control what the background thread is doing 217 // In general, we cannot control what the background thread is doing
215 // (whether it's parsing or waiting for more data). In this test, we have 218 // (whether it's parsing or waiting for more data). In this test, we have
216 // given it so little data that it's surely waiting for more. 219 // given it so little data that it's surely waiting for more.
217 220
218 // Simulate cancelling the network load (e.g., because the user navigated 221 // Simulate cancelling the network load (e.g., because the user navigated
219 // away). 222 // away).
220 EXPECT_FALSE(client.finished()); 223 EXPECT_FALSE(client.finished());
221 pendingScript().stopWatchingForLoad(&client); 224 pendingScript().stopWatchingForLoad(&client);
222 m_pendingScript = PendingScriptWrapper::create(); // This will destroy m_res ource. 225 m_pendingScript = PendingScriptWrapper::create(); // This will destroy m_res ource.
223 m_resource = 0; 226 m_resource = 0;
224 227
225 // The V8 side will complete too. This should not crash. We don't receive 228 // The V8 side will complete too. This should not crash. We don't receive
226 // any results from the streaming and the client doesn't get notified. 229 // any results from the streaming and the client doesn't get notified.
227 processTasksUntilStreamingComplete(); 230 processTasksUntilStreamingComplete();
228 EXPECT_FALSE(client.finished()); 231 EXPECT_FALSE(client.finished());
229 } 232 }
230 233
231 TEST_F(ScriptStreamingTest, SuppressingStreaming) 234 TEST_P(ScriptStreamingTest, SuppressingStreaming)
232 { 235 {
233 // If we notice during streaming that there is a code cache, streaming 236 // If we notice during streaming that there is a code cache, streaming
234 // is suppressed (V8 doesn't parse while the script is loading), and the 237 // is suppressed (V8 doesn't parse while the script is loading), and the
235 // upper layer (ScriptResourceClient) should get a notification when the 238 // upper layer (ScriptResourceClient) should get a notification when the
236 // script is loaded. 239 // script is loaded.
237 ScriptStreamer::startStreaming(pendingScript(), m_settings.get(), m_scope.sc riptState(), PendingScript::ParsingBlocking); 240 ScriptStreamer::startStreaming(pendingScript(), m_settings.get(), m_scope.sc riptState(), PendingScript::ParsingBlocking);
238 TestScriptResourceClient client; 241 TestScriptResourceClient client;
239 pendingScript().watchForLoad(&client); 242 pendingScript().watchForLoad(&client);
240 appendData("function foo() {"); 243 appendData("function foo() {");
241 appendPadding(); 244 appendPadding();
242 245
243 m_resource->setCachedMetadata(V8ScriptRunner::tagForCodeCache(), "X", 1, Res ource::CacheLocally); 246 m_resource->setCachedMetadata(V8ScriptRunner::tagForCodeCache(), "X", 1, Res ource::CacheLocally);
244 247
245 appendPadding(); 248 appendPadding();
246 finish(); 249 finish();
247 processTasksUntilStreamingComplete(); 250 processTasksUntilStreamingComplete();
248 EXPECT_TRUE(client.finished()); 251 EXPECT_TRUE(client.finished());
249 252
250 bool errorOccurred = false; 253 bool errorOccurred = false;
251 ScriptSourceCode sourceCode = pendingScript().getSource(KURL(), errorOccurre d); 254 ScriptSourceCode sourceCode = pendingScript().getSource(KURL(), errorOccurre d);
252 EXPECT_FALSE(errorOccurred); 255 EXPECT_FALSE(errorOccurred);
253 // ScriptSourceCode doesn't refer to the streamer, since we have suppressed 256 // ScriptSourceCode doesn't refer to the streamer, since we have suppressed
254 // the streaming and resumed the non-streaming code path for script 257 // the streaming and resumed the non-streaming code path for script
255 // compilation. 258 // compilation.
256 EXPECT_FALSE(sourceCode.streamer()); 259 EXPECT_FALSE(sourceCode.streamer());
257 } 260 }
258 261
259 TEST_F(ScriptStreamingTest, EmptyScripts) 262 TEST_P(ScriptStreamingTest, EmptyScripts)
260 { 263 {
261 // Empty scripts should also be streamed properly, that is, the upper layer 264 // Empty scripts should also be streamed properly, that is, the upper layer
262 // (ScriptResourceClient) should be notified when an empty script has been 265 // (ScriptResourceClient) should be notified when an empty script has been
263 // loaded. 266 // loaded.
264 ScriptStreamer::startStreaming(pendingScript(), m_settings.get(), m_scope.sc riptState(), PendingScript::ParsingBlocking); 267 ScriptStreamer::startStreaming(pendingScript(), m_settings.get(), m_scope.sc riptState(), PendingScript::ParsingBlocking);
265 TestScriptResourceClient client; 268 TestScriptResourceClient client;
266 pendingScript().watchForLoad(&client); 269 pendingScript().watchForLoad(&client);
267 270
268 // Finish the script without sending any data. 271 // Finish the script without sending any data.
269 finish(); 272 finish();
270 // The finished notification should arrive immediately and not be cycled 273 // The finished notification should arrive immediately and not be cycled
271 // through a background thread. 274 // through a background thread.
272 EXPECT_TRUE(client.finished()); 275 EXPECT_TRUE(client.finished());
273 276
274 bool errorOccurred = false; 277 bool errorOccurred = false;
275 ScriptSourceCode sourceCode = pendingScript().getSource(KURL(), errorOccurre d); 278 ScriptSourceCode sourceCode = pendingScript().getSource(KURL(), errorOccurre d);
276 EXPECT_FALSE(errorOccurred); 279 EXPECT_FALSE(errorOccurred);
277 EXPECT_FALSE(sourceCode.streamer()); 280 EXPECT_FALSE(sourceCode.streamer());
278 } 281 }
279 282
283 INSTANTIATE_TEST_CASE_P(ScriptStreamingInstantiation, ScriptStreamingTest, ::tes ting::Values(false, true));
284
280 } // namespace 285 } // namespace
281 286
282 } // namespace blink 287 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698