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 "config.h" | 5 #include "config.h" |
6 #include "bindings/core/v8/ScriptStreamer.h" | 6 #include "bindings/core/v8/ScriptStreamer.h" |
7 | 7 |
8 #include "bindings/core/v8/ScriptStreamerThread.h" | 8 #include "bindings/core/v8/ScriptStreamerThread.h" |
9 #include "bindings/core/v8/V8ScriptRunner.h" | 9 #include "bindings/core/v8/V8ScriptRunner.h" |
10 #include "core/dom/Document.h" | 10 #include "core/dom/Document.h" |
(...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
276 | 276 |
277 size_t ScriptStreamer::kSmallScriptThreshold = 30 * 1024; | 277 size_t ScriptStreamer::kSmallScriptThreshold = 30 * 1024; |
278 | 278 |
279 void ScriptStreamer::startStreaming(PendingScript& script, PendingScript::Type s
criptType, Settings* settings, ScriptState* scriptState) | 279 void ScriptStreamer::startStreaming(PendingScript& script, PendingScript::Type s
criptType, Settings* settings, ScriptState* scriptState) |
280 { | 280 { |
281 // We don't yet know whether the script will really be streamed. E.g., | 281 // We don't yet know whether the script will really be streamed. E.g., |
282 // suppressing streaming for short scripts is done later. Record only the | 282 // suppressing streaming for short scripts is done later. Record only the |
283 // sure negative cases here. | 283 // sure negative cases here. |
284 bool startedStreaming = startStreamingInternal(script, scriptType, settings,
scriptState); | 284 bool startedStreaming = startStreamingInternal(script, scriptType, settings,
scriptState); |
285 if (!startedStreaming) | 285 if (!startedStreaming) |
286 blink::Platform::current()->histogramEnumeration(startedStreamingHistogr
amName(scriptType), 0, 2); | 286 Platform::current()->histogramEnumeration(startedStreamingHistogramName(
scriptType), 0, 2); |
287 } | 287 } |
288 | 288 |
289 bool ScriptStreamer::convertEncoding(const char* encodingName, v8::ScriptCompile
r::StreamedSource::Encoding* encoding) | 289 bool ScriptStreamer::convertEncoding(const char* encodingName, v8::ScriptCompile
r::StreamedSource::Encoding* encoding) |
290 { | 290 { |
291 // Here's a list of encodings we can use for streaming. These are | 291 // Here's a list of encodings we can use for streaming. These are |
292 // the canonical names. | 292 // the canonical names. |
293 if (strcmp(encodingName, "windows-1252") == 0 | 293 if (strcmp(encodingName, "windows-1252") == 0 |
294 || strcmp(encodingName, "ISO-8859-1") == 0 | 294 || strcmp(encodingName, "ISO-8859-1") == 0 |
295 || strcmp(encodingName, "US-ASCII") == 0) { | 295 || strcmp(encodingName, "US-ASCII") == 0) { |
296 *encoding = v8::ScriptCompiler::StreamedSource::ONE_BYTE; | 296 *encoding = v8::ScriptCompiler::StreamedSource::ONE_BYTE; |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
378 const char* data = 0; | 378 const char* data = 0; |
379 unsigned length = resource->resourceBuffer()->getSomeData(data, 0); | 379 unsigned length = resource->resourceBuffer()->getSomeData(data, 0); |
380 | 380 |
381 OwnPtr<TextResourceDecoder> decoder(TextResourceDecoder::create("applica
tion/javascript", resource->encoding())); | 381 OwnPtr<TextResourceDecoder> decoder(TextResourceDecoder::create("applica
tion/javascript", resource->encoding())); |
382 lengthOfBOM = decoder->checkForBOM(data, length); | 382 lengthOfBOM = decoder->checkForBOM(data, length); |
383 | 383 |
384 // Maybe the encoding changed because we saw the BOM; get the encoding | 384 // Maybe the encoding changed because we saw the BOM; get the encoding |
385 // from the decoder. | 385 // from the decoder. |
386 if (!convertEncoding(decoder->encoding().name(), &m_encoding)) { | 386 if (!convertEncoding(decoder->encoding().name(), &m_encoding)) { |
387 suppressStreaming(); | 387 suppressStreaming(); |
388 blink::Platform::current()->histogramEnumeration(notStreamingReasonH
istogramName(m_scriptType), EncodingNotSupported, NotStreamingReasonEnd); | 388 Platform::current()->histogramEnumeration(notStreamingReasonHistogra
mName(m_scriptType), EncodingNotSupported, NotStreamingReasonEnd); |
389 blink::Platform::current()->histogramEnumeration(startedStreamingHis
togramName(m_scriptType), 0, 2); | 389 Platform::current()->histogramEnumeration(startedStreamingHistogramN
ame(m_scriptType), 0, 2); |
390 return; | 390 return; |
391 } | 391 } |
392 if (ScriptStreamerThread::shared()->isRunningTask()) { | 392 if (ScriptStreamerThread::shared()->isRunningTask()) { |
393 // At the moment we only have one thread for running the tasks. A | 393 // At the moment we only have one thread for running the tasks. A |
394 // new task shouldn't be queued before the running task completes, | 394 // new task shouldn't be queued before the running task completes, |
395 // because the running task can block and wait for data from the | 395 // because the running task can block and wait for data from the |
396 // network. | 396 // network. |
397 suppressStreaming(); | 397 suppressStreaming(); |
398 blink::Platform::current()->histogramEnumeration(notStreamingReasonH
istogramName(m_scriptType), ThreadBusy, NotStreamingReasonEnd); | 398 Platform::current()->histogramEnumeration(notStreamingReasonHistogra
mName(m_scriptType), ThreadBusy, NotStreamingReasonEnd); |
399 blink::Platform::current()->histogramEnumeration(startedStreamingHis
togramName(m_scriptType), 0, 2); | 399 Platform::current()->histogramEnumeration(startedStreamingHistogramN
ame(m_scriptType), 0, 2); |
400 return; | 400 return; |
401 } | 401 } |
402 | 402 |
403 if (!m_scriptState->contextIsValid()) { | 403 if (!m_scriptState->contextIsValid()) { |
404 suppressStreaming(); | 404 suppressStreaming(); |
405 blink::Platform::current()->histogramEnumeration(notStreamingReasonH
istogramName(m_scriptType), ContextNotValid, NotStreamingReasonEnd); | 405 Platform::current()->histogramEnumeration(notStreamingReasonHistogra
mName(m_scriptType), ContextNotValid, NotStreamingReasonEnd); |
406 blink::Platform::current()->histogramEnumeration(startedStreamingHis
togramName(m_scriptType), 0, 2); | 406 Platform::current()->histogramEnumeration(startedStreamingHistogramN
ame(m_scriptType), 0, 2); |
407 return; | 407 return; |
408 } | 408 } |
409 | 409 |
410 ASSERT(!m_stream); | 410 ASSERT(!m_stream); |
411 ASSERT(!m_source); | 411 ASSERT(!m_source); |
412 m_stream = new SourceStream(); | 412 m_stream = new SourceStream(); |
413 // m_source takes ownership of m_stream. | 413 // m_source takes ownership of m_stream. |
414 m_source = adoptPtr(new v8::ScriptCompiler::StreamedSource(m_stream, m_e
ncoding)); | 414 m_source = adoptPtr(new v8::ScriptCompiler::StreamedSource(m_stream, m_e
ncoding)); |
415 | 415 |
416 ScriptState::Scope scope(m_scriptState.get()); | 416 ScriptState::Scope scope(m_scriptState.get()); |
417 WTF::OwnPtr<v8::ScriptCompiler::ScriptStreamingTask> scriptStreamingTask
(adoptPtr(v8::ScriptCompiler::StartStreamingScript(m_scriptState->isolate(), m_s
ource.get(), m_compileOptions))); | 417 WTF::OwnPtr<v8::ScriptCompiler::ScriptStreamingTask> scriptStreamingTask
(adoptPtr(v8::ScriptCompiler::StartStreamingScript(m_scriptState->isolate(), m_s
ource.get(), m_compileOptions))); |
418 if (!scriptStreamingTask) { | 418 if (!scriptStreamingTask) { |
419 // V8 cannot stream the script. | 419 // V8 cannot stream the script. |
420 suppressStreaming(); | 420 suppressStreaming(); |
421 m_stream = 0; | 421 m_stream = 0; |
422 m_source.clear(); | 422 m_source.clear(); |
423 blink::Platform::current()->histogramEnumeration(notStreamingReasonH
istogramName(m_scriptType), V8CannotStream, NotStreamingReasonEnd); | 423 Platform::current()->histogramEnumeration(notStreamingReasonHistogra
mName(m_scriptType), V8CannotStream, NotStreamingReasonEnd); |
424 blink::Platform::current()->histogramEnumeration(startedStreamingHis
togramName(m_scriptType), 0, 2); | 424 Platform::current()->histogramEnumeration(startedStreamingHistogramN
ame(m_scriptType), 0, 2); |
425 return; | 425 return; |
426 } | 426 } |
427 | 427 |
428 // ScriptStreamer needs to stay alive as long as the background task is | 428 // ScriptStreamer needs to stay alive as long as the background task is |
429 // running. This is taken care of with a manual ref() & deref() pair; | 429 // running. This is taken care of with a manual ref() & deref() pair; |
430 // the corresponding deref() is in streamingComplete. | 430 // the corresponding deref() is in streamingComplete. |
431 ref(); | 431 ref(); |
432 ScriptStreamingTask* task = new ScriptStreamingTask(scriptStreamingTask.
release(), this); | 432 ScriptStreamingTask* task = new ScriptStreamingTask(scriptStreamingTask.
release(), this); |
433 ScriptStreamerThread::shared()->postTask(task); | 433 ScriptStreamerThread::shared()->postTask(task); |
434 blink::Platform::current()->histogramEnumeration(startedStreamingHistogr
amName(m_scriptType), 1, 2); | 434 Platform::current()->histogramEnumeration(startedStreamingHistogramName(
m_scriptType), 1, 2); |
435 } | 435 } |
436 if (m_stream) | 436 if (m_stream) |
437 m_stream->didReceiveData(this, lengthOfBOM); | 437 m_stream->didReceiveData(this, lengthOfBOM); |
438 } | 438 } |
439 | 439 |
440 void ScriptStreamer::notifyFinished(Resource* resource) | 440 void ScriptStreamer::notifyFinished(Resource* resource) |
441 { | 441 { |
442 ASSERT(isMainThread()); | 442 ASSERT(isMainThread()); |
443 ASSERT(m_resource == resource); | 443 ASSERT(m_resource == resource); |
444 // A special case: empty and small scripts. We didn't receive enough data to | 444 // A special case: empty and small scripts. We didn't receive enough data to |
445 // start the streaming before this notification. In that case, there won't | 445 // start the streaming before this notification. In that case, there won't |
446 // be a "parsing complete" notification either, and we should not wait for | 446 // be a "parsing complete" notification either, and we should not wait for |
447 // it. | 447 // it. |
448 if (!m_haveEnoughDataForStreaming) { | 448 if (!m_haveEnoughDataForStreaming) { |
449 blink::Platform::current()->histogramEnumeration(notStreamingReasonHisto
gramName(m_scriptType), ScriptTooSmall, NotStreamingReasonEnd); | 449 Platform::current()->histogramEnumeration(notStreamingReasonHistogramNam
e(m_scriptType), ScriptTooSmall, NotStreamingReasonEnd); |
450 blink::Platform::current()->histogramEnumeration(startedStreamingHistogr
amName(m_scriptType), 0, 2); | 450 Platform::current()->histogramEnumeration(startedStreamingHistogramName(
m_scriptType), 0, 2); |
451 suppressStreaming(); | 451 suppressStreaming(); |
452 } | 452 } |
453 if (m_stream) | 453 if (m_stream) |
454 m_stream->didFinishLoading(); | 454 m_stream->didFinishLoading(); |
455 m_loadingFinished = true; | 455 m_loadingFinished = true; |
456 | 456 |
457 // Calling notifyFinishedToClient can result into the upper layers dropping | 457 // Calling notifyFinishedToClient can result into the upper layers dropping |
458 // references to ScriptStreamer. Keep it alive until this function ends. | 458 // references to ScriptStreamer. Keep it alive until this function ends. |
459 RefPtrWillBeRawPtr<ScriptStreamer> protect(this); | 459 RefPtrWillBeRawPtr<ScriptStreamer> protect(this); |
460 | 460 |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
529 } | 529 } |
530 if (m_client) | 530 if (m_client) |
531 m_client->notifyFinished(m_resource); | 531 m_client->notifyFinished(m_resource); |
532 } | 532 } |
533 | 533 |
534 bool ScriptStreamer::startStreamingInternal(PendingScript& script, PendingScript
::Type scriptType, Settings* settings, ScriptState* scriptState) | 534 bool ScriptStreamer::startStreamingInternal(PendingScript& script, PendingScript
::Type scriptType, Settings* settings, ScriptState* scriptState) |
535 { | 535 { |
536 ASSERT(isMainThread()); | 536 ASSERT(isMainThread()); |
537 ScriptResource* resource = script.resource(); | 537 ScriptResource* resource = script.resource(); |
538 if (resource->isLoaded()) { | 538 if (resource->isLoaded()) { |
539 blink::Platform::current()->histogramEnumeration(notStreamingReasonHisto
gramName(scriptType), AlreadyLoaded, NotStreamingReasonEnd); | 539 Platform::current()->histogramEnumeration(notStreamingReasonHistogramNam
e(scriptType), AlreadyLoaded, NotStreamingReasonEnd); |
540 return false; | 540 return false; |
541 } | 541 } |
542 if (!resource->url().protocolIsInHTTPFamily()) { | 542 if (!resource->url().protocolIsInHTTPFamily()) { |
543 blink::Platform::current()->histogramEnumeration(notStreamingReasonHisto
gramName(scriptType), NotHTTP, NotStreamingReasonEnd); | 543 Platform::current()->histogramEnumeration(notStreamingReasonHistogramNam
e(scriptType), NotHTTP, NotStreamingReasonEnd); |
544 return false; | 544 return false; |
545 } | 545 } |
546 if (resource->resourceToRevalidate()) { | 546 if (resource->resourceToRevalidate()) { |
547 blink::Platform::current()->histogramEnumeration(notStreamingReasonHisto
gramName(scriptType), Reload, NotStreamingReasonEnd); | 547 Platform::current()->histogramEnumeration(notStreamingReasonHistogramNam
e(scriptType), Reload, NotStreamingReasonEnd); |
548 // This happens e.g., during reloads. We're actually not going to load | 548 // This happens e.g., during reloads. We're actually not going to load |
549 // the current Resource of the PendingScript but switch to another | 549 // the current Resource of the PendingScript but switch to another |
550 // Resource -> don't stream. | 550 // Resource -> don't stream. |
551 return false; | 551 return false; |
552 } | 552 } |
553 // We cannot filter out short scripts, even if we wait for the HTTP headers | 553 // We cannot filter out short scripts, even if we wait for the HTTP headers |
554 // to arrive: the Content-Length HTTP header is not sent for chunked | 554 // to arrive: the Content-Length HTTP header is not sent for chunked |
555 // downloads. | 555 // downloads. |
556 | 556 |
557 if (!scriptState->contextIsValid()) { | 557 if (!scriptState->contextIsValid()) { |
558 blink::Platform::current()->histogramEnumeration(notStreamingReasonHisto
gramName(scriptType), ContextNotValid, NotStreamingReasonEnd); | 558 Platform::current()->histogramEnumeration(notStreamingReasonHistogramNam
e(scriptType), ContextNotValid, NotStreamingReasonEnd); |
559 return false; | 559 return false; |
560 } | 560 } |
561 | 561 |
562 // Decide what kind of cached data we should produce while streaming. Only | 562 // Decide what kind of cached data we should produce while streaming. Only |
563 // produce parser cache if the non-streaming compile takes advantage of it. | 563 // produce parser cache if the non-streaming compile takes advantage of it. |
564 v8::ScriptCompiler::CompileOptions compileOption = v8::ScriptCompiler::kNoCo
mpileOptions; | 564 v8::ScriptCompiler::CompileOptions compileOption = v8::ScriptCompiler::kNoCo
mpileOptions; |
565 if (settings->v8CacheOptions() == V8CacheOptionsParseMemory || settings->v8C
acheOptions() == V8CacheOptionsParse) | 565 if (settings->v8CacheOptions() == V8CacheOptionsParseMemory || settings->v8C
acheOptions() == V8CacheOptionsParse) |
566 compileOption = v8::ScriptCompiler::kProduceParserCache; | 566 compileOption = v8::ScriptCompiler::kProduceParserCache; |
567 | 567 |
568 // The Resource might go out of scope if the script is no longer | 568 // The Resource might go out of scope if the script is no longer |
569 // needed. This makes PendingScript notify the ScriptStreamer when it is | 569 // needed. This makes PendingScript notify the ScriptStreamer when it is |
570 // destroyed. | 570 // destroyed. |
571 script.setStreamer(ScriptStreamer::create(resource, scriptType, scriptState,
compileOption)); | 571 script.setStreamer(ScriptStreamer::create(resource, scriptType, scriptState,
compileOption)); |
572 | 572 |
573 return true; | 573 return true; |
574 } | 574 } |
575 | 575 |
576 } // namespace blink | 576 } // namespace blink |
OLD | NEW |