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

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

Issue 2861433002: Implement ProcessReusePolicy for SiteInstances (Closed)
Patch Set: Fixed ChromeOS issue 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
« no previous file with comments | « content/browser/site_instance_impl.h ('k') | content/browser/site_instance_impl_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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_(ProcessReusePolicy::DEFAULT) {
34 DCHECK(browsing_instance); 32 DCHECK(browsing_instance);
35 } 33 }
36 34
37 SiteInstanceImpl::~SiteInstanceImpl() { 35 SiteInstanceImpl::~SiteInstanceImpl() {
38 GetContentClient()->browser()->SiteInstanceDeleting(this); 36 GetContentClient()->browser()->SiteInstanceDeleting(this);
39 37
40 if (process_) 38 if (process_)
41 process_->RemoveObserver(this); 39 process_->RemoveObserver(this);
42 40
43 // Now that no one is referencing us, we can safely remove ourselves from 41 // 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(); 74 browsing_instance_->browser_context();
77 if (has_site_ && 75 if (has_site_ &&
78 RenderProcessHost::ShouldUseProcessPerSite(browser_context, site_) && 76 RenderProcessHost::ShouldUseProcessPerSite(browser_context, site_) &&
79 RenderProcessHostImpl::GetProcessHostForSite(browser_context, site_)) { 77 RenderProcessHostImpl::GetProcessHostForSite(browser_context, site_)) {
80 return true; 78 return true;
81 } 79 }
82 80
83 return false; 81 return false;
84 } 82 }
85 83
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) {
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() { 84 RenderProcessHost* SiteInstanceImpl::GetProcess() {
163 // TODO(erikkay) It would be nice to ensure that the renderer type had been 85 // 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 86 // 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 87 // 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 88 // 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. 89 // we then throw away, or worse sharing a process with the wrong process type.
168 // See crbug.com/43448. 90 // See crbug.com/43448.
169 91
170 // Create a new process if ours went away or was reused. 92 // Create a new process if ours went away or was reused.
171 if (!process_) { 93 if (!process_) {
172 BrowserContext* browser_context = browsing_instance_->browser_context(); 94 BrowserContext* browser_context = browsing_instance_->browser_context();
173 bool is_for_guests_only = site_.SchemeIs(kGuestScheme);
174 95
175 // If we should use process-per-site mode (either in general or for the 96 // Check if the ProcessReusePolicy should be updated.
176 // given site), then look for an existing RenderProcessHost for the site. 97 bool should_use_process_per_site =
177 bool use_process_per_site = has_site_ && 98 RenderProcessHost::ShouldUseProcessPerSite(browser_context, site_) &&
178 RenderProcessHost::ShouldUseProcessPerSite(browser_context, site_); 99 has_site_;
179 if (use_process_per_site) { 100 if (should_use_process_per_site) {
180 process_ = RenderProcessHostImpl::GetProcessHostForSite(browser_context, 101 process_reuse_policy_ = ProcessReusePolicy::PROCESS_PER_SITE;
181 site_); 102 } else if (process_reuse_policy_ == ProcessReusePolicy::PROCESS_PER_SITE) {
103 process_reuse_policy_ = ProcessReusePolicy::DEFAULT;
182 } 104 }
183 105
184 if (!process_ && IsDefaultSubframeSiteInstance() && 106 process_ = RenderProcessHostImpl::GetProcessHostForSiteInstance(
185 SiteIsolationPolicy::IsTopDocumentIsolationEnabled()) { 107 browser_context, this);
186 process_ =
187 GetDefaultSubframeProcessHost(browser_context, is_for_guests_only);
188 }
189 108
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_); 109 CHECK(process_);
211 process_->AddObserver(this); 110 process_->AddObserver(this);
212 111
213 // If we are using process-per-site, we need to register this process 112 // 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 113 // 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().) 114 // at this time, we will register it in SetSite().)
216 if (use_process_per_site) { 115 if (process_reuse_policy_ == ProcessReusePolicy::PROCESS_PER_SITE &&
116 has_site_) {
217 RenderProcessHostImpl::RegisterProcessHostForSite(browser_context, 117 RenderProcessHostImpl::RegisterProcessHostForSite(browser_context,
218 process_, site_); 118 process_, site_);
219 } 119 }
220 120
221 TRACE_EVENT2("navigation", "SiteInstanceImpl::GetProcess", 121 TRACE_EVENT2("navigation", "SiteInstanceImpl::GetProcess",
222 "site id", id_, "process id", process_->GetID()); 122 "site id", id_, "process id", process_->GetID());
223 GetContentClient()->browser()->SiteInstanceGotProcess(this); 123 GetContentClient()->browser()->SiteInstanceGotProcess(this);
224 124
225 if (has_site_) 125 if (has_site_)
226 LockToOrigin(); 126 LockToOrigin();
(...skipping 18 matching lines...) Expand all
245 has_site_ = true; 145 has_site_ = true;
246 BrowserContext* browser_context = browsing_instance_->browser_context(); 146 BrowserContext* browser_context = browsing_instance_->browser_context();
247 site_ = GetSiteForURL(browser_context, url); 147 site_ = GetSiteForURL(browser_context, url);
248 148
249 // Now that we have a site, register it with the BrowsingInstance. This 149 // 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 150 // ensures that we won't create another SiteInstance for this site within
251 // the same BrowsingInstance, because all same-site pages within a 151 // the same BrowsingInstance, because all same-site pages within a
252 // BrowsingInstance can script each other. 152 // BrowsingInstance can script each other.
253 browsing_instance_->RegisterSiteInstance(this); 153 browsing_instance_->RegisterSiteInstance(this);
254 154
155 // Update the process reuse policy based on the site.
156 bool should_use_process_per_site =
157 RenderProcessHost::ShouldUseProcessPerSite(browser_context, site_);
158 if (should_use_process_per_site) {
159 process_reuse_policy_ = ProcessReusePolicy::PROCESS_PER_SITE;
160 }
161
255 if (process_) { 162 if (process_) {
256 LockToOrigin(); 163 LockToOrigin();
257 164
258 // Ensure the process is registered for this site if necessary. 165 // Ensure the process is registered for this site if necessary.
259 if (RenderProcessHost::ShouldUseProcessPerSite(browser_context, site_)) { 166 if (should_use_process_per_site) {
260 RenderProcessHostImpl::RegisterProcessHostForSite( 167 RenderProcessHostImpl::RegisterProcessHostForSite(
261 browser_context, process_, site_); 168 browser_context, process_, site_);
262 } 169 }
263 } 170 }
264 } 171 }
265 172
266 const GURL& SiteInstanceImpl::GetSiteURL() const { 173 const GURL& SiteInstanceImpl::GetSiteURL() const {
267 return site_; 174 return site_;
268 } 175 }
269 176
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
316 } 223 }
317 224
318 bool SiteInstanceImpl::RequiresDedicatedProcess() { 225 bool SiteInstanceImpl::RequiresDedicatedProcess() {
319 if (!has_site_) 226 if (!has_site_)
320 return false; 227 return false;
321 228
322 return DoesSiteRequireDedicatedProcess(GetBrowserContext(), site_); 229 return DoesSiteRequireDedicatedProcess(GetBrowserContext(), site_);
323 } 230 }
324 231
325 bool SiteInstanceImpl::IsDefaultSubframeSiteInstance() const { 232 bool SiteInstanceImpl::IsDefaultSubframeSiteInstance() const {
326 return is_default_subframe_site_instance_; 233 return process_reuse_policy_ ==
234 ProcessReusePolicy::USE_DEFAULT_SUBFRAME_PROCESS;
327 } 235 }
328 236
329 void SiteInstanceImpl::IncrementActiveFrameCount() { 237 void SiteInstanceImpl::IncrementActiveFrameCount() {
330 active_frame_count_++; 238 active_frame_count_++;
331 } 239 }
332 240
333 void SiteInstanceImpl::DecrementActiveFrameCount() { 241 void SiteInstanceImpl::DecrementActiveFrameCount() {
334 if (--active_frame_count_ == 0) { 242 if (--active_frame_count_ == 0) {
335 for (auto& observer : observers_) 243 for (auto& observer : observers_)
336 observer.ActiveFrameCountIsZero(this); 244 observer.ActiveFrameCountIsZero(this);
337 } 245 }
338 } 246 }
339 247
340 void SiteInstanceImpl::IncrementRelatedActiveContentsCount() { 248 void SiteInstanceImpl::IncrementRelatedActiveContentsCount() {
341 browsing_instance_->increment_active_contents_count(); 249 browsing_instance_->increment_active_contents_count();
342 } 250 }
343 251
344 void SiteInstanceImpl::DecrementRelatedActiveContentsCount() { 252 void SiteInstanceImpl::DecrementRelatedActiveContentsCount() {
345 browsing_instance_->decrement_active_contents_count(); 253 browsing_instance_->decrement_active_contents_count();
346 } 254 }
347 255
348 void SiteInstanceImpl::AddObserver(Observer* observer) { 256 void SiteInstanceImpl::AddObserver(Observer* observer) {
349 observers_.AddObserver(observer); 257 observers_.AddObserver(observer);
350 } 258 }
351 259
352 void SiteInstanceImpl::RemoveObserver(Observer* observer) { 260 void SiteInstanceImpl::RemoveObserver(Observer* observer) {
353 observers_.RemoveObserver(observer); 261 observers_.RemoveObserver(observer);
354 } 262 }
355 263
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 { 264 BrowserContext* SiteInstanceImpl::GetBrowserContext() const {
362 return browsing_instance_->browser_context(); 265 return browsing_instance_->browser_context();
363 } 266 }
364 267
365 // static 268 // static
366 scoped_refptr<SiteInstance> SiteInstance::Create( 269 scoped_refptr<SiteInstance> SiteInstance::Create(
367 BrowserContext* browser_context) { 270 BrowserContext* browser_context) {
368 return SiteInstanceImpl::Create(browser_context); 271 return SiteInstanceImpl::Create(browser_context);
369 } 272 }
370 273
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
523 browsing_instance_->browser_context(), site_)) 426 browsing_instance_->browser_context(), site_))
524 return; 427 return;
525 428
526 ChildProcessSecurityPolicyImpl* policy = 429 ChildProcessSecurityPolicyImpl* policy =
527 ChildProcessSecurityPolicyImpl::GetInstance(); 430 ChildProcessSecurityPolicyImpl::GetInstance();
528 policy->LockToOrigin(process_->GetID(), site_); 431 policy->LockToOrigin(process_->GetID(), site_);
529 } 432 }
530 } 433 }
531 434
532 } // namespace content 435 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/site_instance_impl.h ('k') | content/browser/site_instance_impl_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698