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

Unified Diff: content/browser/renderer_host/render_process_host_impl.cc

Issue 2857213005: PlzNavigate: implement process reuse for ServiceWorkers (Closed)
Patch Set: Created 3 years, 7 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 side-by-side diff with in-line comments
Download patch
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(

Powered by Google App Engine
This is Rietveld 408576698