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

Side by Side Diff: chrome/browser/prerender/prerender_manager.cc

Issue 9270018: Make a separate histogram for MatchComplete Final Status'es and (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 8 years, 11 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "chrome/browser/prerender/prerender_manager.h" 5 #include "chrome/browser/prerender/prerender_manager.h"
6 6
7 #include <string> 7 #include <string>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/bind_helpers.h" 10 #include "base/bind_helpers.h"
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
77 "POST", 77 "POST",
78 "TRACE", 78 "TRACE",
79 }; 79 };
80 80
81 // Length of prerender history, for display in chrome://net-internals 81 // Length of prerender history, for display in chrome://net-internals
82 const int kHistoryLength = 100; 82 const int kHistoryLength = 100;
83 83
84 // Indicates whether a Prerender has been cancelled such that we need 84 // Indicates whether a Prerender has been cancelled such that we need
85 // a dummy replacement for the purpose of recording the correct PPLT for 85 // a dummy replacement for the purpose of recording the correct PPLT for
86 // the Match Complete case. 86 // the Match Complete case.
87 // Traditionally, "Match" means that a prerendered page was actually visited &
88 // the prerender was used. Our goal is to have "Match" cases line up in the
89 // control group & the experiment group, so that we can make meaningful
90 // comparisons of improvements. However, in the control group, since we don't
91 // actually perform prerenders, many of the cancellation reasons cannot be
92 // detected. Therefore, in the Prerender group, when we cancel for one of these
93 // reasons, we keep track of a dummy Prerender representing what we would
94 // have in the control group. If that dummy prerender in the prerender group
95 // would then be swapped in (but isn't actually b/c it's a dummy), we record
96 // this as a MatchComplete. This allows us to compare MatchComplete's
97 // across Prerender & Control group which ideally should be lining up.
98 // This ensures that there is no bias in terms of the page load times
99 // of the pages forming the difference between the two sets.
dominich 2012/01/23 22:41:40 Could you create an issue for someone to look into
tburkard 2012/01/24 00:59:56 Created Issue 111130 On 2012/01/23 22:41:40, domi
87 100
88 bool NeedMatchCompleteDummyForFinalStatus(FinalStatus final_status) { 101 bool NeedMatchCompleteDummyForFinalStatus(FinalStatus final_status) {
89 return final_status != FINAL_STATUS_USED && 102 return final_status != FINAL_STATUS_USED &&
90 final_status != FINAL_STATUS_TIMED_OUT && 103 final_status != FINAL_STATUS_TIMED_OUT &&
91 final_status != FINAL_STATUS_EVICTED && 104 final_status != FINAL_STATUS_EVICTED &&
92 final_status != FINAL_STATUS_MANAGER_SHUTDOWN && 105 final_status != FINAL_STATUS_MANAGER_SHUTDOWN &&
93 final_status != FINAL_STATUS_APP_TERMINATING && 106 final_status != FINAL_STATUS_APP_TERMINATING &&
94 final_status != FINAL_STATUS_RENDERER_CRASHED && 107 final_status != FINAL_STATUS_RENDERER_CRASHED &&
95 final_status != FINAL_STATUS_WINDOW_OPENER && 108 final_status != FINAL_STATUS_WINDOW_OPENER &&
96 final_status != FINAL_STATUS_FRAGMENT_MISMATCH && 109 final_status != FINAL_STATUS_FRAGMENT_MISMATCH &&
97 final_status != FINAL_STATUS_CACHE_OR_HISTORY_CLEARED && 110 final_status != FINAL_STATUS_CACHE_OR_HISTORY_CLEARED &&
98 final_status != FINAL_STATUS_CANCELLED && 111 final_status != FINAL_STATUS_CANCELLED &&
112 final_status != FINAL_STATUS_SESSION_STORAGE_NAMESPACE_MISMATCH &&
113 final_status != FINAL_STATUS_DEVTOOLS_ATTACHED &&
114 final_status != FINAL_STATUS_CROSS_SITE_NAVIGATION_PENDING &&
99 final_status != FINAL_STATUS_MATCH_COMPLETE_DUMMY; 115 final_status != FINAL_STATUS_MATCH_COMPLETE_DUMMY;
100 } 116 }
101 117
102 } // namespace 118 } // namespace
103 119
104 class PrerenderManager::OnCloseTabContentsDeleter 120 class PrerenderManager::OnCloseTabContentsDeleter
105 : public content::WebContentsDelegate, 121 : public content::WebContentsDelegate,
106 public base::SupportsWeakPtr< 122 public base::SupportsWeakPtr<
107 PrerenderManager::OnCloseTabContentsDeleter> { 123 PrerenderManager::OnCloseTabContentsDeleter> {
108 public: 124 public:
(...skipping 321 matching lines...) Expand 10 before | Expand all | Expand 10 after
430 if (!prerender_contents || !prerender_contents->Init()) 446 if (!prerender_contents || !prerender_contents->Init())
431 return false; 447 return false;
432 448
433 histograms_->RecordPrerenderStarted(origin); 449 histograms_->RecordPrerenderStarted(origin);
434 450
435 // TODO(cbentzel): Move invalid checks here instead of PrerenderContents? 451 // TODO(cbentzel): Move invalid checks here instead of PrerenderContents?
436 PrerenderContentsData data(prerender_contents, GetCurrentTime()); 452 PrerenderContentsData data(prerender_contents, GetCurrentTime());
437 453
438 prerender_list_.push_back(data); 454 prerender_list_.push_back(data);
439 455
440 if (IsControlGroup()) { 456 if (!IsControlGroup()) {
441 data.contents_->set_final_status(FINAL_STATUS_CONTROL_GROUP);
442 } else {
443 last_prerender_start_time_ = GetCurrentTimeTicks(); 457 last_prerender_start_time_ = GetCurrentTimeTicks();
444 data.contents_->StartPrerendering(source_render_view_host, 458 data.contents_->StartPrerendering(source_render_view_host,
445 session_storage_namespace); 459 session_storage_namespace);
446 } 460 }
447 while (prerender_list_.size() > config_.max_elements) { 461 while (prerender_list_.size() > config_.max_elements) {
448 data = prerender_list_.front(); 462 data = prerender_list_.front();
449 prerender_list_.pop_front(); 463 prerender_list_.pop_front();
450 data.contents_->Destroy(FINAL_STATUS_EVICTED); 464 data.contents_->Destroy(FINAL_STATUS_EVICTED);
451 } 465 }
452 StartSchedulingPeriodicCleanups(); 466 StartSchedulingPeriodicCleanups();
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
527 } 541 }
528 } 542 }
529 // Entry not found. 543 // Entry not found.
530 return NULL; 544 return NULL;
531 } 545 }
532 546
533 PrerenderContents* PrerenderManager::GetEntry(const GURL& url) { 547 PrerenderContents* PrerenderManager::GetEntry(const GURL& url) {
534 return GetEntryButNotSpecifiedWC(url, NULL); 548 return GetEntryButNotSpecifiedWC(url, NULL);
535 } 549 }
536 550
551 void PrerenderManager::DestroyAndMarkMatchCompleteAsUsed(
552 PrerenderContents* prerender_contents,
553 FinalStatus final_status) {
554 prerender_contents->set_mc_status(PrerenderContents::MC_REPLACED);
555 histograms_->RecordFinalStatusMatchComplete(
556 prerender_contents->origin(),
557 prerender_contents->experiment_id(),
558 FINAL_STATUS_USED);
559 prerender_contents->Destroy(final_status);
560 }
561
537 bool PrerenderManager::MaybeUsePrerenderedPage(WebContents* web_contents, 562 bool PrerenderManager::MaybeUsePrerenderedPage(WebContents* web_contents,
538 const GURL& url, 563 const GURL& url,
539 const GURL& opener_url) { 564 const GURL& opener_url) {
540 DCHECK(CalledOnValidThread()); 565 DCHECK(CalledOnValidThread());
541 RecordNavigation(url); 566 RecordNavigation(url);
542 567
543 scoped_ptr<PrerenderContents> prerender_contents( 568 scoped_ptr<PrerenderContents> prerender_contents(
544 GetEntryButNotSpecifiedWC(url, web_contents)); 569 GetEntryButNotSpecifiedWC(url, web_contents));
545 if (prerender_contents.get() == NULL) 570 if (prerender_contents.get() == NULL)
546 return false; 571 return false;
(...skipping 15 matching lines...) Expand all
562 if (url_matches && url.ref() != matching_url.ref()) { 587 if (url_matches && url.ref() != matching_url.ref()) {
563 prerender_contents.release()->Destroy(FINAL_STATUS_FRAGMENT_MISMATCH); 588 prerender_contents.release()->Destroy(FINAL_STATUS_FRAGMENT_MISMATCH);
564 return false; 589 return false;
565 } 590 }
566 591
567 // If we are just in the control group (which can be detected by noticing 592 // If we are just in the control group (which can be detected by noticing
568 // that prerendering hasn't even started yet), record that |web_contents| now 593 // that prerendering hasn't even started yet), record that |web_contents| now
569 // would be showing a prerendered contents, but otherwise, don't do anything. 594 // would be showing a prerendered contents, but otherwise, don't do anything.
570 if (!prerender_contents->prerendering_has_started()) { 595 if (!prerender_contents->prerendering_has_started()) {
571 MarkWebContentsAsWouldBePrerendered(web_contents); 596 MarkWebContentsAsWouldBePrerendered(web_contents);
597 prerender_contents.release()->Destroy(FINAL_STATUS_USED);
dominich 2012/01/23 22:41:40 Was this leaking before?
tburkard 2012/01/24 00:59:56 No. Before, the final status in this case was e.g
572 return false; 598 return false;
573 } 599 }
574 600
575 // Don't use prerendered pages if debugger is attached to the tab. 601 // Don't use prerendered pages if debugger is attached to the tab.
576 // See http://crbug.com/98541 602 // See http://crbug.com/98541
577 if (content::DevToolsAgentHostRegistry::IsDebuggerAttached(web_contents)) { 603 if (content::DevToolsAgentHostRegistry::IsDebuggerAttached(web_contents)) {
578 prerender_contents.release()->Destroy(FINAL_STATUS_DEVTOOLS_ATTACHED); 604 DestroyAndMarkMatchCompleteAsUsed(prerender_contents.release(),
605 FINAL_STATUS_DEVTOOLS_ATTACHED);
579 return false; 606 return false;
580 } 607 }
581 608
582 // If the prerendered page is in the middle of a cross-site navigation, 609 // If the prerendered page is in the middle of a cross-site navigation,
583 // don't swap it in because there isn't a good way to merge histories. 610 // don't swap it in because there isn't a good way to merge histories.
584 if (prerender_contents->IsCrossSiteNavigationPending()) { 611 if (prerender_contents->IsCrossSiteNavigationPending()) {
585 prerender_contents.release()->Destroy( 612 DestroyAndMarkMatchCompleteAsUsed(
613 prerender_contents.release(),
586 FINAL_STATUS_CROSS_SITE_NAVIGATION_PENDING); 614 FINAL_STATUS_CROSS_SITE_NAVIGATION_PENDING);
587 return false; 615 return false;
588 } 616 }
589 617
590 // If the session storage namespaces don't match, cancel the prerender. 618 // If the session storage namespaces don't match, cancel the prerender.
591 RenderViewHost* old_render_view_host = web_contents->GetRenderViewHost(); 619 RenderViewHost* old_render_view_host = web_contents->GetRenderViewHost();
592 RenderViewHost* new_render_view_host = 620 RenderViewHost* new_render_view_host =
593 prerender_contents->prerender_contents()->web_contents()-> 621 prerender_contents->prerender_contents()->web_contents()->
594 GetRenderViewHost(); 622 GetRenderViewHost();
595 DCHECK(old_render_view_host); 623 DCHECK(old_render_view_host);
596 DCHECK(new_render_view_host); 624 DCHECK(new_render_view_host);
597 if (old_render_view_host->session_storage_namespace() != 625 if (old_render_view_host->session_storage_namespace() !=
598 new_render_view_host->session_storage_namespace()) { 626 new_render_view_host->session_storage_namespace()) {
599 prerender_contents.release()->Destroy( 627 DestroyAndMarkMatchCompleteAsUsed(
628 prerender_contents.release(),
600 FINAL_STATUS_SESSION_STORAGE_NAMESPACE_MISMATCH); 629 FINAL_STATUS_SESSION_STORAGE_NAMESPACE_MISMATCH);
601 return false; 630 return false;
602 } 631 }
603 632
604 // If we don't want to use prerenders at all, we are done. 633 // If we don't want to use prerenders at all, we are done.
605 // For bookkeeping purposes, we need to mark this TabContents to 634 // For bookkeeping purposes, we need to mark this TabContents to
606 // reflect that it would have been prerendered. 635 // reflect that it would have been prerendered.
607 if (GetMode() == PRERENDER_MODE_EXPERIMENT_NO_USE_GROUP) { 636 if (GetMode() == PRERENDER_MODE_EXPERIMENT_NO_USE_GROUP) {
608 MarkWebContentsAsWouldBePrerendered(web_contents); 637 MarkWebContentsAsWouldBePrerendered(web_contents);
609 prerender_contents.release()->Destroy(FINAL_STATUS_NO_USE_GROUP); 638 prerender_contents.release()->Destroy(FINAL_STATUS_NO_USE_GROUP);
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
698 it != prerender_list_.end(); 727 it != prerender_list_.end();
699 ++it) { 728 ++it) {
700 if (it->contents_ == entry) { 729 if (it->contents_ == entry) {
701 bool swapped_in_dummy_replacement = false; 730 bool swapped_in_dummy_replacement = false;
702 731
703 // If this PrerenderContents is being deleted due to a cancellation, 732 // If this PrerenderContents is being deleted due to a cancellation,
704 // we need to create a dummy replacement for PPLT accounting purposes 733 // we need to create a dummy replacement for PPLT accounting purposes
705 // for the Match Complete group. 734 // for the Match Complete group.
706 // This is the case if the cancellation is for any reason that would not 735 // This is the case if the cancellation is for any reason that would not
707 // occur in the control group case. 736 // occur in the control group case.
708 if (NeedMatchCompleteDummyForFinalStatus(final_status)) { 737 if (entry->mc_status() == PrerenderContents::MC_DEFAULT &&
738 NeedMatchCompleteDummyForFinalStatus(final_status)) {
709 // TODO(tburkard): I'd like to DCHECK that we are actually prerendering. 739 // TODO(tburkard): I'd like to DCHECK that we are actually prerendering.
710 // However, what if new conditions are added and 740 // However, what if new conditions are added and
711 // NeedMatchCompleteDummyForFinalStatus, is not being updated. Not sure 741 // NeedMatchCompleteDummyForFinalStatus, is not being updated. Not sure
712 // what's the best thing to do here. For now, I will just check whether 742 // what's the best thing to do here. For now, I will just check whether
713 // we are actually prerendering. 743 // we are actually prerendering.
714 if (ActuallyPrerendering()) { 744 if (ActuallyPrerendering()) {
745 entry->set_mc_status(PrerenderContents::MC_REPLACED);
715 PrerenderContents* dummy_replacement_prerender_contents = 746 PrerenderContents* dummy_replacement_prerender_contents =
716 CreatePrerenderContents( 747 CreatePrerenderContents(
717 entry->prerender_url(), 748 entry->prerender_url(),
718 entry->referrer(), 749 entry->referrer(),
719 entry->origin(), 750 entry->origin(),
720 entry->experiment_id()); 751 entry->experiment_id());
721 if (dummy_replacement_prerender_contents && 752 if (dummy_replacement_prerender_contents &&
722 dummy_replacement_prerender_contents->Init()) { 753 dummy_replacement_prerender_contents->Init()) {
723 dummy_replacement_prerender_contents-> 754 dummy_replacement_prerender_contents->
724 AddAliasURLsFromOtherPrerenderContents(entry); 755 AddAliasURLsFromOtherPrerenderContents(entry);
756 dummy_replacement_prerender_contents->set_mc_status(
757 PrerenderContents::MC_REPLACEMENT);
725 it->contents_ = dummy_replacement_prerender_contents; 758 it->contents_ = dummy_replacement_prerender_contents;
726 it->contents_->set_final_status(FINAL_STATUS_MATCH_COMPLETE_DUMMY);
727 swapped_in_dummy_replacement = true; 759 swapped_in_dummy_replacement = true;
728 } 760 }
729 } 761 }
730 } 762 }
731 if (!swapped_in_dummy_replacement) 763 if (!swapped_in_dummy_replacement)
732 prerender_list_.erase(it); 764 prerender_list_.erase(it);
733 break; 765 break;
734 } 766 }
735 } 767 }
736 AddToHistory(entry); 768 AddToHistory(entry);
(...skipping 355 matching lines...) Expand 10 before | Expand all | Expand 10 after
1092 void PrerenderManager::DestroyAllContents(FinalStatus final_status) { 1124 void PrerenderManager::DestroyAllContents(FinalStatus final_status) {
1093 DeleteOldTabContents(); 1125 DeleteOldTabContents();
1094 while (!prerender_list_.empty()) { 1126 while (!prerender_list_.empty()) {
1095 PrerenderContentsData data = prerender_list_.front(); 1127 PrerenderContentsData data = prerender_list_.front();
1096 prerender_list_.pop_front(); 1128 prerender_list_.pop_front();
1097 data.contents_->Destroy(final_status); 1129 data.contents_->Destroy(final_status);
1098 } 1130 }
1099 DeletePendingDeleteEntries(); 1131 DeletePendingDeleteEntries();
1100 } 1132 }
1101 1133
1134 void PrerenderManager::RecordFinalStatusWithMatchCompleteStatus(
1135 Origin origin,
1136 uint8 experiment_id,
1137 PrerenderContents::MatchCompleteStatus mc_status,
1138 FinalStatus final_status) const {
1139 if (mc_status != PrerenderContents::MC_REPLACEMENT)
1140 histograms_->RecordFinalStatus(origin, experiment_id, final_status);
1141 if (mc_status != PrerenderContents::MC_REPLACED) {
1142 histograms_->RecordFinalStatusMatchComplete(origin, experiment_id,
1143 final_status);
1144 }
1145 }
1146
1102 void PrerenderManager::RecordFinalStatus(Origin origin, 1147 void PrerenderManager::RecordFinalStatus(Origin origin,
1103 uint8 experiment_id, 1148 uint8 experiment_id,
1104 FinalStatus final_status) const { 1149 FinalStatus final_status) const {
1105 histograms_->RecordFinalStatus(origin, experiment_id, final_status); 1150 RecordFinalStatusWithMatchCompleteStatus(origin, experiment_id,
1151 PrerenderContents::MC_DEFAULT,
1152 final_status);
1106 } 1153 }
1107 1154
1155
1108 PrerenderManager* FindPrerenderManagerUsingRenderProcessId( 1156 PrerenderManager* FindPrerenderManagerUsingRenderProcessId(
1109 int render_process_id) { 1157 int render_process_id) {
1110 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1158 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1111 content::RenderProcessHost* render_process_host = 1159 content::RenderProcessHost* render_process_host =
1112 content::RenderProcessHost::FromID(render_process_id); 1160 content::RenderProcessHost::FromID(render_process_id);
1113 // Each render process is guaranteed to only hold RenderViews owned by the 1161 // Each render process is guaranteed to only hold RenderViews owned by the
1114 // same BrowserContext. This is enforced by 1162 // same BrowserContext. This is enforced by
1115 // RenderProcessHost::GetExistingProcessHost. 1163 // RenderProcessHost::GetExistingProcessHost.
1116 if (!render_process_host || !render_process_host->GetBrowserContext()) 1164 if (!render_process_host || !render_process_host->GetBrowserContext())
1117 return NULL; 1165 return NULL;
1118 Profile* profile = Profile::FromBrowserContext( 1166 Profile* profile = Profile::FromBrowserContext(
1119 render_process_host->GetBrowserContext()); 1167 render_process_host->GetBrowserContext());
1120 if (!profile) 1168 if (!profile)
1121 return NULL; 1169 return NULL;
1122 return PrerenderManagerFactory::GetInstance()->GetForProfile(profile); 1170 return PrerenderManagerFactory::GetInstance()->GetForProfile(profile);
1123 } 1171 }
1124 1172
1125 } // namespace prerender 1173 } // namespace prerender
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698