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 02f2bf99b06e234512fd311e96e72b0f3838a808..3870025b02cf754dd469e6407fcf415a24a8a660 100644 |
| --- a/content/browser/renderer_host/render_process_host_impl.cc |
| +++ b/content/browser/renderer_host/render_process_host_impl.cc |
| @@ -564,6 +564,66 @@ class WorkerURLLoaderFactoryProviderImpl |
| scoped_refptr<ServiceWorkerContextWrapper> service_worker_context_; |
| }; |
| +// The following object is used to keep track of which sites |
| +// RenderProcessHosts are hosting frames and expecting navigations to. |
| +// There are two of them per BrowserContext, one for frames and one for |
| +// navigations. |
| +const void* const kFrameSiteCountPerProcessTrackerKey = |
|
Charlie Reis
2017/05/15 03:41:52
I think pending and committed are probably better
clamy
2017/05/16 14:50:46
Done.
|
| + "FrameSiteCountPerProcessTrackerKey"; |
| +const void* const kNavigationSiteCountPerProcessTrackerKey = |
| + "NavigationSiteCountPerProcessTrackerKey"; |
| +class SiteCountPerProcessTracker : public base::SupportsUserData::Data, |
|
clamy
2017/05/04 16:01:01
This class + data structure looks a bit weird. Thi
nasko
2017/05/05 05:22:00
Yuck! Yet another reason to hate MockRenderProcess
Charlie Reis
2017/05/15 03:41:52
If we really want per-RPH state, we should find a
clamy
2017/05/15 15:21:15
This is how I had written it initially. However, w
Charlie Reis
2017/05/15 23:46:18
Interesting! Yes, I hadn't thought about the proc
clamy
2017/05/16 14:50:46
I've reversed the map as asked, and remove the obs
|
| + public RenderProcessHostObserver { |
| + public: |
| + SiteCountPerProcessTracker() {} |
| + ~SiteCountPerProcessTracker() override {} |
| + |
| + void AddCountForSiteForProcess(RenderProcessHost* render_process_host, |
| + std::string site) { |
|
nasko
2017/05/05 05:22:00
Why accept the site as a string and not a GURL?
clamy
2017/05/16 14:50:46
Done.
|
| + std::map<std::string, int>& counts_per_site = map_[render_process_host]; |
|
nasko
2017/05/05 05:22:00
I assume you are using operator[] intentionally he
clamy
2017/05/05 15:10:11
Yes. We want to create one if we don't have one, a
|
| + if (counts_per_site.empty()) |
| + render_process_host->AddObserver(this); |
| + ++counts_per_site[site]; |
| + } |
| + |
| + void RemoveCountForSiteForProcess(RenderProcessHost* render_process_host, |
| + std::string site) { |
| + std::map<std::string, int>& counts_per_site = map_[render_process_host]; |
|
nasko
2017/05/05 05:22:00
Shouldn't this be map_.find()?
clamy
2017/05/16 14:50:46
Done.
|
| + --counts_per_site[site]; |
| + DCHECK(counts_per_site[site] >= 0); |
| + if (counts_per_site[site] == 0) |
| + counts_per_site.erase(site); |
| + if (counts_per_site.empty()) { |
| + map_.erase(render_process_host); |
| + render_process_host->RemoveObserver(this); |
| + } |
| + } |
| + |
| + void RenderProcessHostDestroyed(RenderProcessHost* host) override { |
| + map_.erase(host); |
| + } |
| + |
| + void FindRenderProcessesForSite( |
| + std::string site, |
| + std::set<RenderProcessHost*>* foreground_processes, |
| + std::set<RenderProcessHost*>* background_processes) { |
| + for (auto site_counts_per_process : map_) { |
| + if (site_counts_per_process.second.count(site) > 0) { |
| + RenderProcessHost* host = site_counts_per_process.first; |
| + if (host->VisibleWidgetCount()) |
| + foreground_processes->insert(host); |
| + else |
| + background_processes->insert(host); |
| + } |
| + } |
| + } |
| + |
| + private: |
| + using SiteCountPerProcessMap = |
| + std::map<RenderProcessHost*, std::map<std::string, int>>; |
| + SiteCountPerProcessMap map_; |
| +}; |
| + |
| } // namespace |
| RendererMainThreadFactoryFunction g_renderer_main_thread_factory = NULL; |
| @@ -1684,6 +1744,90 @@ 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) { |
| + std::string site = SiteInstance::GetSiteForURL(browser_context, site_url) |
| + .possibly_invalid_spec(); |
|
nasko
2017/05/05 05:22:00
Why possibly_invalid_spec()? Shouldn't an non-empt
clamy
2017/05/16 14:50:46
It's now taking a GURL.
|
| + if (site.empty()) |
| + return; |
| + |
| + SiteCountPerProcessTracker* tracker = |
| + static_cast<SiteCountPerProcessTracker*>( |
| + browser_context->GetUserData(kFrameSiteCountPerProcessTrackerKey)); |
| + if (!tracker) { |
| + tracker = new SiteCountPerProcessTracker(); |
| + browser_context->SetUserData(kFrameSiteCountPerProcessTrackerKey, |
| + base::WrapUnique(tracker)); |
| + } |
| + tracker->AddCountForSiteForProcess(render_process_host, site); |
| +} |
| + |
| +// static |
| +void RenderProcessHostImpl::RemoveFrameWithSite( |
| + BrowserContext* browser_context, |
| + RenderProcessHost* render_process_host, |
| + const GURL& site_url) { |
| + std::string site = SiteInstance::GetSiteForURL(browser_context, site_url) |
| + .possibly_invalid_spec(); |
| + if (site.empty()) |
| + return; |
| + |
| + SiteCountPerProcessTracker* tracker = |
| + static_cast<SiteCountPerProcessTracker*>( |
| + browser_context->GetUserData(kFrameSiteCountPerProcessTrackerKey)); |
| + if (!tracker) { |
| + tracker = new SiteCountPerProcessTracker(); |
| + browser_context->SetUserData(kFrameSiteCountPerProcessTrackerKey, |
| + base::WrapUnique(tracker)); |
| + } |
| + tracker->RemoveCountForSiteForProcess(render_process_host, site); |
| +} |
| + |
| +// static |
| +void RenderProcessHostImpl::AddExpectedNavigationToSite( |
| + BrowserContext* browser_context, |
| + RenderProcessHost* render_process_host, |
| + const GURL& site_url) { |
| + std::string site = SiteInstance::GetSiteForURL(browser_context, site_url) |
| + .possibly_invalid_spec(); |
| + if (site.empty()) |
| + return; |
| + |
| + SiteCountPerProcessTracker* tracker = |
| + static_cast<SiteCountPerProcessTracker*>(browser_context->GetUserData( |
| + kNavigationSiteCountPerProcessTrackerKey)); |
| + if (!tracker) { |
| + tracker = new SiteCountPerProcessTracker(); |
| + browser_context->SetUserData(kNavigationSiteCountPerProcessTrackerKey, |
| + base::WrapUnique(tracker)); |
| + } |
| + tracker->AddCountForSiteForProcess(render_process_host, site); |
| +} |
| + |
| +// static |
| +void RenderProcessHostImpl::RemoveExpectedNavigationToSite( |
| + BrowserContext* browser_context, |
| + RenderProcessHost* render_process_host, |
| + const GURL& site_url) { |
| + std::string site = SiteInstance::GetSiteForURL(browser_context, site_url) |
| + .possibly_invalid_spec(); |
| + if (site.empty()) |
| + return; |
| + |
| + SiteCountPerProcessTracker* tracker = |
| + static_cast<SiteCountPerProcessTracker*>(browser_context->GetUserData( |
| + kNavigationSiteCountPerProcessTrackerKey)); |
| + if (!tracker) { |
| + tracker = new SiteCountPerProcessTracker(); |
| + browser_context->SetUserData(kNavigationSiteCountPerProcessTrackerKey, |
| + base::WrapUnique(tracker)); |
| + } |
| + tracker->RemoveCountForSiteForProcess(render_process_host, site); |
| +} |
| + |
| bool RenderProcessHostImpl::IsForGuestsOnly() const { |
| return is_for_guests_only_; |
| } |
| @@ -2796,6 +2940,10 @@ RenderProcessHost* RenderProcessHostImpl::GetProcessHostForSiteInstance( |
| DCHECK(SiteIsolationPolicy::IsTopDocumentIsolationEnabled()); |
| render_process_host = |
| GetDefaultSubframeProcessHost(browser_context, site_instance); |
| + case SiteInstanceImpl::ProcessReusePolicy:: |
| + REUSE_CHECKING_FRAMES_AND_NAVIGATIONS: |
| + render_process_host = |
| + FindReusableProcessHostForSite(browser_context, site_url); |
| break; |
| default: |
| break; |
| @@ -3168,6 +3316,57 @@ RenderProcessHost* RenderProcessHostImpl::GetDefaultSubframeProcessHost( |
| return holder->GetProcessHost(site_instance); |
| } |
| +// static |
| +RenderProcessHost* RenderProcessHostImpl::FindReusableProcessHostForSite( |
| + BrowserContext* browser_context, |
| + const GURL& site_url) { |
| + std::string site = SiteInstance::GetSiteForURL(browser_context, site_url) |
| + .possibly_invalid_spec(); |
| + if (site.empty()) |
| + return nullptr; |
| + |
| + std::set<RenderProcessHost*> eligible_foreground_hosts; |
| + std::set<RenderProcessHost*> eligible_background_hosts; |
| + |
| + // Add the RenderProcessHosts hosting a frame rendering site to the list of |
|
nasko
2017/05/05 05:22:00
nit: "... hosting a frame for |site| to ..."
clamy
2017/05/16 14:50:46
Done.
|
| + // eligible RenderProcessHosts. |
| + SiteCountPerProcessTracker* frame_tracker = |
| + static_cast<SiteCountPerProcessTracker*>( |
| + browser_context->GetUserData(kFrameSiteCountPerProcessTrackerKey)); |
| + if (frame_tracker) { |
| + frame_tracker->FindRenderProcessesForSite(site, &eligible_foreground_hosts, |
| + &eligible_background_hosts); |
| + } |
| + |
| + // Add the RenderProcessHosts expecting a navigation to site to the list of |
| + // eligible RenderProcessHosts. |
| + SiteCountPerProcessTracker* navigation_tracker = |
|
clamy
2017/05/04 16:01:01
if we want to implement process-per-site using thi
|
| + static_cast<SiteCountPerProcessTracker*>(browser_context->GetUserData( |
| + kNavigationSiteCountPerProcessTrackerKey)); |
| + if (frame_tracker) { |
| + navigation_tracker->FindRenderProcessesForSite( |
| + site, &eligible_foreground_hosts, &eligible_background_hosts); |
| + } |
| + |
| + if (!eligible_foreground_hosts.empty()) { |
| + int index = rand() % eligible_foreground_hosts.size(); |
|
nasko
2017/05/05 05:22:00
base::RandInt
clamy
2017/05/16 14:50:46
Done.
|
| + auto iterator = eligible_foreground_hosts.begin(); |
| + for (int i = 0; i < index; ++i) |
| + ++iterator; |
| + return (*iterator); |
| + } |
| + |
| + if (!eligible_background_hosts.empty()) { |
| + int index = rand() % eligible_background_hosts.size(); |
|
nasko
2017/05/05 05:22:00
base::RandInt
clamy
2017/05/16 14:50:46
Done.
|
| + 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( |