| 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 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 121 AppendPadding(); | 122 AppendPadding(); |
| 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 error_occurred = false; | 131 bool error_occurred = false; |
| 131 ScriptSourceCode source_code = | 132 ScriptSourceCode source_code = GetPendingScript() |
| 132 GetPendingScript()->GetSource(KURL(), error_occurred); | 133 ->GetSource(KURL(), error_occurred) |
| 134 ->GetScriptSourceCode(); |
| 133 EXPECT_FALSE(error_occurred); | 135 EXPECT_FALSE(error_occurred); |
| 134 EXPECT_TRUE(source_code.Streamer()); | 136 EXPECT_TRUE(source_code.Streamer()); |
| 135 v8::TryCatch try_catch(scope.GetIsolate()); | 137 v8::TryCatch try_catch(scope.GetIsolate()); |
| 136 v8::Local<v8::Script> script; | 138 v8::Local<v8::Script> script; |
| 137 EXPECT_TRUE(V8ScriptRunner::CompileScript(source_code, scope.GetIsolate(), | 139 EXPECT_TRUE(V8ScriptRunner::CompileScript(source_code, scope.GetIsolate(), |
| 138 kSharableCrossOrigin, | 140 kSharableCrossOrigin, |
| 139 kV8CacheOptionsDefault) | 141 kV8CacheOptionsDefault) |
| 140 .ToLocal(&script)); | 142 .ToLocal(&script)); |
| 141 EXPECT_FALSE(try_catch.HasCaught()); | 143 EXPECT_FALSE(try_catch.HasCaught()); |
| 142 } | 144 } |
| (...skipping 17 matching lines...) Expand all Loading... |
| 160 EXPECT_FALSE(client->Finished()); | 162 EXPECT_FALSE(client->Finished()); |
| 161 | 163 |
| 162 // Force the V8 side to finish before the loading. | 164 // Force the V8 side to finish before the loading. |
| 163 ProcessTasksUntilStreamingComplete(); | 165 ProcessTasksUntilStreamingComplete(); |
| 164 EXPECT_FALSE(client->Finished()); | 166 EXPECT_FALSE(client->Finished()); |
| 165 | 167 |
| 166 Finish(); | 168 Finish(); |
| 167 EXPECT_TRUE(client->Finished()); | 169 EXPECT_TRUE(client->Finished()); |
| 168 | 170 |
| 169 bool error_occurred = false; | 171 bool error_occurred = false; |
| 170 ScriptSourceCode source_code = | 172 ScriptSourceCode source_code = GetPendingScript() |
| 171 GetPendingScript()->GetSource(KURL(), error_occurred); | 173 ->GetSource(KURL(), error_occurred) |
| 174 ->GetScriptSourceCode(); |
| 172 EXPECT_FALSE(error_occurred); | 175 EXPECT_FALSE(error_occurred); |
| 173 EXPECT_TRUE(source_code.Streamer()); | 176 EXPECT_TRUE(source_code.Streamer()); |
| 174 v8::TryCatch try_catch(scope.GetIsolate()); | 177 v8::TryCatch try_catch(scope.GetIsolate()); |
| 175 v8::Local<v8::Script> script; | 178 v8::Local<v8::Script> script; |
| 176 EXPECT_FALSE(V8ScriptRunner::CompileScript(source_code, scope.GetIsolate(), | 179 EXPECT_FALSE(V8ScriptRunner::CompileScript(source_code, scope.GetIsolate(), |
| 177 kSharableCrossOrigin, | 180 kSharableCrossOrigin, |
| 178 kV8CacheOptionsDefault) | 181 kV8CacheOptionsDefault) |
| 179 .ToLocal(&script)); | 182 .ToLocal(&script)); |
| 180 EXPECT_TRUE(try_catch.HasCaught()); | 183 EXPECT_TRUE(try_catch.HasCaught()); |
| 181 } | 184 } |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 227 cache_handler->SetCachedMetadata( | 230 cache_handler->SetCachedMetadata( |
| 228 V8ScriptRunner::TagForCodeCache(cache_handler), "X", 1, | 231 V8ScriptRunner::TagForCodeCache(cache_handler), "X", 1, |
| 229 CachedMetadataHandler::kCacheLocally); | 232 CachedMetadataHandler::kCacheLocally); |
| 230 | 233 |
| 231 AppendPadding(); | 234 AppendPadding(); |
| 232 Finish(); | 235 Finish(); |
| 233 ProcessTasksUntilStreamingComplete(); | 236 ProcessTasksUntilStreamingComplete(); |
| 234 EXPECT_TRUE(client->Finished()); | 237 EXPECT_TRUE(client->Finished()); |
| 235 | 238 |
| 236 bool error_occurred = false; | 239 bool error_occurred = false; |
| 237 ScriptSourceCode source_code = | 240 ScriptSourceCode source_code = GetPendingScript() |
| 238 GetPendingScript()->GetSource(KURL(), error_occurred); | 241 ->GetSource(KURL(), error_occurred) |
| 242 ->GetScriptSourceCode(); |
| 239 EXPECT_FALSE(error_occurred); | 243 EXPECT_FALSE(error_occurred); |
| 240 // ScriptSourceCode doesn't refer to the streamer, since we have suppressed | 244 // ScriptSourceCode doesn't refer to the streamer, since we have suppressed |
| 241 // the streaming and resumed the non-streaming code path for script | 245 // the streaming and resumed the non-streaming code path for script |
| 242 // compilation. | 246 // compilation. |
| 243 EXPECT_FALSE(source_code.Streamer()); | 247 EXPECT_FALSE(source_code.Streamer()); |
| 244 } | 248 } |
| 245 | 249 |
| 246 TEST_F(ScriptStreamingTest, EmptyScripts) { | 250 TEST_F(ScriptStreamingTest, EmptyScripts) { |
| 247 // Empty scripts should also be streamed properly, that is, the upper layer | 251 // Empty scripts should also be streamed properly, that is, the upper layer |
| 248 // (ScriptResourceClient) should be notified when an empty script has been | 252 // (ScriptResourceClient) should be notified when an empty script has been |
| 249 // loaded. | 253 // loaded. |
| 250 V8TestingScope scope; | 254 V8TestingScope scope; |
| 251 ScriptStreamer::StartStreaming( | 255 ScriptStreamer::StartStreaming( |
| 252 GetPendingScript(), ScriptStreamer::kParsingBlocking, settings_.get(), | 256 GetPendingScript(), ScriptStreamer::kParsingBlocking, settings_.get(), |
| 253 scope.GetScriptState(), loading_task_runner_); | 257 scope.GetScriptState(), loading_task_runner_); |
| 254 TestPendingScriptClient* client = new TestPendingScriptClient; | 258 TestPendingScriptClient* client = new TestPendingScriptClient; |
| 255 GetPendingScript()->WatchForLoad(client); | 259 GetPendingScript()->WatchForLoad(client); |
| 256 | 260 |
| 257 // Finish the script without sending any data. | 261 // Finish the script without sending any data. |
| 258 Finish(); | 262 Finish(); |
| 259 // The finished notification should arrive immediately and not be cycled | 263 // The finished notification should arrive immediately and not be cycled |
| 260 // through a background thread. | 264 // through a background thread. |
| 261 EXPECT_TRUE(client->Finished()); | 265 EXPECT_TRUE(client->Finished()); |
| 262 | 266 |
| 263 bool error_occurred = false; | 267 bool error_occurred = false; |
| 264 ScriptSourceCode source_code = | 268 ScriptSourceCode source_code = GetPendingScript() |
| 265 GetPendingScript()->GetSource(KURL(), error_occurred); | 269 ->GetSource(KURL(), error_occurred) |
| 270 ->GetScriptSourceCode(); |
| 266 EXPECT_FALSE(error_occurred); | 271 EXPECT_FALSE(error_occurred); |
| 267 EXPECT_FALSE(source_code.Streamer()); | 272 EXPECT_FALSE(source_code.Streamer()); |
| 268 } | 273 } |
| 269 | 274 |
| 270 TEST_F(ScriptStreamingTest, SmallScripts) { | 275 TEST_F(ScriptStreamingTest, SmallScripts) { |
| 271 // Small scripts shouldn't be streamed. | 276 // Small scripts shouldn't be streamed. |
| 272 V8TestingScope scope; | 277 V8TestingScope scope; |
| 273 ScriptStreamer::SetSmallScriptThresholdForTesting(100); | 278 ScriptStreamer::SetSmallScriptThresholdForTesting(100); |
| 274 | 279 |
| 275 ScriptStreamer::StartStreaming( | 280 ScriptStreamer::StartStreaming( |
| 276 GetPendingScript(), ScriptStreamer::kParsingBlocking, settings_.get(), | 281 GetPendingScript(), ScriptStreamer::kParsingBlocking, settings_.get(), |
| 277 scope.GetScriptState(), loading_task_runner_); | 282 scope.GetScriptState(), loading_task_runner_); |
| 278 TestPendingScriptClient* client = new TestPendingScriptClient; | 283 TestPendingScriptClient* client = new TestPendingScriptClient; |
| 279 GetPendingScript()->WatchForLoad(client); | 284 GetPendingScript()->WatchForLoad(client); |
| 280 | 285 |
| 281 AppendData("function foo() { }"); | 286 AppendData("function foo() { }"); |
| 282 | 287 |
| 283 Finish(); | 288 Finish(); |
| 284 | 289 |
| 285 // The finished notification should arrive immediately and not be cycled | 290 // The finished notification should arrive immediately and not be cycled |
| 286 // through a background thread. | 291 // through a background thread. |
| 287 EXPECT_TRUE(client->Finished()); | 292 EXPECT_TRUE(client->Finished()); |
| 288 | 293 |
| 289 bool error_occurred = false; | 294 bool error_occurred = false; |
| 290 ScriptSourceCode source_code = | 295 ScriptSourceCode source_code = GetPendingScript() |
| 291 GetPendingScript()->GetSource(KURL(), error_occurred); | 296 ->GetSource(KURL(), error_occurred) |
| 297 ->GetScriptSourceCode(); |
| 292 EXPECT_FALSE(error_occurred); | 298 EXPECT_FALSE(error_occurred); |
| 293 EXPECT_FALSE(source_code.Streamer()); | 299 EXPECT_FALSE(source_code.Streamer()); |
| 294 } | 300 } |
| 295 | 301 |
| 296 TEST_F(ScriptStreamingTest, ScriptsWithSmallFirstChunk) { | 302 TEST_F(ScriptStreamingTest, ScriptsWithSmallFirstChunk) { |
| 297 // If a script is long enough, if should be streamed, even if the first data | 303 // If a script is long enough, if should be streamed, even if the first data |
| 298 // chunk is small. | 304 // chunk is small. |
| 299 V8TestingScope scope; | 305 V8TestingScope scope; |
| 300 ScriptStreamer::SetSmallScriptThresholdForTesting(100); | 306 ScriptStreamer::SetSmallScriptThresholdForTesting(100); |
| 301 | 307 |
| 302 ScriptStreamer::StartStreaming( | 308 ScriptStreamer::StartStreaming( |
| 303 GetPendingScript(), ScriptStreamer::kParsingBlocking, settings_.get(), | 309 GetPendingScript(), ScriptStreamer::kParsingBlocking, settings_.get(), |
| 304 scope.GetScriptState(), loading_task_runner_); | 310 scope.GetScriptState(), loading_task_runner_); |
| 305 TestPendingScriptClient* client = new TestPendingScriptClient; | 311 TestPendingScriptClient* client = new TestPendingScriptClient; |
| 306 GetPendingScript()->WatchForLoad(client); | 312 GetPendingScript()->WatchForLoad(client); |
| 307 | 313 |
| 308 // This is the first data chunk which is small. | 314 // This is the first data chunk which is small. |
| 309 AppendData("function foo() { }"); | 315 AppendData("function foo() { }"); |
| 310 AppendPadding(); | 316 AppendPadding(); |
| 311 AppendPadding(); | 317 AppendPadding(); |
| 312 AppendPadding(); | 318 AppendPadding(); |
| 313 | 319 |
| 314 Finish(); | 320 Finish(); |
| 315 | 321 |
| 316 ProcessTasksUntilStreamingComplete(); | 322 ProcessTasksUntilStreamingComplete(); |
| 317 EXPECT_TRUE(client->Finished()); | 323 EXPECT_TRUE(client->Finished()); |
| 318 bool error_occurred = false; | 324 bool error_occurred = false; |
| 319 ScriptSourceCode source_code = | 325 ScriptSourceCode source_code = GetPendingScript() |
| 320 GetPendingScript()->GetSource(KURL(), error_occurred); | 326 ->GetSource(KURL(), error_occurred) |
| 327 ->GetScriptSourceCode(); |
| 321 EXPECT_FALSE(error_occurred); | 328 EXPECT_FALSE(error_occurred); |
| 322 EXPECT_TRUE(source_code.Streamer()); | 329 EXPECT_TRUE(source_code.Streamer()); |
| 323 v8::TryCatch try_catch(scope.GetIsolate()); | 330 v8::TryCatch try_catch(scope.GetIsolate()); |
| 324 v8::Local<v8::Script> script; | 331 v8::Local<v8::Script> script; |
| 325 EXPECT_TRUE(V8ScriptRunner::CompileScript(source_code, scope.GetIsolate(), | 332 EXPECT_TRUE(V8ScriptRunner::CompileScript(source_code, scope.GetIsolate(), |
| 326 kSharableCrossOrigin, | 333 kSharableCrossOrigin, |
| 327 kV8CacheOptionsDefault) | 334 kV8CacheOptionsDefault) |
| 328 .ToLocal(&script)); | 335 .ToLocal(&script)); |
| 329 EXPECT_FALSE(try_catch.HasCaught()); | 336 EXPECT_FALSE(try_catch.HasCaught()); |
| 330 } | 337 } |
| (...skipping 14 matching lines...) Expand all Loading... |
| 345 // \xec\x92\x81 are the raw bytes for \uc481. | 352 // \xec\x92\x81 are the raw bytes for \uc481. |
| 346 AppendData( | 353 AppendData( |
| 347 "function foo() { var foob\xec\x92\x81r = 13; return foob\xec\x92\x81r; " | 354 "function foo() { var foob\xec\x92\x81r = 13; return foob\xec\x92\x81r; " |
| 348 "} foo();"); | 355 "} foo();"); |
| 349 | 356 |
| 350 Finish(); | 357 Finish(); |
| 351 | 358 |
| 352 ProcessTasksUntilStreamingComplete(); | 359 ProcessTasksUntilStreamingComplete(); |
| 353 EXPECT_TRUE(client->Finished()); | 360 EXPECT_TRUE(client->Finished()); |
| 354 bool error_occurred = false; | 361 bool error_occurred = false; |
| 355 ScriptSourceCode source_code = | 362 ScriptSourceCode source_code = GetPendingScript() |
| 356 GetPendingScript()->GetSource(KURL(), error_occurred); | 363 ->GetSource(KURL(), error_occurred) |
| 364 ->GetScriptSourceCode(); |
| 357 EXPECT_FALSE(error_occurred); | 365 EXPECT_FALSE(error_occurred); |
| 358 EXPECT_TRUE(source_code.Streamer()); | 366 EXPECT_TRUE(source_code.Streamer()); |
| 359 v8::TryCatch try_catch(scope.GetIsolate()); | 367 v8::TryCatch try_catch(scope.GetIsolate()); |
| 360 v8::Local<v8::Script> script; | 368 v8::Local<v8::Script> script; |
| 361 EXPECT_TRUE(V8ScriptRunner::CompileScript(source_code, scope.GetIsolate(), | 369 EXPECT_TRUE(V8ScriptRunner::CompileScript(source_code, scope.GetIsolate(), |
| 362 kSharableCrossOrigin, | 370 kSharableCrossOrigin, |
| 363 kV8CacheOptionsDefault) | 371 kV8CacheOptionsDefault) |
| 364 .ToLocal(&script)); | 372 .ToLocal(&script)); |
| 365 EXPECT_FALSE(try_catch.HasCaught()); | 373 EXPECT_FALSE(try_catch.HasCaught()); |
| 366 } | 374 } |
| (...skipping 13 matching lines...) Expand all Loading... |
| 380 // \xef\xbb\xbf is the UTF-8 byte order mark. \xec\x92\x81 are the raw bytes | 388 // \xef\xbb\xbf is the UTF-8 byte order mark. \xec\x92\x81 are the raw bytes |
| 381 // for \uc481. | 389 // for \uc481. |
| 382 AppendData( | 390 AppendData( |
| 383 "\xef\xbb\xbf function foo() { var foob\xec\x92\x81r = 13; return " | 391 "\xef\xbb\xbf function foo() { var foob\xec\x92\x81r = 13; return " |
| 384 "foob\xec\x92\x81r; } foo();"); | 392 "foob\xec\x92\x81r; } foo();"); |
| 385 | 393 |
| 386 Finish(); | 394 Finish(); |
| 387 ProcessTasksUntilStreamingComplete(); | 395 ProcessTasksUntilStreamingComplete(); |
| 388 EXPECT_TRUE(client->Finished()); | 396 EXPECT_TRUE(client->Finished()); |
| 389 bool error_occurred = false; | 397 bool error_occurred = false; |
| 390 ScriptSourceCode source_code = | 398 ScriptSourceCode source_code = GetPendingScript() |
| 391 GetPendingScript()->GetSource(KURL(), error_occurred); | 399 ->GetSource(KURL(), error_occurred) |
| 400 ->GetScriptSourceCode(); |
| 392 EXPECT_FALSE(error_occurred); | 401 EXPECT_FALSE(error_occurred); |
| 393 EXPECT_TRUE(source_code.Streamer()); | 402 EXPECT_TRUE(source_code.Streamer()); |
| 394 v8::TryCatch try_catch(scope.GetIsolate()); | 403 v8::TryCatch try_catch(scope.GetIsolate()); |
| 395 v8::Local<v8::Script> script; | 404 v8::Local<v8::Script> script; |
| 396 EXPECT_TRUE(V8ScriptRunner::CompileScript(source_code, scope.GetIsolate(), | 405 EXPECT_TRUE(V8ScriptRunner::CompileScript(source_code, scope.GetIsolate(), |
| 397 kSharableCrossOrigin, | 406 kSharableCrossOrigin, |
| 398 kV8CacheOptionsDefault) | 407 kV8CacheOptionsDefault) |
| 399 .ToLocal(&script)); | 408 .ToLocal(&script)); |
| 400 EXPECT_FALSE(try_catch.HasCaught()); | 409 EXPECT_FALSE(try_catch.HasCaught()); |
| 401 } | 410 } |
| 402 | 411 |
| 403 } // namespace | 412 } // namespace |
| 404 | 413 |
| 405 } // namespace blink | 414 } // namespace blink |
| OLD | NEW |