OLD | NEW |
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 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 "chrome/browser/renderer_host/render_process_host.h" | 5 #include "chrome/browser/renderer_host/render_process_host.h" |
6 | 6 |
7 #include "base/rand_util.h" | 7 #include "base/rand_util.h" |
8 #include "base/sys_info.h" | 8 #include "base/sys_info.h" |
| 9 #include "chrome/browser/child_process_security_policy.h" |
9 #include "chrome/common/chrome_constants.h" | 10 #include "chrome/common/chrome_constants.h" |
10 #include "chrome/common/notification_service.h" | 11 #include "chrome/common/notification_service.h" |
11 | 12 |
12 namespace { | 13 namespace { |
13 | 14 |
14 unsigned int GetMaxRendererProcessCount() { | 15 size_t GetMaxRendererProcessCount() { |
15 // Defines the maximum number of renderer processes according to the | 16 // Defines the maximum number of renderer processes according to the |
16 // amount of installed memory as reported by the OS. The table | 17 // amount of installed memory as reported by the OS. The table |
17 // values are calculated by assuming that you want the renderers to | 18 // values are calculated by assuming that you want the renderers to |
18 // use half of the installed ram and assuming that each tab uses | 19 // use half of the installed ram and assuming that each tab uses |
19 // ~40MB, however the curve is not linear but piecewise linear with | 20 // ~40MB, however the curve is not linear but piecewise linear with |
20 // interleaved slopes of 3 and 2. | 21 // interleaved slopes of 3 and 2. |
21 // If you modify this table you need to adjust browser\browser_uitest.cc | 22 // If you modify this table you need to adjust browser\browser_uitest.cc |
22 // to match the expected number of processes. | 23 // to match the expected number of processes. |
23 | 24 |
24 static const int kMaxRenderersByRamTier[] = { | 25 static const size_t kMaxRenderersByRamTier[] = { |
25 3, // less than 256MB | 26 3, // less than 256MB |
26 6, // 256MB | 27 6, // 256MB |
27 9, // 512MB | 28 9, // 512MB |
28 12, // 768MB | 29 12, // 768MB |
29 14, // 1024MB | 30 14, // 1024MB |
30 18, // 1280MB | 31 18, // 1280MB |
31 20, // 1536MB | 32 20, // 1536MB |
32 22, // 1792MB | 33 22, // 1792MB |
33 24, // 2048MB | 34 24, // 2048MB |
34 26, // 2304MB | 35 26, // 2304MB |
35 29, // 2560MB | 36 29, // 2560MB |
36 32, // 2816MB | 37 32, // 2816MB |
37 35, // 3072MB | 38 35, // 3072MB |
38 38, // 3328MB | 39 38, // 3328MB |
39 40 // 3584MB | 40 40 // 3584MB |
40 }; | 41 }; |
41 | 42 |
42 static unsigned int max_count = 0; | 43 static size_t max_count = 0; |
43 if (!max_count) { | 44 if (!max_count) { |
44 size_t memory_tier = base::SysInfo::AmountOfPhysicalMemoryMB() / 256; | 45 size_t memory_tier = base::SysInfo::AmountOfPhysicalMemoryMB() / 256; |
45 if (memory_tier >= arraysize(kMaxRenderersByRamTier)) | 46 if (memory_tier >= arraysize(kMaxRenderersByRamTier)) |
46 max_count = chrome::kMaxRendererProcessCount; | 47 max_count = chrome::kMaxRendererProcessCount; |
47 else | 48 else |
48 max_count = kMaxRenderersByRamTier[memory_tier]; | 49 max_count = kMaxRenderersByRamTier[memory_tier]; |
49 } | 50 } |
50 return max_count; | 51 return max_count; |
51 } | 52 } |
52 | 53 |
53 // Returns true if the given host is suitable for launching a new view | 54 // Returns true if the given host is suitable for launching a new view |
54 // associated with the given profile. | 55 // associated with the given profile. |
55 static bool IsSuitableHost(Profile* profile, RenderProcessHost* host) { | 56 static bool IsSuitableHost(RenderProcessHost* host, Profile* profile, |
56 return host->profile() == profile; | 57 RenderProcessHost::Type type) { |
| 58 // If the host doesn't have a PID yet, we don't know what it will be used |
| 59 // for, so just say it's unsuitable to be safe. |
| 60 if (host->pid() == -1) |
| 61 return false; |
| 62 |
| 63 if (host->profile() != profile) |
| 64 return false; |
| 65 |
| 66 RenderProcessHost::Type host_type = RenderProcessHost::TYPE_NORMAL; |
| 67 if (ChildProcessSecurityPolicy::GetInstance()->HasDOMUIBindings(host->pid())) |
| 68 host_type = RenderProcessHost::TYPE_DOMUI; |
| 69 if (ChildProcessSecurityPolicy::GetInstance()-> |
| 70 HasExtensionBindings(host->pid())) |
| 71 host_type = RenderProcessHost::TYPE_EXTENSION; |
| 72 |
| 73 return host_type == type; |
57 } | 74 } |
58 | 75 |
59 // the global list of all renderer processes | 76 // the global list of all renderer processes |
60 IDMap<RenderProcessHost> all_hosts; | 77 IDMap<RenderProcessHost> all_hosts; |
61 | 78 |
62 } // namespace | 79 } // namespace |
63 | 80 |
64 bool RenderProcessHost::run_renderer_in_process_ = false; | 81 bool RenderProcessHost::run_renderer_in_process_ = false; |
65 | 82 |
66 RenderProcessHost::RenderProcessHost(Profile* profile) | 83 RenderProcessHost::RenderProcessHost(Profile* profile) |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
120 return all_hosts.size(); | 137 return all_hosts.size(); |
121 } | 138 } |
122 | 139 |
123 // static | 140 // static |
124 RenderProcessHost* RenderProcessHost::FromID(int render_process_id) { | 141 RenderProcessHost* RenderProcessHost::FromID(int render_process_id) { |
125 return all_hosts.Lookup(render_process_id); | 142 return all_hosts.Lookup(render_process_id); |
126 } | 143 } |
127 | 144 |
128 // static | 145 // static |
129 bool RenderProcessHost::ShouldTryToUseExistingProcessHost() { | 146 bool RenderProcessHost::ShouldTryToUseExistingProcessHost() { |
130 unsigned int renderer_process_count = | 147 size_t renderer_process_count = all_hosts.size(); |
131 static_cast<unsigned int>(all_hosts.size()); | |
132 | 148 |
133 // NOTE: Sometimes it's necessary to create more render processes than | 149 // NOTE: Sometimes it's necessary to create more render processes than |
134 // GetMaxRendererProcessCount(), for instance when we want to create | 150 // GetMaxRendererProcessCount(), for instance when we want to create |
135 // a renderer process for a profile that has no existing renderers. | 151 // a renderer process for a profile that has no existing renderers. |
136 // This is OK in moderation, since the GetMaxRendererProcessCount() | 152 // This is OK in moderation, since the GetMaxRendererProcessCount() |
137 // is conservative. | 153 // is conservative. |
138 | 154 |
139 return run_renderer_in_process() || | 155 return run_renderer_in_process() || |
140 (renderer_process_count >= GetMaxRendererProcessCount()); | 156 (renderer_process_count >= GetMaxRendererProcessCount()); |
141 } | 157 } |
142 | 158 |
143 // static | 159 // static |
144 RenderProcessHost* RenderProcessHost::GetExistingProcessHost(Profile* profile) { | 160 RenderProcessHost* RenderProcessHost::GetExistingProcessHost(Profile* profile, |
| 161 Type type) { |
145 // First figure out which existing renderers we can use. | 162 // First figure out which existing renderers we can use. |
146 std::vector<RenderProcessHost*> suitable_renderers; | 163 std::vector<RenderProcessHost*> suitable_renderers; |
147 suitable_renderers.reserve(size()); | 164 suitable_renderers.reserve(size()); |
148 | 165 |
149 for (iterator iter = begin(); iter != end(); ++iter) { | 166 for (iterator iter = begin(); iter != end(); ++iter) { |
150 if (IsSuitableHost(profile, iter->second)) | 167 if (run_renderer_in_process() || |
| 168 IsSuitableHost(iter->second, profile, type)) |
151 suitable_renderers.push_back(iter->second); | 169 suitable_renderers.push_back(iter->second); |
152 } | 170 } |
153 | 171 |
154 // Now pick a random suitable renderer, if we have any. | 172 // Now pick a random suitable renderer, if we have any. |
155 if (!suitable_renderers.empty()) { | 173 if (!suitable_renderers.empty()) { |
156 int suitable_count = static_cast<int>(suitable_renderers.size()); | 174 int suitable_count = static_cast<int>(suitable_renderers.size()); |
157 int random_index = base::RandInt(0, suitable_count - 1); | 175 int random_index = base::RandInt(0, suitable_count - 1); |
158 return suitable_renderers[random_index]; | 176 return suitable_renderers[random_index]; |
159 } | 177 } |
160 | 178 |
161 return NULL; | 179 return NULL; |
162 } | 180 } |
163 | 181 |
164 void RenderProcessHost::SetProcessID(int pid) { | 182 void RenderProcessHost::SetProcessID(int pid) { |
165 if (pid_ != -1) { | 183 if (pid_ != -1) { |
166 // This object is being reused after a renderer crash. Remove the old pid. | 184 // This object is being reused after a renderer crash. Remove the old pid. |
167 all_hosts.Remove(pid_); | 185 all_hosts.Remove(pid_); |
168 } | 186 } |
169 | 187 |
170 pid_ = pid; | 188 pid_ = pid; |
171 all_hosts.AddWithID(this, pid); | 189 all_hosts.AddWithID(this, pid); |
172 } | 190 } |
| 191 |
| 192 void RenderProcessHost::RemoveFromList() { |
| 193 if (all_hosts.Lookup(pid_)) |
| 194 all_hosts.Remove(pid_); |
| 195 } |
OLD | NEW |