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

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

Issue 680493002: Revert "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"
11 #include "bindings/core/v8/ScriptStreamingMode.h"
12 #include "bindings/core/v8/V8Binding.h" 11 #include "bindings/core/v8/V8Binding.h"
13 #include "bindings/core/v8/V8ScriptRunner.h" 12 #include "bindings/core/v8/V8ScriptRunner.h"
14 #include "core/dom/PendingScript.h" 13 #include "core/dom/PendingScript.h"
15 #include "core/frame/Settings.h" 14 #include "core/frame/Settings.h"
16 #include "platform/Task.h" 15 #include "platform/Task.h"
17 #include "platform/heap/Handle.h" 16 #include "platform/heap/Handle.h"
18 #include "public/platform/Platform.h" 17 #include "public/platform/Platform.h"
19 18
20 #include <gtest/gtest.h> 19 #include <gtest/gtest.h>
21 #include <v8.h> 20 #include <v8.h>
(...skipping 30 matching lines...) Expand all
52 } 51 }
53 52
54 PendingScriptWrapper(Element* element, ScriptResource* resource) 53 PendingScriptWrapper(Element* element, ScriptResource* resource)
55 : m_pendingScript(PendingScript(element, resource)) 54 : m_pendingScript(PendingScript(element, resource))
56 { 55 {
57 } 56 }
58 57
59 PendingScript m_pendingScript; 58 PendingScript m_pendingScript;
60 }; 59 };
61 60
62 // The bool param for ScriptStreamingTest controls whether to make the main 61 class ScriptStreamingTest : public testing::Test {
63 // thread block and wait for parsing.
64 class ScriptStreamingTest : public testing::TestWithParam<bool> {
65 public: 62 public:
66 ScriptStreamingTest() 63 ScriptStreamingTest()
67 : m_scope(v8::Isolate::GetCurrent()) 64 : m_scope(v8::Isolate::GetCurrent())
68 , m_settings(Settings::create()) 65 , m_settings(Settings::create())
69 , m_resourceRequest("http://www.streaming-test.com/") 66 , m_resourceRequest("http://www.streaming-test.com/")
70 , m_resource(new ScriptResource(m_resourceRequest, "text/utf-8")) 67 , m_resource(new ScriptResource(m_resourceRequest, "text/utf-8"))
71 , m_pendingScript(PendingScriptWrapper::create(0, m_resource)) // Takes ownership of m_resource. 68 , m_pendingScript(PendingScriptWrapper::create(0, m_resource)) // Takes ownership of m_resource.
72 { 69 {
73 m_settings->setV8ScriptStreamingEnabled(true); 70 m_settings->setV8ScriptStreamingEnabled(true);
74 if (GetParam())
75 m_settings->setV8ScriptStreamingMode(ScriptStreamingModeAllPlusBlock ParsingBlocking);
76 m_resource->setLoading(true); 71 m_resource->setLoading(true);
77 ScriptStreamer::setSmallScriptThresholdForTesting(0); 72 ScriptStreamer::setSmallScriptThresholdForTesting(0);
78 } 73 }
79 74
80 ScriptState* scriptState() const { return m_scope.scriptState(); } 75 ScriptState* scriptState() const { return m_scope.scriptState(); }
81 v8::Isolate* isolate() const { return m_scope.isolate(); } 76 v8::Isolate* isolate() const { return m_scope.isolate(); }
82 77
83 PendingScript& pendingScript() const { return m_pendingScript->get(); } 78 PendingScript& pendingScript() const { return m_pendingScript->get(); }
84 79
85 protected: 80 protected:
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
138 : m_finished(false) { } 133 : m_finished(false) { }
139 134
140 virtual void notifyFinished(Resource*) override { m_finished = true; } 135 virtual void notifyFinished(Resource*) override { m_finished = true; }
141 136
142 bool finished() const { return m_finished; } 137 bool finished() const { return m_finished; }
143 138
144 private: 139 private:
145 bool m_finished; 140 bool m_finished;
146 }; 141 };
147 142
148 TEST_P(ScriptStreamingTest, CompilingStreamedScript) 143 TEST_F(ScriptStreamingTest, CompilingStreamedScript)
149 { 144 {
150 // Test that we can successfully compile a streamed script. 145 // Test that we can successfully compile a streamed script.
151 ScriptStreamer::startStreaming(pendingScript(), m_settings.get(), m_scope.sc riptState(), PendingScript::ParsingBlocking); 146 ScriptStreamer::startStreaming(pendingScript(), m_settings.get(), m_scope.sc riptState(), PendingScript::ParsingBlocking);
152 TestScriptResourceClient client; 147 TestScriptResourceClient client;
153 pendingScript().watchForLoad(&client); 148 pendingScript().watchForLoad(&client);
154 149
155 appendData("function foo() {"); 150 appendData("function foo() {");
156 appendPadding(); 151 appendPadding();
157 appendData("return 5; }"); 152 appendData("return 5; }");
158 appendPadding(); 153 appendPadding();
159 appendData("foo();"); 154 appendData("foo();");
160 EXPECT_FALSE(client.finished()); 155 EXPECT_FALSE(client.finished());
161 finish(); 156 finish();
162 157
163 // Process tasks on the main thread until the streaming background thread 158 // Process tasks on the main thread until the streaming background thread
164 // has completed its tasks. 159 // has completed its tasks.
165 processTasksUntilStreamingComplete(); 160 processTasksUntilStreamingComplete();
166 EXPECT_TRUE(client.finished()); 161 EXPECT_TRUE(client.finished());
167 bool errorOccurred = false; 162 bool errorOccurred = false;
168 ScriptSourceCode sourceCode = pendingScript().getSource(KURL(), errorOccurre d); 163 ScriptSourceCode sourceCode = pendingScript().getSource(KURL(), errorOccurre d);
169 EXPECT_FALSE(errorOccurred); 164 EXPECT_FALSE(errorOccurred);
170 EXPECT_TRUE(sourceCode.streamer()); 165 EXPECT_TRUE(sourceCode.streamer());
171 v8::TryCatch tryCatch; 166 v8::TryCatch tryCatch;
172 v8::Handle<v8::Script> script = V8ScriptRunner::compileScript(sourceCode, is olate()); 167 v8::Handle<v8::Script> script = V8ScriptRunner::compileScript(sourceCode, is olate());
173 EXPECT_FALSE(script.IsEmpty()); 168 EXPECT_FALSE(script.IsEmpty());
174 EXPECT_FALSE(tryCatch.HasCaught()); 169 EXPECT_FALSE(tryCatch.HasCaught());
175 } 170 }
176 171
177 TEST_P(ScriptStreamingTest, CompilingStreamedScriptWithParseError) 172 TEST_F(ScriptStreamingTest, CompilingStreamedScriptWithParseError)
178 { 173 {
179 // Test that scripts with parse errors are handled properly. In those cases, 174 // Test that scripts with parse errors are handled properly. In those cases,
180 // the V8 side typically finished before loading finishes: make sure we 175 // the V8 side typically finished before loading finishes: make sure we
181 // handle it gracefully. 176 // handle it gracefully.
182 ScriptStreamer::startStreaming(pendingScript(), m_settings.get(), m_scope.sc riptState(), PendingScript::ParsingBlocking); 177 ScriptStreamer::startStreaming(pendingScript(), m_settings.get(), m_scope.sc riptState(), PendingScript::ParsingBlocking);
183 TestScriptResourceClient client; 178 TestScriptResourceClient client;
184 pendingScript().watchForLoad(&client); 179 pendingScript().watchForLoad(&client);
185 appendData("function foo() {"); 180 appendData("function foo() {");
186 appendData("this is the part which will be a parse error"); 181 appendData("this is the part which will be a parse error");
187 // V8 won't realize the parse error until it actually starts parsing the 182 // V8 won't realize the parse error until it actually starts parsing the
(...skipping 12 matching lines...) Expand all
200 bool errorOccurred = false; 195 bool errorOccurred = false;
201 ScriptSourceCode sourceCode = pendingScript().getSource(KURL(), errorOccurre d); 196 ScriptSourceCode sourceCode = pendingScript().getSource(KURL(), errorOccurre d);
202 EXPECT_FALSE(errorOccurred); 197 EXPECT_FALSE(errorOccurred);
203 EXPECT_TRUE(sourceCode.streamer()); 198 EXPECT_TRUE(sourceCode.streamer());
204 v8::TryCatch tryCatch; 199 v8::TryCatch tryCatch;
205 v8::Handle<v8::Script> script = V8ScriptRunner::compileScript(sourceCode, is olate()); 200 v8::Handle<v8::Script> script = V8ScriptRunner::compileScript(sourceCode, is olate());
206 EXPECT_TRUE(script.IsEmpty()); 201 EXPECT_TRUE(script.IsEmpty());
207 EXPECT_TRUE(tryCatch.HasCaught()); 202 EXPECT_TRUE(tryCatch.HasCaught());
208 } 203 }
209 204
210 TEST_P(ScriptStreamingTest, CancellingStreaming) 205 TEST_F(ScriptStreamingTest, CancellingStreaming)
211 { 206 {
212 // Test that the upper layers (PendingScript and up) can be ramped down 207 // Test that the upper layers (PendingScript and up) can be ramped down
213 // while streaming is ongoing, and ScriptStreamer handles it gracefully. 208 // while streaming is ongoing, and ScriptStreamer handles it gracefully.
214 ScriptStreamer::startStreaming(pendingScript(), m_settings.get(), m_scope.sc riptState(), PendingScript::ParsingBlocking); 209 ScriptStreamer::startStreaming(pendingScript(), m_settings.get(), m_scope.sc riptState(), PendingScript::ParsingBlocking);
215 TestScriptResourceClient client; 210 TestScriptResourceClient client;
216 pendingScript().watchForLoad(&client); 211 pendingScript().watchForLoad(&client);
217 appendData("function foo() {"); 212 appendData("function foo() {");
218 213
219 // In general, we cannot control what the background thread is doing 214 // In general, we cannot control what the background thread is doing
220 // (whether it's parsing or waiting for more data). In this test, we have 215 // (whether it's parsing or waiting for more data). In this test, we have
221 // given it so little data that it's surely waiting for more. 216 // given it so little data that it's surely waiting for more.
222 217
223 // Simulate cancelling the network load (e.g., because the user navigated 218 // Simulate cancelling the network load (e.g., because the user navigated
224 // away). 219 // away).
225 EXPECT_FALSE(client.finished()); 220 EXPECT_FALSE(client.finished());
226 pendingScript().stopWatchingForLoad(&client); 221 pendingScript().stopWatchingForLoad(&client);
227 pendingScript().releaseElementAndClear(); 222 pendingScript().releaseElementAndClear();
228 m_pendingScript = PendingScriptWrapper::create(); // This will destroy m_res ource. 223 m_pendingScript = PendingScriptWrapper::create(); // This will destroy m_res ource.
229 m_resource = 0; 224 m_resource = 0;
230 225
231 // The V8 side will complete too. This should not crash. We don't receive 226 // The V8 side will complete too. This should not crash. We don't receive
232 // any results from the streaming and the client doesn't get notified. 227 // any results from the streaming and the client doesn't get notified.
233 processTasksUntilStreamingComplete(); 228 processTasksUntilStreamingComplete();
234 EXPECT_FALSE(client.finished()); 229 EXPECT_FALSE(client.finished());
235 } 230 }
236 231
237 TEST_P(ScriptStreamingTest, SuppressingStreaming) 232 TEST_F(ScriptStreamingTest, SuppressingStreaming)
238 { 233 {
239 // If we notice during streaming that there is a code cache, streaming 234 // If we notice during streaming that there is a code cache, streaming
240 // is suppressed (V8 doesn't parse while the script is loading), and the 235 // is suppressed (V8 doesn't parse while the script is loading), and the
241 // upper layer (ScriptResourceClient) should get a notification when the 236 // upper layer (ScriptResourceClient) should get a notification when the
242 // script is loaded. 237 // script is loaded.
243 ScriptStreamer::startStreaming(pendingScript(), m_settings.get(), m_scope.sc riptState(), PendingScript::ParsingBlocking); 238 ScriptStreamer::startStreaming(pendingScript(), m_settings.get(), m_scope.sc riptState(), PendingScript::ParsingBlocking);
244 TestScriptResourceClient client; 239 TestScriptResourceClient client;
245 pendingScript().watchForLoad(&client); 240 pendingScript().watchForLoad(&client);
246 appendData("function foo() {"); 241 appendData("function foo() {");
247 appendPadding(); 242 appendPadding();
248 243
249 m_resource->setCachedMetadata(V8ScriptRunner::tagForCodeCache(), "X", 1, Res ource::CacheLocally); 244 m_resource->setCachedMetadata(V8ScriptRunner::tagForCodeCache(), "X", 1, Res ource::CacheLocally);
250 245
251 appendPadding(); 246 appendPadding();
252 finish(); 247 finish();
253 processTasksUntilStreamingComplete(); 248 processTasksUntilStreamingComplete();
254 EXPECT_TRUE(client.finished()); 249 EXPECT_TRUE(client.finished());
255 250
256 bool errorOccurred = false; 251 bool errorOccurred = false;
257 ScriptSourceCode sourceCode = pendingScript().getSource(KURL(), errorOccurre d); 252 ScriptSourceCode sourceCode = pendingScript().getSource(KURL(), errorOccurre d);
258 EXPECT_FALSE(errorOccurred); 253 EXPECT_FALSE(errorOccurred);
259 // ScriptSourceCode doesn't refer to the streamer, since we have suppressed 254 // ScriptSourceCode doesn't refer to the streamer, since we have suppressed
260 // the streaming and resumed the non-streaming code path for script 255 // the streaming and resumed the non-streaming code path for script
261 // compilation. 256 // compilation.
262 EXPECT_FALSE(sourceCode.streamer()); 257 EXPECT_FALSE(sourceCode.streamer());
263 } 258 }
264 259
265 TEST_P(ScriptStreamingTest, EmptyScripts) 260 TEST_F(ScriptStreamingTest, EmptyScripts)
266 { 261 {
267 // Empty scripts should also be streamed properly, that is, the upper layer 262 // Empty scripts should also be streamed properly, that is, the upper layer
268 // (ScriptResourceClient) should be notified when an empty script has been 263 // (ScriptResourceClient) should be notified when an empty script has been
269 // loaded. 264 // loaded.
270 ScriptStreamer::startStreaming(pendingScript(), m_settings.get(), m_scope.sc riptState(), PendingScript::ParsingBlocking); 265 ScriptStreamer::startStreaming(pendingScript(), m_settings.get(), m_scope.sc riptState(), PendingScript::ParsingBlocking);
271 TestScriptResourceClient client; 266 TestScriptResourceClient client;
272 pendingScript().watchForLoad(&client); 267 pendingScript().watchForLoad(&client);
273 268
274 // Finish the script without sending any data. 269 // Finish the script without sending any data.
275 finish(); 270 finish();
276 // The finished notification should arrive immediately and not be cycled 271 // The finished notification should arrive immediately and not be cycled
277 // through a background thread. 272 // through a background thread.
278 EXPECT_TRUE(client.finished()); 273 EXPECT_TRUE(client.finished());
279 274
280 bool errorOccurred = false; 275 bool errorOccurred = false;
281 ScriptSourceCode sourceCode = pendingScript().getSource(KURL(), errorOccurre d); 276 ScriptSourceCode sourceCode = pendingScript().getSource(KURL(), errorOccurre d);
282 EXPECT_FALSE(errorOccurred); 277 EXPECT_FALSE(errorOccurred);
283 EXPECT_FALSE(sourceCode.streamer()); 278 EXPECT_FALSE(sourceCode.streamer());
284 } 279 }
285 280
286 TEST_P(ScriptStreamingTest, SmallScripts) 281 TEST_F(ScriptStreamingTest, SmallScripts)
287 { 282 {
288 // Small scripts shouldn't be streamed. 283 // Small scripts shouldn't be streamed.
289 ScriptStreamer::setSmallScriptThresholdForTesting(100); 284 ScriptStreamer::setSmallScriptThresholdForTesting(100);
290 285
291 ScriptStreamer::startStreaming(pendingScript(), m_settings.get(), m_scope.sc riptState(), PendingScript::ParsingBlocking); 286 ScriptStreamer::startStreaming(pendingScript(), m_settings.get(), m_scope.sc riptState(), PendingScript::ParsingBlocking);
292 TestScriptResourceClient client; 287 TestScriptResourceClient client;
293 pendingScript().watchForLoad(&client); 288 pendingScript().watchForLoad(&client);
294 289
295 appendData("function foo() { }"); 290 appendData("function foo() { }");
296 291
297 finish(); 292 finish();
298 293
299 // The finished notification should arrive immediately and not be cycled 294 // The finished notification should arrive immediately and not be cycled
300 // through a background thread. 295 // through a background thread.
301 EXPECT_TRUE(client.finished()); 296 EXPECT_TRUE(client.finished());
302 297
303 bool errorOccurred = false; 298 bool errorOccurred = false;
304 ScriptSourceCode sourceCode = pendingScript().getSource(KURL(), errorOccurre d); 299 ScriptSourceCode sourceCode = pendingScript().getSource(KURL(), errorOccurre d);
305 EXPECT_FALSE(errorOccurred); 300 EXPECT_FALSE(errorOccurred);
306 EXPECT_FALSE(sourceCode.streamer()); 301 EXPECT_FALSE(sourceCode.streamer());
307 } 302 }
308 303
309 TEST_P(ScriptStreamingTest, ScriptsWithSmallFirstChunk) 304 TEST_F(ScriptStreamingTest, ScriptsWithSmallFirstChunk)
310 { 305 {
311 // If a script is long enough, if should be streamed, even if the first data 306 // If a script is long enough, if should be streamed, even if the first data
312 // chunk is small. 307 // chunk is small.
313 ScriptStreamer::setSmallScriptThresholdForTesting(100); 308 ScriptStreamer::setSmallScriptThresholdForTesting(100);
314 309
315 ScriptStreamer::startStreaming(pendingScript(), m_settings.get(), m_scope.sc riptState(), PendingScript::ParsingBlocking); 310 ScriptStreamer::startStreaming(pendingScript(), m_settings.get(), m_scope.sc riptState(), PendingScript::ParsingBlocking);
316 TestScriptResourceClient client; 311 TestScriptResourceClient client;
317 pendingScript().watchForLoad(&client); 312 pendingScript().watchForLoad(&client);
318 313
319 // This is the first data chunk which is small. 314 // This is the first data chunk which is small.
320 appendData("function foo() { }"); 315 appendData("function foo() { }");
321 appendPadding(); 316 appendPadding();
322 appendPadding(); 317 appendPadding();
323 appendPadding(); 318 appendPadding();
324 319
325 finish(); 320 finish();
326 321
327 processTasksUntilStreamingComplete(); 322 processTasksUntilStreamingComplete();
328 EXPECT_TRUE(client.finished()); 323 EXPECT_TRUE(client.finished());
329 bool errorOccurred = false; 324 bool errorOccurred = false;
330 ScriptSourceCode sourceCode = pendingScript().getSource(KURL(), errorOccurre d); 325 ScriptSourceCode sourceCode = pendingScript().getSource(KURL(), errorOccurre d);
331 EXPECT_FALSE(errorOccurred); 326 EXPECT_FALSE(errorOccurred);
332 EXPECT_TRUE(sourceCode.streamer()); 327 EXPECT_TRUE(sourceCode.streamer());
333 v8::TryCatch tryCatch; 328 v8::TryCatch tryCatch;
334 v8::Handle<v8::Script> script = V8ScriptRunner::compileScript(sourceCode, is olate()); 329 v8::Handle<v8::Script> script = V8ScriptRunner::compileScript(sourceCode, is olate());
335 EXPECT_FALSE(script.IsEmpty()); 330 EXPECT_FALSE(script.IsEmpty());
336 EXPECT_FALSE(tryCatch.HasCaught()); 331 EXPECT_FALSE(tryCatch.HasCaught());
337 } 332 }
338 333
339 INSTANTIATE_TEST_CASE_P(ScriptStreamingInstantiation, ScriptStreamingTest, ::tes ting::Values(false, true));
340
341 } // namespace 334 } // namespace
342 335
343 } // namespace blink 336 } // namespace blink
OLDNEW
« no previous file with comments | « Source/bindings/core/v8/ScriptStreamer.cpp ('k') | Source/bindings/core/v8/ScriptStreamerThread.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698