| 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 4b8da41c0162081e2f28950e3fa15fba28df747e..0e30f25ad8c6dd539c5963fe4e5058ca2e368c28 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
|
| +// 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 kCommittedSiteCountPerProcessTrackerKey =
|
| + "CommittedSiteCountPerProcessTrackerKey";
|
| +const void* const kPendingSiteCountPerProcessTrackerKey =
|
| + "PendingSiteCountPerProcessTrackerKey";
|
| +class SiteCountPerProcessTracker : public base::SupportsUserData::Data {
|
| + public:
|
| + SiteCountPerProcessTracker() {}
|
| + ~SiteCountPerProcessTracker() override {}
|
| +
|
| + void AddCountForSiteForProcess(int render_process_host_id,
|
| + 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,
|
| + 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_;
|
| }
|
| @@ -2864,6 +3001,9 @@ RenderProcessHost* RenderProcessHostImpl::GetProcessHostForSiteInstance(
|
| DCHECK(SiteIsolationPolicy::IsTopDocumentIsolationEnabled());
|
| render_process_host = GetDefaultSubframeProcessHost(
|
| browser_context, site_instance, is_for_guests_only);
|
| + case SiteInstanceImpl::ProcessReusePolicy::REUSE_PENDING_OR_COMMITTED_SITE:
|
| + render_process_host =
|
| + FindReusableProcessHostForSite(browser_context, site_url);
|
| break;
|
| default:
|
| break;
|
| @@ -3257,6 +3397,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);
|
| + }
|
| +
|
| + 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(
|
|
|