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

Side by Side Diff: content/browser/site_instance_impl.cc

Issue 2861433002: Implement ProcessReusePolicy for SiteInstances (Closed)
Patch Set: Rebase 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 unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/browser/site_instance_impl.h" 5 #include "content/browser/site_instance_impl.h"
6 6
7 #include "base/memory/ptr_util.h" 7 #include "base/memory/ptr_util.h"
8 #include "content/browser/browsing_instance.h" 8 #include "content/browser/browsing_instance.h"
9 #include "content/browser/child_process_security_policy_impl.h" 9 #include "content/browser/child_process_security_policy_impl.h"
10 #include "content/browser/frame_host/debug_urls.h" 10 #include "content/browser/frame_host/debug_urls.h"
11 #include "content/browser/frame_host/frame_tree_node.h" 11 #include "content/browser/frame_host/frame_tree_node.h"
12 #include "content/browser/renderer_host/render_process_host_impl.h" 12 #include "content/browser/renderer_host/render_process_host_impl.h"
13 #include "content/browser/storage_partition_impl.h" 13 #include "content/browser/storage_partition_impl.h"
14 #include "content/common/site_isolation_policy.h" 14 #include "content/common/site_isolation_policy.h"
15 #include "content/public/browser/content_browser_client.h" 15 #include "content/public/browser/content_browser_client.h"
16 #include "content/public/browser/render_process_host_factory.h" 16 #include "content/public/browser/render_process_host_factory.h"
17 #include "content/public/browser/web_ui_controller_factory.h" 17 #include "content/public/browser/web_ui_controller_factory.h"
18 #include "content/public/common/url_constants.h" 18 #include "content/public/common/url_constants.h"
19 #include "net/base/registry_controlled_domains/registry_controlled_domain.h" 19 #include "net/base/registry_controlled_domains/registry_controlled_domain.h"
20 20
21 namespace content { 21 namespace content {
22 22
23 const RenderProcessHostFactory*
24 SiteInstanceImpl::g_render_process_host_factory_ = NULL;
25 int32_t SiteInstanceImpl::next_site_instance_id_ = 1; 23 int32_t SiteInstanceImpl::next_site_instance_id_ = 1;
26 24
27 SiteInstanceImpl::SiteInstanceImpl(BrowsingInstance* browsing_instance) 25 SiteInstanceImpl::SiteInstanceImpl(BrowsingInstance* browsing_instance)
28 : id_(next_site_instance_id_++), 26 : id_(next_site_instance_id_++),
29 active_frame_count_(0), 27 active_frame_count_(0),
30 browsing_instance_(browsing_instance), 28 browsing_instance_(browsing_instance),
31 process_(nullptr), 29 process_(nullptr),
32 has_site_(false), 30 has_site_(false),
33 is_default_subframe_site_instance_(false) { 31 process_reuse_policy_(
32 RenderProcessHostImpl::ProcessReusePolicy::DEFAULT) {
34 DCHECK(browsing_instance); 33 DCHECK(browsing_instance);
35 } 34 }
36 35
37 SiteInstanceImpl::~SiteInstanceImpl() { 36 SiteInstanceImpl::~SiteInstanceImpl() {
38 GetContentClient()->browser()->SiteInstanceDeleting(this); 37 GetContentClient()->browser()->SiteInstanceDeleting(this);
39 38
40 if (process_) 39 if (process_)
41 process_->RemoveObserver(this); 40 process_->RemoveObserver(this);
42 41
43 // Now that no one is referencing us, we can safely remove ourselves from 42 // Now that no one is referencing us, we can safely remove ourselves from
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
76 browsing_instance_->browser_context(); 75 browsing_instance_->browser_context();
77 if (has_site_ && 76 if (has_site_ &&
78 RenderProcessHost::ShouldUseProcessPerSite(browser_context, site_) && 77 RenderProcessHost::ShouldUseProcessPerSite(browser_context, site_) &&
79 RenderProcessHostImpl::GetProcessHostForSite(browser_context, site_)) { 78 RenderProcessHostImpl::GetProcessHostForSite(browser_context, site_)) {
80 return true; 79 return true;
81 } 80 }
82 81
83 return false; 82 return false;
84 } 83 }
85 84
86 namespace {
87
88 const void* const kDefaultSubframeProcessHostHolderKey =
89 &kDefaultSubframeProcessHostHolderKey;
90
91 class DefaultSubframeProcessHostHolder : public base::SupportsUserData::Data,
92 public RenderProcessHostObserver {
93 public:
94 explicit DefaultSubframeProcessHostHolder(BrowserContext* browser_context)
95 : browser_context_(browser_context) {}
96 ~DefaultSubframeProcessHostHolder() override {}
97
98 // Gets the correct render process to use for this SiteInstance.
99 RenderProcessHost* GetProcessHost(SiteInstance* site_instance,
100 bool is_for_guests_only) {
101 StoragePartition* default_partition =
102 BrowserContext::GetDefaultStoragePartition(browser_context_);
103 StoragePartition* partition =
104 BrowserContext::GetStoragePartition(browser_context_, site_instance);
105
106 // Is this the default storage partition? If it isn't, then just give it its
107 // own non-shared process.
108 if (partition != default_partition || is_for_guests_only) {
109 RenderProcessHostImpl* host = new RenderProcessHostImpl(
110 browser_context_, static_cast<StoragePartitionImpl*>(partition),
111 is_for_guests_only);
112 host->SetIsNeverSuitableForReuse();
113 return host;
114 }
115
116 if (host_) {
117 // If we already have a shared host for the default storage partition, use
118 // it.
119 return host_;
120 }
121
122 host_ = new RenderProcessHostImpl(
123 browser_context_, static_cast<StoragePartitionImpl*>(partition),
124 false /* for guests only */);
125 host_->SetIsNeverSuitableForReuse();
126 host_->AddObserver(this);
127
128 return host_;
129 }
130
131 void RenderProcessHostDestroyed(RenderProcessHost* host) override {
132 DCHECK_EQ(host_, host);
133 host_->RemoveObserver(this);
134 host_ = nullptr;
135 }
136
137 private:
138 BrowserContext* browser_context_;
139
140 // The default subframe render process used for the default storage partition
141 // of this BrowserContext.
142 RenderProcessHostImpl* host_ = nullptr;
143 };
144
145 } // namespace
146
147 RenderProcessHost* SiteInstanceImpl::GetDefaultSubframeProcessHost(
148 BrowserContext* browser_context,
149 bool is_for_guests_only) {
nasko 2017/05/03 23:46:17 Ok, I didn't realize this is code that just moved
clamy 2017/05/04 15:56:19 I did the modifications as requested in the other
150 DefaultSubframeProcessHostHolder* holder =
151 static_cast<DefaultSubframeProcessHostHolder*>(
152 browser_context->GetUserData(&kDefaultSubframeProcessHostHolderKey));
153 if (!holder) {
154 holder = new DefaultSubframeProcessHostHolder(browser_context);
155 browser_context->SetUserData(kDefaultSubframeProcessHostHolderKey,
156 base::WrapUnique(holder));
157 }
158
159 return holder->GetProcessHost(this, is_for_guests_only);
160 }
161
162 RenderProcessHost* SiteInstanceImpl::GetProcess() { 85 RenderProcessHost* SiteInstanceImpl::GetProcess() {
163 // TODO(erikkay) It would be nice to ensure that the renderer type had been 86 // TODO(erikkay) It would be nice to ensure that the renderer type had been
164 // properly set before we get here. The default tab creation case winds up 87 // properly set before we get here. The default tab creation case winds up
165 // with no site set at this point, so it will default to TYPE_NORMAL. This 88 // with no site set at this point, so it will default to TYPE_NORMAL. This
166 // may not be correct, so we'll wind up potentially creating a process that 89 // may not be correct, so we'll wind up potentially creating a process that
167 // we then throw away, or worse sharing a process with the wrong process type. 90 // we then throw away, or worse sharing a process with the wrong process type.
168 // See crbug.com/43448. 91 // See crbug.com/43448.
169 92
170 // Create a new process if ours went away or was reused. 93 // Create a new process if ours went away or was reused.
171 if (!process_) { 94 if (!process_) {
172 BrowserContext* browser_context = browsing_instance_->browser_context(); 95 BrowserContext* browser_context = browsing_instance_->browser_context();
173 bool is_for_guests_only = site_.SchemeIs(kGuestScheme); 96 process_ = RenderProcessHostImpl::GetProcessHostForSiteInstance(
97 browser_context, this);
174 98
175 // If we should use process-per-site mode (either in general or for the
176 // given site), then look for an existing RenderProcessHost for the site.
177 bool use_process_per_site = has_site_ &&
178 RenderProcessHost::ShouldUseProcessPerSite(browser_context, site_);
179 if (use_process_per_site) {
180 process_ = RenderProcessHostImpl::GetProcessHostForSite(browser_context,
181 site_);
182 }
183
184 if (!process_ && IsDefaultSubframeSiteInstance() &&
185 SiteIsolationPolicy::IsTopDocumentIsolationEnabled()) {
186 process_ =
187 GetDefaultSubframeProcessHost(browser_context, is_for_guests_only);
188 }
189
190 // If not (or if none found), see if we should reuse an existing process.
191 if (!process_ && RenderProcessHostImpl::ShouldTryToUseExistingProcessHost(
192 browser_context, site_)) {
193 process_ = RenderProcessHostImpl::GetExistingProcessHost(browser_context,
194 site_);
195 }
196
197 // Otherwise (or if that fails), create a new one.
198 if (!process_) {
199 if (g_render_process_host_factory_) {
200 process_ = g_render_process_host_factory_->CreateRenderProcessHost(
201 browser_context, this);
202 } else {
203 StoragePartitionImpl* partition =
204 static_cast<StoragePartitionImpl*>(
205 BrowserContext::GetStoragePartition(browser_context, this));
206 process_ = new RenderProcessHostImpl(browser_context, partition,
207 is_for_guests_only);
208 }
209 }
210 CHECK(process_); 99 CHECK(process_);
211 process_->AddObserver(this); 100 process_->AddObserver(this);
212 101
213 // If we are using process-per-site, we need to register this process 102 // If we are using process-per-site, we need to register this process
214 // for the current site so that we can find it again. (If no site is set 103 // for the current site so that we can find it again. (If no site is set
215 // at this time, we will register it in SetSite().) 104 // at this time, we will register it in SetSite().)
216 if (use_process_per_site) { 105 if (process_reuse_policy_ ==
106 RenderProcessHostImpl::ProcessReusePolicy::PROCESS_PER_SITE &&
107 has_site_) {
217 RenderProcessHostImpl::RegisterProcessHostForSite(browser_context, 108 RenderProcessHostImpl::RegisterProcessHostForSite(browser_context,
Charlie Reis 2017/05/03 23:28:00 Ah, I suppose there's still a fair amount needed b
clamy 2017/05/04 15:56:19 Indeed. The goal of this patch is to move the code
218 process_, site_); 109 process_, site_);
219 } 110 }
220 111
221 TRACE_EVENT2("navigation", "SiteInstanceImpl::GetProcess", 112 TRACE_EVENT2("navigation", "SiteInstanceImpl::GetProcess",
222 "site id", id_, "process id", process_->GetID()); 113 "site id", id_, "process id", process_->GetID());
223 GetContentClient()->browser()->SiteInstanceGotProcess(this); 114 GetContentClient()->browser()->SiteInstanceGotProcess(this);
224 115
225 if (has_site_) 116 if (has_site_)
226 LockToOrigin(); 117 LockToOrigin();
227 } 118 }
(...skipping 17 matching lines...) Expand all
245 has_site_ = true; 136 has_site_ = true;
246 BrowserContext* browser_context = browsing_instance_->browser_context(); 137 BrowserContext* browser_context = browsing_instance_->browser_context();
247 site_ = GetSiteForURL(browser_context, url); 138 site_ = GetSiteForURL(browser_context, url);
248 139
249 // Now that we have a site, register it with the BrowsingInstance. This 140 // Now that we have a site, register it with the BrowsingInstance. This
250 // ensures that we won't create another SiteInstance for this site within 141 // ensures that we won't create another SiteInstance for this site within
251 // the same BrowsingInstance, because all same-site pages within a 142 // the same BrowsingInstance, because all same-site pages within a
252 // BrowsingInstance can script each other. 143 // BrowsingInstance can script each other.
253 browsing_instance_->RegisterSiteInstance(this); 144 browsing_instance_->RegisterSiteInstance(this);
254 145
146 // Update the process reuse policy based on the site.
147 bool should_use_process_per_site =
148 RenderProcessHost::ShouldUseProcessPerSite(browser_context, site_);
149 if (should_use_process_per_site) {
150 process_reuse_policy_ =
151 RenderProcessHostImpl::ProcessReusePolicy::PROCESS_PER_SITE;
152 }
153
255 if (process_) { 154 if (process_) {
256 LockToOrigin(); 155 LockToOrigin();
257 156
258 // Ensure the process is registered for this site if necessary. 157 // Ensure the process is registered for this site if necessary.
259 if (RenderProcessHost::ShouldUseProcessPerSite(browser_context, site_)) { 158 if (should_use_process_per_site) {
260 RenderProcessHostImpl::RegisterProcessHostForSite( 159 RenderProcessHostImpl::RegisterProcessHostForSite(
261 browser_context, process_, site_); 160 browser_context, process_, site_);
262 } 161 }
263 } 162 }
264 } 163 }
265 164
266 const GURL& SiteInstanceImpl::GetSiteURL() const { 165 const GURL& SiteInstanceImpl::GetSiteURL() const {
267 return site_; 166 return site_;
268 } 167 }
269 168
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
316 } 215 }
317 216
318 bool SiteInstanceImpl::RequiresDedicatedProcess() { 217 bool SiteInstanceImpl::RequiresDedicatedProcess() {
319 if (!has_site_) 218 if (!has_site_)
320 return false; 219 return false;
321 220
322 return DoesSiteRequireDedicatedProcess(GetBrowserContext(), site_); 221 return DoesSiteRequireDedicatedProcess(GetBrowserContext(), site_);
323 } 222 }
324 223
325 bool SiteInstanceImpl::IsDefaultSubframeSiteInstance() const { 224 bool SiteInstanceImpl::IsDefaultSubframeSiteInstance() const {
326 return is_default_subframe_site_instance_; 225 return process_reuse_policy_ == RenderProcessHostImpl::ProcessReusePolicy::
226 USE_DEFAULT_SUBFRAME_INSTANCE;
327 } 227 }
328 228
329 void SiteInstanceImpl::IncrementActiveFrameCount() { 229 void SiteInstanceImpl::IncrementActiveFrameCount() {
330 active_frame_count_++; 230 active_frame_count_++;
331 } 231 }
332 232
333 void SiteInstanceImpl::DecrementActiveFrameCount() { 233 void SiteInstanceImpl::DecrementActiveFrameCount() {
334 if (--active_frame_count_ == 0) { 234 if (--active_frame_count_ == 0) {
335 for (auto& observer : observers_) 235 for (auto& observer : observers_)
336 observer.ActiveFrameCountIsZero(this); 236 observer.ActiveFrameCountIsZero(this);
337 } 237 }
338 } 238 }
339 239
340 void SiteInstanceImpl::IncrementRelatedActiveContentsCount() { 240 void SiteInstanceImpl::IncrementRelatedActiveContentsCount() {
341 browsing_instance_->increment_active_contents_count(); 241 browsing_instance_->increment_active_contents_count();
342 } 242 }
343 243
344 void SiteInstanceImpl::DecrementRelatedActiveContentsCount() { 244 void SiteInstanceImpl::DecrementRelatedActiveContentsCount() {
345 browsing_instance_->decrement_active_contents_count(); 245 browsing_instance_->decrement_active_contents_count();
346 } 246 }
347 247
348 void SiteInstanceImpl::AddObserver(Observer* observer) { 248 void SiteInstanceImpl::AddObserver(Observer* observer) {
349 observers_.AddObserver(observer); 249 observers_.AddObserver(observer);
350 } 250 }
351 251
352 void SiteInstanceImpl::RemoveObserver(Observer* observer) { 252 void SiteInstanceImpl::RemoveObserver(Observer* observer) {
353 observers_.RemoveObserver(observer); 253 observers_.RemoveObserver(observer);
354 } 254 }
355 255
356 void SiteInstanceImpl::set_render_process_host_factory(
357 const RenderProcessHostFactory* rph_factory) {
358 g_render_process_host_factory_ = rph_factory;
359 }
360
361 BrowserContext* SiteInstanceImpl::GetBrowserContext() const { 256 BrowserContext* SiteInstanceImpl::GetBrowserContext() const {
362 return browsing_instance_->browser_context(); 257 return browsing_instance_->browser_context();
363 } 258 }
364 259
365 // static 260 // static
366 scoped_refptr<SiteInstance> SiteInstance::Create( 261 scoped_refptr<SiteInstance> SiteInstance::Create(
367 BrowserContext* browser_context) { 262 BrowserContext* browser_context) {
368 return SiteInstanceImpl::Create(browser_context); 263 return SiteInstanceImpl::Create(browser_context);
369 } 264 }
370 265
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
523 browsing_instance_->browser_context(), site_)) 418 browsing_instance_->browser_context(), site_))
524 return; 419 return;
525 420
526 ChildProcessSecurityPolicyImpl* policy = 421 ChildProcessSecurityPolicyImpl* policy =
527 ChildProcessSecurityPolicyImpl::GetInstance(); 422 ChildProcessSecurityPolicyImpl::GetInstance();
528 policy->LockToOrigin(process_->GetID(), site_); 423 policy->LockToOrigin(process_->GetID(), site_);
529 } 424 }
530 } 425 }
531 426
532 } // namespace content 427 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698