Chromium Code Reviews| 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( |