Index: content/browser/renderer_host/render_process_host_impl.cc |
diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc |
index c94b514e0caf32eeddd9f42c60fdb76843f2c5ce..d2a764609d624deed85d6fa3db173416138aac98 100644 |
--- a/content/browser/renderer_host/render_process_host_impl.cc |
+++ b/content/browser/renderer_host/render_process_host_impl.cc |
@@ -629,6 +629,67 @@ class RenderProcessHostIsReadyObserver : public RenderProcessHostObserver { |
DISALLOW_COPY_AND_ASSIGN(RenderProcessHostIsReadyObserver); |
}; |
+// The following object is used to keep track of which sites |
Charlie Reis
2017/05/23 07:29:13
nit: s/object/class/
nit: used to track the sites
clamy
2017/05/23 13:41:15
Done.
|
+// RenderProcessHosts are hosting frames and expecting navigations to. |
+// There are two of them per BrowserContext, one for frames and one for |
Charlie Reis
2017/05/23 07:29:13
nit: Colon rather than comma (to make it seem more
clamy
2017/05/23 13:41:15
Done.
|
+// navigations. |
Charlie Reis
2017/05/23 07:29:13
Can you elaborate a bit further here, explaining h
clamy
2017/05/23 13:41:15
Done.
|
+const void* const kCommittedSiteCountPerProcessTrackerKey = |
+ "CommittedSiteCountPerProcessTrackerKey"; |
+const void* const kPendingSiteCountPerProcessTrackerKey = |
+ "PendingSiteCountPerProcessTrackerKey"; |
+class SiteCountPerProcessTracker : public base::SupportsUserData::Data { |
Charlie Reis
2017/05/23 07:29:13
nit: Maybe SiteProcessCountTracker (now that we've
clamy
2017/05/23 13:41:15
Done.
|
+ public: |
+ SiteCountPerProcessTracker() {} |
+ ~SiteCountPerProcessTracker() override {} |
+ |
+ void AddCountForSiteForProcess(int render_process_host_id, |
Charlie Reis
2017/05/23 07:29:13
nit: IncrementSiteProcessCount
nit: Swap parameter
clamy
2017/05/23 13:41:15
Done.
|
+ const GURL& site_url) { |
+ std::map<ProcessID, Count>& counts_per_process = map_[site_url]; |
+ ++counts_per_process[render_process_host_id]; |
+ } |
+ |
+ void RemoveCountForSiteForProcess(int render_process_host_id, |
Charlie Reis
2017/05/23 07:29:13
nit: DecrementSiteProcessCount and swap parameter
clamy
2017/05/23 13:41:15
Done.
|
+ const GURL& site_url) { |
+ auto result = map_.find(site_url); |
+ DCHECK(result != map_.end()); |
+ std::map<ProcessID, Count>& counts_per_process = result->second; |
+ |
+ --counts_per_process[render_process_host_id]; |
+ DCHECK(counts_per_process[render_process_host_id] >= 0); |
+ |
+ if (counts_per_process[render_process_host_id] == 0) |
+ counts_per_process.erase(render_process_host_id); |
+ |
+ if (counts_per_process.empty()) |
+ map_.erase(site_url); |
+ } |
+ |
+ void FindRenderProcessesForSite( |
+ const GURL& site_url, |
+ std::set<RenderProcessHost*>* foreground_processes, |
+ std::set<RenderProcessHost*>* background_processes) { |
+ auto result = map_.find(site_url); |
+ if (result == map_.end()) |
+ return; |
+ |
+ std::map<ProcessID, Count>& counts_per_process = result->second; |
+ for (auto iter : counts_per_process) { |
+ RenderProcessHost* host = RenderProcessHost::FromID(iter.first); |
+ DCHECK(host); |
+ if (host->VisibleWidgetCount()) |
+ foreground_processes->insert(host); |
+ else |
+ background_processes->insert(host); |
+ } |
+ } |
+ |
+ private: |
+ using ProcessID = int; |
+ using Count = int; |
+ using CountPerProcessPerSiteMap = std::map<GURL, std::map<ProcessID, Count>>; |
+ CountPerProcessPerSiteMap map_; |
+}; |
+ |
} // namespace |
RendererMainThreadFactoryFunction g_renderer_main_thread_factory = NULL; |
@@ -1748,6 +1809,82 @@ void RenderProcessHostImpl::set_render_process_host_factory( |
g_render_process_host_factory_ = rph_factory; |
} |
+// static |
+void RenderProcessHostImpl::AddFrameWithSite( |
+ BrowserContext* browser_context, |
+ RenderProcessHost* render_process_host, |
+ const GURL& site_url) { |
+ if (site_url.is_empty()) |
+ return; |
+ |
+ SiteCountPerProcessTracker* tracker = |
+ static_cast<SiteCountPerProcessTracker*>(browser_context->GetUserData( |
+ kCommittedSiteCountPerProcessTrackerKey)); |
+ if (!tracker) { |
+ tracker = new SiteCountPerProcessTracker(); |
+ browser_context->SetUserData(kCommittedSiteCountPerProcessTrackerKey, |
+ base::WrapUnique(tracker)); |
+ } |
+ tracker->AddCountForSiteForProcess(render_process_host->GetID(), site_url); |
+} |
+ |
+// static |
+void RenderProcessHostImpl::RemoveFrameWithSite( |
+ BrowserContext* browser_context, |
+ RenderProcessHost* render_process_host, |
+ const GURL& site_url) { |
+ if (site_url.is_empty()) |
+ return; |
+ |
+ SiteCountPerProcessTracker* tracker = |
+ static_cast<SiteCountPerProcessTracker*>(browser_context->GetUserData( |
+ kCommittedSiteCountPerProcessTrackerKey)); |
+ if (!tracker) { |
+ tracker = new SiteCountPerProcessTracker(); |
+ browser_context->SetUserData(kCommittedSiteCountPerProcessTrackerKey, |
+ base::WrapUnique(tracker)); |
+ } |
+ tracker->RemoveCountForSiteForProcess(render_process_host->GetID(), site_url); |
+} |
+ |
+// static |
+void RenderProcessHostImpl::AddExpectedNavigationToSite( |
+ BrowserContext* browser_context, |
+ RenderProcessHost* render_process_host, |
+ const GURL& site_url) { |
+ if (site_url.is_empty()) |
+ return; |
+ |
+ SiteCountPerProcessTracker* tracker = |
+ static_cast<SiteCountPerProcessTracker*>( |
+ browser_context->GetUserData(kPendingSiteCountPerProcessTrackerKey)); |
+ if (!tracker) { |
+ tracker = new SiteCountPerProcessTracker(); |
+ browser_context->SetUserData(kPendingSiteCountPerProcessTrackerKey, |
+ base::WrapUnique(tracker)); |
+ } |
+ tracker->AddCountForSiteForProcess(render_process_host->GetID(), site_url); |
+} |
+ |
+// static |
+void RenderProcessHostImpl::RemoveExpectedNavigationToSite( |
+ BrowserContext* browser_context, |
+ RenderProcessHost* render_process_host, |
+ const GURL& site_url) { |
+ if (site_url.is_empty()) |
+ return; |
+ |
+ SiteCountPerProcessTracker* tracker = |
+ static_cast<SiteCountPerProcessTracker*>( |
+ browser_context->GetUserData(kPendingSiteCountPerProcessTrackerKey)); |
+ if (!tracker) { |
+ tracker = new SiteCountPerProcessTracker(); |
+ browser_context->SetUserData(kPendingSiteCountPerProcessTrackerKey, |
+ base::WrapUnique(tracker)); |
+ } |
+ tracker->RemoveCountForSiteForProcess(render_process_host->GetID(), site_url); |
+} |
+ |
bool RenderProcessHostImpl::IsForGuestsOnly() const { |
return is_for_guests_only_; |
} |
@@ -2873,6 +3010,10 @@ RenderProcessHost* RenderProcessHostImpl::GetProcessHostForSiteInstance( |
render_process_host = GetDefaultSubframeProcessHost( |
browser_context, site_instance, is_for_guests_only); |
break; |
+ case SiteInstanceImpl::ProcessReusePolicy::REUSE_PENDING_OR_COMMITTED_SITE: |
+ render_process_host = |
+ FindReusableProcessHostForSite(browser_context, site_url); |
+ break; |
default: |
break; |
} |
@@ -3265,6 +3406,55 @@ RenderProcessHost* RenderProcessHostImpl::GetDefaultSubframeProcessHost( |
return holder->GetProcessHost(site_instance, is_for_guests_only); |
} |
+// static |
+RenderProcessHost* RenderProcessHostImpl::FindReusableProcessHostForSite( |
+ BrowserContext* browser_context, |
+ const GURL& site_url) { |
+ if (site_url.is_empty()) |
+ return nullptr; |
+ |
+ std::set<RenderProcessHost*> eligible_foreground_hosts; |
+ std::set<RenderProcessHost*> eligible_background_hosts; |
+ |
+ // Add the RenderProcessHosts hosting a frame for |site_url| to the list of |
+ // eligible RenderProcessHosts. |
+ SiteCountPerProcessTracker* committed_tracker = |
+ static_cast<SiteCountPerProcessTracker*>(browser_context->GetUserData( |
+ kCommittedSiteCountPerProcessTrackerKey)); |
+ if (committed_tracker) { |
+ committed_tracker->FindRenderProcessesForSite( |
+ site_url, &eligible_foreground_hosts, &eligible_background_hosts); |
+ } |
+ |
+ // Add the RenderProcessHosts expecting a navigation to |site_url| to the list |
+ // of eligible RenderProcessHosts. |
+ SiteCountPerProcessTracker* pending_tracker = |
+ static_cast<SiteCountPerProcessTracker*>( |
+ browser_context->GetUserData(kPendingSiteCountPerProcessTrackerKey)); |
+ if (pending_tracker) { |
+ pending_tracker->FindRenderProcessesForSite( |
+ site_url, &eligible_foreground_hosts, &eligible_background_hosts); |
Charlie Reis
2017/05/23 07:29:14
Should there be any preference between processes t
clamy
2017/05/23 13:41:15
I think it would prioritize the navigating ones to
|
+ } |
+ |
+ if (!eligible_foreground_hosts.empty()) { |
+ int index = base::RandInt(0, eligible_foreground_hosts.size() - 1); |
+ auto iterator = eligible_foreground_hosts.begin(); |
+ for (int i = 0; i < index; ++i) |
+ ++iterator; |
+ return (*iterator); |
+ } |
+ |
+ if (!eligible_background_hosts.empty()) { |
+ int index = base::RandInt(0, eligible_background_hosts.size() - 1); |
+ auto iterator = eligible_background_hosts.begin(); |
+ for (int i = 0; i < index; ++i) |
+ ++iterator; |
+ return (*iterator); |
+ } |
+ |
+ return nullptr; |
+} |
+ |
#if BUILDFLAG(ENABLE_WEBRTC) |
void RenderProcessHostImpl::OnRegisterAecDumpConsumer(int id) { |
BrowserThread::PostTask( |