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

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

Issue 1031623002: Script streaming: add UMA for tracking the reason why we don't stream. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Created 5 years, 9 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
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 #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"
11 #include "core/dom/Element.h" 11 #include "core/dom/Element.h"
12 #include "core/dom/PendingScript.h" 12 #include "core/dom/PendingScript.h"
13 #include "core/fetch/ScriptResource.h" 13 #include "core/fetch/ScriptResource.h"
14 #include "core/frame/Settings.h" 14 #include "core/frame/Settings.h"
15 #include "core/html/parser/TextResourceDecoder.h" 15 #include "core/html/parser/TextResourceDecoder.h"
16 #include "platform/SharedBuffer.h" 16 #include "platform/SharedBuffer.h"
17 #include "platform/TraceEvent.h" 17 #include "platform/TraceEvent.h"
18 #include "public/platform/Platform.h" 18 #include "public/platform/Platform.h"
19 #include "wtf/MainThread.h" 19 #include "wtf/MainThread.h"
20 #include "wtf/text/TextEncodingRegistry.h" 20 #include "wtf/text/TextEncodingRegistry.h"
21 21
22 namespace blink { 22 namespace blink {
23 23
24 namespace { 24 namespace {
25 const char* kHistogramName = "WebCore.Scripts.Async.StartedStreaming"; 25 const char* kStartedStreamingHistogramName = "WebCore.Scripts.Async.StartedStrea ming";
26 const char* kNotStreamingReasonHistogramName = "WebCore.Scripts.Async.NotStreami ngReason";
26 } 27 }
27 28
28 // For passing data between the main thread (producer) and the streamer thread 29 // For passing data between the main thread (producer) and the streamer thread
29 // (consumer). The main thread prepares the data (copies it from Resource) and 30 // (consumer). The main thread prepares the data (copies it from Resource) and
30 // the streamer thread feeds it to V8. 31 // the streamer thread feeds it to V8.
31 class SourceStreamDataQueue { 32 class SourceStreamDataQueue {
32 WTF_MAKE_NONCOPYABLE(SourceStreamDataQueue); 33 WTF_MAKE_NONCOPYABLE(SourceStreamDataQueue);
33 public: 34 public:
34 SourceStreamDataQueue() 35 SourceStreamDataQueue()
35 : m_finished(false) { } 36 : m_finished(false) { }
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after
222 223
223 size_t ScriptStreamer::kSmallScriptThreshold = 30 * 1024; 224 size_t ScriptStreamer::kSmallScriptThreshold = 30 * 1024;
224 225
225 void ScriptStreamer::startStreaming(PendingScript& script, Settings* settings, S criptState* scriptState) 226 void ScriptStreamer::startStreaming(PendingScript& script, Settings* settings, S criptState* scriptState)
226 { 227 {
227 // We don't yet know whether the script will really be streamed. E.g., 228 // We don't yet know whether the script will really be streamed. E.g.,
228 // suppressing streaming for short scripts is done later. Record only the 229 // suppressing streaming for short scripts is done later. Record only the
229 // sure negative cases here. 230 // sure negative cases here.
230 bool startedStreaming = startStreamingInternal(script, settings, scriptState ); 231 bool startedStreaming = startStreamingInternal(script, settings, scriptState );
231 if (!startedStreaming) 232 if (!startedStreaming)
232 blink::Platform::current()->histogramEnumeration(kHistogramName, 0, 2); 233 blink::Platform::current()->histogramEnumeration(kStartedStreamingHistog ramName, 0, 2);
233 } 234 }
234 235
235 bool ScriptStreamer::convertEncoding(const char* encodingName, v8::ScriptCompile r::StreamedSource::Encoding* encoding) 236 bool ScriptStreamer::convertEncoding(const char* encodingName, v8::ScriptCompile r::StreamedSource::Encoding* encoding)
236 { 237 {
237 // Here's a list of encodings we can use for streaming. These are 238 // Here's a list of encodings we can use for streaming. These are
238 // the canonical names. 239 // the canonical names.
239 if (strcmp(encodingName, "windows-1252") == 0 240 if (strcmp(encodingName, "windows-1252") == 0
240 || strcmp(encodingName, "ISO-8859-1") == 0 241 || strcmp(encodingName, "ISO-8859-1") == 0
241 || strcmp(encodingName, "US-ASCII") == 0) { 242 || strcmp(encodingName, "US-ASCII") == 0) {
242 *encoding = v8::ScriptCompiler::StreamedSource::ONE_BYTE; 243 *encoding = v8::ScriptCompiler::StreamedSource::ONE_BYTE;
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
316 const char* data = 0; 317 const char* data = 0;
317 unsigned length = resource->resourceBuffer()->getSomeData(data, 0); 318 unsigned length = resource->resourceBuffer()->getSomeData(data, 0);
318 319
319 OwnPtr<TextResourceDecoder> decoder(TextResourceDecoder::create("applica tion/javascript", resource->encoding())); 320 OwnPtr<TextResourceDecoder> decoder(TextResourceDecoder::create("applica tion/javascript", resource->encoding()));
320 lengthOfBOM = decoder->checkForBOM(data, length); 321 lengthOfBOM = decoder->checkForBOM(data, length);
321 322
322 // Maybe the encoding changed because we saw the BOM; get the encoding 323 // Maybe the encoding changed because we saw the BOM; get the encoding
323 // from the decoder. 324 // from the decoder.
324 if (!convertEncoding(decoder->encoding().name(), &m_encoding)) { 325 if (!convertEncoding(decoder->encoding().name(), &m_encoding)) {
325 suppressStreaming(); 326 suppressStreaming();
326 blink::Platform::current()->histogramEnumeration(kHistogramName, 0, 2); 327 blink::Platform::current()->histogramEnumeration(kNotStreamingReason HistogramName, 4, 8);
328 blink::Platform::current()->histogramEnumeration(kStartedStreamingHi stogramName, 0, 2);
327 return; 329 return;
328 } 330 }
329 if (ScriptStreamerThread::shared()->isRunningTask()) { 331 if (ScriptStreamerThread::shared()->isRunningTask()) {
330 // At the moment we only have one thread for running the tasks. A 332 // At the moment we only have one thread for running the tasks. A
331 // new task shouldn't be queued before the running task completes, 333 // new task shouldn't be queued before the running task completes,
332 // because the running task can block and wait for data from the 334 // because the running task can block and wait for data from the
333 // network. 335 // network.
334 suppressStreaming(); 336 suppressStreaming();
335 blink::Platform::current()->histogramEnumeration(kHistogramName, 0, 2); 337 blink::Platform::current()->histogramEnumeration(kNotStreamingReason HistogramName, 5, 8);
338 blink::Platform::current()->histogramEnumeration(kStartedStreamingHi stogramName, 0, 2);
336 return; 339 return;
337 } 340 }
338 341
339 if (!m_scriptState->contextIsValid()) { 342 if (!m_scriptState->contextIsValid()) {
340 suppressStreaming(); 343 suppressStreaming();
341 blink::Platform::current()->histogramEnumeration(kHistogramName, 0, 2); 344 blink::Platform::current()->histogramEnumeration(kNotStreamingReason HistogramName, 3, 8);
345 blink::Platform::current()->histogramEnumeration(kStartedStreamingHi stogramName, 0, 2);
342 return; 346 return;
343 } 347 }
344 348
345 ASSERT(!m_stream); 349 ASSERT(!m_stream);
346 ASSERT(!m_source); 350 ASSERT(!m_source);
347 m_stream = new SourceStream(); 351 m_stream = new SourceStream();
348 // m_source takes ownership of m_stream. 352 // m_source takes ownership of m_stream.
349 m_source = adoptPtr(new v8::ScriptCompiler::StreamedSource(m_stream, m_e ncoding)); 353 m_source = adoptPtr(new v8::ScriptCompiler::StreamedSource(m_stream, m_e ncoding));
350 354
351 ScriptState::Scope scope(m_scriptState.get()); 355 ScriptState::Scope scope(m_scriptState.get());
352 WTF::OwnPtr<v8::ScriptCompiler::ScriptStreamingTask> scriptStreamingTask (adoptPtr(v8::ScriptCompiler::StartStreamingScript(m_scriptState->isolate(), m_s ource.get(), m_compileOptions))); 356 WTF::OwnPtr<v8::ScriptCompiler::ScriptStreamingTask> scriptStreamingTask (adoptPtr(v8::ScriptCompiler::StartStreamingScript(m_scriptState->isolate(), m_s ource.get(), m_compileOptions)));
353 if (!scriptStreamingTask) { 357 if (!scriptStreamingTask) {
354 // V8 cannot stream the script. 358 // V8 cannot stream the script.
355 suppressStreaming(); 359 suppressStreaming();
356 m_stream = 0; 360 m_stream = 0;
357 m_source.clear(); 361 m_source.clear();
358 blink::Platform::current()->histogramEnumeration(kHistogramName, 0, 2); 362 blink::Platform::current()->histogramEnumeration(kNotStreamingReason HistogramName, 6, 8);
363 blink::Platform::current()->histogramEnumeration(kStartedStreamingHi stogramName, 0, 2);
359 return; 364 return;
360 } 365 }
361 366
362 // ScriptStreamer needs to stay alive as long as the background task is 367 // ScriptStreamer needs to stay alive as long as the background task is
363 // running. This is taken care of with a manual ref() & deref() pair; 368 // running. This is taken care of with a manual ref() & deref() pair;
364 // the corresponding deref() is in streamingComplete. 369 // the corresponding deref() is in streamingComplete.
365 ref(); 370 ref();
366 ScriptStreamingTask* task = new ScriptStreamingTask(scriptStreamingTask. release(), this); 371 ScriptStreamingTask* task = new ScriptStreamingTask(scriptStreamingTask. release(), this);
367 ScriptStreamerThread::shared()->postTask(task); 372 ScriptStreamerThread::shared()->postTask(task);
368 blink::Platform::current()->histogramEnumeration(kHistogramName, 1, 2); 373 blink::Platform::current()->histogramEnumeration(kStartedStreamingHistog ramName, 1, 2);
369 } 374 }
370 if (m_stream) 375 if (m_stream)
371 m_stream->didReceiveData(this, lengthOfBOM); 376 m_stream->didReceiveData(this, lengthOfBOM);
372 } 377 }
373 378
374 void ScriptStreamer::notifyFinished(Resource* resource) 379 void ScriptStreamer::notifyFinished(Resource* resource)
375 { 380 {
376 ASSERT(isMainThread()); 381 ASSERT(isMainThread());
377 ASSERT(m_resource == resource); 382 ASSERT(m_resource == resource);
378 // A special case: empty and small scripts. We didn't receive enough data to 383 // A special case: empty and small scripts. We didn't receive enough data to
379 // start the streaming before this notification. In that case, there won't 384 // start the streaming before this notification. In that case, there won't
380 // be a "parsing complete" notification either, and we should not wait for 385 // be a "parsing complete" notification either, and we should not wait for
381 // it. 386 // it.
382 if (!m_haveEnoughDataForStreaming) { 387 if (!m_haveEnoughDataForStreaming) {
383 blink::Platform::current()->histogramEnumeration(kHistogramName, 0, 2); 388 blink::Platform::current()->histogramEnumeration(kNotStreamingReasonHist ogramName, 7, 8);
389 blink::Platform::current()->histogramEnumeration(kStartedStreamingHistog ramName, 0, 2);
384 suppressStreaming(); 390 suppressStreaming();
385 } 391 }
386 if (m_stream) 392 if (m_stream)
387 m_stream->didFinishLoading(); 393 m_stream->didFinishLoading();
388 m_loadingFinished = true; 394 m_loadingFinished = true;
389 395
390 // Calling notifyFinishedToClient can result into the upper layers dropping 396 // Calling notifyFinishedToClient can result into the upper layers dropping
391 // references to ScriptStreamer. Keep it alive until this function ends. 397 // references to ScriptStreamer. Keep it alive until this function ends.
392 RefPtrWillBeRawPtr<ScriptStreamer> protect(this); 398 RefPtrWillBeRawPtr<ScriptStreamer> protect(this);
393 399
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
460 return; 466 return;
461 } 467 }
462 if (m_client) 468 if (m_client)
463 m_client->notifyFinished(m_resource); 469 m_client->notifyFinished(m_resource);
464 } 470 }
465 471
466 bool ScriptStreamer::startStreamingInternal(PendingScript& script, Settings* set tings, ScriptState* scriptState) 472 bool ScriptStreamer::startStreamingInternal(PendingScript& script, Settings* set tings, ScriptState* scriptState)
467 { 473 {
468 ASSERT(isMainThread()); 474 ASSERT(isMainThread());
469 ScriptResource* resource = script.resource(); 475 ScriptResource* resource = script.resource();
470 if (resource->isLoaded()) 476 if (resource->isLoaded()) {
477 blink::Platform::current()->histogramEnumeration(kNotStreamingReasonHist ogramName, 0, 8);
471 return false; 478 return false;
472 if (!resource->url().protocolIsInHTTPFamily()) 479 }
480 if (!resource->url().protocolIsInHTTPFamily()) {
481 blink::Platform::current()->histogramEnumeration(kNotStreamingReasonHist ogramName, 1, 8);
473 return false; 482 return false;
483 }
474 if (resource->resourceToRevalidate()) { 484 if (resource->resourceToRevalidate()) {
485 blink::Platform::current()->histogramEnumeration(kNotStreamingReasonHist ogramName, 2, 8);
475 // This happens e.g., during reloads. We're actually not going to load 486 // This happens e.g., during reloads. We're actually not going to load
476 // the current Resource of the PendingScript but switch to another 487 // the current Resource of the PendingScript but switch to another
477 // Resource -> don't stream. 488 // Resource -> don't stream.
478 return false; 489 return false;
479 } 490 }
480 // We cannot filter out short scripts, even if we wait for the HTTP headers 491 // We cannot filter out short scripts, even if we wait for the HTTP headers
481 // to arrive: the Content-Length HTTP header is not sent for chunked 492 // to arrive: the Content-Length HTTP header is not sent for chunked
482 // downloads. 493 // downloads.
483 494
484 if (!scriptState->contextIsValid()) 495 if (!scriptState->contextIsValid()) {
496 blink::Platform::current()->histogramEnumeration(kNotStreamingReasonHist ogramName, 3, 8);
Ilya Sherman 2015/03/23 22:14:44 Could you please use enumerated constant names, ra
485 return false; 497 return false;
498 }
486 499
487 // Decide what kind of cached data we should produce while streaming. By 500 // Decide what kind of cached data we should produce while streaming. By
488 // default, we generate the parser cache for streamed scripts, to emulate 501 // default, we generate the parser cache for streamed scripts, to emulate
489 // the non-streaming behavior (see V8ScriptRunner::compileScript). 502 // the non-streaming behavior (see V8ScriptRunner::compileScript).
490 v8::ScriptCompiler::CompileOptions compileOption = v8::ScriptCompiler::kProd uceParserCache; 503 v8::ScriptCompiler::CompileOptions compileOption = v8::ScriptCompiler::kProd uceParserCache;
491 if (settings->v8CacheOptions() == V8CacheOptionsCode || settings->v8CacheOpt ions() == V8CacheOptionsCodeCompressed) 504 if (settings->v8CacheOptions() == V8CacheOptionsCode || settings->v8CacheOpt ions() == V8CacheOptionsCodeCompressed)
492 compileOption = v8::ScriptCompiler::kProduceCodeCache; 505 compileOption = v8::ScriptCompiler::kProduceCodeCache;
493 506
494 // The Resource might go out of scope if the script is no longer 507 // The Resource might go out of scope if the script is no longer
495 // needed. This makes PendingScript notify the ScriptStreamer when it is 508 // needed. This makes PendingScript notify the ScriptStreamer when it is
496 // destroyed. 509 // destroyed.
497 script.setStreamer(ScriptStreamer::create(resource, scriptState, compileOpti on)); 510 script.setStreamer(ScriptStreamer::create(resource, scriptState, compileOpti on));
498 511
499 return true; 512 return true;
500 } 513 }
501 514
502 } // namespace blink 515 } // namespace blink
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698