| 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 |