OLD | NEW |
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 #include "bindings/core/v8/ScriptStreamer.h" | 5 #include "bindings/core/v8/ScriptStreamer.h" |
6 | 6 |
7 #include <memory> | 7 #include <memory> |
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/V8Binding.h" | 11 #include "bindings/core/v8/V8Binding.h" |
12 #include "bindings/core/v8/V8BindingForTesting.h" | 12 #include "bindings/core/v8/V8BindingForTesting.h" |
13 #include "bindings/core/v8/V8ScriptRunner.h" | 13 #include "bindings/core/v8/V8ScriptRunner.h" |
| 14 #include "core/dom/ClassicScript.h" |
14 #include "core/dom/Element.h" | 15 #include "core/dom/Element.h" |
15 #include "core/dom/PendingScript.h" | 16 #include "core/dom/PendingScript.h" |
16 #include "core/frame/Settings.h" | 17 #include "core/frame/Settings.h" |
17 #include "platform/heap/Handle.h" | 18 #include "platform/heap/Handle.h" |
18 #include "platform/testing/UnitTestHelpers.h" | 19 #include "platform/testing/UnitTestHelpers.h" |
19 #include "public/platform/Platform.h" | 20 #include "public/platform/Platform.h" |
20 #include "public/platform/WebScheduler.h" | 21 #include "public/platform/WebScheduler.h" |
21 #include "testing/gtest/include/gtest/gtest.h" | 22 #include "testing/gtest/include/gtest/gtest.h" |
22 #include "v8/include/v8.h" | 23 #include "v8/include/v8.h" |
23 | 24 |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
122 appendData("foo();"); | 123 appendData("foo();"); |
123 EXPECT_FALSE(client->finished()); | 124 EXPECT_FALSE(client->finished()); |
124 finish(); | 125 finish(); |
125 | 126 |
126 // Process tasks on the main thread until the streaming background thread | 127 // Process tasks on the main thread until the streaming background thread |
127 // has completed its tasks. | 128 // has completed its tasks. |
128 processTasksUntilStreamingComplete(); | 129 processTasksUntilStreamingComplete(); |
129 EXPECT_TRUE(client->finished()); | 130 EXPECT_TRUE(client->finished()); |
130 bool errorOccurred = false; | 131 bool errorOccurred = false; |
131 ScriptSourceCode sourceCode = | 132 ScriptSourceCode sourceCode = |
132 getPendingScript()->getSource(KURL(), errorOccurred); | 133 getPendingScript()->getSource(KURL(), errorOccurred)->scriptSourceCode(); |
133 EXPECT_FALSE(errorOccurred); | 134 EXPECT_FALSE(errorOccurred); |
134 EXPECT_TRUE(sourceCode.streamer()); | 135 EXPECT_TRUE(sourceCode.streamer()); |
135 v8::TryCatch tryCatch(scope.isolate()); | 136 v8::TryCatch tryCatch(scope.isolate()); |
136 v8::Local<v8::Script> script; | 137 v8::Local<v8::Script> script; |
137 EXPECT_TRUE(V8ScriptRunner::compileScript(sourceCode, scope.isolate(), | 138 EXPECT_TRUE(V8ScriptRunner::compileScript(sourceCode, scope.isolate(), |
138 SharableCrossOrigin, | 139 SharableCrossOrigin, |
139 V8CacheOptionsDefault) | 140 V8CacheOptionsDefault) |
140 .ToLocal(&script)); | 141 .ToLocal(&script)); |
141 EXPECT_FALSE(tryCatch.HasCaught()); | 142 EXPECT_FALSE(tryCatch.HasCaught()); |
142 } | 143 } |
(...skipping 18 matching lines...) Expand all Loading... |
161 | 162 |
162 // Force the V8 side to finish before the loading. | 163 // Force the V8 side to finish before the loading. |
163 processTasksUntilStreamingComplete(); | 164 processTasksUntilStreamingComplete(); |
164 EXPECT_FALSE(client->finished()); | 165 EXPECT_FALSE(client->finished()); |
165 | 166 |
166 finish(); | 167 finish(); |
167 EXPECT_TRUE(client->finished()); | 168 EXPECT_TRUE(client->finished()); |
168 | 169 |
169 bool errorOccurred = false; | 170 bool errorOccurred = false; |
170 ScriptSourceCode sourceCode = | 171 ScriptSourceCode sourceCode = |
171 getPendingScript()->getSource(KURL(), errorOccurred); | 172 getPendingScript()->getSource(KURL(), errorOccurred)->scriptSourceCode(); |
172 EXPECT_FALSE(errorOccurred); | 173 EXPECT_FALSE(errorOccurred); |
173 EXPECT_TRUE(sourceCode.streamer()); | 174 EXPECT_TRUE(sourceCode.streamer()); |
174 v8::TryCatch tryCatch(scope.isolate()); | 175 v8::TryCatch tryCatch(scope.isolate()); |
175 v8::Local<v8::Script> script; | 176 v8::Local<v8::Script> script; |
176 EXPECT_FALSE(V8ScriptRunner::compileScript(sourceCode, scope.isolate(), | 177 EXPECT_FALSE(V8ScriptRunner::compileScript(sourceCode, scope.isolate(), |
177 SharableCrossOrigin, | 178 SharableCrossOrigin, |
178 V8CacheOptionsDefault) | 179 V8CacheOptionsDefault) |
179 .ToLocal(&script)); | 180 .ToLocal(&script)); |
180 EXPECT_TRUE(tryCatch.HasCaught()); | 181 EXPECT_TRUE(tryCatch.HasCaught()); |
181 } | 182 } |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
227 cacheHandler->setCachedMetadata(V8ScriptRunner::tagForCodeCache(cacheHandler), | 228 cacheHandler->setCachedMetadata(V8ScriptRunner::tagForCodeCache(cacheHandler), |
228 "X", 1, CachedMetadataHandler::CacheLocally); | 229 "X", 1, CachedMetadataHandler::CacheLocally); |
229 | 230 |
230 appendPadding(); | 231 appendPadding(); |
231 finish(); | 232 finish(); |
232 processTasksUntilStreamingComplete(); | 233 processTasksUntilStreamingComplete(); |
233 EXPECT_TRUE(client->finished()); | 234 EXPECT_TRUE(client->finished()); |
234 | 235 |
235 bool errorOccurred = false; | 236 bool errorOccurred = false; |
236 ScriptSourceCode sourceCode = | 237 ScriptSourceCode sourceCode = |
237 getPendingScript()->getSource(KURL(), errorOccurred); | 238 getPendingScript()->getSource(KURL(), errorOccurred)->scriptSourceCode(); |
238 EXPECT_FALSE(errorOccurred); | 239 EXPECT_FALSE(errorOccurred); |
239 // ScriptSourceCode doesn't refer to the streamer, since we have suppressed | 240 // ScriptSourceCode doesn't refer to the streamer, since we have suppressed |
240 // the streaming and resumed the non-streaming code path for script | 241 // the streaming and resumed the non-streaming code path for script |
241 // compilation. | 242 // compilation. |
242 EXPECT_FALSE(sourceCode.streamer()); | 243 EXPECT_FALSE(sourceCode.streamer()); |
243 } | 244 } |
244 | 245 |
245 TEST_F(ScriptStreamingTest, EmptyScripts) { | 246 TEST_F(ScriptStreamingTest, EmptyScripts) { |
246 // Empty scripts should also be streamed properly, that is, the upper layer | 247 // Empty scripts should also be streamed properly, that is, the upper layer |
247 // (ScriptResourceClient) should be notified when an empty script has been | 248 // (ScriptResourceClient) should be notified when an empty script has been |
248 // loaded. | 249 // loaded. |
249 V8TestingScope scope; | 250 V8TestingScope scope; |
250 ScriptStreamer::startStreaming( | 251 ScriptStreamer::startStreaming( |
251 getPendingScript(), ScriptStreamer::ParsingBlocking, m_settings.get(), | 252 getPendingScript(), ScriptStreamer::ParsingBlocking, m_settings.get(), |
252 scope.getScriptState(), m_loadingTaskRunner); | 253 scope.getScriptState(), m_loadingTaskRunner); |
253 TestPendingScriptClient* client = new TestPendingScriptClient; | 254 TestPendingScriptClient* client = new TestPendingScriptClient; |
254 getPendingScript()->watchForLoad(client); | 255 getPendingScript()->watchForLoad(client); |
255 | 256 |
256 // Finish the script without sending any data. | 257 // Finish the script without sending any data. |
257 finish(); | 258 finish(); |
258 // The finished notification should arrive immediately and not be cycled | 259 // The finished notification should arrive immediately and not be cycled |
259 // through a background thread. | 260 // through a background thread. |
260 EXPECT_TRUE(client->finished()); | 261 EXPECT_TRUE(client->finished()); |
261 | 262 |
262 bool errorOccurred = false; | 263 bool errorOccurred = false; |
263 ScriptSourceCode sourceCode = | 264 ScriptSourceCode sourceCode = |
264 getPendingScript()->getSource(KURL(), errorOccurred); | 265 getPendingScript()->getSource(KURL(), errorOccurred)->scriptSourceCode(); |
265 EXPECT_FALSE(errorOccurred); | 266 EXPECT_FALSE(errorOccurred); |
266 EXPECT_FALSE(sourceCode.streamer()); | 267 EXPECT_FALSE(sourceCode.streamer()); |
267 } | 268 } |
268 | 269 |
269 TEST_F(ScriptStreamingTest, SmallScripts) { | 270 TEST_F(ScriptStreamingTest, SmallScripts) { |
270 // Small scripts shouldn't be streamed. | 271 // Small scripts shouldn't be streamed. |
271 V8TestingScope scope; | 272 V8TestingScope scope; |
272 ScriptStreamer::setSmallScriptThresholdForTesting(100); | 273 ScriptStreamer::setSmallScriptThresholdForTesting(100); |
273 | 274 |
274 ScriptStreamer::startStreaming( | 275 ScriptStreamer::startStreaming( |
275 getPendingScript(), ScriptStreamer::ParsingBlocking, m_settings.get(), | 276 getPendingScript(), ScriptStreamer::ParsingBlocking, m_settings.get(), |
276 scope.getScriptState(), m_loadingTaskRunner); | 277 scope.getScriptState(), m_loadingTaskRunner); |
277 TestPendingScriptClient* client = new TestPendingScriptClient; | 278 TestPendingScriptClient* client = new TestPendingScriptClient; |
278 getPendingScript()->watchForLoad(client); | 279 getPendingScript()->watchForLoad(client); |
279 | 280 |
280 appendData("function foo() { }"); | 281 appendData("function foo() { }"); |
281 | 282 |
282 finish(); | 283 finish(); |
283 | 284 |
284 // The finished notification should arrive immediately and not be cycled | 285 // The finished notification should arrive immediately and not be cycled |
285 // through a background thread. | 286 // through a background thread. |
286 EXPECT_TRUE(client->finished()); | 287 EXPECT_TRUE(client->finished()); |
287 | 288 |
288 bool errorOccurred = false; | 289 bool errorOccurred = false; |
289 ScriptSourceCode sourceCode = | 290 ScriptSourceCode sourceCode = |
290 getPendingScript()->getSource(KURL(), errorOccurred); | 291 getPendingScript()->getSource(KURL(), errorOccurred)->scriptSourceCode(); |
291 EXPECT_FALSE(errorOccurred); | 292 EXPECT_FALSE(errorOccurred); |
292 EXPECT_FALSE(sourceCode.streamer()); | 293 EXPECT_FALSE(sourceCode.streamer()); |
293 } | 294 } |
294 | 295 |
295 TEST_F(ScriptStreamingTest, ScriptsWithSmallFirstChunk) { | 296 TEST_F(ScriptStreamingTest, ScriptsWithSmallFirstChunk) { |
296 // If a script is long enough, if should be streamed, even if the first data | 297 // If a script is long enough, if should be streamed, even if the first data |
297 // chunk is small. | 298 // chunk is small. |
298 V8TestingScope scope; | 299 V8TestingScope scope; |
299 ScriptStreamer::setSmallScriptThresholdForTesting(100); | 300 ScriptStreamer::setSmallScriptThresholdForTesting(100); |
300 | 301 |
301 ScriptStreamer::startStreaming( | 302 ScriptStreamer::startStreaming( |
302 getPendingScript(), ScriptStreamer::ParsingBlocking, m_settings.get(), | 303 getPendingScript(), ScriptStreamer::ParsingBlocking, m_settings.get(), |
303 scope.getScriptState(), m_loadingTaskRunner); | 304 scope.getScriptState(), m_loadingTaskRunner); |
304 TestPendingScriptClient* client = new TestPendingScriptClient; | 305 TestPendingScriptClient* client = new TestPendingScriptClient; |
305 getPendingScript()->watchForLoad(client); | 306 getPendingScript()->watchForLoad(client); |
306 | 307 |
307 // This is the first data chunk which is small. | 308 // This is the first data chunk which is small. |
308 appendData("function foo() { }"); | 309 appendData("function foo() { }"); |
309 appendPadding(); | 310 appendPadding(); |
310 appendPadding(); | 311 appendPadding(); |
311 appendPadding(); | 312 appendPadding(); |
312 | 313 |
313 finish(); | 314 finish(); |
314 | 315 |
315 processTasksUntilStreamingComplete(); | 316 processTasksUntilStreamingComplete(); |
316 EXPECT_TRUE(client->finished()); | 317 EXPECT_TRUE(client->finished()); |
317 bool errorOccurred = false; | 318 bool errorOccurred = false; |
318 ScriptSourceCode sourceCode = | 319 ScriptSourceCode sourceCode = |
319 getPendingScript()->getSource(KURL(), errorOccurred); | 320 getPendingScript()->getSource(KURL(), errorOccurred)->scriptSourceCode(); |
320 EXPECT_FALSE(errorOccurred); | 321 EXPECT_FALSE(errorOccurred); |
321 EXPECT_TRUE(sourceCode.streamer()); | 322 EXPECT_TRUE(sourceCode.streamer()); |
322 v8::TryCatch tryCatch(scope.isolate()); | 323 v8::TryCatch tryCatch(scope.isolate()); |
323 v8::Local<v8::Script> script; | 324 v8::Local<v8::Script> script; |
324 EXPECT_TRUE(V8ScriptRunner::compileScript(sourceCode, scope.isolate(), | 325 EXPECT_TRUE(V8ScriptRunner::compileScript(sourceCode, scope.isolate(), |
325 SharableCrossOrigin, | 326 SharableCrossOrigin, |
326 V8CacheOptionsDefault) | 327 V8CacheOptionsDefault) |
327 .ToLocal(&script)); | 328 .ToLocal(&script)); |
328 EXPECT_FALSE(tryCatch.HasCaught()); | 329 EXPECT_FALSE(tryCatch.HasCaught()); |
329 } | 330 } |
(...skipping 15 matching lines...) Expand all Loading... |
345 appendData( | 346 appendData( |
346 "function foo() { var foob\xec\x92\x81r = 13; return foob\xec\x92\x81r; " | 347 "function foo() { var foob\xec\x92\x81r = 13; return foob\xec\x92\x81r; " |
347 "} foo();"); | 348 "} foo();"); |
348 | 349 |
349 finish(); | 350 finish(); |
350 | 351 |
351 processTasksUntilStreamingComplete(); | 352 processTasksUntilStreamingComplete(); |
352 EXPECT_TRUE(client->finished()); | 353 EXPECT_TRUE(client->finished()); |
353 bool errorOccurred = false; | 354 bool errorOccurred = false; |
354 ScriptSourceCode sourceCode = | 355 ScriptSourceCode sourceCode = |
355 getPendingScript()->getSource(KURL(), errorOccurred); | 356 getPendingScript()->getSource(KURL(), errorOccurred)->scriptSourceCode(); |
356 EXPECT_FALSE(errorOccurred); | 357 EXPECT_FALSE(errorOccurred); |
357 EXPECT_TRUE(sourceCode.streamer()); | 358 EXPECT_TRUE(sourceCode.streamer()); |
358 v8::TryCatch tryCatch(scope.isolate()); | 359 v8::TryCatch tryCatch(scope.isolate()); |
359 v8::Local<v8::Script> script; | 360 v8::Local<v8::Script> script; |
360 EXPECT_TRUE(V8ScriptRunner::compileScript(sourceCode, scope.isolate(), | 361 EXPECT_TRUE(V8ScriptRunner::compileScript(sourceCode, scope.isolate(), |
361 SharableCrossOrigin, | 362 SharableCrossOrigin, |
362 V8CacheOptionsDefault) | 363 V8CacheOptionsDefault) |
363 .ToLocal(&script)); | 364 .ToLocal(&script)); |
364 EXPECT_FALSE(tryCatch.HasCaught()); | 365 EXPECT_FALSE(tryCatch.HasCaught()); |
365 } | 366 } |
(...skipping 15 matching lines...) Expand all Loading... |
381 // for \uc481. | 382 // for \uc481. |
382 appendData( | 383 appendData( |
383 "\xef\xbb\xbf function foo() { var foob\xec\x92\x81r = 13; return " | 384 "\xef\xbb\xbf function foo() { var foob\xec\x92\x81r = 13; return " |
384 "foob\xec\x92\x81r; } foo();"); | 385 "foob\xec\x92\x81r; } foo();"); |
385 | 386 |
386 finish(); | 387 finish(); |
387 processTasksUntilStreamingComplete(); | 388 processTasksUntilStreamingComplete(); |
388 EXPECT_TRUE(client->finished()); | 389 EXPECT_TRUE(client->finished()); |
389 bool errorOccurred = false; | 390 bool errorOccurred = false; |
390 ScriptSourceCode sourceCode = | 391 ScriptSourceCode sourceCode = |
391 getPendingScript()->getSource(KURL(), errorOccurred); | 392 getPendingScript()->getSource(KURL(), errorOccurred)->scriptSourceCode(); |
392 EXPECT_FALSE(errorOccurred); | 393 EXPECT_FALSE(errorOccurred); |
393 EXPECT_TRUE(sourceCode.streamer()); | 394 EXPECT_TRUE(sourceCode.streamer()); |
394 v8::TryCatch tryCatch(scope.isolate()); | 395 v8::TryCatch tryCatch(scope.isolate()); |
395 v8::Local<v8::Script> script; | 396 v8::Local<v8::Script> script; |
396 EXPECT_TRUE(V8ScriptRunner::compileScript(sourceCode, scope.isolate(), | 397 EXPECT_TRUE(V8ScriptRunner::compileScript(sourceCode, scope.isolate(), |
397 SharableCrossOrigin, | 398 SharableCrossOrigin, |
398 V8CacheOptionsDefault) | 399 V8CacheOptionsDefault) |
399 .ToLocal(&script)); | 400 .ToLocal(&script)); |
400 EXPECT_FALSE(tryCatch.HasCaught()); | 401 EXPECT_FALSE(tryCatch.HasCaught()); |
401 } | 402 } |
402 | 403 |
403 } // namespace | 404 } // namespace |
404 | 405 |
405 } // namespace blink | 406 } // namespace blink |
OLD | NEW |